Access "Login with Ace Data Cloud" (OAuth 2.0)

Enable your product to support "Login with Ace Data Cloud" and, after user authorization, act on behalf of the user to read and write their Ace Data Cloud resources (profile, API Token, subscriptions, usage, orders, etc.). The underlying mechanism is the standard OAuth 2.0 Authorization Code Flow + PKCE, which is completely consistent with the login methods of GitHub / Google — any existing OAuth client library you have can be used directly.

Suitable Scenarios: You are developing a third-party application / Agent / MCP client / automation workflow and want users to log in with their Ace Data Cloud account with one click, accessing their resources on the platform as needed, without requiring users to manually copy and paste the API Key.

Terminology & Endpoint Quick Reference

All endpoints are at https://auth.acedata.cloud, and you can always get the latest address through the discovery endpoint:

curl https://auth.acedata.cloud/.well-known/oauth-authorization-server
Purpose Endpoint
Discovery Document GET /.well-known/oauth-authorization-server
User Authorization Page (Browser Redirect) GET https://auth.acedata.cloud/oauth2/authorize
Token Endpoint (Exchange / Refresh token) POST https://auth.acedata.cloud/oauth2/token
Revoke Token POST https://auth.acedata.cloud/oauth2/revoke
User Information (UserInfo) GET https://auth.acedata.cloud/api/v1/users/me
Application Registration Management (Self-service) https://auth.acedata.cloud/user/oauth-apps

Supported capabilities: response_type=code, grant_types=authorization_code, refresh_token, code_challenge_methods=S256, plain, client authentication methods client_secret_post (confidential client) / none (PKCE public client).

Permission Scope (Scope)

Apply for "least privilege," and users will see each permission you request on the authorization page.

Identity (OIDC Compatible)

Scope Meaning /users/me Return Fields
openid User unique identifier id
profile Basic information username, nickname, avatar, is_verified, date_joined
email Email email
phone Phone number (sensitive) phone, region

Platform Resource

Scope Meaning
applications:read / applications:write Read / Modify user service subscriptions and quotas
credentials:read / credentials:write Read / Create Revoke user API Token
usage:read Read user call history
orders:read / orders:write Read orders / Place orders and initiate payment

Aggregation (Automatically Expanded)

Scope Expanded To
platform:read applications:read + credentials:read + usage:read + orders:read
platform:write applications:write + credentials:write + orders:write
platform platform:read + platform:write

Special

Scope Meaning
offline_access Issue Refresh Token (if not requested, only Access Token is issued, and re-authorization is required when it expires)

Typical combinations: Third-party "one-click login" = openid profile; MCP / IDE client needs to automatically configure Key = openid profile credentials:read credentials:write; Full management console = openid profile email platform offline_access.

Step 1: Register an OAuth Application

Open auth.acedata.cloud/user/oauth-apps → "Create Application," fill in:

  1. Application Name / Description / Logo: Will be displayed on the user's authorization consent page.
  2. Client Type:
    • Confidential — You have a backend that can securely store client_secret (Web service, backend service).
    • Public — Pure frontend / desktop / CLI / mobile, cannot store secrets, must use PKCE.
  3. Redirect URIs: The address to which users are redirected after authorization is complete, must exactly match the redirect_uri you passed when initiating authorization, can fill in multiple.
  4. Permission Scope (Scopes): Check the scopes you need from the previous section.

After saving, obtain client_id; confidential clients will also once display client_secret—save it immediately, as it cannot be viewed again after closing (can be regenerated on the details page under "Rotate Secret," and the old secret will become invalid immediately).

Each account can create a maximum of 20 OAuth applications.

Step 2: Redirect the User to the Authorization Page

In your application, redirect the user's browser to the authorization page with the query parameters:

https://auth.acedata.cloud/oauth2/authorize
  ?response_type=code
  &client_id=<your client_id>
  &redirect_uri=<your registered callback address>
  &scope=openid%20profile%20credentials:read
  &state=<random CSRF protection string>
  &code_challenge=<PKCE challenge value>          # Required for public clients
  &code_challenge_method=S256            # Required for public clients
  • state: A randomly generated string that is returned as is during the callback, used for CSRF protection, must be validated.
  • PKCE (mandatory for public clients, recommended for confidential clients): First generate a random code_verifier, then calculate code_challenge = BASE64URL( SHA256( code_verifier ) ), place the code_challenge in the authorization URL, keep the code_verifier for use in Step 4.

