Skip to content

Authentication and app connections

Register an app, obtain user consent, and manage OAuth tokens.

Public reads need no authentication. For protected operations, run OAuth and API calls from your app’s server and keep credentials out of browser code, source control, and logs.

  1. Open Account → Apps.
  2. Register a name, exact callback URL, client type, and required scopes.
  3. Save the client ID and, for a confidential client, the issued client secret in your server’s secret store.

Register each deployment or self-hosted installation separately.

Client type When to choose it Token authentication
Public / native / self-hosted The installation cannot keep a client secret client_id in the form; no secret
Confidential server The installation can protect a server-side secret HTTP Basic (client_secret_basic)

Both types require PKCE with S256 and make protected calls from their backend. Callbacks must use HTTPS, except public clients may use HTTP loopback callbacks on localhost, 127.0.0.1, or ::1. The registered URL must match redirect_uri exactly, including path and query string. Dynamic registration is not supported.

Generate a random state and PKCE verifier on your server. Store them for the callback attempt, then redirect the browser to:

https://mediux.io/api/auth/oauth2/authorize?response_type=code&client_id=CLIENT_ID&redirect_uri=https%3A%2F%2Fapp.example%2Foauth%2Fcallback&resource=https%3A%2F%2Fapi.mediux.io%2Fme&scope=openid%20profile%20offline_access%20assets%3Awrite&code_challenge=BASE64URL_SHA256_OF_VERIFIER&code_challenge_method=S256&state=STATE&nonce=NONCE&prompt=consent

Use your registered callback, requested scopes, and generated values. The resource is always https://api.mediux.io/me. The user signs in and approves the connection on Mediux.

At the callback, reject missing, expired, or mismatched state values and check for an OAuth error. Exchange the short-lived code from your server:

Terminal window
curl --fail-with-body --request POST \
https://api.mediux.io/api/auth/oauth2/token \
--user "$CLIENT_ID:$CLIENT_SECRET" \
-H 'Content-Type: application/x-www-form-urlencoded' \
--data-urlencode 'grant_type=authorization_code' \
--data-urlencode "client_id=$CLIENT_ID" \
--data-urlencode "code=$AUTHORIZATION_CODE" \
--data-urlencode "redirect_uri=$REDIRECT_URI" \
--data-urlencode "code_verifier=$CODE_VERIFIER" \
--data-urlencode 'resource=https://api.mediux.io/me'

Public clients omit --user. Keep the returned access and refresh tokens on your server. Send the access token as Authorization: Bearer ACCESS_TOKEN when calling /me/*; do not send account cookies.

Request only the scopes your app needs. Permissions never override resource ownership.

Scope Permission
assets:write Add artwork and edit language or edition metadata
assets:replace Replace artwork and select an animated preview frame
sets:write Create, read, and edit owned Sets; assign eligible artwork
groups:write Create, read, and edit owned Boxsets and Loadouts
relationships:write Read and manage follows and hides
openid, profile Standard identity scopes
offline_access Obtain a refresh token

Media Set creation requires sets:write and assets:write. Group posters need groups:write plus the asset scope for adding or replacing. See the operation tables for exact requirements.

Refresh tokens require offline_access. Renew from your server with the same client; renewal keeps the connection’s original scopes:

Terminal window
curl --fail-with-body --request POST \
https://api.mediux.io/api/auth/oauth2/token \
--user "$CLIENT_ID:$CLIENT_SECRET" \
-H 'Content-Type: application/x-www-form-urlencoded' \
--data-urlencode 'grant_type=refresh_token' \
--data-urlencode "client_id=$CLIENT_ID" \
--data-urlencode "refresh_token=$REFRESH_TOKEN"

Save the returned credentials securely. Do not blindly retry an uncertain refresh: a lost successful response may require the user to reconnect. The SDK does not refresh tokens automatically.

Revoke the refresh token when disconnecting:

Terminal window
curl --fail-with-body --request POST \
https://api.mediux.io/api/auth/oauth2/revoke \
--user "$CLIENT_ID:$CLIENT_SECRET" \
-H 'Content-Type: application/x-www-form-urlencoded' \
--data-urlencode "client_id=$CLIENT_ID" \
--data-urlencode "token=$REFRESH_TOKEN" \
--data-urlencode 'token_type_hint=refresh_token'

Public clients omit --user in both requests. Revocation is idempotent for the matching connection and does not undo saved artwork. OAuth failures use the provider’s error field.

Users can review scopes and disconnect apps in Account → Apps. Disconnection blocks further protected calls and renewal for that connection. It leaves the user’s account session and saved artwork intact. Account logout is separate; password or other security changes may require reconnection.

For an unrecognized connection, disconnect it and rotate credentials held by the installation.

Purpose URL
OAuth metadata https://mediux.io/api/auth/.well-known/oauth-authorization-server
OpenID Connect metadata https://mediux.io/api/auth/.well-known/openid-configuration
Authorization https://mediux.io/api/auth/oauth2/authorize
Exchange and refresh https://api.mediux.io/api/auth/oauth2/token
Revoke https://api.mediux.io/api/auth/oauth2/revoke