OAuth

Endpoint reference

Every endpoint exposed by the OAuth 2.1 authorization server.

EndpointAuthPurpose
GET /.well-known/oauth-authorization-serverPublicRFC 8414 metadata document
GET /.well-known/jwks.jsonPublicRFC 7517 public signing keys (RS256)
GET /api/v2/oauth/authorizePublic (browser)Authorization endpoint — validates request, issues PRT, 302s to consent
GET /api/v2/oauth/authorize/context?prt=User BearerConsent-screen data for a pending PRT
POST /api/v2/oauth/authorize/decisionUser BearerRecord Allow/Deny, issue authorization code
POST /api/v2/oauth/tokenClient credentialsToken endpoint — all three grants
POST /api/v2/oauth/introspectClient credentialsRFC 7662 token introspection
POST /api/v2/oauth/revokeClient credentialsRFC 7009 token revocation
GET /api/v2/oauth/consentsUser BearerList apps the user has authorized
DELETE /api/v2/oauth/consents/:clientIdUser BearerRevoke consent (and the client's tokens) for one app
POST /api/v2/admin/oauth-clientsPlatform adminRegister a partner OAuth client

Client audiences

Every OAuth client is created with an immutable audience that controls who can complete its consent flow:

TENANT — the client belongs to one customer tenant. Only users of that exact tenant can authorize it: a user from any other tenant gets user tenant does not match client tenant. This is the right choice for a partner app integrating on behalf of a single customer workspace.

PLATFORM — the client is registered at platform level and any customer tenant's users may authorize it. Platform-workspace accounts (platform admins themselves) can never complete an OAuth consent flow with either audience — platform-workspace accounts cannot complete OAuth flows — because tokens always represent a customer-tenant user. The audience is set at creation in the admin console and cannot be changed afterwards; re-register the client to switch.

POST /oauth/token

Client authentication is HTTP Basic (client_secret_basic), POST body (client_secret_post), or none for public clients using PKCE alone.

grant_typeRequired fields
authorization_codecode, redirect_uri (must match /authorize exactly), code_verifier
refresh_tokenrefresh_token, optional scope (may only narrow)
client_credentialsoptional scope (subset of the client's allowed scopes)
200 OK
{
  "access_token": "eyJhbGciOiJSUzI1NiIsImtpZCI6Ii4uLiJ9...",
  "token_type": "Bearer",
  "expires_in": 900,
  "scope": "interview:read interview:create",
  "refresh_token": "8f3a1c9b7e6d4f2a..."
}

Access token claims

Access tokens are RS256-signed at+jwt. Verify against /.well-known/jwks.json, matching on the kid header (two kids may be published during key rotation).

json
{
  "iss": "https://devapi.teamcast.ai",
  "sub": "usr_4471",
  "aud": "teamcast-api",
  "client_id": "oauth_client_9f3a1c...",
  "scope": "interview:read interview:create",
  "tenant_id": "tnt_8a21b6",
  "jti": "6e2f...",
  "iat": 1735689600,
  "exp": 1735690500
}

Scope catalog

ScopeGrants
interview:createCreate interviews in the account
interview:readView interviews in the account
interview:approveApprove interview plans and assessments
interview:updateEdit interviews in the account
candidate:readView candidate information
recording:readAccess interview recordings
webhook:readView webhook configuration
webhook:updateCreate, update, and delete webhook configuration
A client's allowed scopes (OAuthClient.scopes) are the authoritative ceiling — re-checked at /authorize, /authorize/decision, and every grant. Requesting a scope outside that set fails the request rather than silently downgrading it.
Was this page helpful?