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:
POST /v1/onboarding/startPOST /v1/onboarding/verify-emailGET /v1/onboarding/statePOST /v1/onboarding/advanceas neededPOST /v1/onboarding/api-key- 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_tokenonly 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#
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:
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.
{
"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:
curl https://api.withflintpay.com/v1/onboarding/state \
-H "Authorization: Bearer YOUR_ONBOARDING_SESSION_TOKEN"
Key response fields:
statusnext_steppending_stepsprofilerequirementsdocument_requestscan_issue_api_key
The top-level status tells your agent what kind of work remains:
needs_inputneeds_external_actionwaiting_for_reviewready_for_api_keycomplete
next_step is the primary action Flint wants next. Typical values include:
complete_business_profilestart_onboardingcomplete_verification_stepcreate_api_key
Step 4: Advance Setup As Needed#
When Flint still needs more information, send it with POST /v1/onboarding/advance:
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_typeplustoken - 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:
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:
{
"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:
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:
POST /v1/onboarding/start- wait for a human or mailbox integration to read the emailed code
POST /v1/onboarding/verify-emailGET /v1/onboarding/statePOST /v1/onboarding/advanceuntil Flint returns eitherwaiting_for_revieworready_for_api_key- if Flint returns
complete_verification_step, opennext_step.external_actionfor a human - when Flint returns
ready_for_api_key, callPOST /v1/onboarding/api-key - switch to the normal
/v1/...API and/v1/openapi.json
