From today, the Redactr API authenticates with OAuth 2.0 client_credentials. You create an application, exchange a client_id and client_secret for a one-hour access token, and send that token as a bearer on every request. The old long-lived API tokens still work for now, but they're on a deprecation timer.
What's changing and when
- From today — OAuth client credentials is live. Create applications from Settings → Applications in the dashboard.
- From 1 June 2026 — you'll no longer be able to create new API tokens. Existing ones keep working.
- From 1 July 2026 — API tokens stop working entirely. All requests will need an OAuth access token.
Five weeks to migrate. If you've got more than a handful of integrations and want extra runway, drop us a line at inbox@redactr.io.
Why we're making the move
API tokens were fine when the API was small. They've become the awkward bit of an otherwise standards-shaped surface, and they leave a few problems on the table that OAuth fixes for free.
- Short-lived by default. Access tokens last one hour. A leaked token has a much smaller blast radius — an attacker has minutes, not months. Long-lived API tokens can sit in the wrong CI log for years.
- Rotation without downtime. Rotate a
client_secretand the active access token keeps working until it expires. No coordinated cutover, no integration outage. - Generated clients understand it. Every OpenAPI client generator knows
clientCredentialsout of the box. The auth code is one option in the generator config rather than a custom interceptor you maintain by hand. - One credential per integration. Multiple applications per team means your staging environment, your production worker, and your one-off backfill script all get their own credentials. Revoke one without taking the others down.
How to migrate
The mechanics are short. Create an application, exchange the credentials for a token, and use the token as a bearer.
# 1. Exchange credentials for an access token
curl -X POST https://api.redactr.io/oauth/token \
-H 'Accept: application/json' \
-d 'grant_type=client_credentials' \
-d 'scope=*' \
--data-urlencode 'client_id=YOUR_CLIENT_ID' \
--data-urlencode 'client_secret=YOUR_CLIENT_SECRET'
# 2. Use the access_token from the response on subsequent requests
curl https://api.redactr.io/v1/suggestions \
-H "Authorization: Bearer $ACCESS_TOKEN" \
-F "file=@/path/to/document.pdf" \
-F "agent=english-dsar"Tokens are valid for one hour. Reuse yours until it expires rather than fetching a new one on every call — the token endpoint is rate-limited to 60 requests per minute per IP.
The full reference, including the /oauth/token request body, the response schema, and the clientCredentials security definition for client generators, lives in the API documentation.
In a generated client
Our SDK story is OpenAPI plus a generator of your choice — a typed client native to whatever language your stack already speaks, built from a spec we keep in sync with the live API. Most generators have first-class support for OAuth 2.0, so wiring up client credentials is configuration rather than code:
const client = new RedactrClient({
baseUrl: 'https://api.redactr.io',
auth: {
type: 'oauth2',
tokenUrl: 'https://api.redactr.io/oauth/token',
clientId: process.env.REDACTR_CLIENT_ID,
clientSecret: process.env.REDACTR_CLIENT_SECRET,
},
})The exact shape depends on your generator, but the values are the same: token URL, client ID, client secret. The generator handles fetching and refreshing the token for you.
What isn't changing
Endpoints, payloads, error shapes, idempotency keys, sparse fieldsets — none of it moves. Only the Authorization header changes, and only by the value (still Bearer <token>, just sourced from /oauth/token instead of the dashboard).
If you'd rather not touch your integration twice, you can swap the auth scheme today. If you'd rather wait, you've got until 1 July.