Docs
Search docs

Accept an invite — join the organization or the repository

POST/api/invites/{token}/accept

acceptInvite

Session-authenticated caller only. The caller must hold a verified email equal (case-insensitively) to the invited address, else 403 `forbidden` (`invite_email_mismatch`) and the invite stays pending. In one transaction: marks the invite accepted and creates or upgrades the grant — an org membership, or an account grant on the repository — never demoting an existing role, bound to the invited address (ADR 0164): it lapses if the account stops holding that address verified. An org invite then auto-joins the default team. 409 `already_exists` if the invite is no longer pending.

Requires authentication using a session cookie — see tokens and scopes.

curl

curl -X POST 'https://neosource.dev/api/invites/TOKEN/accept' \
  -b 'ns_session=$NEOSOURCE_SESSION'

fetch

fetch("https://neosource.dev/api/invites/TOKEN/accept", {
  method: "POST",
  credentials: "include",
});

Path parameters

tokenrequired

string

Responses

200Accepted

application/json

AcceptInviteResponse

object

targetrequired

InviteTarget

What an invite grants on accept.

one of
  • object

    Membership of an organization. Slug + display name suffice for the SPA to render "X invited you to join Y" without the `invite_id`.

    kindrequired

    string

    "org"

    org_display_namerequired

    string

    org_slugrequired

    string

    rolerequired
    WorkspaceRole
  • object

    A grant on one repository.

    kindrequired

    string

    "repo"

    ownerrequired

    string

    reporequired

    string

    rolerequired
    RepoRole

403Forbidden — one of: forbidden, needs_scope

application/json

one of
  • ErrorForbidden
  • NeedsScopeError

    object

    `403` body returned when a classic OAuth token is asked for something its granted scopes do not cover — an explicit private listing without `repo`, or the one-click GitHub mirror without `admin:public_key`. `scope` names the missing grant so the client can say exactly what the token lacks. There is no elevation route to widen it any more (a re-link goes through the GitHub App, whose tokens carry no scopes), so the client's answer is to say so, never to start a handshake.

    errorrequired

    string

    Always `needs_scope` — this body exists to carry the extra fields that kind needs.

    "needs_scope"

    scoperequired

    string

    The provider scope to request via elevation (e.g. `"repo"`).

Standard errors

Bodies documented once for the whole API — see standard errors.

  • 400Bad Request — one of: invalid_input
  • 401Authentication required
  • 404Not Found — one of: not_found
  • 409Conflict — one of: already_exists, conflict
  • 429Rate limited — retry after the `Retry-After` header
  • 500Internal server error
  • 503Service temporarily unavailable / at capacity — retry after the `Retry-After` header
  • 504Gateway timeout — the request exceeded the server's handling budget

Schemas

Referenced above. Listed here rather than expanded inline, so the same definition is not repeated at every level.

WorkspaceRole

string

Workspace membership role. Ordered low → high (`Member < Admin < Owner`) so that `if actor_role >= WorkspaceRole::Admin` reads naturally.

"member""admin""owner"

RepoRole

string

Repo-level role (read/write/maintain/admin). Ordered low → high so `if role >= RepoRole::Write` reads naturally.

"read""write""maintain""admin"