curl -X POST https://auth.acedata.cloud/oauth2/token \
  -d grant_type=authorization_code \
  -d code=<上一步拿到的 code> \
  -d client_id=<你的 client_id> \
  -d redirect_uri=<和第 2 步完全一致的回调地址> \
  -d code_verifier=<第 4 步生成的 code_verifier>

第 4 步:使用令牌访问资源

成功获取到令牌后,你可以使用 Access Token 访问用户的资源。

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

第 5 步:刷新令牌(可选)

如果你申请了 offline_access 权限,可以使用 Refresh Token 刷新 Access Token。

curl -X POST https://auth.acedata.cloud/oauth2/token \
  -d grant_type=refresh_token \
  -d refresh_token=<你的 Refresh Token> \
  -d client_id=<你的 client_id> \
  -d client_secret=<你的 client_secret>

第 6 步:撤销令牌(可选)

如果需要撤销 Access Token 或 Refresh Token,可以调用撤销令牌端点。

curl -X POST https://auth.acedata.cloud/oauth2/revoke \
  -d token=<你的 Access Token 或 Refresh Token> \
  -d client_id=<你的 client_id> \
  -d client_secret=<你的 client_secret>

注意事项

  • 确保在生产环境中安全存储 client_secret
  • 定期检查和更新你的 OAuth 应用设置。
  • 处理用户授权和错误时,确保提供良好的用户体验。
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 URL>

Successful response (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 with offline_access>"
}

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

Step 4: Call the API with Access Token

Just put 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, authenticated 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 verify the scope claim in the JWT—tokens can only access resources authorized by the user. If unauthorized resources are accessed, it will return 403.

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 after refreshing (rotated), 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, and after user authorization, the MCP server can call api.acedata.cloud on behalf of the user—no need for the user to manually paste 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 one used during 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