Skip to content
OpenRelay is in early access, and the /v1 API is stable. New capabilities ship in the changelog.
API ReferenceBilling and usageBilling

Start saving a card (Stripe SetupIntent)

Creates a Stripe SetupIntent to save a card and returns its client secret, the publishable key, and bankCheck, true when the bank must confirm the card. The inline Elements form confirms the client secret. The dashboard's card form sends its device identification and a Turnstile token as optional query parameters, and the card save is judged on them: a device that puts the account on a verification hold gets 403 ACCOUNT_PENDING_VERIFICATION, or 403 VERIFICATION_UNAVAILABLE when the hold could not be recorded. Anything else that looks wrong about the request or the account (no verified device, a missing or failed Turnstile token, a new account, a recent failed card, and more) asks the card's bank to confirm the card with 3D Secure, and bankCheck says so. The operation takes no request body, so a bare POST (the CLI, the MCP tool) still works and its card always needs the bank's confirmation. After stripe.confirmSetup succeeds, call the complete operation to learn whether the card was kept.

Required permission

Requires the billing.manage permission. See Permissions for the roles and API key permissions that include it.

Command line

The orl CLI wraps this endpoint:

orl billing setup-intent create
POST
/v1/orgs/{orgId}/billing/setup-intent

Authorization

apiKey
headerAuthorizationBearer <token>

OpenRelay API key. Send it as Authorization: Bearer or_… (legacy vl_… keys still work).

Path Parameters

orgId*string

Query Parameters

deviceFingerprint?string

Fingerprint visitor id from the dashboard's card form. Verified against deviceEventId before it is used.

Lengthlength <= 128
deviceEventId?string

Fingerprint event id of the identification that produced deviceFingerprint.

Lengthlength <= 128
turnstileToken?string

Cloudflare Turnstile token from the card form's widget, rendered with action card_save. Verified with Cloudflare once; a token is single use.

Lengthlength <= 2048

Response Body

SetupIntent client secret + publishable key

application/json
  1. response
clientSecret*string
publishableKey*string
bankCheck*boolean

True when the card's bank is asked to confirm this card with 3D Secure (a challenge in the bank's app or page). A card the bank does not confirm is not kept.

Example Request
curl -X POST 'https://api.openrelay.inc/v1/orgs/string/billing/setup-intent'
Example Response
{  "clientSecret": "string",  "publishableKey": "string",  "bankCheck": true}