Skip to Content
API referenceAuthentication

Authentication

The Platform API has two kinds of caller, and they never share a credential.

CallerCredentialWhere it works
Your serverTenant API key → ten-minute machine token/platform/v1/* only
A learner’s browserTheir own MTP portal session, opened by a sign-in ticketThe portal and the session gateway

A machine token is refused by every route outside /platform/v1; a portal session is refused by /platform/v1. Neither can be turned into the other.

API keys

A tenant administrator with the MANAGE_API_KEYS permission creates keys at Organization admin → API keys. Each key has:

  • a client_id of the form mtp_ followed by 24 hex characters,
  • a client_secret, shown once at creation and never recoverable,
  • a fixed set of scopes, and
  • an optional expiry.

Revoking a key refuses its outstanding tokens on their next use. Scopes cannot be edited; make a new key.

Scopes

ScopeGrants
content.readList published content items (summaries; never documents)
learners.readLook up learners in the organization by email or id
enrollments.readRead a learner’s course enrollments and progress
enrollments.writeEnroll a learner in a published course
learners.sign_inMint single-use sign-in tickets that open a learner’s own portal session

Grant the narrowest set that does the job. A call the key is not scoped for answers 403.

Getting a machine token

POST /oauth/token implements the OAuth 2.0 client credentials grant (RFC 6749 §4.4).

POST /oauth/token Content-Type: application/json { "grant_type": "client_credentials", "client_id": "mtp_0123456789abcdef01234567", "client_secret": "…" }
{ "access_token": "eyJ…", "token_type": "Bearer", "expires_in": 600, "scope": "content.read enrollments.read" }

Present the token as Authorization: Bearer …. Tokens live ten minutes; cache one and refresh it shortly before it expires. A 401 from any Platform API route means the token has expired or its key was revoked: fetch a new token once and retry, then treat a second 401 as final. Unknown keys, wrong secrets, revoked and expired keys all answer the same 401 from the token endpoint, and each attempt is recorded in the tenant’s audit trail.

The client secret belongs on a server. Never ship it to a browser or a mobile app; give those a learner session through a sign-in ticket instead.

Tenant scope

A key belongs to exactly one organization. Every Platform API call acts in that organization, so there is no organization id to pass and no way to address another tenant. Resources outside the tenant answer 404, never 403.

Last updated on