Developer Setup
Use the setup surface when you do not have a Flint API key yet.
Most developers should not start here. If you can use the dashboard, create a test API key there and go to Quickstart.
The preferred setup flow is:
POST /v1/setup/startPOST /v1/setup/verify-emailGET /v1/setup/statePOST /v1/setup/advanceas neededPOST /v1/setup/api-key- Switch to the normal
/v1/...API with that API key
developer_session_token is a short-lived setup token. It works on setup routes under /v1/setup/... and onboarding routes under /v1/onboarding/.... It does not authenticate normal resource requests like /v1/orders.
Verification is email-gated. Agents need either a human-in-the-loop or mailbox access to read the emailed code. verification_token currently expires after 15 minutes, and developer_session_token is currently minted for 24 hours.
Completing setup provisions a default private sandbox for the merchant. After you mint the first test key, normal /v1/... requests on the public API run inside that sandbox automatically. See Sandboxes for sandbox management.
Methods
Preferred setup flow
/v1/setup/startStart setup by emailing a verification code and returning a temporary verification token.
/v1/setup/verify-emailVerify the emailed code, provision the Flint user and merchant if needed, and return a developer_session_token.
/v1/setup/stateGet the current setup state machine, including the primary next step for an agent or human.
/v1/setup/advanceSubmit whatever you currently know, re-evaluate onboarding, and return the next setup step.
/v1/setup/api-keyCreate the first external API key for the current setup session.
Auth Model
Before you have an API key
POST /v1/setup/startrequires no authPOST /v1/setup/verify-emailrequires no auth, but it does require the emailed verification code and verification token
After verification
Use the returned token as:
Authorization: Bearer <developer_session_token>
You can also send:
X-Developer-Session-Token: <developer_session_token>
Authorization: Bearer ... is the recommended default.
Sandbox-management routes under /v1/developer/sandboxes/... accept the same developer_session_token during setup or a normal external API key afterward.
Rate Limits
The setup surface has stricter anti-abuse rate limits than the normal /v1 resource API.
POST /v1/setup/startis tightly limitedPOST /v1/setup/verify-emailis tightly limitedPOST /v1/setup/api-keyis also rate limited
GET /v1/setup/state and POST /v1/setup/advance still use setup auth, but they follow the normal authenticated route-class budgets after verification.
If you receive 429 rate_limit_error, back off and retry later.
If you need higher setup throughput for a legitimate integration or agent workflow, contact support@withflintpay.com.
For the current default limits across both setup and the broader public API, see Rate Limits.
Start Setup
Request Fields
emailstringrequiredDeveloper email address. Flint emails a short-lived verification code here.
first_namestringrequiredDeveloper first name.
last_namestringrequiredDeveloper last name.
Example
{
"email": "owner@example.com",
"first_name": "Jane",
"last_name": "Doe"
}
{
"data": {
"verification_started": true,
"verification_token": "devver_v1.c2FtcGxlLXZlcmlmaWNhdGlvbi10b2tlbg",
"expires_at": "2026-03-18T20:00:00Z"
},
"request_id": "req_123"
}
Store verification_token temporarily. You send it back with the emailed verification code in the next step.
Verify Setup Email
Request Fields
verification_tokenstringrequiredTemporary token returned by /v1/setup/start.
verification_codestringrequiredShort-lived code emailed to the developer.
Example
{
"verification_token": "devver_v1.c2FtcGxlLXZlcmlmaWNhdGlvbi10b2tlbg",
"verification_code": "482193"
}
{
"data": {
"developer_session_token": "devsess_v1.c2FtcGxlLWRldmVsb3Blci1zZXNzaW9uLXRva2Vu",
"user": {
"user_id": "usr_123",
"first_name": "Jane",
"last_name": "Doe",
"email": "owner@example.com",
"default_merchant_id": "mer_123",
"status": "active",
"created_at": "2026-03-18T19:45:00Z",
"updated_at": "2026-03-18T19:45:00Z"
},
"merchant": {
"merchant_id": "mer_123",
"email": "owner@example.com",
"status": "active",
"onboarding_status": "not_started",
"charges_enabled": false,
"payouts_enabled": false,
"details_submitted": false,
"created_at": "2026-03-18T19:45:00Z",
"updated_at": "2026-03-18T19:45:00Z"
},
"setup_state": "merchant_ready",
"merchant_created": true,
"default_sandbox_id": "test_01JQEXAMPLEDEFAULT12345678",
"charges_enabled": false,
"payouts_enabled": false,
"details_submitted": false,
"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": "req_123"
}
user.default_merchant_id is the setup default merchant selection for that developer identity.
Get Setup State
GET /v1/setup/state is the agent-friendly state machine surface. Instead of choosing between separate onboarding verbs, ask Flint what the next step is.
Key response fields:
setup_statestatusnext_steppending_stepsprofileproviderprovider_sessionrequirementscan_issue_api_key
Example:
{
"data": {
"merchant_id": "mer_123",
"merchant_created": true,
"email_verified": true,
"default_sandbox_id": "test_01JQEXAMPLEDEFAULT12345678",
"can_issue_api_key": true,
"setup_state": "onboarding_available",
"status": "needs_external_action",
"next_step": {
"code": "complete_verification_step",
"owner": "human",
"surface": "embedded",
"machine_completable": false,
"external_action": {
"provider": "stripe",
"kind": "embedded",
"client_secret": "seti_123"
}
},
"pending_steps": [],
"profile": {
"email": "owner@example.com"
},
"requirements": {
"currently_due": [
{ "field": "external_account" }
]
},
"charges_enabled": false,
"payouts_enabled": false,
"details_submitted": false
},
"request_id": "req_123"
}
Top-level setup status values are:
needs_inputneeds_external_actionwaiting_for_reviewready_for_api_keycomplete
Advance Setup
POST /v1/setup/advance is the main mutating step. Send whatever you currently know and let Flint decide what should happen next.
Request Fields
profileobjectFlint-owned merchant profile fields such as email, support_email, support_phone, support_url, and website_url.
countrystringMerchant country for processor onboarding.
capability_requestsarrayRequested processor capabilities such as card_payments or transfers.
artifactsarrayProvider-specific sensitive artifacts collected outside Flint, such as Stripe account_token.
surfacestringPreferred verification surface when Flint needs a provider session. Supported values are hosted and embedded.
return_urlstringReturn URL for hosted provider onboarding.
refresh_urlstringRefresh URL for hosted provider onboarding.
sandbox_idstringOptional sandbox to bind when evaluating test-mode onboarding.
include_future_requirementsbooleanInclude future provider requirements when Flint evaluates the next step.
Example
curl -X POST https://api.withflintpay.com/v1/setup/advance \
-H "Content-Type: application/json" \
-H "Authorization: Bearer YOUR_DEVELOPER_SESSION_TOKEN" \
-H "Idempotency-Key: setup-advance-001" \
-d '{
"profile": {
"support_email": "help@example.com",
"website_url": "https://example.com"
},
"country": "US",
"artifacts": [
{
"provider": "stripe",
"type": "account_token",
"token": "tok_123"
}
],
"surface": "embedded"
}'
If Flint still needs human completion, the response includes next_step.code = "complete_verification_step" and a provider_session.
Create Setup API Key
Create the first external API key for the current setup session.
Request Fields
namestringrequiredHuman-readable name for the first API key.
sandbox_idstringOptional sandbox binding for the first test key. If omitted, Flint binds the key to the default sandbox automatically.
scopesarrayOptional scope list. If omitted, Flint applies the starter scope set. If provided, every scope must stay within that starter set during setup.
Example response:
{
"data": {
"api_key_id": "key_123",
"name": "First backend integration",
"key_prefix": "flint_test_abcd1234",
"key_type": "external",
"status": "active",
"secret_key": "flint_test_0123456789abcdef0123456789abcdef0123456789abcdef0123456789abcdef"
},
"request_id": "req_123"
}
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.
