Onboarding

The onboarding API creates a Flint account from an email address and makes the first sandbox API key available after email verification, without sending the developer through the Flint dashboard. It also drives embedded merchant onboarding as a state machine: start with an email, verify it to receive an onboarding_session_token, then read GET /v1/onboarding/state. Submit machine-completable work using next_step.submit_method, next_step.submit_endpoint, and required_fields. Profile and account intent go to POST /v1/onboarding/advance. Browser and review steps omit the submit method and endpoint. When next_step.launch requires a human browser, mint credentials separately with POST /v1/merchant-account-sessions, render the returned embedded components, then poll state.

next_step.launch.endpoint uses the same public API base as next_step.submit_endpoint: absolute when configured, relative otherwise.

The onboarding_session_token is a sandbox-only setup credential. On GET /v1/onboarding/state, POST /v1/onboarding/advance, and POST /v1/merchant-account-sessions, a session request without sandbox_id targets the merchant's default sandbox, and sandbox_id can name another sandbox of the same merchant. The session never reaches the live account. If the merchant has no default sandbox, these requests return SANDBOX_SELECTION_REQUIRED. The same routes also accept an API key: a sandbox key reaches its sandbox, and a live key created in the dashboard drives live onboarding and later remediation with sandbox_id omitted. The initial key is sandbox-bound and can be issued while provider verification is still outstanding. Payment and payout operations stay gated by their requested capabilities. Browser exit is never completion. State and readiness are backend-observed, pending_verification means wait, and merchant-account-session refresh uses POST /v1/merchant-account-sessions/refresh with the latest signed launch_token.

When no onboarding actions remain and the first key can be issued, status is ready_for_api_key with create_api_key as next_step, even if review is pending or onboarding is complete. After the key exists, status reflects review or completion.

The merchant's onboarding_status stays completed once reached, even when Stripe later asks for more details. Read requirements and next_step to find work that is due after completion.

The create_api_key action uses submit_method: "POST" and lists name in required_fields. POST /v1/onboarding/api-key accepts an optional sandbox_id in the JSON body or query string, and a non-empty body value takes precedence. Its returned submit endpoint includes the query parameter when a sandbox is selected. Omit both values to use the default sandbox.

POST /v1/onboarding/start sends a code and returns a verification token. Each token allows five incorrect code attempts; later attempts return VERIFICATION_ATTEMPTS_EXCEEDED. Correct codes do not count against either limit, including retries with merchant_id after 409 MERCHANT_SELECTION_REQUIRED or after a server error. Start again with a new idempotency key to send a new code and get a new token. After 20 incorrect codes per email in one hour, start and verify return 429 RATE_LIMIT_EXCEEDED with Retry-After.

POST /v1/onboarding/verify-email returns onboarding_session_expires_at, the UTC expiry of the 24-hour session, and default_sandbox_id, the sandbox the session targets by default. The session cannot be refreshed; verify the email again to get a new one. Its can_issue_api_key is true when the merchant has no external API key and a default sandbox exists. merchant_created tells you whether this request created the merchant. Read GET /v1/onboarding/state for the workflow status and available actions.

If verification returns 503 IDENTITY_UNAVAILABLE, retry after a short delay. For 500 IDENTITY_RESOLUTION_FAILED, contact Flint support. An email that already has a Flint account returns 409 EMAIL_ALREADY_LINKED, and an account that already issued its first key returns 409 INITIAL_API_KEY_ALREADY_CREATED from POST /v1/onboarding/api-key. In both cases, sign in with flint login or the dashboard instead of signing up again.

Note:

The API and agent onboarding guide walks through the full state machine, including document handling and first-key issuance.

Local development with the CLI#

If you already have a Flint account, use browser login and verify your setup:

Shell
flint login
flint doctor

Confirm the terminal code in your browser, choose your merchant and sandbox, and approve the requested permissions. The CLI refreshes access automatically. Use flint login --no-open to open the link yourself, --profile NAME for another profile, and --live for explicit production access. flint logout --confirm revokes the OAuth session. See the CLI guide for session lifetimes and revocation.

