Getting started
Authentication
OAuth2 client credentials, tokens and environments.
The API uses the OAuth2 client credentials flow. You exchange your client reference and secret for a JWT bearer token, then send that token on every request. There are no session cookies and no browser redirects. It's two server-to-server calls.
Exchanging credentials for a token
The token endpoint takes form-encoded fields, not JSON. It is the one call that carries no bearer token of its own:
Then authenticate every other call with the access_token:
If you have the CLI set up, firsty auth token
prints a valid token and nothing else, so it pipes straight into a shell
variable. It handles the exchange and the caching for you.
Token lifetime and caching
Tokens live for 24 hours. Cache them and refresh shortly before expiry rather than requesting one per call. The token endpoint has its own rate limit. Treat the token as an opaque string; don't build logic on the JWT's contents.
A 401 mid-session means the token expired or the credential is no longer
valid: fetch a fresh token once, retry, and fail loudly if it still fails.
Environments
| Environment | Base URL | Credentials |
|---|---|---|
| Staging (sandbox) | https://connect.test.firsty.app/api/v3 | Claimed via firsty init |
| Production | https://connect.firsty.app/api/v3 | Issued when you go live |
Tokens are issued per environment, so use the one minted against the base URL
you're calling. Derive the token URL from that base URL too
({baseUrl}/auth/token): the spec's tokenUrl names production only.
Keeping secrets out of the client
Never ship the client secret, or a bearer token, to a browser or mobile app. Proxy through your own backend; anything in client code is public no matter how it's obfuscated.