After the user logs in and clicks "Agree," the browser will be redirected back to:

<redirect_uri>?code=<authorization code>&state=<state returned as is>

If the user declines: <redirect_uri>?error=access_denied&error_description=...&state=....

The authorization code is valid for 10 minutes and can only be used once.

Step 3: Exchange the Authorization Code for a Token

In your backend (confidential client) or client (PKCE public client), call the token endpoint using the code.

Confidential Client (with client_secret):

curl -X POST https://auth.acedata.cloud/oauth2/token \
  -d grant_type=authorization_code \
  -d code=<code obtained in the previous step> \
  -d client_id=<your client_id> \
  -d client_secret=<your client_secret> \
  -d redirect_uri=<callback address that exactly matches Step 2>

Public Client (PKCE, without client_secret):

curl -X POST https://auth.acedata.cloud/oauth2/token \
  -d grant_type=authorization_code \
  -d code=<code> \
  -d client_id=<your client_id> \
  -d code_verifier=<code_verifier generated in Step 2> \
  -d redirect_uri=<callback address>

Successful response (the refresh_token only appears when offline_access is requested):

{
  "access_token": "<JWT>",
  "token_type": "Bearer",
  "expires_in": 1296000,
  "scope": "openid profile credentials:read",
  "refresh_token": "<JWT, only when offline_access>"
}

access_token is a JWT that contains the scope claims; valid for 15 days (expires_in in seconds). The Refresh Token is valid for 30 days.

Step 4: Call the API with the Access Token

Place the token in the Authorization: Bearer header.

Read User Information (UserInfo, fields filtered by authorized scope):

curl https://auth.acedata.cloud/api/v1/users/me \
  -H "Authorization: Bearer <access_token>"

Call Platform Resource API (api.acedata.cloud, authorized by scope). For example, if credentials:read is granted:

curl https://api.acedata.cloud/api/v1/credentials/ \
  -H "Authorization: Bearer <access_token>"

The platform backend will validate the scope claims in the JWT—tokens can only access resources authorized by the user. If unauthorized resources are accessed, a 403 will be returned.

Refresh Token

After the Access Token expires, use the Refresh Token to obtain a new pair of tokens (requires that offline_access was initially requested):

curl -X POST https://auth.acedata.cloud/oauth2/token \
  -d grant_type=refresh_token \
  -d refresh_token=<your refresh_token>

The return structure is the same as in step 3; the scope will be retained as is from the original authorization. The old Refresh Token becomes invalid (rotated) after refreshing, please save the new one.

Revoke Token

curl -X POST https://auth.acedata.cloud/oauth2/revoke \
  -d token=<access_token or refresh_token>

Real Case: This is how our own MCP server connects

The 15+ MCP servers of Ace Data Cloud (NanoBanana, Midjourney, Suno, Seedance, Kling…) that appear in Claude Desktop / Cursor with the "Sign in with Ace Data Cloud" link follow this process: they are all registered as public (PKCE) type OAuth applications, requesting credentials related scopes. After user authorization, the MCP server can call api.acedata.cloud on behalf of the user—without the user manually pasting the API Key. Your connection method is exactly the same as theirs.

Common Errors

Error responses are uniformly formatted as { "error": "<code>", "error_description": "<human-readable explanation>" }:

error Meaning / Troubleshooting
invalid_request Missing or illegal parameters (e.g., did not send code / client_id)
invalid_client client_id does not exist, application is disabled, or client_secret is incorrect
invalid_grant Authorization code does not exist / has expired (>10 minutes) / has been used / PKCE verification failed / redirect_uri does not match the authorization
access_denied User clicked "Deny" on the authorization page
unsupported_grant_type grant_type is not authorization_code or refresh_token

Rate Limits

Item Value
Maximum number of OAuth applications per account 20
Authorization code validity period 10 minutes, single use
Access Token validity period 15 days
Refresh Token validity period 30 days (rotated)
redirect_uri Must match the registered value exactly
client_secret Displayed only once during creation / rotation, stored on the server as SHA-256 hash