Use flint signup to create an account from the terminal, flint auth import for an existing API key, or FLINT_API_KEY for CI.

Create merchant account session#

POST/v1/merchant-account-sessionsIdempotent

Requires scope merchants.account_sessions.write

Creates an embedded browser handoff for one or more allowlisted account components. An onboarding session is limited to the merchant's default sandbox unless sandbox_id in the JSON body names another sandbox of the same merchant. Live onboarding requires a live API key.

Request body

collection_strategyenum
  • upfront
  • incremental
componentsarray of enumRequired
  • account_onboarding
  • account_management
  • payouts
  • balances
  • tax_documents
  • notification_banner
future_requirementsenum
  • omit
  • include
sandbox_idstring
targeted_requirement_idsarray of string

Response · 201

dataobjectRequired
metaobject
request_idstring
curl -X POST https://api.withflintpay.com/v1/merchant-account-sessions \
  -H "Flint-Version: 2026-09-07" \
  -H "Authorization: Bearer YOUR_API_KEY" \
  -H "Content-Type: application/json" \
  -H "Idempotency-Key: a-unique-key" \
  -d '{
    "collection_strategy": "upfront",
    "components": [
      "account_onboarding"
    ],
    "future_requirements": "include"
  }'

Refresh merchant account session#

POST/v1/merchant-account-sessions/refreshIdempotent

Requires scope merchants.account_sessions.write

Creates a fresh provider session from a signed launch token after rechecking the authenticated principal, merchant environment, account controller, and component grant. An onboarding session can refresh only sandbox launch tokens created by the same user with an onboarding session. The sandbox is pinned by the launch token, using the merchant's default sandbox unless sandbox_id named another sandbox of the same merchant at creation. Live onboarding requires a live API key, and refresh requires the same API key that created the launch token.

Request body

launch_tokenstringRequired

Response · 201

Same response as Create merchant account session.

curl -X POST https://api.withflintpay.com/v1/merchant-account-sessions/refresh \
  -H "Flint-Version: 2026-09-07" \
  -H "Authorization: Bearer YOUR_API_KEY" \
  -H "Content-Type: application/json" \
  -H "Idempotency-Key: a-unique-key" \
  -d '{
    "launch_token": "aslaunch_v1.example"
  }'

Advance onboarding flow#

POST/v1/onboarding/advanceIdempotent

Requires scope merchants.onboarding.write

Submits whatever the caller currently knows, re-evaluates onboarding, reconciles onboarding requirements, and returns the next step in the consolidated onboarding state machine. Send an empty JSON object when the current next_step only asks to refresh onboarding requirements. An onboarding session is limited to the merchant's default sandbox unless sandbox_id names another sandbox of the same merchant. Live onboarding requires a live API key.

Query parameters

sandbox_idstring

Optional sandbox to bind when advancing test-mode onboarding. The returned next_step.submit_endpoint includes this parameter when needed.

Request body

countryenum

ISO 3166-1 alpha-2 country code.

  • US
profileobject
requested_capabilitiesone of

Exact initial Flint capability set. Include accept_card_payments and receive_payouts together. Optionally include accept_ach_debit_payments, or omit the field to use the card and payout default set.

sandbox_idstring

Response · 200

dataobjectRequired
metaobject
request_idstring
curl -X POST https://api.withflintpay.com/v1/onboarding/advance \
  -H "Flint-Version: 2026-09-07" \
  -H "Authorization: Bearer YOUR_API_KEY" \
  -H "Content-Type: application/json" \
  -H "Idempotency-Key: a-unique-key" \
  -d '{
    "country": "US",
    "profile": {
      "support_email": "help@example.com",
      "website_url": "https://withflintpay.com"
    },
    "requested_capabilities": [
      "accept_card_payments",
      "receive_payouts"
    ]
  }'

Create onboarding API key#

POST/v1/onboarding/api-keyIdempotent

Requires an onboarding session

