Documentation · Getting Started

Authentication

Client-credential token exchange, scopes, rotation and where secrets may live.

Example
Purpose
Establish a safe pattern for machine-to-machine access from an integration layer.
Prerequisites
  • Integration client issued for the sandbox
  • Server-side secret storage
Architecture
The integration layer exchanges client credentials for a short-lived bearer token, caches it in memory until shortly before expiry, and attaches it to every request. Browsers never see the client secret or the token.

Configuration

Token endpointPOST /api/v1/auth/token
Lifetime3600s (example)
Scopesusers.write assignments.write results.read certificates.read webhooks.write

Implementation steps

  1. 01Store client_id and client_secret in a server-side secret manager.
  2. 02Request a token with grant_type=client_credentials and the minimum scopes required.
  3. 03Cache the token; refresh at 80% of its lifetime.
  4. 04Retry once on 401 with a fresh token before surfacing an error.
  5. 05Rotate secrets on a schedule and support two active credentials during rotation.

Examples

Token request

bash
curl -X POST "https://sandbox.integration-lab.local/api/v1/auth/token" \
  -H "Content-Type: application/json" \
  -d '{"grant_type":"client_credentials","client_id":"$CLIENT_ID","client_secret":"$CLIENT_SECRET","scope":"users.write assignments.write"}'

Testing procedure

  • Call a protected endpoint without a scope and assert 403
  • Expire the cached token and assert transparent refresh

Troubleshooting

401 invalid_client

Credentials belong to a different environment. Sandbox and production clients are distinct.

Intermittent 401

Clock skew or cached expired token. Refresh proactively.