Customer sessions

A customer session is a buyer-scoped credential. Your backend authenticates the buyer however you already do, then asks Flint for a session bound to one customer. The session secret is the only credential accepted by /v1/me, and the customer it names is the only customer those endpoints will read or write.

Creating a session needs a secret API key with customers.sessions.write. Everything the session can then do is fixed by Flint, not chosen by the caller: there is no scope argument, and no way to widen it.

Three windows#

One create call returns up to three credentials, each with its own lifetime.

CredentialFieldDefaultRange
account_urlaccount_url_expires_in_seconds15 minutes1 minute to 1 hour
secretexpires_in_seconds1 hour5 minutes to 24 hours
refresh_tokenrefresh_expires_in_seconds7 days1 hour to 30 days

account_url is returned only when the merchant uses Flint's hosted account. It is a one-time link that signs the buyer in, so it is the shortest-lived of the three and belongs in a redirect, never in stored state.

secret (flint_cses_) is the working credential. Send it as Authorization: Bearer.

refresh_token (flint_cref_) buys a new pair when the secret expires.

Bash
curl -X POST https://api.withflintpay.com/v1/customer-sessions \
  -H "Authorization: Bearer $FLINT_SECRET_KEY" \
  -H "Content-Type: application/json" \
  -d '{"customer_id": "cus_01JQEXAMPLE0000000000000000"}'

Refresh rotates both credentials#

POST /v1/customer-sessions/refresh takes the refresh token and nothing else. It needs no API key, which is what lets a buyer-facing backend session keep itself alive without holding your secret key on that path. It requires an Idempotency-Key.

Every refresh invalidates the token it consumed and returns a new secret and a new refresh token. Store the newest pair and serialize concurrent refreshes, because two parallel refreshes with the same token means the second one is a reuse.

Presenting a refresh token that has already been rotated away revokes the entire session family and returns CUSTOMER_SESSION_REFRESH_REUSED. That is the intended response to a stolen token, so treat it as a signal rather than a transient failure: sign the buyer out and re-authenticate them. Do not retry.

ErrorMeaningWhat to do
CUSTOMER_SESSION_EXPIREDThe secret aged outRefresh, then retry the call
CUSTOMER_SESSION_REFRESH_EXPIREDThe refresh token aged outRe-authenticate the buyer and create a new session
CUSTOMER_SESSION_REFRESH_REUSEDA rotated token was presented againRe-authenticate the buyer. The family is already revoked
INVALID_CUSTOMER_SESSIONThe credential is malformed or unknownRe-authenticate the buyer
CUSTOMER_SESSION_REQUIREDA /v1/me call arrived without a session secretSend the secret as a bearer token

Revocation#

Revoke one session when a buyer signs out of one device. Revoke every session for a customer when the buyer changes their password, when you close their account, or when you suspect a takeover.

Bash
curl -X POST https://api.withflintpay.com/v1/customers/cus_01JQEXAMPLE0000000000000000/sessions/revoke \
  -H "Authorization: Bearer $FLINT_SECRET_KEY"

Revoking customer sessions does not sign the buyer out of Flint's own hosted account, and signing out of the hosted account does not revoke your customer sessions. The two are independent.

Keep the secret on your server#

A customer session secret is a server-side credential with the same handling rules as an API key. It does not belong in browser code, a mobile bundle, a URL, or a log. The browser talks to your backend, and your backend talks to Flint.

Flint does not currently accept a customer session from a public client.

Create a customer session#

POST/v1/customer-sessionsIdempotentRequires scope: customers.sessions.write

Mints a server-side, customer-scoped credential after the merchant has authenticated the buyer. Secret and refresh_token are returned only in this response. Flint-hosted merchants also receive a separately expiring one-time account_url.

Request body
account_url_expires_in_secondsinteger
customer_idstringrequired
expires_in_secondsinteger
refresh_expires_in_secondsinteger
Response · 201
dataobjectrequired
metaobject
request_idstring