Creates the first long-lived sandbox API key. An onboarding session is limited to the merchant's default sandbox unless sandbox_id names another sandbox of the same merchant. Live onboarding requires a live API key created in the dashboard.

Query parameters

sandbox_idstring

Optional sandbox to bind the initial key to. The returned create_api_key submit_endpoint includes this parameter when needed.

Request body

namestringRequired
sandbox_idstring
scopesarray of string

Response · 201

dataobjectRequired
metaobject
request_idstring
curl -X POST https://api.withflintpay.com/v1/onboarding/api-key \
  -H "Flint-Version: 2026-09-07" \
  -H "Authorization: Bearer YOUR_API_KEY" \
  -H "Content-Type: application/json" \
  -H "Idempotency-Key: a-unique-key" \
  -d '{
    "name": "First backend integration",
    "scopes": [
      "commerce.orders.read",
      "commerce.orders.write",
      "customers.read",
      "customers.write"
    ]
  }'

Start onboarding flow#

POST/v1/onboarding/startIdempotent

No API key required

Starts the consolidated onboarding flow by emailing a short-lived verification code and returning a temporary verification token.

Request body

emailstringRequired
first_namestringRequired
last_namestringRequired

Response · 200

dataobjectRequired
metaobject
request_idstring
curl -X POST https://api.withflintpay.com/v1/onboarding/start \
  -H "Flint-Version: 2026-09-07" \
  -H "Authorization: Bearer YOUR_API_KEY" \
  -H "Content-Type: application/json" \
  -H "Idempotency-Key: a-unique-key" \
  -d '{
    "email": "owner@example.com",
    "first_name": "Jane",
    "last_name": "Doe"
  }'
curl https://api.withflintpay.com/v1/onboarding/state \
  -H "Flint-Version: 2026-09-07" \
  -H "Authorization: Bearer YOUR_API_KEY"
JSON
{
  "data": {
    "can_issue_api_key": true,
    "country": "US",
    "default_sandbox_id": "test_01JQEXAMPLEDEFAULT12345678",
    "merchant_id": "mer_123",
    "next_step": {
      "code": "complete_verification_step",
      "launch": {
        "component": "account_onboarding",
        "endpoint": "/v1/merchant-account-sessions",
        "method": "POST",
        "recommended_policy": {
          "collection_strategy": "upfront",
          "future_requirements": "include"
        },
        "sandbox_id": "test_01JQEXAMPLEDEFAULT12345678"
      },
      "machine_completable": false,
      "owner": "human"
    },
    "profile": {
      "email": "owner@example.com",
      "support_email": "help@example.com",
      "support_phone": "+14155552671",
      "support_url": "https://example.com/support",
      "website_url": "https://withflintpay.com"
    },
    "requested_capabilities": [
      "accept_card_payments",
      "receive_payouts"
    ],
    "requirements": {
      "current_deadline_at": "2026-04-01T00:00:00Z",
      "currently_due": [
        "merchant_category_code",
        "business_website"
      ],
      "eventually_due": [
        "representative_first_name"
      ]
    },
    "status": "needs_external_action"
  },
  "request_id": "bce56cba-0827-44aa-bb56-4f200ba15ee6"
}

Verify onboarding email#

POST/v1/onboarding/verify-emailIdempotent

No API key required

Verifies the emailed code, provisions the Flint user and merchant if needed, and returns an onboarding session token. The token expires at onboarding_session_expires_at and cannot be refreshed. Verify the email again to get a new one.

Request body

merchant_idstring
verification_codestringRequired
verification_tokenstringRequired

Response · 200

dataobjectRequired
metaobject
request_idstring
curl -X POST https://api.withflintpay.com/v1/onboarding/verify-email \
  -H "Flint-Version: 2026-09-07" \
  -H "Authorization: Bearer YOUR_API_KEY" \
  -H "Content-Type: application/json" \
  -H "Idempotency-Key: a-unique-key" \
  -d '{
    "verification_code": "482193",
    "verification_token": "example"
  }'

Was this helpful?