---
title: "Accept a product invite."
method: POST
path: "/invites/accept"
tags: ["Invites"]
---

# Accept a product invite.

`POST /invites/accept`

## Request

- Base URL: `https://api.mnemom.ai/v1`
- URL: `https://api.mnemom.ai/v1/invites/accept`
- Auth: HTTP bearer

RG M1 invite flow (MNE-7166). Redeems an opaque `pinv_…` invite token: validates the token, marks the `product_invite` `accepted` exactly-once, grants the invitee access to the invited product(s), and tops the account's µ balance up to the invite's per-product entitlement (never a sum, never a debit; computed server-side at accept time) via billing. Invitee-facing and authenticated — a user invite requires the caller to be that user (403 `invite_account_mismatch` otherwise); an email-bound invite requires the caller's account email (resolved server-side, never from the request) to match the invited address; the emailed token is the proof of inbox possession, so the email need not be confirmed yet (403 `invite_email_mismatch` otherwise; 502 if the identity lookup fails, 503 if no identity provider is configured); an org invite requires the caller to be an owner/admin of that org. Idempotent: a second accept re-asserts access and returns 200 without re-firing the grant. The grant amount is admin-only and never appears in the request or response — the response only reports whether the starter grant `fired` or was `deferred`.

## Request body

- object
  - `token` string, required: The opaque `pinv_…` invite token from the accept link.

## Response `200`

Invite accepted (or already accepted). Product access is granted; the response reports whether the starter grant fired or was deferred. Never carries the grant amount.

- object
  - `accepted` boolean, required: True once the invite is in the accepted state.
  - `already_accepted` boolean: Present and true when the invite was already accepted (idempotent re-accept); the grant is not re-fired.
  - `account_type` 'user' | 'org', required: The account type the product access landed on.
  - `account_id` string, required: The user or org id the product access landed on.
  - `products` string[], required: The products the invite granted access to.
  - `grant` 'fired' | 'deferred': Whether the starter grant was settled (`fired`: forwarded to billing, or nothing owed because the products entitle no µ or the account already holds the entitlement) or deferred for a later retry/backfill (`deferred`). Omitted on an idempotent re-accept.

## Other responses

- `400`: Bad request
- `401`: Authentication required
- `403`: Forbidden
- `404`: Resource not found
- `409`: The invite's state changed concurrently (a competing accept/expire/revoke won the race) — retry.
- `410`: The invite is expired or revoked and can no longer be accepted.
- `429`: Rate-limit exceeded. The global per-IP limiter (100 requests/minute, applied to every `/v1/*` route) rejected this request. Back off until the window resets — `Retry-After` carries the cooldown in seconds and `X-RateLimit-Reset` the absolute reset time.
- `500`: Server error — request was well-formed but the server failed to fulfill it. Typically a downstream dependency (DB / RPC / external API) returned an unexpected error.
- `502`: An upstream dependency returned an invalid response.
- `503`: An upstream dependency is currently unavailable. The request was not processed; retry after the cooldown window.

---

[API](https://skmtc.dev/mnemom/apis/mnemom-api.md) · [All operations](https://skmtc.dev/mnemom/apis/mnemom-api/llms.txt) · [OpenAPI document](https://skmtc.dev/mnemom/apis/mnemom-api/revisions/274b7a6ea182?raw)
