SpaceMediaSpaceMedia
Start here

Authentication

Every Reports API operation declares its own authentication requirement in the OpenAPI contract. Follow the security declaration on the exact operation you are calling rather than assuming a section-wide rule.

What a tenant is

A tenant is the reporting account your credentials belong to. It is the Reports API equivalent of the Delivery API's organization, but the two are issued separately and their identifiers are not interchangeable.

Every request carries the tenant as X-Tenant-ID, an opaque UUID. SpaceMedia issues it with your Reports API client credentials. There is no endpoint that discovers it and no way to derive it from a Delivery API organization reference.

Get your first token

Machine clients exchange approved tenant credentials at POST /api/platform/v1/oauth/token. The client id and secret go in an HTTP Basic header, not in the body.

curl --request POST 'https://reports.spacemedia.uk/api/platform/v1/oauth/token' \
  --user 'CLIENT_ID:CLIENT_SECRET' \
  --header 'X-Tenant-ID: 4f1c2d6a-8e35-4a71-9b02-7c5d3e8a61f4' \
  --header 'Content-Type: application/json' \
  --data '{"grant_type":"client_credentials"}'

The response returns an opaque token, its lifetime in seconds, and the scopes actually granted. expires_in never exceeds 3600.

{
  "access_token": "0000000000000000000000000000000000000000",
  "token_type": "Bearer",
  "expires_in": 3600,
  "scope": "exports:read exports:write"
}

Read scope from the response rather than assuming what you asked for was granted. Requesting a scope the tenant has not approved does not fail the exchange; it returns a token without it, and the call that needs it fails later with 403.

Verify the token

GET /api/platform/v1/api/session confirms the token, the tenant binding, and the granted scopes in one call. Use it as the first request of any integration and as a health check.

curl 'https://reports.spacemedia.uk/api/platform/v1/api/session' \
  --header 'Authorization: Bearer 0000000000000000000000000000000000000000' \
  --header 'X-Tenant-ID: 4f1c2d6a-8e35-4a71-9b02-7c5d3e8a61f4'

It returns the client, the tenant, the scope array, and expires_at. Refresh before that timestamp rather than waiting for a 401.

Scopes

ScopeGrants
tenant:readRead the API session and tenant binding.
analytics:readRead published analytics.
calculations:read, calculations:writeRead and run royalty calculations.
catalog:read, catalog:writeRead and update catalog mapping records.
exports:read, exports:writeList and download exports, and queue new ones.
imports:read, imports:writeRead import state, and create or cancel imports.
ledger:readRead ledger entries.
payees:read, payees:writeRead and update payee records.
statements:readRead royalty statements.
webhooks:read, webhooks:writeRead and manage webhook ingress configuration.

Each endpoint page lists the scope it requires. Request the smallest set that covers your workload.

Handling credentials

  • Store client credentials and tokens only on trusted server infrastructure.
  • Request the smallest approved scope set.
  • Never reuse Delivery API credentials against the Reports API.
  • Revoke or rotate a client immediately when its operator or workload changes.
  • Treat a disabled route or tenant capability as unavailable even when the token is otherwise valid.

Human operations

Routes under /platform/v1/* use an authenticated human session. Mutations can additionally require CSRF protection, recent multi-factor authentication, maker-checker separation, or idempotency controls.

These are not machine API substitutes. Where an approval needs a person, the contract keeps it on the human surface deliberately, and there is no scope that moves it.

Tenant isolation

Every token, session, import, export, and evidence record is tenant scoped. Never pass a tenant reference from one authenticated context into another, and never persist cross-tenant lookup results in a shared cache.

Common questions

Which surface should my integration use? Machine OAuth for anything automated. If the operation you need only exists on the human surface, that is a policy decision about who may approve it.

Where do I get my X-Tenant-ID? SpaceMedia issues it with your Reports API client credentials. It is not the same value as a Delivery API organization reference, and no endpoint returns it.

Can I reuse my Delivery API token here? No. The two APIs issue separate credentials against separate hosts. A Delivery API bearer token is rejected by reports.spacemedia.uk.

My token is valid but the call is denied. Why? A valid token does not imply an enabled route or an approved tenant capability. See Availability.

How often should I rotate a client? On any change of operator or workload, and immediately on suspected exposure. Rotation is cheap; an unrotated credential after a team change is not.

What must never go in a support ticket? Credentials, bearer tokens, signing secrets, report files, and customer financial data. Send the operation, UTC timestamp, environment, sanitized request and response, public reference, and correlation identifier instead.

Was this page helpful?

On this page