Quick start
Configure an approved sandbox client and implement Fiest OAuth safely.
This guide is the shortest safe path for implementing an approved Partner API sandbox connection. It uses the public Fiest Partner API contract and a client registration supplied privately by Fiest.
Sandbox preview
The sandbox is available to approved partners and contains synthetic test data. Production uses a separate, explicitly approved client registration. Do not substitute production URLs or credentials while following this sandbox guide.
Registration values
| Setting | Value |
|---|---|
| OAuth issuer | https://auth-sandbox.fiest.io |
| Client ID | Your Fiest-issued sandbox client ID |
| Client type | Public OAuth client |
| Client secret | None |
| Redirect URI | Your exact registered HTTPS callback |
| API resource | https://api-sandbox.fiest.io |
| OpenAPI contract | https://docs.fiest.io/openapi.yaml |
Fiest shares the client ID and confirms the exact redirect URI directly with each approved partner. Do not copy values from another integration.
These sandbox endpoints do not grant access to Fiest's internal development or staging systems.
Why there is no client secret
This registration is a public OAuth client protected by PKCE S256. A static secret embedded in a distributed client cannot be kept confidential. Security instead relies on the exact redirect allowlist, high-entropy state, PKCE, one-time short-lived authorization codes, audience binding, and rotating refresh tokens.
Request these scopes:
offline_access
fiest.restaurant.read
fiest.accounting.readRequest fiest.organization.read only when Fiest has explicitly approved a
Management organization integration. The initial partner sandbox flow should
use one restaurant and the smallest scope set above.
Use OAuth discovery instead of hardcoding authorization, token, JWKS, or revocation endpoints. Every authorization and token request must use the exact API resource above.
Complete sandbox authorization
The partner starts the connection from its own product and redirects the user
to auth-sandbox.fiest.io. The user does not need to visit the production Fiest
Dashboard first.
For the initial sandbox test:
- Expand Use an email code instead on the Fiest authorization page.
- Enter the pre-provisioned sandbox account email supplied by Fiest.
- Enter the six-digit code delivered directly to that inbox. The partner application and coding agent must never request or receive the code.
- Choose one reviewed test restaurant and approve the displayed read-only permissions.
- Fiest redirects the browser to the exact registered partner callback.
Email verification only proves an existing Fiest identity; it never creates an account. Organization-wide authorization is introduced separately through the Fiest Management flow.
Token lifecycle
The token response is authoritative. Read expires_in, store the resulting
expiry with the connection, and do not assume that a token remains valid just
because it has not reached its expected expiry. A Fiest owner, administrator,
or security control can revoke access earlier.
| Credential | Current lifetime | Required client behavior |
|---|---|---|
| Authorization code | 5 minutes, single-use | Exchange it promptly and exactly once with the original PKCE verifier. Never persist it as a connection credential. |
| Access token | 1 hour | Send it only to the exact API resource for which it was issued. Use the returned expires_in value and obtain a replacement with the current refresh token when needed. |
| Refresh token | 90 days, rotating | Store it encrypted. Each successful refresh consumes it and returns a new refresh token with a new bounded 90-day lifetime. Replace the stored token atomically. |
Refresh-token replay invalidates the associated refresh family. If refresh is rejected definitively, or no valid refresh token remains, delete unusable token material and move the connection to an explicit Reconnect Fiest state. Do not retry a consumed refresh token.
Revocation is independent of these maximum lifetimes. A revoked connection,
removed membership, disabled client, or invalid authorization boundary can
make otherwise unexpired tokens unusable immediately. Reconnecting starts a
new OAuth authorization; it must not reuse an earlier authorization code,
state, PKCE verifier, or refresh token.
Implementation sequence
- Generate a high-entropy OAuth
stateand PKCE verifier for each connection attempt. - Store both server-side with a short expiry and send only the PKCE
S256challenge to Fiest. - Redirect the user to the discovered authorization endpoint with the exact client ID, redirect URI, resource, and scopes.
- Handle both successful
codecallbacks and OAutherrorcallbacks. - Consume
stateand the authorization code once, then exchange the code with the original PKCE verifier. - Encrypt access and refresh tokens in durable server-side storage.
- Record the access-token expiry from
expires_in. Replace rotating refresh tokens atomically. A replay or definitive refresh failure must move the connection into a clear reconnect state. - Discover the current authorization boundary with
GET /v1/restaurants. Never infer or accept a restaurant outside that response. - Read the approved restaurant profile or accounting summary using only the published operations.
Keep credentials out of the browser and logs
Never render or log access tokens, refresh tokens, authorization codes,
cookies, PKCE material, customer records, or financial payloads. Retain only
the safe request_id when support correlation is needed.
Prompt for a coding agent
Copy the prompt below into Claude Code, Codex, Cursor, or another coding agent. Give the agent this page and the public OpenAPI contract as its authoritative inputs.
Implement my approved sandbox integration with the Fiest Partner API.
Treat this quick-start page and
https://docs.fiest.io/openapi.yaml as the only authoritative contracts.
Build a server-side OAuth 2.1 authorization-code client with PKCE S256:
- issuer: https://auth-sandbox.fiest.io
- client ID: <insert the client ID supplied privately by Fiest>
- redirect URI: <insert the exact HTTPS callback registered with Fiest>
- resource/audience: https://api-sandbox.fiest.io
- scopes: offline_access fiest.restaurant.read fiest.accounting.read
- client type: public; do not invent or request a client secret
Use discovery rather than hardcoding authorization, token, JWKS, or revocation
endpoints. Generate high-entropy state and a PKCE verifier per attempt, store
them server-side with a short expiry, consume state once, and exchange each
authorization code once with the original verifier and exact resource.
Store access and rotating refresh tokens encrypted in durable server-side
storage. Treat access tokens as one-hour credentials while honoring the token
response's `expires_in` value. Replace the refresh token atomically, reject
replay, and move the connection to an explicit reconnect state when refresh
fails definitively. A successful refresh returns a new rotating refresh token
with a new bounded 90-day lifetime.
Never render or log tokens, authorization codes, PKCE material, cookies,
customer data, or financial payloads.
Implement the callback's OAuth success and error paths, then implement only
the public GET operations in the supplied OpenAPI contract. Discover the
authorized restaurant ID from GET /v1/restaurants; never accept or infer a
restaurant outside that grant. Branch on stable API error codes and retain
request_id for redacted support logs.
Add automated tests for state expiry and reuse, wrong PKCE verifier, callback
errors, one-time code exchange, exact resource/audience, refresh rotation and
replay, reconnect state, out-of-grant restaurant denial, invalid dates, 429
Retry-After handling, and redaction. Do not request write scopes, use an MCP
token, add a generic HTTP proxy, or point any test at production.
Before claiming success, report:
1. the files changed;
2. the durable state/token storage model;
3. all tests and type checks run;
4. any assumption not explicitly supported by the two provided contracts; and
5. what remains for a real browser authorization.
Do not describe type safety as verified if the strict typecheck did not run.
Report the exact blocker instead.Acceptance checklist
Before the sandbox connection is considered complete:
- the registered callback handles OAuth success and denial without returning
404; - the authorized restaurant list contains only the reviewed restaurant or organization boundary;
- an out-of-grant restaurant returns the documented safe error;
- two complete accounting periods reconcile;
- refresh rotation succeeds once and replay of the previous token fails;
- revocation denies the next API request and reconnect restores the same reviewed boundary;
429handling respectsRetry-After; and- operational logs contain request IDs but no credentials or financial data.
See stable API errors before adding retry behavior.