API & Agent Onboarding

Use this guide only if you need to create the merchant and first API key entirely over the API.

If you can use the dashboard, do not start here. Create a test API key there and go straight to Accept Your First Payment.

The preferred setup flow is:

  1. POST /v1/onboarding/start
  2. POST /v1/onboarding/verify-email
  3. GET /v1/onboarding/state
  4. POST /v1/onboarding/advance as needed
  5. POST /v1/onboarding/api-key
  6. Switch to the normal /v1/... API

Merchant verification is optional at this stage. You can create the first API key before verification finishes.

Before You Start#

  • Use the public API for both sandbox and live work: https://api.withflintpay.com
  • Sandbox isolation comes from sandbox-bound flint_test_... keys, not from a shared global test tenant
  • Make sure you control the email address you use for verification
  • Be ready to read the emailed verification code
  • Keep the temporary verification_token only long enough to complete the verification step

This guide uses the /v1/onboarding/... state machine. The same flow handles ongoing compliance remediation after the first key exists: read state and advance again with a normal API key when new requirements come due.

Completing setup also provisions a default private sandbox for the merchant. After you mint the first test key, normal /v1/... requests against the public API run inside that sandbox automatically.

Onboarding endpoints are rate limited more aggressively than the standard /v1 resource API. If you receive 429, back off and retry.

A bot cannot complete this flow unless it can either read the verification email itself or hand the emailed code to a human. verification_token currently expires after 15 minutes. onboarding_session_token is setup-only and does not authenticate normal resource routes like /v1/orders.

Step 1: Start Setup#

Bash
curl -X POST https://api.withflintpay.com/v1/onboarding/start \
  -H "Content-Type: application/json" \
  -d '{
    "email": "owner@example.com",
    "first_name": "Jane",
    "last_name": "Doe"
  }'

Save data.verification_token. Flint emails a short-lived verification code to the requested email address.

Step 2: Verify Email#

Use the emailed code plus the returned verification_token:

Bash
curl -X POST https://api.withflintpay.com/v1/onboarding/verify-email \
  -H "Content-Type: application/json" \
  -d '{
    "verification_token": "devver_v1.c2FtcGxlLXZlcmlmaWNhdGlvbi10b2tlbg",
    "verification_code": "482193"
  }'

Save data.onboarding_session_token. At this point the Flint user and merchant exist, but you still do not have a normal API key.

JSON
{
  "data": {
    "onboarding_session_token": "devsess_v1.c2FtcGxlLWRldmVsb3Blci1zZXNzaW9uLXRva2Vu",
    "user": {
      "user_id": "usr_123",
      "default_merchant_id": "mer_123",
      "email": "owner@example.com",
      "status": "active"
    },
    "merchant": {
      "merchant_id": "mer_123",
      "status": "active",
      "onboarding_status": "not_started"
    },
    "default_sandbox_id": "test_01JQEXAMPLEDEFAULT12345678",
    "status": "merchant_ready",
    "merchant_created": true,
    "can_issue_api_key": true,
    "next_step": {
      "code": "check_onboarding_state",
      "owner": "agent",
      "surface": "api",
      "machine_completable": true,
      "submit_method": "GET",
      "submit_endpoint": "/v1/onboarding/state"
    }
  },
  "request_id": "7c9e2f4a-8b1d-4e3a-9f60-2d8c5b7a1e94"
}

At this point:

  • the Flint user exists
  • the merchant exists
  • a default private sandbox exists for test-mode work
  • the developer can log into the dashboard later with the same email
  • no normal API key exists yet

Step 3: Ask Flint For The Next Step#

Use the onboarding state machine instead of choosing between separate onboarding verbs yourself:

Bash
curl https://api.withflintpay.com/v1/onboarding/state \
  -H "Authorization: Bearer YOUR_ONBOARDING_SESSION_TOKEN"

Key response fields:

  • status
  • next_step
  • pending_steps
  • profile
  • requirements
  • document_requests
  • can_issue_api_key

The top-level status tells your agent what kind of work remains:

  • needs_input
  • needs_external_action
  • waiting_for_review
  • ready_for_api_key
  • complete

next_step is the primary action Flint wants next. Typical values include:

  • complete_business_profile
  • start_onboarding
  • complete_verification_step
  • create_api_key

Step 4: Advance Setup As Needed#

When Flint still needs more information, send it with POST /v1/onboarding/advance:

Bash
curl -X POST https://api.withflintpay.com/v1/onboarding/advance \
  -H "Content-Type: application/json" \
  -H "Authorization: Bearer YOUR_ONBOARDING_SESSION_TOKEN" \
  -H "Idempotency-Key: onboarding-advance-001" \
  -d '{
    "profile": {
      "support_email": "help@example.com",
      "website_url": "https://example.com"
    },
    "country": "US",
    "artifacts": [
      {
        "artifact_type": "account_token",
        "token": "tok_123"
      }
    ],
    "surface": "embedded"
  }'

Use this endpoint for:

  • Flint-owned profile fields
  • payment capability requests
  • tokenized verification artifacts collected client-side, sent as artifact_type plus token
  • asking Flint to continue and return an external verification action when needed

If the response comes back with status = "needs_external_action" and next_step.code = "complete_verification_step", hand next_step.external_action to a human browser: url for the hosted surface, or client_secret plus publishable_key for the embedded surface.

If the response comes back with status = "waiting_for_review", stop mutating and wait for review to finish.

Step 5: Mint The First External API Key#

Once GET /v1/onboarding/state returns status = "ready_for_api_key", create the first key:

Bash
curl -X POST https://api.withflintpay.com/v1/onboarding/api-key \
  -H "Content-Type: application/json" \
  -H "Authorization: Bearer YOUR_ONBOARDING_SESSION_TOKEN" \
  -d '{
    "name": "First backend integration"
  }'

This endpoint returns 201 Created. If you omit scopes, Flint applies the starter scope set. If you do send scopes, they must stay within that starter set during setup.

If you omit sandbox_id, Flint binds the first test key to the default sandbox automatically.

That starter scope set includes the permissions needed to manage sandboxes after setup.

Example response:

JSON
{
  "data": {
    "api_key_id": "key_123",
    "name": "First backend integration",
    "sandbox_id": "test_01JQEXAMPLEDEFAULT12345678",
    "key_prefix": "flint_test_abcd1234",
    "key_type": "external",
    "status": "active",
    "secret_key": "flint_test_0123456789abcdef0123456789abcdef0123456789abcdef0123456789abcdef"
  },
  "request_id": "5a3e9c7b-2d6f-4c4a-8b1e-0f7d4a9c2e65"
}

Store secret_key immediately. It is returned once.

After this step, stop treating the session as a setup workflow. New integrations should authenticate with the external API key, and future key management should happen through the normal /v1/api-keys resource API.

Step 6: Switch To The Normal Public API#

After you have the external API key:

Bash
curl https://api.withflintpay.com/v1/orders \
  -H "Authorization: Bearer YOUR_API_KEY"

Do not keep using onboarding_session_token for normal resource work. It is a setup token, not a normal API credential.

For Agents#

The clean agent loop is:

  1. POST /v1/onboarding/start
  2. wait for a human or mailbox integration to read the emailed code
  3. POST /v1/onboarding/verify-email
  4. GET /v1/onboarding/state
  5. POST /v1/onboarding/advance until Flint returns either waiting_for_review or ready_for_api_key
  6. if Flint returns complete_verification_step, open next_step.external_action for a human
  7. when Flint returns ready_for_api_key, call POST /v1/onboarding/api-key
  8. switch to the normal /v1/... API and /v1/openapi.json

Next Steps#

Rate this doc