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.
Register one installation
Section titled “Register one installation”- Open Account → Apps.
- Register a name, exact callback URL, client type, and required scopes.
- 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.
Connect a User with OAuth
Section titled “Connect a User with OAuth”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=consentUse 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:
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.
Permission scopes
Section titled “Permission scopes”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 and revoke deliberately
Section titled “Refresh and revoke deliberately”Refresh tokens require offline_access. Renew from your server with the same
client; renewal keeps the connection’s original scopes:
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:
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.
Inspect and disconnect connections
Section titled “Inspect and disconnect connections”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.
Endpoint directory
Section titled “Endpoint directory”| 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 |