---
title: "Attach an anonymously minted passport to the caller's account"
method: POST
path: "/api/account/claim"
tags: ["Agent Passport"]
---

# Attach an anonymously minted passport to the caller's account

`POST /api/account/claim`

## Request

- Base URL: `https://flint.network`
- URL: `https://flint.network/api/account/claim`
- Auth: one of:
  - API key in cookie `flint_session`
  - HTTP bearer

Attaches an unclaimed passport to the authenticated caller's FLINT account. Two request shapes: { passport_id, claim_token } presents the one-time token from the mint's claim_url. { passport_id } alone works only when the caller's account already holds a pending-claim binding for this passport (begin_claim or refresh_claim_token while signed in, the MCP claim flow, or the flint_claim_intent cookie surviving an OTP delay). Every non-owned failure returns a distinct reason code instead of one shared error string.

## Request body

- union
  - ClaimByTokenRequest
    - `passport_id` string, required
    - `claim_token` string, required: The one-time claim token from the mint's claim_url.
  - ClaimBySessionRequest: Valid only when the caller's authenticated account already holds a pending-claim binding for this passport_id: begin_claim while signed in, refresh_claim_token while signed in, the MCP claim flow, or the flint_claim_intent cookie set by begin_claim while signed out (survives an OTP delay and the /welcome new-account redirect within its 30-minute window).
    - `passport_id` string, required

## Response `200`

Passport claimed.

- ClaimResponse
  - `ok` boolean
  - `owned` true
  - `passport_id` string
  - `passport_url` string
  - `ownership` Ownership: Public-safe ownership and claim lifecycle state for a passport. Never includes emails or raw WorkOS user ids. Identical shape on the issue response, GET /api/passport/{passport_id}, and POST /api/account/claim.
    - `owned` boolean: True once a FLINT account holds this passport.
    - `unclaimed` boolean: The logical negation of owned.
    - `claimed_at` string, date-time, nullable: When the passport was claimed. Null while unclaimed.
    - `owner_account_ref` string, nullable: One-way account reference: "acct_" followed by the first 16 hex characters of sha256(owner user id). Never the raw WorkOS user id or email. Null while unclaimed.
    - `claim_state` 'claimed' | 'pending' | 'superseded' | 'none': "claimed": owned. "pending": unclaimed with an open claim token. "superseded": unclaimed and replaced by a remint. "none": unclaimed with no open claim (claim-token storage failed at mint, or it was consumed with no refresh).
    - `superseded_by` string, nullable: passport_id of the passport that superseded this one, when this passport was UNCLAIMED at the time of a remint with the same controller_id and agent_id. Null otherwise. A CLAIMED passport is never superseded automatically.
    - `supersedes` string[]: passport_id values this passport superseded at mint (prior unclaimed passports for the same controller_id and agent_id).
    - `protection_state` 'unprotected' | 'armed_no_channel' | 'protected' | 'frozen' | 'revoked': Sentinel protection summary: unprotected (not claimed or not armed), armed_no_channel (armed, no alert channel linked), protected (armed with a channel), frozen, or revoked.

## Other responses

- `400`: Invalid request body or passport_id.
- `401`: No WorkOSOwnerSession cookie or bearerAgentSession token was presented.
- `403`: claim_token_invalid: the claim token is wrong.
- `404`: no_pending_claim: this passport has no open claim to redeem.
- `409`: passport_already_owned: this passport is already claimed.
- `410`: passport_superseded: this passport was replaced by a remint while unclaimed.
- `429`: Too many claim attempts.

---

[API](https://skmtc.dev/flint/apis/flint-agent-transaction-control-api.md) · [All operations](https://skmtc.dev/flint/apis/flint-agent-transaction-control-api/llms.txt) · [OpenAPI document](https://skmtc.dev/flint/apis/flint-agent-transaction-control-api/revisions/eb5052b7b5dc?raw)
