> ## Documentation Index
> Fetch the complete documentation index at: https://spreecommerce.org/docs/llms.txt
> Use this file to discover all available pages before exploring further.

# Accept an invitation

> Accepts the invitation and returns a signed-in seller session, so the new
member lands in the panel rather than on a login form.

The email is never taken from the request — it always comes from the
invitation, which is what stops the link being redirected to another
address.

`password` is required when no account exists for the invited address, in
which case it sets one. When an account already exists, the same field is
how the person proves the account is theirs.




## OpenAPI

````yaml /api-reference/seller.yaml post /api/v3/seller/auth/invitations/{id}/accept
openapi: 3.0.3
info:
  title: Seller API
  contact:
    name: Spree Commerce
    url: https://spreecommerce.org
    email: hello@spreecommerce.org
  description: |
    Spree Seller API v3 - the marketplace seller panel, where a seller runs
    their own shop inside someone else's marketplace.

    This is a branch of its own, not a narrowing of the Admin API. Every
    endpoint is scoped server-side to the seller the request acts as, which
    is what makes cross-seller access impossible by construction rather
    than by rule. Sellers never call the Admin API.

    ## Authentication

    Sign in at `POST /api/v3/seller/auth/login` and send the returned JWT as
    `Authorization: Bearer <token>`. The token carries a `seller_api`
    audience — a token minted for the storefront or the back office is not
    accepted here, and vice versa.

    There is deliberately **no secret API key** for this branch: a
    credential that could act as a seller without a seller signing in is
    exactly what the separate audience exists to prevent.

    ### Choosing a seller

    A user may run more than one seller. Login returns the list; send the
    chosen seller's ID in the `X-Spree-Seller-Id` header on every
    authenticated request. The store is derived from the seller — never
    sent — so no header can widen what a seller reaches. A request that
    names no seller the caller belongs to is rejected with `403`.

    ## Response Format

    All responses are JSON. List endpoints return paginated responses with
    `data` and `meta` keys.

    ## Error Handling

    Errors return a consistent format:
    ```json
    {
      "error": {
        "code": "validation_error",
        "message": "Validation failed",
        "details": { "name": ["can't be blank"] }
      }
    }
    ```
  version: v3
servers:
  - url: http://{defaultHost}
    variables:
      defaultHost:
        default: localhost:3000
security: []
tags:
  - name: Authentication
    description: Seller sign-in, token refresh, logout, and invitation acceptance
  - name: Account
    description: The signed-in user, the sellers they may act for, and what they may do
  - name: Countries
    description: Country and state reference data for the panel's address forms
  - name: Delivery Methods
    description: >-
      The seller's own ways to ship, and the marketplace methods shared with
      them
  - name: Delivery Profiles
    description: >-
      The marketplace's delivery vocabulary — what kind of goods a product is,
      which decides how it ships
  - name: Delivery Zones
    description: >-
      The marketplace's destinations, for narrowing where a seller's own method
      ships
  - name: Onboarding
    description: >-
      The marketplace checklist a seller completes before admission, and what
      they submit against it
  - name: Policies
    description: The seller's own legal documents, as the marketplace asks them to publish
  - name: Product Types
    description: The types a seller may list a product against, and what each adds
  - name: Products
    description: The seller's own catalog
  - name: Profile
    description: >-
      The seller's own record — presentation, contact details, addresses, and
      tax registration
  - name: Stock Locations
    description: Where the seller keeps stock, and so where their returns are sent
  - name: Team
    description: Who runs this seller, and the invitations nobody has accepted yet
  - name: Uploads
    description: Presigned direct uploads for the documents onboarding asks for