Error codes

AUTH_REQUIREDCUSTOMER_SESSIONS_UNAVAILABLECUSTOMER_SESSION_NOT_FOUNDIDEMPOTENCY_KEY_IN_PROGRESSIDEMPOTENCY_KEY_REUSEDINSUFFICIENT_SCOPEINVALID_CUSTOMER_SESSIONINVALID_REQUESTRATE_LIMIT_EXCEEDEDRESOURCE_NOT_FOUNDSERVICE_UNAVAILABLE
Bash
curl -X POST https://api.withflintpay.com/v1/customer-sessions \
  -H "Authorization: Bearer YOUR_API_KEY" \
  -H "Content-Type: application/json" \
  -H "Idempotency-Key: a-unique-key" \
  -d '{
    "customer_id": ""
  }'

Revoke a customer session#

POST/v1/customer-sessions/{customer_session_id}/revokeIdempotentRequires scope: customers.sessions.write

Revokes one customer session. This does not revoke an independent Flint Account buyer session.

Path parameters
customer_session_idstringrequired

Flint customer session ID.

Response · 200
dataobjectrequired
metaobject
request_idstring

Error codes

AUTH_REQUIREDCUSTOMER_SESSIONS_UNAVAILABLECUSTOMER_SESSION_NOT_FOUNDIDEMPOTENCY_KEY_IN_PROGRESSIDEMPOTENCY_KEY_REUSEDINSUFFICIENT_SCOPEINVALID_REQUESTRATE_LIMIT_EXCEEDEDRESOURCE_NOT_FOUNDSERVICE_UNAVAILABLE
Bash
curl -X POST https://api.withflintpay.com/v1/customer-sessions/{customer_session_id}/revoke \
  -H "Authorization: Bearer YOUR_API_KEY"

Refresh a customer session#

POST/v1/customer-sessions/refreshIdempotentNo API key required

Rotates a customer session secret and refresh token without a merchant API key. Reusing a rotated refresh token revokes the session family.

Request body
refresh_tokenstringrequired
Response · 200
dataobjectrequired
metaobject
request_idstring

Error codes

AUTH_REQUIREDCUSTOMER_SESSIONS_UNAVAILABLECUSTOMER_SESSION_REFRESH_EXPIREDCUSTOMER_SESSION_REFRESH_REUSEDIDEMPOTENCY_KEY_IN_PROGRESSIDEMPOTENCY_KEY_REQUIREDIDEMPOTENCY_KEY_REUSEDINVALID_REQUESTRATE_LIMIT_EXCEEDEDSERVICE_UNAVAILABLE
Bash
curl -X POST https://api.withflintpay.com/v1/customer-sessions/refresh \
  -H "Authorization: Bearer YOUR_API_KEY" \
  -H "Content-Type: application/json" \
  -H "Idempotency-Key: a-unique-key" \
  -d '{
    "refresh_token": ""
  }'

Revoke a customer's sessions#

POST/v1/customers/{customer_id}/sessions/revokeIdempotentRequires scope: customers.sessions.write

Revokes every customer session for one customer in the selected merchant environment. Flint Account buyer sessions remain independent.

Path parameters
customer_idstringrequired

Flint customer ID.

Response · 200
dataobjectrequired
metaobject
request_idstring

Error codes

AUTH_REQUIREDCUSTOMER_SESSIONS_UNAVAILABLECUSTOMER_SESSION_NOT_FOUNDIDEMPOTENCY_KEY_IN_PROGRESSIDEMPOTENCY_KEY_REUSEDINSUFFICIENT_SCOPEINVALID_REQUESTRATE_LIMIT_EXCEEDEDRESOURCE_NOT_FOUNDSERVICE_UNAVAILABLE
Bash
curl -X POST https://api.withflintpay.com/v1/customers/cus_123/sessions/revoke \
  -H "Authorization: Bearer YOUR_API_KEY"
Rate this doc