Skip to main content
POST
/
auth
/
exchange
const response = await fetch(
  "https://firespark.vercel.app/api/storefront/v1/auth/exchange",
  {
    method: "POST",
    headers: { "Content-Type": "application/json" },
    body: JSON.stringify({
      grant_type: "urn:ietf:params:oauth:grant-type:token-exchange",
      subject_token: idToken,
      subject_token_type: "urn:ietf:params:oauth:token-type:id_token"
    })
  }
);

const { access_token } = await response.json();
{
  "access_token": "eyJhbGciOiJSUzI1NiIsInR5cCI6IkpXVCJ9...",
  "issued_token_type": "urn:ietf:params:oauth:token-type:access_token",
  "token_type": "Bearer",
  "expires_in": 3600
}
The Storefront API supports OAuth 2.0 Token Exchange (RFC 8693) for public clients. Your app, web, or kiosk sends the customer’s OIDC ID token and receives a short-lived Fire spark access token in return. No client_id or client_secret is required. Fire spark reads the ID token’s iss and aud claims, finds the merchant’s configured identity provider, validates the token against that provider’s JWKS, and issues an access token bound to the customer identified by the sub claim.

When to use token exchange

Use this endpoint when:
  • Customers sign in with an OIDC-compliant identity provider on the client
  • Your channel needs to call the Storefront API on behalf of that customer
  • You want Fire spark to validate identity and limit API access to a single customer
Send the ID token, not opaque access tokens or API keys. ID tokens are JWTs that identify the authenticated user through standard claims: sub, iss, and aud. Every OIDC-compliant provider exposes them after sign-in.

Prerequisites

  1. Configure your identity provider in the Fire spark dashboard for your merchant.
  2. Authenticate the customer on the client and obtain a fresh OIDC ID token from your provider.

How it works

1

Customer signs in on the client

Your app completes sign-in with your OIDC provider using that provider’s client SDK. Retrieve the ID token the provider issues for the authenticated session.
2

Client sends the ID token

Your client calls POST /auth/exchange with the ID token as subject_token. No merchant ID or API secret is needed in the request.
3

Fire spark resolves the merchant and validates the token

Fire spark matches the token’s iss and aud to the provider configured for a merchant, verifies the signature and expiration using that provider’s JWKS, and reads sub as the customer’s external identifier.
4

Client uses the Fire spark access token

Fire spark returns an access token for that customer. Use it in the Authorization header for Storefront API requests.

Obtain the ID token

Each provider exposes the ID token through its client SDK. Use the method that returns the JWT ID token for the current session.
import { useAuth0 } from "@auth0/auth0-react";

const { getIdTokenClaims } = useAuth0();
const claims = await getIdTokenClaims();
const idToken = claims?.__raw;

Token exchange request

Send a POST request to /auth/exchange with Content-Type: application/json. The request body is the same regardless of provider.
const response = await fetch(
  "https://firespark.vercel.app/api/storefront/v1/auth/exchange",
  {
    method: "POST",
    headers: { "Content-Type": "application/json" },
    body: JSON.stringify({
      grant_type: "urn:ietf:params:oauth:grant-type:token-exchange",
      subject_token: idToken,
      subject_token_type: "urn:ietf:params:oauth:token-type:id_token"
    })
  }
);

const { access_token } = await response.json();
{
  "access_token": "eyJhbGciOiJSUzI1NiIsInR5cCI6IkpXVCJ9...",
  "issued_token_type": "urn:ietf:params:oauth:token-type:access_token",
  "token_type": "Bearer",
  "expires_in": 3600
}

Request body

FieldRequiredDescription
grant_typeYesMust be urn:ietf:params:oauth:grant-type:token-exchange.
subject_tokenYesThe OIDC ID token from your identity provider for the signed-in customer.
subject_token_typeYesMust be urn:ietf:params:oauth:token-type:id_token. Opaque access tokens are not accepted.

How Fire spark identifies the merchant

Fire spark does not require a merchant ID in the request. It inspects the ID token claims:
ClaimPurpose
issIdentifies the identity provider issuer URL.
audIdentifies the provider project, realm, or app client.
subStable customer identifier used to resolve or create the customer record.
Fire spark matches iss and aud against the provider configuration registered for a merchant, then validates the token signature before issuing an access token.

Supported providers

Any OIDC-compliant provider that issues JWT ID tokens with a discoverable JWKS endpoint is supported. Register the provider in the dashboard before going to production.
ProviderTypical iss formatHow to get the ID token
Auth0https://{tenant}.auth0.com/getIdTokenClaims().__raw
Clerkhttps://{your-clerk-domain}getToken()
Supabasehttps://{project-ref}.supabase.co/auth/v1getSession().access_token
Firebasehttps://securetoken.google.com/{projectId}getIdToken()
Amazon Cognitohttps://cognito-idp.{region}.amazonaws.com/{userPoolId}fetchAuthSession().tokens.idToken
Oktahttps://{okta-domain}/oauth2/{authorizationServerId}tokenManager.get("idToken")
Keycloakhttps://{host}/realms/{realm}keycloak.idToken
The iss and aud values must match exactly what Fire spark has on file for your merchant. Copy them from a decoded ID token when configuring the provider in the dashboard.

Use the exchanged token

Include the Fire spark access token in the Authorization header. The token only grants access to resources for the customer linked to the original sub claim.
curl "https://firespark.vercel.app/api/storefront/v1/customers/me" \
  -H "Authorization: Bearer FIRESPARK_ACCESS_TOKEN"
Re-exchange when your provider refreshes the ID token. Fire spark access tokens are short-lived and are not a replacement for keeping the IdP session current.

Security properties

  • Public client profile: Designed for mobile and web clients. No confidential credentials are sent or stored in the app.
  • ID token only: Only OIDC JWT ID tokens are accepted as subject_token. Opaque or provider API tokens are rejected.
  • Cryptographic validation: Signature, iss, aud, and exp are verified against the merchant’s registered provider before any customer data is returned.
  • Customer isolation: The issued access token is bound to the sub from the ID token. Requests for other customers are rejected.
  • Short-lived tokens: Exchanged tokens expire after expires_in seconds.
Always call this endpoint over HTTPS. Do not log ID tokens or Fire spark access tokens. Refresh the exchange when your provider rotates the ID token.

Error responses

Errors follow RFC 6749 and RFC 8693. The endpoint returns application/json with an error field.
ErrorDescription
invalid_requestA required field is missing or malformed.
invalid_grantThe ID token is invalid, expired, or does not match any registered provider for a merchant.
unsupported_grant_typeThe grant_type value is not supported.
Error
{
  "error": "invalid_grant",
  "error_description": "No merchant is configured for this token issuer and audience."
}