Skip to Content
API ReferenceREST Endpoints

REST Endpoints

The Foir public API is GraphQL-first, but a handful of surfaces are plain REST because their callers aren’t GraphQL clients — a mail client following an unsubscribe link, Stripe POSTing a billing event, or an off-the-shelf OIDC library discovering the customer login lane. They all live on the same public host, https://api.foir.dev.

EndpointMethodAuthPurpose
/v1/email/unsubscribeGET, POSTSigned token (query string)RFC 8058 one-click unsubscribe from notification emails
/v1/webhooks/stripePOSTStripe-Signature headerStripe → Foir billing webhook receiver (operated by Foir)
/customer/.well-known/openid-configurationGETnoneOIDC discovery document for the customer login lane
/customer/oauth/authorize, /token, /revokeGET, POSTPKCE / clientOAuth 2.1 authorization-code flow (see the Login with Foir guide)
/.well-known/jwks.jsonGETnonePublic keys for verifying customer access tokens

The internal admin and CLI auth endpoints (operator login, auth/cli/*) are not part of the public API — they live on Foir’s internal host and aren’t reachable here.

Email unsubscribe (RFC 8058)

Every notification email Foir sends carries an RFC 8058  List-Unsubscribe header pointing at:

https://api.foir.dev/v1/email/unsubscribe?token=<signed-token>

The token is a self-contained, HMAC-signed value Foir mints when the email is queued; it identifies the recipient and is the only credential. There is nothing for you to call or configure — the endpoint exists so a recipient’s mail client (or the “unsubscribe” link in the email) can opt them out of notification emails in one click.

MethodBehavior
GETRenders a confirmation page. Prefetch-safe — it never changes state, so a mail client or security scanner that prefetches the link can’t silently unsubscribe anyone.
POSTPerforms the opt-out. This is the RFC 8058 one-click target (mail clients POST it directly) and the confirmation page’s button.

A successful opt-out records a global opt-out from notification emails for that recipient. Account and security emails are unaffected.

Responses: 200 with an HTML page on success; 400 with an HTML page when the token is missing, invalid, or expired.

Stripe webhook

POST https://api.foir.dev/v1/webhooks/stripe

Foir’s billing receiver for Stripe webhook events  (subscription lifecycle, invoice paid / payment failed). It is operated by Foir — API consumers don’t call it; it’s listed here for completeness of the public surface.

Authentication is the Stripe-Signature header, verified server-side against the raw request body (Stripe signs the raw bytes), so the signature is the only credential and no secret is exposed at the edge.

Responses: 2xx once the event is accepted; 400 for a missing or unverifiable signature; 503 while the receiver is unconfigured (so Stripe retries).

Customer authentication (OIDC)

The customer hosted-login lane — Login with Foir — is a standard OAuth 2.1 / OIDC authorization server. Most apps integrate it through the two GraphQL mutations described in the Login with Foir guide; you generally don’t call these REST endpoints directly.

If you’re integrating from a generic OIDC library (Auth0 SDK, Spring Security, etc.), point it at the discovery document and let it auto-configure:

https://api.foir.dev/customer/.well-known/openid-configuration

It advertises the lane’s endpoints:

EndpointMethodPurpose
/customer/oauth/authorizeGETAuthorization-code request (PKCE S256 required). Bounces the customer into the hosted login UI.
/customer/oauth/tokenPOSTExchange an authorization code for tokens (grant_type=authorization_code) or rotate a refresh token (grant_type=refresh_token). Form-encoded, per RFC 6749.
/customer/oauth/revokePOSTRevoke a refresh token and its rotation family (RFC 7009 ).
/.well-known/jwks.jsonGETPublic keys for verifying customer access tokens.

Access tokens are 15-minute EdDSA JWTs (issuer foir-customer); refresh tokens are 30-day opaque strings, rotated on every use with replay detection. You don’t need to verify tokens yourself — the platform does — but a backend-for-frontend that wants to can fetch the keys from the JWKS URL above. See Authentication for using customer tokens against the GraphQL API.

Last updated on