Skip to navigation

Authentication

The Fluveo /v1 API authenticates with secret API keys, using the same schemes declared by the Stripe OpenAPI contract. Existing Stripe-style auth code works unchanged.

Secret keys

A secret key is a server-side credential. Both modes use one API hostname:

Key prefixEnvironmentBase URL
sk_test_...Testhttps://api.devfluveo.com
sk_live_...Productionhttps://api.fluveo.dev

Responses carry a livemode boolean so you can confirm which mode authenticated the request. Onboarding also issues pk_test_... for browser-side test integrations. Controlled BR setup may issue live keys after an active live binding exists, but public live /v1 admission remains disabled.

Key lifecycle

Keys are managed from the dashboard API keys page (and the first one is shown when you create your merchant).

  • Issue — “Create secret key” mints a new sk_test_ and shows the full key exactly once. Fluveo stores only a SHA-256 hash; the plaintext is never logged and can never be re-displayed.
  • Hint — after the show-once screen, a key is listed by a hint that keeps its full type+mode prefix plus the last four characters, e.g. sk_test_…a1b2. The hint preserves enough to tell test from live at a glance, but not enough to reconstruct the key.
  • Revoke — revoking a key is immediate and permanent; a revoked key is rejected on /v1. Revoked keys stay listed (with their hint and last-used time) for your audit trail. Propagation: a just-revoked key may keep working for up to 60 seconds while a cached resolution expires. Treat 60s as the worst-case window when rotating after a suspected leak.
  • Recover a lost key — there is no “reveal”. If you lose a key, create a new one and revoke the old one.

The two schemes

The /v1 API accepts either scheme. They are equivalent — pick whichever fits your HTTP client.

SchemeHow
HTTP Basic Authsecret key as the username, empty password: -u sk_test_...:
Bearer AuthAuthorization: Bearer sk_test_...

Docs and runnable examples prefer Basic Auth because it is the canonical curl form. Note the trailing colon in -u sk_test_...: — it sets an empty password so curl doesn’t prompt for one.

# Basic Auth (canonical)
curl https://api.devfluveo.com/v1/payment_intents \
-u sk_test_...: \
-d amount=4242 -d currency=usd
# Bearer Auth (equivalent)
curl https://api.devfluveo.com/v1/payment_intents \
-H "Authorization: Bearer sk_test_..." \
-d amount=4242 -d currency=usd

Secret keys vs. publishable keys

Publishable keys (pk_test_..., pk_live_...) are browser-side keys. They pair with a PaymentIntent’s client_secret so the customer’s browser can complete authentication directly — they are not valid for secret-key server operations and will be rejected on /v1 write calls.

KeySideUsed for
sk_test_ / sk_live_ServerAuthenticating /v1 API requests
pk_test_ / pk_live_BrowserClient-side confirmation with client_secret

The launch /v1 surface does not accept an api-key header — secret-key auth is the only supported scheme.

Keeping keys safe

  • Never expose a secret key in browser code, mobile apps, or a public repository. Anyone with sk_live_... can move real money. Use the publishable key + client_secret for anything client-side.
  • Use sandbox keys (sk_test_) everywhere except production. They run against the sandbox and can’t touch live funds.
  • Store keys in a secrets manager / environment variable, not in source.
  • Rotate a key from the dashboard if it may have leaked: create a new key, move your integration over, then revoke the old one. Revocation takes effect within 60 seconds (see Key lifecycle).

Authentication errors

A missing, invalid, or revoked key returns HTTP 401 with an authentication_error. The message never confirms whether a key once existed:

{
"error": {
"type": "authentication_error",
"message": "Invalid API Key provided."
}
}

If Fluveo cannot verify your key because authentication dependencies are temporarily unavailable, at capacity, or past their deadline, the response is 503 api_error. Retry with backoff using the same key; do not rotate it because of this response:

{
"error": {
"type": "api_error",
"message": "The request could not be completed because authentication is temporarily unavailable. Please try again shortly."
}
}

The 503 happens while the key is being checked, before Fluveo does any work for the request.

An internal authentication configuration or response-integrity failure returns 500 api_error with the message “The request could not be completed due to an internal error. Please try again or contact support.” The 500 can happen while the key is being checked, or later, after Fluveo has read the request (for example after ownership or idempotency checks), but always before any call to a payment processor. Neither refusal contains code or param, and neither sets Retry-After. The 503 carries Stripe-Should-Retry: true (nothing ran, so a retry is safe); the 500 carries no retry header. An invalid or revoked key remains a 401. These authentication responses apply to every region, including Brazil.

See Errors for the full error envelope and every error type.