paths:
  /api/v3/seller/auth/invitations/{id}/accept:
    parameters:
      - name: id
        in: path
        description: Invitation ID from the emailed link
        required: true
        schema:
          type: string
    post:
      tags:
        - Authentication
      summary: Accept an invitation
      description: >
        Accepts the invitation and returns a signed-in seller session, so the
        new

        member lands in the panel rather than on a login form.


        The email is never taken from the request — it always comes from the

        invitation, which is what stops the link being redirected to another

        address.


        `password` is required when no account exists for the invited address,
        in

        which case it sets one. When an account already exists, the same field
        is

        how the person proves the account is theirs.
      parameters:
        - name: token
          in: query
          required: true
          description: The token from the emailed link
          schema:
            type: string
      requestBody:
        content:
          application/json:
            schema:
              type: object
              properties:
                password:
                  type: string
                  example: password123
                password_confirmation:
                  type: string
                  example: password123
                first_name:
                  type: string
                  example: Robin
                last_name:
                  type: string
                  example: Ellis
      responses:
        '200':
          description: invitation accepted, session issued
          content:
            application/json:
              example:
                token: >-
                  eyJhbGciOiJIUzI1NiJ9.eyJ1c2VyX2lkIjoyLCJ1c2VyX3R5cGUiOiJhZG1pbiIsImp0aSI6IjRmYzVlNzBmLWU1ODAtNDExNi1hOWU5LTBjNDliMGExYjMxNCIsImlzcyI6InNwcmVlIiwiYXVkIjoic2VsbGVyX2FwaSIsImV4cCI6MTc2ODQ3ODcwMH0.H0mJ1zDqTi6mNs_BZBRTJ77OMsWAqeUXvQM09YPLefs
                user:
                  id: adm_gbHJdmfrXB
                  email: newcomer@acme.test
                  first_name: Robin
                  last_name: Ellis
                  full_name: Robin Ellis
                  created_at: '2026-01-15T12:00:00.000Z'
                  avatar_url: null
                sellers:
                  - id: sel_UkLWZg9DAJ
                    name: Seller 44
                    status: approved
              schema:
                $ref: '#/components/schemas/AuthResponse'
        '404':
          description: wrong token, or an invitation that can no longer be accepted
          content:
            application/json:
              example:
                error:
                  code: record_not_found
                  message: Invitation not found, expired, or already accepted.
              schema:
                $ref: '#/components/schemas/ErrorResponse'
components:
  schemas:
    AuthResponse:
      type: object
      properties:
        token:
          type: string
          description: JWT access token, `seller_api` audience
        user:
          $ref: '#/components/schemas/TeamMember'
        sellers:
          type: array
          description: >-
            The sellers this user may act for. Pick one and send its `id` as
            `X-Spree-Seller-Id` on every subsequent request.
          items:
            $ref: '#/components/schemas/SellerSummary'
      required:
        - token
        - user
        - sellers
    ErrorResponse:
      type: object
      properties:
        error:
          type: object
          properties:
            code:
              type: string
              example: record_not_found
            message:
              type: string
              example: Record not found
            details:
              type: object
              description: Field-specific validation errors
              nullable: true
              example:
                name:
                  - is too short
                  - is required
                email:
                  - is invalid
          required:
            - code
            - message
      required:
        - error
      example:
        error:
          code: validation_error
          message: Validation failed
          details:
            name:
              - is too short
            email:
              - is invalid
    TeamMember:
      type: object
      properties:
        id:
          type: string
        email:
          type: string
        first_name:
          type: string
          nullable: true
        last_name:
          type: string
          nullable: true
        full_name:
          type: string
          nullable: true
        created_at:
          type: string
        avatar_url:
          type: string
          nullable: true
      required:
        - id
        - email
        - first_name
        - last_name
        - full_name
        - created_at
        - avatar_url
      x-typelizer: true
    SellerSummary:
      type: object
      description: A seller the signed-in user may act for
      properties:
        id:
          type: string
          description: Prefixed seller ID — send as `X-Spree-Seller-Id`
          example: sel_abc123
        name:
          type: string
          example: Acme Supplies
        status:
          type: string
          example: approved
          description: Seller lifecycle status
      required:
        - id
        - name
        - status

````