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

# Accept an invitation

> Accept an invitation.

Body: {"token": "..."}

AUTH (2026-07-27). This endpoint used to take no auth dependency at all and
resolve the member purely from ``invite.email`` — a magic-link design where
possession of the token IS the proof of identity. That is a sound pattern, but
only while the token reaches nobody except the invited mailbox. It did not:
``invite.token`` is returned in the create response to the INVITER (the single
place it appears in the whole backend — there is no invite email and no
template), so the party who mints a token is the party who can redeem it. Any
org admin could therefore invite an arbitrary existing user at role
``admin``/``owner``, self-redeem, and silently plant that person in their org —
which also steers the victim's own session, since ``_resolve_clerk_identity``
falls back to an unordered ``.first()`` across memberships.

The fix keeps the token as the *lookup* key but stops treating it as a bearer
credential: the caller must be authenticated AND must own the invited address.
That closes the hole without depending on an email channel that does not exist
yet. When invite delivery ships, drop ``token`` from the create response — the
token becomes a genuine secret again and this check becomes belt-and-braces.



## OpenAPI

````yaml /openapi.json post /api/v1/org/accept-invite
openapi: 3.1.0
info:
  title: DecimalAI Platform
  description: Agent Dataset Lifecycle Platform — Backend API
  version: 0.1.0
servers: []
security:
  - BearerAuth: []
tags:
  - name: traces
    description: >-
      Ingest, search, and inspect agent execution traces. A trace is the atomic
      unit of the platform — every other feature (evaluation, compatibility
      scoring, dataset building) operates on traces. Each trace is auto-tagged
      with the manifest hash of the agent that produced it.
  - name: eval-scores
    description: >-
      Push, fetch, and aggregate per-trace evaluation scores. Scores carry
      source provenance (built-in, DeepEval, LangSmith, custom) and feed the
      unified decision engine, which produces a keep / repair / replay / drop
      verdict per trace.
  - name: skills
    description: >-
      Manage reusable instruction blocks (SKILL.md files) that modify agent
      behavior. Skills are first-class manifest components — changes to a skill
      appear in your regression-check impact reports. Use these endpoints to
      create, version, fork, and sync skills with your local SKILL.md files.
  - name: manifests
    description: >-
      Register and inspect manifest versions. A manifest is a snapshot of your
      agent's structural identity (tools, prompts, models, skills) at a point in
      time. The SDK registers manifests automatically; these endpoints expose
      the underlying records.
  - name: datasets
    description: >-
      Build versioned SFT/DPO training datasets from manifest-classified,
      eval-scored traces. Datasets are reproducible — each version locks the
      manifest and filter set used to build it. Export as JSONL, Parquet, or
      push to HuggingFace Hub.
  - name: replay
    description: >-
      Re-execute historical traces against a new manifest version. Replay is the
      deferred-future capability for behavioral verification of agent changes.
      The SDK creates a replay batch, your worker executes each task, then
      submits results back here for eval scoring.
  - name: registry
    description: >-
      Browse and install community skills from the public skills registry. Each
      registry skill carries a SkillScore — an evidence-tiered quality composite
      computed from real-world evals, benchmarks, and ratings across
      organizations. Installing creates a fork in your org — edits don't affect
      the public version.
  - name: agents
    description: >-
      List and inspect agents, plus their multi-agent topology (orchestrator →
      sub-agent edges discovered from traces). Agents are identified by a stable
      agent_name string set in your SDK init() call.
  - name: import
    description: >-
      Bulk-import historical traces from another observability platform or a
      JSONL backup. Useful for migrating from LangSmith / Braintrust / Langfuse.
      Duplicate trace IDs are silently skipped — re-running an import is safe.
paths:
  /api/v1/org/accept-invite:
    post:
      tags:
        - organization
      summary: Accept an invitation
      description: >-
        Accept an invitation.


        Body: {"token": "..."}


        AUTH (2026-07-27). This endpoint used to take no auth dependency at all
        and

        resolve the member purely from ``invite.email`` — a magic-link design
        where

        possession of the token IS the proof of identity. That is a sound
        pattern, but

        only while the token reaches nobody except the invited mailbox. It did
        not:

        ``invite.token`` is returned in the create response to the INVITER (the
        single

        place it appears in the whole backend — there is no invite email and no

        template), so the party who mints a token is the party who can redeem
        it. Any

        org admin could therefore invite an arbitrary existing user at role

        ``admin``/``owner``, self-redeem, and silently plant that person in
        their org —

        which also steers the victim's own session, since
        ``_resolve_clerk_identity``

        falls back to an unordered ``.first()`` across memberships.


        The fix keeps the token as the *lookup* key but stops treating it as a
        bearer

        credential: the caller must be authenticated AND must own the invited
        address.

        That closes the hole without depending on an email channel that does not
        exist

        yet. When invite delivery ships, drop ``token`` from the create response
        — the

        token becomes a genuine secret again and this check becomes
        belt-and-braces.
      operationId: accept_invite_api_v1_org_accept_invite_post
      parameters:
        - name: Authorization
          in: header
          required: false
          schema:
            type: string
            title: Authorization
        - name: decimal_session
          in: cookie
          required: false
          schema:
            anyOf:
              - type: string
              - type: 'null'
            title: Decimal Session
      requestBody:
        required: true
        content:
          application/json:
            schema:
              type: object
              additionalProperties:
                type: string
              title: Body
      responses:
        '200':
          description: Successful Response
          content:
            application/json:
              schema:
                type: object
                additionalProperties: true
                title: Response Accept Invite Api V1 Org Accept Invite Post
        '422':
          description: Validation Error
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/HTTPValidationError'
components:
  schemas:
    HTTPValidationError:
      properties:
        detail:
          items:
            $ref: '#/components/schemas/ValidationError'
          type: array
          title: Detail
      type: object
      title: HTTPValidationError
    ValidationError:
      properties:
        loc:
          items:
            anyOf:
              - type: string
              - type: integer
          type: array
          title: Location
        msg:
          type: string
          title: Message
        type:
          type: string
          title: Error Type
        input:
          title: Input
        ctx:
          type: object
          title: Context
      type: object
      required:
        - loc
        - msg
        - type
      title: ValidationError
  securitySchemes:
    BearerAuth:
      type: http
      scheme: bearer
      description: Enter your API key (e.g. dai_sk_test_key_001)

````