DigitalOcean OAuth API
Last verified 28 Sep 2026
OAuth 2.0 is an open standard for authorization that enables third-party applications to obtain limited access to a service. The DigitalOcean OAuth API lets you obtain limited access to DigitalOcean teams by delegating authentication to DigitalOcean.
About the DigitalOcean OAuth API
Our OAuth API supports the authorization code flow, meant for applications that can perform a server-side token exchange, and the implicit authorization flow, meant for client-side applications such as mobile or desktop clients.
The OAuth API supports two types of clients, distinguished by whether they can keep a client secret confidential:
- Confidential clients can securely store a client secret, such as web applications running on a server. You register them manually in the control panel, which assigns them a client ID and a client secret that they use to request access tokens.
- Public clients cannot securely store a client secret, such as native, desktop, command-line, or Model Context Protocol (MCP) clients. They have no client secret and instead secure the authorization code exchange using PKCE. You typically create them using Dynamic Client Registration.
The DigitalOcean authorization server, https://cloud.digitalocean.com/v1/oauth, has the following endpoints:
| Endpoint | Description |
|---|---|
/authorize |
Request user authorization |
/token |
Request an authorized access token |
/token (with grant_type=refresh_token) |
Refresh an access token using a refresh token |
/revoke |
Revoke an access token |
/register |
Dynamically register a public OAuth client |
/register/{client_id} |
Read, update, or delete a dynamically registered client |
The authorization server also publishes an authorization server metadata document at https://cloud.digitalocean.com/.well-known/oauth-authorization-server.
To use the OAuth API, first register your application to use OAuth. Registering a confidential application assigns it a client ID and client secret which you then use in API calls to the DigitalOcean authorization server. Public clients can instead be registered programmatically using Dynamic Client Registration, which assigns a client ID but no client secret.
For issues and errors, use the OAuth API troubleshooting guide.
/authorize: Request User Authorization
Use the https://cloud.digitalocean.com/v1/oauth/authorize endpoint as an authorization link to send to a user for your registered OAuth application.
Example
You can view an example link for a registered OAuth application in the control panel. On the OAuth Applications page, click the … next to the application’s name, then click View to open the OAuth Application Details window. In this window, the Link to authorization code section has an example link.
Parameters
| Parameter | Type | Necessity | Description |
|---|---|---|---|
client_id |
string | Required | The client ID for your registered OAuth application on DigitalOcean. |
redirect_uri |
string | Required | The callback URL where users are sent after authorization. Must match a callback URL you provided during application registration. |
response_type |
string | Required | Set to code to request an authorization code. Set to token to request an OAuth token for implicit authorization. |
scope |
string | Optional | See all token scopes. |
state |
string | Optional | An unguessable random string. Used to protect against request forgery attacks. Recommended. |
prompt |
string | Optional | A space-separated list of strings that defines the behavior of the authorization page as shown to the user when they authorize an OAuth application. See values below. |
code_challenge |
string | Optional | The PKCE code challenge. Required for public clients. Only valid with response_type=code. |
code_challenge_method |
string | Optional | The PKCE code challenge method. Only S256 is supported. Required when code_challenge is provided. |
The response_type parameter can have the following values:
-
code: Requests an authorization code. Used for the authorization code flow for web applications.When you use this response type, you request the access token grant with the
/tokenendpoint. -
token: Requests an OAuth token. Used for the implicit authorization flow for client-side applications.When you use this response type, you receive the access token grant in a callback.
The prompt parameter can have the following values:
-
select_account(default):-
If a user is not signed in, they are required to sign in.
-
Signed-in users must authorize the OAuth application before proceeding.
-
-
none:-
Signed-in users who have already authorized the application are redirected back to the valid
redirect_urlwith a new token. A hint can be used by specifying aniquery parameter with the first 6 characters of an expected account UUID. -
Signed-in users who haven’t authorized the application are redirected with
error=consent_required. Signed-out users are redirected witherror=login_required.
-
Public clients must use response_type=code and secure the authorization code exchange with PKCE. When authorizing a public client, include a code_challenge and set code_challenge_method to S256. Retain the corresponding code verifier. You exchange it for a token by passing it as the code_verifier parameter to the /token endpoint. PKCE is only used with the authorization code flow. Although PKCE is required only for public clients, confidential clients can also use it for additional protection.
If you omit the scope parameter in the authorization request, the consent screen displays a Manage permissions option, allowing the user to select specific granular scopes to grant.
Public clients may register more than one redirect URI, and any one of them can be used with redirect_uri. Loopback redirect URIs (127.0.0.1, [::1], or localhost) match on any port, so a native application can use the ephemeral port it binds at runtime.
Returns
If the user authorizes the application, DigitalOcean redirects back to your redirect_uri with the following parameters:
-
One of the following, depending on the specified
response_type:-
The
codeparameter with an authorization code. Use this in access token requests to the/tokenendpoint. -
The
tokenparameter with an OAuth token. Here is an example callback (access token grant) fortokenresponse types:
https://example.com/callback#access_token=doo_v1_EXAMPLE4ea...381 &token_type=bearer &expires_in=2592000 &state=0807edf7d85e5d -
-
The
stateparameter, if you specified one in the authorization request.Verify that the value of
statein the response matches the one you provided in the request. If not, it indicates that the request may be a forgery attack created by a third party, and you should abort the request. -
The
expires_inparameter, which indicates the time remaining before the token expires in seconds.
The token is available to use to make requests via the DigitalOcean API until the token expires (30 days after being issued for confidential clients, or one hour for public clients) or is otherwise invalidated (for example, revoked or refreshed).
POST /token: Request Authorized Access Token
If a user authorizes your application with the authorization code flow, make a POST request to the https://cloud.digitalocean.com/v1/oauth/token endpoint with the appropriate parameters to request the access token.
Example
Here is an example access token request for a confidential client using curl:
curl -X POST "https://cloud.digitalocean.com/v1/oauth/token?grant_type=authorization_code
&code=f252c4bd6b1b4d249b7
&client_id=4c413ac36ac22268
&client_secret=b05a2ad77b24f3
&redirect_uri=https://example.com/callback"A public client authenticates with a PKCE code_verifier instead of a client_secret:
curl -X POST "https://cloud.digitalocean.com/v1/oauth/token?grant_type=authorization_code
&code=f252c4bd6b1b4d249b7
&client_id=4c413ac36ac22268
&code_verifier=EXAMPLE_dBjftJeZ4CVP-mB92K27uhbUJU1p1r_wW1gFWFOEjXk
&redirect_uri=https://example.com/callback"Parameters
| Parameter | Type | Necessity | Description |
|---|---|---|---|
grant_type |
string | Required | Must be set to authorization_code for an access token request. |
code |
string | Required | The code received as a response to authorization with the /authorize endpoint. |
client_id |
string | Required | The client ID for your registered OAuth application on DigitalOcean. |
client_secret |
string | Conditional | The client secret for your registered OAuth application on DigitalOcean. Required for confidential clients. Public clients omit this and send code_verifier instead. |
code_verifier |
string | Conditional | The PKCE code verifier corresponding to the code_challenge sent to the /authorize endpoint. Required for public clients. |
redirect_uri |
string | Required | Must match the callback URL that you supplied during application registration. |
Response
If the request was successful, the authorization server returns a JSON access token grant similar to the following:
{
"access_token": "doo_v1_EXAMPLE4efe8999d0892b6069bc754a78c656f8e843361e1e4d1cd04ac85c381",
"token_type": "bearer",
"expires_in": 2592000,
"refresh_token": "dor_v1_EXAMPLE3104521c47be0b580e9296453ef4y319b02b5513469f0ec72d99af2e2",
"scope": "read",
"info": {
"name": "Sammy the Shark",
"email":"[email protected]",
"uuid":"EXAMPLE0-a636-11ec-9e9d-3381ceabe039",
"team_uuid": "EXAMPLE1-a636-11ec-a6ac-1323bf96ef4d",
"team_name": "My Team"
}
}In addition to other information, the response includes two important items: access_token and refresh_token.
The access token is available to use to make requests via the DigitalOcean API until the token expires or token is otherwise invalidated.
For public clients, the access token is short-lived and expires in one hour ("expires_in": 3600). Use the refresh_token to obtain a new access token when it expires.
The following is an example public-client response:
{
"access_token": "doo_v1_EXAMPLE4efe8999d0892b6069bc754a78c656f8e843361e1e4d1cd04ac85c381",
"token_type": "Bearer",
"expires_in": 3600,
"refresh_token": "dor_v1_EXAMPLE3104521c47be0b580e9296453ef4y319b02b5513469f0ec72d99af2e2",
"scope": "read",
"info": {
"name": "Sammy the Shark",
"email":"[email protected]",
"uuid":"EXAMPLE0-a636-11ec-9e9d-3381ceabe039",
"team_uuid": "EXAMPLE1-a636-11ec-a6ac-1323bf96ef4d",
"team_name": "My Team"
}
}POST /token: Refresh Token
Each access token comes with a refresh token. You can use a refresh token exactly once to create a new access token (and refresh token). Doing so invalidates the access token that the refresh token was issued with. A common use case is refreshing an expired token.
To refresh a token, make a POST request to the https://cloud.digitalocean.com/v1/oauth/token endpoint with grant_type=refresh_token.
Example
curl -X POST "https://cloud.digitalocean.com/v1/oauth/token" \
-d "grant_type=refresh_token" \
-d "refresh_token=dor_v1_EXAMPLE3104521c47be0b580e9296453ef4y319b02b5513469f0ec72d99af2e2"Parameters
| Parameter | Type | Necessity | Description |
|---|---|---|---|
grant_type |
string | Required | Must be set to refresh_token for a token refresh request. |
refresh_token |
string | Required | The refresh_token that was received with the original access token. |
Response
The refresh token response is in the same format as the original access token grant. See the response for /token. For public clients, refreshed access tokens are also short-lived and expire after one hour.
POST /revoke: Revoke Token Flow
Revoking an access token invalidates it so that it cannot be used.
To revoke an access token, send a POST request to the https://cloud.digitalocean.com/v1/oauth/revoke endpoint with an Authorization: Bearer header and the appropriate parameters.
Parameters
| Parameter | Type | Necessity | Description |
|---|---|---|---|
token |
string | Required | Must be set to the value of the access token. |
Response
The response to this request is an empty JSON object.
/.well-known/oauth-authorization-server: Authorization Server Metadata
The authorization server publishes an OAuth 2.0 authorization server metadata document so that clients can automatically discover its endpoints and capabilities. This is useful for public clients, such as MCP clients, that register and authorize programmatically.
Send an unauthenticated GET request to the https://cloud.digitalocean.com/.well-known/oauth-authorization-server endpoint to retrieve the document.
Example
Retrieve the authorization server metadata document using curl:
curl "https://cloud.digitalocean.com/.well-known/oauth-authorization-server"Response
The authorization server returns a JSON metadata document similar to the following:
{
"issuer": "https://cloud.digitalocean.com",
"authorization_endpoint": "https://cloud.digitalocean.com/v1/oauth/authorize",
"token_endpoint": "https://cloud.digitalocean.com/v1/oauth/token",
"registration_endpoint": "https://cloud.digitalocean.com/v1/oauth/register",
"revocation_endpoint": "https://cloud.digitalocean.com/v1/oauth/revoke",
"response_types_supported": ["code"],
"response_modes_supported": ["query"],
"grant_types_supported": ["authorization_code", "refresh_token"],
"token_endpoint_auth_methods_supported": ["client_secret_post", "none"],
"code_challenge_methods_supported": ["S256"],
"client_id_metadata_document_supported": false
}The token_endpoint_auth_methods_supported field lists client_secret_post for confidential clients and none for public clients, which authenticate using PKCE instead of a client secret. The code_challenge_methods_supported field lists S256, the only PKCE code challenge method the authorization server supports.
POST /register: Dynamic Client Registration
Public clients are registered programmatically using OAuth 2.0 Dynamic Client Registration. Send an unauthenticated POST request with a JSON body to the https://cloud.digitalocean.com/v1/oauth/register endpoint to create a new client. This endpoint registers public clients only and never returns a client secret.
Example
Register a public client using curl:
curl -X POST "https://cloud.digitalocean.com/v1/oauth/register" \
-H "Content-Type: application/json" \
-d '{
"client_name": "My CLI App",
"client_uri": "https://example.com",
"redirect_uris": ["http://127.0.0.1:33418/callback", "http://localhost:33418/callback"],
"token_endpoint_auth_method": "none",
"grant_types": ["authorization_code", "refresh_token"],
"response_types": ["code"]
}'Parameters
Send the following parameters in the JSON request body.
| Parameter | Type | Necessity | Description |
|---|---|---|---|
redirect_uris |
array of strings | Required | The callback URLs where users are sent after authorization. Provide at least one and at most five. Any one of them can be used at authorization time. |
token_endpoint_auth_method |
string | Required | Must be set to none. Only public clients can be registered dynamically. |
grant_types |
array of strings | Required | Must include authorization_code. Can also include refresh_token. |
response_types |
array of strings | Optional | Defaults to ["code"]. Must be ["code"] if provided. |
client_name |
string | Optional | A human-readable name for the client. |
client_uri |
string | Optional | A URL for the client’s homepage. |
Response
If the request is successful, the authorization server returns a 201 Created response with a JSON body similar to the following:
{
"client_id": "4c413ac36ac22268",
"client_id_issued_at": 1727181600,
"redirect_uris": ["http://127.0.0.1:33418/callback", "http://localhost:33418/callback"],
"token_endpoint_auth_method": "none",
"grant_types": ["authorization_code", "refresh_token"],
"response_types": ["code"],
"client_name": "My CLI App",
"client_uri": "https://example.com",
"registration_access_token": "fedcba9876543210fedcba9876543210fedcba9876543210fedcba9876543210",
"registration_client_uri": "https://cloud.digitalocean.com/v1/oauth/register/4c413ac36ac22268"
}The response never includes a client_secret. Store the registration_access_token and registration_client_uri values, which you need to read, update, or delete the client later. The registration_access_token is shown only in this response and cannot be retrieved again.
/register/{client_id}: Manage a Registered Client
Use the https://cloud.digitalocean.com/v1/oauth/register/{client_id} endpoints to read, update, or delete a dynamically registered public client, as defined by OAuth 2.0 Dynamic Client Registration Management. Replace {client_id} with the client_id returned during registration.
All three methods require the registration_access_token returned during registration, sent as a bearer token in the Authorization header.
Get a Client
Send a GET request to retrieve the client’s current registration. The response uses the same format as the registration response but never includes the registration access token.
Retrieve a client using curl, replacing <your-registration-access-token> with the token returned during registration:
curl "https://cloud.digitalocean.com/v1/oauth/register/4c413ac36ac22268" \
-H "Authorization: Bearer <your-registration-access-token>"Update a Client
Send a PUT request with a JSON body to replace the client’s metadata. Include the client_id in the body, which must match the client_id in the URL. The same validation rules as registration apply, and the registration access token is not rotated. The response returns the updated registration in the same format as the registration response, without the registration access token.
Update a client using curl:
curl -X PUT "https://cloud.digitalocean.com/v1/oauth/register/4c413ac36ac22268" \
-H "Authorization: Bearer <your-registration-access-token>" \
-H "Content-Type: application/json" \
-d '{
"client_id": "4c413ac36ac22268",
"client_name": "renamed-client",
"client_uri": "https://renamed.example.com",
"redirect_uris": ["http://127.0.0.1:40000/callback"],
"token_endpoint_auth_method": "none",
"grant_types": ["authorization_code", "refresh_token"]
}'Delete a Client
Send a DELETE request to remove the client along with its tokens and grants. A successful request returns a 204 No Content response with an empty body.
Delete a client using curl:
curl -X DELETE "https://cloud.digitalocean.com/v1/oauth/register/4c413ac36ac22268" \
-H "Authorization: Bearer <your-registration-access-token>"