Authentication
Authentication is a two-stage flow. A long-lived key and secret identify the integration; a short-lived bearer token authorizes each request. The key and secret are sent exactly once, to the token endpoint, and never again.
An admin creates the key and secret at Settings > DDEX Gateway. For a DDEX integration, select Create credentials and confirm ddex:read, ddex:write, and ddex:manage. That screen presets those capabilities, but creating and rotating credentials is always an explicit administrator action. Copy the key and secret when they appear, because the secret is shown only once.
Token exchange
The values below are production-format placeholder credentials. They are intentionally invalid and must be replaced with credentials generated in the dashboard.
curl --request POST 'https://enterprise.spacemedia.uk/api/v1/token' \
--header 'X-Api-Key: 00000000-0000-4000-8000-000000000000' \
--header 'X-Api-Secret: 0000000000000000000000000000000000000000'Successful response:
{
"success": true,
"data": {
"access_token": "0000000000000000000000000000000000000000963fbb8e",
"token_type": "Bearer",
"expires_at": "2026-07-04T11:30:00+00:00"
}
}Access tokens always expire. The default lifetime is 1 hour, and organization administrators can configure a lifetime from 5 minutes to 24 hours. Refresh the token before expires_at.
Authenticated requests
curl 'https://enterprise.spacemedia.uk/api/v1/countries' \
--header 'Accept: application/json' \
--header 'Authorization: Bearer 0000000000000000000000000000000000000000963fbb8e'Acting for an organization user
Catalog write and upload endpoints require X-User-Id to attribute an artist, release, track, split, or upload to a user in the same organization. This does not inherit that user's dashboard roles or permissions. Authorization comes from the API client's domain capabilities, and the user reference supplies catalog ownership and quota context only.
curl 'https://enterprise.spacemedia.uk/api/v1/releases' \
--header 'Authorization: Bearer 0000000000000000000000000000000000000000963fbb8e' \
--header 'X-User-Id: 9d7046b2-3ab1-4c9d-9bd8-90bbd22b7df2'Use the public user_id returned by the API, never a numeric account reference.
See Acting for Users for the full boundary.
WordPress OAuth is a separate token
The WordPress OAuth endpoints under /api/v1/integrations/wordpress/oauth/* do not use organization API keys or Delivery API bearer tokens. They exist so a WordPress plugin can read an authorized catalog on a site owner's behalf, and they run their own flow:
- Register. SpaceMedia verifies a one-time challenge on the site's own public HTTPS host and returns a public
client_id. There is no client secret at any point. - Authorize. The site owner approves access on a SpaceMedia consent screen in a browser session, bound with OAuth
stateand PKCES256. - Exchange. The plugin trades the authorization code for a short-lived WordPress OAuth access token.
- Read.
GET .../oauth/catalogreturns bounded release pages, read-only, using that token. - Revoke.
POST .../oauth/revokeinvalidates the connection and its tokens.
Treat that access token as a different credential type with a different lifetime. It is not interchangeable with an organization bearer token in either direction, and the catalog endpoint accepts nothing else.
Each API client receives explicit capabilities. New credentials default to catalog:read only. Grant the smallest set required by the integration.
The catalog:read default applies to clients created outside the DDEX credential flow. Installing the Enterprise Delivery API add-on does not silently add delivery permissions to an existing API client.
| Domain | Read capability | Write capability |
|---|---|---|
| Catalog, artists, releases, tracks, splits, and smartlinks | catalog:read | catalog:write |
| Account settings and labels | account:read | account:write |
| Billing, subscriptions, and checkouts | billing:read | billing:write |
| Users | users:read | users:manage |
| Members and roles | members:read | members:manage |
| Branding and email themes | branding:read | branding:manage |
| Copyright | copyright:read | copyright:write |
| Release review | review:read | review:process |
| Add-ons | addons:read | addons:manage |
| DDEX | ddex:read | ddex:write or ddex:manage for connection administration |
| Enterprise webhooks | webhooks:read | webhooks:manage |
users:act-as is additionally required whenever X-User-Id is sent. Feedback submission uses feedback:write.
Security rules
- Never send API key or secret after the token exchange request.
- Never place bearer tokens in query strings.
- Rotate credentials if a secret is exposed.
- Do not use cross-organization selectors in public integrations.
- Use separate API credentials per integration so access can be rotated without affecting every workflow.
- Refresh the access token before
expires_at.
Common questions
How long does a token last?
One hour by default. An admin can configure anywhere from 5 minutes to 24 hours. Refresh before expires_at rather than waiting for a 401.
What happens when credentials are rotated? Every bearer token issued from the old pair stops working immediately. Plan rotation into a maintenance window.
Can I add capabilities to an existing credential by installing an add-on? No. Installing the Enterprise Delivery API add-on never silently widens an existing client. Capabilities are granted explicitly.
Do I need a separate credential per environment? Yes. Staging and production credentials are not interchangeable, and reusing production credentials in test tooling is the most common way secrets leak.
Was this page helpful?