AUTH4D-35: Stitch provider client
@auth4/provider-stitch obtains Stitch Express access tokens and sends authenticated REST
requests. It exposes no HTTP routes. Stitch Express (https://express.stitch.money) is a separate
product from the Stitch Enterprise GraphQL API at api.stitch.money; Express credentials are not
accepted there.
Tokens come from POST https://express.stitch.money/api/v1/token. The request is JSON:
{ clientId, clientSecret, scope }, and the response is
{ success: true, data: { accessToken } }. Express accepts one scope per token. API requests go to
https://express.stitch.money/api/v1/... with Authorization: Bearer <token>, and every response
is wrapped as { success, data }. Callers supply the client ID (STITCH_CLIENT_ID var), the client
secret (STITCH_CLIENT_SECRET Worker secret) and the scope, such as client_paymentrequest. The
package never reads globals or environment bindings.
Viewing the client secret in the Stitch Express dashboard regenerates it, and the previous secret
stops working at once. A token request then fails with HTTP 400 invalid_credentials.
Tokens are valid for 15 minutes; the response carries no expiry. They are cached only in isolate memory and refreshed 60 seconds early by default. Concurrent callers share one token request. An HTTP 401 response invalidates the token and retries exactly once. Each HTTP attempt times out after 10 seconds by default.
Failures throw StitchError with a fixed message and a kind:
| Response | kind |
|---|---|
Token 400 invalid_credentials, or a second 401 |
auth |
| 403 (token minted with the wrong scope) | auth |
| Other 4xx: 400 field errors, 404, 409 | validation |
429, 5xx, or a 2xx without success: true and data |
upstream |
| No response, or the client-side timeout | network |
The error also carries status, the fixed operationName, the envelope’s snake_case code,
timedOut and retryable. Provider messages, response bodies, request bodies, tokens and
credentials are never kept. Diagnostics contain only the phase (token or api), outcome,
attempt, duration, status and operation name. createObservabilityStitchSink forwards them through
the allowlisting @auth4/observability logger. redactText scrubs known secrets and
credential-shaped text from any string that might reach a log.
Local development may override the endpoints with a loopback origin only.
Source: docs/api-spec/auth4d-35.md