Harness Runtimepublic

Last verified 29 Oct 2026

DigitalOcean Harness Runtime API under /v2/agents. An environment is a reusable configuration that defines what an agent needs to do work; starting a session from an environment provisions an isolated sandbox. Define an environment with a YAML environment spec, or save it as an Environment Config and create sessions from {name, config_id}.

Environment Configs (/v2/agents/configs) are immutable team-scoped configurations. Soft-delete releases the active name while keeping config_id resolvable for existing sessions; clone copies a sanitized environment under a new name (credentials are never copied).

Checkpoints capture live sandbox machine state for fork and in-place rollback. Templates (/v2/agents/templates) manage team custom sandbox templates and their build history.

Triggers (/v2/agents/triggers) fire an agent run on a webhook delivery or cron schedule, each firing recorded as an execution. The session event feed (GET /v2/agents/sessions/{session_id}/events) is a Server-Sent Events stream, and port-forward (GET /v2/agents/sessions/{session_id}/port-forward/{port}) opens a WebSocket tunnel to a guest port.

Base URL https://api.digitalocean.com

Endpoints

GET List active Environment Configs for the caller's team. POST Create an Environment Config (environment spec + optional Insights opt-in). GET Get an active Environment Config and its environment spec. DELETE Soft-delete an Environment Config. POST Clone an Environment Config under a new name. GET List the sessions created from one Environment Config. GET ListSessions enumerates sessions for the caller's tenant. POST CreateSession provisions a sandbox and starts a Harness Runtime session. POST ValidatePolicy checks a manifest's tool-permission policy against the agent's capabilities without creating a session. GET ListSandboxSizes returns the customer-selectable sandbox (microVM) size catalog. GET GetSession returns the current snapshot of a session. PATCH PatchSession updates session-scoped settings on an existing session. DELETE DestroySession tears down the sandbox and marks the session DESTROYED. GET ListCheckpoints enumerates a session's checkpoints, newest first. POST CreateCheckpoint captures the session's live sandbox state as a durable checkpoint. GET GetCheckpoint returns the current snapshot of a checkpoint. DELETE DeleteCheckpoint removes a checkpoint and its underlying machine-state capture. POST RollbackToCheckpoint rewinds a session to a checkpoint. POST ForkSession creates child sessions from a checkpoint of this session. POST ResolveHITL records the user's decision on a pending HITL request. POST SendInput delivers a user chat message into the session. POST PauseSession freezes the session's microVM sandbox. POST ResumeSession explicitly thaws a PAUSED session's microVM sandbox. POST ExecInSandbox runs a one-shot command inside the session's sandbox. GET Download a file or tar archive from the session's sandbox workspace. POST Start a staged (large-file) workspace transfer. GET Get the status of a staged workspace transfer. POST Cancel a staged workspace transfer. POST Finalize a staged upload. POST Mint presigned PUT URLs for one or more multipart upload parts. POST Upload a file or tar archive into the session's sandbox workspace. GET StreamSessionEvents opens the session's Server-Sent Events feed. GET PortForwardSession opens a WebSocket tunnel to a guest TCP port. GET GetIngressURL returns the public HTTPS URL of the session's OpenHands Agent Server. GET ListTeamTemplates returns the caller's team custom templates. POST CreateTemplate creates a team custom template and kicks a build. GET GetTemplate returns a team custom template by public id. PUT UpdateTemplate updates a team template's source and kicks a new build. DELETE DeleteTemplate deletes a team custom template. GET ListTemplateBuilds returns build history for a template. GET GetTemplateBuild returns a single template build. GET ListTriggers enumerates the calling team's triggers. POST CreateTrigger creates a webhook or cron trigger. GET GetTriggerBySession reverse-looks-up the trigger that produced or binds a session. GET ListReusableSessions lists the team's PAUSED sessions for the reuse picker. GET GetTrigger returns a single trigger by id. PATCH UpdateTrigger updates, pauses, or re-enables a trigger. DELETE DeleteTrigger soft-deletes a trigger. GET ListTriggerExecutions returns a trigger's execution history. GET GetTriggerExecution returns a single execution, including its payload. POST CancelExecution ends a running execution and frees the trigger's in-flight slot. POST RotateTriggerSecret issues a new webhook secret. POST ReceiveTriggerWebhook accepts a signed delivery from an external system. GET ListWebhookProviders lists supported webhook providers for the create-trigger UI.

GET List active Environment Configs for the caller's team.

/v2/agents/configs
Authorizations: bearer_auth (1 scope)
Http: Bearer
Required scopes: agent_harness_session:read

OAuth Authentication

In order to interact with the DigitalOcean API, you or your application must authenticate.

The DigitalOcean API handles this through OAuth, an open standard for authorization. OAuth allows you to delegate access to your account. Scopes can be used to grant full access, read-only access, or access to a specific set of endpoints.

You can generate an OAuth token by visiting the Apps & API section of the DigitalOcean control panel for your account.

An OAuth token functions as a complete authentication request. In effect, it acts as a substitute for a username and password pair.

Because of this, it is absolutely essential that you keep your OAuth tokens secure. In fact, upon generation, the web interface will only display each token a single time in order to prevent the token from being compromised.

DigitalOcean access tokens begin with an identifiable prefix in order to distinguish them from other similar tokens.

  • dop_v1_ for personal access tokens generated in the control panel
  • doo_v1_ for tokens generated by applications using the OAuth flow
  • dor_v1_ for OAuth refresh tokens

Scopes

Scopes act like permissions assigned to an API token. These permissions determine what actions the token can perform. You can create API tokens that grant read-only access, full access, or limited access to specific endpoints by using custom scopes.

Generally, scopes are designed to match HTTP verbs and common CRUD operations (Create, Read, Update, Delete).

HTTP Verb CRUD Operation Scope
GET Read <resource>:read
POST Create <resource>:create
PUT/PATCH Update <resource>:update
DELETE Delete <resource>:delete

For example, creating a new Droplet by making a POST request to the /v2/droplets endpoint requires the droplet:create scope while listing Droplets by making a GET request to the /v2/droplets endpoint requires the droplet:read scope.

Each endpoint below specifies which scope is required to access it when using custom scopes.

How to Authenticate with OAuth

In order to make an authenticated request, include a bearer-type Authorization header containing your OAuth token. All requests must be made over HTTPS.

Authenticate with a Bearer Authorization Header

curl -X $HTTP_METHOD -H "Authorization: Bearer $DIGITALOCEAN_TOKEN" "https://api.digitalocean.com/v2/$OBJECT"

Returns lightweight team-scoped config metadata without loading or returning environment-spec JSON. Soft-deleted configs are excluded.

Query Parameters

page_size integer (int32) 1 – 200 optional
Example: 50

Page size. Defaults to 50 when omitted. Values above 200 are rejected.

Default: 50
page_token string optional

Opaque keyset cursor returned by the previous page.

search string optional
Example: support

Optional case-insensitive substring filter on config name (contains). Empty or omitted returns the unfiltered page. At most 64 characters.

curl -X GET \
  -H "Content-Type: application/json" \
  -H "Authorization: Bearer $DIGITALOCEAN_TOKEN" \
  "https://api.digitalocean.com/v2/agents/configs"
curl -X GET \
  -H "Authorization: Bearer $API_TOKEN" \
  "https://api.digitalocean.com/v2/agents/configs"

Responses

200

A page of active Environment Configs.

ratelimit-limit integer

The default limit on number of requests that can be made per hour and per minute. Current rate limits are 5000 requests per hour and 250 requests per minute.

ratelimit-remaining integer

The number of requests in your hourly quota that remain before you hit your request limit. See https://docs.digitalocean.com/reference/api/reference/#rate-limit for information about how requests expire.

ratelimit-reset integer

The time when the oldest request will expire. The value is given in Unix epoch time. See https://docs.digitalocean.com/reference/api/reference/#rate-limit for information about how requests expire.

configs array of object optional
Show child properties
agentspec_schema_version string required
Example: agents.digitalocean.com/v1alpha1

The manifest contract the server accepted at create time: the manifest's own apiVersion for legacy envelope parses (currently agents.digitalocean.com/v1alpha1), or agents.digitalocean.com/flat.v1 for flat-format parses.

content_hash string required
Example: 75803fef24dc731824ecd4a1853c76153c7d8503534092b94da3ca3f31a882f4

Lowercase SHA-256 hex digest of the canonical sanitized manifest JSON.

created_at string (date-time) required
Example: 2026-08-01T12:00:00Z
created_by string required
Example: user-1

Authenticated user identity that created the config.

id string (uuid) required
Example: 019fb39c-14d9-7080-933e-b9b90e25acda
name string required
Example: support-agent
updated_at string (date-time) required
Example: 2026-08-01T12:00:00Z
next_page_token string optional
400

Invalid pagination input.

ratelimit-limit integer

The default limit on number of requests that can be made per hour and per minute. Current rate limits are 5000 requests per hour and 250 requests per minute.

ratelimit-remaining integer

The number of requests in your hourly quota that remain before you hit your request limit. See https://docs.digitalocean.com/reference/api/reference/#rate-limit for information about how requests expire.

ratelimit-reset integer

The time when the oldest request will expire. The value is given in Unix epoch time. See https://docs.digitalocean.com/reference/api/reference/#rate-limit for information about how requests expire.

id string required
Example: not_found

A short identifier corresponding to the HTTP status code returned. For example, the ID for a response returning a 404 status code would be "not_found."

message string required
Example: The resource you were accessing could not be found.

A message providing additional information about the error, including details to help resolve it when possible.

request_id string optional
Example: 4d9d8375-3c56-4925-a3e7-eb137fed17e9

Optionally, some endpoints may include a request ID that should be provided when reporting bugs or opening support tickets to help identify the issue.

401

Authentication failed due to invalid credentials.

ratelimit-limit integer

The default limit on number of requests that can be made per hour and per minute. Current rate limits are 5000 requests per hour and 250 requests per minute.

ratelimit-remaining integer

The number of requests in your hourly quota that remain before you hit your request limit. See https://docs.digitalocean.com/reference/api/reference/#rate-limit for information about how requests expire.

ratelimit-reset integer

The time when the oldest request will expire. The value is given in Unix epoch time. See https://docs.digitalocean.com/reference/api/reference/#rate-limit for information about how requests expire.

id string required
Example: not_found

A short identifier corresponding to the HTTP status code returned. For example, the ID for a response returning a 404 status code would be "not_found."

message string required
Example: The resource you were accessing could not be found.

A message providing additional information about the error, including details to help resolve it when possible.

request_id string optional
Example: 4d9d8375-3c56-4925-a3e7-eb137fed17e9

Optionally, some endpoints may include a request ID that should be provided when reporting bugs or opening support tickets to help identify the issue.

429

The API rate limit has been exceeded.

ratelimit-limit integer

The default limit on number of requests that can be made per hour and per minute. Current rate limits are 5000 requests per hour and 250 requests per minute.

ratelimit-remaining integer

The number of requests in your hourly quota that remain before you hit your request limit. See https://docs.digitalocean.com/reference/api/reference/#rate-limit for information about how requests expire.

ratelimit-reset integer

The time when the oldest request will expire. The value is given in Unix epoch time. See https://docs.digitalocean.com/reference/api/reference/#rate-limit for information about how requests expire.

id string required
Example: not_found

A short identifier corresponding to the HTTP status code returned. For example, the ID for a response returning a 404 status code would be "not_found."

message string required
Example: The resource you were accessing could not be found.

A message providing additional information about the error, including details to help resolve it when possible.

request_id string optional
Example: 4d9d8375-3c56-4925-a3e7-eb137fed17e9

Optionally, some endpoints may include a request ID that should be provided when reporting bugs or opening support tickets to help identify the issue.

500

There was a server error.

ratelimit-limit integer

The default limit on number of requests that can be made per hour and per minute. Current rate limits are 5000 requests per hour and 250 requests per minute.

ratelimit-remaining integer

The number of requests in your hourly quota that remain before you hit your request limit. See https://docs.digitalocean.com/reference/api/reference/#rate-limit for information about how requests expire.

ratelimit-reset integer

The time when the oldest request will expire. The value is given in Unix epoch time. See https://docs.digitalocean.com/reference/api/reference/#rate-limit for information about how requests expire.

id string required
Example: not_found

A short identifier corresponding to the HTTP status code returned. For example, the ID for a response returning a 404 status code would be "not_found."

message string required
Example: The resource you were accessing could not be found.

A message providing additional information about the error, including details to help resolve it when possible.

request_id string optional
Example: 4d9d8375-3c56-4925-a3e7-eb137fed17e9

Optionally, some endpoints may include a request ID that should be provided when reporting bugs or opening support tickets to help identify the issue.

default

There was an unexpected error.

ratelimit-limit integer

The default limit on number of requests that can be made per hour and per minute. Current rate limits are 5000 requests per hour and 250 requests per minute.

ratelimit-remaining integer

The number of requests in your hourly quota that remain before you hit your request limit. See https://docs.digitalocean.com/reference/api/reference/#rate-limit for information about how requests expire.

ratelimit-reset integer

The time when the oldest request will expire. The value is given in Unix epoch time. See https://docs.digitalocean.com/reference/api/reference/#rate-limit for information about how requests expire.

id string required
Example: not_found

A short identifier corresponding to the HTTP status code returned. For example, the ID for a response returning a 404 status code would be "not_found."

message string required
Example: The resource you were accessing could not be found.

A message providing additional information about the error, including details to help resolve it when possible.

request_id string optional
Example: 4d9d8375-3c56-4925-a3e7-eb137fed17e9

Optionally, some endpoints may include a request ID that should be provided when reporting bugs or opening support tickets to help identify the issue.

{
  "configs": [
    {
      "agentspec_schema_version": "agents.digitalocean.com/v1alpha1",
      "content_hash": "75803fef24dc731824ecd4a1853c76153c7d8503534092b94da3ca3f31a882f4",
      "created_at": "2026-08-01T12:00:00Z",
      "created_by": "user-1",
      "id": "019fb39c-14d9-7080-933e-b9b90e25acda",
      "name": "support-agent",
      "updated_at": "2026-08-01T12:00:00Z"
    }
  ],
  "next_page_token": ""
}
{
  "id": "not_found",
  "message": "The resource you were accessing could not be found.",
  "request_id": "4d9d8375-3c56-4925-a3e7-eb137fed17e9"
}
{
  "id": "unauthorized",
  "message": "Unable to authenticate you."
}
{
  "id": "too_many_requests",
  "message": "API rate limit exceeded."
}
{
  "id": "server_error",
  "message": "Unexpected server-side error"
}
{
  "id": "example_error",
  "message": "some error message"
}

POST Create an Environment Config (environment spec + optional Insights opt-in).

/v2/agents/configs
Authorizations: bearer_auth (1 scope)
Http: Bearer
Required scopes: agent_harness_session:create

OAuth Authentication

In order to interact with the DigitalOcean API, you or your application must authenticate.

The DigitalOcean API handles this through OAuth, an open standard for authorization. OAuth allows you to delegate access to your account. Scopes can be used to grant full access, read-only access, or access to a specific set of endpoints.

You can generate an OAuth token by visiting the Apps & API section of the DigitalOcean control panel for your account.

An OAuth token functions as a complete authentication request. In effect, it acts as a substitute for a username and password pair.

Because of this, it is absolutely essential that you keep your OAuth tokens secure. In fact, upon generation, the web interface will only display each token a single time in order to prevent the token from being compromised.

DigitalOcean access tokens begin with an identifiable prefix in order to distinguish them from other similar tokens.

  • dop_v1_ for personal access tokens generated in the control panel
  • doo_v1_ for tokens generated by applications using the OAuth flow
  • dor_v1_ for OAuth refresh tokens

Scopes

Scopes act like permissions assigned to an API token. These permissions determine what actions the token can perform. You can create API tokens that grant read-only access, full access, or limited access to specific endpoints by using custom scopes.

Generally, scopes are designed to match HTTP verbs and common CRUD operations (Create, Read, Update, Delete).

HTTP Verb CRUD Operation Scope
GET Read <resource>:read
POST Create <resource>:create
PUT/PATCH Update <resource>:update
DELETE Delete <resource>:delete

For example, creating a new Droplet by making a POST request to the /v2/droplets endpoint requires the droplet:create scope while listing Droplets by making a GET request to the /v2/droplets endpoint requires the droplet:read scope.

Each endpoint below specifies which scope is required to access it when using custom scopes.

How to Authenticate with OAuth

In order to make an authenticated request, include a bearer-type Authorization header containing your OAuth token. All requests must be made over HTTPS.

Authenticate with a Bearer Authorization Header

curl -X $HTTP_METHOD -H "Authorization: Bearer $DIGITALOCEAN_TOKEN" "https://api.digitalocean.com/v2/$OBJECT"

Accepts name, environment-spec YAML text, and optional Insights telemetry opt-in. Tenant secrets are declared inside the environment spec (write-only values), not as sibling request fields. Responses never echo secret values; GET/create may include credential slot metadata (name/source/provider only). Configs are immutable after create.

Request Body: application/json

Environment Config create body. Secret values live in the environment-spec YAML and are never returned.

insights object optional
manifest_yaml string required

Customer environment-spec YAML text. The HTTP JSON body is capped at 1 MiB and this field is capped at 512 KiB.

name string required
Example: support-agent

Config name, case-insensitively unique among the team's active configs.

Content type application/json
{
  "insights": {
    "logs": true,
    "metrics": true,
    "traces": true
  },
  "manifest_yaml": "apiVersion: agents.digitalocean.com/v1alpha1\nkind: Agent\nspec:\n  runtime:\n    adapter: opencode\n",
  "name": "support-agent"
}
curl -X POST \
  -H "Content-Type: application/json" \
  -H "Authorization: Bearer $DIGITALOCEAN_TOKEN" \
  -d '{"name":"support-agent","manifest_yaml":"apiVersion: agents.digitalocean.com/v1alpha1\nkind: Agent\nspec:\n  runtime:\n    adapter: opencode\n"}' \
  "https://api.digitalocean.com/v2/agents/configs"
curl -X POST \
  -H "Authorization: Bearer $API_TOKEN" \
  -H "Content-Type: application/json" \
  -d '{
  "insights": {
    "logs": true,
    "metrics": true,
    "traces": true
  },
  "manifest_yaml": "apiVersion: agents.digitalocean.com/v1alpha1\nkind: Agent\nspec:\n  runtime:\n    adapter: opencode\n",
  "name": "support-agent"
}' \
  "https://api.digitalocean.com/v2/agents/configs"

Responses

201

Config created.

ratelimit-limit integer

The default limit on number of requests that can be made per hour and per minute. Current rate limits are 5000 requests per hour and 250 requests per minute.

ratelimit-remaining integer

The number of requests in your hourly quota that remain before you hit your request limit. See https://docs.digitalocean.com/reference/api/reference/#rate-limit for information about how requests expire.

ratelimit-reset integer

The time when the oldest request will expire. The value is given in Unix epoch time. See https://docs.digitalocean.com/reference/api/reference/#rate-limit for information about how requests expire.

config object optional

Immutable team-scoped Environment Config: one sanitized manifest per config. There is no update; clone to a new config to change content.

Show child properties
agentspec_schema_version string required
Example: agents.digitalocean.com/v1alpha1

The manifest contract the server accepted at create time: the manifest's own apiVersion for legacy envelope parses (currently agents.digitalocean.com/v1alpha1), or agents.digitalocean.com/flat.v1 for flat-format parses.

content_hash string required
Example: 75803fef24dc731824ecd4a1853c76153c7d8503534092b94da3ca3f31a882f4

Lowercase SHA-256 hex digest of the canonical sanitized manifest JSON.

created_at string (date-time) required
Example: 2026-08-01T12:00:00Z
created_by string required
Example: user-1

Authenticated user identity that created the config.

credentials array of object optional

Redacted credential slot metadata (name/source/provider). Secret values are never included.

Show child properties
name string required
Example: OPENAI_API_KEY
provider string optional
Example: openai
source string, one of: tenantSecret, oauth optional
Example: tenantSecret
id string (uuid) required
Example: 019fb39c-14d9-7080-933e-b9b90e25acda
insights object optional
manifest object required

Canonical runnable environment spec JSON, immutable after create. Validated non-secret spec.env and spec.permissions remain; spec.secrets retains name/source/provider but omits ref and the write-only value; metadata.name is cleared while safe metadata such as labels remains.

name string required
Example: support-agent
updated_at string (date-time) required
Example: 2026-08-01T12:00:00Z
400

Invalid name, JSON wrapper, or environment spec.

ratelimit-limit integer

The default limit on number of requests that can be made per hour and per minute. Current rate limits are 5000 requests per hour and 250 requests per minute.

ratelimit-remaining integer

The number of requests in your hourly quota that remain before you hit your request limit. See https://docs.digitalocean.com/reference/api/reference/#rate-limit for information about how requests expire.

ratelimit-reset integer

The time when the oldest request will expire. The value is given in Unix epoch time. See https://docs.digitalocean.com/reference/api/reference/#rate-limit for information about how requests expire.

id string required
Example: not_found

A short identifier corresponding to the HTTP status code returned. For example, the ID for a response returning a 404 status code would be "not_found."

message string required
Example: The resource you were accessing could not be found.

A message providing additional information about the error, including details to help resolve it when possible.

request_id string optional
Example: 4d9d8375-3c56-4925-a3e7-eb137fed17e9

Optionally, some endpoints may include a request ID that should be provided when reporting bugs or opening support tickets to help identify the issue.

401

Authentication failed due to invalid credentials.

ratelimit-limit integer

The default limit on number of requests that can be made per hour and per minute. Current rate limits are 5000 requests per hour and 250 requests per minute.

ratelimit-remaining integer

The number of requests in your hourly quota that remain before you hit your request limit. See https://docs.digitalocean.com/reference/api/reference/#rate-limit for information about how requests expire.

ratelimit-reset integer

The time when the oldest request will expire. The value is given in Unix epoch time. See https://docs.digitalocean.com/reference/api/reference/#rate-limit for information about how requests expire.

id string required
Example: not_found

A short identifier corresponding to the HTTP status code returned. For example, the ID for a response returning a 404 status code would be "not_found."

message string required
Example: The resource you were accessing could not be found.

A message providing additional information about the error, including details to help resolve it when possible.

request_id string optional
Example: 4d9d8375-3c56-4925-a3e7-eb137fed17e9

Optionally, some endpoints may include a request ID that should be provided when reporting bugs or opening support tickets to help identify the issue.

409

An active config with this name already exists for the team.

ratelimit-limit integer

The default limit on number of requests that can be made per hour and per minute. Current rate limits are 5000 requests per hour and 250 requests per minute.

ratelimit-remaining integer

The number of requests in your hourly quota that remain before you hit your request limit. See https://docs.digitalocean.com/reference/api/reference/#rate-limit for information about how requests expire.

ratelimit-reset integer

The time when the oldest request will expire. The value is given in Unix epoch time. See https://docs.digitalocean.com/reference/api/reference/#rate-limit for information about how requests expire.

id string required
Example: not_found

A short identifier corresponding to the HTTP status code returned. For example, the ID for a response returning a 404 status code would be "not_found."

message string required
Example: The resource you were accessing could not be found.

A message providing additional information about the error, including details to help resolve it when possible.

request_id string optional
Example: 4d9d8375-3c56-4925-a3e7-eb137fed17e9

Optionally, some endpoints may include a request ID that should be provided when reporting bugs or opening support tickets to help identify the issue.

413

Request body exceeds 1 MiB.

ratelimit-limit integer

The default limit on number of requests that can be made per hour and per minute. Current rate limits are 5000 requests per hour and 250 requests per minute.

ratelimit-remaining integer

The number of requests in your hourly quota that remain before you hit your request limit. See https://docs.digitalocean.com/reference/api/reference/#rate-limit for information about how requests expire.

ratelimit-reset integer

The time when the oldest request will expire. The value is given in Unix epoch time. See https://docs.digitalocean.com/reference/api/reference/#rate-limit for information about how requests expire.

id string required
Example: not_found

A short identifier corresponding to the HTTP status code returned. For example, the ID for a response returning a 404 status code would be "not_found."

message string required
Example: The resource you were accessing could not be found.

A message providing additional information about the error, including details to help resolve it when possible.

request_id string optional
Example: 4d9d8375-3c56-4925-a3e7-eb137fed17e9

Optionally, some endpoints may include a request ID that should be provided when reporting bugs or opening support tickets to help identify the issue.

415

Content-Type is not application/json.

ratelimit-limit integer

The default limit on number of requests that can be made per hour and per minute. Current rate limits are 5000 requests per hour and 250 requests per minute.

ratelimit-remaining integer

The number of requests in your hourly quota that remain before you hit your request limit. See https://docs.digitalocean.com/reference/api/reference/#rate-limit for information about how requests expire.

ratelimit-reset integer

The time when the oldest request will expire. The value is given in Unix epoch time. See https://docs.digitalocean.com/reference/api/reference/#rate-limit for information about how requests expire.

id string required
Example: not_found

A short identifier corresponding to the HTTP status code returned. For example, the ID for a response returning a 404 status code would be "not_found."

message string required
Example: The resource you were accessing could not be found.

A message providing additional information about the error, including details to help resolve it when possible.

request_id string optional
Example: 4d9d8375-3c56-4925-a3e7-eb137fed17e9

Optionally, some endpoints may include a request ID that should be provided when reporting bugs or opening support tickets to help identify the issue.

429

The API rate limit has been exceeded.

ratelimit-limit integer

The default limit on number of requests that can be made per hour and per minute. Current rate limits are 5000 requests per hour and 250 requests per minute.

ratelimit-remaining integer

The number of requests in your hourly quota that remain before you hit your request limit. See https://docs.digitalocean.com/reference/api/reference/#rate-limit for information about how requests expire.

ratelimit-reset integer

The time when the oldest request will expire. The value is given in Unix epoch time. See https://docs.digitalocean.com/reference/api/reference/#rate-limit for information about how requests expire.

id string required
Example: not_found

A short identifier corresponding to the HTTP status code returned. For example, the ID for a response returning a 404 status code would be "not_found."

message string required
Example: The resource you were accessing could not be found.

A message providing additional information about the error, including details to help resolve it when possible.

request_id string optional
Example: 4d9d8375-3c56-4925-a3e7-eb137fed17e9

Optionally, some endpoints may include a request ID that should be provided when reporting bugs or opening support tickets to help identify the issue.

500

There was a server error.

ratelimit-limit integer

The default limit on number of requests that can be made per hour and per minute. Current rate limits are 5000 requests per hour and 250 requests per minute.

ratelimit-remaining integer

The number of requests in your hourly quota that remain before you hit your request limit. See https://docs.digitalocean.com/reference/api/reference/#rate-limit for information about how requests expire.

ratelimit-reset integer

The time when the oldest request will expire. The value is given in Unix epoch time. See https://docs.digitalocean.com/reference/api/reference/#rate-limit for information about how requests expire.

id string required
Example: not_found

A short identifier corresponding to the HTTP status code returned. For example, the ID for a response returning a 404 status code would be "not_found."

message string required
Example: The resource you were accessing could not be found.

A message providing additional information about the error, including details to help resolve it when possible.

request_id string optional
Example: 4d9d8375-3c56-4925-a3e7-eb137fed17e9

Optionally, some endpoints may include a request ID that should be provided when reporting bugs or opening support tickets to help identify the issue.

default

There was an unexpected error.

ratelimit-limit integer

The default limit on number of requests that can be made per hour and per minute. Current rate limits are 5000 requests per hour and 250 requests per minute.

ratelimit-remaining integer

The number of requests in your hourly quota that remain before you hit your request limit. See https://docs.digitalocean.com/reference/api/reference/#rate-limit for information about how requests expire.

ratelimit-reset integer

The time when the oldest request will expire. The value is given in Unix epoch time. See https://docs.digitalocean.com/reference/api/reference/#rate-limit for information about how requests expire.

id string required
Example: not_found

A short identifier corresponding to the HTTP status code returned. For example, the ID for a response returning a 404 status code would be "not_found."

message string required
Example: The resource you were accessing could not be found.

A message providing additional information about the error, including details to help resolve it when possible.

request_id string optional
Example: 4d9d8375-3c56-4925-a3e7-eb137fed17e9

Optionally, some endpoints may include a request ID that should be provided when reporting bugs or opening support tickets to help identify the issue.

{
  "config": {
    "agentspec_schema_version": "agents.digitalocean.com/v1alpha1",
    "content_hash": "75803fef24dc731824ecd4a1853c76153c7d8503534092b94da3ca3f31a882f4",
    "created_at": "2026-08-01T12:00:00Z",
    "created_by": "user-1",
    "credentials": [],
    "id": "019fb39c-14d9-7080-933e-b9b90e25acda",
    "insights": {
      "logs": true,
      "metrics": true,
      "traces": true
    },
    "manifest": {
      "apiVersion": "agents.digitalocean.com/v1alpha1",
      "kind": "Agent"
    },
    "name": "support-agent",
    "updated_at": "2026-08-01T12:00:00Z"
  }
}
{
  "id": "not_found",
  "message": "The resource you were accessing could not be found.",
  "request_id": "4d9d8375-3c56-4925-a3e7-eb137fed17e9"
}
{
  "id": "unauthorized",
  "message": "Unable to authenticate you."
}
{
  "id": "not_found",
  "message": "The resource you were accessing could not be found.",
  "request_id": "4d9d8375-3c56-4925-a3e7-eb137fed17e9"
}
{
  "id": "not_found",
  "message": "The resource you were accessing could not be found.",
  "request_id": "4d9d8375-3c56-4925-a3e7-eb137fed17e9"
}
{
  "id": "not_found",
  "message": "The resource you were accessing could not be found.",
  "request_id": "4d9d8375-3c56-4925-a3e7-eb137fed17e9"
}
{
  "id": "too_many_requests",
  "message": "API rate limit exceeded."
}
{
  "id": "server_error",
  "message": "Unexpected server-side error"
}
{
  "id": "example_error",
  "message": "some error message"
}

GET Get an active Environment Config and its environment spec.

/v2/agents/configs/{config_id}
Authorizations: bearer_auth (1 scope)
Http: Bearer
Required scopes: agent_harness_session:read

OAuth Authentication

In order to interact with the DigitalOcean API, you or your application must authenticate.

The DigitalOcean API handles this through OAuth, an open standard for authorization. OAuth allows you to delegate access to your account. Scopes can be used to grant full access, read-only access, or access to a specific set of endpoints.

You can generate an OAuth token by visiting the Apps & API section of the DigitalOcean control panel for your account.

An OAuth token functions as a complete authentication request. In effect, it acts as a substitute for a username and password pair.

Because of this, it is absolutely essential that you keep your OAuth tokens secure. In fact, upon generation, the web interface will only display each token a single time in order to prevent the token from being compromised.

DigitalOcean access tokens begin with an identifiable prefix in order to distinguish them from other similar tokens.

  • dop_v1_ for personal access tokens generated in the control panel
  • doo_v1_ for tokens generated by applications using the OAuth flow
  • dor_v1_ for OAuth refresh tokens

Scopes

Scopes act like permissions assigned to an API token. These permissions determine what actions the token can perform. You can create API tokens that grant read-only access, full access, or limited access to specific endpoints by using custom scopes.

Generally, scopes are designed to match HTTP verbs and common CRUD operations (Create, Read, Update, Delete).

HTTP Verb CRUD Operation Scope
GET Read <resource>:read
POST Create <resource>:create
PUT/PATCH Update <resource>:update
DELETE Delete <resource>:delete

For example, creating a new Droplet by making a POST request to the /v2/droplets endpoint requires the droplet:create scope while listing Droplets by making a GET request to the /v2/droplets endpoint requires the droplet:read scope.

Each endpoint below specifies which scope is required to access it when using custom scopes.

How to Authenticate with OAuth

In order to make an authenticated request, include a bearer-type Authorization header containing your OAuth token. All requests must be made over HTTPS.

Authenticate with a Bearer Authorization Header

curl -X $HTTP_METHOD -H "Authorization: Bearer $DIGITALOCEAN_TOKEN" "https://api.digitalocean.com/v2/$OBJECT"

Returns one team-scoped Environment Config including the sanitized environment spec and redacted credential slot metadata. Secret values are never returned.

Path Parameters

config_id string (uuid) required
Example: 019fb39c-14d9-7080-933e-b9b90e25acda

The Environment Config UUID.

curl -X GET \
  -H "Content-Type: application/json" \
  -H "Authorization: Bearer $DIGITALOCEAN_TOKEN" \
  "https://api.digitalocean.com/v2/agents/configs/019fb39c-14d9-7080-933e-b9b90e25acda"
curl -X GET \
  -H "Authorization: Bearer $API_TOKEN" \
  "https://api.digitalocean.com/v2/agents/configs/{config_id}"

Responses

200

The team-scoped config.

ratelimit-limit integer

The default limit on number of requests that can be made per hour and per minute. Current rate limits are 5000 requests per hour and 250 requests per minute.

ratelimit-remaining integer

The number of requests in your hourly quota that remain before you hit your request limit. See https://docs.digitalocean.com/reference/api/reference/#rate-limit for information about how requests expire.

ratelimit-reset integer

The time when the oldest request will expire. The value is given in Unix epoch time. See https://docs.digitalocean.com/reference/api/reference/#rate-limit for information about how requests expire.

config object optional

Immutable team-scoped Environment Config: one sanitized manifest per config. There is no update; clone to a new config to change content.

Show child properties
agentspec_schema_version string required
Example: agents.digitalocean.com/v1alpha1

The manifest contract the server accepted at create time: the manifest's own apiVersion for legacy envelope parses (currently agents.digitalocean.com/v1alpha1), or agents.digitalocean.com/flat.v1 for flat-format parses.

content_hash string required
Example: 75803fef24dc731824ecd4a1853c76153c7d8503534092b94da3ca3f31a882f4

Lowercase SHA-256 hex digest of the canonical sanitized manifest JSON.

created_at string (date-time) required
Example: 2026-08-01T12:00:00Z
created_by string required
Example: user-1

Authenticated user identity that created the config.

credentials array of object optional

Redacted credential slot metadata (name/source/provider). Secret values are never included.

Show child properties
name string required
Example: OPENAI_API_KEY
provider string optional
Example: openai
source string, one of: tenantSecret, oauth optional
Example: tenantSecret
id string (uuid) required
Example: 019fb39c-14d9-7080-933e-b9b90e25acda
insights object optional
manifest object required

Canonical runnable environment spec JSON, immutable after create. Validated non-secret spec.env and spec.permissions remain; spec.secrets retains name/source/provider but omits ref and the write-only value; metadata.name is cleared while safe metadata such as labels remains.

name string required
Example: support-agent
updated_at string (date-time) required
Example: 2026-08-01T12:00:00Z
400

config_id is not a UUID.

ratelimit-limit integer

The default limit on number of requests that can be made per hour and per minute. Current rate limits are 5000 requests per hour and 250 requests per minute.

ratelimit-remaining integer

The number of requests in your hourly quota that remain before you hit your request limit. See https://docs.digitalocean.com/reference/api/reference/#rate-limit for information about how requests expire.

ratelimit-reset integer

The time when the oldest request will expire. The value is given in Unix epoch time. See https://docs.digitalocean.com/reference/api/reference/#rate-limit for information about how requests expire.

id string required
Example: not_found

A short identifier corresponding to the HTTP status code returned. For example, the ID for a response returning a 404 status code would be "not_found."

message string required
Example: The resource you were accessing could not be found.

A message providing additional information about the error, including details to help resolve it when possible.

request_id string optional
Example: 4d9d8375-3c56-4925-a3e7-eb137fed17e9

Optionally, some endpoints may include a request ID that should be provided when reporting bugs or opening support tickets to help identify the issue.

401

Authentication failed due to invalid credentials.

ratelimit-limit integer

The default limit on number of requests that can be made per hour and per minute. Current rate limits are 5000 requests per hour and 250 requests per minute.

ratelimit-remaining integer

The number of requests in your hourly quota that remain before you hit your request limit. See https://docs.digitalocean.com/reference/api/reference/#rate-limit for information about how requests expire.

ratelimit-reset integer

The time when the oldest request will expire. The value is given in Unix epoch time. See https://docs.digitalocean.com/reference/api/reference/#rate-limit for information about how requests expire.

id string required
Example: not_found

A short identifier corresponding to the HTTP status code returned. For example, the ID for a response returning a 404 status code would be "not_found."

message string required
Example: The resource you were accessing could not be found.

A message providing additional information about the error, including details to help resolve it when possible.

request_id string optional
Example: 4d9d8375-3c56-4925-a3e7-eb137fed17e9

Optionally, some endpoints may include a request ID that should be provided when reporting bugs or opening support tickets to help identify the issue.

404

The resource was not found.

ratelimit-limit integer

The default limit on number of requests that can be made per hour and per minute. Current rate limits are 5000 requests per hour and 250 requests per minute.

ratelimit-remaining integer

The number of requests in your hourly quota that remain before you hit your request limit. See https://docs.digitalocean.com/reference/api/reference/#rate-limit for information about how requests expire.

ratelimit-reset integer

The time when the oldest request will expire. The value is given in Unix epoch time. See https://docs.digitalocean.com/reference/api/reference/#rate-limit for information about how requests expire.

id string required
Example: not_found

A short identifier corresponding to the HTTP status code returned. For example, the ID for a response returning a 404 status code would be "not_found."

message string required
Example: The resource you were accessing could not be found.

A message providing additional information about the error, including details to help resolve it when possible.

request_id string optional
Example: 4d9d8375-3c56-4925-a3e7-eb137fed17e9

Optionally, some endpoints may include a request ID that should be provided when reporting bugs or opening support tickets to help identify the issue.

429

The API rate limit has been exceeded.

ratelimit-limit integer

The default limit on number of requests that can be made per hour and per minute. Current rate limits are 5000 requests per hour and 250 requests per minute.

ratelimit-remaining integer

The number of requests in your hourly quota that remain before you hit your request limit. See https://docs.digitalocean.com/reference/api/reference/#rate-limit for information about how requests expire.

ratelimit-reset integer

The time when the oldest request will expire. The value is given in Unix epoch time. See https://docs.digitalocean.com/reference/api/reference/#rate-limit for information about how requests expire.

id string required
Example: not_found

A short identifier corresponding to the HTTP status code returned. For example, the ID for a response returning a 404 status code would be "not_found."

message string required
Example: The resource you were accessing could not be found.

A message providing additional information about the error, including details to help resolve it when possible.

request_id string optional
Example: 4d9d8375-3c56-4925-a3e7-eb137fed17e9

Optionally, some endpoints may include a request ID that should be provided when reporting bugs or opening support tickets to help identify the issue.

500

There was a server error.

ratelimit-limit integer

The default limit on number of requests that can be made per hour and per minute. Current rate limits are 5000 requests per hour and 250 requests per minute.

ratelimit-remaining integer

The number of requests in your hourly quota that remain before you hit your request limit. See https://docs.digitalocean.com/reference/api/reference/#rate-limit for information about how requests expire.

ratelimit-reset integer

The time when the oldest request will expire. The value is given in Unix epoch time. See https://docs.digitalocean.com/reference/api/reference/#rate-limit for information about how requests expire.

id string required
Example: not_found

A short identifier corresponding to the HTTP status code returned. For example, the ID for a response returning a 404 status code would be "not_found."

message string required
Example: The resource you were accessing could not be found.

A message providing additional information about the error, including details to help resolve it when possible.

request_id string optional
Example: 4d9d8375-3c56-4925-a3e7-eb137fed17e9

Optionally, some endpoints may include a request ID that should be provided when reporting bugs or opening support tickets to help identify the issue.

default

There was an unexpected error.

ratelimit-limit integer

The default limit on number of requests that can be made per hour and per minute. Current rate limits are 5000 requests per hour and 250 requests per minute.

ratelimit-remaining integer

The number of requests in your hourly quota that remain before you hit your request limit. See https://docs.digitalocean.com/reference/api/reference/#rate-limit for information about how requests expire.

ratelimit-reset integer

The time when the oldest request will expire. The value is given in Unix epoch time. See https://docs.digitalocean.com/reference/api/reference/#rate-limit for information about how requests expire.

id string required
Example: not_found

A short identifier corresponding to the HTTP status code returned. For example, the ID for a response returning a 404 status code would be "not_found."

message string required
Example: The resource you were accessing could not be found.

A message providing additional information about the error, including details to help resolve it when possible.

request_id string optional
Example: 4d9d8375-3c56-4925-a3e7-eb137fed17e9

Optionally, some endpoints may include a request ID that should be provided when reporting bugs or opening support tickets to help identify the issue.

{
  "config": {
    "agentspec_schema_version": "agents.digitalocean.com/v1alpha1",
    "content_hash": "75803fef24dc731824ecd4a1853c76153c7d8503534092b94da3ca3f31a882f4",
    "created_at": "2026-08-01T12:00:00Z",
    "created_by": "user-1",
    "credentials": [],
    "id": "019fb39c-14d9-7080-933e-b9b90e25acda",
    "insights": {
      "logs": true,
      "metrics": true,
      "traces": true
    },
    "manifest": {
      "apiVersion": "agents.digitalocean.com/v1alpha1",
      "kind": "Agent"
    },
    "name": "support-agent",
    "updated_at": "2026-08-01T12:00:00Z"
  }
}
{
  "id": "not_found",
  "message": "The resource you were accessing could not be found.",
  "request_id": "4d9d8375-3c56-4925-a3e7-eb137fed17e9"
}
{
  "id": "unauthorized",
  "message": "Unable to authenticate you."
}
{
  "id": "not_found",
  "message": "The resource you requested could not be found."
}
{
  "id": "too_many_requests",
  "message": "API rate limit exceeded."
}
{
  "id": "server_error",
  "message": "Unexpected server-side error"
}
{
  "id": "example_error",
  "message": "some error message"
}

DELETE Soft-delete an Environment Config.

/v2/agents/configs/{config_id}
Authorizations: bearer_auth (1 scope)
Http: Bearer
Required scopes: agent_harness_session:manage

OAuth Authentication

In order to interact with the DigitalOcean API, you or your application must authenticate.

The DigitalOcean API handles this through OAuth, an open standard for authorization. OAuth allows you to delegate access to your account. Scopes can be used to grant full access, read-only access, or access to a specific set of endpoints.

You can generate an OAuth token by visiting the Apps & API section of the DigitalOcean control panel for your account.

An OAuth token functions as a complete authentication request. In effect, it acts as a substitute for a username and password pair.

Because of this, it is absolutely essential that you keep your OAuth tokens secure. In fact, upon generation, the web interface will only display each token a single time in order to prevent the token from being compromised.

DigitalOcean access tokens begin with an identifiable prefix in order to distinguish them from other similar tokens.

  • dop_v1_ for personal access tokens generated in the control panel
  • doo_v1_ for tokens generated by applications using the OAuth flow
  • dor_v1_ for OAuth refresh tokens

Scopes

Scopes act like permissions assigned to an API token. These permissions determine what actions the token can perform. You can create API tokens that grant read-only access, full access, or limited access to specific endpoints by using custom scopes.

Generally, scopes are designed to match HTTP verbs and common CRUD operations (Create, Read, Update, Delete).

HTTP Verb CRUD Operation Scope
GET Read <resource>:read
POST Create <resource>:create
PUT/PATCH Update <resource>:update
DELETE Delete <resource>:delete

For example, creating a new Droplet by making a POST request to the /v2/droplets endpoint requires the droplet:create scope while listing Droplets by making a GET request to the /v2/droplets endpoint requires the droplet:read scope.

Each endpoint below specifies which scope is required to access it when using custom scopes.

How to Authenticate with OAuth

In order to make an authenticated request, include a bearer-type Authorization header containing your OAuth token. All requests must be made over HTTPS.

Authenticate with a Bearer Authorization Header

curl -X $HTTP_METHOD -H "Authorization: Bearer $DIGITALOCEAN_TOKEN" "https://api.digitalocean.com/v2/$OBJECT"

Releases the active team-scoped name; the config row is retained (soft delete), so sessions created from it keep a resolvable config_id.

Path Parameters

config_id string (uuid) required
Example: 019fb39c-14d9-7080-933e-b9b90e25acda

The Environment Config UUID.

curl -X DELETE \
  -H "Content-Type: application/json" \
  -H "Authorization: Bearer $DIGITALOCEAN_TOKEN" \
  "https://api.digitalocean.com/v2/agents/configs/019fb39c-14d9-7080-933e-b9b90e25acda"
curl -X DELETE \
  -H "Authorization: Bearer $API_TOKEN" \
  "https://api.digitalocean.com/v2/agents/configs/{config_id}"

Responses

204

Config soft-deleted; no response body.

ratelimit-limit integer

The default limit on number of requests that can be made per hour and per minute. Current rate limits are 5000 requests per hour and 250 requests per minute.

ratelimit-remaining integer

The number of requests in your hourly quota that remain before you hit your request limit. See https://docs.digitalocean.com/reference/api/reference/#rate-limit for information about how requests expire.

ratelimit-reset integer

The time when the oldest request will expire. The value is given in Unix epoch time. See https://docs.digitalocean.com/reference/api/reference/#rate-limit for information about how requests expire.

400

config_id is not a UUID.

ratelimit-limit integer

The default limit on number of requests that can be made per hour and per minute. Current rate limits are 5000 requests per hour and 250 requests per minute.

ratelimit-remaining integer

The number of requests in your hourly quota that remain before you hit your request limit. See https://docs.digitalocean.com/reference/api/reference/#rate-limit for information about how requests expire.

ratelimit-reset integer

The time when the oldest request will expire. The value is given in Unix epoch time. See https://docs.digitalocean.com/reference/api/reference/#rate-limit for information about how requests expire.

id string required
Example: not_found

A short identifier corresponding to the HTTP status code returned. For example, the ID for a response returning a 404 status code would be "not_found."

message string required
Example: The resource you were accessing could not be found.

A message providing additional information about the error, including details to help resolve it when possible.

request_id string optional
Example: 4d9d8375-3c56-4925-a3e7-eb137fed17e9

Optionally, some endpoints may include a request ID that should be provided when reporting bugs or opening support tickets to help identify the issue.

401

Authentication failed due to invalid credentials.

ratelimit-limit integer

The default limit on number of requests that can be made per hour and per minute. Current rate limits are 5000 requests per hour and 250 requests per minute.

ratelimit-remaining integer

The number of requests in your hourly quota that remain before you hit your request limit. See https://docs.digitalocean.com/reference/api/reference/#rate-limit for information about how requests expire.

ratelimit-reset integer

The time when the oldest request will expire. The value is given in Unix epoch time. See https://docs.digitalocean.com/reference/api/reference/#rate-limit for information about how requests expire.

id string required
Example: not_found

A short identifier corresponding to the HTTP status code returned. For example, the ID for a response returning a 404 status code would be "not_found."

message string required
Example: The resource you were accessing could not be found.

A message providing additional information about the error, including details to help resolve it when possible.

request_id string optional
Example: 4d9d8375-3c56-4925-a3e7-eb137fed17e9

Optionally, some endpoints may include a request ID that should be provided when reporting bugs or opening support tickets to help identify the issue.

404

The resource was not found.

ratelimit-limit integer

The default limit on number of requests that can be made per hour and per minute. Current rate limits are 5000 requests per hour and 250 requests per minute.

ratelimit-remaining integer

The number of requests in your hourly quota that remain before you hit your request limit. See https://docs.digitalocean.com/reference/api/reference/#rate-limit for information about how requests expire.

ratelimit-reset integer

The time when the oldest request will expire. The value is given in Unix epoch time. See https://docs.digitalocean.com/reference/api/reference/#rate-limit for information about how requests expire.

id string required
Example: not_found

A short identifier corresponding to the HTTP status code returned. For example, the ID for a response returning a 404 status code would be "not_found."

message string required
Example: The resource you were accessing could not be found.

A message providing additional information about the error, including details to help resolve it when possible.

request_id string optional
Example: 4d9d8375-3c56-4925-a3e7-eb137fed17e9

Optionally, some endpoints may include a request ID that should be provided when reporting bugs or opening support tickets to help identify the issue.

409

Config still has active sessions (or active credential binding sets).

ratelimit-limit integer

The default limit on number of requests that can be made per hour and per minute. Current rate limits are 5000 requests per hour and 250 requests per minute.

ratelimit-remaining integer

The number of requests in your hourly quota that remain before you hit your request limit. See https://docs.digitalocean.com/reference/api/reference/#rate-limit for information about how requests expire.

ratelimit-reset integer

The time when the oldest request will expire. The value is given in Unix epoch time. See https://docs.digitalocean.com/reference/api/reference/#rate-limit for information about how requests expire.

id string required
Example: not_found

A short identifier corresponding to the HTTP status code returned. For example, the ID for a response returning a 404 status code would be "not_found."

message string required
Example: The resource you were accessing could not be found.

A message providing additional information about the error, including details to help resolve it when possible.

request_id string optional
Example: 4d9d8375-3c56-4925-a3e7-eb137fed17e9

Optionally, some endpoints may include a request ID that should be provided when reporting bugs or opening support tickets to help identify the issue.

429

The API rate limit has been exceeded.

ratelimit-limit integer

The default limit on number of requests that can be made per hour and per minute. Current rate limits are 5000 requests per hour and 250 requests per minute.

ratelimit-remaining integer

The number of requests in your hourly quota that remain before you hit your request limit. See https://docs.digitalocean.com/reference/api/reference/#rate-limit for information about how requests expire.

ratelimit-reset integer

The time when the oldest request will expire. The value is given in Unix epoch time. See https://docs.digitalocean.com/reference/api/reference/#rate-limit for information about how requests expire.

id string required
Example: not_found

A short identifier corresponding to the HTTP status code returned. For example, the ID for a response returning a 404 status code would be "not_found."

message string required
Example: The resource you were accessing could not be found.

A message providing additional information about the error, including details to help resolve it when possible.

request_id string optional
Example: 4d9d8375-3c56-4925-a3e7-eb137fed17e9

Optionally, some endpoints may include a request ID that should be provided when reporting bugs or opening support tickets to help identify the issue.

500

There was a server error.

ratelimit-limit integer

The default limit on number of requests that can be made per hour and per minute. Current rate limits are 5000 requests per hour and 250 requests per minute.

ratelimit-remaining integer

The number of requests in your hourly quota that remain before you hit your request limit. See https://docs.digitalocean.com/reference/api/reference/#rate-limit for information about how requests expire.

ratelimit-reset integer

The time when the oldest request will expire. The value is given in Unix epoch time. See https://docs.digitalocean.com/reference/api/reference/#rate-limit for information about how requests expire.

id string required
Example: not_found

A short identifier corresponding to the HTTP status code returned. For example, the ID for a response returning a 404 status code would be "not_found."

message string required
Example: The resource you were accessing could not be found.

A message providing additional information about the error, including details to help resolve it when possible.

request_id string optional
Example: 4d9d8375-3c56-4925-a3e7-eb137fed17e9

Optionally, some endpoints may include a request ID that should be provided when reporting bugs or opening support tickets to help identify the issue.

default

There was an unexpected error.

ratelimit-limit integer

The default limit on number of requests that can be made per hour and per minute. Current rate limits are 5000 requests per hour and 250 requests per minute.

ratelimit-remaining integer

The number of requests in your hourly quota that remain before you hit your request limit. See https://docs.digitalocean.com/reference/api/reference/#rate-limit for information about how requests expire.

ratelimit-reset integer

The time when the oldest request will expire. The value is given in Unix epoch time. See https://docs.digitalocean.com/reference/api/reference/#rate-limit for information about how requests expire.

id string required
Example: not_found

A short identifier corresponding to the HTTP status code returned. For example, the ID for a response returning a 404 status code would be "not_found."

message string required
Example: The resource you were accessing could not be found.

A message providing additional information about the error, including details to help resolve it when possible.

request_id string optional
Example: 4d9d8375-3c56-4925-a3e7-eb137fed17e9

Optionally, some endpoints may include a request ID that should be provided when reporting bugs or opening support tickets to help identify the issue.

{
  "id": "not_found",
  "message": "The resource you were accessing could not be found.",
  "request_id": "4d9d8375-3c56-4925-a3e7-eb137fed17e9"
}
{
  "id": "unauthorized",
  "message": "Unable to authenticate you."
}
{
  "id": "not_found",
  "message": "The resource you requested could not be found."
}
{
  "id": "not_found",
  "message": "The resource you were accessing could not be found.",
  "request_id": "4d9d8375-3c56-4925-a3e7-eb137fed17e9"
}
{
  "id": "too_many_requests",
  "message": "API rate limit exceeded."
}
{
  "id": "server_error",
  "message": "Unexpected server-side error"
}
{
  "id": "example_error",
  "message": "some error message"
}

POST Clone an Environment Config under a new name.

/v2/agents/configs/{config_id}/clone
Authorizations: bearer_auth (1 scope)
Http: Bearer
Required scopes: agent_harness_session:create

OAuth Authentication

In order to interact with the DigitalOcean API, you or your application must authenticate.

The DigitalOcean API handles this through OAuth, an open standard for authorization. OAuth allows you to delegate access to your account. Scopes can be used to grant full access, read-only access, or access to a specific set of endpoints.

You can generate an OAuth token by visiting the Apps & API section of the DigitalOcean control panel for your account.

An OAuth token functions as a complete authentication request. In effect, it acts as a substitute for a username and password pair.

Because of this, it is absolutely essential that you keep your OAuth tokens secure. In fact, upon generation, the web interface will only display each token a single time in order to prevent the token from being compromised.

DigitalOcean access tokens begin with an identifiable prefix in order to distinguish them from other similar tokens.

  • dop_v1_ for personal access tokens generated in the control panel
  • doo_v1_ for tokens generated by applications using the OAuth flow
  • dor_v1_ for OAuth refresh tokens

Scopes

Scopes act like permissions assigned to an API token. These permissions determine what actions the token can perform. You can create API tokens that grant read-only access, full access, or limited access to specific endpoints by using custom scopes.

Generally, scopes are designed to match HTTP verbs and common CRUD operations (Create, Read, Update, Delete).

HTTP Verb CRUD Operation Scope
GET Read <resource>:read
POST Create <resource>:create
PUT/PATCH Update <resource>:update
DELETE Delete <resource>:delete

For example, creating a new Droplet by making a POST request to the /v2/droplets endpoint requires the droplet:create scope while listing Droplets by making a GET request to the /v2/droplets endpoint requires the droplet:read scope.

Each endpoint below specifies which scope is required to access it when using custom scopes.

How to Authenticate with OAuth

In order to make an authenticated request, include a bearer-type Authorization header containing your OAuth token. All requests must be made over HTTPS.

Authenticate with a Bearer Authorization Header

curl -X $HTTP_METHOD -H "Authorization: Bearer $DIGITALOCEAN_TOKEN" "https://api.digitalocean.com/v2/$OBJECT"

Copies the source config's sanitized manifest to a new UUID. Source and clone are independent (no lineage). Credential bindings are never copied: if the manifest declares secret slots, supply secrets/oauth_assignments again (write-only). content_hash matches the source when the manifest is unchanged.

Path Parameters

config_id string (uuid) required
Example: 019fb39c-14d9-7080-933e-b9b90e25acda

The Environment Config UUID.

Request Body: application/json

Clone body with required new name plus write-only credentials for any declared slots.

name string required

New config name, unique among the team's active configs.

oauth_assignments object optional

Write-only map from oauth logical slot to an OAuth assignment UUID. Required when the source declares those slots; never copied from the source.

secrets object optional

Write-only map from tenantSecret logical slot to plaintext. Required when the source declares those slots; never copied from the source.

Content type application/json
{
  "name": "string"
}
curl -X POST \
  -H "Content-Type: application/json" \
  -H "Authorization: Bearer $DIGITALOCEAN_TOKEN" \
  -d '{"name":"support-agent-v2"}' \
  "https://api.digitalocean.com/v2/agents/configs/{config_id}/clone"
curl -X POST \
  -H "Authorization: Bearer $API_TOKEN" \
  -H "Content-Type: application/json" \
  -d '{
  "name": "string"
}' \
  "https://api.digitalocean.com/v2/agents/configs/{config_id}/clone"

Responses

201

Clone created.

ratelimit-limit integer

The default limit on number of requests that can be made per hour and per minute. Current rate limits are 5000 requests per hour and 250 requests per minute.

ratelimit-remaining integer

The number of requests in your hourly quota that remain before you hit your request limit. See https://docs.digitalocean.com/reference/api/reference/#rate-limit for information about how requests expire.

ratelimit-reset integer

The time when the oldest request will expire. The value is given in Unix epoch time. See https://docs.digitalocean.com/reference/api/reference/#rate-limit for information about how requests expire.

config object optional

Immutable team-scoped Environment Config: one sanitized manifest per config. There is no update; clone to a new config to change content.

Show child properties
agentspec_schema_version string required
Example: agents.digitalocean.com/v1alpha1

The manifest contract the server accepted at create time: the manifest's own apiVersion for legacy envelope parses (currently agents.digitalocean.com/v1alpha1), or agents.digitalocean.com/flat.v1 for flat-format parses.

content_hash string required
Example: 75803fef24dc731824ecd4a1853c76153c7d8503534092b94da3ca3f31a882f4

Lowercase SHA-256 hex digest of the canonical sanitized manifest JSON.

created_at string (date-time) required
Example: 2026-08-01T12:00:00Z
created_by string required
Example: user-1

Authenticated user identity that created the config.

credentials array of object optional

Redacted credential slot metadata (name/source/provider). Secret values are never included.

Show child properties
name string required
Example: OPENAI_API_KEY
provider string optional
Example: openai
source string, one of: tenantSecret, oauth optional
Example: tenantSecret
id string (uuid) required
Example: 019fb39c-14d9-7080-933e-b9b90e25acda
insights object optional
manifest object required

Canonical runnable environment spec JSON, immutable after create. Validated non-secret spec.env and spec.permissions remain; spec.secrets retains name/source/provider but omits ref and the write-only value; metadata.name is cleared while safe metadata such as labels remains.

name string required
Example: support-agent
updated_at string (date-time) required
Example: 2026-08-01T12:00:00Z
400

Invalid name, missing credential slots, or source environment spec fails current durable validation.

ratelimit-limit integer

The default limit on number of requests that can be made per hour and per minute. Current rate limits are 5000 requests per hour and 250 requests per minute.

ratelimit-remaining integer

The number of requests in your hourly quota that remain before you hit your request limit. See https://docs.digitalocean.com/reference/api/reference/#rate-limit for information about how requests expire.

ratelimit-reset integer

The time when the oldest request will expire. The value is given in Unix epoch time. See https://docs.digitalocean.com/reference/api/reference/#rate-limit for information about how requests expire.

id string required
Example: not_found

A short identifier corresponding to the HTTP status code returned. For example, the ID for a response returning a 404 status code would be "not_found."

message string required
Example: The resource you were accessing could not be found.

A message providing additional information about the error, including details to help resolve it when possible.

request_id string optional
Example: 4d9d8375-3c56-4925-a3e7-eb137fed17e9

Optionally, some endpoints may include a request ID that should be provided when reporting bugs or opening support tickets to help identify the issue.

401

Authentication failed due to invalid credentials.

ratelimit-limit integer

The default limit on number of requests that can be made per hour and per minute. Current rate limits are 5000 requests per hour and 250 requests per minute.

ratelimit-remaining integer

The number of requests in your hourly quota that remain before you hit your request limit. See https://docs.digitalocean.com/reference/api/reference/#rate-limit for information about how requests expire.

ratelimit-reset integer

The time when the oldest request will expire. The value is given in Unix epoch time. See https://docs.digitalocean.com/reference/api/reference/#rate-limit for information about how requests expire.

id string required
Example: not_found

A short identifier corresponding to the HTTP status code returned. For example, the ID for a response returning a 404 status code would be "not_found."

message string required
Example: The resource you were accessing could not be found.

A message providing additional information about the error, including details to help resolve it when possible.

request_id string optional
Example: 4d9d8375-3c56-4925-a3e7-eb137fed17e9

Optionally, some endpoints may include a request ID that should be provided when reporting bugs or opening support tickets to help identify the issue.

404

The resource was not found.

ratelimit-limit integer

The default limit on number of requests that can be made per hour and per minute. Current rate limits are 5000 requests per hour and 250 requests per minute.

ratelimit-remaining integer

The number of requests in your hourly quota that remain before you hit your request limit. See https://docs.digitalocean.com/reference/api/reference/#rate-limit for information about how requests expire.

ratelimit-reset integer

The time when the oldest request will expire. The value is given in Unix epoch time. See https://docs.digitalocean.com/reference/api/reference/#rate-limit for information about how requests expire.

id string required
Example: not_found

A short identifier corresponding to the HTTP status code returned. For example, the ID for a response returning a 404 status code would be "not_found."

message string required
Example: The resource you were accessing could not be found.

A message providing additional information about the error, including details to help resolve it when possible.

request_id string optional
Example: 4d9d8375-3c56-4925-a3e7-eb137fed17e9

Optionally, some endpoints may include a request ID that should be provided when reporting bugs or opening support tickets to help identify the issue.

409

An active config with this name already exists for the team.

ratelimit-limit integer

The default limit on number of requests that can be made per hour and per minute. Current rate limits are 5000 requests per hour and 250 requests per minute.

ratelimit-remaining integer

The number of requests in your hourly quota that remain before you hit your request limit. See https://docs.digitalocean.com/reference/api/reference/#rate-limit for information about how requests expire.

ratelimit-reset integer

The time when the oldest request will expire. The value is given in Unix epoch time. See https://docs.digitalocean.com/reference/api/reference/#rate-limit for information about how requests expire.

id string required
Example: not_found

A short identifier corresponding to the HTTP status code returned. For example, the ID for a response returning a 404 status code would be "not_found."

message string required
Example: The resource you were accessing could not be found.

A message providing additional information about the error, including details to help resolve it when possible.

request_id string optional
Example: 4d9d8375-3c56-4925-a3e7-eb137fed17e9

Optionally, some endpoints may include a request ID that should be provided when reporting bugs or opening support tickets to help identify the issue.

413

Request body exceeds 1 MiB.

ratelimit-limit integer

The default limit on number of requests that can be made per hour and per minute. Current rate limits are 5000 requests per hour and 250 requests per minute.

ratelimit-remaining integer

The number of requests in your hourly quota that remain before you hit your request limit. See https://docs.digitalocean.com/reference/api/reference/#rate-limit for information about how requests expire.

ratelimit-reset integer

The time when the oldest request will expire. The value is given in Unix epoch time. See https://docs.digitalocean.com/reference/api/reference/#rate-limit for information about how requests expire.

id string required
Example: not_found

A short identifier corresponding to the HTTP status code returned. For example, the ID for a response returning a 404 status code would be "not_found."

message string required
Example: The resource you were accessing could not be found.

A message providing additional information about the error, including details to help resolve it when possible.

request_id string optional
Example: 4d9d8375-3c56-4925-a3e7-eb137fed17e9

Optionally, some endpoints may include a request ID that should be provided when reporting bugs or opening support tickets to help identify the issue.

415

Content-Type is not application/json.

ratelimit-limit integer

The default limit on number of requests that can be made per hour and per minute. Current rate limits are 5000 requests per hour and 250 requests per minute.

ratelimit-remaining integer

The number of requests in your hourly quota that remain before you hit your request limit. See https://docs.digitalocean.com/reference/api/reference/#rate-limit for information about how requests expire.

ratelimit-reset integer

The time when the oldest request will expire. The value is given in Unix epoch time. See https://docs.digitalocean.com/reference/api/reference/#rate-limit for information about how requests expire.

id string required
Example: not_found

A short identifier corresponding to the HTTP status code returned. For example, the ID for a response returning a 404 status code would be "not_found."

message string required
Example: The resource you were accessing could not be found.

A message providing additional information about the error, including details to help resolve it when possible.

request_id string optional
Example: 4d9d8375-3c56-4925-a3e7-eb137fed17e9

Optionally, some endpoints may include a request ID that should be provided when reporting bugs or opening support tickets to help identify the issue.

429

The API rate limit has been exceeded.

ratelimit-limit integer

The default limit on number of requests that can be made per hour and per minute. Current rate limits are 5000 requests per hour and 250 requests per minute.

ratelimit-remaining integer

The number of requests in your hourly quota that remain before you hit your request limit. See https://docs.digitalocean.com/reference/api/reference/#rate-limit for information about how requests expire.

ratelimit-reset integer

The time when the oldest request will expire. The value is given in Unix epoch time. See https://docs.digitalocean.com/reference/api/reference/#rate-limit for information about how requests expire.

id string required
Example: not_found

A short identifier corresponding to the HTTP status code returned. For example, the ID for a response returning a 404 status code would be "not_found."

message string required
Example: The resource you were accessing could not be found.

A message providing additional information about the error, including details to help resolve it when possible.

request_id string optional
Example: 4d9d8375-3c56-4925-a3e7-eb137fed17e9

Optionally, some endpoints may include a request ID that should be provided when reporting bugs or opening support tickets to help identify the issue.

500

There was a server error.

ratelimit-limit integer

The default limit on number of requests that can be made per hour and per minute. Current rate limits are 5000 requests per hour and 250 requests per minute.

ratelimit-remaining integer

The number of requests in your hourly quota that remain before you hit your request limit. See https://docs.digitalocean.com/reference/api/reference/#rate-limit for information about how requests expire.

ratelimit-reset integer

The time when the oldest request will expire. The value is given in Unix epoch time. See https://docs.digitalocean.com/reference/api/reference/#rate-limit for information about how requests expire.

id string required
Example: not_found

A short identifier corresponding to the HTTP status code returned. For example, the ID for a response returning a 404 status code would be "not_found."

message string required
Example: The resource you were accessing could not be found.

A message providing additional information about the error, including details to help resolve it when possible.

request_id string optional
Example: 4d9d8375-3c56-4925-a3e7-eb137fed17e9

Optionally, some endpoints may include a request ID that should be provided when reporting bugs or opening support tickets to help identify the issue.

default

There was an unexpected error.

ratelimit-limit integer

The default limit on number of requests that can be made per hour and per minute. Current rate limits are 5000 requests per hour and 250 requests per minute.

ratelimit-remaining integer

The number of requests in your hourly quota that remain before you hit your request limit. See https://docs.digitalocean.com/reference/api/reference/#rate-limit for information about how requests expire.

ratelimit-reset integer

The time when the oldest request will expire. The value is given in Unix epoch time. See https://docs.digitalocean.com/reference/api/reference/#rate-limit for information about how requests expire.

id string required
Example: not_found

A short identifier corresponding to the HTTP status code returned. For example, the ID for a response returning a 404 status code would be "not_found."

message string required
Example: The resource you were accessing could not be found.

A message providing additional information about the error, including details to help resolve it when possible.

request_id string optional
Example: 4d9d8375-3c56-4925-a3e7-eb137fed17e9

Optionally, some endpoints may include a request ID that should be provided when reporting bugs or opening support tickets to help identify the issue.

{
  "config": {
    "agentspec_schema_version": "agents.digitalocean.com/v1alpha1",
    "content_hash": "75803fef24dc731824ecd4a1853c76153c7d8503534092b94da3ca3f31a882f4",
    "created_at": "2026-08-01T12:00:00Z",
    "created_by": "user-1",
    "credentials": [],
    "id": "019fb39c-14d9-7080-933e-b9b90e25acda",
    "insights": {
      "logs": true,
      "metrics": true,
      "traces": true
    },
    "manifest": {
      "apiVersion": "agents.digitalocean.com/v1alpha1",
      "kind": "Agent"
    },
    "name": "support-agent",
    "updated_at": "2026-08-01T12:00:00Z"
  }
}
{
  "id": "not_found",
  "message": "The resource you were accessing could not be found.",
  "request_id": "4d9d8375-3c56-4925-a3e7-eb137fed17e9"
}
{
  "id": "unauthorized",
  "message": "Unable to authenticate you."
}
{
  "id": "not_found",
  "message": "The resource you requested could not be found."
}
{
  "id": "not_found",
  "message": "The resource you were accessing could not be found.",
  "request_id": "4d9d8375-3c56-4925-a3e7-eb137fed17e9"
}
{
  "id": "not_found",
  "message": "The resource you were accessing could not be found.",
  "request_id": "4d9d8375-3c56-4925-a3e7-eb137fed17e9"
}
{
  "id": "not_found",
  "message": "The resource you were accessing could not be found.",
  "request_id": "4d9d8375-3c56-4925-a3e7-eb137fed17e9"
}
{
  "id": "too_many_requests",
  "message": "API rate limit exceeded."
}
{
  "id": "server_error",
  "message": "Unexpected server-side error"
}
{
  "id": "example_error",
  "message": "some error message"
}

GET List the sessions created from one Environment Config.

/v2/agents/configs/{config_id}/sessions
Authorizations: bearer_auth (1 scope)
Http: Bearer
Required scopes: agent_harness_session:read

OAuth Authentication

In order to interact with the DigitalOcean API, you or your application must authenticate.

The DigitalOcean API handles this through OAuth, an open standard for authorization. OAuth allows you to delegate access to your account. Scopes can be used to grant full access, read-only access, or access to a specific set of endpoints.

You can generate an OAuth token by visiting the Apps & API section of the DigitalOcean control panel for your account.

An OAuth token functions as a complete authentication request. In effect, it acts as a substitute for a username and password pair.

Because of this, it is absolutely essential that you keep your OAuth tokens secure. In fact, upon generation, the web interface will only display each token a single time in order to prevent the token from being compromised.

DigitalOcean access tokens begin with an identifiable prefix in order to distinguish them from other similar tokens.

  • dop_v1_ for personal access tokens generated in the control panel
  • doo_v1_ for tokens generated by applications using the OAuth flow
  • dor_v1_ for OAuth refresh tokens

Scopes

Scopes act like permissions assigned to an API token. These permissions determine what actions the token can perform. You can create API tokens that grant read-only access, full access, or limited access to specific endpoints by using custom scopes.

Generally, scopes are designed to match HTTP verbs and common CRUD operations (Create, Read, Update, Delete).

HTTP Verb CRUD Operation Scope
GET Read <resource>:read
POST Create <resource>:create
PUT/PATCH Update <resource>:update
DELETE Delete <resource>:delete

For example, creating a new Droplet by making a POST request to the /v2/droplets endpoint requires the droplet:create scope while listing Droplets by making a GET request to the /v2/droplets endpoint requires the droplet:read scope.

Each endpoint below specifies which scope is required to access it when using custom scopes.

How to Authenticate with OAuth

In order to make an authenticated request, include a bearer-type Authorization header containing your OAuth token. All requests must be made over HTTPS.

Authenticate with a Bearer Authorization Header

curl -X $HTTP_METHOD -H "Authorization: Bearer $DIGITALOCEAN_TOKEN" "https://api.digitalocean.com/v2/$OBJECT"

Enumerates the caller's team sessions whose session was created from this durable Environment Config. Keyset-paginated on an opaque cursor, newest first, same shape and status semantics as GET /v2/agents/sessions.

Path Parameters

config_id string (uuid) required
Example: 019fb39c-14d9-7080-933e-b9b90e25acda

The Environment Config UUID.

Query Parameters

page_size integer (int32) 1 – 200 optional
Example: 50

Page size. Defaults to 50 when omitted or non-positive; values above 200 are clamped to 200.

Default: 50
page_token string optional

Opaque keyset cursor returned by the previous page. Empty starts from the beginning.

status string (enum) optional
Example: SESSION_STATUS_READY

Optional filter on session status. Empty / SESSION_STATUS_UNSPECIFIED still hides destroyed and failed sessions by default; SESSION_STATUS_ALL opts out and returns every session regardless of status.

curl -X GET \
  -H "Content-Type: application/json" \
  -H "Authorization: Bearer $DIGITALOCEAN_TOKEN" \
  "https://api.digitalocean.com/v2/agents/configs/019fb39c-14d9-7080-933e-b9b90e25acda/sessions"
curl -X GET \
  -H "Authorization: Bearer $API_TOKEN" \
  "https://api.digitalocean.com/v2/agents/configs/{config_id}/sessions"

Responses

200

A page of sessions created from the config.

ratelimit-limit integer

The default limit on number of requests that can be made per hour and per minute. Current rate limits are 5000 requests per hour and 250 requests per minute.

ratelimit-remaining integer

The number of requests in your hourly quota that remain before you hit your request limit. See https://docs.digitalocean.com/reference/api/reference/#rate-limit for information about how requests expire.

ratelimit-reset integer

The time when the oldest request will expire. The value is given in Unix epoch time. See https://docs.digitalocean.com/reference/api/reference/#rate-limit for information about how requests expire.

next_page_token string optional
Example: example

Opaque cursor for the next page. Empty when there are no further pages.

sessions array of object optional
Show child properties
agent_kind string (enum) optional
Example: AGENT_KIND_UNSPECIFIED

AgentKind identifies what runs inside the session sandbox. CreateSession accepts CLAUDE_CODE, OPENCODE, CODEX_CLI, CURSOR_CLI, OPENAI_CODEX, LANGGRAPH, and CREWAI (the supported set is overridable via HARNESS_SUPPORTED_AGENT_KINDS); other values are rejected with 400. AGENT_KIND_OPENAI_CODEX is the OpenAI sandbox-provider kind (DO runs codex exec-server; the agent loop lives at OpenAI). AGENT_KIND_LANGGRAPH is the LangGraph framework adapter. AGENT_KIND_CREWAI is the CrewAI Crew framework adapter: like LANGGRAPH the template bakes no agent code, so spec.env must supply FRAMEWORK_REPO and FRAMEWORK_REPO_SHA; a Crew kickoff is one-shot and exposes no HITL surface. CREWAI is additionally gated per team and returns 400 for teams it is not enabled for.

config_id string (uuid) optional
Example: 11111111-2222-3333-4444-555555555555

Durable Environment Config UUID the session was created from (inline manifests persist a config too, named after the session). Persisted and returned on create/get/list; absent only for sessions created before config references were stored.

created_at string (date-time) optional
Example: 2026-08-01T12:00:00Z
fork_from_checkpoint_id string optional
Example: example

Lineage: harness-api checkpoint id (cp_) the child booted from at fork time. Drives OHP inherited-history replay on attach. Omitted/empty for root sessions and legacy forks created before this field was persisted.

fork_id string (uuid) optional
Example: 11111111-2222-3333-4444-555555555555

Lineage: branch label assigned when this session was created by ForkSession (or rollback's internal fork). Omitted/empty for root sessions.

idle_timeout_seconds integer (int64) optional
Example: 60

This session's own idle-pause timeout (manifest idle_timeout). Omitted when the session uses the deployment-wide default.

keep_warm boolean optional
Example: false

Session is exempt from idle auto-pause (manifest keep_warm, or the agent-kind default: hermes sessions keep warm). Pause requests against such a session are rejected with 409. Omitted when false.

last_event_at string (date-time) optional
Example: 2026-08-01T12:00:00Z

Timestamp of the most recent event in this session's canonical stream. Drives the inactivity policy that pauses idle sessions.

name string optional
Example: demo-agent

User-assignable display name, unique per team among non-terminal sessions. Usable in place of session_id by clients (doctl / Console resolve it to the id via the ListSessions ?name= filter; the {session_id} path stays UUID-only). Supplied via the environment-spec metadata.name, or auto-generated ("session--") when omitted.

openai_environment_id string optional
Example: example

OpenAI Agents API environment id (env_…), captured from the resolved CODEX_ENVIRONMENT_ID guest env value. Populated only for AGENT_KIND_OPENAI_CODEX sessions. Non-secret correlation metadata.

openai_session_id string optional
Example: example

OpenAI Agents API session id (sess_…) this DO sandbox hosts. Populated only for AGENT_KIND_OPENAI_CODEX sessions (empty otherwise). Non-secret correlation metadata; a client (doctl agents attach) reads it to bridge to the OpenAI session. See docs/design/openai-sandbox-provider.md.

parent_session_id string optional
Example: example

Lineage: id of the session this one was forked from. Omitted/empty for root (non-fork) sessions.

pause_reason string optional
Example: example

Why this session is paused. Present only when status is SESSION_STATUS_PAUSED; omitted otherwise. Known values: manual (PauseSession RPC), idle (inactivity auto-pause), low_balance (prepay gate). Clients should treat an unrecognized value as an opaque reason string.

repo_hint string optional
Example: example

Optional repository hint supplied at session creation (first spec.workspace.repos entry of the manifest). Not authoritative; the agent may change repos in-session.

resume_on_topoff boolean optional
Example: false

Session consents to being resumed automatically when the team's prepayment balance is restored after a low-balance pause. Defaults to false at create time; may be toggled later via PATCH /v2/agents/sessions/{session_id} (resume_on_topoff only). Only a session paused with reason low_balance whose latest run did not complete is ever resumed automatically - a session the customer paused themselves, or one that idled out, stays paused regardless. Not an environment-spec field, and forks do not inherit it. Omitted when false.

sandbox_id string optional
Example: example

Sandbox identity for support / debugging. Informational; omitted until a sandbox is allocated.

session_id string optional
Example: a1b2c3d4-e5f6-7890-abcd-ef1234567890
status string (enum) optional
Example: SESSION_STATUS_UNSPECIFIED

SessionStatus is the lifecycle state of the sandbox + agent pair. SESSION_STATUS_ALL is a ListSessions status-filter value only -- no session is ever actually in this status. SESSION_STATUS_LOCKED is reserved for internal use and never appears in an end-user-facing response.

warnings array of string optional
Example: []

Non-fatal advisories computed from the manifest at create time: one entry per populated accepted-but-not-yet-enforced section (flat names: secrets, model, tools, memory, budget, max_lifetime, mounts; legacy manifests get the corresponding spec.* paths), a deprecation entry when a legacy-envelope manifest or an adapter alias (codex-cli, cursor-cli) is used, and a heuristic entry per credential-looking spec.env value. Populated on the CreateSession response only.

400

Invalid pagination input or config_id.

ratelimit-limit integer

The default limit on number of requests that can be made per hour and per minute. Current rate limits are 5000 requests per hour and 250 requests per minute.

ratelimit-remaining integer

The number of requests in your hourly quota that remain before you hit your request limit. See https://docs.digitalocean.com/reference/api/reference/#rate-limit for information about how requests expire.

ratelimit-reset integer

The time when the oldest request will expire. The value is given in Unix epoch time. See https://docs.digitalocean.com/reference/api/reference/#rate-limit for information about how requests expire.

id string required
Example: not_found

A short identifier corresponding to the HTTP status code returned. For example, the ID for a response returning a 404 status code would be "not_found."

message string required
Example: The resource you were accessing could not be found.

A message providing additional information about the error, including details to help resolve it when possible.

request_id string optional
Example: 4d9d8375-3c56-4925-a3e7-eb137fed17e9

Optionally, some endpoints may include a request ID that should be provided when reporting bugs or opening support tickets to help identify the issue.

401

Authentication failed due to invalid credentials.

ratelimit-limit integer

The default limit on number of requests that can be made per hour and per minute. Current rate limits are 5000 requests per hour and 250 requests per minute.

ratelimit-remaining integer

The number of requests in your hourly quota that remain before you hit your request limit. See https://docs.digitalocean.com/reference/api/reference/#rate-limit for information about how requests expire.

ratelimit-reset integer

The time when the oldest request will expire. The value is given in Unix epoch time. See https://docs.digitalocean.com/reference/api/reference/#rate-limit for information about how requests expire.

id string required
Example: not_found

A short identifier corresponding to the HTTP status code returned. For example, the ID for a response returning a 404 status code would be "not_found."

message string required
Example: The resource you were accessing could not be found.

A message providing additional information about the error, including details to help resolve it when possible.

request_id string optional
Example: 4d9d8375-3c56-4925-a3e7-eb137fed17e9

Optionally, some endpoints may include a request ID that should be provided when reporting bugs or opening support tickets to help identify the issue.

404

The resource was not found.

ratelimit-limit integer

The default limit on number of requests that can be made per hour and per minute. Current rate limits are 5000 requests per hour and 250 requests per minute.

ratelimit-remaining integer

The number of requests in your hourly quota that remain before you hit your request limit. See https://docs.digitalocean.com/reference/api/reference/#rate-limit for information about how requests expire.

ratelimit-reset integer

The time when the oldest request will expire. The value is given in Unix epoch time. See https://docs.digitalocean.com/reference/api/reference/#rate-limit for information about how requests expire.

id string required
Example: not_found

A short identifier corresponding to the HTTP status code returned. For example, the ID for a response returning a 404 status code would be "not_found."

message string required
Example: The resource you were accessing could not be found.

A message providing additional information about the error, including details to help resolve it when possible.

request_id string optional
Example: 4d9d8375-3c56-4925-a3e7-eb137fed17e9

Optionally, some endpoints may include a request ID that should be provided when reporting bugs or opening support tickets to help identify the issue.

429

The API rate limit has been exceeded.

ratelimit-limit integer

The default limit on number of requests that can be made per hour and per minute. Current rate limits are 5000 requests per hour and 250 requests per minute.

ratelimit-remaining integer

The number of requests in your hourly quota that remain before you hit your request limit. See https://docs.digitalocean.com/reference/api/reference/#rate-limit for information about how requests expire.

ratelimit-reset integer

The time when the oldest request will expire. The value is given in Unix epoch time. See https://docs.digitalocean.com/reference/api/reference/#rate-limit for information about how requests expire.

id string required
Example: not_found

A short identifier corresponding to the HTTP status code returned. For example, the ID for a response returning a 404 status code would be "not_found."

message string required
Example: The resource you were accessing could not be found.

A message providing additional information about the error, including details to help resolve it when possible.

request_id string optional
Example: 4d9d8375-3c56-4925-a3e7-eb137fed17e9

Optionally, some endpoints may include a request ID that should be provided when reporting bugs or opening support tickets to help identify the issue.

500

There was a server error.

ratelimit-limit integer

The default limit on number of requests that can be made per hour and per minute. Current rate limits are 5000 requests per hour and 250 requests per minute.

ratelimit-remaining integer

The number of requests in your hourly quota that remain before you hit your request limit. See https://docs.digitalocean.com/reference/api/reference/#rate-limit for information about how requests expire.

ratelimit-reset integer

The time when the oldest request will expire. The value is given in Unix epoch time. See https://docs.digitalocean.com/reference/api/reference/#rate-limit for information about how requests expire.

id string required
Example: not_found

A short identifier corresponding to the HTTP status code returned. For example, the ID for a response returning a 404 status code would be "not_found."

message string required
Example: The resource you were accessing could not be found.

A message providing additional information about the error, including details to help resolve it when possible.

request_id string optional
Example: 4d9d8375-3c56-4925-a3e7-eb137fed17e9

Optionally, some endpoints may include a request ID that should be provided when reporting bugs or opening support tickets to help identify the issue.

default

There was an unexpected error.

ratelimit-limit integer

The default limit on number of requests that can be made per hour and per minute. Current rate limits are 5000 requests per hour and 250 requests per minute.

ratelimit-remaining integer

The number of requests in your hourly quota that remain before you hit your request limit. See https://docs.digitalocean.com/reference/api/reference/#rate-limit for information about how requests expire.

ratelimit-reset integer

The time when the oldest request will expire. The value is given in Unix epoch time. See https://docs.digitalocean.com/reference/api/reference/#rate-limit for information about how requests expire.

id string required
Example: not_found

A short identifier corresponding to the HTTP status code returned. For example, the ID for a response returning a 404 status code would be "not_found."

message string required
Example: The resource you were accessing could not be found.

A message providing additional information about the error, including details to help resolve it when possible.

request_id string optional
Example: 4d9d8375-3c56-4925-a3e7-eb137fed17e9

Optionally, some endpoints may include a request ID that should be provided when reporting bugs or opening support tickets to help identify the issue.

{
  "next_page_token": "example",
  "sessions": [
    {
      "agent_kind": "AGENT_KIND_UNSPECIFIED",
      "config_id": "11111111-2222-3333-4444-555555555555",
      "created_at": "2026-08-01T12:00:00Z",
      "fork_from_checkpoint_id": "example",
      "fork_id": "11111111-2222-3333-4444-555555555555",
      "idle_timeout_seconds": 60,
      "keep_warm": false,
      "last_event_at": "2026-08-01T12:00:00Z",
      "name": "demo-agent",
      "openai_environment_id": "example",
      "openai_session_id": "example",
      "parent_session_id": "example",
      "pause_reason": "example",
      "repo_hint": "example",
      "resume_on_topoff": false,
      "sandbox_id": "example",
      "session_id": "a1b2c3d4-e5f6-7890-abcd-ef1234567890",
      "status": "SESSION_STATUS_UNSPECIFIED",
      "warnings": []
    }
  ]
}
{
  "id": "not_found",
  "message": "The resource you were accessing could not be found.",
  "request_id": "4d9d8375-3c56-4925-a3e7-eb137fed17e9"
}
{
  "id": "unauthorized",
  "message": "Unable to authenticate you."
}
{
  "id": "not_found",
  "message": "The resource you requested could not be found."
}
{
  "id": "too_many_requests",
  "message": "API rate limit exceeded."
}
{
  "id": "server_error",
  "message": "Unexpected server-side error"
}
{
  "id": "example_error",
  "message": "some error message"
}

GET ListSessions enumerates sessions for the caller's tenant.

/v2/agents/sessions
Authorizations: bearer_auth (1 scope)
Http: Bearer
Required scopes: agent_harness_session:read

OAuth Authentication

In order to interact with the DigitalOcean API, you or your application must authenticate.

The DigitalOcean API handles this through OAuth, an open standard for authorization. OAuth allows you to delegate access to your account. Scopes can be used to grant full access, read-only access, or access to a specific set of endpoints.

You can generate an OAuth token by visiting the Apps & API section of the DigitalOcean control panel for your account.

An OAuth token functions as a complete authentication request. In effect, it acts as a substitute for a username and password pair.

Because of this, it is absolutely essential that you keep your OAuth tokens secure. In fact, upon generation, the web interface will only display each token a single time in order to prevent the token from being compromised.

DigitalOcean access tokens begin with an identifiable prefix in order to distinguish them from other similar tokens.

  • dop_v1_ for personal access tokens generated in the control panel
  • doo_v1_ for tokens generated by applications using the OAuth flow
  • dor_v1_ for OAuth refresh tokens

Scopes

Scopes act like permissions assigned to an API token. These permissions determine what actions the token can perform. You can create API tokens that grant read-only access, full access, or limited access to specific endpoints by using custom scopes.

Generally, scopes are designed to match HTTP verbs and common CRUD operations (Create, Read, Update, Delete).

HTTP Verb CRUD Operation Scope
GET Read <resource>:read
POST Create <resource>:create
PUT/PATCH Update <resource>:update
DELETE Delete <resource>:delete

For example, creating a new Droplet by making a POST request to the /v2/droplets endpoint requires the droplet:create scope while listing Droplets by making a GET request to the /v2/droplets endpoint requires the droplet:read scope.

Each endpoint below specifies which scope is required to access it when using custom scopes.

How to Authenticate with OAuth

In order to make an authenticated request, include a bearer-type Authorization header containing your OAuth token. All requests must be made over HTTPS.

Authenticate with a Bearer Authorization Header

curl -X $HTTP_METHOD -H "Authorization: Bearer $DIGITALOCEAN_TOKEN" "https://api.digitalocean.com/v2/$OBJECT"

Keyset-paginated on an opaque cursor. Results are scoped to the authenticated team. Destroyed and failed sessions are omitted by default (matching the Cloud Console); pass status=SESSION_STATUS_ALL to list every session regardless of status, or an explicit status such as status=SESSION_STATUS_FAILED or status=SESSION_STATUS_DESTROYED to list only those.

Query Parameters

page_size integer (int32) 1 – 200 optional
Example: 50

Page size. Defaults to 50 when omitted or non-positive; values above 200 are clamped to 200 (not rejected).

Default: 50
page_token string optional

Opaque keyset cursor returned by the previous page. Empty starts from the beginning.

status string (enum) optional
Example: SESSION_STATUS_UNSPECIFIED

Optional filter on session status. Empty / SESSION_STATUS_UNSPECIFIED means no explicit filter, which still hides destroyed and failed sessions by default; SESSION_STATUS_ALL opts out and returns every session regardless of status (no session is ever actually in this status; it only means something as a filter value here); any other explicit status overrides the default.

Default: SESSION_STATUS_UNSPECIFIED
name string optional
Example: demo-agent

Optional exact-name filter (case-insensitive). Returns the single live (non-terminal) session that currently holds this name for the caller's team, or an empty list if none does. Matches the live holder only, so historical terminal rows and reused names never make it ambiguous (per-team live-name uniqueness bounds it to at most one). This is how clients (doctl / Console) resolve a session name to its id; the {session_id} path stays UUID-only.

search string optional
Example: demo

Optional case-insensitive substring filter on session name (contains), for callers that don't know the exact name (e.g. a UI search box). Unlike name, this may return zero, one, or many sessions, including terminal ones. Independent of name; at most 64 characters.

curl -X GET \
  -H "Content-Type: application/json" \
  -H "Authorization: Bearer $DIGITALOCEAN_TOKEN" \
  "https://api.digitalocean.com/v2/agents/sessions"
curl -X GET \
  -H "Authorization: Bearer $API_TOKEN" \
  "https://api.digitalocean.com/v2/agents/sessions"

Responses

200

A successful response.

ratelimit-limit integer

The default limit on number of requests that can be made per hour and per minute. Current rate limits are 5000 requests per hour and 250 requests per minute.

ratelimit-remaining integer

The number of requests in your hourly quota that remain before you hit your request limit. See https://docs.digitalocean.com/reference/api/reference/#rate-limit for information about how requests expire.

ratelimit-reset integer

The time when the oldest request will expire. The value is given in Unix epoch time. See https://docs.digitalocean.com/reference/api/reference/#rate-limit for information about how requests expire.

next_page_token string optional
Example: example

Opaque cursor for the next page. Empty when there are no further pages.

sessions array of object optional
Show child properties
agent_kind string (enum) optional
Example: AGENT_KIND_UNSPECIFIED

AgentKind identifies what runs inside the session sandbox. CreateSession accepts CLAUDE_CODE, OPENCODE, CODEX_CLI, CURSOR_CLI, OPENAI_CODEX, LANGGRAPH, and CREWAI (the supported set is overridable via HARNESS_SUPPORTED_AGENT_KINDS); other values are rejected with 400. AGENT_KIND_OPENAI_CODEX is the OpenAI sandbox-provider kind (DO runs codex exec-server; the agent loop lives at OpenAI). AGENT_KIND_LANGGRAPH is the LangGraph framework adapter. AGENT_KIND_CREWAI is the CrewAI Crew framework adapter: like LANGGRAPH the template bakes no agent code, so spec.env must supply FRAMEWORK_REPO and FRAMEWORK_REPO_SHA; a Crew kickoff is one-shot and exposes no HITL surface. CREWAI is additionally gated per team and returns 400 for teams it is not enabled for.

config_id string (uuid) optional
Example: 11111111-2222-3333-4444-555555555555

Durable Environment Config UUID the session was created from (inline manifests persist a config too, named after the session). Persisted and returned on create/get/list; absent only for sessions created before config references were stored.

created_at string (date-time) optional
Example: 2026-08-01T12:00:00Z
fork_from_checkpoint_id string optional
Example: example

Lineage: harness-api checkpoint id (cp_) the child booted from at fork time. Drives OHP inherited-history replay on attach. Omitted/empty for root sessions and legacy forks created before this field was persisted.

fork_id string (uuid) optional
Example: 11111111-2222-3333-4444-555555555555

Lineage: branch label assigned when this session was created by ForkSession (or rollback's internal fork). Omitted/empty for root sessions.

idle_timeout_seconds integer (int64) optional
Example: 60

This session's own idle-pause timeout (manifest idle_timeout). Omitted when the session uses the deployment-wide default.

keep_warm boolean optional
Example: false

Session is exempt from idle auto-pause (manifest keep_warm, or the agent-kind default: hermes sessions keep warm). Pause requests against such a session are rejected with 409. Omitted when false.

last_event_at string (date-time) optional
Example: 2026-08-01T12:00:00Z

Timestamp of the most recent event in this session's canonical stream. Drives the inactivity policy that pauses idle sessions.

name string optional
Example: demo-agent

User-assignable display name, unique per team among non-terminal sessions. Usable in place of session_id by clients (doctl / Console resolve it to the id via the ListSessions ?name= filter; the {session_id} path stays UUID-only). Supplied via the environment-spec metadata.name, or auto-generated ("session--") when omitted.

openai_environment_id string optional
Example: example

OpenAI Agents API environment id (env_…), captured from the resolved CODEX_ENVIRONMENT_ID guest env value. Populated only for AGENT_KIND_OPENAI_CODEX sessions. Non-secret correlation metadata.

openai_session_id string optional
Example: example

OpenAI Agents API session id (sess_…) this DO sandbox hosts. Populated only for AGENT_KIND_OPENAI_CODEX sessions (empty otherwise). Non-secret correlation metadata; a client (doctl agents attach) reads it to bridge to the OpenAI session. See docs/design/openai-sandbox-provider.md.

parent_session_id string optional
Example: example

Lineage: id of the session this one was forked from. Omitted/empty for root (non-fork) sessions.

pause_reason string optional
Example: example

Why this session is paused. Present only when status is SESSION_STATUS_PAUSED; omitted otherwise. Known values: manual (PauseSession RPC), idle (inactivity auto-pause), low_balance (prepay gate). Clients should treat an unrecognized value as an opaque reason string.

repo_hint string optional
Example: example

Optional repository hint supplied at session creation (first spec.workspace.repos entry of the manifest). Not authoritative; the agent may change repos in-session.

resume_on_topoff boolean optional
Example: false

Session consents to being resumed automatically when the team's prepayment balance is restored after a low-balance pause. Defaults to false at create time; may be toggled later via PATCH /v2/agents/sessions/{session_id} (resume_on_topoff only). Only a session paused with reason low_balance whose latest run did not complete is ever resumed automatically - a session the customer paused themselves, or one that idled out, stays paused regardless. Not an environment-spec field, and forks do not inherit it. Omitted when false.

sandbox_id string optional
Example: example

Sandbox identity for support / debugging. Informational; omitted until a sandbox is allocated.

session_id string optional
Example: a1b2c3d4-e5f6-7890-abcd-ef1234567890
status string (enum) optional
Example: SESSION_STATUS_UNSPECIFIED

SessionStatus is the lifecycle state of the sandbox + agent pair. SESSION_STATUS_ALL is a ListSessions status-filter value only -- no session is ever actually in this status. SESSION_STATUS_LOCKED is reserved for internal use and never appears in an end-user-facing response.

warnings array of string optional
Example: []

Non-fatal advisories computed from the manifest at create time: one entry per populated accepted-but-not-yet-enforced section (flat names: secrets, model, tools, memory, budget, max_lifetime, mounts; legacy manifests get the corresponding spec.* paths), a deprecation entry when a legacy-envelope manifest or an adapter alias (codex-cli, cursor-cli) is used, and a heuristic entry per credential-looking spec.env value. Populated on the CreateSession response only.

400

Invalid page_token.

ratelimit-limit integer

The default limit on number of requests that can be made per hour and per minute. Current rate limits are 5000 requests per hour and 250 requests per minute.

ratelimit-remaining integer

The number of requests in your hourly quota that remain before you hit your request limit. See https://docs.digitalocean.com/reference/api/reference/#rate-limit for information about how requests expire.

ratelimit-reset integer

The time when the oldest request will expire. The value is given in Unix epoch time. See https://docs.digitalocean.com/reference/api/reference/#rate-limit for information about how requests expire.

id string required
Example: not_found

A short identifier corresponding to the HTTP status code returned. For example, the ID for a response returning a 404 status code would be "not_found."

message string required
Example: The resource you were accessing could not be found.

A message providing additional information about the error, including details to help resolve it when possible.

request_id string optional
Example: 4d9d8375-3c56-4925-a3e7-eb137fed17e9

Optionally, some endpoints may include a request ID that should be provided when reporting bugs or opening support tickets to help identify the issue.

401

Authentication failed due to invalid credentials.

ratelimit-limit integer

The default limit on number of requests that can be made per hour and per minute. Current rate limits are 5000 requests per hour and 250 requests per minute.

ratelimit-remaining integer

The number of requests in your hourly quota that remain before you hit your request limit. See https://docs.digitalocean.com/reference/api/reference/#rate-limit for information about how requests expire.

ratelimit-reset integer

The time when the oldest request will expire. The value is given in Unix epoch time. See https://docs.digitalocean.com/reference/api/reference/#rate-limit for information about how requests expire.

id string required
Example: not_found

A short identifier corresponding to the HTTP status code returned. For example, the ID for a response returning a 404 status code would be "not_found."

message string required
Example: The resource you were accessing could not be found.

A message providing additional information about the error, including details to help resolve it when possible.

request_id string optional
Example: 4d9d8375-3c56-4925-a3e7-eb137fed17e9

Optionally, some endpoints may include a request ID that should be provided when reporting bugs or opening support tickets to help identify the issue.

404

The resource was not found.

ratelimit-limit integer

The default limit on number of requests that can be made per hour and per minute. Current rate limits are 5000 requests per hour and 250 requests per minute.

ratelimit-remaining integer

The number of requests in your hourly quota that remain before you hit your request limit. See https://docs.digitalocean.com/reference/api/reference/#rate-limit for information about how requests expire.

ratelimit-reset integer

The time when the oldest request will expire. The value is given in Unix epoch time. See https://docs.digitalocean.com/reference/api/reference/#rate-limit for information about how requests expire.

id string required
Example: not_found

A short identifier corresponding to the HTTP status code returned. For example, the ID for a response returning a 404 status code would be "not_found."

message string required
Example: The resource you were accessing could not be found.

A message providing additional information about the error, including details to help resolve it when possible.

request_id string optional
Example: 4d9d8375-3c56-4925-a3e7-eb137fed17e9

Optionally, some endpoints may include a request ID that should be provided when reporting bugs or opening support tickets to help identify the issue.

429

The API rate limit has been exceeded.

ratelimit-limit integer

The default limit on number of requests that can be made per hour and per minute. Current rate limits are 5000 requests per hour and 250 requests per minute.

ratelimit-remaining integer

The number of requests in your hourly quota that remain before you hit your request limit. See https://docs.digitalocean.com/reference/api/reference/#rate-limit for information about how requests expire.

ratelimit-reset integer

The time when the oldest request will expire. The value is given in Unix epoch time. See https://docs.digitalocean.com/reference/api/reference/#rate-limit for information about how requests expire.

id string required
Example: not_found

A short identifier corresponding to the HTTP status code returned. For example, the ID for a response returning a 404 status code would be "not_found."

message string required
Example: The resource you were accessing could not be found.

A message providing additional information about the error, including details to help resolve it when possible.

request_id string optional
Example: 4d9d8375-3c56-4925-a3e7-eb137fed17e9

Optionally, some endpoints may include a request ID that should be provided when reporting bugs or opening support tickets to help identify the issue.

500

There was a server error.

ratelimit-limit integer

The default limit on number of requests that can be made per hour and per minute. Current rate limits are 5000 requests per hour and 250 requests per minute.

ratelimit-remaining integer

The number of requests in your hourly quota that remain before you hit your request limit. See https://docs.digitalocean.com/reference/api/reference/#rate-limit for information about how requests expire.

ratelimit-reset integer

The time when the oldest request will expire. The value is given in Unix epoch time. See https://docs.digitalocean.com/reference/api/reference/#rate-limit for information about how requests expire.

id string required
Example: not_found

A short identifier corresponding to the HTTP status code returned. For example, the ID for a response returning a 404 status code would be "not_found."

message string required
Example: The resource you were accessing could not be found.

A message providing additional information about the error, including details to help resolve it when possible.

request_id string optional
Example: 4d9d8375-3c56-4925-a3e7-eb137fed17e9

Optionally, some endpoints may include a request ID that should be provided when reporting bugs or opening support tickets to help identify the issue.

default

There was an unexpected error.

ratelimit-limit integer

The default limit on number of requests that can be made per hour and per minute. Current rate limits are 5000 requests per hour and 250 requests per minute.

ratelimit-remaining integer

The number of requests in your hourly quota that remain before you hit your request limit. See https://docs.digitalocean.com/reference/api/reference/#rate-limit for information about how requests expire.

ratelimit-reset integer

The time when the oldest request will expire. The value is given in Unix epoch time. See https://docs.digitalocean.com/reference/api/reference/#rate-limit for information about how requests expire.

id string required
Example: not_found

A short identifier corresponding to the HTTP status code returned. For example, the ID for a response returning a 404 status code would be "not_found."

message string required
Example: The resource you were accessing could not be found.

A message providing additional information about the error, including details to help resolve it when possible.

request_id string optional
Example: 4d9d8375-3c56-4925-a3e7-eb137fed17e9

Optionally, some endpoints may include a request ID that should be provided when reporting bugs or opening support tickets to help identify the issue.

{
  "next_page_token": "example",
  "sessions": [
    {
      "agent_kind": "AGENT_KIND_UNSPECIFIED",
      "config_id": "11111111-2222-3333-4444-555555555555",
      "created_at": "2026-08-01T12:00:00Z",
      "fork_from_checkpoint_id": "example",
      "fork_id": "11111111-2222-3333-4444-555555555555",
      "idle_timeout_seconds": 60,
      "keep_warm": false,
      "last_event_at": "2026-08-01T12:00:00Z",
      "name": "demo-agent",
      "openai_environment_id": "example",
      "openai_session_id": "example",
      "parent_session_id": "example",
      "pause_reason": "example",
      "repo_hint": "example",
      "resume_on_topoff": false,
      "sandbox_id": "example",
      "session_id": "a1b2c3d4-e5f6-7890-abcd-ef1234567890",
      "status": "SESSION_STATUS_UNSPECIFIED",
      "warnings": []
    }
  ]
}
{
  "id": "not_found",
  "message": "The resource you were accessing could not be found.",
  "request_id": "4d9d8375-3c56-4925-a3e7-eb137fed17e9"
}
{
  "id": "unauthorized",
  "message": "Unable to authenticate you."
}
{
  "id": "not_found",
  "message": "The resource you requested could not be found."
}
{
  "id": "too_many_requests",
  "message": "API rate limit exceeded."
}
{
  "id": "server_error",
  "message": "Unexpected server-side error"
}
{
  "id": "example_error",
  "message": "some error message"
}

POST CreateSession provisions a sandbox and starts a Harness Runtime session.

/v2/agents/sessions
Authorizations: bearer_auth (1 scope)
Http: Bearer
Required scopes: agent_harness_session:create

OAuth Authentication

In order to interact with the DigitalOcean API, you or your application must authenticate.

The DigitalOcean API handles this through OAuth, an open standard for authorization. OAuth allows you to delegate access to your account. Scopes can be used to grant full access, read-only access, or access to a specific set of endpoints.

You can generate an OAuth token by visiting the Apps & API section of the DigitalOcean control panel for your account.

An OAuth token functions as a complete authentication request. In effect, it acts as a substitute for a username and password pair.

Because of this, it is absolutely essential that you keep your OAuth tokens secure. In fact, upon generation, the web interface will only display each token a single time in order to prevent the token from being compromised.

DigitalOcean access tokens begin with an identifiable prefix in order to distinguish them from other similar tokens.

  • dop_v1_ for personal access tokens generated in the control panel
  • doo_v1_ for tokens generated by applications using the OAuth flow
  • dor_v1_ for OAuth refresh tokens

Scopes

Scopes act like permissions assigned to an API token. These permissions determine what actions the token can perform. You can create API tokens that grant read-only access, full access, or limited access to specific endpoints by using custom scopes.

Generally, scopes are designed to match HTTP verbs and common CRUD operations (Create, Read, Update, Delete).

HTTP Verb CRUD Operation Scope
GET Read <resource>:read
POST Create <resource>:create
PUT/PATCH Update <resource>:update
DELETE Delete <resource>:delete

For example, creating a new Droplet by making a POST request to the /v2/droplets endpoint requires the droplet:create scope while listing Droplets by making a GET request to the /v2/droplets endpoint requires the droplet:read scope.

Each endpoint below specifies which scope is required to access it when using custom scopes.

How to Authenticate with OAuth

In order to make an authenticated request, include a bearer-type Authorization header containing your OAuth token. All requests must be made over HTTPS.

Authenticate with a Bearer Authorization Header

curl -X $HTTP_METHOD -H "Authorization: Bearer $DIGITALOCEAN_TOKEN" "https://api.digitalocean.com/v2/$OBJECT"

Returns once the session row is allocated. Sandbox boot completes asynchronously.

Two mutually exclusive request forms are selected by Content-Type (same contract as harness-api harness.swagger.json):

  • YAML (application/x-yaml, application/yaml, text/yaml, text/x-yaml): the environment spec. Two environment-spec formats are accepted during the dual-format transition: the flat format (primary) and the legacy agents.digitalocean.com/v1alpha1 envelope (deprecated). A top-level apiVersion key selects the legacy parser; its absence selects flat. Internally persists a durable Environment Config, then creates the session.
  • JSON (application/json): {name, config_id} loads the config, resolves its credentials from Secrets Manager at the version pinned when the config was created, and creates the session.

The OpenAPI requestBody schemas the JSON form for client generation (Autorest cannot emit a multi–content-type body). The live API still accepts the YAML forms listed above.

Successful responses may include config_id on the session. X-Device-UUID (if present) is persisted on the session row. Query parameters openai_session_id and resume_on_topoff apply to both forms; when both the JSON body field and ?resume_on_topoff= are present, the query parameter wins.

Query Parameters

openai_session_id string optional
Example: sess_abc123

OpenAI Agents API session id (sess_…) for adapter: codex-agentapi. doctl creates the OpenAI session before calling DO and passes the resulting id here; harness-api persists it for correlation. Empty/omitted for every other agent kind.

resume_on_topoff boolean optional
Example: false

Opt the new session in to automatic resumption when the team's prepayment balance is restored. Defaults to false. Exists as a query parameter so the environment spec (YAML body) form can carry it too. On the application/json form the body field is idiomatic, but this parameter wins when both are present. Must be exactly one of true/false/1/0; anything else is a 400.

Header Parameters

X-Device-UUID string optional
Example: device-uuid-example

Optional hardware device id forwarded by doctl. Persisted on the session row for lifecycle attribution. Values over 128 bytes are ignored.

Request Body: application/json

CreateSessionConfigRequest with application/json. The live API also accepts a raw environment spec under YAML Content-Types (see operation description); those forms are omitted from content so generated clients (pydo/autorest) can emit this operation.

config_id string (uuid) required
Example: 11111111-2222-3333-4444-555555555555
name string required
Example: demo-agent

Session name, independent of the config name. Must satisfy the existing environment-spec metadata.name rules and must not be UUID-shaped.

resume_on_topoff boolean optional
Example: false

Opt the new session in to automatic resumption when the team's prepayment balance is restored. Defaults to false. Session-scoped, not config-scoped: the referenced config never confers this, so one shared config cannot enrol every session created from it. Omit to leave the default (or to let the ?resume_on_topoff= query parameter supply it).

Content type application/json
{
  "config_id": "11111111-2222-3333-4444-555555555555",
  "name": "demo-agent",
  "resume_on_topoff": false
}
curl -X POST \
  -H "Content-Type: application/json" \
  -H "Authorization: Bearer $DIGITALOCEAN_TOKEN" \
  -d '{"name":"demo-agent","config_id":"019fb39c-14d9-7080-933e-b9b90e25acda"}' \
  "https://api.digitalocean.com/v2/agents/sessions"
curl -X POST \
  -H "Authorization: Bearer $API_TOKEN" \
  -H "Content-Type: application/json" \
  -d '{
  "config_id": "11111111-2222-3333-4444-555555555555",
  "name": "demo-agent",
  "resume_on_topoff": false
}' \
  "https://api.digitalocean.com/v2/agents/sessions"

Responses

200

Session row allocated; sandbox boot continues asynchronously.

ratelimit-limit integer

The default limit on number of requests that can be made per hour and per minute. Current rate limits are 5000 requests per hour and 250 requests per minute.

ratelimit-remaining integer

The number of requests in your hourly quota that remain before you hit your request limit. See https://docs.digitalocean.com/reference/api/reference/#rate-limit for information about how requests expire.

ratelimit-reset integer

The time when the oldest request will expire. The value is given in Unix epoch time. See https://docs.digitalocean.com/reference/api/reference/#rate-limit for information about how requests expire.

session object optional

Session is the user-facing record of a environment session + sandbox pair.

Show child properties
agent_kind string (enum) optional
Example: AGENT_KIND_UNSPECIFIED

AgentKind identifies what runs inside the session sandbox. CreateSession accepts CLAUDE_CODE, OPENCODE, CODEX_CLI, CURSOR_CLI, OPENAI_CODEX, LANGGRAPH, and CREWAI (the supported set is overridable via HARNESS_SUPPORTED_AGENT_KINDS); other values are rejected with 400. AGENT_KIND_OPENAI_CODEX is the OpenAI sandbox-provider kind (DO runs codex exec-server; the agent loop lives at OpenAI). AGENT_KIND_LANGGRAPH is the LangGraph framework adapter. AGENT_KIND_CREWAI is the CrewAI Crew framework adapter: like LANGGRAPH the template bakes no agent code, so spec.env must supply FRAMEWORK_REPO and FRAMEWORK_REPO_SHA; a Crew kickoff is one-shot and exposes no HITL surface. CREWAI is additionally gated per team and returns 400 for teams it is not enabled for.

config_id string (uuid) optional
Example: 11111111-2222-3333-4444-555555555555

Durable Environment Config UUID the session was created from (inline manifests persist a config too, named after the session). Persisted and returned on create/get/list; absent only for sessions created before config references were stored.

created_at string (date-time) optional
Example: 2026-08-01T12:00:00Z
fork_from_checkpoint_id string optional
Example: example

Lineage: harness-api checkpoint id (cp_) the child booted from at fork time. Drives OHP inherited-history replay on attach. Omitted/empty for root sessions and legacy forks created before this field was persisted.

fork_id string (uuid) optional
Example: 11111111-2222-3333-4444-555555555555

Lineage: branch label assigned when this session was created by ForkSession (or rollback's internal fork). Omitted/empty for root sessions.

idle_timeout_seconds integer (int64) optional
Example: 60

This session's own idle-pause timeout (manifest idle_timeout). Omitted when the session uses the deployment-wide default.

keep_warm boolean optional
Example: false

Session is exempt from idle auto-pause (manifest keep_warm, or the agent-kind default: hermes sessions keep warm). Pause requests against such a session are rejected with 409. Omitted when false.

last_event_at string (date-time) optional
Example: 2026-08-01T12:00:00Z

Timestamp of the most recent event in this session's canonical stream. Drives the inactivity policy that pauses idle sessions.

name string optional
Example: demo-agent

User-assignable display name, unique per team among non-terminal sessions. Usable in place of session_id by clients (doctl / Console resolve it to the id via the ListSessions ?name= filter; the {session_id} path stays UUID-only). Supplied via the environment-spec metadata.name, or auto-generated ("session--") when omitted.

openai_environment_id string optional
Example: example

OpenAI Agents API environment id (env_…), captured from the resolved CODEX_ENVIRONMENT_ID guest env value. Populated only for AGENT_KIND_OPENAI_CODEX sessions. Non-secret correlation metadata.

openai_session_id string optional
Example: example

OpenAI Agents API session id (sess_…) this DO sandbox hosts. Populated only for AGENT_KIND_OPENAI_CODEX sessions (empty otherwise). Non-secret correlation metadata; a client (doctl agents attach) reads it to bridge to the OpenAI session. See docs/design/openai-sandbox-provider.md.

parent_session_id string optional
Example: example

Lineage: id of the session this one was forked from. Omitted/empty for root (non-fork) sessions.

pause_reason string optional
Example: example

Why this session is paused. Present only when status is SESSION_STATUS_PAUSED; omitted otherwise. Known values: manual (PauseSession RPC), idle (inactivity auto-pause), low_balance (prepay gate). Clients should treat an unrecognized value as an opaque reason string.

repo_hint string optional
Example: example

Optional repository hint supplied at session creation (first spec.workspace.repos entry of the manifest). Not authoritative; the agent may change repos in-session.

resume_on_topoff boolean optional
Example: false

Session consents to being resumed automatically when the team's prepayment balance is restored after a low-balance pause. Defaults to false at create time; may be toggled later via PATCH /v2/agents/sessions/{session_id} (resume_on_topoff only). Only a session paused with reason low_balance whose latest run did not complete is ever resumed automatically - a session the customer paused themselves, or one that idled out, stays paused regardless. Not an environment-spec field, and forks do not inherit it. Omitted when false.

sandbox_id string optional
Example: example

Sandbox identity for support / debugging. Informational; omitted until a sandbox is allocated.

session_id string optional
Example: a1b2c3d4-e5f6-7890-abcd-ef1234567890
status string (enum) optional
Example: SESSION_STATUS_UNSPECIFIED

SessionStatus is the lifecycle state of the sandbox + agent pair. SESSION_STATUS_ALL is a ListSessions status-filter value only -- no session is ever actually in this status. SESSION_STATUS_LOCKED is reserved for internal use and never appears in an end-user-facing response.

warnings array of string optional
Example: []

Non-fatal advisories computed from the manifest at create time: one entry per populated accepted-but-not-yet-enforced section (flat names: secrets, model, tools, memory, budget, max_lifetime, mounts; legacy manifests get the corresponding spec.* paths), a deprecation entry when a legacy-envelope manifest or an adapter alias (codex-cli, cursor-cli) is used, and a heuristic entry per credential-looking spec.env value. Populated on the CreateSession response only.

400

Invalid manifest/config JSON, incompatible credentials, or invalid query parameter.

ratelimit-limit integer

The default limit on number of requests that can be made per hour and per minute. Current rate limits are 5000 requests per hour and 250 requests per minute.

ratelimit-remaining integer

The number of requests in your hourly quota that remain before you hit your request limit. See https://docs.digitalocean.com/reference/api/reference/#rate-limit for information about how requests expire.

ratelimit-reset integer

The time when the oldest request will expire. The value is given in Unix epoch time. See https://docs.digitalocean.com/reference/api/reference/#rate-limit for information about how requests expire.

id string required
Example: not_found

A short identifier corresponding to the HTTP status code returned. For example, the ID for a response returning a 404 status code would be "not_found."

message string required
Example: The resource you were accessing could not be found.

A message providing additional information about the error, including details to help resolve it when possible.

request_id string optional
Example: 4d9d8375-3c56-4925-a3e7-eb137fed17e9

Optionally, some endpoints may include a request ID that should be provided when reporting bugs or opening support tickets to help identify the issue.

401

Authentication failed due to invalid credentials.

ratelimit-limit integer

The default limit on number of requests that can be made per hour and per minute. Current rate limits are 5000 requests per hour and 250 requests per minute.

ratelimit-remaining integer

The number of requests in your hourly quota that remain before you hit your request limit. See https://docs.digitalocean.com/reference/api/reference/#rate-limit for information about how requests expire.

ratelimit-reset integer

The time when the oldest request will expire. The value is given in Unix epoch time. See https://docs.digitalocean.com/reference/api/reference/#rate-limit for information about how requests expire.

id string required
Example: not_found

A short identifier corresponding to the HTTP status code returned. For example, the ID for a response returning a 404 status code would be "not_found."

message string required
Example: The resource you were accessing could not be found.

A message providing additional information about the error, including details to help resolve it when possible.

request_id string optional
Example: 4d9d8375-3c56-4925-a3e7-eb137fed17e9

Optionally, some endpoints may include a request ID that should be provided when reporting bugs or opening support tickets to help identify the issue.

402

The team is blocked by the prepayment gate.

ratelimit-limit integer

The default limit on number of requests that can be made per hour and per minute. Current rate limits are 5000 requests per hour and 250 requests per minute.

ratelimit-remaining integer

The number of requests in your hourly quota that remain before you hit your request limit. See https://docs.digitalocean.com/reference/api/reference/#rate-limit for information about how requests expire.

ratelimit-reset integer

The time when the oldest request will expire. The value is given in Unix epoch time. See https://docs.digitalocean.com/reference/api/reference/#rate-limit for information about how requests expire.

id string required
Example: not_found

A short identifier corresponding to the HTTP status code returned. For example, the ID for a response returning a 404 status code would be "not_found."

message string required
Example: The resource you were accessing could not be found.

A message providing additional information about the error, including details to help resolve it when possible.

request_id string optional
Example: 4d9d8375-3c56-4925-a3e7-eb137fed17e9

Optionally, some endpoints may include a request ID that should be provided when reporting bugs or opening support tickets to help identify the issue.

403

Secrets Manager denied access to a pinned credential.

ratelimit-limit integer

The default limit on number of requests that can be made per hour and per minute. Current rate limits are 5000 requests per hour and 250 requests per minute.

ratelimit-remaining integer

The number of requests in your hourly quota that remain before you hit your request limit. See https://docs.digitalocean.com/reference/api/reference/#rate-limit for information about how requests expire.

ratelimit-reset integer

The time when the oldest request will expire. The value is given in Unix epoch time. See https://docs.digitalocean.com/reference/api/reference/#rate-limit for information about how requests expire.

id string required
Example: not_found

A short identifier corresponding to the HTTP status code returned. For example, the ID for a response returning a 404 status code would be "not_found."

message string required
Example: The resource you were accessing could not be found.

A message providing additional information about the error, including details to help resolve it when possible.

request_id string optional
Example: 4d9d8375-3c56-4925-a3e7-eb137fed17e9

Optionally, some endpoints may include a request ID that should be provided when reporting bugs or opening support tickets to help identify the issue.

404

The resource was not found.

ratelimit-limit integer

The default limit on number of requests that can be made per hour and per minute. Current rate limits are 5000 requests per hour and 250 requests per minute.

ratelimit-remaining integer

The number of requests in your hourly quota that remain before you hit your request limit. See https://docs.digitalocean.com/reference/api/reference/#rate-limit for information about how requests expire.

ratelimit-reset integer

The time when the oldest request will expire. The value is given in Unix epoch time. See https://docs.digitalocean.com/reference/api/reference/#rate-limit for information about how requests expire.

id string required
Example: not_found

A short identifier corresponding to the HTTP status code returned. For example, the ID for a response returning a 404 status code would be "not_found."

message string required
Example: The resource you were accessing could not be found.

A message providing additional information about the error, including details to help resolve it when possible.

request_id string optional
Example: 4d9d8375-3c56-4925-a3e7-eb137fed17e9

Optionally, some endpoints may include a request ID that should be provided when reporting bugs or opening support tickets to help identify the issue.

409

Team is at the active-session quota, or a live session name already exists.

ratelimit-limit integer

The default limit on number of requests that can be made per hour and per minute. Current rate limits are 5000 requests per hour and 250 requests per minute.

ratelimit-remaining integer

The number of requests in your hourly quota that remain before you hit your request limit. See https://docs.digitalocean.com/reference/api/reference/#rate-limit for information about how requests expire.

ratelimit-reset integer

The time when the oldest request will expire. The value is given in Unix epoch time. See https://docs.digitalocean.com/reference/api/reference/#rate-limit for information about how requests expire.

id string required
Example: not_found

A short identifier corresponding to the HTTP status code returned. For example, the ID for a response returning a 404 status code would be "not_found."

message string required
Example: The resource you were accessing could not be found.

A message providing additional information about the error, including details to help resolve it when possible.

request_id string optional
Example: 4d9d8375-3c56-4925-a3e7-eb137fed17e9

Optionally, some endpoints may include a request ID that should be provided when reporting bugs or opening support tickets to help identify the issue.

413

JSON body exceeds 16 KiB or YAML body exceeds 1 MiB.

ratelimit-limit integer

The default limit on number of requests that can be made per hour and per minute. Current rate limits are 5000 requests per hour and 250 requests per minute.

ratelimit-remaining integer

The number of requests in your hourly quota that remain before you hit your request limit. See https://docs.digitalocean.com/reference/api/reference/#rate-limit for information about how requests expire.

ratelimit-reset integer

The time when the oldest request will expire. The value is given in Unix epoch time. See https://docs.digitalocean.com/reference/api/reference/#rate-limit for information about how requests expire.

id string required
Example: not_found

A short identifier corresponding to the HTTP status code returned. For example, the ID for a response returning a 404 status code would be "not_found."

message string required
Example: The resource you were accessing could not be found.

A message providing additional information about the error, including details to help resolve it when possible.

request_id string optional
Example: 4d9d8375-3c56-4925-a3e7-eb137fed17e9

Optionally, some endpoints may include a request ID that should be provided when reporting bugs or opening support tickets to help identify the issue.

415

Unsupported Content-Type.

ratelimit-limit integer

The default limit on number of requests that can be made per hour and per minute. Current rate limits are 5000 requests per hour and 250 requests per minute.

ratelimit-remaining integer

The number of requests in your hourly quota that remain before you hit your request limit. See https://docs.digitalocean.com/reference/api/reference/#rate-limit for information about how requests expire.

ratelimit-reset integer

The time when the oldest request will expire. The value is given in Unix epoch time. See https://docs.digitalocean.com/reference/api/reference/#rate-limit for information about how requests expire.

id string required
Example: not_found

A short identifier corresponding to the HTTP status code returned. For example, the ID for a response returning a 404 status code would be "not_found."

message string required
Example: The resource you were accessing could not be found.

A message providing additional information about the error, including details to help resolve it when possible.

request_id string optional
Example: 4d9d8375-3c56-4925-a3e7-eb137fed17e9

Optionally, some endpoints may include a request ID that should be provided when reporting bugs or opening support tickets to help identify the issue.

429

The API rate limit has been exceeded.

ratelimit-limit integer

The default limit on number of requests that can be made per hour and per minute. Current rate limits are 5000 requests per hour and 250 requests per minute.

ratelimit-remaining integer

The number of requests in your hourly quota that remain before you hit your request limit. See https://docs.digitalocean.com/reference/api/reference/#rate-limit for information about how requests expire.

ratelimit-reset integer

The time when the oldest request will expire. The value is given in Unix epoch time. See https://docs.digitalocean.com/reference/api/reference/#rate-limit for information about how requests expire.

id string required
Example: not_found

A short identifier corresponding to the HTTP status code returned. For example, the ID for a response returning a 404 status code would be "not_found."

message string required
Example: The resource you were accessing could not be found.

A message providing additional information about the error, including details to help resolve it when possible.

request_id string optional
Example: 4d9d8375-3c56-4925-a3e7-eb137fed17e9

Optionally, some endpoints may include a request ID that should be provided when reporting bugs or opening support tickets to help identify the issue.

500

There was a server error.

ratelimit-limit integer

The default limit on number of requests that can be made per hour and per minute. Current rate limits are 5000 requests per hour and 250 requests per minute.

ratelimit-remaining integer

The number of requests in your hourly quota that remain before you hit your request limit. See https://docs.digitalocean.com/reference/api/reference/#rate-limit for information about how requests expire.

ratelimit-reset integer

The time when the oldest request will expire. The value is given in Unix epoch time. See https://docs.digitalocean.com/reference/api/reference/#rate-limit for information about how requests expire.

id string required
Example: not_found

A short identifier corresponding to the HTTP status code returned. For example, the ID for a response returning a 404 status code would be "not_found."

message string required
Example: The resource you were accessing could not be found.

A message providing additional information about the error, including details to help resolve it when possible.

request_id string optional
Example: 4d9d8375-3c56-4925-a3e7-eb137fed17e9

Optionally, some endpoints may include a request ID that should be provided when reporting bugs or opening support tickets to help identify the issue.

501

Requested capability is not available.

ratelimit-limit integer

The default limit on number of requests that can be made per hour and per minute. Current rate limits are 5000 requests per hour and 250 requests per minute.

ratelimit-remaining integer

The number of requests in your hourly quota that remain before you hit your request limit. See https://docs.digitalocean.com/reference/api/reference/#rate-limit for information about how requests expire.

ratelimit-reset integer

The time when the oldest request will expire. The value is given in Unix epoch time. See https://docs.digitalocean.com/reference/api/reference/#rate-limit for information about how requests expire.

id string required
Example: not_found

A short identifier corresponding to the HTTP status code returned. For example, the ID for a response returning a 404 status code would be "not_found."

message string required
Example: The resource you were accessing could not be found.

A message providing additional information about the error, including details to help resolve it when possible.

request_id string optional
Example: 4d9d8375-3c56-4925-a3e7-eb137fed17e9

Optionally, some endpoints may include a request ID that should be provided when reporting bugs or opening support tickets to help identify the issue.

503

Secrets Manager is unavailable.

ratelimit-limit integer

The default limit on number of requests that can be made per hour and per minute. Current rate limits are 5000 requests per hour and 250 requests per minute.

ratelimit-remaining integer

The number of requests in your hourly quota that remain before you hit your request limit. See https://docs.digitalocean.com/reference/api/reference/#rate-limit for information about how requests expire.

ratelimit-reset integer

The time when the oldest request will expire. The value is given in Unix epoch time. See https://docs.digitalocean.com/reference/api/reference/#rate-limit for information about how requests expire.

id string required
Example: not_found

A short identifier corresponding to the HTTP status code returned. For example, the ID for a response returning a 404 status code would be "not_found."

message string required
Example: The resource you were accessing could not be found.

A message providing additional information about the error, including details to help resolve it when possible.

request_id string optional
Example: 4d9d8375-3c56-4925-a3e7-eb137fed17e9

Optionally, some endpoints may include a request ID that should be provided when reporting bugs or opening support tickets to help identify the issue.

default

There was an unexpected error.

ratelimit-limit integer

The default limit on number of requests that can be made per hour and per minute. Current rate limits are 5000 requests per hour and 250 requests per minute.

ratelimit-remaining integer

The number of requests in your hourly quota that remain before you hit your request limit. See https://docs.digitalocean.com/reference/api/reference/#rate-limit for information about how requests expire.

ratelimit-reset integer

The time when the oldest request will expire. The value is given in Unix epoch time. See https://docs.digitalocean.com/reference/api/reference/#rate-limit for information about how requests expire.

id string required
Example: not_found

A short identifier corresponding to the HTTP status code returned. For example, the ID for a response returning a 404 status code would be "not_found."

message string required
Example: The resource you were accessing could not be found.

A message providing additional information about the error, including details to help resolve it when possible.

request_id string optional
Example: 4d9d8375-3c56-4925-a3e7-eb137fed17e9

Optionally, some endpoints may include a request ID that should be provided when reporting bugs or opening support tickets to help identify the issue.

{
  "session": {
    "agent_kind": "AGENT_KIND_UNSPECIFIED",
    "config_id": "11111111-2222-3333-4444-555555555555",
    "created_at": "2026-08-01T12:00:00Z",
    "fork_from_checkpoint_id": "example",
    "fork_id": "11111111-2222-3333-4444-555555555555",
    "idle_timeout_seconds": 60,
    "keep_warm": false,
    "last_event_at": "2026-08-01T12:00:00Z",
    "name": "demo-agent",
    "openai_environment_id": "example",
    "openai_session_id": "example",
    "parent_session_id": "example",
    "pause_reason": "example",
    "repo_hint": "example",
    "resume_on_topoff": false,
    "sandbox_id": "example",
    "session_id": "a1b2c3d4-e5f6-7890-abcd-ef1234567890",
    "status": "SESSION_STATUS_UNSPECIFIED",
    "warnings": []
  }
}
{
  "id": "not_found",
  "message": "The resource you were accessing could not be found.",
  "request_id": "4d9d8375-3c56-4925-a3e7-eb137fed17e9"
}
{
  "id": "unauthorized",
  "message": "Unable to authenticate you."
}
{
  "id": "not_found",
  "message": "The resource you were accessing could not be found.",
  "request_id": "4d9d8375-3c56-4925-a3e7-eb137fed17e9"
}
{
  "id": "not_found",
  "message": "The resource you were accessing could not be found.",
  "request_id": "4d9d8375-3c56-4925-a3e7-eb137fed17e9"
}
{
  "id": "not_found",
  "message": "The resource you requested could not be found."
}
{
  "id": "not_found",
  "message": "The resource you were accessing could not be found.",
  "request_id": "4d9d8375-3c56-4925-a3e7-eb137fed17e9"
}
{
  "id": "not_found",
  "message": "The resource you were accessing could not be found.",
  "request_id": "4d9d8375-3c56-4925-a3e7-eb137fed17e9"
}
{
  "id": "not_found",
  "message": "The resource you were accessing could not be found.",
  "request_id": "4d9d8375-3c56-4925-a3e7-eb137fed17e9"
}
{
  "id": "too_many_requests",
  "message": "API rate limit exceeded."
}
{
  "id": "server_error",
  "message": "Unexpected server-side error"
}
{
  "id": "not_found",
  "message": "The resource you were accessing could not be found.",
  "request_id": "4d9d8375-3c56-4925-a3e7-eb137fed17e9"
}
{
  "id": "not_found",
  "message": "The resource you were accessing could not be found.",
  "request_id": "4d9d8375-3c56-4925-a3e7-eb137fed17e9"
}
{
  "id": "example_error",
  "message": "some error message"
}

POST ValidatePolicy checks a manifest's tool-permission policy against the agent's capabilities without creating a session.

/v2/agents/sessions/policy/validate
Authorizations: bearer_auth (1 scope)
Http: Bearer
Required scopes: agent_harness_session:read

OAuth Authentication

In order to interact with the DigitalOcean API, you or your application must authenticate.

The DigitalOcean API handles this through OAuth, an open standard for authorization. OAuth allows you to delegate access to your account. Scopes can be used to grant full access, read-only access, or access to a specific set of endpoints.

You can generate an OAuth token by visiting the Apps & API section of the DigitalOcean control panel for your account.

An OAuth token functions as a complete authentication request. In effect, it acts as a substitute for a username and password pair.

Because of this, it is absolutely essential that you keep your OAuth tokens secure. In fact, upon generation, the web interface will only display each token a single time in order to prevent the token from being compromised.

DigitalOcean access tokens begin with an identifiable prefix in order to distinguish them from other similar tokens.

  • dop_v1_ for personal access tokens generated in the control panel
  • doo_v1_ for tokens generated by applications using the OAuth flow
  • dor_v1_ for OAuth refresh tokens

Scopes

Scopes act like permissions assigned to an API token. These permissions determine what actions the token can perform. You can create API tokens that grant read-only access, full access, or limited access to specific endpoints by using custom scopes.

Generally, scopes are designed to match HTTP verbs and common CRUD operations (Create, Read, Update, Delete).

HTTP Verb CRUD Operation Scope
GET Read <resource>:read
POST Create <resource>:create
PUT/PATCH Update <resource>:update
DELETE Delete <resource>:delete

For example, creating a new Droplet by making a POST request to the /v2/droplets endpoint requires the droplet:create scope while listing Droplets by making a GET request to the /v2/droplets endpoint requires the droplet:read scope.

Each endpoint below specifies which scope is required to access it when using custom scopes.

How to Authenticate with OAuth

In order to make an authenticated request, include a bearer-type Authorization header containing your OAuth token. All requests must be made over HTTPS.

Authenticate with a Bearer Authorization Header

curl -X $HTTP_METHOD -H "Authorization: Bearer $DIGITALOCEAN_TOKEN" "https://api.digitalocean.com/v2/$OBJECT"

Stateless preflight: parses the same environment spec as CreateSession and runs the identical resolve + validate pipeline against the capability descriptor stamped on the selected template's image (resolved per-request via the sandbox, not a separate registry). Returns per-rule verdicts. Nothing is provisioned or persisted.

Each rule is validated against the descriptor for the (agent, version) the template resolves to and gets a verdict: exact, degraded, unsupported, or unverified. ok is false when any strict rule is unsupported or unverified — i.e. CreateSession would reject the policy for that agent. An empty spec.permissions returns ok: true with no verdicts. Because it shares the create path's descriptor lookup, the verdicts match what CreateSession would compute.

Request Body: application/x-yaml

The same environment spec you would submit to CreateSession (YAML). Only agent/template selection and the permissions block are used. The live API also accepts application/yaml, text/yaml, and text/x-yaml; OpenAPI content lists a single media type so generated clients can emit this operation.

apiVersion string, one of: agents.digitalocean.com/v1alpha1 optional
Example: agents.digitalocean.com/v1alpha1

Legacy envelope only - must be "agents.digitalocean.com/v1alpha1", and its presence is what routes the document to the deprecated legacy parser. Flat-format manifests carry no version key (the endpoint owns the contract); required, with kind and spec, when authoring the legacy format.

kind string, one of: Agent optional
Example: Agent

Must be "Agent".

metadata object optional
Show child properties
description string optional
Example: Use when ...

Free-form description (max 1024 chars), stored and echoed back for Console / catalog surfaces.

labels object optional
Example: {}
name string optional
Example: example

Optional team-unique session name: 1-64 chars of letters, digits, '-', '.', '_', starting and ending alphanumeric; case-insensitive; must not be UUID-shaped. Omit to have the control plane generate one ("session--"). Unique among the team's ACTIVE (non-terminal) sessions; destroying a session frees its name for reuse.

spec object optional
Show child properties
defaults object optional
Show child properties
budget object optional

Accepted, not yet enforced (returns a warning). Advisory per-run ceilings, clamped server-side to tenant policy.

Show child properties
maxCostUSD number optional
Example: 1
maxSteps integer optional
Example: 1
maxWallClockSeconds integer (int64) optional
Example: 1
onBreach string, one of: pause, humanInput, fail optional
Example: pause
env object optional
Example: {}

Non-secret guest env (debug-readable - never put secrets here; use spec.secrets). Reserved platform keys (TEAM_ID, SESSION_ID, SANDBOX_ID, CONTROL_PLANE_CALLBACK_URL, SANDBOX_TEMPLATE, SANDBOX_AGENT_WORKDIR, SIZE_SLUG, SANDBOX_IMAGE_ID, SANDBOX_OCI_REF, PLANO_PERMISSION_*) are rejected. Credential-looking values (dop_v1_..., sk-..., ghp_...) trigger a create-time warning.

memory object optional

Accepted, not yet enforced (returns a warning).

Show child properties
backend string required
Example: example
scope string, one of: tenant, user, agent, session optional
Example: tenant
mode string, one of: interactive, served optional
Example: interactive

Explicit lifecycle discriminator. Defaults to "interactive" (spec.serving forbidden); "served" requires spec.serving.

model object optional

Accepted, not yet enforced (returns a warning). Model routing (Plano); catalog-validated when enforcement lands.

Show child properties
default string optional
Example: example
profile string optional
Example: example
routing string optional
Example: example
permissions object optional

Customer-declared tool-execution permission policy (spec.permissions). REQUEST only: the policy engine resolves it (∩ tenant ∩ platform) into the canonical policy and validates it against the (agent, version) capability descriptor. Absent or empty means the agent keeps its built-in default gating — no policy is shipped to the sandbox.

Show child properties
defaultAction string, one of: allow, ask, deny optional
Example: allow

Disposition for tool calls that match no rule. Defaults to "ask" when omitted.

filesystem object optional

Filesystem boundary, enforced by the microVM (read-only root + bind-mounted writable roots) for every agent.

Show child properties
allowWrite array of string optional
Example: ["example"]

Additional writable paths beyond the workspace. Values must not contain shell-style ${VAR}/$VAR expansions.

mode string, one of: read-only, workspace-write optional
Example: read-only
network object optional

Network boundary. Narrows (subtract-only) spec.sandbox.egress; link-local/internal addresses stay blocked by the broader egress policy.

Show child properties
allow array of string optional
Example: ["example"]
default string, one of: allow, deny optional
Example: allow
rules array of object optional

Ordered match→action rules. Declared order is authoritative: the LAST matching rule wins (author-order last-match).

Show child properties
action string, one of: allow, ask, deny required
Example: allow
enforcement string, one of: strict, best-effort optional
Example: strict

What happens when the agent cannot enforce the rule exactly. "strict" rejects the session; "best-effort" degrades to the closest more-restrictive form and warns (never widens). Defaults to strict for deny rules, best-effort otherwise.

match object optional

Optional keys narrowing the rule (e.g. {"command": "npm run deploy"} for bash). Values are globs and must not contain shell-style ${VAR}/$VAR expansions.

Additional nested properties not shown. Refer to the full API spec for details.
tool string required
Example: example

Tool taxonomy this rule matches (e.g. bash, file.read, file.write, web.fetch, git.*, mcp).

runtime object required

Canonical adapter ids: claude-code | opencode | codex | cursor | hermes | codex-agentapi | custom. codex-agentapi is the OpenAI sandbox-provider runtime (DO runs codex exec-server; the agent loop lives at OpenAI) and pairs with the opaque spec.runtime.config block. codex-cli and cursor-cli are deprecated aliases (accepted with a create-time warning). The framework adapters (openai-agents, claude-agent-sdk, crewai, langgraph) are declared but not yet supported; CreateSession rejects them. adapter: custom requires the custom block.

Show child properties
adapter string (enum) required
Example: claude-code
config object optional
Example: {}

OPAQUE, provider-specific runtime config. Only for adapter: codex-agentapi today, where it is the OpenAI Agents API create-session body (agent/environment/input) that doctl forwards verbatim to OpenAI's POST /v1/agents/sessions; harness-api stores and echoes it but never parses or validates its contents (so DO stays forward-compatible as OpenAI's schema evolves). The OpenAI session_id is passed on the create call (the openai_session_id query parameter), not in this block.

custom object optional

BYO container; requires adapter: custom. image is required and should be digest-pinned.

Show child properties
entrypoint array of string optional
Example: ["example"]
image string required
Example: example.registry/image@sha256:abc
sandbox object optional
Show child properties
egress object optional

Requested egress policy (legacy envelope). unrestricted opts out of platform-default host allowlists and cannot combine with allow / allowIps / vpcUuid / subnetUuid. Absent or empty means no destination ACL (same as unrestricted). Flat authors prefer egress: unrestricted (scalar), a bare host list, or an object with allow_hosts / allow_ips / vpc_uuid / subnet_uuid. Platform host defaults are unioned only when allow names something; allowIps does not trigger that union (IP-only turns the destination ACL on without domain rules). VPC attachment is create-time immutable; ownership is verified at session create. Allowlists are a request only: the server intersects them with tenant + platform policy and can only narrow them.

Show child properties
allow array of object optional
Additional nested properties not shown. Refer to the full API spec for details.
allowIps array of string optional
Example: ["example"]

Exact IPv4/IPv6 literals (not CIDRs).

subnetUuid string optional
Example: example

Optional subnet within vpcUuid.

unrestricted boolean optional
Example: true

When true, opts out of the platform-default host allowlist union. Mutually exclusive with allow / allowIps / vpcUuid / subnetUuid.

vpcUuid string optional
Example: example

Customer VPC UUID. Create-time immutable.

idleTimeoutSeconds integer (int64) optional
Example: 1

Inactivity suspend timeout. 0 means tenant policy default.

maxLifetimeSeconds integer (int64) optional
Example: 1

Hard wall-clock ceiling for the whole session, independent of activity. Accepted, not yet enforced (returns a warning).

mounts array of object optional

Requested data mounts. Accepted, not yet enforced (returns a warning). accessKeyRef/secretKeyRef name declared tenantSecret slots in spec.secrets, validated at create; declare those slots with env: false so the keys stay mount-scoped and out of the guest env.

Show child properties
accessKeyRef string required
Example: my-secret

Names a declared tenantSecret slot in spec.secrets.

bucket string required
Example: my-bucket
endpoint string optional
Example: https://nyc3.digitaloceanspaces.com

Optional storage endpoint override; https:// only.

path string required
Example: /mnt/data

Absolute guest path the mount appears at.

readOnly boolean optional
Example: true
secretKeyRef string required
Example: my-secret

Names a declared tenantSecret slot in spec.secrets.

type string, one of: s3fuse required
Example: s3fuse
persistentWorkspace boolean optional
Example: true
sizeSlug string optional
Example: example

Requested sandbox size (catalog: GET /v2/agents/sessions/sandbox/sizes). Empty means the service default.

template string optional
Example: example

Optional sandbox template. Empty (or the legacy placeholder "coding") means "no preference": the template derives from the adapter.

secrets array of object optional

Declared credential requirements. source tenantSecret is enforced today: value is write-only plaintext, extracted into Secrets Manager at create and never persisted or returned. source oauth requires provider, carries no value, and is accepted but not yet enforced. ref is legacy and ignored. env false keeps the resolved value out of the guest environment (mount-only slots).

Show child properties
env boolean optional
Example: true

Whether the resolved credential is injected into the guest env. Omitted means true; false is for mount-only slots (tenantSecret only).

name string required
Example: example
provider string optional
Example: openai
ref string optional
Example: do.actions
source string, one of: oauth, tenantSecret required
Example: oauth
value string optional
Example: sk-example

Write-only tenantSecret plaintext; never persisted or returned.

serving object optional

Present only when spec.mode is "served" (autoscaled fleet).

Show child properties
maxReplicas integer optional
Example: 1
minReplicas integer optional
Example: 1
scaleToZero object optional
Show child properties
idleSeconds integer (int64) optional
Example: 1
targetConcurrency integer optional
Example: 1
skills array of object optional

Inline agent skills (SKILL.md shape): reusable markdown instructions the agent loads on demand, selected by description. Accepted, not yet enforced (returns a warning). Max 32 entries; instructions additionally capped at 256 KiB summed across the list so a valid manifest always fits the request-body limits. v0 is inline-only - remote skill sources come later as an additive field.

Show child properties
allowedTools array of string optional
Example: ["example"]

Advisory scoping of which tools the skill expects to use (experimental in the skills standard). NOT a security boundary - spec.permissions remains the only enforcement surface.

description string required
Example: Use when ...

Load-bearing: the agent reads it to decide WHEN to load the skill (progressive disclosure); write it as "Use when ...". Max 1024 chars.

instructions string required
Example: Use when diagnosing errors.

The markdown body (the content below the SKILL.md frontmatter). Max 32 KiB.

license string optional
Example: Apache-2.0

Optional standard passthrough (e.g. Apache-2.0).

metadata object optional
Example: {}

Optional string-map passthrough (e.g. author), rendered into the frontmatter verbatim.

name string required
Example: example

Unique across the list; 1-64 chars of lowercase letters, digits, and single hyphen separators - no consecutive hyphens, per the Agent Skills spec (safe as a directory name at materialization).

tools object optional

Accepted, not yet enforced (returns a warning). Exactly one of mcpServers or bundle.

Show child properties
bundle string optional
Example: default
mcpServers array of object optional
Show child properties
auth object optional

Brokered credential for an INLINE server (invalid on the catalog form). secretRef names a declared tenantSecret slot in spec.secrets, validated at create; the slot is resolved server-side and sent as an HTTP header. Plaintext credentials are never accepted.

Additional nested properties not shown. Refer to the full API spec for details.
name string optional
Example: example

Inline server name (required with url): 1-64 chars of lowercase letters, digits, '-', '.', '_', starting/ending alphanumeric. Unique across the list. Must not start with do. (reserved for catalog refs).

preloadTools array of string optional
Example: ["example"]

Catalog form only. Individual tools (optional integer pin) advertised directly in the session MCP tools/list next to the action_search/action_invoke/action_code meta tools. Each entry must appear in tools when tools is set; toolbelt references are rejected. Every preloaded schema is in the model's context on every turn, so keep this to a handful of tools. Omitted means nothing is preloaded.

ref string optional
Example: do.actions

DO-owned catalog reference (catalog form); do.* only, e.g. do.actions. Mutually exclusive with name/url/auth.

tools array of string optional
Example: ["example"]

Optional selection allowlist; omitted means all tools the server advertises. Each entry is an individual tool name with an optional integer version pin (e.g. web_search, execute_code@3) or a toolbelt reference - a server-defined named tool group written toolbelt:[@] (e.g. toolbelt:read-only@1; catalog refs only). Versions are integer pins (no semver). The server owns belt expansion; a pinned tool or belt attaches exactly that version, an unpinned one resolves at session create and is frozen for the session (no floating latest). Entries non-empty, unique per server. The selection bounds the session and is never preloaded into the session MCP tools/list; see preloadTools.

url string optional
Example: https://example.com

Inline server endpoint; https:// only.

workspace object optional

Repositories the session works against.

Show child properties
repos array of string optional
Example: ["example"]

GitHub OWNER/REPO entries, unique. The first entry becomes the session's repo_hint; the full list is the forward shape for multi-repo sessions.

Content type application/x-yaml
{
  "apiVersion": "agents.digitalocean.com/v1alpha1",
  "kind": "Agent",
  "metadata": {
    "description": "Use when ...",
    "labels": {},
    "name": "example"
  },
  "spec": {
    "env": {},
    "memory": {
      "backend": "example",
      "scope": "tenant"
    },
    "mode": "interactive",
    "model": {
      "default": "example",
      "profile": "example",
      "routing": "example"
    },
    "permissions": {
      "defaultAction": "allow",
      "rules": []
    },
    "runtime": {
      "adapter": "claude-code",
      "config": {}
    },
    "sandbox": {
      "idleTimeoutSeconds": 1,
      "maxLifetimeSeconds": 1,
      "mounts": [],
      "persistentWorkspace": true,
      "sizeSlug": "example",
      "template": "example"
    },
    "secrets": [],
    "serving": {
      "maxReplicas": 1,
      "minReplicas": 1,
      "targetConcurrency": 1
    },
    "skills": [],
    "tools": {
      "bundle": "default",
      "mcpServers": []
    },
    "workspace": {
      "repos": [
        "example"
      ]
    }
  }
}
curl -X POST \
  -H "Content-Type: application/json" \
  -H "Authorization: Bearer $DIGITALOCEAN_TOKEN" \
  "https://api.digitalocean.com/v2/agents/sessions/policy/validate"
curl -X POST \
  -H "Authorization: Bearer $API_TOKEN" \
  -H "Content-Type: application/x-yaml" \
  -d '{
  "apiVersion": "agents.digitalocean.com/v1alpha1",
  "kind": "Agent",
  "metadata": {
    "description": "Use when ...",
    "labels": {},
    "name": "example"
  },
  "spec": {
    "env": {},
    "memory": {
      "backend": "example",
      "scope": "tenant"
    },
    "mode": "interactive",
    "model": {
      "default": "example",
      "profile": "example",
      "routing": "example"
    },
    "permissions": {
      "defaultAction": "allow",
      "rules": []
    },
    "runtime": {
      "adapter": "claude-code",
      "config": {}
    },
    "sandbox": {
      "idleTimeoutSeconds": 1,
      "maxLifetimeSeconds": 1,
      "mounts": [],
      "persistentWorkspace": true,
      "sizeSlug": "example",
      "template": "example"
    },
    "secrets": [],
    "serving": {
      "maxReplicas": 1,
      "minReplicas": 1,
      "targetConcurrency": 1
    },
    "skills": [],
    "tools": {
      "bundle": "default",
      "mcpServers": []
    },
    "workspace": {
      "repos": [
        "example"
      ]
    }
  }
}' \
  "https://api.digitalocean.com/v2/agents/sessions/policy/validate"

Responses

200

Per-rule verdicts for the agent the manifest resolves to. A 200 with ok: false still means the policy would be rejected at CreateSession.

ratelimit-limit integer

The default limit on number of requests that can be made per hour and per minute. Current rate limits are 5000 requests per hour and 250 requests per minute.

ratelimit-remaining integer

The number of requests in your hourly quota that remain before you hit your request limit. See https://docs.digitalocean.com/reference/api/reference/#rate-limit for information about how requests expire.

ratelimit-reset integer

The time when the oldest request will expire. The value is given in Unix epoch time. See https://docs.digitalocean.com/reference/api/reference/#rate-limit for information about how requests expire.

agent string optional
Example: example
defaultAction string, one of: allow, ask, deny optional
Example: allow

Catch-all disposition AS SHIPPED (after unverified allow→ask downgrade). When defaultActionVerdict is degraded, this remains the shipped value; see defaultActionRendered for what the agent will actually enforce.

defaultActionReason string optional
Example: example

Human-readable explanation when defaultActionVerdict is degraded.

defaultActionRendered string, one of: allow, ask, deny optional
Example: allow

Disposition the agent will actually enforce as the catch-all: equals defaultAction when exact; the more-restrictive degrade target (usually ask) when degraded.

defaultActionVerdict string, one of: exact, degraded, unsupported, unverified optional
Example: exact

exact — agent can enforce the catch-all as written; degraded — agent cannot enforce the requested defaultAction (warn-only; shipped value unchanged); omitted when no descriptor was available to classify against.

ok boolean optional
Example: true

False when any strict rule is unsupported or unverified — i.e. CreateSession would reject this policy for this (agent, version).

verdicts array of object optional
Show child properties
reason string optional
Example: example

Human-readable explanation of the verdict.

rendered string, one of: allow, ask, deny optional
Example: allow

The disposition the agent will actually enforce: the requested action when exact/unverified, the more-restrictive target when degraded, omitted when unsupported (cannot render).

rule object optional

A rule after resolution (∩ tenant ∩ platform), carrying a stable id for audit correlation.

Show child properties
action string, one of: allow, ask, deny optional
Example: allow
enforcement string, one of: strict, best-effort optional
Example: strict
id string optional
Example: example

Stable rule id assigned during resolution; correlates with the PolicyDenied event's matched rule.

match object optional
tool string optional
Example: example
suggestion string optional
Example: example

Optional actionable hint (e.g. "set enforcement: best-effort, or target a capable agent").

verdict string, one of: exact, degraded, unsupported, unverified optional
Example: exact

exact — enforced precisely as written; degraded — renderable only in a more-restrictive form (deny→ask), warned; unsupported — cannot be enforced (strict ⇒ session reject); unverified — no descriptor available, rendered conservatively but unproven.

version string optional
Example: example
400

Malformed manifest or invalid spec.permissions.

ratelimit-limit integer

The default limit on number of requests that can be made per hour and per minute. Current rate limits are 5000 requests per hour and 250 requests per minute.

ratelimit-remaining integer

The number of requests in your hourly quota that remain before you hit your request limit. See https://docs.digitalocean.com/reference/api/reference/#rate-limit for information about how requests expire.

ratelimit-reset integer

The time when the oldest request will expire. The value is given in Unix epoch time. See https://docs.digitalocean.com/reference/api/reference/#rate-limit for information about how requests expire.

id string required
Example: not_found

A short identifier corresponding to the HTTP status code returned. For example, the ID for a response returning a 404 status code would be "not_found."

message string required
Example: The resource you were accessing could not be found.

A message providing additional information about the error, including details to help resolve it when possible.

request_id string optional
Example: 4d9d8375-3c56-4925-a3e7-eb137fed17e9

Optionally, some endpoints may include a request ID that should be provided when reporting bugs or opening support tickets to help identify the issue.

401

Authentication failed due to invalid credentials.

ratelimit-limit integer

The default limit on number of requests that can be made per hour and per minute. Current rate limits are 5000 requests per hour and 250 requests per minute.

ratelimit-remaining integer

The number of requests in your hourly quota that remain before you hit your request limit. See https://docs.digitalocean.com/reference/api/reference/#rate-limit for information about how requests expire.

ratelimit-reset integer

The time when the oldest request will expire. The value is given in Unix epoch time. See https://docs.digitalocean.com/reference/api/reference/#rate-limit for information about how requests expire.

id string required
Example: not_found

A short identifier corresponding to the HTTP status code returned. For example, the ID for a response returning a 404 status code would be "not_found."

message string required
Example: The resource you were accessing could not be found.

A message providing additional information about the error, including details to help resolve it when possible.

request_id string optional
Example: 4d9d8375-3c56-4925-a3e7-eb137fed17e9

Optionally, some endpoints may include a request ID that should be provided when reporting bugs or opening support tickets to help identify the issue.

404

The resource was not found.

ratelimit-limit integer

The default limit on number of requests that can be made per hour and per minute. Current rate limits are 5000 requests per hour and 250 requests per minute.

ratelimit-remaining integer

The number of requests in your hourly quota that remain before you hit your request limit. See https://docs.digitalocean.com/reference/api/reference/#rate-limit for information about how requests expire.

ratelimit-reset integer

The time when the oldest request will expire. The value is given in Unix epoch time. See https://docs.digitalocean.com/reference/api/reference/#rate-limit for information about how requests expire.

id string required
Example: not_found

A short identifier corresponding to the HTTP status code returned. For example, the ID for a response returning a 404 status code would be "not_found."

message string required
Example: The resource you were accessing could not be found.

A message providing additional information about the error, including details to help resolve it when possible.

request_id string optional
Example: 4d9d8375-3c56-4925-a3e7-eb137fed17e9

Optionally, some endpoints may include a request ID that should be provided when reporting bugs or opening support tickets to help identify the issue.

429

The API rate limit has been exceeded.

ratelimit-limit integer

The default limit on number of requests that can be made per hour and per minute. Current rate limits are 5000 requests per hour and 250 requests per minute.

ratelimit-remaining integer

The number of requests in your hourly quota that remain before you hit your request limit. See https://docs.digitalocean.com/reference/api/reference/#rate-limit for information about how requests expire.

ratelimit-reset integer

The time when the oldest request will expire. The value is given in Unix epoch time. See https://docs.digitalocean.com/reference/api/reference/#rate-limit for information about how requests expire.

id string required
Example: not_found

A short identifier corresponding to the HTTP status code returned. For example, the ID for a response returning a 404 status code would be "not_found."

message string required
Example: The resource you were accessing could not be found.

A message providing additional information about the error, including details to help resolve it when possible.

request_id string optional
Example: 4d9d8375-3c56-4925-a3e7-eb137fed17e9

Optionally, some endpoints may include a request ID that should be provided when reporting bugs or opening support tickets to help identify the issue.

500

There was a server error.

ratelimit-limit integer

The default limit on number of requests that can be made per hour and per minute. Current rate limits are 5000 requests per hour and 250 requests per minute.

ratelimit-remaining integer

The number of requests in your hourly quota that remain before you hit your request limit. See https://docs.digitalocean.com/reference/api/reference/#rate-limit for information about how requests expire.

ratelimit-reset integer

The time when the oldest request will expire. The value is given in Unix epoch time. See https://docs.digitalocean.com/reference/api/reference/#rate-limit for information about how requests expire.

id string required
Example: not_found

A short identifier corresponding to the HTTP status code returned. For example, the ID for a response returning a 404 status code would be "not_found."

message string required
Example: The resource you were accessing could not be found.

A message providing additional information about the error, including details to help resolve it when possible.

request_id string optional
Example: 4d9d8375-3c56-4925-a3e7-eb137fed17e9

Optionally, some endpoints may include a request ID that should be provided when reporting bugs or opening support tickets to help identify the issue.

default

There was an unexpected error.

ratelimit-limit integer

The default limit on number of requests that can be made per hour and per minute. Current rate limits are 5000 requests per hour and 250 requests per minute.

ratelimit-remaining integer

The number of requests in your hourly quota that remain before you hit your request limit. See https://docs.digitalocean.com/reference/api/reference/#rate-limit for information about how requests expire.

ratelimit-reset integer

The time when the oldest request will expire. The value is given in Unix epoch time. See https://docs.digitalocean.com/reference/api/reference/#rate-limit for information about how requests expire.

id string required
Example: not_found

A short identifier corresponding to the HTTP status code returned. For example, the ID for a response returning a 404 status code would be "not_found."

message string required
Example: The resource you were accessing could not be found.

A message providing additional information about the error, including details to help resolve it when possible.

request_id string optional
Example: 4d9d8375-3c56-4925-a3e7-eb137fed17e9

Optionally, some endpoints may include a request ID that should be provided when reporting bugs or opening support tickets to help identify the issue.

{
  "agent": "example",
  "defaultAction": "allow",
  "defaultActionReason": "example",
  "defaultActionRendered": "allow",
  "defaultActionVerdict": "exact",
  "ok": true,
  "verdicts": [
    {
      "reason": "example",
      "rendered": "allow",
      "suggestion": "example",
      "verdict": "exact"
    }
  ],
  "version": "example"
}
{
  "id": "not_found",
  "message": "The resource you were accessing could not be found.",
  "request_id": "4d9d8375-3c56-4925-a3e7-eb137fed17e9"
}
{
  "id": "unauthorized",
  "message": "Unable to authenticate you."
}
{
  "id": "not_found",
  "message": "The resource you requested could not be found."
}
{
  "id": "too_many_requests",
  "message": "API rate limit exceeded."
}
{
  "id": "server_error",
  "message": "Unexpected server-side error"
}
{
  "id": "example_error",
  "message": "some error message"
}

GET ListSandboxSizes returns the customer-selectable sandbox (microVM) size catalog.

/v2/agents/sessions/sandbox/sizes
Authorizations: bearer_auth (1 scope)
Http: Bearer
Required scopes: agent_harness_session:read

OAuth Authentication

In order to interact with the DigitalOcean API, you or your application must authenticate.

The DigitalOcean API handles this through OAuth, an open standard for authorization. OAuth allows you to delegate access to your account. Scopes can be used to grant full access, read-only access, or access to a specific set of endpoints.

You can generate an OAuth token by visiting the Apps & API section of the DigitalOcean control panel for your account.

An OAuth token functions as a complete authentication request. In effect, it acts as a substitute for a username and password pair.

Because of this, it is absolutely essential that you keep your OAuth tokens secure. In fact, upon generation, the web interface will only display each token a single time in order to prevent the token from being compromised.

DigitalOcean access tokens begin with an identifiable prefix in order to distinguish them from other similar tokens.

  • dop_v1_ for personal access tokens generated in the control panel
  • doo_v1_ for tokens generated by applications using the OAuth flow
  • dor_v1_ for OAuth refresh tokens

Scopes

Scopes act like permissions assigned to an API token. These permissions determine what actions the token can perform. You can create API tokens that grant read-only access, full access, or limited access to specific endpoints by using custom scopes.

Generally, scopes are designed to match HTTP verbs and common CRUD operations (Create, Read, Update, Delete).

HTTP Verb CRUD Operation Scope
GET Read <resource>:read
POST Create <resource>:create
PUT/PATCH Update <resource>:update
DELETE Delete <resource>:delete

For example, creating a new Droplet by making a POST request to the /v2/droplets endpoint requires the droplet:create scope while listing Droplets by making a GET request to the /v2/droplets endpoint requires the droplet:read scope.

Each endpoint below specifies which scope is required to access it when using custom scopes.

How to Authenticate with OAuth

In order to make an authenticated request, include a bearer-type Authorization header containing your OAuth token. All requests must be made over HTTPS.

Authenticate with a Bearer Authorization Header

curl -X $HTTP_METHOD -H "Authorization: Bearer $DIGITALOCEAN_TOKEN" "https://api.digitalocean.com/v2/$OBJECT"

Read-only catalog the UI (and other clients) render as the size picker, instead of hardcoding the list. The set is the single source of truth shared with create-time validation and the default-size fallback, so every slug returned here is accepted by CreateSession as spec.sandbox.sizeSlug. Sizes are returned smallest-to-largest. Static and safe to cache; independent of team/session; no pagination.

curl -X GET \
  -H "Content-Type: application/json" \
  -H "Authorization: Bearer $DIGITALOCEAN_TOKEN" \
  "https://api.digitalocean.com/v2/agents/sessions/sandbox/sizes"
curl -X GET \
  -H "Authorization: Bearer $API_TOKEN" \
  "https://api.digitalocean.com/v2/agents/sessions/sandbox/sizes"

Responses

200

The supported sandbox sizes.

ratelimit-limit integer

The default limit on number of requests that can be made per hour and per minute. Current rate limits are 5000 requests per hour and 250 requests per minute.

ratelimit-remaining integer

The number of requests in your hourly quota that remain before you hit your request limit. See https://docs.digitalocean.com/reference/api/reference/#rate-limit for information about how requests expire.

ratelimit-reset integer

The time when the oldest request will expire. The value is given in Unix epoch time. See https://docs.digitalocean.com/reference/api/reference/#rate-limit for information about how requests expire.

sizes array of object optional

Selectable sizes, ordered smallest-to-largest.

Show child properties
memory_mb integer (int64) optional
Example: 4096

Memory in MB (for display).

price_per_hour_usd number (double) optional
Example: 3e-05

Hourly on-demand price in USD (for display).

price_per_month_usd number (double) optional
Example: 93.744

Monthly on-demand price in USD, assuming continuous usage (for display).

slug string optional
Example: mars-2vcpu-4gb

DO size slug; submit as spec.sandbox.sizeSlug on CreateSession. e.g. "mars-2vcpu-4gb".

vcpus integer (int64) optional
Example: 2

vCPU count (for display).

401

Authentication failed due to invalid credentials.

ratelimit-limit integer

The default limit on number of requests that can be made per hour and per minute. Current rate limits are 5000 requests per hour and 250 requests per minute.

ratelimit-remaining integer

The number of requests in your hourly quota that remain before you hit your request limit. See https://docs.digitalocean.com/reference/api/reference/#rate-limit for information about how requests expire.

ratelimit-reset integer

The time when the oldest request will expire. The value is given in Unix epoch time. See https://docs.digitalocean.com/reference/api/reference/#rate-limit for information about how requests expire.

id string required
Example: not_found

A short identifier corresponding to the HTTP status code returned. For example, the ID for a response returning a 404 status code would be "not_found."

message string required
Example: The resource you were accessing could not be found.

A message providing additional information about the error, including details to help resolve it when possible.

request_id string optional
Example: 4d9d8375-3c56-4925-a3e7-eb137fed17e9

Optionally, some endpoints may include a request ID that should be provided when reporting bugs or opening support tickets to help identify the issue.

404

The resource was not found.

ratelimit-limit integer

The default limit on number of requests that can be made per hour and per minute. Current rate limits are 5000 requests per hour and 250 requests per minute.

ratelimit-remaining integer

The number of requests in your hourly quota that remain before you hit your request limit. See https://docs.digitalocean.com/reference/api/reference/#rate-limit for information about how requests expire.

ratelimit-reset integer

The time when the oldest request will expire. The value is given in Unix epoch time. See https://docs.digitalocean.com/reference/api/reference/#rate-limit for information about how requests expire.

id string required
Example: not_found

A short identifier corresponding to the HTTP status code returned. For example, the ID for a response returning a 404 status code would be "not_found."

message string required
Example: The resource you were accessing could not be found.

A message providing additional information about the error, including details to help resolve it when possible.

request_id string optional
Example: 4d9d8375-3c56-4925-a3e7-eb137fed17e9

Optionally, some endpoints may include a request ID that should be provided when reporting bugs or opening support tickets to help identify the issue.

429

The API rate limit has been exceeded.

ratelimit-limit integer

The default limit on number of requests that can be made per hour and per minute. Current rate limits are 5000 requests per hour and 250 requests per minute.

ratelimit-remaining integer

The number of requests in your hourly quota that remain before you hit your request limit. See https://docs.digitalocean.com/reference/api/reference/#rate-limit for information about how requests expire.

ratelimit-reset integer

The time when the oldest request will expire. The value is given in Unix epoch time. See https://docs.digitalocean.com/reference/api/reference/#rate-limit for information about how requests expire.

id string required
Example: not_found

A short identifier corresponding to the HTTP status code returned. For example, the ID for a response returning a 404 status code would be "not_found."

message string required
Example: The resource you were accessing could not be found.

A message providing additional information about the error, including details to help resolve it when possible.

request_id string optional
Example: 4d9d8375-3c56-4925-a3e7-eb137fed17e9

Optionally, some endpoints may include a request ID that should be provided when reporting bugs or opening support tickets to help identify the issue.

500

There was a server error.

ratelimit-limit integer

The default limit on number of requests that can be made per hour and per minute. Current rate limits are 5000 requests per hour and 250 requests per minute.

ratelimit-remaining integer

The number of requests in your hourly quota that remain before you hit your request limit. See https://docs.digitalocean.com/reference/api/reference/#rate-limit for information about how requests expire.

ratelimit-reset integer

The time when the oldest request will expire. The value is given in Unix epoch time. See https://docs.digitalocean.com/reference/api/reference/#rate-limit for information about how requests expire.

id string required
Example: not_found

A short identifier corresponding to the HTTP status code returned. For example, the ID for a response returning a 404 status code would be "not_found."

message string required
Example: The resource you were accessing could not be found.

A message providing additional information about the error, including details to help resolve it when possible.

request_id string optional
Example: 4d9d8375-3c56-4925-a3e7-eb137fed17e9

Optionally, some endpoints may include a request ID that should be provided when reporting bugs or opening support tickets to help identify the issue.

default

There was an unexpected error.

ratelimit-limit integer

The default limit on number of requests that can be made per hour and per minute. Current rate limits are 5000 requests per hour and 250 requests per minute.

ratelimit-remaining integer

The number of requests in your hourly quota that remain before you hit your request limit. See https://docs.digitalocean.com/reference/api/reference/#rate-limit for information about how requests expire.

ratelimit-reset integer

The time when the oldest request will expire. The value is given in Unix epoch time. See https://docs.digitalocean.com/reference/api/reference/#rate-limit for information about how requests expire.

id string required
Example: not_found

A short identifier corresponding to the HTTP status code returned. For example, the ID for a response returning a 404 status code would be "not_found."

message string required
Example: The resource you were accessing could not be found.

A message providing additional information about the error, including details to help resolve it when possible.

request_id string optional
Example: 4d9d8375-3c56-4925-a3e7-eb137fed17e9

Optionally, some endpoints may include a request ID that should be provided when reporting bugs or opening support tickets to help identify the issue.

{
  "sizes": [
    {
      "memory_mb": 4096,
      "price_per_hour_usd": 0.00003,
      "price_per_month_usd": 93.744,
      "slug": "mars-2vcpu-4gb",
      "vcpus": 2
    }
  ]
}
{
  "id": "unauthorized",
  "message": "Unable to authenticate you."
}
{
  "id": "not_found",
  "message": "The resource you requested could not be found."
}
{
  "id": "too_many_requests",
  "message": "API rate limit exceeded."
}
{
  "id": "server_error",
  "message": "Unexpected server-side error"
}
{
  "id": "example_error",
  "message": "some error message"
}

GET GetSession returns the current snapshot of a session.

/v2/agents/sessions/{session_id}
Authorizations: bearer_auth (1 scope)
Http: Bearer
Required scopes: agent_harness_session:read

OAuth Authentication

In order to interact with the DigitalOcean API, you or your application must authenticate.

The DigitalOcean API handles this through OAuth, an open standard for authorization. OAuth allows you to delegate access to your account. Scopes can be used to grant full access, read-only access, or access to a specific set of endpoints.

You can generate an OAuth token by visiting the Apps & API section of the DigitalOcean control panel for your account.

An OAuth token functions as a complete authentication request. In effect, it acts as a substitute for a username and password pair.

Because of this, it is absolutely essential that you keep your OAuth tokens secure. In fact, upon generation, the web interface will only display each token a single time in order to prevent the token from being compromised.

DigitalOcean access tokens begin with an identifiable prefix in order to distinguish them from other similar tokens.

  • dop_v1_ for personal access tokens generated in the control panel
  • doo_v1_ for tokens generated by applications using the OAuth flow
  • dor_v1_ for OAuth refresh tokens

Scopes

Scopes act like permissions assigned to an API token. These permissions determine what actions the token can perform. You can create API tokens that grant read-only access, full access, or limited access to specific endpoints by using custom scopes.

Generally, scopes are designed to match HTTP verbs and common CRUD operations (Create, Read, Update, Delete).

HTTP Verb CRUD Operation Scope
GET Read <resource>:read
POST Create <resource>:create
PUT/PATCH Update <resource>:update
DELETE Delete <resource>:delete

For example, creating a new Droplet by making a POST request to the /v2/droplets endpoint requires the droplet:create scope while listing Droplets by making a GET request to the /v2/droplets endpoint requires the droplet:read scope.

Each endpoint below specifies which scope is required to access it when using custom scopes.

How to Authenticate with OAuth

In order to make an authenticated request, include a bearer-type Authorization header containing your OAuth token. All requests must be made over HTTPS.

Authenticate with a Bearer Authorization Header

curl -X $HTTP_METHOD -H "Authorization: Bearer $DIGITALOCEAN_TOKEN" "https://api.digitalocean.com/v2/$OBJECT"

GetSession returns the current snapshot of a session.

Path Parameters

session_id string required
Example: a1b2c3d4-e5f6-7890-abcd-ef1234567890

The session UUID.

curl -X GET \
  -H "Content-Type: application/json" \
  -H "Authorization: Bearer $DIGITALOCEAN_TOKEN" \
  "https://api.digitalocean.com/v2/agents/sessions/{session_id}"
curl -X GET \
  -H "Authorization: Bearer $API_TOKEN" \
  "https://api.digitalocean.com/v2/agents/sessions/{session_id}"

Responses

200

A successful response.

ratelimit-limit integer

The default limit on number of requests that can be made per hour and per minute. Current rate limits are 5000 requests per hour and 250 requests per minute.

ratelimit-remaining integer

The number of requests in your hourly quota that remain before you hit your request limit. See https://docs.digitalocean.com/reference/api/reference/#rate-limit for information about how requests expire.

ratelimit-reset integer

The time when the oldest request will expire. The value is given in Unix epoch time. See https://docs.digitalocean.com/reference/api/reference/#rate-limit for information about how requests expire.

session object optional

Session is the user-facing record of a environment session + sandbox pair.

Show child properties
agent_kind string (enum) optional
Example: AGENT_KIND_UNSPECIFIED

AgentKind identifies what runs inside the session sandbox. CreateSession accepts CLAUDE_CODE, OPENCODE, CODEX_CLI, CURSOR_CLI, OPENAI_CODEX, LANGGRAPH, and CREWAI (the supported set is overridable via HARNESS_SUPPORTED_AGENT_KINDS); other values are rejected with 400. AGENT_KIND_OPENAI_CODEX is the OpenAI sandbox-provider kind (DO runs codex exec-server; the agent loop lives at OpenAI). AGENT_KIND_LANGGRAPH is the LangGraph framework adapter. AGENT_KIND_CREWAI is the CrewAI Crew framework adapter: like LANGGRAPH the template bakes no agent code, so spec.env must supply FRAMEWORK_REPO and FRAMEWORK_REPO_SHA; a Crew kickoff is one-shot and exposes no HITL surface. CREWAI is additionally gated per team and returns 400 for teams it is not enabled for.

config_id string (uuid) optional
Example: 11111111-2222-3333-4444-555555555555

Durable Environment Config UUID the session was created from (inline manifests persist a config too, named after the session). Persisted and returned on create/get/list; absent only for sessions created before config references were stored.

created_at string (date-time) optional
Example: 2026-08-01T12:00:00Z
fork_from_checkpoint_id string optional
Example: example

Lineage: harness-api checkpoint id (cp_) the child booted from at fork time. Drives OHP inherited-history replay on attach. Omitted/empty for root sessions and legacy forks created before this field was persisted.

fork_id string (uuid) optional
Example: 11111111-2222-3333-4444-555555555555

Lineage: branch label assigned when this session was created by ForkSession (or rollback's internal fork). Omitted/empty for root sessions.

idle_timeout_seconds integer (int64) optional
Example: 60

This session's own idle-pause timeout (manifest idle_timeout). Omitted when the session uses the deployment-wide default.

keep_warm boolean optional
Example: false

Session is exempt from idle auto-pause (manifest keep_warm, or the agent-kind default: hermes sessions keep warm). Pause requests against such a session are rejected with 409. Omitted when false.

last_event_at string (date-time) optional
Example: 2026-08-01T12:00:00Z

Timestamp of the most recent event in this session's canonical stream. Drives the inactivity policy that pauses idle sessions.

name string optional
Example: demo-agent

User-assignable display name, unique per team among non-terminal sessions. Usable in place of session_id by clients (doctl / Console resolve it to the id via the ListSessions ?name= filter; the {session_id} path stays UUID-only). Supplied via the environment-spec metadata.name, or auto-generated ("session--") when omitted.

openai_environment_id string optional
Example: example

OpenAI Agents API environment id (env_…), captured from the resolved CODEX_ENVIRONMENT_ID guest env value. Populated only for AGENT_KIND_OPENAI_CODEX sessions. Non-secret correlation metadata.

openai_session_id string optional
Example: example

OpenAI Agents API session id (sess_…) this DO sandbox hosts. Populated only for AGENT_KIND_OPENAI_CODEX sessions (empty otherwise). Non-secret correlation metadata; a client (doctl agents attach) reads it to bridge to the OpenAI session. See docs/design/openai-sandbox-provider.md.

parent_session_id string optional
Example: example

Lineage: id of the session this one was forked from. Omitted/empty for root (non-fork) sessions.

pause_reason string optional
Example: example

Why this session is paused. Present only when status is SESSION_STATUS_PAUSED; omitted otherwise. Known values: manual (PauseSession RPC), idle (inactivity auto-pause), low_balance (prepay gate). Clients should treat an unrecognized value as an opaque reason string.

repo_hint string optional
Example: example

Optional repository hint supplied at session creation (first spec.workspace.repos entry of the manifest). Not authoritative; the agent may change repos in-session.

resume_on_topoff boolean optional
Example: false

Session consents to being resumed automatically when the team's prepayment balance is restored after a low-balance pause. Defaults to false at create time; may be toggled later via PATCH /v2/agents/sessions/{session_id} (resume_on_topoff only). Only a session paused with reason low_balance whose latest run did not complete is ever resumed automatically - a session the customer paused themselves, or one that idled out, stays paused regardless. Not an environment-spec field, and forks do not inherit it. Omitted when false.

sandbox_id string optional
Example: example

Sandbox identity for support / debugging. Informational; omitted until a sandbox is allocated.

session_id string optional
Example: a1b2c3d4-e5f6-7890-abcd-ef1234567890
status string (enum) optional
Example: SESSION_STATUS_UNSPECIFIED

SessionStatus is the lifecycle state of the sandbox + agent pair. SESSION_STATUS_ALL is a ListSessions status-filter value only -- no session is ever actually in this status. SESSION_STATUS_LOCKED is reserved for internal use and never appears in an end-user-facing response.

warnings array of string optional
Example: []

Non-fatal advisories computed from the manifest at create time: one entry per populated accepted-but-not-yet-enforced section (flat names: secrets, model, tools, memory, budget, max_lifetime, mounts; legacy manifests get the corresponding spec.* paths), a deprecation entry when a legacy-envelope manifest or an adapter alias (codex-cli, cursor-cli) is used, and a heuristic entry per credential-looking spec.env value. Populated on the CreateSession response only.

401

Authentication failed due to invalid credentials.

ratelimit-limit integer

The default limit on number of requests that can be made per hour and per minute. Current rate limits are 5000 requests per hour and 250 requests per minute.

ratelimit-remaining integer

The number of requests in your hourly quota that remain before you hit your request limit. See https://docs.digitalocean.com/reference/api/reference/#rate-limit for information about how requests expire.

ratelimit-reset integer

The time when the oldest request will expire. The value is given in Unix epoch time. See https://docs.digitalocean.com/reference/api/reference/#rate-limit for information about how requests expire.

id string required
Example: not_found

A short identifier corresponding to the HTTP status code returned. For example, the ID for a response returning a 404 status code would be "not_found."

message string required
Example: The resource you were accessing could not be found.

A message providing additional information about the error, including details to help resolve it when possible.

request_id string optional
Example: 4d9d8375-3c56-4925-a3e7-eb137fed17e9

Optionally, some endpoints may include a request ID that should be provided when reporting bugs or opening support tickets to help identify the issue.

403

Session belongs to another team.

ratelimit-limit integer

The default limit on number of requests that can be made per hour and per minute. Current rate limits are 5000 requests per hour and 250 requests per minute.

ratelimit-remaining integer

The number of requests in your hourly quota that remain before you hit your request limit. See https://docs.digitalocean.com/reference/api/reference/#rate-limit for information about how requests expire.

ratelimit-reset integer

The time when the oldest request will expire. The value is given in Unix epoch time. See https://docs.digitalocean.com/reference/api/reference/#rate-limit for information about how requests expire.

id string required
Example: not_found

A short identifier corresponding to the HTTP status code returned. For example, the ID for a response returning a 404 status code would be "not_found."

message string required
Example: The resource you were accessing could not be found.

A message providing additional information about the error, including details to help resolve it when possible.

request_id string optional
Example: 4d9d8375-3c56-4925-a3e7-eb137fed17e9

Optionally, some endpoints may include a request ID that should be provided when reporting bugs or opening support tickets to help identify the issue.

404

The resource was not found.

ratelimit-limit integer

The default limit on number of requests that can be made per hour and per minute. Current rate limits are 5000 requests per hour and 250 requests per minute.

ratelimit-remaining integer

The number of requests in your hourly quota that remain before you hit your request limit. See https://docs.digitalocean.com/reference/api/reference/#rate-limit for information about how requests expire.

ratelimit-reset integer

The time when the oldest request will expire. The value is given in Unix epoch time. See https://docs.digitalocean.com/reference/api/reference/#rate-limit for information about how requests expire.

id string required
Example: not_found

A short identifier corresponding to the HTTP status code returned. For example, the ID for a response returning a 404 status code would be "not_found."

message string required
Example: The resource you were accessing could not be found.

A message providing additional information about the error, including details to help resolve it when possible.

request_id string optional
Example: 4d9d8375-3c56-4925-a3e7-eb137fed17e9

Optionally, some endpoints may include a request ID that should be provided when reporting bugs or opening support tickets to help identify the issue.

423

This session is unavailable; contact support.

ratelimit-limit integer

The default limit on number of requests that can be made per hour and per minute. Current rate limits are 5000 requests per hour and 250 requests per minute.

ratelimit-remaining integer

The number of requests in your hourly quota that remain before you hit your request limit. See https://docs.digitalocean.com/reference/api/reference/#rate-limit for information about how requests expire.

ratelimit-reset integer

The time when the oldest request will expire. The value is given in Unix epoch time. See https://docs.digitalocean.com/reference/api/reference/#rate-limit for information about how requests expire.

id string required
Example: not_found

A short identifier corresponding to the HTTP status code returned. For example, the ID for a response returning a 404 status code would be "not_found."

message string required
Example: The resource you were accessing could not be found.

A message providing additional information about the error, including details to help resolve it when possible.

request_id string optional
Example: 4d9d8375-3c56-4925-a3e7-eb137fed17e9

Optionally, some endpoints may include a request ID that should be provided when reporting bugs or opening support tickets to help identify the issue.

429

The API rate limit has been exceeded.

ratelimit-limit integer

The default limit on number of requests that can be made per hour and per minute. Current rate limits are 5000 requests per hour and 250 requests per minute.

ratelimit-remaining integer

The number of requests in your hourly quota that remain before you hit your request limit. See https://docs.digitalocean.com/reference/api/reference/#rate-limit for information about how requests expire.

ratelimit-reset integer

The time when the oldest request will expire. The value is given in Unix epoch time. See https://docs.digitalocean.com/reference/api/reference/#rate-limit for information about how requests expire.

id string required
Example: not_found

A short identifier corresponding to the HTTP status code returned. For example, the ID for a response returning a 404 status code would be "not_found."

message string required
Example: The resource you were accessing could not be found.

A message providing additional information about the error, including details to help resolve it when possible.

request_id string optional
Example: 4d9d8375-3c56-4925-a3e7-eb137fed17e9

Optionally, some endpoints may include a request ID that should be provided when reporting bugs or opening support tickets to help identify the issue.

500

There was a server error.

ratelimit-limit integer

The default limit on number of requests that can be made per hour and per minute. Current rate limits are 5000 requests per hour and 250 requests per minute.

ratelimit-remaining integer

The number of requests in your hourly quota that remain before you hit your request limit. See https://docs.digitalocean.com/reference/api/reference/#rate-limit for information about how requests expire.

ratelimit-reset integer

The time when the oldest request will expire. The value is given in Unix epoch time. See https://docs.digitalocean.com/reference/api/reference/#rate-limit for information about how requests expire.

id string required
Example: not_found

A short identifier corresponding to the HTTP status code returned. For example, the ID for a response returning a 404 status code would be "not_found."

message string required
Example: The resource you were accessing could not be found.

A message providing additional information about the error, including details to help resolve it when possible.

request_id string optional
Example: 4d9d8375-3c56-4925-a3e7-eb137fed17e9

Optionally, some endpoints may include a request ID that should be provided when reporting bugs or opening support tickets to help identify the issue.

default

There was an unexpected error.

ratelimit-limit integer

The default limit on number of requests that can be made per hour and per minute. Current rate limits are 5000 requests per hour and 250 requests per minute.

ratelimit-remaining integer

The number of requests in your hourly quota that remain before you hit your request limit. See https://docs.digitalocean.com/reference/api/reference/#rate-limit for information about how requests expire.

ratelimit-reset integer

The time when the oldest request will expire. The value is given in Unix epoch time. See https://docs.digitalocean.com/reference/api/reference/#rate-limit for information about how requests expire.

id string required
Example: not_found

A short identifier corresponding to the HTTP status code returned. For example, the ID for a response returning a 404 status code would be "not_found."

message string required
Example: The resource you were accessing could not be found.

A message providing additional information about the error, including details to help resolve it when possible.

request_id string optional
Example: 4d9d8375-3c56-4925-a3e7-eb137fed17e9

Optionally, some endpoints may include a request ID that should be provided when reporting bugs or opening support tickets to help identify the issue.

{
  "session": {
    "agent_kind": "AGENT_KIND_UNSPECIFIED",
    "config_id": "11111111-2222-3333-4444-555555555555",
    "created_at": "2026-08-01T12:00:00Z",
    "fork_from_checkpoint_id": "example",
    "fork_id": "11111111-2222-3333-4444-555555555555",
    "idle_timeout_seconds": 60,
    "keep_warm": false,
    "last_event_at": "2026-08-01T12:00:00Z",
    "name": "demo-agent",
    "openai_environment_id": "example",
    "openai_session_id": "example",
    "parent_session_id": "example",
    "pause_reason": "example",
    "repo_hint": "example",
    "resume_on_topoff": false,
    "sandbox_id": "example",
    "session_id": "a1b2c3d4-e5f6-7890-abcd-ef1234567890",
    "status": "SESSION_STATUS_UNSPECIFIED",
    "warnings": []
  }
}
{
  "id": "unauthorized",
  "message": "Unable to authenticate you."
}
{
  "id": "not_found",
  "message": "The resource you were accessing could not be found.",
  "request_id": "4d9d8375-3c56-4925-a3e7-eb137fed17e9"
}
{
  "id": "not_found",
  "message": "The resource you requested could not be found."
}
{
  "id": "not_found",
  "message": "The resource you were accessing could not be found.",
  "request_id": "4d9d8375-3c56-4925-a3e7-eb137fed17e9"
}
{
  "id": "too_many_requests",
  "message": "API rate limit exceeded."
}
{
  "id": "server_error",
  "message": "Unexpected server-side error"
}
{
  "id": "example_error",
  "message": "some error message"
}

PATCH PatchSession updates session-scoped settings on an existing session.

/v2/agents/sessions/{session_id}
Authorizations: bearer_auth (1 scope)
Http: Bearer
Required scopes: agent_harness_session:manage

OAuth Authentication

In order to interact with the DigitalOcean API, you or your application must authenticate.

The DigitalOcean API handles this through OAuth, an open standard for authorization. OAuth allows you to delegate access to your account. Scopes can be used to grant full access, read-only access, or access to a specific set of endpoints.

You can generate an OAuth token by visiting the Apps & API section of the DigitalOcean control panel for your account.

An OAuth token functions as a complete authentication request. In effect, it acts as a substitute for a username and password pair.

Because of this, it is absolutely essential that you keep your OAuth tokens secure. In fact, upon generation, the web interface will only display each token a single time in order to prevent the token from being compromised.

DigitalOcean access tokens begin with an identifiable prefix in order to distinguish them from other similar tokens.

  • dop_v1_ for personal access tokens generated in the control panel
  • doo_v1_ for tokens generated by applications using the OAuth flow
  • dor_v1_ for OAuth refresh tokens

Scopes

Scopes act like permissions assigned to an API token. These permissions determine what actions the token can perform. You can create API tokens that grant read-only access, full access, or limited access to specific endpoints by using custom scopes.

Generally, scopes are designed to match HTTP verbs and common CRUD operations (Create, Read, Update, Delete).

HTTP Verb CRUD Operation Scope
GET Read <resource>:read
POST Create <resource>:create
PUT/PATCH Update <resource>:update
DELETE Delete <resource>:delete

For example, creating a new Droplet by making a POST request to the /v2/droplets endpoint requires the droplet:create scope while listing Droplets by making a GET request to the /v2/droplets endpoint requires the droplet:read scope.

Each endpoint below specifies which scope is required to access it when using custom scopes.

How to Authenticate with OAuth

In order to make an authenticated request, include a bearer-type Authorization header containing your OAuth token. All requests must be made over HTTPS.

Authenticate with a Bearer Authorization Header

curl -X $HTTP_METHOD -H "Authorization: Bearer $DIGITALOCEAN_TOKEN" "https://api.digitalocean.com/v2/$OBJECT"

Partial update of session-scoped settings (not the agent manifest / config). The body must include at least one recognized patchable property; an empty object {} is 400. Only properties listed on PatchSessionRequest are accepted — any other top-level JSON key is rejected with 400. Omitted properties are left unchanged. Today the only patchable field is resume_on_topoff; more session settings may be added over time. Terminal sessions (DESTROYED, FAILED) cannot be patched.

Path Parameters

session_id string required
Example: a1b2c3d4-e5f6-7890-abcd-ef1234567890

The session UUID.

Request Body: application/json

PATCH body: allowlisted session-scoped settings. At least one property required.

resume_on_topoff boolean optional
Example: false

When present, sets whether this session opts in to automatic resumption when the team's prepayment balance is restored after a low-balance pause. Session-scoped consent, not config-scoped. Omitted properties are not modified.

Content type application/json
{
  "resume_on_topoff": false
}
curl -X PATCH \
  -H "Content-Type: application/json" \
  -H "Authorization: Bearer $DIGITALOCEAN_TOKEN" \
  -d '{"resume_on_topoff":true}' \
  "https://api.digitalocean.com/v2/agents/sessions/{session_id}"
curl -X PATCH \
  -H "Authorization: Bearer $API_TOKEN" \
  -H "Content-Type: application/json" \
  -d '{
  "resume_on_topoff": false
}' \
  "https://api.digitalocean.com/v2/agents/sessions/{session_id}"

Responses

200

Updated session snapshot.

ratelimit-limit integer

The default limit on number of requests that can be made per hour and per minute. Current rate limits are 5000 requests per hour and 250 requests per minute.

ratelimit-remaining integer

The number of requests in your hourly quota that remain before you hit your request limit. See https://docs.digitalocean.com/reference/api/reference/#rate-limit for information about how requests expire.

ratelimit-reset integer

The time when the oldest request will expire. The value is given in Unix epoch time. See https://docs.digitalocean.com/reference/api/reference/#rate-limit for information about how requests expire.

session object optional

Session is the user-facing record of a environment session + sandbox pair.

Show child properties
agent_kind string (enum) optional
Example: AGENT_KIND_UNSPECIFIED

AgentKind identifies what runs inside the session sandbox. CreateSession accepts CLAUDE_CODE, OPENCODE, CODEX_CLI, CURSOR_CLI, OPENAI_CODEX, LANGGRAPH, and CREWAI (the supported set is overridable via HARNESS_SUPPORTED_AGENT_KINDS); other values are rejected with 400. AGENT_KIND_OPENAI_CODEX is the OpenAI sandbox-provider kind (DO runs codex exec-server; the agent loop lives at OpenAI). AGENT_KIND_LANGGRAPH is the LangGraph framework adapter. AGENT_KIND_CREWAI is the CrewAI Crew framework adapter: like LANGGRAPH the template bakes no agent code, so spec.env must supply FRAMEWORK_REPO and FRAMEWORK_REPO_SHA; a Crew kickoff is one-shot and exposes no HITL surface. CREWAI is additionally gated per team and returns 400 for teams it is not enabled for.

config_id string (uuid) optional
Example: 11111111-2222-3333-4444-555555555555

Durable Environment Config UUID the session was created from (inline manifests persist a config too, named after the session). Persisted and returned on create/get/list; absent only for sessions created before config references were stored.

created_at string (date-time) optional
Example: 2026-08-01T12:00:00Z
fork_from_checkpoint_id string optional
Example: example

Lineage: harness-api checkpoint id (cp_) the child booted from at fork time. Drives OHP inherited-history replay on attach. Omitted/empty for root sessions and legacy forks created before this field was persisted.

fork_id string (uuid) optional
Example: 11111111-2222-3333-4444-555555555555

Lineage: branch label assigned when this session was created by ForkSession (or rollback's internal fork). Omitted/empty for root sessions.

idle_timeout_seconds integer (int64) optional
Example: 60

This session's own idle-pause timeout (manifest idle_timeout). Omitted when the session uses the deployment-wide default.

keep_warm boolean optional
Example: false

Session is exempt from idle auto-pause (manifest keep_warm, or the agent-kind default: hermes sessions keep warm). Pause requests against such a session are rejected with 409. Omitted when false.

last_event_at string (date-time) optional
Example: 2026-08-01T12:00:00Z

Timestamp of the most recent event in this session's canonical stream. Drives the inactivity policy that pauses idle sessions.

name string optional
Example: demo-agent

User-assignable display name, unique per team among non-terminal sessions. Usable in place of session_id by clients (doctl / Console resolve it to the id via the ListSessions ?name= filter; the {session_id} path stays UUID-only). Supplied via the environment-spec metadata.name, or auto-generated ("session--") when omitted.

openai_environment_id string optional
Example: example

OpenAI Agents API environment id (env_…), captured from the resolved CODEX_ENVIRONMENT_ID guest env value. Populated only for AGENT_KIND_OPENAI_CODEX sessions. Non-secret correlation metadata.

openai_session_id string optional
Example: example

OpenAI Agents API session id (sess_…) this DO sandbox hosts. Populated only for AGENT_KIND_OPENAI_CODEX sessions (empty otherwise). Non-secret correlation metadata; a client (doctl agents attach) reads it to bridge to the OpenAI session. See docs/design/openai-sandbox-provider.md.

parent_session_id string optional
Example: example

Lineage: id of the session this one was forked from. Omitted/empty for root (non-fork) sessions.

pause_reason string optional
Example: example

Why this session is paused. Present only when status is SESSION_STATUS_PAUSED; omitted otherwise. Known values: manual (PauseSession RPC), idle (inactivity auto-pause), low_balance (prepay gate). Clients should treat an unrecognized value as an opaque reason string.

repo_hint string optional
Example: example

Optional repository hint supplied at session creation (first spec.workspace.repos entry of the manifest). Not authoritative; the agent may change repos in-session.

resume_on_topoff boolean optional
Example: false

Session consents to being resumed automatically when the team's prepayment balance is restored after a low-balance pause. Defaults to false at create time; may be toggled later via PATCH /v2/agents/sessions/{session_id} (resume_on_topoff only). Only a session paused with reason low_balance whose latest run did not complete is ever resumed automatically - a session the customer paused themselves, or one that idled out, stays paused regardless. Not an environment-spec field, and forks do not inherit it. Omitted when false.

sandbox_id string optional
Example: example

Sandbox identity for support / debugging. Informational; omitted until a sandbox is allocated.

session_id string optional
Example: a1b2c3d4-e5f6-7890-abcd-ef1234567890
status string (enum) optional
Example: SESSION_STATUS_UNSPECIFIED

SessionStatus is the lifecycle state of the sandbox + agent pair. SESSION_STATUS_ALL is a ListSessions status-filter value only -- no session is ever actually in this status. SESSION_STATUS_LOCKED is reserved for internal use and never appears in an end-user-facing response.

warnings array of string optional
Example: []

Non-fatal advisories computed from the manifest at create time: one entry per populated accepted-but-not-yet-enforced section (flat names: secrets, model, tools, memory, budget, max_lifetime, mounts; legacy manifests get the corresponding spec.* paths), a deprecation entry when a legacy-envelope manifest or an adapter alias (codex-cli, cursor-cli) is used, and a heuristic entry per credential-looking spec.env value. Populated on the CreateSession response only.

400

Malformed body, unknown field, or no recognized patchable properties.

ratelimit-limit integer

The default limit on number of requests that can be made per hour and per minute. Current rate limits are 5000 requests per hour and 250 requests per minute.

ratelimit-remaining integer

The number of requests in your hourly quota that remain before you hit your request limit. See https://docs.digitalocean.com/reference/api/reference/#rate-limit for information about how requests expire.

ratelimit-reset integer

The time when the oldest request will expire. The value is given in Unix epoch time. See https://docs.digitalocean.com/reference/api/reference/#rate-limit for information about how requests expire.

id string required
Example: not_found

A short identifier corresponding to the HTTP status code returned. For example, the ID for a response returning a 404 status code would be "not_found."

message string required
Example: The resource you were accessing could not be found.

A message providing additional information about the error, including details to help resolve it when possible.

request_id string optional
Example: 4d9d8375-3c56-4925-a3e7-eb137fed17e9

Optionally, some endpoints may include a request ID that should be provided when reporting bugs or opening support tickets to help identify the issue.

401

Authentication failed due to invalid credentials.

ratelimit-limit integer

The default limit on number of requests that can be made per hour and per minute. Current rate limits are 5000 requests per hour and 250 requests per minute.

ratelimit-remaining integer

The number of requests in your hourly quota that remain before you hit your request limit. See https://docs.digitalocean.com/reference/api/reference/#rate-limit for information about how requests expire.

ratelimit-reset integer

The time when the oldest request will expire. The value is given in Unix epoch time. See https://docs.digitalocean.com/reference/api/reference/#rate-limit for information about how requests expire.

id string required
Example: not_found

A short identifier corresponding to the HTTP status code returned. For example, the ID for a response returning a 404 status code would be "not_found."

message string required
Example: The resource you were accessing could not be found.

A message providing additional information about the error, including details to help resolve it when possible.

request_id string optional
Example: 4d9d8375-3c56-4925-a3e7-eb137fed17e9

Optionally, some endpoints may include a request ID that should be provided when reporting bugs or opening support tickets to help identify the issue.

403

Session belongs to another team.

ratelimit-limit integer

The default limit on number of requests that can be made per hour and per minute. Current rate limits are 5000 requests per hour and 250 requests per minute.

ratelimit-remaining integer

The number of requests in your hourly quota that remain before you hit your request limit. See https://docs.digitalocean.com/reference/api/reference/#rate-limit for information about how requests expire.

ratelimit-reset integer

The time when the oldest request will expire. The value is given in Unix epoch time. See https://docs.digitalocean.com/reference/api/reference/#rate-limit for information about how requests expire.

id string required
Example: not_found

A short identifier corresponding to the HTTP status code returned. For example, the ID for a response returning a 404 status code would be "not_found."

message string required
Example: The resource you were accessing could not be found.

A message providing additional information about the error, including details to help resolve it when possible.

request_id string optional
Example: 4d9d8375-3c56-4925-a3e7-eb137fed17e9

Optionally, some endpoints may include a request ID that should be provided when reporting bugs or opening support tickets to help identify the issue.

404

The resource was not found.

ratelimit-limit integer

The default limit on number of requests that can be made per hour and per minute. Current rate limits are 5000 requests per hour and 250 requests per minute.

ratelimit-remaining integer

The number of requests in your hourly quota that remain before you hit your request limit. See https://docs.digitalocean.com/reference/api/reference/#rate-limit for information about how requests expire.

ratelimit-reset integer

The time when the oldest request will expire. The value is given in Unix epoch time. See https://docs.digitalocean.com/reference/api/reference/#rate-limit for information about how requests expire.

id string required
Example: not_found

A short identifier corresponding to the HTTP status code returned. For example, the ID for a response returning a 404 status code would be "not_found."

message string required
Example: The resource you were accessing could not be found.

A message providing additional information about the error, including details to help resolve it when possible.

request_id string optional
Example: 4d9d8375-3c56-4925-a3e7-eb137fed17e9

Optionally, some endpoints may include a request ID that should be provided when reporting bugs or opening support tickets to help identify the issue.

409

Session is in a terminal state and cannot be updated.

ratelimit-limit integer

The default limit on number of requests that can be made per hour and per minute. Current rate limits are 5000 requests per hour and 250 requests per minute.

ratelimit-remaining integer

The number of requests in your hourly quota that remain before you hit your request limit. See https://docs.digitalocean.com/reference/api/reference/#rate-limit for information about how requests expire.

ratelimit-reset integer

The time when the oldest request will expire. The value is given in Unix epoch time. See https://docs.digitalocean.com/reference/api/reference/#rate-limit for information about how requests expire.

id string required
Example: not_found

A short identifier corresponding to the HTTP status code returned. For example, the ID for a response returning a 404 status code would be "not_found."

message string required
Example: The resource you were accessing could not be found.

A message providing additional information about the error, including details to help resolve it when possible.

request_id string optional
Example: 4d9d8375-3c56-4925-a3e7-eb137fed17e9

Optionally, some endpoints may include a request ID that should be provided when reporting bugs or opening support tickets to help identify the issue.

423

This session is unavailable; contact support.

ratelimit-limit integer

The default limit on number of requests that can be made per hour and per minute. Current rate limits are 5000 requests per hour and 250 requests per minute.

ratelimit-remaining integer

The number of requests in your hourly quota that remain before you hit your request limit. See https://docs.digitalocean.com/reference/api/reference/#rate-limit for information about how requests expire.

ratelimit-reset integer

The time when the oldest request will expire. The value is given in Unix epoch time. See https://docs.digitalocean.com/reference/api/reference/#rate-limit for information about how requests expire.

id string required
Example: not_found

A short identifier corresponding to the HTTP status code returned. For example, the ID for a response returning a 404 status code would be "not_found."

message string required
Example: The resource you were accessing could not be found.

A message providing additional information about the error, including details to help resolve it when possible.

request_id string optional
Example: 4d9d8375-3c56-4925-a3e7-eb137fed17e9

Optionally, some endpoints may include a request ID that should be provided when reporting bugs or opening support tickets to help identify the issue.

429

The API rate limit has been exceeded.

ratelimit-limit integer

The default limit on number of requests that can be made per hour and per minute. Current rate limits are 5000 requests per hour and 250 requests per minute.

ratelimit-remaining integer

The number of requests in your hourly quota that remain before you hit your request limit. See https://docs.digitalocean.com/reference/api/reference/#rate-limit for information about how requests expire.

ratelimit-reset integer

The time when the oldest request will expire. The value is given in Unix epoch time. See https://docs.digitalocean.com/reference/api/reference/#rate-limit for information about how requests expire.

id string required
Example: not_found

A short identifier corresponding to the HTTP status code returned. For example, the ID for a response returning a 404 status code would be "not_found."

message string required
Example: The resource you were accessing could not be found.

A message providing additional information about the error, including details to help resolve it when possible.

request_id string optional
Example: 4d9d8375-3c56-4925-a3e7-eb137fed17e9

Optionally, some endpoints may include a request ID that should be provided when reporting bugs or opening support tickets to help identify the issue.

500

There was a server error.

ratelimit-limit integer

The default limit on number of requests that can be made per hour and per minute. Current rate limits are 5000 requests per hour and 250 requests per minute.

ratelimit-remaining integer

The number of requests in your hourly quota that remain before you hit your request limit. See https://docs.digitalocean.com/reference/api/reference/#rate-limit for information about how requests expire.

ratelimit-reset integer

The time when the oldest request will expire. The value is given in Unix epoch time. See https://docs.digitalocean.com/reference/api/reference/#rate-limit for information about how requests expire.

id string required
Example: not_found

A short identifier corresponding to the HTTP status code returned. For example, the ID for a response returning a 404 status code would be "not_found."

message string required
Example: The resource you were accessing could not be found.

A message providing additional information about the error, including details to help resolve it when possible.

request_id string optional
Example: 4d9d8375-3c56-4925-a3e7-eb137fed17e9

Optionally, some endpoints may include a request ID that should be provided when reporting bugs or opening support tickets to help identify the issue.

default

There was an unexpected error.

ratelimit-limit integer

The default limit on number of requests that can be made per hour and per minute. Current rate limits are 5000 requests per hour and 250 requests per minute.

ratelimit-remaining integer

The number of requests in your hourly quota that remain before you hit your request limit. See https://docs.digitalocean.com/reference/api/reference/#rate-limit for information about how requests expire.

ratelimit-reset integer

The time when the oldest request will expire. The value is given in Unix epoch time. See https://docs.digitalocean.com/reference/api/reference/#rate-limit for information about how requests expire.

id string required
Example: not_found

A short identifier corresponding to the HTTP status code returned. For example, the ID for a response returning a 404 status code would be "not_found."

message string required
Example: The resource you were accessing could not be found.

A message providing additional information about the error, including details to help resolve it when possible.

request_id string optional
Example: 4d9d8375-3c56-4925-a3e7-eb137fed17e9

Optionally, some endpoints may include a request ID that should be provided when reporting bugs or opening support tickets to help identify the issue.

{
  "session": {
    "agent_kind": "AGENT_KIND_UNSPECIFIED",
    "config_id": "11111111-2222-3333-4444-555555555555",
    "created_at": "2026-08-01T12:00:00Z",
    "fork_from_checkpoint_id": "example",
    "fork_id": "11111111-2222-3333-4444-555555555555",
    "idle_timeout_seconds": 60,
    "keep_warm": false,
    "last_event_at": "2026-08-01T12:00:00Z",
    "name": "demo-agent",
    "openai_environment_id": "example",
    "openai_session_id": "example",
    "parent_session_id": "example",
    "pause_reason": "example",
    "repo_hint": "example",
    "resume_on_topoff": false,
    "sandbox_id": "example",
    "session_id": "a1b2c3d4-e5f6-7890-abcd-ef1234567890",
    "status": "SESSION_STATUS_UNSPECIFIED",
    "warnings": []
  }
}
{
  "id": "not_found",
  "message": "The resource you were accessing could not be found.",
  "request_id": "4d9d8375-3c56-4925-a3e7-eb137fed17e9"
}
{
  "id": "unauthorized",
  "message": "Unable to authenticate you."
}
{
  "id": "not_found",
  "message": "The resource you were accessing could not be found.",
  "request_id": "4d9d8375-3c56-4925-a3e7-eb137fed17e9"
}
{
  "id": "not_found",
  "message": "The resource you requested could not be found."
}
{
  "id": "not_found",
  "message": "The resource you were accessing could not be found.",
  "request_id": "4d9d8375-3c56-4925-a3e7-eb137fed17e9"
}
{
  "id": "not_found",
  "message": "The resource you were accessing could not be found.",
  "request_id": "4d9d8375-3c56-4925-a3e7-eb137fed17e9"
}
{
  "id": "too_many_requests",
  "message": "API rate limit exceeded."
}
{
  "id": "server_error",
  "message": "Unexpected server-side error"
}
{
  "id": "example_error",
  "message": "some error message"
}

DELETE DestroySession tears down the sandbox and marks the session DESTROYED.

/v2/agents/sessions/{session_id}
Authorizations: bearer_auth (1 scope)
Http: Bearer
Required scopes: agent_harness_session:manage

OAuth Authentication

In order to interact with the DigitalOcean API, you or your application must authenticate.

The DigitalOcean API handles this through OAuth, an open standard for authorization. OAuth allows you to delegate access to your account. Scopes can be used to grant full access, read-only access, or access to a specific set of endpoints.

You can generate an OAuth token by visiting the Apps & API section of the DigitalOcean control panel for your account.

An OAuth token functions as a complete authentication request. In effect, it acts as a substitute for a username and password pair.

Because of this, it is absolutely essential that you keep your OAuth tokens secure. In fact, upon generation, the web interface will only display each token a single time in order to prevent the token from being compromised.

DigitalOcean access tokens begin with an identifiable prefix in order to distinguish them from other similar tokens.

  • dop_v1_ for personal access tokens generated in the control panel
  • doo_v1_ for tokens generated by applications using the OAuth flow
  • dor_v1_ for OAuth refresh tokens

Scopes

Scopes act like permissions assigned to an API token. These permissions determine what actions the token can perform. You can create API tokens that grant read-only access, full access, or limited access to specific endpoints by using custom scopes.

Generally, scopes are designed to match HTTP verbs and common CRUD operations (Create, Read, Update, Delete).

HTTP Verb CRUD Operation Scope
GET Read <resource>:read
POST Create <resource>:create
PUT/PATCH Update <resource>:update
DELETE Delete <resource>:delete

For example, creating a new Droplet by making a POST request to the /v2/droplets endpoint requires the droplet:create scope while listing Droplets by making a GET request to the /v2/droplets endpoint requires the droplet:read scope.

Each endpoint below specifies which scope is required to access it when using custom scopes.

How to Authenticate with OAuth

In order to make an authenticated request, include a bearer-type Authorization header containing your OAuth token. All requests must be made over HTTPS.

Authenticate with a Bearer Authorization Header

curl -X $HTTP_METHOD -H "Authorization: Bearer $DIGITALOCEAN_TOKEN" "https://api.digitalocean.com/v2/$OBJECT"

Persistent workspace contents are retained per tenant policy. Returns 204 No Content on success.

Path Parameters

session_id string required
Example: a1b2c3d4-e5f6-7890-abcd-ef1234567890

The session UUID.

Header Parameters

X-Device-UUID string optional
Example: device-uuid-example

Optional hardware device id forwarded by doctl. Recorded on the session row as the device that performed the destroy.

curl -X DELETE \
  -H "Content-Type: application/json" \
  -H "Authorization: Bearer $DIGITALOCEAN_TOKEN" \
  "https://api.digitalocean.com/v2/agents/sessions/{session_id}"
curl -X DELETE \
  -H "Authorization: Bearer $API_TOKEN" \
  "https://api.digitalocean.com/v2/agents/sessions/{session_id}"

Responses

204

Session destroyed; no response body.

ratelimit-limit integer

The default limit on number of requests that can be made per hour and per minute. Current rate limits are 5000 requests per hour and 250 requests per minute.

ratelimit-remaining integer

The number of requests in your hourly quota that remain before you hit your request limit. See https://docs.digitalocean.com/reference/api/reference/#rate-limit for information about how requests expire.

ratelimit-reset integer

The time when the oldest request will expire. The value is given in Unix epoch time. See https://docs.digitalocean.com/reference/api/reference/#rate-limit for information about how requests expire.

401

Authentication failed due to invalid credentials.

ratelimit-limit integer

The default limit on number of requests that can be made per hour and per minute. Current rate limits are 5000 requests per hour and 250 requests per minute.

ratelimit-remaining integer

The number of requests in your hourly quota that remain before you hit your request limit. See https://docs.digitalocean.com/reference/api/reference/#rate-limit for information about how requests expire.

ratelimit-reset integer

The time when the oldest request will expire. The value is given in Unix epoch time. See https://docs.digitalocean.com/reference/api/reference/#rate-limit for information about how requests expire.

id string required
Example: not_found

A short identifier corresponding to the HTTP status code returned. For example, the ID for a response returning a 404 status code would be "not_found."

message string required
Example: The resource you were accessing could not be found.

A message providing additional information about the error, including details to help resolve it when possible.

request_id string optional
Example: 4d9d8375-3c56-4925-a3e7-eb137fed17e9

Optionally, some endpoints may include a request ID that should be provided when reporting bugs or opening support tickets to help identify the issue.

403

Session belongs to another team.

ratelimit-limit integer

The default limit on number of requests that can be made per hour and per minute. Current rate limits are 5000 requests per hour and 250 requests per minute.

ratelimit-remaining integer

The number of requests in your hourly quota that remain before you hit your request limit. See https://docs.digitalocean.com/reference/api/reference/#rate-limit for information about how requests expire.

ratelimit-reset integer

The time when the oldest request will expire. The value is given in Unix epoch time. See https://docs.digitalocean.com/reference/api/reference/#rate-limit for information about how requests expire.

id string required
Example: not_found

A short identifier corresponding to the HTTP status code returned. For example, the ID for a response returning a 404 status code would be "not_found."

message string required
Example: The resource you were accessing could not be found.

A message providing additional information about the error, including details to help resolve it when possible.

request_id string optional
Example: 4d9d8375-3c56-4925-a3e7-eb137fed17e9

Optionally, some endpoints may include a request ID that should be provided when reporting bugs or opening support tickets to help identify the issue.

404

The resource was not found.

ratelimit-limit integer

The default limit on number of requests that can be made per hour and per minute. Current rate limits are 5000 requests per hour and 250 requests per minute.

ratelimit-remaining integer

The number of requests in your hourly quota that remain before you hit your request limit. See https://docs.digitalocean.com/reference/api/reference/#rate-limit for information about how requests expire.

ratelimit-reset integer

The time when the oldest request will expire. The value is given in Unix epoch time. See https://docs.digitalocean.com/reference/api/reference/#rate-limit for information about how requests expire.

id string required
Example: not_found

A short identifier corresponding to the HTTP status code returned. For example, the ID for a response returning a 404 status code would be "not_found."

message string required
Example: The resource you were accessing could not be found.

A message providing additional information about the error, including details to help resolve it when possible.

request_id string optional
Example: 4d9d8375-3c56-4925-a3e7-eb137fed17e9

Optionally, some endpoints may include a request ID that should be provided when reporting bugs or opening support tickets to help identify the issue.

423

This session is unavailable; contact support.

ratelimit-limit integer

The default limit on number of requests that can be made per hour and per minute. Current rate limits are 5000 requests per hour and 250 requests per minute.

ratelimit-remaining integer

The number of requests in your hourly quota that remain before you hit your request limit. See https://docs.digitalocean.com/reference/api/reference/#rate-limit for information about how requests expire.

ratelimit-reset integer

The time when the oldest request will expire. The value is given in Unix epoch time. See https://docs.digitalocean.com/reference/api/reference/#rate-limit for information about how requests expire.

id string required
Example: not_found

A short identifier corresponding to the HTTP status code returned. For example, the ID for a response returning a 404 status code would be "not_found."

message string required
Example: The resource you were accessing could not be found.

A message providing additional information about the error, including details to help resolve it when possible.

request_id string optional
Example: 4d9d8375-3c56-4925-a3e7-eb137fed17e9

Optionally, some endpoints may include a request ID that should be provided when reporting bugs or opening support tickets to help identify the issue.

429

The API rate limit has been exceeded.

ratelimit-limit integer

The default limit on number of requests that can be made per hour and per minute. Current rate limits are 5000 requests per hour and 250 requests per minute.

ratelimit-remaining integer

The number of requests in your hourly quota that remain before you hit your request limit. See https://docs.digitalocean.com/reference/api/reference/#rate-limit for information about how requests expire.

ratelimit-reset integer

The time when the oldest request will expire. The value is given in Unix epoch time. See https://docs.digitalocean.com/reference/api/reference/#rate-limit for information about how requests expire.

id string required
Example: not_found

A short identifier corresponding to the HTTP status code returned. For example, the ID for a response returning a 404 status code would be "not_found."

message string required
Example: The resource you were accessing could not be found.

A message providing additional information about the error, including details to help resolve it when possible.

request_id string optional
Example: 4d9d8375-3c56-4925-a3e7-eb137fed17e9

Optionally, some endpoints may include a request ID that should be provided when reporting bugs or opening support tickets to help identify the issue.

500

There was a server error.

ratelimit-limit integer

The default limit on number of requests that can be made per hour and per minute. Current rate limits are 5000 requests per hour and 250 requests per minute.

ratelimit-remaining integer

The number of requests in your hourly quota that remain before you hit your request limit. See https://docs.digitalocean.com/reference/api/reference/#rate-limit for information about how requests expire.

ratelimit-reset integer

The time when the oldest request will expire. The value is given in Unix epoch time. See https://docs.digitalocean.com/reference/api/reference/#rate-limit for information about how requests expire.

id string required
Example: not_found

A short identifier corresponding to the HTTP status code returned. For example, the ID for a response returning a 404 status code would be "not_found."

message string required
Example: The resource you were accessing could not be found.

A message providing additional information about the error, including details to help resolve it when possible.

request_id string optional
Example: 4d9d8375-3c56-4925-a3e7-eb137fed17e9

Optionally, some endpoints may include a request ID that should be provided when reporting bugs or opening support tickets to help identify the issue.

default

There was an unexpected error.

ratelimit-limit integer

The default limit on number of requests that can be made per hour and per minute. Current rate limits are 5000 requests per hour and 250 requests per minute.

ratelimit-remaining integer

The number of requests in your hourly quota that remain before you hit your request limit. See https://docs.digitalocean.com/reference/api/reference/#rate-limit for information about how requests expire.

ratelimit-reset integer

The time when the oldest request will expire. The value is given in Unix epoch time. See https://docs.digitalocean.com/reference/api/reference/#rate-limit for information about how requests expire.

id string required
Example: not_found

A short identifier corresponding to the HTTP status code returned. For example, the ID for a response returning a 404 status code would be "not_found."

message string required
Example: The resource you were accessing could not be found.

A message providing additional information about the error, including details to help resolve it when possible.

request_id string optional
Example: 4d9d8375-3c56-4925-a3e7-eb137fed17e9

Optionally, some endpoints may include a request ID that should be provided when reporting bugs or opening support tickets to help identify the issue.

{
  "id": "unauthorized",
  "message": "Unable to authenticate you."
}
{
  "id": "not_found",
  "message": "The resource you were accessing could not be found.",
  "request_id": "4d9d8375-3c56-4925-a3e7-eb137fed17e9"
}
{
  "id": "not_found",
  "message": "The resource you requested could not be found."
}
{
  "id": "not_found",
  "message": "The resource you were accessing could not be found.",
  "request_id": "4d9d8375-3c56-4925-a3e7-eb137fed17e9"
}
{
  "id": "too_many_requests",
  "message": "API rate limit exceeded."
}
{
  "id": "server_error",
  "message": "Unexpected server-side error"
}
{
  "id": "example_error",
  "message": "some error message"
}

GET ListCheckpoints enumerates a session's checkpoints, newest first.

/v2/agents/sessions/{session_id}/checkpoints
Authorizations: bearer_auth (1 scope)
Http: Bearer
Required scopes: agent_harness_session:read

OAuth Authentication

In order to interact with the DigitalOcean API, you or your application must authenticate.

The DigitalOcean API handles this through OAuth, an open standard for authorization. OAuth allows you to delegate access to your account. Scopes can be used to grant full access, read-only access, or access to a specific set of endpoints.

You can generate an OAuth token by visiting the Apps & API section of the DigitalOcean control panel for your account.

An OAuth token functions as a complete authentication request. In effect, it acts as a substitute for a username and password pair.

Because of this, it is absolutely essential that you keep your OAuth tokens secure. In fact, upon generation, the web interface will only display each token a single time in order to prevent the token from being compromised.

DigitalOcean access tokens begin with an identifiable prefix in order to distinguish them from other similar tokens.

  • dop_v1_ for personal access tokens generated in the control panel
  • doo_v1_ for tokens generated by applications using the OAuth flow
  • dor_v1_ for OAuth refresh tokens

Scopes

Scopes act like permissions assigned to an API token. These permissions determine what actions the token can perform. You can create API tokens that grant read-only access, full access, or limited access to specific endpoints by using custom scopes.

Generally, scopes are designed to match HTTP verbs and common CRUD operations (Create, Read, Update, Delete).

HTTP Verb CRUD Operation Scope
GET Read <resource>:read
POST Create <resource>:create
PUT/PATCH Update <resource>:update
DELETE Delete <resource>:delete

For example, creating a new Droplet by making a POST request to the /v2/droplets endpoint requires the droplet:create scope while listing Droplets by making a GET request to the /v2/droplets endpoint requires the droplet:read scope.

Each endpoint below specifies which scope is required to access it when using custom scopes.

How to Authenticate with OAuth

In order to make an authenticated request, include a bearer-type Authorization header containing your OAuth token. All requests must be made over HTTPS.

Authenticate with a Bearer Authorization Header

curl -X $HTTP_METHOD -H "Authorization: Bearer $DIGITALOCEAN_TOKEN" "https://api.digitalocean.com/v2/$OBJECT"

Keyset-paginated on an opaque cursor, like ListSessions.

Path Parameters

session_id string required
Example: a1b2c3d4-e5f6-7890-abcd-ef1234567890

The session UUID.

Query Parameters

page_size integer (int32) optional
Example: 50

Page size. Defaults to 50 when omitted or non-positive.

page_token string optional

Opaque keyset cursor returned by the previous page. Empty starts from the beginning.

curl -X GET \
  -H "Authorization: Bearer $DIGITALOCEAN_TOKEN" \
  "https://api.digitalocean.com/v2/agents/sessions/{session_id}/checkpoints"
curl -X GET \
  -H "Authorization: Bearer $API_TOKEN" \
  "https://api.digitalocean.com/v2/agents/sessions/{session_id}/checkpoints"

Responses

200

A successful response.

ratelimit-limit integer

The default limit on number of requests that can be made per hour and per minute. Current rate limits are 5000 requests per hour and 250 requests per minute.

ratelimit-remaining integer

The number of requests in your hourly quota that remain before you hit your request limit. See https://docs.digitalocean.com/reference/api/reference/#rate-limit for information about how requests expire.

ratelimit-reset integer

The time when the oldest request will expire. The value is given in Unix epoch time. See https://docs.digitalocean.com/reference/api/reference/#rate-limit for information about how requests expire.

checkpoints array of object optional

Newest first.

Show child properties
checkpoint_id string optional
Example: cp_9f2c1a4b

Public checkpoint id, stable for the checkpoint's lifetime (e.g. cp_9f2c1a4b).

created_at string (date-time) optional
Example: 2026-08-01T12:00:00Z
error_message string optional
Example: capture timed out

Client-safe failure detail; set only when status is FAILED.

event_id string optional
Example: 01JABCDEFGHJKLMNPQRSTVWXYZ

Event-log cursor (ULID) of the last event included in the cut; forks resume event replay from here.

kind string, one of: explicit, implicit optional
Example: explicit

How the checkpoint came to exist: explicit - requested via CreateCheckpoint; implicit - minted automatically by the platform (on run completion, or when ForkSession is called without from_checkpoint_id).

label string optional
Example: before-refactor

Optional user-supplied label from CreateCheckpoint; empty when omitted.

session_id string optional
Example: a1b2c3d4-e5f6-7890-abcd-ef1234567890

Owning session.

size_bytes integer (int64) optional
Example: 1048576

Size of the captured machine state. 0 until the checkpoint reaches READY.

status string, one of: PENDING, READY, FAILED optional
Example: READY

Capture lifecycle: PENDING -> READY | FAILED. Only READY checkpoints are forkable/restorable. CreateCheckpoint blocks until terminal, so PENDING is only ever observable via list/get while a capture is in flight.

next_page_token string optional

Opaque cursor for the next page. Empty when there are no further pages.

400

Invalid page_token.

ratelimit-limit integer

The default limit on number of requests that can be made per hour and per minute. Current rate limits are 5000 requests per hour and 250 requests per minute.

ratelimit-remaining integer

The number of requests in your hourly quota that remain before you hit your request limit. See https://docs.digitalocean.com/reference/api/reference/#rate-limit for information about how requests expire.

ratelimit-reset integer

The time when the oldest request will expire. The value is given in Unix epoch time. See https://docs.digitalocean.com/reference/api/reference/#rate-limit for information about how requests expire.

id string required
Example: not_found

A short identifier corresponding to the HTTP status code returned. For example, the ID for a response returning a 404 status code would be "not_found."

message string required
Example: The resource you were accessing could not be found.

A message providing additional information about the error, including details to help resolve it when possible.

request_id string optional
Example: 4d9d8375-3c56-4925-a3e7-eb137fed17e9

Optionally, some endpoints may include a request ID that should be provided when reporting bugs or opening support tickets to help identify the issue.

401

Authentication failed due to invalid credentials.

ratelimit-limit integer

The default limit on number of requests that can be made per hour and per minute. Current rate limits are 5000 requests per hour and 250 requests per minute.

ratelimit-remaining integer

The number of requests in your hourly quota that remain before you hit your request limit. See https://docs.digitalocean.com/reference/api/reference/#rate-limit for information about how requests expire.

ratelimit-reset integer

The time when the oldest request will expire. The value is given in Unix epoch time. See https://docs.digitalocean.com/reference/api/reference/#rate-limit for information about how requests expire.

id string required
Example: not_found

A short identifier corresponding to the HTTP status code returned. For example, the ID for a response returning a 404 status code would be "not_found."

message string required
Example: The resource you were accessing could not be found.

A message providing additional information about the error, including details to help resolve it when possible.

request_id string optional
Example: 4d9d8375-3c56-4925-a3e7-eb137fed17e9

Optionally, some endpoints may include a request ID that should be provided when reporting bugs or opening support tickets to help identify the issue.

403

Session belongs to another team.

ratelimit-limit integer

The default limit on number of requests that can be made per hour and per minute. Current rate limits are 5000 requests per hour and 250 requests per minute.

ratelimit-remaining integer

The number of requests in your hourly quota that remain before you hit your request limit. See https://docs.digitalocean.com/reference/api/reference/#rate-limit for information about how requests expire.

ratelimit-reset integer

The time when the oldest request will expire. The value is given in Unix epoch time. See https://docs.digitalocean.com/reference/api/reference/#rate-limit for information about how requests expire.

id string required
Example: not_found

A short identifier corresponding to the HTTP status code returned. For example, the ID for a response returning a 404 status code would be "not_found."

message string required
Example: The resource you were accessing could not be found.

A message providing additional information about the error, including details to help resolve it when possible.

request_id string optional
Example: 4d9d8375-3c56-4925-a3e7-eb137fed17e9

Optionally, some endpoints may include a request ID that should be provided when reporting bugs or opening support tickets to help identify the issue.

404

The resource was not found.

ratelimit-limit integer

The default limit on number of requests that can be made per hour and per minute. Current rate limits are 5000 requests per hour and 250 requests per minute.

ratelimit-remaining integer

The number of requests in your hourly quota that remain before you hit your request limit. See https://docs.digitalocean.com/reference/api/reference/#rate-limit for information about how requests expire.

ratelimit-reset integer

The time when the oldest request will expire. The value is given in Unix epoch time. See https://docs.digitalocean.com/reference/api/reference/#rate-limit for information about how requests expire.

id string required
Example: not_found

A short identifier corresponding to the HTTP status code returned. For example, the ID for a response returning a 404 status code would be "not_found."

message string required
Example: The resource you were accessing could not be found.

A message providing additional information about the error, including details to help resolve it when possible.

request_id string optional
Example: 4d9d8375-3c56-4925-a3e7-eb137fed17e9

Optionally, some endpoints may include a request ID that should be provided when reporting bugs or opening support tickets to help identify the issue.

423

This session is unavailable; contact support.

ratelimit-limit integer

The default limit on number of requests that can be made per hour and per minute. Current rate limits are 5000 requests per hour and 250 requests per minute.

ratelimit-remaining integer

The number of requests in your hourly quota that remain before you hit your request limit. See https://docs.digitalocean.com/reference/api/reference/#rate-limit for information about how requests expire.

ratelimit-reset integer

The time when the oldest request will expire. The value is given in Unix epoch time. See https://docs.digitalocean.com/reference/api/reference/#rate-limit for information about how requests expire.

id string required
Example: not_found

A short identifier corresponding to the HTTP status code returned. For example, the ID for a response returning a 404 status code would be "not_found."

message string required
Example: The resource you were accessing could not be found.

A message providing additional information about the error, including details to help resolve it when possible.

request_id string optional
Example: 4d9d8375-3c56-4925-a3e7-eb137fed17e9

Optionally, some endpoints may include a request ID that should be provided when reporting bugs or opening support tickets to help identify the issue.

429

The API rate limit has been exceeded.

ratelimit-limit integer

The default limit on number of requests that can be made per hour and per minute. Current rate limits are 5000 requests per hour and 250 requests per minute.

ratelimit-remaining integer

The number of requests in your hourly quota that remain before you hit your request limit. See https://docs.digitalocean.com/reference/api/reference/#rate-limit for information about how requests expire.

ratelimit-reset integer

The time when the oldest request will expire. The value is given in Unix epoch time. See https://docs.digitalocean.com/reference/api/reference/#rate-limit for information about how requests expire.

id string required
Example: not_found

A short identifier corresponding to the HTTP status code returned. For example, the ID for a response returning a 404 status code would be "not_found."

message string required
Example: The resource you were accessing could not be found.

A message providing additional information about the error, including details to help resolve it when possible.

request_id string optional
Example: 4d9d8375-3c56-4925-a3e7-eb137fed17e9

Optionally, some endpoints may include a request ID that should be provided when reporting bugs or opening support tickets to help identify the issue.

500

There was a server error.

ratelimit-limit integer

The default limit on number of requests that can be made per hour and per minute. Current rate limits are 5000 requests per hour and 250 requests per minute.

ratelimit-remaining integer

The number of requests in your hourly quota that remain before you hit your request limit. See https://docs.digitalocean.com/reference/api/reference/#rate-limit for information about how requests expire.

ratelimit-reset integer

The time when the oldest request will expire. The value is given in Unix epoch time. See https://docs.digitalocean.com/reference/api/reference/#rate-limit for information about how requests expire.

id string required
Example: not_found

A short identifier corresponding to the HTTP status code returned. For example, the ID for a response returning a 404 status code would be "not_found."

message string required
Example: The resource you were accessing could not be found.

A message providing additional information about the error, including details to help resolve it when possible.

request_id string optional
Example: 4d9d8375-3c56-4925-a3e7-eb137fed17e9

Optionally, some endpoints may include a request ID that should be provided when reporting bugs or opening support tickets to help identify the issue.

default

There was an unexpected error.

ratelimit-limit integer

The default limit on number of requests that can be made per hour and per minute. Current rate limits are 5000 requests per hour and 250 requests per minute.

ratelimit-remaining integer

The number of requests in your hourly quota that remain before you hit your request limit. See https://docs.digitalocean.com/reference/api/reference/#rate-limit for information about how requests expire.

ratelimit-reset integer

The time when the oldest request will expire. The value is given in Unix epoch time. See https://docs.digitalocean.com/reference/api/reference/#rate-limit for information about how requests expire.

id string required
Example: not_found

A short identifier corresponding to the HTTP status code returned. For example, the ID for a response returning a 404 status code would be "not_found."

message string required
Example: The resource you were accessing could not be found.

A message providing additional information about the error, including details to help resolve it when possible.

request_id string optional
Example: 4d9d8375-3c56-4925-a3e7-eb137fed17e9

Optionally, some endpoints may include a request ID that should be provided when reporting bugs or opening support tickets to help identify the issue.

{
  "checkpoints": [
    {
      "checkpoint_id": "cp_9f2c1a4b",
      "created_at": "2026-08-01T12:00:00Z",
      "error_message": "capture timed out",
      "event_id": "01JABCDEFGHJKLMNPQRSTVWXYZ",
      "kind": "explicit",
      "label": "before-refactor",
      "session_id": "a1b2c3d4-e5f6-7890-abcd-ef1234567890",
      "size_bytes": 1048576,
      "status": "READY"
    }
  ],
  "next_page_token": "string"
}
{
  "id": "not_found",
  "message": "The resource you were accessing could not be found.",
  "request_id": "4d9d8375-3c56-4925-a3e7-eb137fed17e9"
}
{
  "id": "unauthorized",
  "message": "Unable to authenticate you."
}
{
  "id": "not_found",
  "message": "The resource you were accessing could not be found.",
  "request_id": "4d9d8375-3c56-4925-a3e7-eb137fed17e9"
}
{
  "id": "not_found",
  "message": "The resource you requested could not be found."
}
{
  "id": "not_found",
  "message": "The resource you were accessing could not be found.",
  "request_id": "4d9d8375-3c56-4925-a3e7-eb137fed17e9"
}
{
  "id": "too_many_requests",
  "message": "API rate limit exceeded."
}
{
  "id": "server_error",
  "message": "Unexpected server-side error"
}
{
  "id": "example_error",
  "message": "some error message"
}

POST CreateCheckpoint captures the session's live sandbox state as a durable checkpoint.

/v2/agents/sessions/{session_id}/checkpoints
Authorizations: bearer_auth (1 scope)
Http: Bearer
Required scopes: agent_harness_session:operate

OAuth Authentication

In order to interact with the DigitalOcean API, you or your application must authenticate.

The DigitalOcean API handles this through OAuth, an open standard for authorization. OAuth allows you to delegate access to your account. Scopes can be used to grant full access, read-only access, or access to a specific set of endpoints.

You can generate an OAuth token by visiting the Apps & API section of the DigitalOcean control panel for your account.

An OAuth token functions as a complete authentication request. In effect, it acts as a substitute for a username and password pair.

Because of this, it is absolutely essential that you keep your OAuth tokens secure. In fact, upon generation, the web interface will only display each token a single time in order to prevent the token from being compromised.

DigitalOcean access tokens begin with an identifiable prefix in order to distinguish them from other similar tokens.

  • dop_v1_ for personal access tokens generated in the control panel
  • doo_v1_ for tokens generated by applications using the OAuth flow
  • dor_v1_ for OAuth refresh tokens

Scopes

Scopes act like permissions assigned to an API token. These permissions determine what actions the token can perform. You can create API tokens that grant read-only access, full access, or limited access to specific endpoints by using custom scopes.

Generally, scopes are designed to match HTTP verbs and common CRUD operations (Create, Read, Update, Delete).

HTTP Verb CRUD Operation Scope
GET Read <resource>:read
POST Create <resource>:create
PUT/PATCH Update <resource>:update
DELETE Delete <resource>:delete

For example, creating a new Droplet by making a POST request to the /v2/droplets endpoint requires the droplet:create scope while listing Droplets by making a GET request to the /v2/droplets endpoint requires the droplet:read scope.

Each endpoint below specifies which scope is required to access it when using custom scopes.

How to Authenticate with OAuth

In order to make an authenticated request, include a bearer-type Authorization header containing your OAuth token. All requests must be made over HTTPS.

Authenticate with a Bearer Authorization Header

curl -X $HTTP_METHOD -H "Authorization: Bearer $DIGITALOCEAN_TOKEN" "https://api.digitalocean.com/v2/$OBJECT"

Synchronous: blocks until the capture reaches READY and returns the terminal Checkpoint — clients never see PENDING on this endpoint and need no poll loop. The checkpoint binds the machine-state capture to the event-log cursor at the cut, so it can later seed forks (POST .../fork) and rollback. Checkpoints are taken between turns; a session with an active turn in flight returns 409.

Path Parameters

session_id string required
Example: a1b2c3d4-e5f6-7890-abcd-ef1234567890

The session UUID.

Request Body: application/json

Optional; an empty or omitted body creates an unlabeled checkpoint.

label string optional

Optional human-readable label stored on the checkpoint; "" if omitted.

Content type application/json
{
  "label": "string"
}
curl -X POST \
  -H "Content-Type: application/json" \
  -H "Authorization: Bearer $DIGITALOCEAN_TOKEN" \
  -d '{"label":"before-refactor"}' \
  "https://api.digitalocean.com/v2/agents/sessions/{session_id}/checkpoints"
curl -X POST \
  -H "Authorization: Bearer $API_TOKEN" \
  -H "Content-Type: application/json" \
  -d '{
  "label": "string"
}' \
  "https://api.digitalocean.com/v2/agents/sessions/{session_id}/checkpoints"

Responses

200

Checkpoint captured. The returned checkpoint is terminal (status READY).

ratelimit-limit integer

The default limit on number of requests that can be made per hour and per minute. Current rate limits are 5000 requests per hour and 250 requests per minute.

ratelimit-remaining integer

The number of requests in your hourly quota that remain before you hit your request limit. See https://docs.digitalocean.com/reference/api/reference/#rate-limit for information about how requests expire.

ratelimit-reset integer

The time when the oldest request will expire. The value is given in Unix epoch time. See https://docs.digitalocean.com/reference/api/reference/#rate-limit for information about how requests expire.

checkpoint object optional

Checkpoint is a durable capture of a session's live sandbox machine state bound to the event-log cursor at the cut. READY checkpoints seed forks (ForkSession) and rollback. Internal fields (team_id, the substrate checkpoint id, event_seq) are never serialized.

Show child properties
checkpoint_id string optional
Example: cp_9f2c1a4b

Public checkpoint id, stable for the checkpoint's lifetime (e.g. cp_9f2c1a4b).

created_at string (date-time) optional
Example: 2026-08-01T12:00:00Z
error_message string optional
Example: capture timed out

Client-safe failure detail; set only when status is FAILED.

event_id string optional
Example: 01JABCDEFGHJKLMNPQRSTVWXYZ

Event-log cursor (ULID) of the last event included in the cut; forks resume event replay from here.

kind string, one of: explicit, implicit optional
Example: explicit

How the checkpoint came to exist: explicit - requested via CreateCheckpoint; implicit - minted automatically by the platform (on run completion, or when ForkSession is called without from_checkpoint_id).

label string optional
Example: before-refactor

Optional user-supplied label from CreateCheckpoint; empty when omitted.

session_id string optional
Example: a1b2c3d4-e5f6-7890-abcd-ef1234567890

Owning session.

size_bytes integer (int64) optional
Example: 1048576

Size of the captured machine state. 0 until the checkpoint reaches READY.

status string, one of: PENDING, READY, FAILED optional
Example: READY

Capture lifecycle: PENDING -> READY | FAILED. Only READY checkpoints are forkable/restorable. CreateCheckpoint blocks until terminal, so PENDING is only ever observable via list/get while a capture is in flight.

401

Authentication failed due to invalid credentials.

ratelimit-limit integer

The default limit on number of requests that can be made per hour and per minute. Current rate limits are 5000 requests per hour and 250 requests per minute.

ratelimit-remaining integer

The number of requests in your hourly quota that remain before you hit your request limit. See https://docs.digitalocean.com/reference/api/reference/#rate-limit for information about how requests expire.

ratelimit-reset integer

The time when the oldest request will expire. The value is given in Unix epoch time. See https://docs.digitalocean.com/reference/api/reference/#rate-limit for information about how requests expire.

id string required
Example: not_found

A short identifier corresponding to the HTTP status code returned. For example, the ID for a response returning a 404 status code would be "not_found."

message string required
Example: The resource you were accessing could not be found.

A message providing additional information about the error, including details to help resolve it when possible.

request_id string optional
Example: 4d9d8375-3c56-4925-a3e7-eb137fed17e9

Optionally, some endpoints may include a request ID that should be provided when reporting bugs or opening support tickets to help identify the issue.

402

The team is blocked by the prepayment gate.

ratelimit-limit integer

The default limit on number of requests that can be made per hour and per minute. Current rate limits are 5000 requests per hour and 250 requests per minute.

ratelimit-remaining integer

The number of requests in your hourly quota that remain before you hit your request limit. See https://docs.digitalocean.com/reference/api/reference/#rate-limit for information about how requests expire.

ratelimit-reset integer

The time when the oldest request will expire. The value is given in Unix epoch time. See https://docs.digitalocean.com/reference/api/reference/#rate-limit for information about how requests expire.

id string required
Example: not_found

A short identifier corresponding to the HTTP status code returned. For example, the ID for a response returning a 404 status code would be "not_found."

message string required
Example: The resource you were accessing could not be found.

A message providing additional information about the error, including details to help resolve it when possible.

request_id string optional
Example: 4d9d8375-3c56-4925-a3e7-eb137fed17e9

Optionally, some endpoints may include a request ID that should be provided when reporting bugs or opening support tickets to help identify the issue.

403

Session belongs to another team.

ratelimit-limit integer

The default limit on number of requests that can be made per hour and per minute. Current rate limits are 5000 requests per hour and 250 requests per minute.

ratelimit-remaining integer

The number of requests in your hourly quota that remain before you hit your request limit. See https://docs.digitalocean.com/reference/api/reference/#rate-limit for information about how requests expire.

ratelimit-reset integer

The time when the oldest request will expire. The value is given in Unix epoch time. See https://docs.digitalocean.com/reference/api/reference/#rate-limit for information about how requests expire.

id string required
Example: not_found

A short identifier corresponding to the HTTP status code returned. For example, the ID for a response returning a 404 status code would be "not_found."

message string required
Example: The resource you were accessing could not be found.

A message providing additional information about the error, including details to help resolve it when possible.

request_id string optional
Example: 4d9d8375-3c56-4925-a3e7-eb137fed17e9

Optionally, some endpoints may include a request ID that should be provided when reporting bugs or opening support tickets to help identify the issue.

404

The resource was not found.

ratelimit-limit integer

The default limit on number of requests that can be made per hour and per minute. Current rate limits are 5000 requests per hour and 250 requests per minute.

ratelimit-remaining integer

The number of requests in your hourly quota that remain before you hit your request limit. See https://docs.digitalocean.com/reference/api/reference/#rate-limit for information about how requests expire.

ratelimit-reset integer

The time when the oldest request will expire. The value is given in Unix epoch time. See https://docs.digitalocean.com/reference/api/reference/#rate-limit for information about how requests expire.

id string required
Example: not_found

A short identifier corresponding to the HTTP status code returned. For example, the ID for a response returning a 404 status code would be "not_found."

message string required
Example: The resource you were accessing could not be found.

A message providing additional information about the error, including details to help resolve it when possible.

request_id string optional
Example: 4d9d8375-3c56-4925-a3e7-eb137fed17e9

Optionally, some endpoints may include a request ID that should be provided when reporting bugs or opening support tickets to help identify the issue.

409

Session busy (an active turn is in flight), session not running, or team checkpoint storage quota exceeded.

ratelimit-limit integer

The default limit on number of requests that can be made per hour and per minute. Current rate limits are 5000 requests per hour and 250 requests per minute.

ratelimit-remaining integer

The number of requests in your hourly quota that remain before you hit your request limit. See https://docs.digitalocean.com/reference/api/reference/#rate-limit for information about how requests expire.

ratelimit-reset integer

The time when the oldest request will expire. The value is given in Unix epoch time. See https://docs.digitalocean.com/reference/api/reference/#rate-limit for information about how requests expire.

id string required
Example: not_found

A short identifier corresponding to the HTTP status code returned. For example, the ID for a response returning a 404 status code would be "not_found."

message string required
Example: The resource you were accessing could not be found.

A message providing additional information about the error, including details to help resolve it when possible.

request_id string optional
Example: 4d9d8375-3c56-4925-a3e7-eb137fed17e9

Optionally, some endpoints may include a request ID that should be provided when reporting bugs or opening support tickets to help identify the issue.

423

This session is unavailable; contact support.

ratelimit-limit integer

The default limit on number of requests that can be made per hour and per minute. Current rate limits are 5000 requests per hour and 250 requests per minute.

ratelimit-remaining integer

The number of requests in your hourly quota that remain before you hit your request limit. See https://docs.digitalocean.com/reference/api/reference/#rate-limit for information about how requests expire.

ratelimit-reset integer

The time when the oldest request will expire. The value is given in Unix epoch time. See https://docs.digitalocean.com/reference/api/reference/#rate-limit for information about how requests expire.

id string required
Example: not_found

A short identifier corresponding to the HTTP status code returned. For example, the ID for a response returning a 404 status code would be "not_found."

message string required
Example: The resource you were accessing could not be found.

A message providing additional information about the error, including details to help resolve it when possible.

request_id string optional
Example: 4d9d8375-3c56-4925-a3e7-eb137fed17e9

Optionally, some endpoints may include a request ID that should be provided when reporting bugs or opening support tickets to help identify the issue.

429

The API rate limit has been exceeded.

ratelimit-limit integer

The default limit on number of requests that can be made per hour and per minute. Current rate limits are 5000 requests per hour and 250 requests per minute.

ratelimit-remaining integer

The number of requests in your hourly quota that remain before you hit your request limit. See https://docs.digitalocean.com/reference/api/reference/#rate-limit for information about how requests expire.

ratelimit-reset integer

The time when the oldest request will expire. The value is given in Unix epoch time. See https://docs.digitalocean.com/reference/api/reference/#rate-limit for information about how requests expire.

id string required
Example: not_found

A short identifier corresponding to the HTTP status code returned. For example, the ID for a response returning a 404 status code would be "not_found."

message string required
Example: The resource you were accessing could not be found.

A message providing additional information about the error, including details to help resolve it when possible.

request_id string optional
Example: 4d9d8375-3c56-4925-a3e7-eb137fed17e9

Optionally, some endpoints may include a request ID that should be provided when reporting bugs or opening support tickets to help identify the issue.

500

There was a server error.

ratelimit-limit integer

The default limit on number of requests that can be made per hour and per minute. Current rate limits are 5000 requests per hour and 250 requests per minute.

ratelimit-remaining integer

The number of requests in your hourly quota that remain before you hit your request limit. See https://docs.digitalocean.com/reference/api/reference/#rate-limit for information about how requests expire.

ratelimit-reset integer

The time when the oldest request will expire. The value is given in Unix epoch time. See https://docs.digitalocean.com/reference/api/reference/#rate-limit for information about how requests expire.

id string required
Example: not_found

A short identifier corresponding to the HTTP status code returned. For example, the ID for a response returning a 404 status code would be "not_found."

message string required
Example: The resource you were accessing could not be found.

A message providing additional information about the error, including details to help resolve it when possible.

request_id string optional
Example: 4d9d8375-3c56-4925-a3e7-eb137fed17e9

Optionally, some endpoints may include a request ID that should be provided when reporting bugs or opening support tickets to help identify the issue.

501

Checkpoints are not supported for this agent/substrate.

ratelimit-limit integer

The default limit on number of requests that can be made per hour and per minute. Current rate limits are 5000 requests per hour and 250 requests per minute.

ratelimit-remaining integer

The number of requests in your hourly quota that remain before you hit your request limit. See https://docs.digitalocean.com/reference/api/reference/#rate-limit for information about how requests expire.

ratelimit-reset integer

The time when the oldest request will expire. The value is given in Unix epoch time. See https://docs.digitalocean.com/reference/api/reference/#rate-limit for information about how requests expire.

id string required
Example: not_found

A short identifier corresponding to the HTTP status code returned. For example, the ID for a response returning a 404 status code would be "not_found."

message string required
Example: The resource you were accessing could not be found.

A message providing additional information about the error, including details to help resolve it when possible.

request_id string optional
Example: 4d9d8375-3c56-4925-a3e7-eb137fed17e9

Optionally, some endpoints may include a request ID that should be provided when reporting bugs or opening support tickets to help identify the issue.

default

There was an unexpected error.

ratelimit-limit integer

The default limit on number of requests that can be made per hour and per minute. Current rate limits are 5000 requests per hour and 250 requests per minute.

ratelimit-remaining integer

The number of requests in your hourly quota that remain before you hit your request limit. See https://docs.digitalocean.com/reference/api/reference/#rate-limit for information about how requests expire.

ratelimit-reset integer

The time when the oldest request will expire. The value is given in Unix epoch time. See https://docs.digitalocean.com/reference/api/reference/#rate-limit for information about how requests expire.

id string required
Example: not_found

A short identifier corresponding to the HTTP status code returned. For example, the ID for a response returning a 404 status code would be "not_found."

message string required
Example: The resource you were accessing could not be found.

A message providing additional information about the error, including details to help resolve it when possible.

request_id string optional
Example: 4d9d8375-3c56-4925-a3e7-eb137fed17e9

Optionally, some endpoints may include a request ID that should be provided when reporting bugs or opening support tickets to help identify the issue.

{
  "checkpoint": {
    "checkpoint_id": "cp_9f2c1a4b",
    "created_at": "2026-08-01T12:00:00Z",
    "error_message": "capture timed out",
    "event_id": "01JABCDEFGHJKLMNPQRSTVWXYZ",
    "kind": "explicit",
    "label": "before-refactor",
    "session_id": "a1b2c3d4-e5f6-7890-abcd-ef1234567890",
    "size_bytes": 1048576,
    "status": "READY"
  }
}
{
  "id": "unauthorized",
  "message": "Unable to authenticate you."
}
{
  "id": "not_found",
  "message": "The resource you were accessing could not be found.",
  "request_id": "4d9d8375-3c56-4925-a3e7-eb137fed17e9"
}
{
  "id": "not_found",
  "message": "The resource you were accessing could not be found.",
  "request_id": "4d9d8375-3c56-4925-a3e7-eb137fed17e9"
}
{
  "id": "not_found",
  "message": "The resource you requested could not be found."
}
{
  "id": "not_found",
  "message": "The resource you were accessing could not be found.",
  "request_id": "4d9d8375-3c56-4925-a3e7-eb137fed17e9"
}
{
  "id": "not_found",
  "message": "The resource you were accessing could not be found.",
  "request_id": "4d9d8375-3c56-4925-a3e7-eb137fed17e9"
}
{
  "id": "too_many_requests",
  "message": "API rate limit exceeded."
}
{
  "id": "server_error",
  "message": "Unexpected server-side error"
}
{
  "id": "not_found",
  "message": "The resource you were accessing could not be found.",
  "request_id": "4d9d8375-3c56-4925-a3e7-eb137fed17e9"
}
{
  "id": "example_error",
  "message": "some error message"
}

GET GetCheckpoint returns the current snapshot of a checkpoint.

/v2/agents/sessions/{session_id}/checkpoints/{checkpoint_id}
Authorizations: bearer_auth (1 scope)
Http: Bearer
Required scopes: agent_harness_session:read

OAuth Authentication

In order to interact with the DigitalOcean API, you or your application must authenticate.

The DigitalOcean API handles this through OAuth, an open standard for authorization. OAuth allows you to delegate access to your account. Scopes can be used to grant full access, read-only access, or access to a specific set of endpoints.

You can generate an OAuth token by visiting the Apps & API section of the DigitalOcean control panel for your account.

An OAuth token functions as a complete authentication request. In effect, it acts as a substitute for a username and password pair.

Because of this, it is absolutely essential that you keep your OAuth tokens secure. In fact, upon generation, the web interface will only display each token a single time in order to prevent the token from being compromised.

DigitalOcean access tokens begin with an identifiable prefix in order to distinguish them from other similar tokens.

  • dop_v1_ for personal access tokens generated in the control panel
  • doo_v1_ for tokens generated by applications using the OAuth flow
  • dor_v1_ for OAuth refresh tokens

Scopes

Scopes act like permissions assigned to an API token. These permissions determine what actions the token can perform. You can create API tokens that grant read-only access, full access, or limited access to specific endpoints by using custom scopes.

Generally, scopes are designed to match HTTP verbs and common CRUD operations (Create, Read, Update, Delete).

HTTP Verb CRUD Operation Scope
GET Read <resource>:read
POST Create <resource>:create
PUT/PATCH Update <resource>:update
DELETE Delete <resource>:delete

For example, creating a new Droplet by making a POST request to the /v2/droplets endpoint requires the droplet:create scope while listing Droplets by making a GET request to the /v2/droplets endpoint requires the droplet:read scope.

Each endpoint below specifies which scope is required to access it when using custom scopes.

How to Authenticate with OAuth

In order to make an authenticated request, include a bearer-type Authorization header containing your OAuth token. All requests must be made over HTTPS.

Authenticate with a Bearer Authorization Header

curl -X $HTTP_METHOD -H "Authorization: Bearer $DIGITALOCEAN_TOKEN" "https://api.digitalocean.com/v2/$OBJECT"

GetCheckpoint returns the current snapshot of a checkpoint.

Path Parameters

session_id string required
Example: a1b2c3d4-e5f6-7890-abcd-ef1234567890

The session UUID.

checkpoint_id string required
Example: cp_9f2c1a4b

The checkpoint id.

curl -X GET \
  -H "Authorization: Bearer $DIGITALOCEAN_TOKEN" \
  "https://api.digitalocean.com/v2/agents/sessions/{session_id}/checkpoints/{checkpoint_id}"
curl -X GET \
  -H "Authorization: Bearer $API_TOKEN" \
  "https://api.digitalocean.com/v2/agents/sessions/{session_id}/checkpoints/{checkpoint_id}"

Responses

200

A successful response.

ratelimit-limit integer

The default limit on number of requests that can be made per hour and per minute. Current rate limits are 5000 requests per hour and 250 requests per minute.

ratelimit-remaining integer

The number of requests in your hourly quota that remain before you hit your request limit. See https://docs.digitalocean.com/reference/api/reference/#rate-limit for information about how requests expire.

ratelimit-reset integer

The time when the oldest request will expire. The value is given in Unix epoch time. See https://docs.digitalocean.com/reference/api/reference/#rate-limit for information about how requests expire.

checkpoint object optional

Checkpoint is a durable capture of a session's live sandbox machine state bound to the event-log cursor at the cut. READY checkpoints seed forks (ForkSession) and rollback. Internal fields (team_id, the substrate checkpoint id, event_seq) are never serialized.

Show child properties
checkpoint_id string optional
Example: cp_9f2c1a4b

Public checkpoint id, stable for the checkpoint's lifetime (e.g. cp_9f2c1a4b).

created_at string (date-time) optional
Example: 2026-08-01T12:00:00Z
error_message string optional
Example: capture timed out

Client-safe failure detail; set only when status is FAILED.

event_id string optional
Example: 01JABCDEFGHJKLMNPQRSTVWXYZ

Event-log cursor (ULID) of the last event included in the cut; forks resume event replay from here.

kind string, one of: explicit, implicit optional
Example: explicit

How the checkpoint came to exist: explicit - requested via CreateCheckpoint; implicit - minted automatically by the platform (on run completion, or when ForkSession is called without from_checkpoint_id).

label string optional
Example: before-refactor

Optional user-supplied label from CreateCheckpoint; empty when omitted.

session_id string optional
Example: a1b2c3d4-e5f6-7890-abcd-ef1234567890

Owning session.

size_bytes integer (int64) optional
Example: 1048576

Size of the captured machine state. 0 until the checkpoint reaches READY.

status string, one of: PENDING, READY, FAILED optional
Example: READY

Capture lifecycle: PENDING -> READY | FAILED. Only READY checkpoints are forkable/restorable. CreateCheckpoint blocks until terminal, so PENDING is only ever observable via list/get while a capture is in flight.

401

Authentication failed due to invalid credentials.

ratelimit-limit integer

The default limit on number of requests that can be made per hour and per minute. Current rate limits are 5000 requests per hour and 250 requests per minute.

ratelimit-remaining integer

The number of requests in your hourly quota that remain before you hit your request limit. See https://docs.digitalocean.com/reference/api/reference/#rate-limit for information about how requests expire.

ratelimit-reset integer

The time when the oldest request will expire. The value is given in Unix epoch time. See https://docs.digitalocean.com/reference/api/reference/#rate-limit for information about how requests expire.

id string required
Example: not_found

A short identifier corresponding to the HTTP status code returned. For example, the ID for a response returning a 404 status code would be "not_found."

message string required
Example: The resource you were accessing could not be found.

A message providing additional information about the error, including details to help resolve it when possible.

request_id string optional
Example: 4d9d8375-3c56-4925-a3e7-eb137fed17e9

Optionally, some endpoints may include a request ID that should be provided when reporting bugs or opening support tickets to help identify the issue.

403

Session belongs to another team.

ratelimit-limit integer

The default limit on number of requests that can be made per hour and per minute. Current rate limits are 5000 requests per hour and 250 requests per minute.

ratelimit-remaining integer

The number of requests in your hourly quota that remain before you hit your request limit. See https://docs.digitalocean.com/reference/api/reference/#rate-limit for information about how requests expire.

ratelimit-reset integer

The time when the oldest request will expire. The value is given in Unix epoch time. See https://docs.digitalocean.com/reference/api/reference/#rate-limit for information about how requests expire.

id string required
Example: not_found

A short identifier corresponding to the HTTP status code returned. For example, the ID for a response returning a 404 status code would be "not_found."

message string required
Example: The resource you were accessing could not be found.

A message providing additional information about the error, including details to help resolve it when possible.

request_id string optional
Example: 4d9d8375-3c56-4925-a3e7-eb137fed17e9

Optionally, some endpoints may include a request ID that should be provided when reporting bugs or opening support tickets to help identify the issue.

404

The resource was not found.

ratelimit-limit integer

The default limit on number of requests that can be made per hour and per minute. Current rate limits are 5000 requests per hour and 250 requests per minute.

ratelimit-remaining integer

The number of requests in your hourly quota that remain before you hit your request limit. See https://docs.digitalocean.com/reference/api/reference/#rate-limit for information about how requests expire.

ratelimit-reset integer

The time when the oldest request will expire. The value is given in Unix epoch time. See https://docs.digitalocean.com/reference/api/reference/#rate-limit for information about how requests expire.

id string required
Example: not_found

A short identifier corresponding to the HTTP status code returned. For example, the ID for a response returning a 404 status code would be "not_found."

message string required
Example: The resource you were accessing could not be found.

A message providing additional information about the error, including details to help resolve it when possible.

request_id string optional
Example: 4d9d8375-3c56-4925-a3e7-eb137fed17e9

Optionally, some endpoints may include a request ID that should be provided when reporting bugs or opening support tickets to help identify the issue.

423

This session is unavailable; contact support.

ratelimit-limit integer

The default limit on number of requests that can be made per hour and per minute. Current rate limits are 5000 requests per hour and 250 requests per minute.

ratelimit-remaining integer

The number of requests in your hourly quota that remain before you hit your request limit. See https://docs.digitalocean.com/reference/api/reference/#rate-limit for information about how requests expire.

ratelimit-reset integer

The time when the oldest request will expire. The value is given in Unix epoch time. See https://docs.digitalocean.com/reference/api/reference/#rate-limit for information about how requests expire.

id string required
Example: not_found

A short identifier corresponding to the HTTP status code returned. For example, the ID for a response returning a 404 status code would be "not_found."

message string required
Example: The resource you were accessing could not be found.

A message providing additional information about the error, including details to help resolve it when possible.

request_id string optional
Example: 4d9d8375-3c56-4925-a3e7-eb137fed17e9

Optionally, some endpoints may include a request ID that should be provided when reporting bugs or opening support tickets to help identify the issue.

429

The API rate limit has been exceeded.

ratelimit-limit integer

The default limit on number of requests that can be made per hour and per minute. Current rate limits are 5000 requests per hour and 250 requests per minute.

ratelimit-remaining integer

The number of requests in your hourly quota that remain before you hit your request limit. See https://docs.digitalocean.com/reference/api/reference/#rate-limit for information about how requests expire.

ratelimit-reset integer

The time when the oldest request will expire. The value is given in Unix epoch time. See https://docs.digitalocean.com/reference/api/reference/#rate-limit for information about how requests expire.

id string required
Example: not_found

A short identifier corresponding to the HTTP status code returned. For example, the ID for a response returning a 404 status code would be "not_found."

message string required
Example: The resource you were accessing could not be found.

A message providing additional information about the error, including details to help resolve it when possible.

request_id string optional
Example: 4d9d8375-3c56-4925-a3e7-eb137fed17e9

Optionally, some endpoints may include a request ID that should be provided when reporting bugs or opening support tickets to help identify the issue.

500

There was a server error.

ratelimit-limit integer

The default limit on number of requests that can be made per hour and per minute. Current rate limits are 5000 requests per hour and 250 requests per minute.

ratelimit-remaining integer

The number of requests in your hourly quota that remain before you hit your request limit. See https://docs.digitalocean.com/reference/api/reference/#rate-limit for information about how requests expire.

ratelimit-reset integer

The time when the oldest request will expire. The value is given in Unix epoch time. See https://docs.digitalocean.com/reference/api/reference/#rate-limit for information about how requests expire.

id string required
Example: not_found

A short identifier corresponding to the HTTP status code returned. For example, the ID for a response returning a 404 status code would be "not_found."

message string required
Example: The resource you were accessing could not be found.

A message providing additional information about the error, including details to help resolve it when possible.

request_id string optional
Example: 4d9d8375-3c56-4925-a3e7-eb137fed17e9

Optionally, some endpoints may include a request ID that should be provided when reporting bugs or opening support tickets to help identify the issue.

default

There was an unexpected error.

ratelimit-limit integer

The default limit on number of requests that can be made per hour and per minute. Current rate limits are 5000 requests per hour and 250 requests per minute.

ratelimit-remaining integer

The number of requests in your hourly quota that remain before you hit your request limit. See https://docs.digitalocean.com/reference/api/reference/#rate-limit for information about how requests expire.

ratelimit-reset integer

The time when the oldest request will expire. The value is given in Unix epoch time. See https://docs.digitalocean.com/reference/api/reference/#rate-limit for information about how requests expire.

id string required
Example: not_found

A short identifier corresponding to the HTTP status code returned. For example, the ID for a response returning a 404 status code would be "not_found."

message string required
Example: The resource you were accessing could not be found.

A message providing additional information about the error, including details to help resolve it when possible.

request_id string optional
Example: 4d9d8375-3c56-4925-a3e7-eb137fed17e9

Optionally, some endpoints may include a request ID that should be provided when reporting bugs or opening support tickets to help identify the issue.

{
  "checkpoint": {
    "checkpoint_id": "cp_9f2c1a4b",
    "created_at": "2026-08-01T12:00:00Z",
    "error_message": "capture timed out",
    "event_id": "01JABCDEFGHJKLMNPQRSTVWXYZ",
    "kind": "explicit",
    "label": "before-refactor",
    "session_id": "a1b2c3d4-e5f6-7890-abcd-ef1234567890",
    "size_bytes": 1048576,
    "status": "READY"
  }
}
{
  "id": "unauthorized",
  "message": "Unable to authenticate you."
}
{
  "id": "not_found",
  "message": "The resource you were accessing could not be found.",
  "request_id": "4d9d8375-3c56-4925-a3e7-eb137fed17e9"
}
{
  "id": "not_found",
  "message": "The resource you requested could not be found."
}
{
  "id": "not_found",
  "message": "The resource you were accessing could not be found.",
  "request_id": "4d9d8375-3c56-4925-a3e7-eb137fed17e9"
}
{
  "id": "too_many_requests",
  "message": "API rate limit exceeded."
}
{
  "id": "server_error",
  "message": "Unexpected server-side error"
}
{
  "id": "example_error",
  "message": "some error message"
}

DELETE DeleteCheckpoint removes a checkpoint and its underlying machine-state capture.

/v2/agents/sessions/{session_id}/checkpoints/{checkpoint_id}
Authorizations: bearer_auth (1 scope)
Http: Bearer
Required scopes: agent_harness_session:operate

OAuth Authentication

In order to interact with the DigitalOcean API, you or your application must authenticate.

The DigitalOcean API handles this through OAuth, an open standard for authorization. OAuth allows you to delegate access to your account. Scopes can be used to grant full access, read-only access, or access to a specific set of endpoints.

You can generate an OAuth token by visiting the Apps & API section of the DigitalOcean control panel for your account.

An OAuth token functions as a complete authentication request. In effect, it acts as a substitute for a username and password pair.

Because of this, it is absolutely essential that you keep your OAuth tokens secure. In fact, upon generation, the web interface will only display each token a single time in order to prevent the token from being compromised.

DigitalOcean access tokens begin with an identifiable prefix in order to distinguish them from other similar tokens.

  • dop_v1_ for personal access tokens generated in the control panel
  • doo_v1_ for tokens generated by applications using the OAuth flow
  • dor_v1_ for OAuth refresh tokens

Scopes

Scopes act like permissions assigned to an API token. These permissions determine what actions the token can perform. You can create API tokens that grant read-only access, full access, or limited access to specific endpoints by using custom scopes.

Generally, scopes are designed to match HTTP verbs and common CRUD operations (Create, Read, Update, Delete).

HTTP Verb CRUD Operation Scope
GET Read <resource>:read
POST Create <resource>:create
PUT/PATCH Update <resource>:update
DELETE Delete <resource>:delete

For example, creating a new Droplet by making a POST request to the /v2/droplets endpoint requires the droplet:create scope while listing Droplets by making a GET request to the /v2/droplets endpoint requires the droplet:read scope.

Each endpoint below specifies which scope is required to access it when using custom scopes.

How to Authenticate with OAuth

In order to make an authenticated request, include a bearer-type Authorization header containing your OAuth token. All requests must be made over HTTPS.

Authenticate with a Bearer Authorization Header

curl -X $HTTP_METHOD -H "Authorization: Bearer $DIGITALOCEAN_TOKEN" "https://api.digitalocean.com/v2/$OBJECT"

Idempotent: deleting an already-gone checkpoint still returns 200. Removes the DB row and the substrate checkpoint.

Path Parameters

session_id string required
Example: a1b2c3d4-e5f6-7890-abcd-ef1234567890

The session UUID.

checkpoint_id string required
Example: cp_9f2c1a4b

The checkpoint id.

curl -X DELETE \
  -H "Authorization: Bearer $DIGITALOCEAN_TOKEN" \
  "https://api.digitalocean.com/v2/agents/sessions/{session_id}/checkpoints/{checkpoint_id}"
curl -X DELETE \
  -H "Authorization: Bearer $API_TOKEN" \
  "https://api.digitalocean.com/v2/agents/sessions/{session_id}/checkpoints/{checkpoint_id}"

Responses

200

Checkpoint deleted.

ratelimit-limit integer

The default limit on number of requests that can be made per hour and per minute. Current rate limits are 5000 requests per hour and 250 requests per minute.

ratelimit-remaining integer

The number of requests in your hourly quota that remain before you hit your request limit. See https://docs.digitalocean.com/reference/api/reference/#rate-limit for information about how requests expire.

ratelimit-reset integer

The time when the oldest request will expire. The value is given in Unix epoch time. See https://docs.digitalocean.com/reference/api/reference/#rate-limit for information about how requests expire.

checkpoint_id string optional

Echo of the requested checkpoint id.

deleted boolean optional

Always true on 200 (delete is idempotent).

401

Authentication failed due to invalid credentials.

ratelimit-limit integer

The default limit on number of requests that can be made per hour and per minute. Current rate limits are 5000 requests per hour and 250 requests per minute.

ratelimit-remaining integer

The number of requests in your hourly quota that remain before you hit your request limit. See https://docs.digitalocean.com/reference/api/reference/#rate-limit for information about how requests expire.

ratelimit-reset integer

The time when the oldest request will expire. The value is given in Unix epoch time. See https://docs.digitalocean.com/reference/api/reference/#rate-limit for information about how requests expire.

id string required
Example: not_found

A short identifier corresponding to the HTTP status code returned. For example, the ID for a response returning a 404 status code would be "not_found."

message string required
Example: The resource you were accessing could not be found.

A message providing additional information about the error, including details to help resolve it when possible.

request_id string optional
Example: 4d9d8375-3c56-4925-a3e7-eb137fed17e9

Optionally, some endpoints may include a request ID that should be provided when reporting bugs or opening support tickets to help identify the issue.

403

Session belongs to another team.

ratelimit-limit integer

The default limit on number of requests that can be made per hour and per minute. Current rate limits are 5000 requests per hour and 250 requests per minute.

ratelimit-remaining integer

The number of requests in your hourly quota that remain before you hit your request limit. See https://docs.digitalocean.com/reference/api/reference/#rate-limit for information about how requests expire.

ratelimit-reset integer

The time when the oldest request will expire. The value is given in Unix epoch time. See https://docs.digitalocean.com/reference/api/reference/#rate-limit for information about how requests expire.

id string required
Example: not_found

A short identifier corresponding to the HTTP status code returned. For example, the ID for a response returning a 404 status code would be "not_found."

message string required
Example: The resource you were accessing could not be found.

A message providing additional information about the error, including details to help resolve it when possible.

request_id string optional
Example: 4d9d8375-3c56-4925-a3e7-eb137fed17e9

Optionally, some endpoints may include a request ID that should be provided when reporting bugs or opening support tickets to help identify the issue.

404

The resource was not found.

ratelimit-limit integer

The default limit on number of requests that can be made per hour and per minute. Current rate limits are 5000 requests per hour and 250 requests per minute.

ratelimit-remaining integer

The number of requests in your hourly quota that remain before you hit your request limit. See https://docs.digitalocean.com/reference/api/reference/#rate-limit for information about how requests expire.

ratelimit-reset integer

The time when the oldest request will expire. The value is given in Unix epoch time. See https://docs.digitalocean.com/reference/api/reference/#rate-limit for information about how requests expire.

id string required
Example: not_found

A short identifier corresponding to the HTTP status code returned. For example, the ID for a response returning a 404 status code would be "not_found."

message string required
Example: The resource you were accessing could not be found.

A message providing additional information about the error, including details to help resolve it when possible.

request_id string optional
Example: 4d9d8375-3c56-4925-a3e7-eb137fed17e9

Optionally, some endpoints may include a request ID that should be provided when reporting bugs or opening support tickets to help identify the issue.

423

This session is unavailable; contact support.

ratelimit-limit integer

The default limit on number of requests that can be made per hour and per minute. Current rate limits are 5000 requests per hour and 250 requests per minute.

ratelimit-remaining integer

The number of requests in your hourly quota that remain before you hit your request limit. See https://docs.digitalocean.com/reference/api/reference/#rate-limit for information about how requests expire.

ratelimit-reset integer

The time when the oldest request will expire. The value is given in Unix epoch time. See https://docs.digitalocean.com/reference/api/reference/#rate-limit for information about how requests expire.

id string required
Example: not_found

A short identifier corresponding to the HTTP status code returned. For example, the ID for a response returning a 404 status code would be "not_found."

message string required
Example: The resource you were accessing could not be found.

A message providing additional information about the error, including details to help resolve it when possible.

request_id string optional
Example: 4d9d8375-3c56-4925-a3e7-eb137fed17e9

Optionally, some endpoints may include a request ID that should be provided when reporting bugs or opening support tickets to help identify the issue.

429

The API rate limit has been exceeded.

ratelimit-limit integer

The default limit on number of requests that can be made per hour and per minute. Current rate limits are 5000 requests per hour and 250 requests per minute.

ratelimit-remaining integer

The number of requests in your hourly quota that remain before you hit your request limit. See https://docs.digitalocean.com/reference/api/reference/#rate-limit for information about how requests expire.

ratelimit-reset integer

The time when the oldest request will expire. The value is given in Unix epoch time. See https://docs.digitalocean.com/reference/api/reference/#rate-limit for information about how requests expire.

id string required
Example: not_found

A short identifier corresponding to the HTTP status code returned. For example, the ID for a response returning a 404 status code would be "not_found."

message string required
Example: The resource you were accessing could not be found.

A message providing additional information about the error, including details to help resolve it when possible.

request_id string optional
Example: 4d9d8375-3c56-4925-a3e7-eb137fed17e9

Optionally, some endpoints may include a request ID that should be provided when reporting bugs or opening support tickets to help identify the issue.

500

There was a server error.

ratelimit-limit integer

The default limit on number of requests that can be made per hour and per minute. Current rate limits are 5000 requests per hour and 250 requests per minute.

ratelimit-remaining integer

The number of requests in your hourly quota that remain before you hit your request limit. See https://docs.digitalocean.com/reference/api/reference/#rate-limit for information about how requests expire.

ratelimit-reset integer

The time when the oldest request will expire. The value is given in Unix epoch time. See https://docs.digitalocean.com/reference/api/reference/#rate-limit for information about how requests expire.

id string required
Example: not_found

A short identifier corresponding to the HTTP status code returned. For example, the ID for a response returning a 404 status code would be "not_found."

message string required
Example: The resource you were accessing could not be found.

A message providing additional information about the error, including details to help resolve it when possible.

request_id string optional
Example: 4d9d8375-3c56-4925-a3e7-eb137fed17e9

Optionally, some endpoints may include a request ID that should be provided when reporting bugs or opening support tickets to help identify the issue.

default

There was an unexpected error.

ratelimit-limit integer

The default limit on number of requests that can be made per hour and per minute. Current rate limits are 5000 requests per hour and 250 requests per minute.

ratelimit-remaining integer

The number of requests in your hourly quota that remain before you hit your request limit. See https://docs.digitalocean.com/reference/api/reference/#rate-limit for information about how requests expire.

ratelimit-reset integer

The time when the oldest request will expire. The value is given in Unix epoch time. See https://docs.digitalocean.com/reference/api/reference/#rate-limit for information about how requests expire.

id string required
Example: not_found

A short identifier corresponding to the HTTP status code returned. For example, the ID for a response returning a 404 status code would be "not_found."

message string required
Example: The resource you were accessing could not be found.

A message providing additional information about the error, including details to help resolve it when possible.

request_id string optional
Example: 4d9d8375-3c56-4925-a3e7-eb137fed17e9

Optionally, some endpoints may include a request ID that should be provided when reporting bugs or opening support tickets to help identify the issue.

{
  "checkpoint_id": "string",
  "deleted": true
}
{
  "id": "unauthorized",
  "message": "Unable to authenticate you."
}
{
  "id": "not_found",
  "message": "The resource you were accessing could not be found.",
  "request_id": "4d9d8375-3c56-4925-a3e7-eb137fed17e9"
}
{
  "id": "not_found",
  "message": "The resource you requested could not be found."
}
{
  "id": "not_found",
  "message": "The resource you were accessing could not be found.",
  "request_id": "4d9d8375-3c56-4925-a3e7-eb137fed17e9"
}
{
  "id": "too_many_requests",
  "message": "API rate limit exceeded."
}
{
  "id": "server_error",
  "message": "Unexpected server-side error"
}
{
  "id": "example_error",
  "message": "some error message"
}

POST RollbackToCheckpoint rewinds a session to a checkpoint.

/v2/agents/sessions/{session_id}/checkpoints/{checkpoint_id}/rollback
Authorizations: bearer_auth (1 scope)
Http: Bearer
Required scopes: agent_harness_session:operate

OAuth Authentication

In order to interact with the DigitalOcean API, you or your application must authenticate.

The DigitalOcean API handles this through OAuth, an open standard for authorization. OAuth allows you to delegate access to your account. Scopes can be used to grant full access, read-only access, or access to a specific set of endpoints.

You can generate an OAuth token by visiting the Apps & API section of the DigitalOcean control panel for your account.

An OAuth token functions as a complete authentication request. In effect, it acts as a substitute for a username and password pair.

Because of this, it is absolutely essential that you keep your OAuth tokens secure. In fact, upon generation, the web interface will only display each token a single time in order to prevent the token from being compromised.

DigitalOcean access tokens begin with an identifiable prefix in order to distinguish them from other similar tokens.

  • dop_v1_ for personal access tokens generated in the control panel
  • doo_v1_ for tokens generated by applications using the OAuth flow
  • dor_v1_ for OAuth refresh tokens

Scopes

Scopes act like permissions assigned to an API token. These permissions determine what actions the token can perform. You can create API tokens that grant read-only access, full access, or limited access to specific endpoints by using custom scopes.

Generally, scopes are designed to match HTTP verbs and common CRUD operations (Create, Read, Update, Delete).

HTTP Verb CRUD Operation Scope
GET Read <resource>:read
POST Create <resource>:create
PUT/PATCH Update <resource>:update
DELETE Delete <resource>:delete

For example, creating a new Droplet by making a POST request to the /v2/droplets endpoint requires the droplet:create scope while listing Droplets by making a GET request to the /v2/droplets endpoint requires the droplet:read scope.

Each endpoint below specifies which scope is required to access it when using custom scopes.

How to Authenticate with OAuth

In order to make an authenticated request, include a bearer-type Authorization header containing your OAuth token. All requests must be made over HTTPS.

Authenticate with a Bearer Authorization Header

curl -X $HTTP_METHOD -H "Authorization: Bearer $DIGITALOCEAN_TOKEN" "https://api.digitalocean.com/v2/$OBJECT"

In-place restore: boots a fresh sandbox from the checkpoint and atomically swaps the session's sandbox pointer to it, so the session keeps its same session_id; the old sandbox is then torn down.

Path Parameters

session_id string required
Example: a1b2c3d4-e5f6-7890-abcd-ef1234567890

The session UUID.

checkpoint_id string required
Example: cp_9f2c1a4b

The checkpoint id.

curl -X POST \
  -H "Content-Type: application/json" \
  -H "Authorization: Bearer $DIGITALOCEAN_TOKEN" \
  "https://api.digitalocean.com/v2/agents/sessions/{session_id}/checkpoints/{checkpoint_id}/rollback"
curl -X POST \
  -H "Authorization: Bearer $API_TOKEN" \
  -H "Content-Type: application/json" \
  "https://api.digitalocean.com/v2/agents/sessions/{session_id}/checkpoints/{checkpoint_id}/rollback"

Responses

200

The session after in-place rollback: same session_id, sandbox_id swapped to the restored VM.

ratelimit-limit integer

The default limit on number of requests that can be made per hour and per minute. Current rate limits are 5000 requests per hour and 250 requests per minute.

ratelimit-remaining integer

The number of requests in your hourly quota that remain before you hit your request limit. See https://docs.digitalocean.com/reference/api/reference/#rate-limit for information about how requests expire.

ratelimit-reset integer

The time when the oldest request will expire. The value is given in Unix epoch time. See https://docs.digitalocean.com/reference/api/reference/#rate-limit for information about how requests expire.

session object optional

Session is the user-facing record of a environment session + sandbox pair.

Show child properties
agent_kind string (enum) optional
Example: AGENT_KIND_UNSPECIFIED

AgentKind identifies what runs inside the session sandbox. CreateSession accepts CLAUDE_CODE, OPENCODE, CODEX_CLI, CURSOR_CLI, OPENAI_CODEX, LANGGRAPH, and CREWAI (the supported set is overridable via HARNESS_SUPPORTED_AGENT_KINDS); other values are rejected with 400. AGENT_KIND_OPENAI_CODEX is the OpenAI sandbox-provider kind (DO runs codex exec-server; the agent loop lives at OpenAI). AGENT_KIND_LANGGRAPH is the LangGraph framework adapter. AGENT_KIND_CREWAI is the CrewAI Crew framework adapter: like LANGGRAPH the template bakes no agent code, so spec.env must supply FRAMEWORK_REPO and FRAMEWORK_REPO_SHA; a Crew kickoff is one-shot and exposes no HITL surface. CREWAI is additionally gated per team and returns 400 for teams it is not enabled for.

config_id string (uuid) optional
Example: 11111111-2222-3333-4444-555555555555

Durable Environment Config UUID the session was created from (inline manifests persist a config too, named after the session). Persisted and returned on create/get/list; absent only for sessions created before config references were stored.

created_at string (date-time) optional
Example: 2026-08-01T12:00:00Z
fork_from_checkpoint_id string optional
Example: example

Lineage: harness-api checkpoint id (cp_) the child booted from at fork time. Drives OHP inherited-history replay on attach. Omitted/empty for root sessions and legacy forks created before this field was persisted.

fork_id string (uuid) optional
Example: 11111111-2222-3333-4444-555555555555

Lineage: branch label assigned when this session was created by ForkSession (or rollback's internal fork). Omitted/empty for root sessions.

idle_timeout_seconds integer (int64) optional
Example: 60

This session's own idle-pause timeout (manifest idle_timeout). Omitted when the session uses the deployment-wide default.

keep_warm boolean optional
Example: false

Session is exempt from idle auto-pause (manifest keep_warm, or the agent-kind default: hermes sessions keep warm). Pause requests against such a session are rejected with 409. Omitted when false.

last_event_at string (date-time) optional
Example: 2026-08-01T12:00:00Z

Timestamp of the most recent event in this session's canonical stream. Drives the inactivity policy that pauses idle sessions.

name string optional
Example: demo-agent

User-assignable display name, unique per team among non-terminal sessions. Usable in place of session_id by clients (doctl / Console resolve it to the id via the ListSessions ?name= filter; the {session_id} path stays UUID-only). Supplied via the environment-spec metadata.name, or auto-generated ("session--") when omitted.

openai_environment_id string optional
Example: example

OpenAI Agents API environment id (env_…), captured from the resolved CODEX_ENVIRONMENT_ID guest env value. Populated only for AGENT_KIND_OPENAI_CODEX sessions. Non-secret correlation metadata.

openai_session_id string optional
Example: example

OpenAI Agents API session id (sess_…) this DO sandbox hosts. Populated only for AGENT_KIND_OPENAI_CODEX sessions (empty otherwise). Non-secret correlation metadata; a client (doctl agents attach) reads it to bridge to the OpenAI session. See docs/design/openai-sandbox-provider.md.

parent_session_id string optional
Example: example

Lineage: id of the session this one was forked from. Omitted/empty for root (non-fork) sessions.

pause_reason string optional
Example: example

Why this session is paused. Present only when status is SESSION_STATUS_PAUSED; omitted otherwise. Known values: manual (PauseSession RPC), idle (inactivity auto-pause), low_balance (prepay gate). Clients should treat an unrecognized value as an opaque reason string.

repo_hint string optional
Example: example

Optional repository hint supplied at session creation (first spec.workspace.repos entry of the manifest). Not authoritative; the agent may change repos in-session.

resume_on_topoff boolean optional
Example: false

Session consents to being resumed automatically when the team's prepayment balance is restored after a low-balance pause. Defaults to false at create time; may be toggled later via PATCH /v2/agents/sessions/{session_id} (resume_on_topoff only). Only a session paused with reason low_balance whose latest run did not complete is ever resumed automatically - a session the customer paused themselves, or one that idled out, stays paused regardless. Not an environment-spec field, and forks do not inherit it. Omitted when false.

sandbox_id string optional
Example: example

Sandbox identity for support / debugging. Informational; omitted until a sandbox is allocated.

session_id string optional
Example: a1b2c3d4-e5f6-7890-abcd-ef1234567890
status string (enum) optional
Example: SESSION_STATUS_UNSPECIFIED

SessionStatus is the lifecycle state of the sandbox + agent pair. SESSION_STATUS_ALL is a ListSessions status-filter value only -- no session is ever actually in this status. SESSION_STATUS_LOCKED is reserved for internal use and never appears in an end-user-facing response.

warnings array of string optional
Example: []

Non-fatal advisories computed from the manifest at create time: one entry per populated accepted-but-not-yet-enforced section (flat names: secrets, model, tools, memory, budget, max_lifetime, mounts; legacy manifests get the corresponding spec.* paths), a deprecation entry when a legacy-envelope manifest or an adapter alias (codex-cli, cursor-cli) is used, and a heuristic entry per credential-looking spec.env value. Populated on the CreateSession response only.

401

Authentication failed due to invalid credentials.

ratelimit-limit integer

The default limit on number of requests that can be made per hour and per minute. Current rate limits are 5000 requests per hour and 250 requests per minute.

ratelimit-remaining integer

The number of requests in your hourly quota that remain before you hit your request limit. See https://docs.digitalocean.com/reference/api/reference/#rate-limit for information about how requests expire.

ratelimit-reset integer

The time when the oldest request will expire. The value is given in Unix epoch time. See https://docs.digitalocean.com/reference/api/reference/#rate-limit for information about how requests expire.

id string required
Example: not_found

A short identifier corresponding to the HTTP status code returned. For example, the ID for a response returning a 404 status code would be "not_found."

message string required
Example: The resource you were accessing could not be found.

A message providing additional information about the error, including details to help resolve it when possible.

request_id string optional
Example: 4d9d8375-3c56-4925-a3e7-eb137fed17e9

Optionally, some endpoints may include a request ID that should be provided when reporting bugs or opening support tickets to help identify the issue.

402

The team is blocked by the prepayment gate.

ratelimit-limit integer

The default limit on number of requests that can be made per hour and per minute. Current rate limits are 5000 requests per hour and 250 requests per minute.

ratelimit-remaining integer

The number of requests in your hourly quota that remain before you hit your request limit. See https://docs.digitalocean.com/reference/api/reference/#rate-limit for information about how requests expire.

ratelimit-reset integer

The time when the oldest request will expire. The value is given in Unix epoch time. See https://docs.digitalocean.com/reference/api/reference/#rate-limit for information about how requests expire.

id string required
Example: not_found

A short identifier corresponding to the HTTP status code returned. For example, the ID for a response returning a 404 status code would be "not_found."

message string required
Example: The resource you were accessing could not be found.

A message providing additional information about the error, including details to help resolve it when possible.

request_id string optional
Example: 4d9d8375-3c56-4925-a3e7-eb137fed17e9

Optionally, some endpoints may include a request ID that should be provided when reporting bugs or opening support tickets to help identify the issue.

403

Session belongs to another team.

ratelimit-limit integer

The default limit on number of requests that can be made per hour and per minute. Current rate limits are 5000 requests per hour and 250 requests per minute.

ratelimit-remaining integer

The number of requests in your hourly quota that remain before you hit your request limit. See https://docs.digitalocean.com/reference/api/reference/#rate-limit for information about how requests expire.

ratelimit-reset integer

The time when the oldest request will expire. The value is given in Unix epoch time. See https://docs.digitalocean.com/reference/api/reference/#rate-limit for information about how requests expire.

id string required
Example: not_found

A short identifier corresponding to the HTTP status code returned. For example, the ID for a response returning a 404 status code would be "not_found."

message string required
Example: The resource you were accessing could not be found.

A message providing additional information about the error, including details to help resolve it when possible.

request_id string optional
Example: 4d9d8375-3c56-4925-a3e7-eb137fed17e9

Optionally, some endpoints may include a request ID that should be provided when reporting bugs or opening support tickets to help identify the issue.

404

The resource was not found.

ratelimit-limit integer

The default limit on number of requests that can be made per hour and per minute. Current rate limits are 5000 requests per hour and 250 requests per minute.

ratelimit-remaining integer

The number of requests in your hourly quota that remain before you hit your request limit. See https://docs.digitalocean.com/reference/api/reference/#rate-limit for information about how requests expire.

ratelimit-reset integer

The time when the oldest request will expire. The value is given in Unix epoch time. See https://docs.digitalocean.com/reference/api/reference/#rate-limit for information about how requests expire.

id string required
Example: not_found

A short identifier corresponding to the HTTP status code returned. For example, the ID for a response returning a 404 status code would be "not_found."

message string required
Example: The resource you were accessing could not be found.

A message providing additional information about the error, including details to help resolve it when possible.

request_id string optional
Example: 4d9d8375-3c56-4925-a3e7-eb137fed17e9

Optionally, some endpoints may include a request ID that should be provided when reporting bugs or opening support tickets to help identify the issue.

409

Checkpoint is not READY, or session cannot be rolled back in its current state.

ratelimit-limit integer

The default limit on number of requests that can be made per hour and per minute. Current rate limits are 5000 requests per hour and 250 requests per minute.

ratelimit-remaining integer

The number of requests in your hourly quota that remain before you hit your request limit. See https://docs.digitalocean.com/reference/api/reference/#rate-limit for information about how requests expire.

ratelimit-reset integer

The time when the oldest request will expire. The value is given in Unix epoch time. See https://docs.digitalocean.com/reference/api/reference/#rate-limit for information about how requests expire.

id string required
Example: not_found

A short identifier corresponding to the HTTP status code returned. For example, the ID for a response returning a 404 status code would be "not_found."

message string required
Example: The resource you were accessing could not be found.

A message providing additional information about the error, including details to help resolve it when possible.

request_id string optional
Example: 4d9d8375-3c56-4925-a3e7-eb137fed17e9

Optionally, some endpoints may include a request ID that should be provided when reporting bugs or opening support tickets to help identify the issue.

423

This session is unavailable; contact support.

ratelimit-limit integer

The default limit on number of requests that can be made per hour and per minute. Current rate limits are 5000 requests per hour and 250 requests per minute.

ratelimit-remaining integer

The number of requests in your hourly quota that remain before you hit your request limit. See https://docs.digitalocean.com/reference/api/reference/#rate-limit for information about how requests expire.

ratelimit-reset integer

The time when the oldest request will expire. The value is given in Unix epoch time. See https://docs.digitalocean.com/reference/api/reference/#rate-limit for information about how requests expire.

id string required
Example: not_found

A short identifier corresponding to the HTTP status code returned. For example, the ID for a response returning a 404 status code would be "not_found."

message string required
Example: The resource you were accessing could not be found.

A message providing additional information about the error, including details to help resolve it when possible.

request_id string optional
Example: 4d9d8375-3c56-4925-a3e7-eb137fed17e9

Optionally, some endpoints may include a request ID that should be provided when reporting bugs or opening support tickets to help identify the issue.

429

The API rate limit has been exceeded.

ratelimit-limit integer

The default limit on number of requests that can be made per hour and per minute. Current rate limits are 5000 requests per hour and 250 requests per minute.

ratelimit-remaining integer

The number of requests in your hourly quota that remain before you hit your request limit. See https://docs.digitalocean.com/reference/api/reference/#rate-limit for information about how requests expire.

ratelimit-reset integer

The time when the oldest request will expire. The value is given in Unix epoch time. See https://docs.digitalocean.com/reference/api/reference/#rate-limit for information about how requests expire.

id string required
Example: not_found

A short identifier corresponding to the HTTP status code returned. For example, the ID for a response returning a 404 status code would be "not_found."

message string required
Example: The resource you were accessing could not be found.

A message providing additional information about the error, including details to help resolve it when possible.

request_id string optional
Example: 4d9d8375-3c56-4925-a3e7-eb137fed17e9

Optionally, some endpoints may include a request ID that should be provided when reporting bugs or opening support tickets to help identify the issue.

500

There was a server error.

ratelimit-limit integer

The default limit on number of requests that can be made per hour and per minute. Current rate limits are 5000 requests per hour and 250 requests per minute.

ratelimit-remaining integer

The number of requests in your hourly quota that remain before you hit your request limit. See https://docs.digitalocean.com/reference/api/reference/#rate-limit for information about how requests expire.

ratelimit-reset integer

The time when the oldest request will expire. The value is given in Unix epoch time. See https://docs.digitalocean.com/reference/api/reference/#rate-limit for information about how requests expire.

id string required
Example: not_found

A short identifier corresponding to the HTTP status code returned. For example, the ID for a response returning a 404 status code would be "not_found."

message string required
Example: The resource you were accessing could not be found.

A message providing additional information about the error, including details to help resolve it when possible.

request_id string optional
Example: 4d9d8375-3c56-4925-a3e7-eb137fed17e9

Optionally, some endpoints may include a request ID that should be provided when reporting bugs or opening support tickets to help identify the issue.

501

Rollback is not supported for this agent/substrate.

ratelimit-limit integer

The default limit on number of requests that can be made per hour and per minute. Current rate limits are 5000 requests per hour and 250 requests per minute.

ratelimit-remaining integer

The number of requests in your hourly quota that remain before you hit your request limit. See https://docs.digitalocean.com/reference/api/reference/#rate-limit for information about how requests expire.

ratelimit-reset integer

The time when the oldest request will expire. The value is given in Unix epoch time. See https://docs.digitalocean.com/reference/api/reference/#rate-limit for information about how requests expire.

id string required
Example: not_found

A short identifier corresponding to the HTTP status code returned. For example, the ID for a response returning a 404 status code would be "not_found."

message string required
Example: The resource you were accessing could not be found.

A message providing additional information about the error, including details to help resolve it when possible.

request_id string optional
Example: 4d9d8375-3c56-4925-a3e7-eb137fed17e9

Optionally, some endpoints may include a request ID that should be provided when reporting bugs or opening support tickets to help identify the issue.

default

There was an unexpected error.

ratelimit-limit integer

The default limit on number of requests that can be made per hour and per minute. Current rate limits are 5000 requests per hour and 250 requests per minute.

ratelimit-remaining integer

The number of requests in your hourly quota that remain before you hit your request limit. See https://docs.digitalocean.com/reference/api/reference/#rate-limit for information about how requests expire.

ratelimit-reset integer

The time when the oldest request will expire. The value is given in Unix epoch time. See https://docs.digitalocean.com/reference/api/reference/#rate-limit for information about how requests expire.

id string required
Example: not_found

A short identifier corresponding to the HTTP status code returned. For example, the ID for a response returning a 404 status code would be "not_found."

message string required
Example: The resource you were accessing could not be found.

A message providing additional information about the error, including details to help resolve it when possible.

request_id string optional
Example: 4d9d8375-3c56-4925-a3e7-eb137fed17e9

Optionally, some endpoints may include a request ID that should be provided when reporting bugs or opening support tickets to help identify the issue.

{
  "session": {
    "agent_kind": "AGENT_KIND_UNSPECIFIED",
    "config_id": "11111111-2222-3333-4444-555555555555",
    "created_at": "2026-08-01T12:00:00Z",
    "fork_from_checkpoint_id": "example",
    "fork_id": "11111111-2222-3333-4444-555555555555",
    "idle_timeout_seconds": 60,
    "keep_warm": false,
    "last_event_at": "2026-08-01T12:00:00Z",
    "name": "demo-agent",
    "openai_environment_id": "example",
    "openai_session_id": "example",
    "parent_session_id": "example",
    "pause_reason": "example",
    "repo_hint": "example",
    "resume_on_topoff": false,
    "sandbox_id": "example",
    "session_id": "a1b2c3d4-e5f6-7890-abcd-ef1234567890",
    "status": "SESSION_STATUS_UNSPECIFIED",
    "warnings": []
  }
}
{
  "id": "unauthorized",
  "message": "Unable to authenticate you."
}
{
  "id": "not_found",
  "message": "The resource you were accessing could not be found.",
  "request_id": "4d9d8375-3c56-4925-a3e7-eb137fed17e9"
}
{
  "id": "not_found",
  "message": "The resource you were accessing could not be found.",
  "request_id": "4d9d8375-3c56-4925-a3e7-eb137fed17e9"
}
{
  "id": "not_found",
  "message": "The resource you requested could not be found."
}
{
  "id": "not_found",
  "message": "The resource you were accessing could not be found.",
  "request_id": "4d9d8375-3c56-4925-a3e7-eb137fed17e9"
}
{
  "id": "not_found",
  "message": "The resource you were accessing could not be found.",
  "request_id": "4d9d8375-3c56-4925-a3e7-eb137fed17e9"
}
{
  "id": "too_many_requests",
  "message": "API rate limit exceeded."
}
{
  "id": "server_error",
  "message": "Unexpected server-side error"
}
{
  "id": "not_found",
  "message": "The resource you were accessing could not be found.",
  "request_id": "4d9d8375-3c56-4925-a3e7-eb137fed17e9"
}
{
  "id": "example_error",
  "message": "some error message"
}

POST ForkSession creates child sessions from a checkpoint of this session.

/v2/agents/sessions/{session_id}/fork
Authorizations: bearer_auth (1 scope)
Http: Bearer
Required scopes: agent_harness_session:create

OAuth Authentication

In order to interact with the DigitalOcean API, you or your application must authenticate.

The DigitalOcean API handles this through OAuth, an open standard for authorization. OAuth allows you to delegate access to your account. Scopes can be used to grant full access, read-only access, or access to a specific set of endpoints.

You can generate an OAuth token by visiting the Apps & API section of the DigitalOcean control panel for your account.

An OAuth token functions as a complete authentication request. In effect, it acts as a substitute for a username and password pair.

Because of this, it is absolutely essential that you keep your OAuth tokens secure. In fact, upon generation, the web interface will only display each token a single time in order to prevent the token from being compromised.

DigitalOcean access tokens begin with an identifiable prefix in order to distinguish them from other similar tokens.

  • dop_v1_ for personal access tokens generated in the control panel
  • doo_v1_ for tokens generated by applications using the OAuth flow
  • dor_v1_ for OAuth refresh tokens

Scopes

Scopes act like permissions assigned to an API token. These permissions determine what actions the token can perform. You can create API tokens that grant read-only access, full access, or limited access to specific endpoints by using custom scopes.

Generally, scopes are designed to match HTTP verbs and common CRUD operations (Create, Read, Update, Delete).

HTTP Verb CRUD Operation Scope
GET Read <resource>:read
POST Create <resource>:create
PUT/PATCH Update <resource>:update
DELETE Delete <resource>:delete

For example, creating a new Droplet by making a POST request to the /v2/droplets endpoint requires the droplet:create scope while listing Droplets by making a GET request to the /v2/droplets endpoint requires the droplet:read scope.

Each endpoint below specifies which scope is required to access it when using custom scopes.

How to Authenticate with OAuth

In order to make an authenticated request, include a bearer-type Authorization header containing your OAuth token. All requests must be made over HTTPS.

Authenticate with a Bearer Authorization Header

curl -X $HTTP_METHOD -H "Authorization: Bearer $DIGITALOCEAN_TOKEN" "https://api.digitalocean.com/v2/$OBJECT"

Each child boots a fresh sandbox from the checkpoint's machine-state capture and is drivable exactly like any other session (input, HITL), with parent_session_id and fork_id set for lineage. When from_checkpoint_id is omitted, an implicit checkpoint of the session "now" is captured first and the children fork from that. All-or-nothing: on failure nothing is left running.

Path Parameters

session_id string required
Example: a1b2c3d4-e5f6-7890-abcd-ef1234567890

The session UUID.

Request Body: application/json

Optional; an empty or omitted body forks a single child from an implicit checkpoint of "now".

count integer (int32) optional

Number of child sessions to create, 1-4. Defaults to 1 when omitted; a value outside 1-4 is rejected with 400.

from_checkpoint_id string optional

Checkpoint to fork from; must be READY. Omitted/empty means capture an implicit checkpoint of the session "now" first and fork from that.

Content type application/json
{
  "count": 1,
  "from_checkpoint_id": "string"
}
curl -X POST \
  -H "Content-Type: application/json" \
  -H "Authorization: Bearer $DIGITALOCEAN_TOKEN" \
  -d '{"count":1}' \
  "https://api.digitalocean.com/v2/agents/sessions/{session_id}/fork"
curl -X POST \
  -H "Authorization: Bearer $API_TOKEN" \
  -H "Content-Type: application/json" \
  -d '{
  "count": 1,
  "from_checkpoint_id": "string"
}' \
  "https://api.digitalocean.com/v2/agents/sessions/{session_id}/fork"

Responses

200

The created child sessions (each a full Session, PROVISIONING -> READY).

ratelimit-limit integer

The default limit on number of requests that can be made per hour and per minute. Current rate limits are 5000 requests per hour and 250 requests per minute.

ratelimit-remaining integer

The number of requests in your hourly quota that remain before you hit your request limit. See https://docs.digitalocean.com/reference/api/reference/#rate-limit for information about how requests expire.

ratelimit-reset integer

The time when the oldest request will expire. The value is given in Unix epoch time. See https://docs.digitalocean.com/reference/api/reference/#rate-limit for information about how requests expire.

sessions array of object optional

The created child sessions, each a full Session with parent_session_id and fork_id set (PROVISIONING -> READY) and drivable exactly like any other session.

Show child properties
agent_kind string (enum) optional
Example: AGENT_KIND_UNSPECIFIED

AgentKind identifies what runs inside the session sandbox. CreateSession accepts CLAUDE_CODE, OPENCODE, CODEX_CLI, CURSOR_CLI, OPENAI_CODEX, LANGGRAPH, and CREWAI (the supported set is overridable via HARNESS_SUPPORTED_AGENT_KINDS); other values are rejected with 400. AGENT_KIND_OPENAI_CODEX is the OpenAI sandbox-provider kind (DO runs codex exec-server; the agent loop lives at OpenAI). AGENT_KIND_LANGGRAPH is the LangGraph framework adapter. AGENT_KIND_CREWAI is the CrewAI Crew framework adapter: like LANGGRAPH the template bakes no agent code, so spec.env must supply FRAMEWORK_REPO and FRAMEWORK_REPO_SHA; a Crew kickoff is one-shot and exposes no HITL surface. CREWAI is additionally gated per team and returns 400 for teams it is not enabled for.

config_id string (uuid) optional
Example: 11111111-2222-3333-4444-555555555555

Durable Environment Config UUID the session was created from (inline manifests persist a config too, named after the session). Persisted and returned on create/get/list; absent only for sessions created before config references were stored.

created_at string (date-time) optional
Example: 2026-08-01T12:00:00Z
fork_from_checkpoint_id string optional
Example: example

Lineage: harness-api checkpoint id (cp_) the child booted from at fork time. Drives OHP inherited-history replay on attach. Omitted/empty for root sessions and legacy forks created before this field was persisted.

fork_id string (uuid) optional
Example: 11111111-2222-3333-4444-555555555555

Lineage: branch label assigned when this session was created by ForkSession (or rollback's internal fork). Omitted/empty for root sessions.

idle_timeout_seconds integer (int64) optional
Example: 60

This session's own idle-pause timeout (manifest idle_timeout). Omitted when the session uses the deployment-wide default.

keep_warm boolean optional
Example: false

Session is exempt from idle auto-pause (manifest keep_warm, or the agent-kind default: hermes sessions keep warm). Pause requests against such a session are rejected with 409. Omitted when false.

last_event_at string (date-time) optional
Example: 2026-08-01T12:00:00Z

Timestamp of the most recent event in this session's canonical stream. Drives the inactivity policy that pauses idle sessions.

name string optional
Example: demo-agent

User-assignable display name, unique per team among non-terminal sessions. Usable in place of session_id by clients (doctl / Console resolve it to the id via the ListSessions ?name= filter; the {session_id} path stays UUID-only). Supplied via the environment-spec metadata.name, or auto-generated ("session--") when omitted.

openai_environment_id string optional
Example: example

OpenAI Agents API environment id (env_…), captured from the resolved CODEX_ENVIRONMENT_ID guest env value. Populated only for AGENT_KIND_OPENAI_CODEX sessions. Non-secret correlation metadata.

openai_session_id string optional
Example: example

OpenAI Agents API session id (sess_…) this DO sandbox hosts. Populated only for AGENT_KIND_OPENAI_CODEX sessions (empty otherwise). Non-secret correlation metadata; a client (doctl agents attach) reads it to bridge to the OpenAI session. See docs/design/openai-sandbox-provider.md.

parent_session_id string optional
Example: example

Lineage: id of the session this one was forked from. Omitted/empty for root (non-fork) sessions.

pause_reason string optional
Example: example

Why this session is paused. Present only when status is SESSION_STATUS_PAUSED; omitted otherwise. Known values: manual (PauseSession RPC), idle (inactivity auto-pause), low_balance (prepay gate). Clients should treat an unrecognized value as an opaque reason string.

repo_hint string optional
Example: example

Optional repository hint supplied at session creation (first spec.workspace.repos entry of the manifest). Not authoritative; the agent may change repos in-session.

resume_on_topoff boolean optional
Example: false

Session consents to being resumed automatically when the team's prepayment balance is restored after a low-balance pause. Defaults to false at create time; may be toggled later via PATCH /v2/agents/sessions/{session_id} (resume_on_topoff only). Only a session paused with reason low_balance whose latest run did not complete is ever resumed automatically - a session the customer paused themselves, or one that idled out, stays paused regardless. Not an environment-spec field, and forks do not inherit it. Omitted when false.

sandbox_id string optional
Example: example

Sandbox identity for support / debugging. Informational; omitted until a sandbox is allocated.

session_id string optional
Example: a1b2c3d4-e5f6-7890-abcd-ef1234567890
status string (enum) optional
Example: SESSION_STATUS_UNSPECIFIED

SessionStatus is the lifecycle state of the sandbox + agent pair. SESSION_STATUS_ALL is a ListSessions status-filter value only -- no session is ever actually in this status. SESSION_STATUS_LOCKED is reserved for internal use and never appears in an end-user-facing response.

warnings array of string optional
Example: []

Non-fatal advisories computed from the manifest at create time: one entry per populated accepted-but-not-yet-enforced section (flat names: secrets, model, tools, memory, budget, max_lifetime, mounts; legacy manifests get the corresponding spec.* paths), a deprecation entry when a legacy-envelope manifest or an adapter alias (codex-cli, cursor-cli) is used, and a heuristic entry per credential-looking spec.env value. Populated on the CreateSession response only.

401

Authentication failed due to invalid credentials.

ratelimit-limit integer

The default limit on number of requests that can be made per hour and per minute. Current rate limits are 5000 requests per hour and 250 requests per minute.

ratelimit-remaining integer

The number of requests in your hourly quota that remain before you hit your request limit. See https://docs.digitalocean.com/reference/api/reference/#rate-limit for information about how requests expire.

ratelimit-reset integer

The time when the oldest request will expire. The value is given in Unix epoch time. See https://docs.digitalocean.com/reference/api/reference/#rate-limit for information about how requests expire.

id string required
Example: not_found

A short identifier corresponding to the HTTP status code returned. For example, the ID for a response returning a 404 status code would be "not_found."

message string required
Example: The resource you were accessing could not be found.

A message providing additional information about the error, including details to help resolve it when possible.

request_id string optional
Example: 4d9d8375-3c56-4925-a3e7-eb137fed17e9

Optionally, some endpoints may include a request ID that should be provided when reporting bugs or opening support tickets to help identify the issue.

402

The team is blocked by the prepayment gate.

ratelimit-limit integer

The default limit on number of requests that can be made per hour and per minute. Current rate limits are 5000 requests per hour and 250 requests per minute.

ratelimit-remaining integer

The number of requests in your hourly quota that remain before you hit your request limit. See https://docs.digitalocean.com/reference/api/reference/#rate-limit for information about how requests expire.

ratelimit-reset integer

The time when the oldest request will expire. The value is given in Unix epoch time. See https://docs.digitalocean.com/reference/api/reference/#rate-limit for information about how requests expire.

id string required
Example: not_found

A short identifier corresponding to the HTTP status code returned. For example, the ID for a response returning a 404 status code would be "not_found."

message string required
Example: The resource you were accessing could not be found.

A message providing additional information about the error, including details to help resolve it when possible.

request_id string optional
Example: 4d9d8375-3c56-4925-a3e7-eb137fed17e9

Optionally, some endpoints may include a request ID that should be provided when reporting bugs or opening support tickets to help identify the issue.

403

Session belongs to another team.

ratelimit-limit integer

The default limit on number of requests that can be made per hour and per minute. Current rate limits are 5000 requests per hour and 250 requests per minute.

ratelimit-remaining integer

The number of requests in your hourly quota that remain before you hit your request limit. See https://docs.digitalocean.com/reference/api/reference/#rate-limit for information about how requests expire.

ratelimit-reset integer

The time when the oldest request will expire. The value is given in Unix epoch time. See https://docs.digitalocean.com/reference/api/reference/#rate-limit for information about how requests expire.

id string required
Example: not_found

A short identifier corresponding to the HTTP status code returned. For example, the ID for a response returning a 404 status code would be "not_found."

message string required
Example: The resource you were accessing could not be found.

A message providing additional information about the error, including details to help resolve it when possible.

request_id string optional
Example: 4d9d8375-3c56-4925-a3e7-eb137fed17e9

Optionally, some endpoints may include a request ID that should be provided when reporting bugs or opening support tickets to help identify the issue.

404

The resource was not found.

ratelimit-limit integer

The default limit on number of requests that can be made per hour and per minute. Current rate limits are 5000 requests per hour and 250 requests per minute.

ratelimit-remaining integer

The number of requests in your hourly quota that remain before you hit your request limit. See https://docs.digitalocean.com/reference/api/reference/#rate-limit for information about how requests expire.

ratelimit-reset integer

The time when the oldest request will expire. The value is given in Unix epoch time. See https://docs.digitalocean.com/reference/api/reference/#rate-limit for information about how requests expire.

id string required
Example: not_found

A short identifier corresponding to the HTTP status code returned. For example, the ID for a response returning a 404 status code would be "not_found."

message string required
Example: The resource you were accessing could not be found.

A message providing additional information about the error, including details to help resolve it when possible.

request_id string optional
Example: 4d9d8375-3c56-4925-a3e7-eb137fed17e9

Optionally, some endpoints may include a request ID that should be provided when reporting bugs or opening support tickets to help identify the issue.

409

Team is at the active-session quota, the checkpoint is not READY, or the source session is itself a fork.

ratelimit-limit integer

The default limit on number of requests that can be made per hour and per minute. Current rate limits are 5000 requests per hour and 250 requests per minute.

ratelimit-remaining integer

The number of requests in your hourly quota that remain before you hit your request limit. See https://docs.digitalocean.com/reference/api/reference/#rate-limit for information about how requests expire.

ratelimit-reset integer

The time when the oldest request will expire. The value is given in Unix epoch time. See https://docs.digitalocean.com/reference/api/reference/#rate-limit for information about how requests expire.

id string required
Example: not_found

A short identifier corresponding to the HTTP status code returned. For example, the ID for a response returning a 404 status code would be "not_found."

message string required
Example: The resource you were accessing could not be found.

A message providing additional information about the error, including details to help resolve it when possible.

request_id string optional
Example: 4d9d8375-3c56-4925-a3e7-eb137fed17e9

Optionally, some endpoints may include a request ID that should be provided when reporting bugs or opening support tickets to help identify the issue.

423

This session is unavailable; contact support.

ratelimit-limit integer

The default limit on number of requests that can be made per hour and per minute. Current rate limits are 5000 requests per hour and 250 requests per minute.

ratelimit-remaining integer

The number of requests in your hourly quota that remain before you hit your request limit. See https://docs.digitalocean.com/reference/api/reference/#rate-limit for information about how requests expire.

ratelimit-reset integer

The time when the oldest request will expire. The value is given in Unix epoch time. See https://docs.digitalocean.com/reference/api/reference/#rate-limit for information about how requests expire.

id string required
Example: not_found

A short identifier corresponding to the HTTP status code returned. For example, the ID for a response returning a 404 status code would be "not_found."

message string required
Example: The resource you were accessing could not be found.

A message providing additional information about the error, including details to help resolve it when possible.

request_id string optional
Example: 4d9d8375-3c56-4925-a3e7-eb137fed17e9

Optionally, some endpoints may include a request ID that should be provided when reporting bugs or opening support tickets to help identify the issue.

429

The API rate limit has been exceeded.

ratelimit-limit integer

The default limit on number of requests that can be made per hour and per minute. Current rate limits are 5000 requests per hour and 250 requests per minute.

ratelimit-remaining integer

The number of requests in your hourly quota that remain before you hit your request limit. See https://docs.digitalocean.com/reference/api/reference/#rate-limit for information about how requests expire.

ratelimit-reset integer

The time when the oldest request will expire. The value is given in Unix epoch time. See https://docs.digitalocean.com/reference/api/reference/#rate-limit for information about how requests expire.

id string required
Example: not_found

A short identifier corresponding to the HTTP status code returned. For example, the ID for a response returning a 404 status code would be "not_found."

message string required
Example: The resource you were accessing could not be found.

A message providing additional information about the error, including details to help resolve it when possible.

request_id string optional
Example: 4d9d8375-3c56-4925-a3e7-eb137fed17e9

Optionally, some endpoints may include a request ID that should be provided when reporting bugs or opening support tickets to help identify the issue.

500

There was a server error.

ratelimit-limit integer

The default limit on number of requests that can be made per hour and per minute. Current rate limits are 5000 requests per hour and 250 requests per minute.

ratelimit-remaining integer

The number of requests in your hourly quota that remain before you hit your request limit. See https://docs.digitalocean.com/reference/api/reference/#rate-limit for information about how requests expire.

ratelimit-reset integer

The time when the oldest request will expire. The value is given in Unix epoch time. See https://docs.digitalocean.com/reference/api/reference/#rate-limit for information about how requests expire.

id string required
Example: not_found

A short identifier corresponding to the HTTP status code returned. For example, the ID for a response returning a 404 status code would be "not_found."

message string required
Example: The resource you were accessing could not be found.

A message providing additional information about the error, including details to help resolve it when possible.

request_id string optional
Example: 4d9d8375-3c56-4925-a3e7-eb137fed17e9

Optionally, some endpoints may include a request ID that should be provided when reporting bugs or opening support tickets to help identify the issue.

501

Forking is not supported for this agent/substrate.

ratelimit-limit integer

The default limit on number of requests that can be made per hour and per minute. Current rate limits are 5000 requests per hour and 250 requests per minute.

ratelimit-remaining integer

The number of requests in your hourly quota that remain before you hit your request limit. See https://docs.digitalocean.com/reference/api/reference/#rate-limit for information about how requests expire.

ratelimit-reset integer

The time when the oldest request will expire. The value is given in Unix epoch time. See https://docs.digitalocean.com/reference/api/reference/#rate-limit for information about how requests expire.

id string required
Example: not_found

A short identifier corresponding to the HTTP status code returned. For example, the ID for a response returning a 404 status code would be "not_found."

message string required
Example: The resource you were accessing could not be found.

A message providing additional information about the error, including details to help resolve it when possible.

request_id string optional
Example: 4d9d8375-3c56-4925-a3e7-eb137fed17e9

Optionally, some endpoints may include a request ID that should be provided when reporting bugs or opening support tickets to help identify the issue.

default

There was an unexpected error.

ratelimit-limit integer

The default limit on number of requests that can be made per hour and per minute. Current rate limits are 5000 requests per hour and 250 requests per minute.

ratelimit-remaining integer

The number of requests in your hourly quota that remain before you hit your request limit. See https://docs.digitalocean.com/reference/api/reference/#rate-limit for information about how requests expire.

ratelimit-reset integer

The time when the oldest request will expire. The value is given in Unix epoch time. See https://docs.digitalocean.com/reference/api/reference/#rate-limit for information about how requests expire.

id string required
Example: not_found

A short identifier corresponding to the HTTP status code returned. For example, the ID for a response returning a 404 status code would be "not_found."

message string required
Example: The resource you were accessing could not be found.

A message providing additional information about the error, including details to help resolve it when possible.

request_id string optional
Example: 4d9d8375-3c56-4925-a3e7-eb137fed17e9

Optionally, some endpoints may include a request ID that should be provided when reporting bugs or opening support tickets to help identify the issue.

{
  "sessions": [
    {
      "agent_kind": "AGENT_KIND_UNSPECIFIED",
      "config_id": "11111111-2222-3333-4444-555555555555",
      "created_at": "2026-08-01T12:00:00Z",
      "fork_from_checkpoint_id": "example",
      "fork_id": "11111111-2222-3333-4444-555555555555",
      "idle_timeout_seconds": 60,
      "keep_warm": false,
      "last_event_at": "2026-08-01T12:00:00Z",
      "name": "demo-agent",
      "openai_environment_id": "example",
      "openai_session_id": "example",
      "parent_session_id": "example",
      "pause_reason": "example",
      "repo_hint": "example",
      "resume_on_topoff": false,
      "sandbox_id": "example",
      "session_id": "a1b2c3d4-e5f6-7890-abcd-ef1234567890",
      "status": "SESSION_STATUS_UNSPECIFIED",
      "warnings": []
    }
  ]
}
{
  "id": "unauthorized",
  "message": "Unable to authenticate you."
}
{
  "id": "not_found",
  "message": "The resource you were accessing could not be found.",
  "request_id": "4d9d8375-3c56-4925-a3e7-eb137fed17e9"
}
{
  "id": "not_found",
  "message": "The resource you were accessing could not be found.",
  "request_id": "4d9d8375-3c56-4925-a3e7-eb137fed17e9"
}
{
  "id": "not_found",
  "message": "The resource you requested could not be found."
}
{
  "id": "not_found",
  "message": "The resource you were accessing could not be found.",
  "request_id": "4d9d8375-3c56-4925-a3e7-eb137fed17e9"
}
{
  "id": "not_found",
  "message": "The resource you were accessing could not be found.",
  "request_id": "4d9d8375-3c56-4925-a3e7-eb137fed17e9"
}
{
  "id": "too_many_requests",
  "message": "API rate limit exceeded."
}
{
  "id": "server_error",
  "message": "Unexpected server-side error"
}
{
  "id": "not_found",
  "message": "The resource you were accessing could not be found.",
  "request_id": "4d9d8375-3c56-4925-a3e7-eb137fed17e9"
}
{
  "id": "example_error",
  "message": "some error message"
}

POST ResolveHITL records the user's decision on a pending HITL request.

/v2/agents/sessions/{session_id}/hitl/{request_id}
Authorizations: bearer_auth (1 scope)
Http: Bearer
Required scopes: agent_harness_session:operate

OAuth Authentication

In order to interact with the DigitalOcean API, you or your application must authenticate.

The DigitalOcean API handles this through OAuth, an open standard for authorization. OAuth allows you to delegate access to your account. Scopes can be used to grant full access, read-only access, or access to a specific set of endpoints.

You can generate an OAuth token by visiting the Apps & API section of the DigitalOcean control panel for your account.

An OAuth token functions as a complete authentication request. In effect, it acts as a substitute for a username and password pair.

Because of this, it is absolutely essential that you keep your OAuth tokens secure. In fact, upon generation, the web interface will only display each token a single time in order to prevent the token from being compromised.

DigitalOcean access tokens begin with an identifiable prefix in order to distinguish them from other similar tokens.

  • dop_v1_ for personal access tokens generated in the control panel
  • doo_v1_ for tokens generated by applications using the OAuth flow
  • dor_v1_ for OAuth refresh tokens

Scopes

Scopes act like permissions assigned to an API token. These permissions determine what actions the token can perform. You can create API tokens that grant read-only access, full access, or limited access to specific endpoints by using custom scopes.

Generally, scopes are designed to match HTTP verbs and common CRUD operations (Create, Read, Update, Delete).

HTTP Verb CRUD Operation Scope
GET Read <resource>:read
POST Create <resource>:create
PUT/PATCH Update <resource>:update
DELETE Delete <resource>:delete

For example, creating a new Droplet by making a POST request to the /v2/droplets endpoint requires the droplet:create scope while listing Droplets by making a GET request to the /v2/droplets endpoint requires the droplet:read scope.

Each endpoint below specifies which scope is required to access it when using custom scopes.

How to Authenticate with OAuth

In order to make an authenticated request, include a bearer-type Authorization header containing your OAuth token. All requests must be made over HTTPS.

Authenticate with a Bearer Authorization Header

curl -X $HTTP_METHOD -H "Authorization: Bearer $DIGITALOCEAN_TOKEN" "https://api.digitalocean.com/v2/$OBJECT"

harness-api forwards the decision into the owning microVM via the inbound runtime.v1.OHR.ResolveHITL RPC (dialed through the guest-fronting proxy), which unblocks the gated agent action. The resolution is also echoed to all attached clients as a HITLResolved event on StreamSession. Returns 204 No Content on success.

Path Parameters

session_id string required
Example: a1b2c3d4-e5f6-7890-abcd-ef1234567890

The session UUID.

request_id string required
Example: hitl_example

The HITL request identifier.

Header Parameters

X-Device-UUID string optional
Example: device-uuid-example

Optional hardware device id forwarded by doctl. Recorded on the resulting HITL decision.

Request Body: application/json

outcome string, one of: HITL_OUTCOME_UNSPECIFIED, HITL_OUTCOME_APPROVE, HITL_OUTCOME_REJECT, HITL_OUTCOME_DEFER required
Example: HITL_OUTCOME_UNSPECIFIED

HITLOutcome is the user's decision on a HITL request. DEFER backs off this attempt without treating it as a rejection.

reason string optional
Example: example

Optional free-text reason. Captured in the audit trail; not interpreted.

source string, one of: RESOLUTION_SOURCE_UNSPECIFIED, RESOLUTION_SOURCE_INLINE_KEYSTROKE, RESOLUTION_SOURCE_OUT_OF_BAND optional
Example: RESOLUTION_SOURCE_UNSPECIFIED

How a HITL resolution was triggered. Defaults to RESOLUTION_SOURCE_OUT_OF_BAND when omitted.

Content type application/json
{
  "outcome": "HITL_OUTCOME_UNSPECIFIED",
  "reason": "example",
  "source": "RESOLUTION_SOURCE_UNSPECIFIED"
}
curl -X POST \
  -H "Content-Type: application/json" \
  -H "Authorization: Bearer $DIGITALOCEAN_TOKEN" \
  "https://api.digitalocean.com/v2/agents/sessions/{session_id}/hitl/{request_id}"
curl -X POST \
  -H "Authorization: Bearer $API_TOKEN" \
  -H "Content-Type: application/json" \
  -d '{
  "outcome": "HITL_OUTCOME_UNSPECIFIED",
  "reason": "example",
  "source": "RESOLUTION_SOURCE_UNSPECIFIED"
}' \
  "https://api.digitalocean.com/v2/agents/sessions/{session_id}/hitl/{request_id}"

Responses

204

Decision recorded; no response body.

ratelimit-limit integer

The default limit on number of requests that can be made per hour and per minute. Current rate limits are 5000 requests per hour and 250 requests per minute.

ratelimit-remaining integer

The number of requests in your hourly quota that remain before you hit your request limit. See https://docs.digitalocean.com/reference/api/reference/#rate-limit for information about how requests expire.

ratelimit-reset integer

The time when the oldest request will expire. The value is given in Unix epoch time. See https://docs.digitalocean.com/reference/api/reference/#rate-limit for information about how requests expire.

400

Malformed JSON or missing outcome.

ratelimit-limit integer

The default limit on number of requests that can be made per hour and per minute. Current rate limits are 5000 requests per hour and 250 requests per minute.

ratelimit-remaining integer

The number of requests in your hourly quota that remain before you hit your request limit. See https://docs.digitalocean.com/reference/api/reference/#rate-limit for information about how requests expire.

ratelimit-reset integer

The time when the oldest request will expire. The value is given in Unix epoch time. See https://docs.digitalocean.com/reference/api/reference/#rate-limit for information about how requests expire.

id string required
Example: not_found

A short identifier corresponding to the HTTP status code returned. For example, the ID for a response returning a 404 status code would be "not_found."

message string required
Example: The resource you were accessing could not be found.

A message providing additional information about the error, including details to help resolve it when possible.

request_id string optional
Example: 4d9d8375-3c56-4925-a3e7-eb137fed17e9

Optionally, some endpoints may include a request ID that should be provided when reporting bugs or opening support tickets to help identify the issue.

401

Authentication failed due to invalid credentials.

ratelimit-limit integer

The default limit on number of requests that can be made per hour and per minute. Current rate limits are 5000 requests per hour and 250 requests per minute.

ratelimit-remaining integer

The number of requests in your hourly quota that remain before you hit your request limit. See https://docs.digitalocean.com/reference/api/reference/#rate-limit for information about how requests expire.

ratelimit-reset integer

The time when the oldest request will expire. The value is given in Unix epoch time. See https://docs.digitalocean.com/reference/api/reference/#rate-limit for information about how requests expire.

id string required
Example: not_found

A short identifier corresponding to the HTTP status code returned. For example, the ID for a response returning a 404 status code would be "not_found."

message string required
Example: The resource you were accessing could not be found.

A message providing additional information about the error, including details to help resolve it when possible.

request_id string optional
Example: 4d9d8375-3c56-4925-a3e7-eb137fed17e9

Optionally, some endpoints may include a request ID that should be provided when reporting bugs or opening support tickets to help identify the issue.

402

The team is blocked by the prepayment gate.

ratelimit-limit integer

The default limit on number of requests that can be made per hour and per minute. Current rate limits are 5000 requests per hour and 250 requests per minute.

ratelimit-remaining integer

The number of requests in your hourly quota that remain before you hit your request limit. See https://docs.digitalocean.com/reference/api/reference/#rate-limit for information about how requests expire.

ratelimit-reset integer

The time when the oldest request will expire. The value is given in Unix epoch time. See https://docs.digitalocean.com/reference/api/reference/#rate-limit for information about how requests expire.

id string required
Example: not_found

A short identifier corresponding to the HTTP status code returned. For example, the ID for a response returning a 404 status code would be "not_found."

message string required
Example: The resource you were accessing could not be found.

A message providing additional information about the error, including details to help resolve it when possible.

request_id string optional
Example: 4d9d8375-3c56-4925-a3e7-eb137fed17e9

Optionally, some endpoints may include a request ID that should be provided when reporting bugs or opening support tickets to help identify the issue.

403

Session belongs to another team.

ratelimit-limit integer

The default limit on number of requests that can be made per hour and per minute. Current rate limits are 5000 requests per hour and 250 requests per minute.

ratelimit-remaining integer

The number of requests in your hourly quota that remain before you hit your request limit. See https://docs.digitalocean.com/reference/api/reference/#rate-limit for information about how requests expire.

ratelimit-reset integer

The time when the oldest request will expire. The value is given in Unix epoch time. See https://docs.digitalocean.com/reference/api/reference/#rate-limit for information about how requests expire.

id string required
Example: not_found

A short identifier corresponding to the HTTP status code returned. For example, the ID for a response returning a 404 status code would be "not_found."

message string required
Example: The resource you were accessing could not be found.

A message providing additional information about the error, including details to help resolve it when possible.

request_id string optional
Example: 4d9d8375-3c56-4925-a3e7-eb137fed17e9

Optionally, some endpoints may include a request ID that should be provided when reporting bugs or opening support tickets to help identify the issue.

404

The resource was not found.

ratelimit-limit integer

The default limit on number of requests that can be made per hour and per minute. Current rate limits are 5000 requests per hour and 250 requests per minute.

ratelimit-remaining integer

The number of requests in your hourly quota that remain before you hit your request limit. See https://docs.digitalocean.com/reference/api/reference/#rate-limit for information about how requests expire.

ratelimit-reset integer

The time when the oldest request will expire. The value is given in Unix epoch time. See https://docs.digitalocean.com/reference/api/reference/#rate-limit for information about how requests expire.

id string required
Example: not_found

A short identifier corresponding to the HTTP status code returned. For example, the ID for a response returning a 404 status code would be "not_found."

message string required
Example: The resource you were accessing could not be found.

A message providing additional information about the error, including details to help resolve it when possible.

request_id string optional
Example: 4d9d8375-3c56-4925-a3e7-eb137fed17e9

Optionally, some endpoints may include a request ID that should be provided when reporting bugs or opening support tickets to help identify the issue.

423

This session is unavailable; contact support.

ratelimit-limit integer

The default limit on number of requests that can be made per hour and per minute. Current rate limits are 5000 requests per hour and 250 requests per minute.

ratelimit-remaining integer

The number of requests in your hourly quota that remain before you hit your request limit. See https://docs.digitalocean.com/reference/api/reference/#rate-limit for information about how requests expire.

ratelimit-reset integer

The time when the oldest request will expire. The value is given in Unix epoch time. See https://docs.digitalocean.com/reference/api/reference/#rate-limit for information about how requests expire.

id string required
Example: not_found

A short identifier corresponding to the HTTP status code returned. For example, the ID for a response returning a 404 status code would be "not_found."

message string required
Example: The resource you were accessing could not be found.

A message providing additional information about the error, including details to help resolve it when possible.

request_id string optional
Example: 4d9d8375-3c56-4925-a3e7-eb137fed17e9

Optionally, some endpoints may include a request ID that should be provided when reporting bugs or opening support tickets to help identify the issue.

429

The API rate limit has been exceeded.

ratelimit-limit integer

The default limit on number of requests that can be made per hour and per minute. Current rate limits are 5000 requests per hour and 250 requests per minute.

ratelimit-remaining integer

The number of requests in your hourly quota that remain before you hit your request limit. See https://docs.digitalocean.com/reference/api/reference/#rate-limit for information about how requests expire.

ratelimit-reset integer

The time when the oldest request will expire. The value is given in Unix epoch time. See https://docs.digitalocean.com/reference/api/reference/#rate-limit for information about how requests expire.

id string required
Example: not_found

A short identifier corresponding to the HTTP status code returned. For example, the ID for a response returning a 404 status code would be "not_found."

message string required
Example: The resource you were accessing could not be found.

A message providing additional information about the error, including details to help resolve it when possible.

request_id string optional
Example: 4d9d8375-3c56-4925-a3e7-eb137fed17e9

Optionally, some endpoints may include a request ID that should be provided when reporting bugs or opening support tickets to help identify the issue.

500

There was a server error.

ratelimit-limit integer

The default limit on number of requests that can be made per hour and per minute. Current rate limits are 5000 requests per hour and 250 requests per minute.

ratelimit-remaining integer

The number of requests in your hourly quota that remain before you hit your request limit. See https://docs.digitalocean.com/reference/api/reference/#rate-limit for information about how requests expire.

ratelimit-reset integer

The time when the oldest request will expire. The value is given in Unix epoch time. See https://docs.digitalocean.com/reference/api/reference/#rate-limit for information about how requests expire.

id string required
Example: not_found

A short identifier corresponding to the HTTP status code returned. For example, the ID for a response returning a 404 status code would be "not_found."

message string required
Example: The resource you were accessing could not be found.

A message providing additional information about the error, including details to help resolve it when possible.

request_id string optional
Example: 4d9d8375-3c56-4925-a3e7-eb137fed17e9

Optionally, some endpoints may include a request ID that should be provided when reporting bugs or opening support tickets to help identify the issue.

default

There was an unexpected error.

ratelimit-limit integer

The default limit on number of requests that can be made per hour and per minute. Current rate limits are 5000 requests per hour and 250 requests per minute.

ratelimit-remaining integer

The number of requests in your hourly quota that remain before you hit your request limit. See https://docs.digitalocean.com/reference/api/reference/#rate-limit for information about how requests expire.

ratelimit-reset integer

The time when the oldest request will expire. The value is given in Unix epoch time. See https://docs.digitalocean.com/reference/api/reference/#rate-limit for information about how requests expire.

id string required
Example: not_found

A short identifier corresponding to the HTTP status code returned. For example, the ID for a response returning a 404 status code would be "not_found."

message string required
Example: The resource you were accessing could not be found.

A message providing additional information about the error, including details to help resolve it when possible.

request_id string optional
Example: 4d9d8375-3c56-4925-a3e7-eb137fed17e9

Optionally, some endpoints may include a request ID that should be provided when reporting bugs or opening support tickets to help identify the issue.

{
  "id": "not_found",
  "message": "The resource you were accessing could not be found.",
  "request_id": "4d9d8375-3c56-4925-a3e7-eb137fed17e9"
}
{
  "id": "unauthorized",
  "message": "Unable to authenticate you."
}
{
  "id": "not_found",
  "message": "The resource you were accessing could not be found.",
  "request_id": "4d9d8375-3c56-4925-a3e7-eb137fed17e9"
}
{
  "id": "not_found",
  "message": "The resource you were accessing could not be found.",
  "request_id": "4d9d8375-3c56-4925-a3e7-eb137fed17e9"
}
{
  "id": "not_found",
  "message": "The resource you requested could not be found."
}
{
  "id": "not_found",
  "message": "The resource you were accessing could not be found.",
  "request_id": "4d9d8375-3c56-4925-a3e7-eb137fed17e9"
}
{
  "id": "too_many_requests",
  "message": "API rate limit exceeded."
}
{
  "id": "server_error",
  "message": "Unexpected server-side error"
}
{
  "id": "example_error",
  "message": "some error message"
}

POST SendInput delivers a user chat message into the session.

/v2/agents/sessions/{session_id}/input
Authorizations: bearer_auth (1 scope)
Http: Bearer
Required scopes: agent_harness_session:operate

OAuth Authentication

In order to interact with the DigitalOcean API, you or your application must authenticate.

The DigitalOcean API handles this through OAuth, an open standard for authorization. OAuth allows you to delegate access to your account. Scopes can be used to grant full access, read-only access, or access to a specific set of endpoints.

You can generate an OAuth token by visiting the Apps & API section of the DigitalOcean control panel for your account.

An OAuth token functions as a complete authentication request. In effect, it acts as a substitute for a username and password pair.

Because of this, it is absolutely essential that you keep your OAuth tokens secure. In fact, upon generation, the web interface will only display each token a single time in order to prevent the token from being compromised.

DigitalOcean access tokens begin with an identifiable prefix in order to distinguish them from other similar tokens.

  • dop_v1_ for personal access tokens generated in the control panel
  • doo_v1_ for tokens generated by applications using the OAuth flow
  • dor_v1_ for OAuth refresh tokens

Scopes

Scopes act like permissions assigned to an API token. These permissions determine what actions the token can perform. You can create API tokens that grant read-only access, full access, or limited access to specific endpoints by using custom scopes.

Generally, scopes are designed to match HTTP verbs and common CRUD operations (Create, Read, Update, Delete).

HTTP Verb CRUD Operation Scope
GET Read <resource>:read
POST Create <resource>:create
PUT/PATCH Update <resource>:update
DELETE Delete <resource>:delete

For example, creating a new Droplet by making a POST request to the /v2/droplets endpoint requires the droplet:create scope while listing Droplets by making a GET request to the /v2/droplets endpoint requires the droplet:read scope.

Each endpoint below specifies which scope is required to access it when using custom scopes.

How to Authenticate with OAuth

In order to make an authenticated request, include a bearer-type Authorization header containing your OAuth token. All requests must be made over HTTPS.

Authenticate with a Bearer Authorization Header

curl -X $HTTP_METHOD -H "Authorization: Bearer $DIGITALOCEAN_TOKEN" "https://api.digitalocean.com/v2/$OBJECT"

The agent observes it on its next turn and emits subsequent events via StreamSession. The input is forwarded to the owning microVM's OHR inbound surface, which attributes it to a run and returns the run id.

Path Parameters

session_id string required
Example: a1b2c3d4-e5f6-7890-abcd-ef1234567890

The session UUID.

Request Body: application/json

text string required
Example: example

The user message to deliver into the session. Required and non-empty.

Content type application/json
{
  "text": "example"
}
curl -X POST \
  -H "Content-Type: application/json" \
  -H "Authorization: Bearer $DIGITALOCEAN_TOKEN" \
  "https://api.digitalocean.com/v2/agents/sessions/{session_id}/input"
curl -X POST \
  -H "Authorization: Bearer $API_TOKEN" \
  -H "Content-Type: application/json" \
  -d '{
  "text": "example"
}' \
  "https://api.digitalocean.com/v2/agents/sessions/{session_id}/input"

Responses

200

Input accepted and attributed to a run.

ratelimit-limit integer

The default limit on number of requests that can be made per hour and per minute. Current rate limits are 5000 requests per hour and 250 requests per minute.

ratelimit-remaining integer

The number of requests in your hourly quota that remain before you hit your request limit. See https://docs.digitalocean.com/reference/api/reference/#rate-limit for information about how requests expire.

ratelimit-reset integer

The time when the oldest request will expire. The value is given in Unix epoch time. See https://docs.digitalocean.com/reference/api/reference/#rate-limit for information about how requests expire.

run_id string optional
Example: example

The run id the input was attributed to. Clients can correlate against the run.started event on the stream. May be empty if OHR returned no run id.

400

Malformed JSON or empty text.

ratelimit-limit integer

The default limit on number of requests that can be made per hour and per minute. Current rate limits are 5000 requests per hour and 250 requests per minute.

ratelimit-remaining integer

The number of requests in your hourly quota that remain before you hit your request limit. See https://docs.digitalocean.com/reference/api/reference/#rate-limit for information about how requests expire.

ratelimit-reset integer

The time when the oldest request will expire. The value is given in Unix epoch time. See https://docs.digitalocean.com/reference/api/reference/#rate-limit for information about how requests expire.

id string required
Example: not_found

A short identifier corresponding to the HTTP status code returned. For example, the ID for a response returning a 404 status code would be "not_found."

message string required
Example: The resource you were accessing could not be found.

A message providing additional information about the error, including details to help resolve it when possible.

request_id string optional
Example: 4d9d8375-3c56-4925-a3e7-eb137fed17e9

Optionally, some endpoints may include a request ID that should be provided when reporting bugs or opening support tickets to help identify the issue.

401

Authentication failed due to invalid credentials.

ratelimit-limit integer

The default limit on number of requests that can be made per hour and per minute. Current rate limits are 5000 requests per hour and 250 requests per minute.

ratelimit-remaining integer

The number of requests in your hourly quota that remain before you hit your request limit. See https://docs.digitalocean.com/reference/api/reference/#rate-limit for information about how requests expire.

ratelimit-reset integer

The time when the oldest request will expire. The value is given in Unix epoch time. See https://docs.digitalocean.com/reference/api/reference/#rate-limit for information about how requests expire.

id string required
Example: not_found

A short identifier corresponding to the HTTP status code returned. For example, the ID for a response returning a 404 status code would be "not_found."

message string required
Example: The resource you were accessing could not be found.

A message providing additional information about the error, including details to help resolve it when possible.

request_id string optional
Example: 4d9d8375-3c56-4925-a3e7-eb137fed17e9

Optionally, some endpoints may include a request ID that should be provided when reporting bugs or opening support tickets to help identify the issue.

402

The team is blocked by the prepayment gate.

ratelimit-limit integer

The default limit on number of requests that can be made per hour and per minute. Current rate limits are 5000 requests per hour and 250 requests per minute.

ratelimit-remaining integer

The number of requests in your hourly quota that remain before you hit your request limit. See https://docs.digitalocean.com/reference/api/reference/#rate-limit for information about how requests expire.

ratelimit-reset integer

The time when the oldest request will expire. The value is given in Unix epoch time. See https://docs.digitalocean.com/reference/api/reference/#rate-limit for information about how requests expire.

id string required
Example: not_found

A short identifier corresponding to the HTTP status code returned. For example, the ID for a response returning a 404 status code would be "not_found."

message string required
Example: The resource you were accessing could not be found.

A message providing additional information about the error, including details to help resolve it when possible.

request_id string optional
Example: 4d9d8375-3c56-4925-a3e7-eb137fed17e9

Optionally, some endpoints may include a request ID that should be provided when reporting bugs or opening support tickets to help identify the issue.

403

Session belongs to another team.

ratelimit-limit integer

The default limit on number of requests that can be made per hour and per minute. Current rate limits are 5000 requests per hour and 250 requests per minute.

ratelimit-remaining integer

The number of requests in your hourly quota that remain before you hit your request limit. See https://docs.digitalocean.com/reference/api/reference/#rate-limit for information about how requests expire.

ratelimit-reset integer

The time when the oldest request will expire. The value is given in Unix epoch time. See https://docs.digitalocean.com/reference/api/reference/#rate-limit for information about how requests expire.

id string required
Example: not_found

A short identifier corresponding to the HTTP status code returned. For example, the ID for a response returning a 404 status code would be "not_found."

message string required
Example: The resource you were accessing could not be found.

A message providing additional information about the error, including details to help resolve it when possible.

request_id string optional
Example: 4d9d8375-3c56-4925-a3e7-eb137fed17e9

Optionally, some endpoints may include a request ID that should be provided when reporting bugs or opening support tickets to help identify the issue.

404

The resource was not found.

ratelimit-limit integer

The default limit on number of requests that can be made per hour and per minute. Current rate limits are 5000 requests per hour and 250 requests per minute.

ratelimit-remaining integer

The number of requests in your hourly quota that remain before you hit your request limit. See https://docs.digitalocean.com/reference/api/reference/#rate-limit for information about how requests expire.

ratelimit-reset integer

The time when the oldest request will expire. The value is given in Unix epoch time. See https://docs.digitalocean.com/reference/api/reference/#rate-limit for information about how requests expire.

id string required
Example: not_found

A short identifier corresponding to the HTTP status code returned. For example, the ID for a response returning a 404 status code would be "not_found."

message string required
Example: The resource you were accessing could not be found.

A message providing additional information about the error, including details to help resolve it when possible.

request_id string optional
Example: 4d9d8375-3c56-4925-a3e7-eb137fed17e9

Optionally, some endpoints may include a request ID that should be provided when reporting bugs or opening support tickets to help identify the issue.

409

Session is not in a state that accepts input (not READY/DETACHED, or has no sandbox).

ratelimit-limit integer

The default limit on number of requests that can be made per hour and per minute. Current rate limits are 5000 requests per hour and 250 requests per minute.

ratelimit-remaining integer

The number of requests in your hourly quota that remain before you hit your request limit. See https://docs.digitalocean.com/reference/api/reference/#rate-limit for information about how requests expire.

ratelimit-reset integer

The time when the oldest request will expire. The value is given in Unix epoch time. See https://docs.digitalocean.com/reference/api/reference/#rate-limit for information about how requests expire.

id string required
Example: not_found

A short identifier corresponding to the HTTP status code returned. For example, the ID for a response returning a 404 status code would be "not_found."

message string required
Example: The resource you were accessing could not be found.

A message providing additional information about the error, including details to help resolve it when possible.

request_id string optional
Example: 4d9d8375-3c56-4925-a3e7-eb137fed17e9

Optionally, some endpoints may include a request ID that should be provided when reporting bugs or opening support tickets to help identify the issue.

423

This session is unavailable; contact support.

ratelimit-limit integer

The default limit on number of requests that can be made per hour and per minute. Current rate limits are 5000 requests per hour and 250 requests per minute.

ratelimit-remaining integer

The number of requests in your hourly quota that remain before you hit your request limit. See https://docs.digitalocean.com/reference/api/reference/#rate-limit for information about how requests expire.

ratelimit-reset integer

The time when the oldest request will expire. The value is given in Unix epoch time. See https://docs.digitalocean.com/reference/api/reference/#rate-limit for information about how requests expire.

id string required
Example: not_found

A short identifier corresponding to the HTTP status code returned. For example, the ID for a response returning a 404 status code would be "not_found."

message string required
Example: The resource you were accessing could not be found.

A message providing additional information about the error, including details to help resolve it when possible.

request_id string optional
Example: 4d9d8375-3c56-4925-a3e7-eb137fed17e9

Optionally, some endpoints may include a request ID that should be provided when reporting bugs or opening support tickets to help identify the issue.

429

The API rate limit has been exceeded.

ratelimit-limit integer

The default limit on number of requests that can be made per hour and per minute. Current rate limits are 5000 requests per hour and 250 requests per minute.

ratelimit-remaining integer

The number of requests in your hourly quota that remain before you hit your request limit. See https://docs.digitalocean.com/reference/api/reference/#rate-limit for information about how requests expire.

ratelimit-reset integer

The time when the oldest request will expire. The value is given in Unix epoch time. See https://docs.digitalocean.com/reference/api/reference/#rate-limit for information about how requests expire.

id string required
Example: not_found

A short identifier corresponding to the HTTP status code returned. For example, the ID for a response returning a 404 status code would be "not_found."

message string required
Example: The resource you were accessing could not be found.

A message providing additional information about the error, including details to help resolve it when possible.

request_id string optional
Example: 4d9d8375-3c56-4925-a3e7-eb137fed17e9

Optionally, some endpoints may include a request ID that should be provided when reporting bugs or opening support tickets to help identify the issue.

500

There was a server error.

ratelimit-limit integer

The default limit on number of requests that can be made per hour and per minute. Current rate limits are 5000 requests per hour and 250 requests per minute.

ratelimit-remaining integer

The number of requests in your hourly quota that remain before you hit your request limit. See https://docs.digitalocean.com/reference/api/reference/#rate-limit for information about how requests expire.

ratelimit-reset integer

The time when the oldest request will expire. The value is given in Unix epoch time. See https://docs.digitalocean.com/reference/api/reference/#rate-limit for information about how requests expire.

id string required
Example: not_found

A short identifier corresponding to the HTTP status code returned. For example, the ID for a response returning a 404 status code would be "not_found."

message string required
Example: The resource you were accessing could not be found.

A message providing additional information about the error, including details to help resolve it when possible.

request_id string optional
Example: 4d9d8375-3c56-4925-a3e7-eb137fed17e9

Optionally, some endpoints may include a request ID that should be provided when reporting bugs or opening support tickets to help identify the issue.

default

There was an unexpected error.

ratelimit-limit integer

The default limit on number of requests that can be made per hour and per minute. Current rate limits are 5000 requests per hour and 250 requests per minute.

ratelimit-remaining integer

The number of requests in your hourly quota that remain before you hit your request limit. See https://docs.digitalocean.com/reference/api/reference/#rate-limit for information about how requests expire.

ratelimit-reset integer

The time when the oldest request will expire. The value is given in Unix epoch time. See https://docs.digitalocean.com/reference/api/reference/#rate-limit for information about how requests expire.

id string required
Example: not_found

A short identifier corresponding to the HTTP status code returned. For example, the ID for a response returning a 404 status code would be "not_found."

message string required
Example: The resource you were accessing could not be found.

A message providing additional information about the error, including details to help resolve it when possible.

request_id string optional
Example: 4d9d8375-3c56-4925-a3e7-eb137fed17e9

Optionally, some endpoints may include a request ID that should be provided when reporting bugs or opening support tickets to help identify the issue.

{
  "run_id": "example"
}
{
  "id": "not_found",
  "message": "The resource you were accessing could not be found.",
  "request_id": "4d9d8375-3c56-4925-a3e7-eb137fed17e9"
}
{
  "id": "unauthorized",
  "message": "Unable to authenticate you."
}
{
  "id": "not_found",
  "message": "The resource you were accessing could not be found.",
  "request_id": "4d9d8375-3c56-4925-a3e7-eb137fed17e9"
}
{
  "id": "not_found",
  "message": "The resource you were accessing could not be found.",
  "request_id": "4d9d8375-3c56-4925-a3e7-eb137fed17e9"
}
{
  "id": "not_found",
  "message": "The resource you requested could not be found."
}
{
  "id": "not_found",
  "message": "The resource you were accessing could not be found.",
  "request_id": "4d9d8375-3c56-4925-a3e7-eb137fed17e9"
}
{
  "id": "not_found",
  "message": "The resource you were accessing could not be found.",
  "request_id": "4d9d8375-3c56-4925-a3e7-eb137fed17e9"
}
{
  "id": "too_many_requests",
  "message": "API rate limit exceeded."
}
{
  "id": "server_error",
  "message": "Unexpected server-side error"
}
{
  "id": "example_error",
  "message": "some error message"
}

POST PauseSession freezes the session's microVM sandbox.

/v2/agents/sessions/{session_id}/pause
Authorizations: bearer_auth (1 scope)
Http: Bearer
Required scopes: agent_harness_session:operate

OAuth Authentication

In order to interact with the DigitalOcean API, you or your application must authenticate.

The DigitalOcean API handles this through OAuth, an open standard for authorization. OAuth allows you to delegate access to your account. Scopes can be used to grant full access, read-only access, or access to a specific set of endpoints.

You can generate an OAuth token by visiting the Apps & API section of the DigitalOcean control panel for your account.

An OAuth token functions as a complete authentication request. In effect, it acts as a substitute for a username and password pair.

Because of this, it is absolutely essential that you keep your OAuth tokens secure. In fact, upon generation, the web interface will only display each token a single time in order to prevent the token from being compromised.

DigitalOcean access tokens begin with an identifiable prefix in order to distinguish them from other similar tokens.

  • dop_v1_ for personal access tokens generated in the control panel
  • doo_v1_ for tokens generated by applications using the OAuth flow
  • dor_v1_ for OAuth refresh tokens

Scopes

Scopes act like permissions assigned to an API token. These permissions determine what actions the token can perform. You can create API tokens that grant read-only access, full access, or limited access to specific endpoints by using custom scopes.

Generally, scopes are designed to match HTTP verbs and common CRUD operations (Create, Read, Update, Delete).

HTTP Verb CRUD Operation Scope
GET Read <resource>:read
POST Create <resource>:create
PUT/PATCH Update <resource>:update
DELETE Delete <resource>:delete

For example, creating a new Droplet by making a POST request to the /v2/droplets endpoint requires the droplet:create scope while listing Droplets by making a GET request to the /v2/droplets endpoint requires the droplet:read scope.

Each endpoint below specifies which scope is required to access it when using custom scopes.

How to Authenticate with OAuth

In order to make an authenticated request, include a bearer-type Authorization header containing your OAuth token. All requests must be made over HTTPS.

Authenticate with a Bearer Authorization Header

curl -X $HTTP_METHOD -H "Authorization: Bearer $DIGITALOCEAN_TOKEN" "https://api.digitalocean.com/v2/$OBJECT"

Supported on microvm-substrate sessions only; dewdrop/docker sessions return 501 Not Implemented. Paused sessions count against quota. Clients learn state via GetSession/ListSessions; no live session.updated event is emitted.

Path Parameters

session_id string required
Example: a1b2c3d4-e5f6-7890-abcd-ef1234567890

The session UUID.

Header Parameters

X-Device-UUID string optional
Example: device-uuid-example

Optional hardware device id forwarded by doctl. Recorded for audit.

curl -X POST \
  -H "Content-Type: application/json" \
  -H "Authorization: Bearer $DIGITALOCEAN_TOKEN" \
  "https://api.digitalocean.com/v2/agents/sessions/{session_id}/pause"
curl -X POST \
  -H "Authorization: Bearer $API_TOKEN" \
  -H "Content-Type: application/json" \
  "https://api.digitalocean.com/v2/agents/sessions/{session_id}/pause"

Responses

204

Session paused.

ratelimit-limit integer

The default limit on number of requests that can be made per hour and per minute. Current rate limits are 5000 requests per hour and 250 requests per minute.

ratelimit-remaining integer

The number of requests in your hourly quota that remain before you hit your request limit. See https://docs.digitalocean.com/reference/api/reference/#rate-limit for information about how requests expire.

ratelimit-reset integer

The time when the oldest request will expire. The value is given in Unix epoch time. See https://docs.digitalocean.com/reference/api/reference/#rate-limit for information about how requests expire.

401

Authentication failed due to invalid credentials.

ratelimit-limit integer

The default limit on number of requests that can be made per hour and per minute. Current rate limits are 5000 requests per hour and 250 requests per minute.

ratelimit-remaining integer

The number of requests in your hourly quota that remain before you hit your request limit. See https://docs.digitalocean.com/reference/api/reference/#rate-limit for information about how requests expire.

ratelimit-reset integer

The time when the oldest request will expire. The value is given in Unix epoch time. See https://docs.digitalocean.com/reference/api/reference/#rate-limit for information about how requests expire.

id string required
Example: not_found

A short identifier corresponding to the HTTP status code returned. For example, the ID for a response returning a 404 status code would be "not_found."

message string required
Example: The resource you were accessing could not be found.

A message providing additional information about the error, including details to help resolve it when possible.

request_id string optional
Example: 4d9d8375-3c56-4925-a3e7-eb137fed17e9

Optionally, some endpoints may include a request ID that should be provided when reporting bugs or opening support tickets to help identify the issue.

402

The team is blocked by the prepayment gate.

ratelimit-limit integer

The default limit on number of requests that can be made per hour and per minute. Current rate limits are 5000 requests per hour and 250 requests per minute.

ratelimit-remaining integer

The number of requests in your hourly quota that remain before you hit your request limit. See https://docs.digitalocean.com/reference/api/reference/#rate-limit for information about how requests expire.

ratelimit-reset integer

The time when the oldest request will expire. The value is given in Unix epoch time. See https://docs.digitalocean.com/reference/api/reference/#rate-limit for information about how requests expire.

id string required
Example: not_found

A short identifier corresponding to the HTTP status code returned. For example, the ID for a response returning a 404 status code would be "not_found."

message string required
Example: The resource you were accessing could not be found.

A message providing additional information about the error, including details to help resolve it when possible.

request_id string optional
Example: 4d9d8375-3c56-4925-a3e7-eb137fed17e9

Optionally, some endpoints may include a request ID that should be provided when reporting bugs or opening support tickets to help identify the issue.

403

Session belongs to another team.

ratelimit-limit integer

The default limit on number of requests that can be made per hour and per minute. Current rate limits are 5000 requests per hour and 250 requests per minute.

ratelimit-remaining integer

The number of requests in your hourly quota that remain before you hit your request limit. See https://docs.digitalocean.com/reference/api/reference/#rate-limit for information about how requests expire.

ratelimit-reset integer

The time when the oldest request will expire. The value is given in Unix epoch time. See https://docs.digitalocean.com/reference/api/reference/#rate-limit for information about how requests expire.

id string required
Example: not_found

A short identifier corresponding to the HTTP status code returned. For example, the ID for a response returning a 404 status code would be "not_found."

message string required
Example: The resource you were accessing could not be found.

A message providing additional information about the error, including details to help resolve it when possible.

request_id string optional
Example: 4d9d8375-3c56-4925-a3e7-eb137fed17e9

Optionally, some endpoints may include a request ID that should be provided when reporting bugs or opening support tickets to help identify the issue.

404

The resource was not found.

ratelimit-limit integer

The default limit on number of requests that can be made per hour and per minute. Current rate limits are 5000 requests per hour and 250 requests per minute.

ratelimit-remaining integer

The number of requests in your hourly quota that remain before you hit your request limit. See https://docs.digitalocean.com/reference/api/reference/#rate-limit for information about how requests expire.

ratelimit-reset integer

The time when the oldest request will expire. The value is given in Unix epoch time. See https://docs.digitalocean.com/reference/api/reference/#rate-limit for information about how requests expire.

id string required
Example: not_found

A short identifier corresponding to the HTTP status code returned. For example, the ID for a response returning a 404 status code would be "not_found."

message string required
Example: The resource you were accessing could not be found.

A message providing additional information about the error, including details to help resolve it when possible.

request_id string optional
Example: 4d9d8375-3c56-4925-a3e7-eb137fed17e9

Optionally, some endpoints may include a request ID that should be provided when reporting bugs or opening support tickets to help identify the issue.

409

Session is not in a pauseable state (must be READY or DETACHED).

ratelimit-limit integer

The default limit on number of requests that can be made per hour and per minute. Current rate limits are 5000 requests per hour and 250 requests per minute.

ratelimit-remaining integer

The number of requests in your hourly quota that remain before you hit your request limit. See https://docs.digitalocean.com/reference/api/reference/#rate-limit for information about how requests expire.

ratelimit-reset integer

The time when the oldest request will expire. The value is given in Unix epoch time. See https://docs.digitalocean.com/reference/api/reference/#rate-limit for information about how requests expire.

id string required
Example: not_found

A short identifier corresponding to the HTTP status code returned. For example, the ID for a response returning a 404 status code would be "not_found."

message string required
Example: The resource you were accessing could not be found.

A message providing additional information about the error, including details to help resolve it when possible.

request_id string optional
Example: 4d9d8375-3c56-4925-a3e7-eb137fed17e9

Optionally, some endpoints may include a request ID that should be provided when reporting bugs or opening support tickets to help identify the issue.

423

This session is unavailable; contact support.

ratelimit-limit integer

The default limit on number of requests that can be made per hour and per minute. Current rate limits are 5000 requests per hour and 250 requests per minute.

ratelimit-remaining integer

The number of requests in your hourly quota that remain before you hit your request limit. See https://docs.digitalocean.com/reference/api/reference/#rate-limit for information about how requests expire.

ratelimit-reset integer

The time when the oldest request will expire. The value is given in Unix epoch time. See https://docs.digitalocean.com/reference/api/reference/#rate-limit for information about how requests expire.

id string required
Example: not_found

A short identifier corresponding to the HTTP status code returned. For example, the ID for a response returning a 404 status code would be "not_found."

message string required
Example: The resource you were accessing could not be found.

A message providing additional information about the error, including details to help resolve it when possible.

request_id string optional
Example: 4d9d8375-3c56-4925-a3e7-eb137fed17e9

Optionally, some endpoints may include a request ID that should be provided when reporting bugs or opening support tickets to help identify the issue.

429

The API rate limit has been exceeded.

ratelimit-limit integer

The default limit on number of requests that can be made per hour and per minute. Current rate limits are 5000 requests per hour and 250 requests per minute.

ratelimit-remaining integer

The number of requests in your hourly quota that remain before you hit your request limit. See https://docs.digitalocean.com/reference/api/reference/#rate-limit for information about how requests expire.

ratelimit-reset integer

The time when the oldest request will expire. The value is given in Unix epoch time. See https://docs.digitalocean.com/reference/api/reference/#rate-limit for information about how requests expire.

id string required
Example: not_found

A short identifier corresponding to the HTTP status code returned. For example, the ID for a response returning a 404 status code would be "not_found."

message string required
Example: The resource you were accessing could not be found.

A message providing additional information about the error, including details to help resolve it when possible.

request_id string optional
Example: 4d9d8375-3c56-4925-a3e7-eb137fed17e9

Optionally, some endpoints may include a request ID that should be provided when reporting bugs or opening support tickets to help identify the issue.

500

There was a server error.

ratelimit-limit integer

The default limit on number of requests that can be made per hour and per minute. Current rate limits are 5000 requests per hour and 250 requests per minute.

ratelimit-remaining integer

The number of requests in your hourly quota that remain before you hit your request limit. See https://docs.digitalocean.com/reference/api/reference/#rate-limit for information about how requests expire.

ratelimit-reset integer

The time when the oldest request will expire. The value is given in Unix epoch time. See https://docs.digitalocean.com/reference/api/reference/#rate-limit for information about how requests expire.

id string required
Example: not_found

A short identifier corresponding to the HTTP status code returned. For example, the ID for a response returning a 404 status code would be "not_found."

message string required
Example: The resource you were accessing could not be found.

A message providing additional information about the error, including details to help resolve it when possible.

request_id string optional
Example: 4d9d8375-3c56-4925-a3e7-eb137fed17e9

Optionally, some endpoints may include a request ID that should be provided when reporting bugs or opening support tickets to help identify the issue.

501

Pause is not supported for this session's substrate (docker/dewdrop).

ratelimit-limit integer

The default limit on number of requests that can be made per hour and per minute. Current rate limits are 5000 requests per hour and 250 requests per minute.

ratelimit-remaining integer

The number of requests in your hourly quota that remain before you hit your request limit. See https://docs.digitalocean.com/reference/api/reference/#rate-limit for information about how requests expire.

ratelimit-reset integer

The time when the oldest request will expire. The value is given in Unix epoch time. See https://docs.digitalocean.com/reference/api/reference/#rate-limit for information about how requests expire.

id string required
Example: not_found

A short identifier corresponding to the HTTP status code returned. For example, the ID for a response returning a 404 status code would be "not_found."

message string required
Example: The resource you were accessing could not be found.

A message providing additional information about the error, including details to help resolve it when possible.

request_id string optional
Example: 4d9d8375-3c56-4925-a3e7-eb137fed17e9

Optionally, some endpoints may include a request ID that should be provided when reporting bugs or opening support tickets to help identify the issue.

default

There was an unexpected error.

ratelimit-limit integer

The default limit on number of requests that can be made per hour and per minute. Current rate limits are 5000 requests per hour and 250 requests per minute.

ratelimit-remaining integer

The number of requests in your hourly quota that remain before you hit your request limit. See https://docs.digitalocean.com/reference/api/reference/#rate-limit for information about how requests expire.

ratelimit-reset integer

The time when the oldest request will expire. The value is given in Unix epoch time. See https://docs.digitalocean.com/reference/api/reference/#rate-limit for information about how requests expire.

id string required
Example: not_found

A short identifier corresponding to the HTTP status code returned. For example, the ID for a response returning a 404 status code would be "not_found."

message string required
Example: The resource you were accessing could not be found.

A message providing additional information about the error, including details to help resolve it when possible.

request_id string optional
Example: 4d9d8375-3c56-4925-a3e7-eb137fed17e9

Optionally, some endpoints may include a request ID that should be provided when reporting bugs or opening support tickets to help identify the issue.

{
  "id": "unauthorized",
  "message": "Unable to authenticate you."
}
{
  "id": "not_found",
  "message": "The resource you were accessing could not be found.",
  "request_id": "4d9d8375-3c56-4925-a3e7-eb137fed17e9"
}
{
  "id": "not_found",
  "message": "The resource you were accessing could not be found.",
  "request_id": "4d9d8375-3c56-4925-a3e7-eb137fed17e9"
}
{
  "id": "not_found",
  "message": "The resource you requested could not be found."
}
{
  "id": "not_found",
  "message": "The resource you were accessing could not be found.",
  "request_id": "4d9d8375-3c56-4925-a3e7-eb137fed17e9"
}
{
  "id": "not_found",
  "message": "The resource you were accessing could not be found.",
  "request_id": "4d9d8375-3c56-4925-a3e7-eb137fed17e9"
}
{
  "id": "too_many_requests",
  "message": "API rate limit exceeded."
}
{
  "id": "server_error",
  "message": "Unexpected server-side error"
}
{
  "id": "not_found",
  "message": "The resource you were accessing could not be found.",
  "request_id": "4d9d8375-3c56-4925-a3e7-eb137fed17e9"
}
{
  "id": "example_error",
  "message": "some error message"
}

POST ResumeSession explicitly thaws a PAUSED session's microVM sandbox.

/v2/agents/sessions/{session_id}/resume
Authorizations: bearer_auth (1 scope)
Http: Bearer
Required scopes: agent_harness_session:operate

OAuth Authentication

In order to interact with the DigitalOcean API, you or your application must authenticate.

The DigitalOcean API handles this through OAuth, an open standard for authorization. OAuth allows you to delegate access to your account. Scopes can be used to grant full access, read-only access, or access to a specific set of endpoints.

You can generate an OAuth token by visiting the Apps & API section of the DigitalOcean control panel for your account.

An OAuth token functions as a complete authentication request. In effect, it acts as a substitute for a username and password pair.

Because of this, it is absolutely essential that you keep your OAuth tokens secure. In fact, upon generation, the web interface will only display each token a single time in order to prevent the token from being compromised.

DigitalOcean access tokens begin with an identifiable prefix in order to distinguish them from other similar tokens.

  • dop_v1_ for personal access tokens generated in the control panel
  • doo_v1_ for tokens generated by applications using the OAuth flow
  • dor_v1_ for OAuth refresh tokens

Scopes

Scopes act like permissions assigned to an API token. These permissions determine what actions the token can perform. You can create API tokens that grant read-only access, full access, or limited access to specific endpoints by using custom scopes.

Generally, scopes are designed to match HTTP verbs and common CRUD operations (Create, Read, Update, Delete).

HTTP Verb CRUD Operation Scope
GET Read <resource>:read
POST Create <resource>:create
PUT/PATCH Update <resource>:update
DELETE Delete <resource>:delete

For example, creating a new Droplet by making a POST request to the /v2/droplets endpoint requires the droplet:create scope while listing Droplets by making a GET request to the /v2/droplets endpoint requires the droplet:read scope.

Each endpoint below specifies which scope is required to access it when using custom scopes.

How to Authenticate with OAuth

In order to make an authenticated request, include a bearer-type Authorization header containing your OAuth token. All requests must be made over HTTPS.

Authenticate with a Bearer Authorization Header

curl -X $HTTP_METHOD -H "Authorization: Bearer $DIGITALOCEAN_TOKEN" "https://api.digitalocean.com/v2/$OBJECT"

Only valid for microvm-substrate sessions; dewdrop/docker sessions return 501 Not Implemented. Implicit resume also occurs when SendInput or ResolveHITL is called on a paused session. Returns synchronously once the sandbox is ready.

Path Parameters

session_id string required
Example: a1b2c3d4-e5f6-7890-abcd-ef1234567890

The session UUID.

Header Parameters

X-Device-UUID string optional
Example: device-uuid-example

Optional hardware device id forwarded by doctl. Recorded for audit.

curl -X POST \
  -H "Content-Type: application/json" \
  -H "Authorization: Bearer $DIGITALOCEAN_TOKEN" \
  "https://api.digitalocean.com/v2/agents/sessions/{session_id}/resume"
curl -X POST \
  -H "Authorization: Bearer $API_TOKEN" \
  -H "Content-Type: application/json" \
  "https://api.digitalocean.com/v2/agents/sessions/{session_id}/resume"

Responses

204

Session resumed.

ratelimit-limit integer

The default limit on number of requests that can be made per hour and per minute. Current rate limits are 5000 requests per hour and 250 requests per minute.

ratelimit-remaining integer

The number of requests in your hourly quota that remain before you hit your request limit. See https://docs.digitalocean.com/reference/api/reference/#rate-limit for information about how requests expire.

ratelimit-reset integer

The time when the oldest request will expire. The value is given in Unix epoch time. See https://docs.digitalocean.com/reference/api/reference/#rate-limit for information about how requests expire.

401

Authentication failed due to invalid credentials.

ratelimit-limit integer

The default limit on number of requests that can be made per hour and per minute. Current rate limits are 5000 requests per hour and 250 requests per minute.

ratelimit-remaining integer

The number of requests in your hourly quota that remain before you hit your request limit. See https://docs.digitalocean.com/reference/api/reference/#rate-limit for information about how requests expire.

ratelimit-reset integer

The time when the oldest request will expire. The value is given in Unix epoch time. See https://docs.digitalocean.com/reference/api/reference/#rate-limit for information about how requests expire.

id string required
Example: not_found

A short identifier corresponding to the HTTP status code returned. For example, the ID for a response returning a 404 status code would be "not_found."

message string required
Example: The resource you were accessing could not be found.

A message providing additional information about the error, including details to help resolve it when possible.

request_id string optional
Example: 4d9d8375-3c56-4925-a3e7-eb137fed17e9

Optionally, some endpoints may include a request ID that should be provided when reporting bugs or opening support tickets to help identify the issue.

402

The team is blocked by the prepayment gate.

ratelimit-limit integer

The default limit on number of requests that can be made per hour and per minute. Current rate limits are 5000 requests per hour and 250 requests per minute.

ratelimit-remaining integer

The number of requests in your hourly quota that remain before you hit your request limit. See https://docs.digitalocean.com/reference/api/reference/#rate-limit for information about how requests expire.

ratelimit-reset integer

The time when the oldest request will expire. The value is given in Unix epoch time. See https://docs.digitalocean.com/reference/api/reference/#rate-limit for information about how requests expire.

id string required
Example: not_found

A short identifier corresponding to the HTTP status code returned. For example, the ID for a response returning a 404 status code would be "not_found."

message string required
Example: The resource you were accessing could not be found.

A message providing additional information about the error, including details to help resolve it when possible.

request_id string optional
Example: 4d9d8375-3c56-4925-a3e7-eb137fed17e9

Optionally, some endpoints may include a request ID that should be provided when reporting bugs or opening support tickets to help identify the issue.

403

Session belongs to another team.

ratelimit-limit integer

The default limit on number of requests that can be made per hour and per minute. Current rate limits are 5000 requests per hour and 250 requests per minute.

ratelimit-remaining integer

The number of requests in your hourly quota that remain before you hit your request limit. See https://docs.digitalocean.com/reference/api/reference/#rate-limit for information about how requests expire.

ratelimit-reset integer

The time when the oldest request will expire. The value is given in Unix epoch time. See https://docs.digitalocean.com/reference/api/reference/#rate-limit for information about how requests expire.

id string required
Example: not_found

A short identifier corresponding to the HTTP status code returned. For example, the ID for a response returning a 404 status code would be "not_found."

message string required
Example: The resource you were accessing could not be found.

A message providing additional information about the error, including details to help resolve it when possible.

request_id string optional
Example: 4d9d8375-3c56-4925-a3e7-eb137fed17e9

Optionally, some endpoints may include a request ID that should be provided when reporting bugs or opening support tickets to help identify the issue.

404

The resource was not found.

ratelimit-limit integer

The default limit on number of requests that can be made per hour and per minute. Current rate limits are 5000 requests per hour and 250 requests per minute.

ratelimit-remaining integer

The number of requests in your hourly quota that remain before you hit your request limit. See https://docs.digitalocean.com/reference/api/reference/#rate-limit for information about how requests expire.

ratelimit-reset integer

The time when the oldest request will expire. The value is given in Unix epoch time. See https://docs.digitalocean.com/reference/api/reference/#rate-limit for information about how requests expire.

id string required
Example: not_found

A short identifier corresponding to the HTTP status code returned. For example, the ID for a response returning a 404 status code would be "not_found."

message string required
Example: The resource you were accessing could not be found.

A message providing additional information about the error, including details to help resolve it when possible.

request_id string optional
Example: 4d9d8375-3c56-4925-a3e7-eb137fed17e9

Optionally, some endpoints may include a request ID that should be provided when reporting bugs or opening support tickets to help identify the issue.

409

Session is not PAUSED.

ratelimit-limit integer

The default limit on number of requests that can be made per hour and per minute. Current rate limits are 5000 requests per hour and 250 requests per minute.

ratelimit-remaining integer

The number of requests in your hourly quota that remain before you hit your request limit. See https://docs.digitalocean.com/reference/api/reference/#rate-limit for information about how requests expire.

ratelimit-reset integer

The time when the oldest request will expire. The value is given in Unix epoch time. See https://docs.digitalocean.com/reference/api/reference/#rate-limit for information about how requests expire.

id string required
Example: not_found

A short identifier corresponding to the HTTP status code returned. For example, the ID for a response returning a 404 status code would be "not_found."

message string required
Example: The resource you were accessing could not be found.

A message providing additional information about the error, including details to help resolve it when possible.

request_id string optional
Example: 4d9d8375-3c56-4925-a3e7-eb137fed17e9

Optionally, some endpoints may include a request ID that should be provided when reporting bugs or opening support tickets to help identify the issue.

423

This session is unavailable; contact support.

ratelimit-limit integer

The default limit on number of requests that can be made per hour and per minute. Current rate limits are 5000 requests per hour and 250 requests per minute.

ratelimit-remaining integer

The number of requests in your hourly quota that remain before you hit your request limit. See https://docs.digitalocean.com/reference/api/reference/#rate-limit for information about how requests expire.

ratelimit-reset integer

The time when the oldest request will expire. The value is given in Unix epoch time. See https://docs.digitalocean.com/reference/api/reference/#rate-limit for information about how requests expire.

id string required
Example: not_found

A short identifier corresponding to the HTTP status code returned. For example, the ID for a response returning a 404 status code would be "not_found."

message string required
Example: The resource you were accessing could not be found.

A message providing additional information about the error, including details to help resolve it when possible.

request_id string optional
Example: 4d9d8375-3c56-4925-a3e7-eb137fed17e9

Optionally, some endpoints may include a request ID that should be provided when reporting bugs or opening support tickets to help identify the issue.

429

The API rate limit has been exceeded.

ratelimit-limit integer

The default limit on number of requests that can be made per hour and per minute. Current rate limits are 5000 requests per hour and 250 requests per minute.

ratelimit-remaining integer

The number of requests in your hourly quota that remain before you hit your request limit. See https://docs.digitalocean.com/reference/api/reference/#rate-limit for information about how requests expire.

ratelimit-reset integer

The time when the oldest request will expire. The value is given in Unix epoch time. See https://docs.digitalocean.com/reference/api/reference/#rate-limit for information about how requests expire.

id string required
Example: not_found

A short identifier corresponding to the HTTP status code returned. For example, the ID for a response returning a 404 status code would be "not_found."

message string required
Example: The resource you were accessing could not be found.

A message providing additional information about the error, including details to help resolve it when possible.

request_id string optional
Example: 4d9d8375-3c56-4925-a3e7-eb137fed17e9

Optionally, some endpoints may include a request ID that should be provided when reporting bugs or opening support tickets to help identify the issue.

500

There was a server error.

ratelimit-limit integer

The default limit on number of requests that can be made per hour and per minute. Current rate limits are 5000 requests per hour and 250 requests per minute.

ratelimit-remaining integer

The number of requests in your hourly quota that remain before you hit your request limit. See https://docs.digitalocean.com/reference/api/reference/#rate-limit for information about how requests expire.

ratelimit-reset integer

The time when the oldest request will expire. The value is given in Unix epoch time. See https://docs.digitalocean.com/reference/api/reference/#rate-limit for information about how requests expire.

id string required
Example: not_found

A short identifier corresponding to the HTTP status code returned. For example, the ID for a response returning a 404 status code would be "not_found."

message string required
Example: The resource you were accessing could not be found.

A message providing additional information about the error, including details to help resolve it when possible.

request_id string optional
Example: 4d9d8375-3c56-4925-a3e7-eb137fed17e9

Optionally, some endpoints may include a request ID that should be provided when reporting bugs or opening support tickets to help identify the issue.

501

Resume is not supported for this session's substrate (docker/dewdrop).

ratelimit-limit integer

The default limit on number of requests that can be made per hour and per minute. Current rate limits are 5000 requests per hour and 250 requests per minute.

ratelimit-remaining integer

The number of requests in your hourly quota that remain before you hit your request limit. See https://docs.digitalocean.com/reference/api/reference/#rate-limit for information about how requests expire.

ratelimit-reset integer

The time when the oldest request will expire. The value is given in Unix epoch time. See https://docs.digitalocean.com/reference/api/reference/#rate-limit for information about how requests expire.

id string required
Example: not_found

A short identifier corresponding to the HTTP status code returned. For example, the ID for a response returning a 404 status code would be "not_found."

message string required
Example: The resource you were accessing could not be found.

A message providing additional information about the error, including details to help resolve it when possible.

request_id string optional
Example: 4d9d8375-3c56-4925-a3e7-eb137fed17e9

Optionally, some endpoints may include a request ID that should be provided when reporting bugs or opening support tickets to help identify the issue.

default

There was an unexpected error.

ratelimit-limit integer

The default limit on number of requests that can be made per hour and per minute. Current rate limits are 5000 requests per hour and 250 requests per minute.

ratelimit-remaining integer

The number of requests in your hourly quota that remain before you hit your request limit. See https://docs.digitalocean.com/reference/api/reference/#rate-limit for information about how requests expire.

ratelimit-reset integer

The time when the oldest request will expire. The value is given in Unix epoch time. See https://docs.digitalocean.com/reference/api/reference/#rate-limit for information about how requests expire.

id string required
Example: not_found

A short identifier corresponding to the HTTP status code returned. For example, the ID for a response returning a 404 status code would be "not_found."

message string required
Example: The resource you were accessing could not be found.

A message providing additional information about the error, including details to help resolve it when possible.

request_id string optional
Example: 4d9d8375-3c56-4925-a3e7-eb137fed17e9

Optionally, some endpoints may include a request ID that should be provided when reporting bugs or opening support tickets to help identify the issue.

{
  "id": "unauthorized",
  "message": "Unable to authenticate you."
}
{
  "id": "not_found",
  "message": "The resource you were accessing could not be found.",
  "request_id": "4d9d8375-3c56-4925-a3e7-eb137fed17e9"
}
{
  "id": "not_found",
  "message": "The resource you were accessing could not be found.",
  "request_id": "4d9d8375-3c56-4925-a3e7-eb137fed17e9"
}
{
  "id": "not_found",
  "message": "The resource you requested could not be found."
}
{
  "id": "not_found",
  "message": "The resource you were accessing could not be found.",
  "request_id": "4d9d8375-3c56-4925-a3e7-eb137fed17e9"
}
{
  "id": "not_found",
  "message": "The resource you were accessing could not be found.",
  "request_id": "4d9d8375-3c56-4925-a3e7-eb137fed17e9"
}
{
  "id": "too_many_requests",
  "message": "API rate limit exceeded."
}
{
  "id": "server_error",
  "message": "Unexpected server-side error"
}
{
  "id": "not_found",
  "message": "The resource you were accessing could not be found.",
  "request_id": "4d9d8375-3c56-4925-a3e7-eb137fed17e9"
}
{
  "id": "example_error",
  "message": "some error message"
}

POST ExecInSandbox runs a one-shot command inside the session's sandbox.

/v2/agents/sessions/{session_id}/sandbox/exec
Authorizations: bearer_auth (1 scope)
Http: Bearer
Required scopes: agent_harness_session:operate

OAuth Authentication

In order to interact with the DigitalOcean API, you or your application must authenticate.

The DigitalOcean API handles this through OAuth, an open standard for authorization. OAuth allows you to delegate access to your account. Scopes can be used to grant full access, read-only access, or access to a specific set of endpoints.

You can generate an OAuth token by visiting the Apps & API section of the DigitalOcean control panel for your account.

An OAuth token functions as a complete authentication request. In effect, it acts as a substitute for a username and password pair.

Because of this, it is absolutely essential that you keep your OAuth tokens secure. In fact, upon generation, the web interface will only display each token a single time in order to prevent the token from being compromised.

DigitalOcean access tokens begin with an identifiable prefix in order to distinguish them from other similar tokens.

  • dop_v1_ for personal access tokens generated in the control panel
  • doo_v1_ for tokens generated by applications using the OAuth flow
  • dor_v1_ for OAuth refresh tokens

Scopes

Scopes act like permissions assigned to an API token. These permissions determine what actions the token can perform. You can create API tokens that grant read-only access, full access, or limited access to specific endpoints by using custom scopes.

Generally, scopes are designed to match HTTP verbs and common CRUD operations (Create, Read, Update, Delete).

HTTP Verb CRUD Operation Scope
GET Read <resource>:read
POST Create <resource>:create
PUT/PATCH Update <resource>:update
DELETE Delete <resource>:delete

For example, creating a new Droplet by making a POST request to the /v2/droplets endpoint requires the droplet:create scope while listing Droplets by making a GET request to the /v2/droplets endpoint requires the droplet:read scope.

Each endpoint below specifies which scope is required to access it when using custom scopes.

How to Authenticate with OAuth

In order to make an authenticated request, include a bearer-type Authorization header containing your OAuth token. All requests must be made over HTTPS.

Authenticate with a Bearer Authorization Header

curl -X $HTTP_METHOD -H "Authorization: Bearer $DIGITALOCEAN_TOKEN" "https://api.digitalocean.com/v2/$OBJECT"

Runs argv directly in the guest (no shell). Stdout/stderr are buffered and capped at 1 MiB each; truncation is indicated via response headers when present. A non-zero exit code is still HTTP 200.

Path Parameters

session_id string required
Example: a1b2c3d4-e5f6-7890-abcd-ef1234567890

The session UUID.

Request Body: application/json

Command to run inside the sandbox.

argv array of string required
Example: ["uname","-a"]

Program and arguments. Required and non-empty; run directly, with no shell interpretation.

stdin string (byte) optional

Optional base64 stdin payload, delivered in full and then closed so the process sees EOF. One-shot only — there is no streaming stdin on this endpoint.

timeout_seconds integer (int64) optional
Example: 60

Optional timeout. Clamped server-side (default 60, maximum 240) regardless of the value sent.

workdir string optional
Example: /workspace

Working directory inside the sandbox. Empty uses the sandbox default (/workspace); not restricted to the workspace root.

Content type application/json
{
  "argv": [
    "uname",
    "-a"
  ],
  "stdin": "",
  "timeout_seconds": 60,
  "workdir": "/workspace"
}
curl -X POST \
  -H "Content-Type: application/json" \
  -H "Authorization: Bearer $DIGITALOCEAN_TOKEN" \
  -d '{"argv":["uname","-a"]}' \
  "https://api.digitalocean.com/v2/agents/sessions/{session_id}/sandbox/exec"
curl -X POST \
  -H "Authorization: Bearer $API_TOKEN" \
  -H "Content-Type: application/json" \
  -d '{
  "argv": [
    "uname",
    "-a"
  ],
  "stdin": "",
  "timeout_seconds": 60,
  "workdir": "/workspace"
}' \
  "https://api.digitalocean.com/v2/agents/sessions/{session_id}/sandbox/exec"

Responses

200

Command finished (check exit_code in the body).

ratelimit-limit integer

The default limit on number of requests that can be made per hour and per minute. Current rate limits are 5000 requests per hour and 250 requests per minute.

ratelimit-remaining integer

The number of requests in your hourly quota that remain before you hit your request limit. See https://docs.digitalocean.com/reference/api/reference/#rate-limit for information about how requests expire.

ratelimit-reset integer

The time when the oldest request will expire. The value is given in Unix epoch time. See https://docs.digitalocean.com/reference/api/reference/#rate-limit for information about how requests expire.

duration_ms integer (int64) optional
Example: 12

Wall-clock duration the guest reported for the command.

exit_code integer (int32) optional
Example: 0

The guest process's exit code. Non-zero is still a 200 response.

stderr string optional

Buffered stderr, capped at 1 MiB. Check X-Exec-Stderr-Truncated for drops.

stdout string optional
Example: Linux

Buffered stdout, capped at 1 MiB. Check X-Exec-Stdout-Truncated for drops.

400

Invalid argv or request body.

ratelimit-limit integer

The default limit on number of requests that can be made per hour and per minute. Current rate limits are 5000 requests per hour and 250 requests per minute.

ratelimit-remaining integer

The number of requests in your hourly quota that remain before you hit your request limit. See https://docs.digitalocean.com/reference/api/reference/#rate-limit for information about how requests expire.

ratelimit-reset integer

The time when the oldest request will expire. The value is given in Unix epoch time. See https://docs.digitalocean.com/reference/api/reference/#rate-limit for information about how requests expire.

id string required
Example: not_found

A short identifier corresponding to the HTTP status code returned. For example, the ID for a response returning a 404 status code would be "not_found."

message string required
Example: The resource you were accessing could not be found.

A message providing additional information about the error, including details to help resolve it when possible.

request_id string optional
Example: 4d9d8375-3c56-4925-a3e7-eb137fed17e9

Optionally, some endpoints may include a request ID that should be provided when reporting bugs or opening support tickets to help identify the issue.

401

Authentication failed due to invalid credentials.

ratelimit-limit integer

The default limit on number of requests that can be made per hour and per minute. Current rate limits are 5000 requests per hour and 250 requests per minute.

ratelimit-remaining integer

The number of requests in your hourly quota that remain before you hit your request limit. See https://docs.digitalocean.com/reference/api/reference/#rate-limit for information about how requests expire.

ratelimit-reset integer

The time when the oldest request will expire. The value is given in Unix epoch time. See https://docs.digitalocean.com/reference/api/reference/#rate-limit for information about how requests expire.

id string required
Example: not_found

A short identifier corresponding to the HTTP status code returned. For example, the ID for a response returning a 404 status code would be "not_found."

message string required
Example: The resource you were accessing could not be found.

A message providing additional information about the error, including details to help resolve it when possible.

request_id string optional
Example: 4d9d8375-3c56-4925-a3e7-eb137fed17e9

Optionally, some endpoints may include a request ID that should be provided when reporting bugs or opening support tickets to help identify the issue.

402

The team is blocked by the prepayment gate.

ratelimit-limit integer

The default limit on number of requests that can be made per hour and per minute. Current rate limits are 5000 requests per hour and 250 requests per minute.

ratelimit-remaining integer

The number of requests in your hourly quota that remain before you hit your request limit. See https://docs.digitalocean.com/reference/api/reference/#rate-limit for information about how requests expire.

ratelimit-reset integer

The time when the oldest request will expire. The value is given in Unix epoch time. See https://docs.digitalocean.com/reference/api/reference/#rate-limit for information about how requests expire.

id string required
Example: not_found

A short identifier corresponding to the HTTP status code returned. For example, the ID for a response returning a 404 status code would be "not_found."

message string required
Example: The resource you were accessing could not be found.

A message providing additional information about the error, including details to help resolve it when possible.

request_id string optional
Example: 4d9d8375-3c56-4925-a3e7-eb137fed17e9

Optionally, some endpoints may include a request ID that should be provided when reporting bugs or opening support tickets to help identify the issue.

403

Session belongs to another team.

ratelimit-limit integer

The default limit on number of requests that can be made per hour and per minute. Current rate limits are 5000 requests per hour and 250 requests per minute.

ratelimit-remaining integer

The number of requests in your hourly quota that remain before you hit your request limit. See https://docs.digitalocean.com/reference/api/reference/#rate-limit for information about how requests expire.

ratelimit-reset integer

The time when the oldest request will expire. The value is given in Unix epoch time. See https://docs.digitalocean.com/reference/api/reference/#rate-limit for information about how requests expire.

id string required
Example: not_found

A short identifier corresponding to the HTTP status code returned. For example, the ID for a response returning a 404 status code would be "not_found."

message string required
Example: The resource you were accessing could not be found.

A message providing additional information about the error, including details to help resolve it when possible.

request_id string optional
Example: 4d9d8375-3c56-4925-a3e7-eb137fed17e9

Optionally, some endpoints may include a request ID that should be provided when reporting bugs or opening support tickets to help identify the issue.

404

The resource was not found.

ratelimit-limit integer

The default limit on number of requests that can be made per hour and per minute. Current rate limits are 5000 requests per hour and 250 requests per minute.

ratelimit-remaining integer

The number of requests in your hourly quota that remain before you hit your request limit. See https://docs.digitalocean.com/reference/api/reference/#rate-limit for information about how requests expire.

ratelimit-reset integer

The time when the oldest request will expire. The value is given in Unix epoch time. See https://docs.digitalocean.com/reference/api/reference/#rate-limit for information about how requests expire.

id string required
Example: not_found

A short identifier corresponding to the HTTP status code returned. For example, the ID for a response returning a 404 status code would be "not_found."

message string required
Example: The resource you were accessing could not be found.

A message providing additional information about the error, including details to help resolve it when possible.

request_id string optional
Example: 4d9d8375-3c56-4925-a3e7-eb137fed17e9

Optionally, some endpoints may include a request ID that should be provided when reporting bugs or opening support tickets to help identify the issue.

409

Session is not in a state that can run exec.

ratelimit-limit integer

The default limit on number of requests that can be made per hour and per minute. Current rate limits are 5000 requests per hour and 250 requests per minute.

ratelimit-remaining integer

The number of requests in your hourly quota that remain before you hit your request limit. See https://docs.digitalocean.com/reference/api/reference/#rate-limit for information about how requests expire.

ratelimit-reset integer

The time when the oldest request will expire. The value is given in Unix epoch time. See https://docs.digitalocean.com/reference/api/reference/#rate-limit for information about how requests expire.

id string required
Example: not_found

A short identifier corresponding to the HTTP status code returned. For example, the ID for a response returning a 404 status code would be "not_found."

message string required
Example: The resource you were accessing could not be found.

A message providing additional information about the error, including details to help resolve it when possible.

request_id string optional
Example: 4d9d8375-3c56-4925-a3e7-eb137fed17e9

Optionally, some endpoints may include a request ID that should be provided when reporting bugs or opening support tickets to help identify the issue.

423

This session is unavailable; contact support.

ratelimit-limit integer

The default limit on number of requests that can be made per hour and per minute. Current rate limits are 5000 requests per hour and 250 requests per minute.

ratelimit-remaining integer

The number of requests in your hourly quota that remain before you hit your request limit. See https://docs.digitalocean.com/reference/api/reference/#rate-limit for information about how requests expire.

ratelimit-reset integer

The time when the oldest request will expire. The value is given in Unix epoch time. See https://docs.digitalocean.com/reference/api/reference/#rate-limit for information about how requests expire.

id string required
Example: not_found

A short identifier corresponding to the HTTP status code returned. For example, the ID for a response returning a 404 status code would be "not_found."

message string required
Example: The resource you were accessing could not be found.

A message providing additional information about the error, including details to help resolve it when possible.

request_id string optional
Example: 4d9d8375-3c56-4925-a3e7-eb137fed17e9

Optionally, some endpoints may include a request ID that should be provided when reporting bugs or opening support tickets to help identify the issue.

429

The API rate limit has been exceeded.

ratelimit-limit integer

The default limit on number of requests that can be made per hour and per minute. Current rate limits are 5000 requests per hour and 250 requests per minute.

ratelimit-remaining integer

The number of requests in your hourly quota that remain before you hit your request limit. See https://docs.digitalocean.com/reference/api/reference/#rate-limit for information about how requests expire.

ratelimit-reset integer

The time when the oldest request will expire. The value is given in Unix epoch time. See https://docs.digitalocean.com/reference/api/reference/#rate-limit for information about how requests expire.

id string required
Example: not_found

A short identifier corresponding to the HTTP status code returned. For example, the ID for a response returning a 404 status code would be "not_found."

message string required
Example: The resource you were accessing could not be found.

A message providing additional information about the error, including details to help resolve it when possible.

request_id string optional
Example: 4d9d8375-3c56-4925-a3e7-eb137fed17e9

Optionally, some endpoints may include a request ID that should be provided when reporting bugs or opening support tickets to help identify the issue.

500

There was a server error.

ratelimit-limit integer

The default limit on number of requests that can be made per hour and per minute. Current rate limits are 5000 requests per hour and 250 requests per minute.

ratelimit-remaining integer

The number of requests in your hourly quota that remain before you hit your request limit. See https://docs.digitalocean.com/reference/api/reference/#rate-limit for information about how requests expire.

ratelimit-reset integer

The time when the oldest request will expire. The value is given in Unix epoch time. See https://docs.digitalocean.com/reference/api/reference/#rate-limit for information about how requests expire.

id string required
Example: not_found

A short identifier corresponding to the HTTP status code returned. For example, the ID for a response returning a 404 status code would be "not_found."

message string required
Example: The resource you were accessing could not be found.

A message providing additional information about the error, including details to help resolve it when possible.

request_id string optional
Example: 4d9d8375-3c56-4925-a3e7-eb137fed17e9

Optionally, some endpoints may include a request ID that should be provided when reporting bugs or opening support tickets to help identify the issue.

default

There was an unexpected error.

ratelimit-limit integer

The default limit on number of requests that can be made per hour and per minute. Current rate limits are 5000 requests per hour and 250 requests per minute.

ratelimit-remaining integer

The number of requests in your hourly quota that remain before you hit your request limit. See https://docs.digitalocean.com/reference/api/reference/#rate-limit for information about how requests expire.

ratelimit-reset integer

The time when the oldest request will expire. The value is given in Unix epoch time. See https://docs.digitalocean.com/reference/api/reference/#rate-limit for information about how requests expire.

id string required
Example: not_found

A short identifier corresponding to the HTTP status code returned. For example, the ID for a response returning a 404 status code would be "not_found."

message string required
Example: The resource you were accessing could not be found.

A message providing additional information about the error, including details to help resolve it when possible.

request_id string optional
Example: 4d9d8375-3c56-4925-a3e7-eb137fed17e9

Optionally, some endpoints may include a request ID that should be provided when reporting bugs or opening support tickets to help identify the issue.

{
  "duration_ms": 12,
  "exit_code": 0,
  "stderr": "",
  "stdout": "Linux"
}
{
  "id": "not_found",
  "message": "The resource you were accessing could not be found.",
  "request_id": "4d9d8375-3c56-4925-a3e7-eb137fed17e9"
}
{
  "id": "unauthorized",
  "message": "Unable to authenticate you."
}
{
  "id": "not_found",
  "message": "The resource you were accessing could not be found.",
  "request_id": "4d9d8375-3c56-4925-a3e7-eb137fed17e9"
}
{
  "id": "not_found",
  "message": "The resource you were accessing could not be found.",
  "request_id": "4d9d8375-3c56-4925-a3e7-eb137fed17e9"
}
{
  "id": "not_found",
  "message": "The resource you requested could not be found."
}
{
  "id": "not_found",
  "message": "The resource you were accessing could not be found.",
  "request_id": "4d9d8375-3c56-4925-a3e7-eb137fed17e9"
}
{
  "id": "not_found",
  "message": "The resource you were accessing could not be found.",
  "request_id": "4d9d8375-3c56-4925-a3e7-eb137fed17e9"
}
{
  "id": "too_many_requests",
  "message": "API rate limit exceeded."
}
{
  "id": "server_error",
  "message": "Unexpected server-side error"
}
{
  "id": "example_error",
  "message": "some error message"
}

GET Download a file or tar archive from the session's sandbox workspace.

/v2/agents/sessions/{session_id}/workspace/download
Authorizations: bearer_auth (1 scope)
Http: Bearer
Required scopes: agent_harness_session:read

OAuth Authentication

In order to interact with the DigitalOcean API, you or your application must authenticate.

The DigitalOcean API handles this through OAuth, an open standard for authorization. OAuth allows you to delegate access to your account. Scopes can be used to grant full access, read-only access, or access to a specific set of endpoints.

You can generate an OAuth token by visiting the Apps & API section of the DigitalOcean control panel for your account.

An OAuth token functions as a complete authentication request. In effect, it acts as a substitute for a username and password pair.

Because of this, it is absolutely essential that you keep your OAuth tokens secure. In fact, upon generation, the web interface will only display each token a single time in order to prevent the token from being compromised.

DigitalOcean access tokens begin with an identifiable prefix in order to distinguish them from other similar tokens.

  • dop_v1_ for personal access tokens generated in the control panel
  • doo_v1_ for tokens generated by applications using the OAuth flow
  • dor_v1_ for OAuth refresh tokens

Scopes

Scopes act like permissions assigned to an API token. These permissions determine what actions the token can perform. You can create API tokens that grant read-only access, full access, or limited access to specific endpoints by using custom scopes.

Generally, scopes are designed to match HTTP verbs and common CRUD operations (Create, Read, Update, Delete).

HTTP Verb CRUD Operation Scope
GET Read <resource>:read
POST Create <resource>:create
PUT/PATCH Update <resource>:update
DELETE Delete <resource>:delete

For example, creating a new Droplet by making a POST request to the /v2/droplets endpoint requires the droplet:create scope while listing Droplets by making a GET request to the /v2/droplets endpoint requires the droplet:read scope.

Each endpoint below specifies which scope is required to access it when using custom scopes.

How to Authenticate with OAuth

In order to make an authenticated request, include a bearer-type Authorization header containing your OAuth token. All requests must be made over HTTPS.

Authenticate with a Bearer Authorization Header

curl -X $HTTP_METHOD -H "Authorization: Bearer $DIGITALOCEAN_TOKEN" "https://api.digitalocean.com/v2/$OBJECT"

Streams the workspace payload back as application/octet-stream using chunked transfer encoding, followed by a fixed integrity footer.

Response body layout: <payload> + <footer>, where the footer is exactly 73 bytes: DOWSSHA1 (8 bytes) + 64-char lowercase SHA-256 hex + \n. The client MUST strip the trailing 73 bytes before saving, verify SHA-256(payload) equals the footer digest, and treat a tail that does not match this shape (magic + 64 hex + newline) as a failed (truncated/corrupt) transfer.

Other metadata:

  • X-Workspace-Is-Archive: true when the payload is a tar archive.
  • X-Workspace-Size-Bytes is a progress hint (not Content-Length) and excludes the footer.
  • The X-Content-Sha256 trailer also carries the digest but is best-effort: edge proxies may strip HTTP trailers, so the body footer is authoritative.

Concurrent transfers (upload + download) are capped server-side; over the cap the request blocks and may return 503.

Path Parameters

session_id string required
Example: a1b2c3d4-e5f6-7890-abcd-ef1234567890

The session UUID.

Query Parameters

path string required
Example: example

Source path inside the sandbox workspace. Relative paths resolve under the workspace root; paths that escape the workspace are rejected. Required.

as_archive boolean optional
Example: true

If true, the guest returns a tar stream of path (e.g. for a directory). Defaults to false (single file).

curl -X GET \
  -H "Content-Type: application/json" \
  -H "Authorization: Bearer $DIGITALOCEAN_TOKEN" \
  "https://api.digitalocean.com/v2/agents/sessions/{session_id}/workspace/download"
curl -X GET \
  -H "Authorization: Bearer $API_TOKEN" \
  "https://api.digitalocean.com/v2/agents/sessions/{session_id}/workspace/download"

Responses

200

Streaming workspace payload (octet-stream) followed by a fixed 73-byte integrity footer (DOWSSHA1 + 64-char sha256 hex + newline). The digest is also delivered best-effort in the X-Content-Sha256 trailer.

ratelimit-limit integer

The default limit on number of requests that can be made per hour and per minute. Current rate limits are 5000 requests per hour and 250 requests per minute.

ratelimit-remaining integer

The number of requests in your hourly quota that remain before you hit your request limit. See https://docs.digitalocean.com/reference/api/reference/#rate-limit for information about how requests expire.

ratelimit-reset integer

The time when the oldest request will expire. The value is given in Unix epoch time. See https://docs.digitalocean.com/reference/api/reference/#rate-limit for information about how requests expire.

400

Missing path, invalid query parameter, or invalid path.

ratelimit-limit integer

The default limit on number of requests that can be made per hour and per minute. Current rate limits are 5000 requests per hour and 250 requests per minute.

ratelimit-remaining integer

The number of requests in your hourly quota that remain before you hit your request limit. See https://docs.digitalocean.com/reference/api/reference/#rate-limit for information about how requests expire.

ratelimit-reset integer

The time when the oldest request will expire. The value is given in Unix epoch time. See https://docs.digitalocean.com/reference/api/reference/#rate-limit for information about how requests expire.

id string required
Example: not_found

A short identifier corresponding to the HTTP status code returned. For example, the ID for a response returning a 404 status code would be "not_found."

message string required
Example: The resource you were accessing could not be found.

A message providing additional information about the error, including details to help resolve it when possible.

request_id string optional
Example: 4d9d8375-3c56-4925-a3e7-eb137fed17e9

Optionally, some endpoints may include a request ID that should be provided when reporting bugs or opening support tickets to help identify the issue.

401

Authentication failed due to invalid credentials.

ratelimit-limit integer

The default limit on number of requests that can be made per hour and per minute. Current rate limits are 5000 requests per hour and 250 requests per minute.

ratelimit-remaining integer

The number of requests in your hourly quota that remain before you hit your request limit. See https://docs.digitalocean.com/reference/api/reference/#rate-limit for information about how requests expire.

ratelimit-reset integer

The time when the oldest request will expire. The value is given in Unix epoch time. See https://docs.digitalocean.com/reference/api/reference/#rate-limit for information about how requests expire.

id string required
Example: not_found

A short identifier corresponding to the HTTP status code returned. For example, the ID for a response returning a 404 status code would be "not_found."

message string required
Example: The resource you were accessing could not be found.

A message providing additional information about the error, including details to help resolve it when possible.

request_id string optional
Example: 4d9d8375-3c56-4925-a3e7-eb137fed17e9

Optionally, some endpoints may include a request ID that should be provided when reporting bugs or opening support tickets to help identify the issue.

403

Path resolves outside the workspace, or the session belongs to another team.

ratelimit-limit integer

The default limit on number of requests that can be made per hour and per minute. Current rate limits are 5000 requests per hour and 250 requests per minute.

ratelimit-remaining integer

The number of requests in your hourly quota that remain before you hit your request limit. See https://docs.digitalocean.com/reference/api/reference/#rate-limit for information about how requests expire.

ratelimit-reset integer

The time when the oldest request will expire. The value is given in Unix epoch time. See https://docs.digitalocean.com/reference/api/reference/#rate-limit for information about how requests expire.

id string required
Example: not_found

A short identifier corresponding to the HTTP status code returned. For example, the ID for a response returning a 404 status code would be "not_found."

message string required
Example: The resource you were accessing could not be found.

A message providing additional information about the error, including details to help resolve it when possible.

request_id string optional
Example: 4d9d8375-3c56-4925-a3e7-eb137fed17e9

Optionally, some endpoints may include a request ID that should be provided when reporting bugs or opening support tickets to help identify the issue.

404

The resource was not found.

ratelimit-limit integer

The default limit on number of requests that can be made per hour and per minute. Current rate limits are 5000 requests per hour and 250 requests per minute.

ratelimit-remaining integer

The number of requests in your hourly quota that remain before you hit your request limit. See https://docs.digitalocean.com/reference/api/reference/#rate-limit for information about how requests expire.

ratelimit-reset integer

The time when the oldest request will expire. The value is given in Unix epoch time. See https://docs.digitalocean.com/reference/api/reference/#rate-limit for information about how requests expire.

id string required
Example: not_found

A short identifier corresponding to the HTTP status code returned. For example, the ID for a response returning a 404 status code would be "not_found."

message string required
Example: The resource you were accessing could not be found.

A message providing additional information about the error, including details to help resolve it when possible.

request_id string optional
Example: 4d9d8375-3c56-4925-a3e7-eb137fed17e9

Optionally, some endpoints may include a request ID that should be provided when reporting bugs or opening support tickets to help identify the issue.

409

Session has no sandbox, or the sandbox is not ready.

ratelimit-limit integer

The default limit on number of requests that can be made per hour and per minute. Current rate limits are 5000 requests per hour and 250 requests per minute.

ratelimit-remaining integer

The number of requests in your hourly quota that remain before you hit your request limit. See https://docs.digitalocean.com/reference/api/reference/#rate-limit for information about how requests expire.

ratelimit-reset integer

The time when the oldest request will expire. The value is given in Unix epoch time. See https://docs.digitalocean.com/reference/api/reference/#rate-limit for information about how requests expire.

id string required
Example: not_found

A short identifier corresponding to the HTTP status code returned. For example, the ID for a response returning a 404 status code would be "not_found."

message string required
Example: The resource you were accessing could not be found.

A message providing additional information about the error, including details to help resolve it when possible.

request_id string optional
Example: 4d9d8375-3c56-4925-a3e7-eb137fed17e9

Optionally, some endpoints may include a request ID that should be provided when reporting bugs or opening support tickets to help identify the issue.

423

This session is unavailable; contact support.

ratelimit-limit integer

The default limit on number of requests that can be made per hour and per minute. Current rate limits are 5000 requests per hour and 250 requests per minute.

ratelimit-remaining integer

The number of requests in your hourly quota that remain before you hit your request limit. See https://docs.digitalocean.com/reference/api/reference/#rate-limit for information about how requests expire.

ratelimit-reset integer

The time when the oldest request will expire. The value is given in Unix epoch time. See https://docs.digitalocean.com/reference/api/reference/#rate-limit for information about how requests expire.

id string required
Example: not_found

A short identifier corresponding to the HTTP status code returned. For example, the ID for a response returning a 404 status code would be "not_found."

message string required
Example: The resource you were accessing could not be found.

A message providing additional information about the error, including details to help resolve it when possible.

request_id string optional
Example: 4d9d8375-3c56-4925-a3e7-eb137fed17e9

Optionally, some endpoints may include a request ID that should be provided when reporting bugs or opening support tickets to help identify the issue.

429

The API rate limit has been exceeded.

ratelimit-limit integer

The default limit on number of requests that can be made per hour and per minute. Current rate limits are 5000 requests per hour and 250 requests per minute.

ratelimit-remaining integer

The number of requests in your hourly quota that remain before you hit your request limit. See https://docs.digitalocean.com/reference/api/reference/#rate-limit for information about how requests expire.

ratelimit-reset integer

The time when the oldest request will expire. The value is given in Unix epoch time. See https://docs.digitalocean.com/reference/api/reference/#rate-limit for information about how requests expire.

id string required
Example: not_found

A short identifier corresponding to the HTTP status code returned. For example, the ID for a response returning a 404 status code would be "not_found."

message string required
Example: The resource you were accessing could not be found.

A message providing additional information about the error, including details to help resolve it when possible.

request_id string optional
Example: 4d9d8375-3c56-4925-a3e7-eb137fed17e9

Optionally, some endpoints may include a request ID that should be provided when reporting bugs or opening support tickets to help identify the issue.

500

There was a server error.

ratelimit-limit integer

The default limit on number of requests that can be made per hour and per minute. Current rate limits are 5000 requests per hour and 250 requests per minute.

ratelimit-remaining integer

The number of requests in your hourly quota that remain before you hit your request limit. See https://docs.digitalocean.com/reference/api/reference/#rate-limit for information about how requests expire.

ratelimit-reset integer

The time when the oldest request will expire. The value is given in Unix epoch time. See https://docs.digitalocean.com/reference/api/reference/#rate-limit for information about how requests expire.

id string required
Example: not_found

A short identifier corresponding to the HTTP status code returned. For example, the ID for a response returning a 404 status code would be "not_found."

message string required
Example: The resource you were accessing could not be found.

A message providing additional information about the error, including details to help resolve it when possible.

request_id string optional
Example: 4d9d8375-3c56-4925-a3e7-eb137fed17e9

Optionally, some endpoints may include a request ID that should be provided when reporting bugs or opening support tickets to help identify the issue.

501

Workspace file transfer is not supported by the active sandbox driver.

ratelimit-limit integer

The default limit on number of requests that can be made per hour and per minute. Current rate limits are 5000 requests per hour and 250 requests per minute.

ratelimit-remaining integer

The number of requests in your hourly quota that remain before you hit your request limit. See https://docs.digitalocean.com/reference/api/reference/#rate-limit for information about how requests expire.

ratelimit-reset integer

The time when the oldest request will expire. The value is given in Unix epoch time. See https://docs.digitalocean.com/reference/api/reference/#rate-limit for information about how requests expire.

id string required
Example: not_found

A short identifier corresponding to the HTTP status code returned. For example, the ID for a response returning a 404 status code would be "not_found."

message string required
Example: The resource you were accessing could not be found.

A message providing additional information about the error, including details to help resolve it when possible.

request_id string optional
Example: 4d9d8375-3c56-4925-a3e7-eb137fed17e9

Optionally, some endpoints may include a request ID that should be provided when reporting bugs or opening support tickets to help identify the issue.

502

Upstream sandbox transfer failed.

ratelimit-limit integer

The default limit on number of requests that can be made per hour and per minute. Current rate limits are 5000 requests per hour and 250 requests per minute.

ratelimit-remaining integer

The number of requests in your hourly quota that remain before you hit your request limit. See https://docs.digitalocean.com/reference/api/reference/#rate-limit for information about how requests expire.

ratelimit-reset integer

The time when the oldest request will expire. The value is given in Unix epoch time. See https://docs.digitalocean.com/reference/api/reference/#rate-limit for information about how requests expire.

id string required
Example: not_found

A short identifier corresponding to the HTTP status code returned. For example, the ID for a response returning a 404 status code would be "not_found."

message string required
Example: The resource you were accessing could not be found.

A message providing additional information about the error, including details to help resolve it when possible.

request_id string optional
Example: 4d9d8375-3c56-4925-a3e7-eb137fed17e9

Optionally, some endpoints may include a request ID that should be provided when reporting bugs or opening support tickets to help identify the issue.

503

Workspace transfer capacity exhausted; retry later.

ratelimit-limit integer

The default limit on number of requests that can be made per hour and per minute. Current rate limits are 5000 requests per hour and 250 requests per minute.

ratelimit-remaining integer

The number of requests in your hourly quota that remain before you hit your request limit. See https://docs.digitalocean.com/reference/api/reference/#rate-limit for information about how requests expire.

ratelimit-reset integer

The time when the oldest request will expire. The value is given in Unix epoch time. See https://docs.digitalocean.com/reference/api/reference/#rate-limit for information about how requests expire.

id string required
Example: not_found

A short identifier corresponding to the HTTP status code returned. For example, the ID for a response returning a 404 status code would be "not_found."

message string required
Example: The resource you were accessing could not be found.

A message providing additional information about the error, including details to help resolve it when possible.

request_id string optional
Example: 4d9d8375-3c56-4925-a3e7-eb137fed17e9

Optionally, some endpoints may include a request ID that should be provided when reporting bugs or opening support tickets to help identify the issue.

default

There was an unexpected error.

ratelimit-limit integer

The default limit on number of requests that can be made per hour and per minute. Current rate limits are 5000 requests per hour and 250 requests per minute.

ratelimit-remaining integer

The number of requests in your hourly quota that remain before you hit your request limit. See https://docs.digitalocean.com/reference/api/reference/#rate-limit for information about how requests expire.

ratelimit-reset integer

The time when the oldest request will expire. The value is given in Unix epoch time. See https://docs.digitalocean.com/reference/api/reference/#rate-limit for information about how requests expire.

id string required
Example: not_found

A short identifier corresponding to the HTTP status code returned. For example, the ID for a response returning a 404 status code would be "not_found."

message string required
Example: The resource you were accessing could not be found.

A message providing additional information about the error, including details to help resolve it when possible.

request_id string optional
Example: 4d9d8375-3c56-4925-a3e7-eb137fed17e9

Optionally, some endpoints may include a request ID that should be provided when reporting bugs or opening support tickets to help identify the issue.

{
  "id": "not_found",
  "message": "The resource you were accessing could not be found.",
  "request_id": "4d9d8375-3c56-4925-a3e7-eb137fed17e9"
}
{
  "id": "unauthorized",
  "message": "Unable to authenticate you."
}
{
  "id": "not_found",
  "message": "The resource you were accessing could not be found.",
  "request_id": "4d9d8375-3c56-4925-a3e7-eb137fed17e9"
}
{
  "id": "not_found",
  "message": "The resource you requested could not be found."
}
{
  "id": "not_found",
  "message": "The resource you were accessing could not be found.",
  "request_id": "4d9d8375-3c56-4925-a3e7-eb137fed17e9"
}
{
  "id": "not_found",
  "message": "The resource you were accessing could not be found.",
  "request_id": "4d9d8375-3c56-4925-a3e7-eb137fed17e9"
}
{
  "id": "too_many_requests",
  "message": "API rate limit exceeded."
}
{
  "id": "server_error",
  "message": "Unexpected server-side error"
}
{
  "id": "not_found",
  "message": "The resource you were accessing could not be found.",
  "request_id": "4d9d8375-3c56-4925-a3e7-eb137fed17e9"
}
{
  "id": "not_found",
  "message": "The resource you were accessing could not be found.",
  "request_id": "4d9d8375-3c56-4925-a3e7-eb137fed17e9"
}
{
  "id": "not_found",
  "message": "The resource you were accessing could not be found.",
  "request_id": "4d9d8375-3c56-4925-a3e7-eb137fed17e9"
}
{
  "id": "example_error",
  "message": "some error message"
}

POST Start a staged (large-file) workspace transfer.

/v2/agents/sessions/{session_id}/workspace/transfers
Authorizations: bearer_auth (1 scope)
Http: Bearer
Required scopes: agent_harness_session:operate

OAuth Authentication

In order to interact with the DigitalOcean API, you or your application must authenticate.

The DigitalOcean API handles this through OAuth, an open standard for authorization. OAuth allows you to delegate access to your account. Scopes can be used to grant full access, read-only access, or access to a specific set of endpoints.

You can generate an OAuth token by visiting the Apps & API section of the DigitalOcean control panel for your account.

An OAuth token functions as a complete authentication request. In effect, it acts as a substitute for a username and password pair.

Because of this, it is absolutely essential that you keep your OAuth tokens secure. In fact, upon generation, the web interface will only display each token a single time in order to prevent the token from being compromised.

DigitalOcean access tokens begin with an identifiable prefix in order to distinguish them from other similar tokens.

  • dop_v1_ for personal access tokens generated in the control panel
  • doo_v1_ for tokens generated by applications using the OAuth flow
  • dor_v1_ for OAuth refresh tokens

Scopes

Scopes act like permissions assigned to an API token. These permissions determine what actions the token can perform. You can create API tokens that grant read-only access, full access, or limited access to specific endpoints by using custom scopes.

Generally, scopes are designed to match HTTP verbs and common CRUD operations (Create, Read, Update, Delete).

HTTP Verb CRUD Operation Scope
GET Read <resource>:read
POST Create <resource>:create
PUT/PATCH Update <resource>:update
DELETE Delete <resource>:delete

For example, creating a new Droplet by making a POST request to the /v2/droplets endpoint requires the droplet:create scope while listing Droplets by making a GET request to the /v2/droplets endpoint requires the droplet:read scope.

Each endpoint below specifies which scope is required to access it when using custom scopes.

How to Authenticate with OAuth

In order to make an authenticated request, include a bearer-type Authorization header containing your OAuth token. All requests must be made over HTTPS.

Authenticate with a Bearer Authorization Header

curl -X $HTTP_METHOD -H "Authorization: Bearer $DIGITALOCEAN_TOKEN" "https://api.digitalocean.com/v2/$OBJECT"

Creates an asynchronous, object-storage-backed transfer for payloads larger than the streaming path supports (> ~50 MiB). Bulk bytes never traverse harness-api: the client PUTs/GETs presigned DO Spaces URLs directly.

Set direction to upload or download.

  • upload: responds 201 with transfer_id + part_size; the client then requests per-part presigned PUT URLs, uploads them to Spaces, and calls commit.
  • download: responds 202 with transfer_id; the client polls GET until completed and then fetches download_url from Spaces.

Upload and cancel currently return 501 until the sandbox backend RPCs ship; download is live.

Path Parameters

session_id string required
Example: a1b2c3d4-e5f6-7890-abcd-ef1234567890

The session UUID.

Request Body: application/json

as_archive boolean optional
Example: true

Download only. When true, path is exported as a tar stream.

direction string, one of: upload, download required
Example: upload

Transfer direction.

is_archive boolean optional
Example: true

Upload only. When true, the payload is a tar the guest extracts at path.

path string required
Example: example

Workspace-relative path. Destination for upload, source for download. Paths that escape the workspace root are rejected.

sha256 string optional
Example: example

Optional lowercase hex SHA-256 of the full payload. If set on an upload, it must match on commit.

size_bytes string (int64) optional
Example: example

Optional total payload size. Validated against the maximum staged object size (50 GiB); a larger value returns 413.

Content type application/json
{
  "as_archive": true,
  "direction": "upload",
  "is_archive": true,
  "path": "example",
  "sha256": "example",
  "size_bytes": "example"
}
curl -X POST \
  -H "Content-Type: application/json" \
  -H "Authorization: Bearer $DIGITALOCEAN_TOKEN" \
  "https://api.digitalocean.com/v2/agents/sessions/{session_id}/workspace/transfers"
curl -X POST \
  -H "Authorization: Bearer $API_TOKEN" \
  -H "Content-Type: application/json" \
  -d '{
  "as_archive": true,
  "direction": "upload",
  "is_archive": true,
  "path": "example",
  "sha256": "example",
  "size_bytes": "example"
}' \
  "https://api.digitalocean.com/v2/agents/sessions/{session_id}/workspace/transfers"

Responses

201

Upload transfer created; proceed to request part upload URLs.

ratelimit-limit integer

The default limit on number of requests that can be made per hour and per minute. Current rate limits are 5000 requests per hour and 250 requests per minute.

ratelimit-remaining integer

The number of requests in your hourly quota that remain before you hit your request limit. See https://docs.digitalocean.com/reference/api/reference/#rate-limit for information about how requests expire.

ratelimit-reset integer

The time when the oldest request will expire. The value is given in Unix epoch time. See https://docs.digitalocean.com/reference/api/reference/#rate-limit for information about how requests expire.

direction string, one of: upload, download optional
Example: upload
expires_at string (date-time) optional
Example: 2026-07-27T12:00:00Z

Transfer credential window.

part_size integer (int64) optional
Example: 1

Upload only. Split the payload into parts of this size; the last part may be smaller.

status string, one of: pending, in_progress, completed, failed optional
Example: pending
transfer_id string optional
Example: example

Opaque id used on all subsequent calls.

upload_id string optional
Example: example

Upload only. Multipart upload id (informational).

202

Download transfer accepted; poll the transfer until completed.

ratelimit-limit integer

The default limit on number of requests that can be made per hour and per minute. Current rate limits are 5000 requests per hour and 250 requests per minute.

ratelimit-remaining integer

The number of requests in your hourly quota that remain before you hit your request limit. See https://docs.digitalocean.com/reference/api/reference/#rate-limit for information about how requests expire.

ratelimit-reset integer

The time when the oldest request will expire. The value is given in Unix epoch time. See https://docs.digitalocean.com/reference/api/reference/#rate-limit for information about how requests expire.

direction string, one of: upload, download optional
Example: upload
expires_at string (date-time) optional
Example: 2026-07-27T12:00:00Z

Transfer credential window.

part_size integer (int64) optional
Example: 1

Upload only. Split the payload into parts of this size; the last part may be smaller.

status string, one of: pending, in_progress, completed, failed optional
Example: pending
transfer_id string optional
Example: example

Opaque id used on all subsequent calls.

upload_id string optional
Example: example

Upload only. Multipart upload id (informational).

400

Missing/invalid direction or path, or invalid JSON.

ratelimit-limit integer

The default limit on number of requests that can be made per hour and per minute. Current rate limits are 5000 requests per hour and 250 requests per minute.

ratelimit-remaining integer

The number of requests in your hourly quota that remain before you hit your request limit. See https://docs.digitalocean.com/reference/api/reference/#rate-limit for information about how requests expire.

ratelimit-reset integer

The time when the oldest request will expire. The value is given in Unix epoch time. See https://docs.digitalocean.com/reference/api/reference/#rate-limit for information about how requests expire.

id string required
Example: not_found

A short identifier corresponding to the HTTP status code returned. For example, the ID for a response returning a 404 status code would be "not_found."

message string required
Example: The resource you were accessing could not be found.

A message providing additional information about the error, including details to help resolve it when possible.

request_id string optional
Example: 4d9d8375-3c56-4925-a3e7-eb137fed17e9

Optionally, some endpoints may include a request ID that should be provided when reporting bugs or opening support tickets to help identify the issue.

401

Authentication failed due to invalid credentials.

ratelimit-limit integer

The default limit on number of requests that can be made per hour and per minute. Current rate limits are 5000 requests per hour and 250 requests per minute.

ratelimit-remaining integer

The number of requests in your hourly quota that remain before you hit your request limit. See https://docs.digitalocean.com/reference/api/reference/#rate-limit for information about how requests expire.

ratelimit-reset integer

The time when the oldest request will expire. The value is given in Unix epoch time. See https://docs.digitalocean.com/reference/api/reference/#rate-limit for information about how requests expire.

id string required
Example: not_found

A short identifier corresponding to the HTTP status code returned. For example, the ID for a response returning a 404 status code would be "not_found."

message string required
Example: The resource you were accessing could not be found.

A message providing additional information about the error, including details to help resolve it when possible.

request_id string optional
Example: 4d9d8375-3c56-4925-a3e7-eb137fed17e9

Optionally, some endpoints may include a request ID that should be provided when reporting bugs or opening support tickets to help identify the issue.

402

The team is blocked by the prepayment gate.

ratelimit-limit integer

The default limit on number of requests that can be made per hour and per minute. Current rate limits are 5000 requests per hour and 250 requests per minute.

ratelimit-remaining integer

The number of requests in your hourly quota that remain before you hit your request limit. See https://docs.digitalocean.com/reference/api/reference/#rate-limit for information about how requests expire.

ratelimit-reset integer

The time when the oldest request will expire. The value is given in Unix epoch time. See https://docs.digitalocean.com/reference/api/reference/#rate-limit for information about how requests expire.

id string required
Example: not_found

A short identifier corresponding to the HTTP status code returned. For example, the ID for a response returning a 404 status code would be "not_found."

message string required
Example: The resource you were accessing could not be found.

A message providing additional information about the error, including details to help resolve it when possible.

request_id string optional
Example: 4d9d8375-3c56-4925-a3e7-eb137fed17e9

Optionally, some endpoints may include a request ID that should be provided when reporting bugs or opening support tickets to help identify the issue.

403

Path resolves outside the workspace, or the session belongs to another team.

ratelimit-limit integer

The default limit on number of requests that can be made per hour and per minute. Current rate limits are 5000 requests per hour and 250 requests per minute.

ratelimit-remaining integer

The number of requests in your hourly quota that remain before you hit your request limit. See https://docs.digitalocean.com/reference/api/reference/#rate-limit for information about how requests expire.

ratelimit-reset integer

The time when the oldest request will expire. The value is given in Unix epoch time. See https://docs.digitalocean.com/reference/api/reference/#rate-limit for information about how requests expire.

id string required
Example: not_found

A short identifier corresponding to the HTTP status code returned. For example, the ID for a response returning a 404 status code would be "not_found."

message string required
Example: The resource you were accessing could not be found.

A message providing additional information about the error, including details to help resolve it when possible.

request_id string optional
Example: 4d9d8375-3c56-4925-a3e7-eb137fed17e9

Optionally, some endpoints may include a request ID that should be provided when reporting bugs or opening support tickets to help identify the issue.

404

The resource was not found.

ratelimit-limit integer

The default limit on number of requests that can be made per hour and per minute. Current rate limits are 5000 requests per hour and 250 requests per minute.

ratelimit-remaining integer

The number of requests in your hourly quota that remain before you hit your request limit. See https://docs.digitalocean.com/reference/api/reference/#rate-limit for information about how requests expire.

ratelimit-reset integer

The time when the oldest request will expire. The value is given in Unix epoch time. See https://docs.digitalocean.com/reference/api/reference/#rate-limit for information about how requests expire.

id string required
Example: not_found

A short identifier corresponding to the HTTP status code returned. For example, the ID for a response returning a 404 status code would be "not_found."

message string required
Example: The resource you were accessing could not be found.

A message providing additional information about the error, including details to help resolve it when possible.

request_id string optional
Example: 4d9d8375-3c56-4925-a3e7-eb137fed17e9

Optionally, some endpoints may include a request ID that should be provided when reporting bugs or opening support tickets to help identify the issue.

409

Session has no sandbox, or the sandbox is not ready.

ratelimit-limit integer

The default limit on number of requests that can be made per hour and per minute. Current rate limits are 5000 requests per hour and 250 requests per minute.

ratelimit-remaining integer

The number of requests in your hourly quota that remain before you hit your request limit. See https://docs.digitalocean.com/reference/api/reference/#rate-limit for information about how requests expire.

ratelimit-reset integer

The time when the oldest request will expire. The value is given in Unix epoch time. See https://docs.digitalocean.com/reference/api/reference/#rate-limit for information about how requests expire.

id string required
Example: not_found

A short identifier corresponding to the HTTP status code returned. For example, the ID for a response returning a 404 status code would be "not_found."

message string required
Example: The resource you were accessing could not be found.

A message providing additional information about the error, including details to help resolve it when possible.

request_id string optional
Example: 4d9d8375-3c56-4925-a3e7-eb137fed17e9

Optionally, some endpoints may include a request ID that should be provided when reporting bugs or opening support tickets to help identify the issue.

413

Declared size exceeds the maximum staged object size.

ratelimit-limit integer

The default limit on number of requests that can be made per hour and per minute. Current rate limits are 5000 requests per hour and 250 requests per minute.

ratelimit-remaining integer

The number of requests in your hourly quota that remain before you hit your request limit. See https://docs.digitalocean.com/reference/api/reference/#rate-limit for information about how requests expire.

ratelimit-reset integer

The time when the oldest request will expire. The value is given in Unix epoch time. See https://docs.digitalocean.com/reference/api/reference/#rate-limit for information about how requests expire.

id string required
Example: not_found

A short identifier corresponding to the HTTP status code returned. For example, the ID for a response returning a 404 status code would be "not_found."

message string required
Example: The resource you were accessing could not be found.

A message providing additional information about the error, including details to help resolve it when possible.

request_id string optional
Example: 4d9d8375-3c56-4925-a3e7-eb137fed17e9

Optionally, some endpoints may include a request ID that should be provided when reporting bugs or opening support tickets to help identify the issue.

423

This session is unavailable; contact support.

ratelimit-limit integer

The default limit on number of requests that can be made per hour and per minute. Current rate limits are 5000 requests per hour and 250 requests per minute.

ratelimit-remaining integer

The number of requests in your hourly quota that remain before you hit your request limit. See https://docs.digitalocean.com/reference/api/reference/#rate-limit for information about how requests expire.

ratelimit-reset integer

The time when the oldest request will expire. The value is given in Unix epoch time. See https://docs.digitalocean.com/reference/api/reference/#rate-limit for information about how requests expire.

id string required
Example: not_found

A short identifier corresponding to the HTTP status code returned. For example, the ID for a response returning a 404 status code would be "not_found."

message string required
Example: The resource you were accessing could not be found.

A message providing additional information about the error, including details to help resolve it when possible.

request_id string optional
Example: 4d9d8375-3c56-4925-a3e7-eb137fed17e9

Optionally, some endpoints may include a request ID that should be provided when reporting bugs or opening support tickets to help identify the issue.

429

The API rate limit has been exceeded.

ratelimit-limit integer

The default limit on number of requests that can be made per hour and per minute. Current rate limits are 5000 requests per hour and 250 requests per minute.

ratelimit-remaining integer

The number of requests in your hourly quota that remain before you hit your request limit. See https://docs.digitalocean.com/reference/api/reference/#rate-limit for information about how requests expire.

ratelimit-reset integer

The time when the oldest request will expire. The value is given in Unix epoch time. See https://docs.digitalocean.com/reference/api/reference/#rate-limit for information about how requests expire.

id string required
Example: not_found

A short identifier corresponding to the HTTP status code returned. For example, the ID for a response returning a 404 status code would be "not_found."

message string required
Example: The resource you were accessing could not be found.

A message providing additional information about the error, including details to help resolve it when possible.

request_id string optional
Example: 4d9d8375-3c56-4925-a3e7-eb137fed17e9

Optionally, some endpoints may include a request ID that should be provided when reporting bugs or opening support tickets to help identify the issue.

500

There was a server error.

ratelimit-limit integer

The default limit on number of requests that can be made per hour and per minute. Current rate limits are 5000 requests per hour and 250 requests per minute.

ratelimit-remaining integer

The number of requests in your hourly quota that remain before you hit your request limit. See https://docs.digitalocean.com/reference/api/reference/#rate-limit for information about how requests expire.

ratelimit-reset integer

The time when the oldest request will expire. The value is given in Unix epoch time. See https://docs.digitalocean.com/reference/api/reference/#rate-limit for information about how requests expire.

id string required
Example: not_found

A short identifier corresponding to the HTTP status code returned. For example, the ID for a response returning a 404 status code would be "not_found."

message string required
Example: The resource you were accessing could not be found.

A message providing additional information about the error, including details to help resolve it when possible.

request_id string optional
Example: 4d9d8375-3c56-4925-a3e7-eb137fed17e9

Optionally, some endpoints may include a request ID that should be provided when reporting bugs or opening support tickets to help identify the issue.

501

Staged transfer (or this direction) is not supported by the active sandbox driver.

ratelimit-limit integer

The default limit on number of requests that can be made per hour and per minute. Current rate limits are 5000 requests per hour and 250 requests per minute.

ratelimit-remaining integer

The number of requests in your hourly quota that remain before you hit your request limit. See https://docs.digitalocean.com/reference/api/reference/#rate-limit for information about how requests expire.

ratelimit-reset integer

The time when the oldest request will expire. The value is given in Unix epoch time. See https://docs.digitalocean.com/reference/api/reference/#rate-limit for information about how requests expire.

id string required
Example: not_found

A short identifier corresponding to the HTTP status code returned. For example, the ID for a response returning a 404 status code would be "not_found."

message string required
Example: The resource you were accessing could not be found.

A message providing additional information about the error, including details to help resolve it when possible.

request_id string optional
Example: 4d9d8375-3c56-4925-a3e7-eb137fed17e9

Optionally, some endpoints may include a request ID that should be provided when reporting bugs or opening support tickets to help identify the issue.

502

Upstream sandbox transfer coordination failed.

ratelimit-limit integer

The default limit on number of requests that can be made per hour and per minute. Current rate limits are 5000 requests per hour and 250 requests per minute.

ratelimit-remaining integer

The number of requests in your hourly quota that remain before you hit your request limit. See https://docs.digitalocean.com/reference/api/reference/#rate-limit for information about how requests expire.

ratelimit-reset integer

The time when the oldest request will expire. The value is given in Unix epoch time. See https://docs.digitalocean.com/reference/api/reference/#rate-limit for information about how requests expire.

id string required
Example: not_found

A short identifier corresponding to the HTTP status code returned. For example, the ID for a response returning a 404 status code would be "not_found."

message string required
Example: The resource you were accessing could not be found.

A message providing additional information about the error, including details to help resolve it when possible.

request_id string optional
Example: 4d9d8375-3c56-4925-a3e7-eb137fed17e9

Optionally, some endpoints may include a request ID that should be provided when reporting bugs or opening support tickets to help identify the issue.

default

There was an unexpected error.

ratelimit-limit integer

The default limit on number of requests that can be made per hour and per minute. Current rate limits are 5000 requests per hour and 250 requests per minute.

ratelimit-remaining integer

The number of requests in your hourly quota that remain before you hit your request limit. See https://docs.digitalocean.com/reference/api/reference/#rate-limit for information about how requests expire.

ratelimit-reset integer

The time when the oldest request will expire. The value is given in Unix epoch time. See https://docs.digitalocean.com/reference/api/reference/#rate-limit for information about how requests expire.

id string required
Example: not_found

A short identifier corresponding to the HTTP status code returned. For example, the ID for a response returning a 404 status code would be "not_found."

message string required
Example: The resource you were accessing could not be found.

A message providing additional information about the error, including details to help resolve it when possible.

request_id string optional
Example: 4d9d8375-3c56-4925-a3e7-eb137fed17e9

Optionally, some endpoints may include a request ID that should be provided when reporting bugs or opening support tickets to help identify the issue.

{
  "direction": "upload",
  "expires_at": "2026-07-27T12:00:00Z",
  "part_size": 1,
  "status": "pending",
  "transfer_id": "example",
  "upload_id": "example"
}
{
  "direction": "upload",
  "expires_at": "2026-07-27T12:00:00Z",
  "part_size": 1,
  "status": "pending",
  "transfer_id": "example",
  "upload_id": "example"
}
{
  "id": "not_found",
  "message": "The resource you were accessing could not be found.",
  "request_id": "4d9d8375-3c56-4925-a3e7-eb137fed17e9"
}
{
  "id": "unauthorized",
  "message": "Unable to authenticate you."
}
{
  "id": "not_found",
  "message": "The resource you were accessing could not be found.",
  "request_id": "4d9d8375-3c56-4925-a3e7-eb137fed17e9"
}
{
  "id": "not_found",
  "message": "The resource you were accessing could not be found.",
  "request_id": "4d9d8375-3c56-4925-a3e7-eb137fed17e9"
}
{
  "id": "not_found",
  "message": "The resource you requested could not be found."
}
{
  "id": "not_found",
  "message": "The resource you were accessing could not be found.",
  "request_id": "4d9d8375-3c56-4925-a3e7-eb137fed17e9"
}
{
  "id": "not_found",
  "message": "The resource you were accessing could not be found.",
  "request_id": "4d9d8375-3c56-4925-a3e7-eb137fed17e9"
}
{
  "id": "not_found",
  "message": "The resource you were accessing could not be found.",
  "request_id": "4d9d8375-3c56-4925-a3e7-eb137fed17e9"
}
{
  "id": "too_many_requests",
  "message": "API rate limit exceeded."
}
{
  "id": "server_error",
  "message": "Unexpected server-side error"
}
{
  "id": "not_found",
  "message": "The resource you were accessing could not be found.",
  "request_id": "4d9d8375-3c56-4925-a3e7-eb137fed17e9"
}
{
  "id": "not_found",
  "message": "The resource you were accessing could not be found.",
  "request_id": "4d9d8375-3c56-4925-a3e7-eb137fed17e9"
}
{
  "id": "example_error",
  "message": "some error message"
}

GET Get the status of a staged workspace transfer.

/v2/agents/sessions/{session_id}/workspace/transfers/{transfer_id}
Authorizations: bearer_auth (1 scope)
Http: Bearer
Required scopes: agent_harness_session:read

OAuth Authentication

In order to interact with the DigitalOcean API, you or your application must authenticate.

The DigitalOcean API handles this through OAuth, an open standard for authorization. OAuth allows you to delegate access to your account. Scopes can be used to grant full access, read-only access, or access to a specific set of endpoints.

You can generate an OAuth token by visiting the Apps & API section of the DigitalOcean control panel for your account.

An OAuth token functions as a complete authentication request. In effect, it acts as a substitute for a username and password pair.

Because of this, it is absolutely essential that you keep your OAuth tokens secure. In fact, upon generation, the web interface will only display each token a single time in order to prevent the token from being compromised.

DigitalOcean access tokens begin with an identifiable prefix in order to distinguish them from other similar tokens.

  • dop_v1_ for personal access tokens generated in the control panel
  • doo_v1_ for tokens generated by applications using the OAuth flow
  • dor_v1_ for OAuth refresh tokens

Scopes

Scopes act like permissions assigned to an API token. These permissions determine what actions the token can perform. You can create API tokens that grant read-only access, full access, or limited access to specific endpoints by using custom scopes.

Generally, scopes are designed to match HTTP verbs and common CRUD operations (Create, Read, Update, Delete).

HTTP Verb CRUD Operation Scope
GET Read <resource>:read
POST Create <resource>:create
PUT/PATCH Update <resource>:update
DELETE Delete <resource>:delete

For example, creating a new Droplet by making a POST request to the /v2/droplets endpoint requires the droplet:create scope while listing Droplets by making a GET request to the /v2/droplets endpoint requires the droplet:read scope.

Each endpoint below specifies which scope is required to access it when using custom scopes.

How to Authenticate with OAuth

In order to make an authenticated request, include a bearer-type Authorization header containing your OAuth token. All requests must be made over HTTPS.

Authenticate with a Bearer Authorization Header

curl -X $HTTP_METHOD -H "Authorization: Bearer $DIGITALOCEAN_TOKEN" "https://api.digitalocean.com/v2/$OBJECT"

Returns the current transfer state. For a completed download the response also carries a freshly minted presigned GET download_url (its TTL starts at poll time) and the payload sha256 for client-side verification.

Path Parameters

session_id string required
Example: a1b2c3d4-e5f6-7890-abcd-ef1234567890

The session UUID.

transfer_id string required
Example: tr_example

The workspace transfer identifier.

curl -X GET \
  -H "Content-Type: application/json" \
  -H "Authorization: Bearer $DIGITALOCEAN_TOKEN" \
  "https://api.digitalocean.com/v2/agents/sessions/{session_id}/workspace/transfers/{transfer_id}"
curl -X GET \
  -H "Authorization: Bearer $API_TOKEN" \
  "https://api.digitalocean.com/v2/agents/sessions/{session_id}/workspace/transfers/{transfer_id}"

Responses

200

Current transfer status.

ratelimit-limit integer

The default limit on number of requests that can be made per hour and per minute. Current rate limits are 5000 requests per hour and 250 requests per minute.

ratelimit-remaining integer

The number of requests in your hourly quota that remain before you hit your request limit. See https://docs.digitalocean.com/reference/api/reference/#rate-limit for information about how requests expire.

ratelimit-reset integer

The time when the oldest request will expire. The value is given in Unix epoch time. See https://docs.digitalocean.com/reference/api/reference/#rate-limit for information about how requests expire.

bytes_written integer (int64) optional
Example: 1
direction string, one of: upload, download optional
Example: upload
download_url string optional
Example: example

Download + completed only. Presigned GET URL; fetch the object directly.

error_message string optional
Example: example

Populated when status is failed.

expires_at string (date-time) optional
Example: 2026-07-27T12:00:00Z

Expiry of download_url when present.

sha256 string optional
Example: example

Lowercase hex SHA-256 of the payload, when known. Verify the downloaded object against this.

status string, one of: pending, in_progress, completed, failed optional
Example: pending
transfer_id string optional
Example: example
401

Authentication failed due to invalid credentials.

ratelimit-limit integer

The default limit on number of requests that can be made per hour and per minute. Current rate limits are 5000 requests per hour and 250 requests per minute.

ratelimit-remaining integer

The number of requests in your hourly quota that remain before you hit your request limit. See https://docs.digitalocean.com/reference/api/reference/#rate-limit for information about how requests expire.

ratelimit-reset integer

The time when the oldest request will expire. The value is given in Unix epoch time. See https://docs.digitalocean.com/reference/api/reference/#rate-limit for information about how requests expire.

id string required
Example: not_found

A short identifier corresponding to the HTTP status code returned. For example, the ID for a response returning a 404 status code would be "not_found."

message string required
Example: The resource you were accessing could not be found.

A message providing additional information about the error, including details to help resolve it when possible.

request_id string optional
Example: 4d9d8375-3c56-4925-a3e7-eb137fed17e9

Optionally, some endpoints may include a request ID that should be provided when reporting bugs or opening support tickets to help identify the issue.

403

The session belongs to another team.

ratelimit-limit integer

The default limit on number of requests that can be made per hour and per minute. Current rate limits are 5000 requests per hour and 250 requests per minute.

ratelimit-remaining integer

The number of requests in your hourly quota that remain before you hit your request limit. See https://docs.digitalocean.com/reference/api/reference/#rate-limit for information about how requests expire.

ratelimit-reset integer

The time when the oldest request will expire. The value is given in Unix epoch time. See https://docs.digitalocean.com/reference/api/reference/#rate-limit for information about how requests expire.

id string required
Example: not_found

A short identifier corresponding to the HTTP status code returned. For example, the ID for a response returning a 404 status code would be "not_found."

message string required
Example: The resource you were accessing could not be found.

A message providing additional information about the error, including details to help resolve it when possible.

request_id string optional
Example: 4d9d8375-3c56-4925-a3e7-eb137fed17e9

Optionally, some endpoints may include a request ID that should be provided when reporting bugs or opening support tickets to help identify the issue.

404

The resource was not found.

ratelimit-limit integer

The default limit on number of requests that can be made per hour and per minute. Current rate limits are 5000 requests per hour and 250 requests per minute.

ratelimit-remaining integer

The number of requests in your hourly quota that remain before you hit your request limit. See https://docs.digitalocean.com/reference/api/reference/#rate-limit for information about how requests expire.

ratelimit-reset integer

The time when the oldest request will expire. The value is given in Unix epoch time. See https://docs.digitalocean.com/reference/api/reference/#rate-limit for information about how requests expire.

id string required
Example: not_found

A short identifier corresponding to the HTTP status code returned. For example, the ID for a response returning a 404 status code would be "not_found."

message string required
Example: The resource you were accessing could not be found.

A message providing additional information about the error, including details to help resolve it when possible.

request_id string optional
Example: 4d9d8375-3c56-4925-a3e7-eb137fed17e9

Optionally, some endpoints may include a request ID that should be provided when reporting bugs or opening support tickets to help identify the issue.

423

This session is unavailable; contact support.

ratelimit-limit integer

The default limit on number of requests that can be made per hour and per minute. Current rate limits are 5000 requests per hour and 250 requests per minute.

ratelimit-remaining integer

The number of requests in your hourly quota that remain before you hit your request limit. See https://docs.digitalocean.com/reference/api/reference/#rate-limit for information about how requests expire.

ratelimit-reset integer

The time when the oldest request will expire. The value is given in Unix epoch time. See https://docs.digitalocean.com/reference/api/reference/#rate-limit for information about how requests expire.

id string required
Example: not_found

A short identifier corresponding to the HTTP status code returned. For example, the ID for a response returning a 404 status code would be "not_found."

message string required
Example: The resource you were accessing could not be found.

A message providing additional information about the error, including details to help resolve it when possible.

request_id string optional
Example: 4d9d8375-3c56-4925-a3e7-eb137fed17e9

Optionally, some endpoints may include a request ID that should be provided when reporting bugs or opening support tickets to help identify the issue.

429

The API rate limit has been exceeded.

ratelimit-limit integer

The default limit on number of requests that can be made per hour and per minute. Current rate limits are 5000 requests per hour and 250 requests per minute.

ratelimit-remaining integer

The number of requests in your hourly quota that remain before you hit your request limit. See https://docs.digitalocean.com/reference/api/reference/#rate-limit for information about how requests expire.

ratelimit-reset integer

The time when the oldest request will expire. The value is given in Unix epoch time. See https://docs.digitalocean.com/reference/api/reference/#rate-limit for information about how requests expire.

id string required
Example: not_found

A short identifier corresponding to the HTTP status code returned. For example, the ID for a response returning a 404 status code would be "not_found."

message string required
Example: The resource you were accessing could not be found.

A message providing additional information about the error, including details to help resolve it when possible.

request_id string optional
Example: 4d9d8375-3c56-4925-a3e7-eb137fed17e9

Optionally, some endpoints may include a request ID that should be provided when reporting bugs or opening support tickets to help identify the issue.

500

There was a server error.

ratelimit-limit integer

The default limit on number of requests that can be made per hour and per minute. Current rate limits are 5000 requests per hour and 250 requests per minute.

ratelimit-remaining integer

The number of requests in your hourly quota that remain before you hit your request limit. See https://docs.digitalocean.com/reference/api/reference/#rate-limit for information about how requests expire.

ratelimit-reset integer

The time when the oldest request will expire. The value is given in Unix epoch time. See https://docs.digitalocean.com/reference/api/reference/#rate-limit for information about how requests expire.

id string required
Example: not_found

A short identifier corresponding to the HTTP status code returned. For example, the ID for a response returning a 404 status code would be "not_found."

message string required
Example: The resource you were accessing could not be found.

A message providing additional information about the error, including details to help resolve it when possible.

request_id string optional
Example: 4d9d8375-3c56-4925-a3e7-eb137fed17e9

Optionally, some endpoints may include a request ID that should be provided when reporting bugs or opening support tickets to help identify the issue.

501

Staged transfer is not supported by the active sandbox driver.

ratelimit-limit integer

The default limit on number of requests that can be made per hour and per minute. Current rate limits are 5000 requests per hour and 250 requests per minute.

ratelimit-remaining integer

The number of requests in your hourly quota that remain before you hit your request limit. See https://docs.digitalocean.com/reference/api/reference/#rate-limit for information about how requests expire.

ratelimit-reset integer

The time when the oldest request will expire. The value is given in Unix epoch time. See https://docs.digitalocean.com/reference/api/reference/#rate-limit for information about how requests expire.

id string required
Example: not_found

A short identifier corresponding to the HTTP status code returned. For example, the ID for a response returning a 404 status code would be "not_found."

message string required
Example: The resource you were accessing could not be found.

A message providing additional information about the error, including details to help resolve it when possible.

request_id string optional
Example: 4d9d8375-3c56-4925-a3e7-eb137fed17e9

Optionally, some endpoints may include a request ID that should be provided when reporting bugs or opening support tickets to help identify the issue.

default

There was an unexpected error.

ratelimit-limit integer

The default limit on number of requests that can be made per hour and per minute. Current rate limits are 5000 requests per hour and 250 requests per minute.

ratelimit-remaining integer

The number of requests in your hourly quota that remain before you hit your request limit. See https://docs.digitalocean.com/reference/api/reference/#rate-limit for information about how requests expire.

ratelimit-reset integer

The time when the oldest request will expire. The value is given in Unix epoch time. See https://docs.digitalocean.com/reference/api/reference/#rate-limit for information about how requests expire.

id string required
Example: not_found

A short identifier corresponding to the HTTP status code returned. For example, the ID for a response returning a 404 status code would be "not_found."

message string required
Example: The resource you were accessing could not be found.

A message providing additional information about the error, including details to help resolve it when possible.

request_id string optional
Example: 4d9d8375-3c56-4925-a3e7-eb137fed17e9

Optionally, some endpoints may include a request ID that should be provided when reporting bugs or opening support tickets to help identify the issue.

{
  "bytes_written": 1,
  "direction": "upload",
  "download_url": "example",
  "error_message": "example",
  "expires_at": "2026-07-27T12:00:00Z",
  "sha256": "example",
  "status": "pending",
  "transfer_id": "example"
}
{
  "id": "unauthorized",
  "message": "Unable to authenticate you."
}
{
  "id": "not_found",
  "message": "The resource you were accessing could not be found.",
  "request_id": "4d9d8375-3c56-4925-a3e7-eb137fed17e9"
}
{
  "id": "not_found",
  "message": "The resource you requested could not be found."
}
{
  "id": "not_found",
  "message": "The resource you were accessing could not be found.",
  "request_id": "4d9d8375-3c56-4925-a3e7-eb137fed17e9"
}
{
  "id": "too_many_requests",
  "message": "API rate limit exceeded."
}
{
  "id": "server_error",
  "message": "Unexpected server-side error"
}
{
  "id": "not_found",
  "message": "The resource you were accessing could not be found.",
  "request_id": "4d9d8375-3c56-4925-a3e7-eb137fed17e9"
}
{
  "id": "example_error",
  "message": "some error message"
}

POST Cancel a staged workspace transfer.

/v2/agents/sessions/{session_id}/workspace/transfers/{transfer_id}/cancel
Authorizations: bearer_auth (1 scope)
Http: Bearer
Required scopes: agent_harness_session:operate

OAuth Authentication

In order to interact with the DigitalOcean API, you or your application must authenticate.

The DigitalOcean API handles this through OAuth, an open standard for authorization. OAuth allows you to delegate access to your account. Scopes can be used to grant full access, read-only access, or access to a specific set of endpoints.

You can generate an OAuth token by visiting the Apps & API section of the DigitalOcean control panel for your account.

An OAuth token functions as a complete authentication request. In effect, it acts as a substitute for a username and password pair.

Because of this, it is absolutely essential that you keep your OAuth tokens secure. In fact, upon generation, the web interface will only display each token a single time in order to prevent the token from being compromised.

DigitalOcean access tokens begin with an identifiable prefix in order to distinguish them from other similar tokens.

  • dop_v1_ for personal access tokens generated in the control panel
  • doo_v1_ for tokens generated by applications using the OAuth flow
  • dor_v1_ for OAuth refresh tokens

Scopes

Scopes act like permissions assigned to an API token. These permissions determine what actions the token can perform. You can create API tokens that grant read-only access, full access, or limited access to specific endpoints by using custom scopes.

Generally, scopes are designed to match HTTP verbs and common CRUD operations (Create, Read, Update, Delete).

HTTP Verb CRUD Operation Scope
GET Read <resource>:read
POST Create <resource>:create
PUT/PATCH Update <resource>:update
DELETE Delete <resource>:delete

For example, creating a new Droplet by making a POST request to the /v2/droplets endpoint requires the droplet:create scope while listing Droplets by making a GET request to the /v2/droplets endpoint requires the droplet:read scope.

Each endpoint below specifies which scope is required to access it when using custom scopes.

How to Authenticate with OAuth

In order to make an authenticated request, include a bearer-type Authorization header containing your OAuth token. All requests must be made over HTTPS.

Authenticate with a Bearer Authorization Header

curl -X $HTTP_METHOD -H "Authorization: Bearer $DIGITALOCEAN_TOKEN" "https://api.digitalocean.com/v2/$OBJECT"

Aborts an in-flight transfer. Idempotent: cancelling an already-terminal transfer returns aborted: false with the current status. The request body is optional.

Path Parameters

session_id string required
Example: a1b2c3d4-e5f6-7890-abcd-ef1234567890

The session UUID.

transfer_id string required
Example: tr_example

The workspace transfer identifier.

Request Body: application/json

reason string optional
Example: example

Optional caller-visible audit/debug context.

Content type application/json
{
  "reason": "example"
}
curl -X POST \
  -H "Content-Type: application/json" \
  -H "Authorization: Bearer $DIGITALOCEAN_TOKEN" \
  "https://api.digitalocean.com/v2/agents/sessions/{session_id}/workspace/transfers/{transfer_id}/cancel"
curl -X POST \
  -H "Authorization: Bearer $API_TOKEN" \
  -H "Content-Type: application/json" \
  -d '{
  "reason": "example"
}' \
  "https://api.digitalocean.com/v2/agents/sessions/{session_id}/workspace/transfers/{transfer_id}/cancel"

Responses

200

Cancel processed.

ratelimit-limit integer

The default limit on number of requests that can be made per hour and per minute. Current rate limits are 5000 requests per hour and 250 requests per minute.

ratelimit-remaining integer

The number of requests in your hourly quota that remain before you hit your request limit. See https://docs.digitalocean.com/reference/api/reference/#rate-limit for information about how requests expire.

ratelimit-reset integer

The time when the oldest request will expire. The value is given in Unix epoch time. See https://docs.digitalocean.com/reference/api/reference/#rate-limit for information about how requests expire.

aborted boolean optional
Example: true

True if this call transitioned an active transfer to terminal; false if it was already terminal.

status string, one of: pending, in_progress, completed, failed optional
Example: pending
transfer_id string optional
Example: example
401

Authentication failed due to invalid credentials.

ratelimit-limit integer

The default limit on number of requests that can be made per hour and per minute. Current rate limits are 5000 requests per hour and 250 requests per minute.

ratelimit-remaining integer

The number of requests in your hourly quota that remain before you hit your request limit. See https://docs.digitalocean.com/reference/api/reference/#rate-limit for information about how requests expire.

ratelimit-reset integer

The time when the oldest request will expire. The value is given in Unix epoch time. See https://docs.digitalocean.com/reference/api/reference/#rate-limit for information about how requests expire.

id string required
Example: not_found

A short identifier corresponding to the HTTP status code returned. For example, the ID for a response returning a 404 status code would be "not_found."

message string required
Example: The resource you were accessing could not be found.

A message providing additional information about the error, including details to help resolve it when possible.

request_id string optional
Example: 4d9d8375-3c56-4925-a3e7-eb137fed17e9

Optionally, some endpoints may include a request ID that should be provided when reporting bugs or opening support tickets to help identify the issue.

402

The team is blocked by the prepayment gate.

ratelimit-limit integer

The default limit on number of requests that can be made per hour and per minute. Current rate limits are 5000 requests per hour and 250 requests per minute.

ratelimit-remaining integer

The number of requests in your hourly quota that remain before you hit your request limit. See https://docs.digitalocean.com/reference/api/reference/#rate-limit for information about how requests expire.

ratelimit-reset integer

The time when the oldest request will expire. The value is given in Unix epoch time. See https://docs.digitalocean.com/reference/api/reference/#rate-limit for information about how requests expire.

id string required
Example: not_found

A short identifier corresponding to the HTTP status code returned. For example, the ID for a response returning a 404 status code would be "not_found."

message string required
Example: The resource you were accessing could not be found.

A message providing additional information about the error, including details to help resolve it when possible.

request_id string optional
Example: 4d9d8375-3c56-4925-a3e7-eb137fed17e9

Optionally, some endpoints may include a request ID that should be provided when reporting bugs or opening support tickets to help identify the issue.

404

The resource was not found.

ratelimit-limit integer

The default limit on number of requests that can be made per hour and per minute. Current rate limits are 5000 requests per hour and 250 requests per minute.

ratelimit-remaining integer

The number of requests in your hourly quota that remain before you hit your request limit. See https://docs.digitalocean.com/reference/api/reference/#rate-limit for information about how requests expire.

ratelimit-reset integer

The time when the oldest request will expire. The value is given in Unix epoch time. See https://docs.digitalocean.com/reference/api/reference/#rate-limit for information about how requests expire.

id string required
Example: not_found

A short identifier corresponding to the HTTP status code returned. For example, the ID for a response returning a 404 status code would be "not_found."

message string required
Example: The resource you were accessing could not be found.

A message providing additional information about the error, including details to help resolve it when possible.

request_id string optional
Example: 4d9d8375-3c56-4925-a3e7-eb137fed17e9

Optionally, some endpoints may include a request ID that should be provided when reporting bugs or opening support tickets to help identify the issue.

423

This session is unavailable; contact support.

ratelimit-limit integer

The default limit on number of requests that can be made per hour and per minute. Current rate limits are 5000 requests per hour and 250 requests per minute.

ratelimit-remaining integer

The number of requests in your hourly quota that remain before you hit your request limit. See https://docs.digitalocean.com/reference/api/reference/#rate-limit for information about how requests expire.

ratelimit-reset integer

The time when the oldest request will expire. The value is given in Unix epoch time. See https://docs.digitalocean.com/reference/api/reference/#rate-limit for information about how requests expire.

id string required
Example: not_found

A short identifier corresponding to the HTTP status code returned. For example, the ID for a response returning a 404 status code would be "not_found."

message string required
Example: The resource you were accessing could not be found.

A message providing additional information about the error, including details to help resolve it when possible.

request_id string optional
Example: 4d9d8375-3c56-4925-a3e7-eb137fed17e9

Optionally, some endpoints may include a request ID that should be provided when reporting bugs or opening support tickets to help identify the issue.

429

The API rate limit has been exceeded.

ratelimit-limit integer

The default limit on number of requests that can be made per hour and per minute. Current rate limits are 5000 requests per hour and 250 requests per minute.

ratelimit-remaining integer

The number of requests in your hourly quota that remain before you hit your request limit. See https://docs.digitalocean.com/reference/api/reference/#rate-limit for information about how requests expire.

ratelimit-reset integer

The time when the oldest request will expire. The value is given in Unix epoch time. See https://docs.digitalocean.com/reference/api/reference/#rate-limit for information about how requests expire.

id string required
Example: not_found

A short identifier corresponding to the HTTP status code returned. For example, the ID for a response returning a 404 status code would be "not_found."

message string required
Example: The resource you were accessing could not be found.

A message providing additional information about the error, including details to help resolve it when possible.

request_id string optional
Example: 4d9d8375-3c56-4925-a3e7-eb137fed17e9

Optionally, some endpoints may include a request ID that should be provided when reporting bugs or opening support tickets to help identify the issue.

500

There was a server error.

ratelimit-limit integer

The default limit on number of requests that can be made per hour and per minute. Current rate limits are 5000 requests per hour and 250 requests per minute.

ratelimit-remaining integer

The number of requests in your hourly quota that remain before you hit your request limit. See https://docs.digitalocean.com/reference/api/reference/#rate-limit for information about how requests expire.

ratelimit-reset integer

The time when the oldest request will expire. The value is given in Unix epoch time. See https://docs.digitalocean.com/reference/api/reference/#rate-limit for information about how requests expire.

id string required
Example: not_found

A short identifier corresponding to the HTTP status code returned. For example, the ID for a response returning a 404 status code would be "not_found."

message string required
Example: The resource you were accessing could not be found.

A message providing additional information about the error, including details to help resolve it when possible.

request_id string optional
Example: 4d9d8375-3c56-4925-a3e7-eb137fed17e9

Optionally, some endpoints may include a request ID that should be provided when reporting bugs or opening support tickets to help identify the issue.

501

Cancel is not supported by the active sandbox driver.

ratelimit-limit integer

The default limit on number of requests that can be made per hour and per minute. Current rate limits are 5000 requests per hour and 250 requests per minute.

ratelimit-remaining integer

The number of requests in your hourly quota that remain before you hit your request limit. See https://docs.digitalocean.com/reference/api/reference/#rate-limit for information about how requests expire.

ratelimit-reset integer

The time when the oldest request will expire. The value is given in Unix epoch time. See https://docs.digitalocean.com/reference/api/reference/#rate-limit for information about how requests expire.

id string required
Example: not_found

A short identifier corresponding to the HTTP status code returned. For example, the ID for a response returning a 404 status code would be "not_found."

message string required
Example: The resource you were accessing could not be found.

A message providing additional information about the error, including details to help resolve it when possible.

request_id string optional
Example: 4d9d8375-3c56-4925-a3e7-eb137fed17e9

Optionally, some endpoints may include a request ID that should be provided when reporting bugs or opening support tickets to help identify the issue.

default

There was an unexpected error.

ratelimit-limit integer

The default limit on number of requests that can be made per hour and per minute. Current rate limits are 5000 requests per hour and 250 requests per minute.

ratelimit-remaining integer

The number of requests in your hourly quota that remain before you hit your request limit. See https://docs.digitalocean.com/reference/api/reference/#rate-limit for information about how requests expire.

ratelimit-reset integer

The time when the oldest request will expire. The value is given in Unix epoch time. See https://docs.digitalocean.com/reference/api/reference/#rate-limit for information about how requests expire.

id string required
Example: not_found

A short identifier corresponding to the HTTP status code returned. For example, the ID for a response returning a 404 status code would be "not_found."

message string required
Example: The resource you were accessing could not be found.

A message providing additional information about the error, including details to help resolve it when possible.

request_id string optional
Example: 4d9d8375-3c56-4925-a3e7-eb137fed17e9

Optionally, some endpoints may include a request ID that should be provided when reporting bugs or opening support tickets to help identify the issue.

{
  "aborted": true,
  "status": "pending",
  "transfer_id": "example"
}
{
  "id": "unauthorized",
  "message": "Unable to authenticate you."
}
{
  "id": "not_found",
  "message": "The resource you were accessing could not be found.",
  "request_id": "4d9d8375-3c56-4925-a3e7-eb137fed17e9"
}
{
  "id": "not_found",
  "message": "The resource you requested could not be found."
}
{
  "id": "not_found",
  "message": "The resource you were accessing could not be found.",
  "request_id": "4d9d8375-3c56-4925-a3e7-eb137fed17e9"
}
{
  "id": "too_many_requests",
  "message": "API rate limit exceeded."
}
{
  "id": "server_error",
  "message": "Unexpected server-side error"
}
{
  "id": "not_found",
  "message": "The resource you were accessing could not be found.",
  "request_id": "4d9d8375-3c56-4925-a3e7-eb137fed17e9"
}
{
  "id": "example_error",
  "message": "some error message"
}

POST Finalize a staged upload.

/v2/agents/sessions/{session_id}/workspace/transfers/{transfer_id}/commit
Authorizations: bearer_auth (1 scope)
Http: Bearer
Required scopes: agent_harness_session:operate

OAuth Authentication

In order to interact with the DigitalOcean API, you or your application must authenticate.

The DigitalOcean API handles this through OAuth, an open standard for authorization. OAuth allows you to delegate access to your account. Scopes can be used to grant full access, read-only access, or access to a specific set of endpoints.

You can generate an OAuth token by visiting the Apps & API section of the DigitalOcean control panel for your account.

An OAuth token functions as a complete authentication request. In effect, it acts as a substitute for a username and password pair.

Because of this, it is absolutely essential that you keep your OAuth tokens secure. In fact, upon generation, the web interface will only display each token a single time in order to prevent the token from being compromised.

DigitalOcean access tokens begin with an identifiable prefix in order to distinguish them from other similar tokens.

  • dop_v1_ for personal access tokens generated in the control panel
  • doo_v1_ for tokens generated by applications using the OAuth flow
  • dor_v1_ for OAuth refresh tokens

Scopes

Scopes act like permissions assigned to an API token. These permissions determine what actions the token can perform. You can create API tokens that grant read-only access, full access, or limited access to specific endpoints by using custom scopes.

Generally, scopes are designed to match HTTP verbs and common CRUD operations (Create, Read, Update, Delete).

HTTP Verb CRUD Operation Scope
GET Read <resource>:read
POST Create <resource>:create
PUT/PATCH Update <resource>:update
DELETE Delete <resource>:delete

For example, creating a new Droplet by making a POST request to the /v2/droplets endpoint requires the droplet:create scope while listing Droplets by making a GET request to the /v2/droplets endpoint requires the droplet:read scope.

Each endpoint below specifies which scope is required to access it when using custom scopes.

How to Authenticate with OAuth

In order to make an authenticated request, include a bearer-type Authorization header containing your OAuth token. All requests must be made over HTTPS.

Authenticate with a Bearer Authorization Header

curl -X $HTTP_METHOD -H "Authorization: Bearer $DIGITALOCEAN_TOKEN" "https://api.digitalocean.com/v2/$OBJECT"

Upload only. Call once, after all parts have been uploaded. Completes the multipart upload and starts the asynchronous import into the workspace. Responds 202; poll the transfer until completed or failed.

Path Parameters

session_id string required
Example: a1b2c3d4-e5f6-7890-abcd-ef1234567890

The session UUID.

transfer_id string required
Example: tr_example

The workspace transfer identifier.

Request Body: application/json

sha256 string optional
Example: example

Optional lowercase hex SHA-256. Must match the value supplied at create when both are set.

Content type application/json
{
  "sha256": "example"
}
curl -X POST \
  -H "Content-Type: application/json" \
  -H "Authorization: Bearer $DIGITALOCEAN_TOKEN" \
  "https://api.digitalocean.com/v2/agents/sessions/{session_id}/workspace/transfers/{transfer_id}/commit"
curl -X POST \
  -H "Authorization: Bearer $API_TOKEN" \
  -H "Content-Type: application/json" \
  -d '{
  "sha256": "example"
}' \
  "https://api.digitalocean.com/v2/agents/sessions/{session_id}/workspace/transfers/{transfer_id}/commit"

Responses

202

Upload committed; import in progress.

ratelimit-limit integer

The default limit on number of requests that can be made per hour and per minute. Current rate limits are 5000 requests per hour and 250 requests per minute.

ratelimit-remaining integer

The number of requests in your hourly quota that remain before you hit your request limit. See https://docs.digitalocean.com/reference/api/reference/#rate-limit for information about how requests expire.

ratelimit-reset integer

The time when the oldest request will expire. The value is given in Unix epoch time. See https://docs.digitalocean.com/reference/api/reference/#rate-limit for information about how requests expire.

size_bytes integer (int64) optional
Example: 1

Size of the completed staging object, when known.

status string, one of: pending, in_progress, completed, failed optional
Example: pending
transfer_id string optional
Example: example
400

Missing transfer_id, sha256 mismatch, or invalid JSON.

ratelimit-limit integer

The default limit on number of requests that can be made per hour and per minute. Current rate limits are 5000 requests per hour and 250 requests per minute.

ratelimit-remaining integer

The number of requests in your hourly quota that remain before you hit your request limit. See https://docs.digitalocean.com/reference/api/reference/#rate-limit for information about how requests expire.

ratelimit-reset integer

The time when the oldest request will expire. The value is given in Unix epoch time. See https://docs.digitalocean.com/reference/api/reference/#rate-limit for information about how requests expire.

id string required
Example: not_found

A short identifier corresponding to the HTTP status code returned. For example, the ID for a response returning a 404 status code would be "not_found."

message string required
Example: The resource you were accessing could not be found.

A message providing additional information about the error, including details to help resolve it when possible.

request_id string optional
Example: 4d9d8375-3c56-4925-a3e7-eb137fed17e9

Optionally, some endpoints may include a request ID that should be provided when reporting bugs or opening support tickets to help identify the issue.

401

Authentication failed due to invalid credentials.

ratelimit-limit integer

The default limit on number of requests that can be made per hour and per minute. Current rate limits are 5000 requests per hour and 250 requests per minute.

ratelimit-remaining integer

The number of requests in your hourly quota that remain before you hit your request limit. See https://docs.digitalocean.com/reference/api/reference/#rate-limit for information about how requests expire.

ratelimit-reset integer

The time when the oldest request will expire. The value is given in Unix epoch time. See https://docs.digitalocean.com/reference/api/reference/#rate-limit for information about how requests expire.

id string required
Example: not_found

A short identifier corresponding to the HTTP status code returned. For example, the ID for a response returning a 404 status code would be "not_found."

message string required
Example: The resource you were accessing could not be found.

A message providing additional information about the error, including details to help resolve it when possible.

request_id string optional
Example: 4d9d8375-3c56-4925-a3e7-eb137fed17e9

Optionally, some endpoints may include a request ID that should be provided when reporting bugs or opening support tickets to help identify the issue.

402

The team is blocked by the prepayment gate.

ratelimit-limit integer

The default limit on number of requests that can be made per hour and per minute. Current rate limits are 5000 requests per hour and 250 requests per minute.

ratelimit-remaining integer

The number of requests in your hourly quota that remain before you hit your request limit. See https://docs.digitalocean.com/reference/api/reference/#rate-limit for information about how requests expire.

ratelimit-reset integer

The time when the oldest request will expire. The value is given in Unix epoch time. See https://docs.digitalocean.com/reference/api/reference/#rate-limit for information about how requests expire.

id string required
Example: not_found

A short identifier corresponding to the HTTP status code returned. For example, the ID for a response returning a 404 status code would be "not_found."

message string required
Example: The resource you were accessing could not be found.

A message providing additional information about the error, including details to help resolve it when possible.

request_id string optional
Example: 4d9d8375-3c56-4925-a3e7-eb137fed17e9

Optionally, some endpoints may include a request ID that should be provided when reporting bugs or opening support tickets to help identify the issue.

404

The resource was not found.

ratelimit-limit integer

The default limit on number of requests that can be made per hour and per minute. Current rate limits are 5000 requests per hour and 250 requests per minute.

ratelimit-remaining integer

The number of requests in your hourly quota that remain before you hit your request limit. See https://docs.digitalocean.com/reference/api/reference/#rate-limit for information about how requests expire.

ratelimit-reset integer

The time when the oldest request will expire. The value is given in Unix epoch time. See https://docs.digitalocean.com/reference/api/reference/#rate-limit for information about how requests expire.

id string required
Example: not_found

A short identifier corresponding to the HTTP status code returned. For example, the ID for a response returning a 404 status code would be "not_found."

message string required
Example: The resource you were accessing could not be found.

A message providing additional information about the error, including details to help resolve it when possible.

request_id string optional
Example: 4d9d8375-3c56-4925-a3e7-eb137fed17e9

Optionally, some endpoints may include a request ID that should be provided when reporting bugs or opening support tickets to help identify the issue.

409

Transfer is not in a committable state.

ratelimit-limit integer

The default limit on number of requests that can be made per hour and per minute. Current rate limits are 5000 requests per hour and 250 requests per minute.

ratelimit-remaining integer

The number of requests in your hourly quota that remain before you hit your request limit. See https://docs.digitalocean.com/reference/api/reference/#rate-limit for information about how requests expire.

ratelimit-reset integer

The time when the oldest request will expire. The value is given in Unix epoch time. See https://docs.digitalocean.com/reference/api/reference/#rate-limit for information about how requests expire.

id string required
Example: not_found

A short identifier corresponding to the HTTP status code returned. For example, the ID for a response returning a 404 status code would be "not_found."

message string required
Example: The resource you were accessing could not be found.

A message providing additional information about the error, including details to help resolve it when possible.

request_id string optional
Example: 4d9d8375-3c56-4925-a3e7-eb137fed17e9

Optionally, some endpoints may include a request ID that should be provided when reporting bugs or opening support tickets to help identify the issue.

423

This session is unavailable; contact support.

ratelimit-limit integer

The default limit on number of requests that can be made per hour and per minute. Current rate limits are 5000 requests per hour and 250 requests per minute.

ratelimit-remaining integer

The number of requests in your hourly quota that remain before you hit your request limit. See https://docs.digitalocean.com/reference/api/reference/#rate-limit for information about how requests expire.

ratelimit-reset integer

The time when the oldest request will expire. The value is given in Unix epoch time. See https://docs.digitalocean.com/reference/api/reference/#rate-limit for information about how requests expire.

id string required
Example: not_found

A short identifier corresponding to the HTTP status code returned. For example, the ID for a response returning a 404 status code would be "not_found."

message string required
Example: The resource you were accessing could not be found.

A message providing additional information about the error, including details to help resolve it when possible.

request_id string optional
Example: 4d9d8375-3c56-4925-a3e7-eb137fed17e9

Optionally, some endpoints may include a request ID that should be provided when reporting bugs or opening support tickets to help identify the issue.

429

The API rate limit has been exceeded.

ratelimit-limit integer

The default limit on number of requests that can be made per hour and per minute. Current rate limits are 5000 requests per hour and 250 requests per minute.

ratelimit-remaining integer

The number of requests in your hourly quota that remain before you hit your request limit. See https://docs.digitalocean.com/reference/api/reference/#rate-limit for information about how requests expire.

ratelimit-reset integer

The time when the oldest request will expire. The value is given in Unix epoch time. See https://docs.digitalocean.com/reference/api/reference/#rate-limit for information about how requests expire.

id string required
Example: not_found

A short identifier corresponding to the HTTP status code returned. For example, the ID for a response returning a 404 status code would be "not_found."

message string required
Example: The resource you were accessing could not be found.

A message providing additional information about the error, including details to help resolve it when possible.

request_id string optional
Example: 4d9d8375-3c56-4925-a3e7-eb137fed17e9

Optionally, some endpoints may include a request ID that should be provided when reporting bugs or opening support tickets to help identify the issue.

500

There was a server error.

ratelimit-limit integer

The default limit on number of requests that can be made per hour and per minute. Current rate limits are 5000 requests per hour and 250 requests per minute.

ratelimit-remaining integer

The number of requests in your hourly quota that remain before you hit your request limit. See https://docs.digitalocean.com/reference/api/reference/#rate-limit for information about how requests expire.

ratelimit-reset integer

The time when the oldest request will expire. The value is given in Unix epoch time. See https://docs.digitalocean.com/reference/api/reference/#rate-limit for information about how requests expire.

id string required
Example: not_found

A short identifier corresponding to the HTTP status code returned. For example, the ID for a response returning a 404 status code would be "not_found."

message string required
Example: The resource you were accessing could not be found.

A message providing additional information about the error, including details to help resolve it when possible.

request_id string optional
Example: 4d9d8375-3c56-4925-a3e7-eb137fed17e9

Optionally, some endpoints may include a request ID that should be provided when reporting bugs or opening support tickets to help identify the issue.

501

Staged upload is not supported by the active sandbox driver.

ratelimit-limit integer

The default limit on number of requests that can be made per hour and per minute. Current rate limits are 5000 requests per hour and 250 requests per minute.

ratelimit-remaining integer

The number of requests in your hourly quota that remain before you hit your request limit. See https://docs.digitalocean.com/reference/api/reference/#rate-limit for information about how requests expire.

ratelimit-reset integer

The time when the oldest request will expire. The value is given in Unix epoch time. See https://docs.digitalocean.com/reference/api/reference/#rate-limit for information about how requests expire.

id string required
Example: not_found

A short identifier corresponding to the HTTP status code returned. For example, the ID for a response returning a 404 status code would be "not_found."

message string required
Example: The resource you were accessing could not be found.

A message providing additional information about the error, including details to help resolve it when possible.

request_id string optional
Example: 4d9d8375-3c56-4925-a3e7-eb137fed17e9

Optionally, some endpoints may include a request ID that should be provided when reporting bugs or opening support tickets to help identify the issue.

default

There was an unexpected error.

ratelimit-limit integer

The default limit on number of requests that can be made per hour and per minute. Current rate limits are 5000 requests per hour and 250 requests per minute.

ratelimit-remaining integer

The number of requests in your hourly quota that remain before you hit your request limit. See https://docs.digitalocean.com/reference/api/reference/#rate-limit for information about how requests expire.

ratelimit-reset integer

The time when the oldest request will expire. The value is given in Unix epoch time. See https://docs.digitalocean.com/reference/api/reference/#rate-limit for information about how requests expire.

id string required
Example: not_found

A short identifier corresponding to the HTTP status code returned. For example, the ID for a response returning a 404 status code would be "not_found."

message string required
Example: The resource you were accessing could not be found.

A message providing additional information about the error, including details to help resolve it when possible.

request_id string optional
Example: 4d9d8375-3c56-4925-a3e7-eb137fed17e9

Optionally, some endpoints may include a request ID that should be provided when reporting bugs or opening support tickets to help identify the issue.

{
  "size_bytes": 1,
  "status": "pending",
  "transfer_id": "example"
}
{
  "id": "not_found",
  "message": "The resource you were accessing could not be found.",
  "request_id": "4d9d8375-3c56-4925-a3e7-eb137fed17e9"
}
{
  "id": "unauthorized",
  "message": "Unable to authenticate you."
}
{
  "id": "not_found",
  "message": "The resource you were accessing could not be found.",
  "request_id": "4d9d8375-3c56-4925-a3e7-eb137fed17e9"
}
{
  "id": "not_found",
  "message": "The resource you requested could not be found."
}
{
  "id": "not_found",
  "message": "The resource you were accessing could not be found.",
  "request_id": "4d9d8375-3c56-4925-a3e7-eb137fed17e9"
}
{
  "id": "not_found",
  "message": "The resource you were accessing could not be found.",
  "request_id": "4d9d8375-3c56-4925-a3e7-eb137fed17e9"
}
{
  "id": "too_many_requests",
  "message": "API rate limit exceeded."
}
{
  "id": "server_error",
  "message": "Unexpected server-side error"
}
{
  "id": "not_found",
  "message": "The resource you were accessing could not be found.",
  "request_id": "4d9d8375-3c56-4925-a3e7-eb137fed17e9"
}
{
  "id": "example_error",
  "message": "some error message"
}

POST Mint presigned PUT URLs for one or more multipart upload parts.

/v2/agents/sessions/{session_id}/workspace/transfers/{transfer_id}/part-upload-urls
Authorizations: bearer_auth (1 scope)
Http: Bearer
Required scopes: agent_harness_session:operate

OAuth Authentication

In order to interact with the DigitalOcean API, you or your application must authenticate.

The DigitalOcean API handles this through OAuth, an open standard for authorization. OAuth allows you to delegate access to your account. Scopes can be used to grant full access, read-only access, or access to a specific set of endpoints.

You can generate an OAuth token by visiting the Apps & API section of the DigitalOcean control panel for your account.

An OAuth token functions as a complete authentication request. In effect, it acts as a substitute for a username and password pair.

Because of this, it is absolutely essential that you keep your OAuth tokens secure. In fact, upon generation, the web interface will only display each token a single time in order to prevent the token from being compromised.

DigitalOcean access tokens begin with an identifiable prefix in order to distinguish them from other similar tokens.

  • dop_v1_ for personal access tokens generated in the control panel
  • doo_v1_ for tokens generated by applications using the OAuth flow
  • dor_v1_ for OAuth refresh tokens

Scopes

Scopes act like permissions assigned to an API token. These permissions determine what actions the token can perform. You can create API tokens that grant read-only access, full access, or limited access to specific endpoints by using custom scopes.

Generally, scopes are designed to match HTTP verbs and common CRUD operations (Create, Read, Update, Delete).

HTTP Verb CRUD Operation Scope
GET Read <resource>:read
POST Create <resource>:create
PUT/PATCH Update <resource>:update
DELETE Delete <resource>:delete

For example, creating a new Droplet by making a POST request to the /v2/droplets endpoint requires the droplet:create scope while listing Droplets by making a GET request to the /v2/droplets endpoint requires the droplet:read scope.

Each endpoint below specifies which scope is required to access it when using custom scopes.

How to Authenticate with OAuth

In order to make an authenticated request, include a bearer-type Authorization header containing your OAuth token. All requests must be made over HTTPS.

Authenticate with a Bearer Authorization Header

curl -X $HTTP_METHOD -H "Authorization: Bearer $DIGITALOCEAN_TOKEN" "https://api.digitalocean.com/v2/$OBJECT"

Upload only. Pass one or more 1-based part_numbers; the response returns a presigned upload_url per part (all sharing one expires_at), so a client can drive parallel part uploads without a round trip per part. PUT each part's bytes directly to its URL (bypassing harness-api). If URLs expire before the PUT, request them again.

Path Parameters

session_id string required
Example: a1b2c3d4-e5f6-7890-abcd-ef1234567890

The session UUID.

transfer_id string required
Example: tr_example

The workspace transfer identifier.

Request Body: application/json

part_numbers array of integer (int32) required

1-based part indices to presign (single or batched).

Content type application/json
{
  "part_numbers": [
    1
  ]
}
curl -X POST \
  -H "Content-Type: application/json" \
  -H "Authorization: Bearer $DIGITALOCEAN_TOKEN" \
  "https://api.digitalocean.com/v2/agents/sessions/{session_id}/workspace/transfers/{transfer_id}/part-upload-urls"
curl -X POST \
  -H "Authorization: Bearer $API_TOKEN" \
  -H "Content-Type: application/json" \
  -d '{
  "part_numbers": [
    1
  ]
}' \
  "https://api.digitalocean.com/v2/agents/sessions/{session_id}/workspace/transfers/{transfer_id}/part-upload-urls"

Responses

200

Presigned PUT URLs for the requested parts.

ratelimit-limit integer

The default limit on number of requests that can be made per hour and per minute. Current rate limits are 5000 requests per hour and 250 requests per minute.

ratelimit-remaining integer

The number of requests in your hourly quota that remain before you hit your request limit. See https://docs.digitalocean.com/reference/api/reference/#rate-limit for information about how requests expire.

ratelimit-reset integer

The time when the oldest request will expire. The value is given in Unix epoch time. See https://docs.digitalocean.com/reference/api/reference/#rate-limit for information about how requests expire.

expires_at string (date-time) optional
Example: 2026-07-27T12:00:00Z

Shared expiry for all URLs in this batch.

part_urls array of object optional

One presigned PUT URL per requested part number, in request order.

Show child properties
part_number integer (int32) optional
Example: 1
upload_url string optional
Example: example

Presigned PUT URL for this part. PUT the part bytes here directly.

transfer_id string optional
Example: example
400

Missing transfer_id, empty part_numbers, or a part number < 1, or invalid JSON.

ratelimit-limit integer

The default limit on number of requests that can be made per hour and per minute. Current rate limits are 5000 requests per hour and 250 requests per minute.

ratelimit-remaining integer

The number of requests in your hourly quota that remain before you hit your request limit. See https://docs.digitalocean.com/reference/api/reference/#rate-limit for information about how requests expire.

ratelimit-reset integer

The time when the oldest request will expire. The value is given in Unix epoch time. See https://docs.digitalocean.com/reference/api/reference/#rate-limit for information about how requests expire.

id string required
Example: not_found

A short identifier corresponding to the HTTP status code returned. For example, the ID for a response returning a 404 status code would be "not_found."

message string required
Example: The resource you were accessing could not be found.

A message providing additional information about the error, including details to help resolve it when possible.

request_id string optional
Example: 4d9d8375-3c56-4925-a3e7-eb137fed17e9

Optionally, some endpoints may include a request ID that should be provided when reporting bugs or opening support tickets to help identify the issue.

401

Authentication failed due to invalid credentials.

ratelimit-limit integer

The default limit on number of requests that can be made per hour and per minute. Current rate limits are 5000 requests per hour and 250 requests per minute.

ratelimit-remaining integer

The number of requests in your hourly quota that remain before you hit your request limit. See https://docs.digitalocean.com/reference/api/reference/#rate-limit for information about how requests expire.

ratelimit-reset integer

The time when the oldest request will expire. The value is given in Unix epoch time. See https://docs.digitalocean.com/reference/api/reference/#rate-limit for information about how requests expire.

id string required
Example: not_found

A short identifier corresponding to the HTTP status code returned. For example, the ID for a response returning a 404 status code would be "not_found."

message string required
Example: The resource you were accessing could not be found.

A message providing additional information about the error, including details to help resolve it when possible.

request_id string optional
Example: 4d9d8375-3c56-4925-a3e7-eb137fed17e9

Optionally, some endpoints may include a request ID that should be provided when reporting bugs or opening support tickets to help identify the issue.

402

The team is blocked by the prepayment gate.

ratelimit-limit integer

The default limit on number of requests that can be made per hour and per minute. Current rate limits are 5000 requests per hour and 250 requests per minute.

ratelimit-remaining integer

The number of requests in your hourly quota that remain before you hit your request limit. See https://docs.digitalocean.com/reference/api/reference/#rate-limit for information about how requests expire.

ratelimit-reset integer

The time when the oldest request will expire. The value is given in Unix epoch time. See https://docs.digitalocean.com/reference/api/reference/#rate-limit for information about how requests expire.

id string required
Example: not_found

A short identifier corresponding to the HTTP status code returned. For example, the ID for a response returning a 404 status code would be "not_found."

message string required
Example: The resource you were accessing could not be found.

A message providing additional information about the error, including details to help resolve it when possible.

request_id string optional
Example: 4d9d8375-3c56-4925-a3e7-eb137fed17e9

Optionally, some endpoints may include a request ID that should be provided when reporting bugs or opening support tickets to help identify the issue.

404

The resource was not found.

ratelimit-limit integer

The default limit on number of requests that can be made per hour and per minute. Current rate limits are 5000 requests per hour and 250 requests per minute.

ratelimit-remaining integer

The number of requests in your hourly quota that remain before you hit your request limit. See https://docs.digitalocean.com/reference/api/reference/#rate-limit for information about how requests expire.

ratelimit-reset integer

The time when the oldest request will expire. The value is given in Unix epoch time. See https://docs.digitalocean.com/reference/api/reference/#rate-limit for information about how requests expire.

id string required
Example: not_found

A short identifier corresponding to the HTTP status code returned. For example, the ID for a response returning a 404 status code would be "not_found."

message string required
Example: The resource you were accessing could not be found.

A message providing additional information about the error, including details to help resolve it when possible.

request_id string optional
Example: 4d9d8375-3c56-4925-a3e7-eb137fed17e9

Optionally, some endpoints may include a request ID that should be provided when reporting bugs or opening support tickets to help identify the issue.

409

Transfer is not in a state that accepts part uploads.

ratelimit-limit integer

The default limit on number of requests that can be made per hour and per minute. Current rate limits are 5000 requests per hour and 250 requests per minute.

ratelimit-remaining integer

The number of requests in your hourly quota that remain before you hit your request limit. See https://docs.digitalocean.com/reference/api/reference/#rate-limit for information about how requests expire.

ratelimit-reset integer

The time when the oldest request will expire. The value is given in Unix epoch time. See https://docs.digitalocean.com/reference/api/reference/#rate-limit for information about how requests expire.

id string required
Example: not_found

A short identifier corresponding to the HTTP status code returned. For example, the ID for a response returning a 404 status code would be "not_found."

message string required
Example: The resource you were accessing could not be found.

A message providing additional information about the error, including details to help resolve it when possible.

request_id string optional
Example: 4d9d8375-3c56-4925-a3e7-eb137fed17e9

Optionally, some endpoints may include a request ID that should be provided when reporting bugs or opening support tickets to help identify the issue.

423

This session is unavailable; contact support.

ratelimit-limit integer

The default limit on number of requests that can be made per hour and per minute. Current rate limits are 5000 requests per hour and 250 requests per minute.

ratelimit-remaining integer

The number of requests in your hourly quota that remain before you hit your request limit. See https://docs.digitalocean.com/reference/api/reference/#rate-limit for information about how requests expire.

ratelimit-reset integer

The time when the oldest request will expire. The value is given in Unix epoch time. See https://docs.digitalocean.com/reference/api/reference/#rate-limit for information about how requests expire.

id string required
Example: not_found

A short identifier corresponding to the HTTP status code returned. For example, the ID for a response returning a 404 status code would be "not_found."

message string required
Example: The resource you were accessing could not be found.

A message providing additional information about the error, including details to help resolve it when possible.

request_id string optional
Example: 4d9d8375-3c56-4925-a3e7-eb137fed17e9

Optionally, some endpoints may include a request ID that should be provided when reporting bugs or opening support tickets to help identify the issue.

429

The API rate limit has been exceeded.

ratelimit-limit integer

The default limit on number of requests that can be made per hour and per minute. Current rate limits are 5000 requests per hour and 250 requests per minute.

ratelimit-remaining integer

The number of requests in your hourly quota that remain before you hit your request limit. See https://docs.digitalocean.com/reference/api/reference/#rate-limit for information about how requests expire.

ratelimit-reset integer

The time when the oldest request will expire. The value is given in Unix epoch time. See https://docs.digitalocean.com/reference/api/reference/#rate-limit for information about how requests expire.

id string required
Example: not_found

A short identifier corresponding to the HTTP status code returned. For example, the ID for a response returning a 404 status code would be "not_found."

message string required
Example: The resource you were accessing could not be found.

A message providing additional information about the error, including details to help resolve it when possible.

request_id string optional
Example: 4d9d8375-3c56-4925-a3e7-eb137fed17e9

Optionally, some endpoints may include a request ID that should be provided when reporting bugs or opening support tickets to help identify the issue.

500

There was a server error.

ratelimit-limit integer

The default limit on number of requests that can be made per hour and per minute. Current rate limits are 5000 requests per hour and 250 requests per minute.

ratelimit-remaining integer

The number of requests in your hourly quota that remain before you hit your request limit. See https://docs.digitalocean.com/reference/api/reference/#rate-limit for information about how requests expire.

ratelimit-reset integer

The time when the oldest request will expire. The value is given in Unix epoch time. See https://docs.digitalocean.com/reference/api/reference/#rate-limit for information about how requests expire.

id string required
Example: not_found

A short identifier corresponding to the HTTP status code returned. For example, the ID for a response returning a 404 status code would be "not_found."

message string required
Example: The resource you were accessing could not be found.

A message providing additional information about the error, including details to help resolve it when possible.

request_id string optional
Example: 4d9d8375-3c56-4925-a3e7-eb137fed17e9

Optionally, some endpoints may include a request ID that should be provided when reporting bugs or opening support tickets to help identify the issue.

501

Staged upload is not supported by the active sandbox driver.

ratelimit-limit integer

The default limit on number of requests that can be made per hour and per minute. Current rate limits are 5000 requests per hour and 250 requests per minute.

ratelimit-remaining integer

The number of requests in your hourly quota that remain before you hit your request limit. See https://docs.digitalocean.com/reference/api/reference/#rate-limit for information about how requests expire.

ratelimit-reset integer

The time when the oldest request will expire. The value is given in Unix epoch time. See https://docs.digitalocean.com/reference/api/reference/#rate-limit for information about how requests expire.

id string required
Example: not_found

A short identifier corresponding to the HTTP status code returned. For example, the ID for a response returning a 404 status code would be "not_found."

message string required
Example: The resource you were accessing could not be found.

A message providing additional information about the error, including details to help resolve it when possible.

request_id string optional
Example: 4d9d8375-3c56-4925-a3e7-eb137fed17e9

Optionally, some endpoints may include a request ID that should be provided when reporting bugs or opening support tickets to help identify the issue.

default

There was an unexpected error.

ratelimit-limit integer

The default limit on number of requests that can be made per hour and per minute. Current rate limits are 5000 requests per hour and 250 requests per minute.

ratelimit-remaining integer

The number of requests in your hourly quota that remain before you hit your request limit. See https://docs.digitalocean.com/reference/api/reference/#rate-limit for information about how requests expire.

ratelimit-reset integer

The time when the oldest request will expire. The value is given in Unix epoch time. See https://docs.digitalocean.com/reference/api/reference/#rate-limit for information about how requests expire.

id string required
Example: not_found

A short identifier corresponding to the HTTP status code returned. For example, the ID for a response returning a 404 status code would be "not_found."

message string required
Example: The resource you were accessing could not be found.

A message providing additional information about the error, including details to help resolve it when possible.

request_id string optional
Example: 4d9d8375-3c56-4925-a3e7-eb137fed17e9

Optionally, some endpoints may include a request ID that should be provided when reporting bugs or opening support tickets to help identify the issue.

{
  "expires_at": "2026-07-27T12:00:00Z",
  "part_urls": [
    {
      "part_number": 1,
      "upload_url": "example"
    }
  ],
  "transfer_id": "example"
}
{
  "id": "not_found",
  "message": "The resource you were accessing could not be found.",
  "request_id": "4d9d8375-3c56-4925-a3e7-eb137fed17e9"
}
{
  "id": "unauthorized",
  "message": "Unable to authenticate you."
}
{
  "id": "not_found",
  "message": "The resource you were accessing could not be found.",
  "request_id": "4d9d8375-3c56-4925-a3e7-eb137fed17e9"
}
{
  "id": "not_found",
  "message": "The resource you requested could not be found."
}
{
  "id": "not_found",
  "message": "The resource you were accessing could not be found.",
  "request_id": "4d9d8375-3c56-4925-a3e7-eb137fed17e9"
}
{
  "id": "not_found",
  "message": "The resource you were accessing could not be found.",
  "request_id": "4d9d8375-3c56-4925-a3e7-eb137fed17e9"
}
{
  "id": "too_many_requests",
  "message": "API rate limit exceeded."
}
{
  "id": "server_error",
  "message": "Unexpected server-side error"
}
{
  "id": "not_found",
  "message": "The resource you were accessing could not be found.",
  "request_id": "4d9d8375-3c56-4925-a3e7-eb137fed17e9"
}
{
  "id": "example_error",
  "message": "some error message"
}

POST Upload a file or tar archive into the session's sandbox workspace.

/v2/agents/sessions/{session_id}/workspace/upload
Authorizations: bearer_auth (1 scope)
Http: Bearer
Required scopes: agent_harness_session:operate

OAuth Authentication

In order to interact with the DigitalOcean API, you or your application must authenticate.

The DigitalOcean API handles this through OAuth, an open standard for authorization. OAuth allows you to delegate access to your account. Scopes can be used to grant full access, read-only access, or access to a specific set of endpoints.

You can generate an OAuth token by visiting the Apps & API section of the DigitalOcean control panel for your account.

An OAuth token functions as a complete authentication request. In effect, it acts as a substitute for a username and password pair.

Because of this, it is absolutely essential that you keep your OAuth tokens secure. In fact, upon generation, the web interface will only display each token a single time in order to prevent the token from being compromised.

DigitalOcean access tokens begin with an identifiable prefix in order to distinguish them from other similar tokens.

  • dop_v1_ for personal access tokens generated in the control panel
  • doo_v1_ for tokens generated by applications using the OAuth flow
  • dor_v1_ for OAuth refresh tokens

Scopes

Scopes act like permissions assigned to an API token. These permissions determine what actions the token can perform. You can create API tokens that grant read-only access, full access, or limited access to specific endpoints by using custom scopes.

Generally, scopes are designed to match HTTP verbs and common CRUD operations (Create, Read, Update, Delete).

HTTP Verb CRUD Operation Scope
GET Read <resource>:read
POST Create <resource>:create
PUT/PATCH Update <resource>:update
DELETE Delete <resource>:delete

For example, creating a new Droplet by making a POST request to the /v2/droplets endpoint requires the droplet:create scope while listing Droplets by making a GET request to the /v2/droplets endpoint requires the droplet:read scope.

Each endpoint below specifies which scope is required to access it when using custom scopes.

How to Authenticate with OAuth

In order to make an authenticated request, include a bearer-type Authorization header containing your OAuth token. All requests must be made over HTTPS.

Authenticate with a Bearer Authorization Header

curl -X $HTTP_METHOD -H "Authorization: Bearer $DIGITALOCEAN_TOKEN" "https://api.digitalocean.com/v2/$OBJECT"

Streams the raw request body to a path inside the sandbox workspace. Concurrent transfers (upload + download) are capped server-side; over the cap the request blocks and may return 503. The optional X-Content-Sha256 request header carries a hex digest the guest verifies after the full payload is written.

Path Parameters

session_id string required
Example: a1b2c3d4-e5f6-7890-abcd-ef1234567890

The session UUID.

Query Parameters

path string required
Example: example

Destination path inside the sandbox workspace. Relative paths resolve under the workspace root; paths that escape the workspace are rejected. Required.

is_archive boolean optional
Example: true

If true, the body is a tar stream that the guest extracts under path. Defaults to false (single file).

Header Parameters

X-Content-Sha256 string optional
Example: example

Optional hex SHA-256 of the full payload. The guest verifies it after writing; a mismatch returns 400.

Request Body: application/octet-stream

Raw file bytes (or tar stream when is_archive=true). Capped at 500 MiB.

Content type application/octet-stream
"example"
curl -X POST \
  -H "Content-Type: application/json" \
  -H "Authorization: Bearer $DIGITALOCEAN_TOKEN" \
  "https://api.digitalocean.com/v2/agents/sessions/{session_id}/workspace/upload"
curl -X POST \
  -H "Authorization: Bearer $API_TOKEN" \
  -H "Content-Type: application/octet-stream" \
  -d '"example"' \
  "https://api.digitalocean.com/v2/agents/sessions/{session_id}/workspace/upload"

Responses

200

Upload committed.

ratelimit-limit integer

The default limit on number of requests that can be made per hour and per minute. Current rate limits are 5000 requests per hour and 250 requests per minute.

ratelimit-remaining integer

The number of requests in your hourly quota that remain before you hit your request limit. See https://docs.digitalocean.com/reference/api/reference/#rate-limit for information about how requests expire.

ratelimit-reset integer

The time when the oldest request will expire. The value is given in Unix epoch time. See https://docs.digitalocean.com/reference/api/reference/#rate-limit for information about how requests expire.

bytes_written integer (int64) optional
Example: 1

Number of bytes committed to the workspace.

path string optional
Example: example

Absolute guest path the payload was written to.

400

Missing path, invalid query parameter, invalid path, or SHA-256 mismatch.

ratelimit-limit integer

The default limit on number of requests that can be made per hour and per minute. Current rate limits are 5000 requests per hour and 250 requests per minute.

ratelimit-remaining integer

The number of requests in your hourly quota that remain before you hit your request limit. See https://docs.digitalocean.com/reference/api/reference/#rate-limit for information about how requests expire.

ratelimit-reset integer

The time when the oldest request will expire. The value is given in Unix epoch time. See https://docs.digitalocean.com/reference/api/reference/#rate-limit for information about how requests expire.

id string required
Example: not_found

A short identifier corresponding to the HTTP status code returned. For example, the ID for a response returning a 404 status code would be "not_found."

message string required
Example: The resource you were accessing could not be found.

A message providing additional information about the error, including details to help resolve it when possible.

request_id string optional
Example: 4d9d8375-3c56-4925-a3e7-eb137fed17e9

Optionally, some endpoints may include a request ID that should be provided when reporting bugs or opening support tickets to help identify the issue.

401

Authentication failed due to invalid credentials.

ratelimit-limit integer

The default limit on number of requests that can be made per hour and per minute. Current rate limits are 5000 requests per hour and 250 requests per minute.

ratelimit-remaining integer

The number of requests in your hourly quota that remain before you hit your request limit. See https://docs.digitalocean.com/reference/api/reference/#rate-limit for information about how requests expire.

ratelimit-reset integer

The time when the oldest request will expire. The value is given in Unix epoch time. See https://docs.digitalocean.com/reference/api/reference/#rate-limit for information about how requests expire.

id string required
Example: not_found

A short identifier corresponding to the HTTP status code returned. For example, the ID for a response returning a 404 status code would be "not_found."

message string required
Example: The resource you were accessing could not be found.

A message providing additional information about the error, including details to help resolve it when possible.

request_id string optional
Example: 4d9d8375-3c56-4925-a3e7-eb137fed17e9

Optionally, some endpoints may include a request ID that should be provided when reporting bugs or opening support tickets to help identify the issue.

402

The team is blocked by the prepayment gate.

ratelimit-limit integer

The default limit on number of requests that can be made per hour and per minute. Current rate limits are 5000 requests per hour and 250 requests per minute.

ratelimit-remaining integer

The number of requests in your hourly quota that remain before you hit your request limit. See https://docs.digitalocean.com/reference/api/reference/#rate-limit for information about how requests expire.

ratelimit-reset integer

The time when the oldest request will expire. The value is given in Unix epoch time. See https://docs.digitalocean.com/reference/api/reference/#rate-limit for information about how requests expire.

id string required
Example: not_found

A short identifier corresponding to the HTTP status code returned. For example, the ID for a response returning a 404 status code would be "not_found."

message string required
Example: The resource you were accessing could not be found.

A message providing additional information about the error, including details to help resolve it when possible.

request_id string optional
Example: 4d9d8375-3c56-4925-a3e7-eb137fed17e9

Optionally, some endpoints may include a request ID that should be provided when reporting bugs or opening support tickets to help identify the issue.

403

Path resolves outside the workspace, or the session belongs to another team.

ratelimit-limit integer

The default limit on number of requests that can be made per hour and per minute. Current rate limits are 5000 requests per hour and 250 requests per minute.

ratelimit-remaining integer

The number of requests in your hourly quota that remain before you hit your request limit. See https://docs.digitalocean.com/reference/api/reference/#rate-limit for information about how requests expire.

ratelimit-reset integer

The time when the oldest request will expire. The value is given in Unix epoch time. See https://docs.digitalocean.com/reference/api/reference/#rate-limit for information about how requests expire.

id string required
Example: not_found

A short identifier corresponding to the HTTP status code returned. For example, the ID for a response returning a 404 status code would be "not_found."

message string required
Example: The resource you were accessing could not be found.

A message providing additional information about the error, including details to help resolve it when possible.

request_id string optional
Example: 4d9d8375-3c56-4925-a3e7-eb137fed17e9

Optionally, some endpoints may include a request ID that should be provided when reporting bugs or opening support tickets to help identify the issue.

404

The resource was not found.

ratelimit-limit integer

The default limit on number of requests that can be made per hour and per minute. Current rate limits are 5000 requests per hour and 250 requests per minute.

ratelimit-remaining integer

The number of requests in your hourly quota that remain before you hit your request limit. See https://docs.digitalocean.com/reference/api/reference/#rate-limit for information about how requests expire.

ratelimit-reset integer

The time when the oldest request will expire. The value is given in Unix epoch time. See https://docs.digitalocean.com/reference/api/reference/#rate-limit for information about how requests expire.

id string required
Example: not_found

A short identifier corresponding to the HTTP status code returned. For example, the ID for a response returning a 404 status code would be "not_found."

message string required
Example: The resource you were accessing could not be found.

A message providing additional information about the error, including details to help resolve it when possible.

request_id string optional
Example: 4d9d8375-3c56-4925-a3e7-eb137fed17e9

Optionally, some endpoints may include a request ID that should be provided when reporting bugs or opening support tickets to help identify the issue.

409

Session has no sandbox, or the sandbox is not ready.

ratelimit-limit integer

The default limit on number of requests that can be made per hour and per minute. Current rate limits are 5000 requests per hour and 250 requests per minute.

ratelimit-remaining integer

The number of requests in your hourly quota that remain before you hit your request limit. See https://docs.digitalocean.com/reference/api/reference/#rate-limit for information about how requests expire.

ratelimit-reset integer

The time when the oldest request will expire. The value is given in Unix epoch time. See https://docs.digitalocean.com/reference/api/reference/#rate-limit for information about how requests expire.

id string required
Example: not_found

A short identifier corresponding to the HTTP status code returned. For example, the ID for a response returning a 404 status code would be "not_found."

message string required
Example: The resource you were accessing could not be found.

A message providing additional information about the error, including details to help resolve it when possible.

request_id string optional
Example: 4d9d8375-3c56-4925-a3e7-eb137fed17e9

Optionally, some endpoints may include a request ID that should be provided when reporting bugs or opening support tickets to help identify the issue.

413

Payload exceeds the maximum allowed size.

ratelimit-limit integer

The default limit on number of requests that can be made per hour and per minute. Current rate limits are 5000 requests per hour and 250 requests per minute.

ratelimit-remaining integer

The number of requests in your hourly quota that remain before you hit your request limit. See https://docs.digitalocean.com/reference/api/reference/#rate-limit for information about how requests expire.

ratelimit-reset integer

The time when the oldest request will expire. The value is given in Unix epoch time. See https://docs.digitalocean.com/reference/api/reference/#rate-limit for information about how requests expire.

id string required
Example: not_found

A short identifier corresponding to the HTTP status code returned. For example, the ID for a response returning a 404 status code would be "not_found."

message string required
Example: The resource you were accessing could not be found.

A message providing additional information about the error, including details to help resolve it when possible.

request_id string optional
Example: 4d9d8375-3c56-4925-a3e7-eb137fed17e9

Optionally, some endpoints may include a request ID that should be provided when reporting bugs or opening support tickets to help identify the issue.

423

This session is unavailable; contact support.

ratelimit-limit integer

The default limit on number of requests that can be made per hour and per minute. Current rate limits are 5000 requests per hour and 250 requests per minute.

ratelimit-remaining integer

The number of requests in your hourly quota that remain before you hit your request limit. See https://docs.digitalocean.com/reference/api/reference/#rate-limit for information about how requests expire.

ratelimit-reset integer

The time when the oldest request will expire. The value is given in Unix epoch time. See https://docs.digitalocean.com/reference/api/reference/#rate-limit for information about how requests expire.

id string required
Example: not_found

A short identifier corresponding to the HTTP status code returned. For example, the ID for a response returning a 404 status code would be "not_found."

message string required
Example: The resource you were accessing could not be found.

A message providing additional information about the error, including details to help resolve it when possible.

request_id string optional
Example: 4d9d8375-3c56-4925-a3e7-eb137fed17e9

Optionally, some endpoints may include a request ID that should be provided when reporting bugs or opening support tickets to help identify the issue.

429

The API rate limit has been exceeded.

ratelimit-limit integer

The default limit on number of requests that can be made per hour and per minute. Current rate limits are 5000 requests per hour and 250 requests per minute.

ratelimit-remaining integer

The number of requests in your hourly quota that remain before you hit your request limit. See https://docs.digitalocean.com/reference/api/reference/#rate-limit for information about how requests expire.

ratelimit-reset integer

The time when the oldest request will expire. The value is given in Unix epoch time. See https://docs.digitalocean.com/reference/api/reference/#rate-limit for information about how requests expire.

id string required
Example: not_found

A short identifier corresponding to the HTTP status code returned. For example, the ID for a response returning a 404 status code would be "not_found."

message string required
Example: The resource you were accessing could not be found.

A message providing additional information about the error, including details to help resolve it when possible.

request_id string optional
Example: 4d9d8375-3c56-4925-a3e7-eb137fed17e9

Optionally, some endpoints may include a request ID that should be provided when reporting bugs or opening support tickets to help identify the issue.

500

There was a server error.

ratelimit-limit integer

The default limit on number of requests that can be made per hour and per minute. Current rate limits are 5000 requests per hour and 250 requests per minute.

ratelimit-remaining integer

The number of requests in your hourly quota that remain before you hit your request limit. See https://docs.digitalocean.com/reference/api/reference/#rate-limit for information about how requests expire.

ratelimit-reset integer

The time when the oldest request will expire. The value is given in Unix epoch time. See https://docs.digitalocean.com/reference/api/reference/#rate-limit for information about how requests expire.

id string required
Example: not_found

A short identifier corresponding to the HTTP status code returned. For example, the ID for a response returning a 404 status code would be "not_found."

message string required
Example: The resource you were accessing could not be found.

A message providing additional information about the error, including details to help resolve it when possible.

request_id string optional
Example: 4d9d8375-3c56-4925-a3e7-eb137fed17e9

Optionally, some endpoints may include a request ID that should be provided when reporting bugs or opening support tickets to help identify the issue.

501

Workspace file transfer is not supported by the active sandbox driver.

ratelimit-limit integer

The default limit on number of requests that can be made per hour and per minute. Current rate limits are 5000 requests per hour and 250 requests per minute.

ratelimit-remaining integer

The number of requests in your hourly quota that remain before you hit your request limit. See https://docs.digitalocean.com/reference/api/reference/#rate-limit for information about how requests expire.

ratelimit-reset integer

The time when the oldest request will expire. The value is given in Unix epoch time. See https://docs.digitalocean.com/reference/api/reference/#rate-limit for information about how requests expire.

id string required
Example: not_found

A short identifier corresponding to the HTTP status code returned. For example, the ID for a response returning a 404 status code would be "not_found."

message string required
Example: The resource you were accessing could not be found.

A message providing additional information about the error, including details to help resolve it when possible.

request_id string optional
Example: 4d9d8375-3c56-4925-a3e7-eb137fed17e9

Optionally, some endpoints may include a request ID that should be provided when reporting bugs or opening support tickets to help identify the issue.

502

Upstream sandbox transfer failed.

ratelimit-limit integer

The default limit on number of requests that can be made per hour and per minute. Current rate limits are 5000 requests per hour and 250 requests per minute.

ratelimit-remaining integer

The number of requests in your hourly quota that remain before you hit your request limit. See https://docs.digitalocean.com/reference/api/reference/#rate-limit for information about how requests expire.

ratelimit-reset integer

The time when the oldest request will expire. The value is given in Unix epoch time. See https://docs.digitalocean.com/reference/api/reference/#rate-limit for information about how requests expire.

id string required
Example: not_found

A short identifier corresponding to the HTTP status code returned. For example, the ID for a response returning a 404 status code would be "not_found."

message string required
Example: The resource you were accessing could not be found.

A message providing additional information about the error, including details to help resolve it when possible.

request_id string optional
Example: 4d9d8375-3c56-4925-a3e7-eb137fed17e9

Optionally, some endpoints may include a request ID that should be provided when reporting bugs or opening support tickets to help identify the issue.

503

Workspace transfer capacity exhausted; retry later.

ratelimit-limit integer

The default limit on number of requests that can be made per hour and per minute. Current rate limits are 5000 requests per hour and 250 requests per minute.

ratelimit-remaining integer

The number of requests in your hourly quota that remain before you hit your request limit. See https://docs.digitalocean.com/reference/api/reference/#rate-limit for information about how requests expire.

ratelimit-reset integer

The time when the oldest request will expire. The value is given in Unix epoch time. See https://docs.digitalocean.com/reference/api/reference/#rate-limit for information about how requests expire.

id string required
Example: not_found

A short identifier corresponding to the HTTP status code returned. For example, the ID for a response returning a 404 status code would be "not_found."

message string required
Example: The resource you were accessing could not be found.

A message providing additional information about the error, including details to help resolve it when possible.

request_id string optional
Example: 4d9d8375-3c56-4925-a3e7-eb137fed17e9

Optionally, some endpoints may include a request ID that should be provided when reporting bugs or opening support tickets to help identify the issue.

default

There was an unexpected error.

ratelimit-limit integer

The default limit on number of requests that can be made per hour and per minute. Current rate limits are 5000 requests per hour and 250 requests per minute.

ratelimit-remaining integer

The number of requests in your hourly quota that remain before you hit your request limit. See https://docs.digitalocean.com/reference/api/reference/#rate-limit for information about how requests expire.

ratelimit-reset integer

The time when the oldest request will expire. The value is given in Unix epoch time. See https://docs.digitalocean.com/reference/api/reference/#rate-limit for information about how requests expire.

id string required
Example: not_found

A short identifier corresponding to the HTTP status code returned. For example, the ID for a response returning a 404 status code would be "not_found."

message string required
Example: The resource you were accessing could not be found.

A message providing additional information about the error, including details to help resolve it when possible.

request_id string optional
Example: 4d9d8375-3c56-4925-a3e7-eb137fed17e9

Optionally, some endpoints may include a request ID that should be provided when reporting bugs or opening support tickets to help identify the issue.

{
  "bytes_written": 1,
  "path": "example"
}
{
  "id": "not_found",
  "message": "The resource you were accessing could not be found.",
  "request_id": "4d9d8375-3c56-4925-a3e7-eb137fed17e9"
}
{
  "id": "unauthorized",
  "message": "Unable to authenticate you."
}
{
  "id": "not_found",
  "message": "The resource you were accessing could not be found.",
  "request_id": "4d9d8375-3c56-4925-a3e7-eb137fed17e9"
}
{
  "id": "not_found",
  "message": "The resource you were accessing could not be found.",
  "request_id": "4d9d8375-3c56-4925-a3e7-eb137fed17e9"
}
{
  "id": "not_found",
  "message": "The resource you requested could not be found."
}
{
  "id": "not_found",
  "message": "The resource you were accessing could not be found.",
  "request_id": "4d9d8375-3c56-4925-a3e7-eb137fed17e9"
}
{
  "id": "not_found",
  "message": "The resource you were accessing could not be found.",
  "request_id": "4d9d8375-3c56-4925-a3e7-eb137fed17e9"
}
{
  "id": "not_found",
  "message": "The resource you were accessing could not be found.",
  "request_id": "4d9d8375-3c56-4925-a3e7-eb137fed17e9"
}
{
  "id": "too_many_requests",
  "message": "API rate limit exceeded."
}
{
  "id": "server_error",
  "message": "Unexpected server-side error"
}
{
  "id": "not_found",
  "message": "The resource you were accessing could not be found.",
  "request_id": "4d9d8375-3c56-4925-a3e7-eb137fed17e9"
}
{
  "id": "not_found",
  "message": "The resource you were accessing could not be found.",
  "request_id": "4d9d8375-3c56-4925-a3e7-eb137fed17e9"
}
{
  "id": "not_found",
  "message": "The resource you were accessing could not be found.",
  "request_id": "4d9d8375-3c56-4925-a3e7-eb137fed17e9"
}
{
  "id": "example_error",
  "message": "some error message"
}

GET StreamSessionEvents opens the session's Server-Sent Events feed.

/v2/agents/sessions/{session_id}/events
Authorizations: bearer_auth (1 scope)
Http: Bearer
Required scopes: agent_harness_session:read

OAuth Authentication

In order to interact with the DigitalOcean API, you or your application must authenticate.

The DigitalOcean API handles this through OAuth, an open standard for authorization. OAuth allows you to delegate access to your account. Scopes can be used to grant full access, read-only access, or access to a specific set of endpoints.

You can generate an OAuth token by visiting the Apps & API section of the DigitalOcean control panel for your account.

An OAuth token functions as a complete authentication request. In effect, it acts as a substitute for a username and password pair.

Because of this, it is absolutely essential that you keep your OAuth tokens secure. In fact, upon generation, the web interface will only display each token a single time in order to prevent the token from being compromised.

DigitalOcean access tokens begin with an identifiable prefix in order to distinguish them from other similar tokens.

  • dop_v1_ for personal access tokens generated in the control panel
  • doo_v1_ for tokens generated by applications using the OAuth flow
  • dor_v1_ for OAuth refresh tokens

Scopes

Scopes act like permissions assigned to an API token. These permissions determine what actions the token can perform. You can create API tokens that grant read-only access, full access, or limited access to specific endpoints by using custom scopes.

Generally, scopes are designed to match HTTP verbs and common CRUD operations (Create, Read, Update, Delete).

HTTP Verb CRUD Operation Scope
GET Read <resource>:read
POST Create <resource>:create
PUT/PATCH Update <resource>:update
DELETE Delete <resource>:delete

For example, creating a new Droplet by making a POST request to the /v2/droplets endpoint requires the droplet:create scope while listing Droplets by making a GET request to the /v2/droplets endpoint requires the droplet:read scope.

Each endpoint below specifies which scope is required to access it when using custom scopes.

How to Authenticate with OAuth

In order to make an authenticated request, include a bearer-type Authorization header containing your OAuth token. All requests must be made over HTTPS.

Authenticate with a Bearer Authorization Header

curl -X $HTTP_METHOD -H "Authorization: Bearer $DIGITALOCEAN_TOKEN" "https://api.digitalocean.com/v2/$OBJECT"

Opens a text/event-stream of the session's canonical events, served by the MARS data plane (OHP). Each frame is event: <type> plus a data: line holding a JSON event envelope; comment lines (: keepalive) arrive about every 15s and must be ignored. Decode every data: with one envelope parser and dispatch on the envelope's type. Every stream opens with a stream.state control frame (its data is a stream_state).

Delivery is at-least-once: clients MUST de-duplicate and order by event_id (a ULID), never by seq. The same path serves two modes:

  • live attach (default): recent context, then an open stream that stays live until the client disconnects. Pass Last-Event-ID (or cursor) to resume strictly after the last event the client already rendered, suppressing the last-N context floor.
  • finite replay (replay_only=true): writes a bounded slice of the stored transcript and closes. This is what doctl agents logs uses; paginate it with replay_from.

OHP serves recent history only (bounded by Kafka retention and an event window); it is not an archive. OHP's own errors (404/429/500/503) use the DO-standard JSON {id, message, request_id} envelope (cthulhu#179797 / MARSOHS-2065); the 401 comes from the edge.

Path Parameters

session_id string required
Example: a1b2c3d4-e5f6-7890-abcd-ef1234567890

The session UUID.

Query Parameters

replay_only boolean optional
Example: false

Write the selected history and then close the stream, rather than going live. Does not advance the device's delivery cursor, so it never supersedes a live attach from the same device.

Default: false
replay_from string optional

Event-id pagination cursor for the replay_only lane only; return events after this one. There is no last-N floor, so a cursor already at the head yields nothing. Ignored on a live attach.

cursor string optional

Query-param equivalent of Last-Event-ID, because a browser EventSource cannot set request headers. Takes precedence over the header when both are present. Live-attach lane only.

device_id string optional

Query-param equivalent of X-Device-UUID. Identifies one client install so its delivery cursor and live slot are its own; a second attach from the same device supersedes the first.

Header Parameters

Last-Event-ID string optional
Example: 01K9YQ0R2M4A7X

The last event this client rendered (not merely received). Its presence marks the request a reconnect, so OHP serves strictly what follows it with no last-N floor. Persist it only after rendering.

X-Device-UUID string optional
Example: d1e2f3a4-b5c6-7890-abcd-ef1234567890

A stable per-install device id. See device_id.

curl -N \
  -H "Authorization: Bearer $DIGITALOCEAN_TOKEN" \
  -H "Accept: text/event-stream" \
  "https://api.digitalocean.com/v2/agents/sessions/{session_id}/events?replay_only=true"
curl -X GET \
  -H "Authorization: Bearer $API_TOKEN" \
  "https://api.digitalocean.com/v2/agents/sessions/{session_id}/events"

Responses

200

An SSE stream. Each frame is event: <type> plus a data: line holding a JSON event envelope (see stream_event). The stream opens with a stream.state control frame, then events oldest-first, then either a stream.state: live frame (live attach) or end-of-stream (replay_only=true).

Cache-Control string

Always no-cache.

ratelimit-limit integer

The default limit on number of requests that can be made per hour and per minute. Current rate limits are 5000 requests per hour and 250 requests per minute.

ratelimit-remaining integer

The number of requests in your hourly quota that remain before you hit your request limit. See https://docs.digitalocean.com/reference/api/reference/#rate-limit for information about how requests expire.

ratelimit-reset integer

The time when the oldest request will expire. The value is given in Unix epoch time. See https://docs.digitalocean.com/reference/api/reference/#rate-limit for information about how requests expire.

credential_binding_set_id string optional
Example: example
data object optional

Type-specific payload, discriminated by type (canonical SPI shapes; numeric fields are JSON numbers):

  • run.started: {agent}
  • run.token_delta: {text}
  • run.tool_call_started: {tool_call_id, name, input}
  • run.tool_call_completed: {tool_call_id, ok, duration_ms, summary}
  • run.human_input_requested: {hitl_id, payload}
  • run.human_input_received: {hitl_id, outcome, actor, reason}
  • run.completed: {total_tokens_in, total_tokens_out, run_cost_micros}
  • run.failed: {code, message}
  • run.paused: {reason}
  • run.resumed: {}
  • session.updated: {}
  • run.state_checkpointed: {checkpoint_id, digest}
  • run.handoff: {from, to, description}
  • run.usage_recorded: {step_id, model_id, usage: {input_tokens, output_tokens, cached_input_tokens, reasoning_tokens, tool_seconds}}
  • run.sandbox_allocated: {sandbox_id, kind, template}
  • run.sandbox_released: {sandbox_id, exit_code, duration_ms}
  • run.cost_accrued: {running_total_micros, delta_micros}
  • run.log: {level, message, fields}
definition_id string optional
Example: example
event_id string optional
Example: example
producer string, one of: agent, ohr, ohp, ohs optional
Example: agent

Server-assigned component that submitted the event.

revision_id string optional
Example: example
run_id string optional
Example: example
seq integer (int64) optional
Example: 1

Producer-supplied sequence number; nonzero values increase monotonically within an ingress stream.

session_id string optional
Example: example
source_event_id string optional
Example: example
source_event_type string optional
Example: example
source_tenant_id string optional
Example: example

Optional runtime-native tenant identifier; distinct from authoritative tenant_id.

tenant_id string optional
Example: example

DO Team ID rendered as a decimal string.

timestamp string (date-time) optional
Example: 2026-07-27T12:00:00Z
trace_parent string optional
Example: example
type string (enum) optional
Example: run.started

Canonical SPI event type. The SSE event: field carries the same value.

401

Authentication failed due to invalid credentials.

ratelimit-limit integer

The default limit on number of requests that can be made per hour and per minute. Current rate limits are 5000 requests per hour and 250 requests per minute.

ratelimit-remaining integer

The number of requests in your hourly quota that remain before you hit your request limit. See https://docs.digitalocean.com/reference/api/reference/#rate-limit for information about how requests expire.

ratelimit-reset integer

The time when the oldest request will expire. The value is given in Unix epoch time. See https://docs.digitalocean.com/reference/api/reference/#rate-limit for information about how requests expire.

id string required
Example: not_found

A short identifier corresponding to the HTTP status code returned. For example, the ID for a response returning a 404 status code would be "not_found."

message string required
Example: The resource you were accessing could not be found.

A message providing additional information about the error, including details to help resolve it when possible.

request_id string optional
Example: 4d9d8375-3c56-4925-a3e7-eb137fed17e9

Optionally, some endpoints may include a request ID that should be provided when reporting bugs or opening support tickets to help identify the issue.

404

Unknown session, or a session belonging to another team. The two are deliberately indistinguishable so a caller cannot enumerate other tenants' session ids.

ratelimit-limit integer

The default limit on number of requests that can be made per hour and per minute. Current rate limits are 5000 requests per hour and 250 requests per minute.

ratelimit-remaining integer

The number of requests in your hourly quota that remain before you hit your request limit. See https://docs.digitalocean.com/reference/api/reference/#rate-limit for information about how requests expire.

ratelimit-reset integer

The time when the oldest request will expire. The value is given in Unix epoch time. See https://docs.digitalocean.com/reference/api/reference/#rate-limit for information about how requests expire.

id string required
Example: not_found

A short identifier corresponding to the HTTP status code returned. For example, the ID for a response returning a 404 status code would be "not_found."

message string required
Example: The resource you were accessing could not be found.

A message providing additional information about the error, including details to help resolve it when possible.

request_id string optional
Example: 4d9d8375-3c56-4925-a3e7-eb137fed17e9

Optionally, some endpoints may include a request ID that should be provided when reporting bugs or opening support tickets to help identify the issue.

429

Attach admission limit reached. Retry after the Retry-After hint.

Retry-After integer

Seconds to wait before retrying.

ratelimit-limit integer

The default limit on number of requests that can be made per hour and per minute. Current rate limits are 5000 requests per hour and 250 requests per minute.

ratelimit-remaining integer

The number of requests in your hourly quota that remain before you hit your request limit. See https://docs.digitalocean.com/reference/api/reference/#rate-limit for information about how requests expire.

ratelimit-reset integer

The time when the oldest request will expire. The value is given in Unix epoch time. See https://docs.digitalocean.com/reference/api/reference/#rate-limit for information about how requests expire.

id string required
Example: not_found

A short identifier corresponding to the HTTP status code returned. For example, the ID for a response returning a 404 status code would be "not_found."

message string required
Example: The resource you were accessing could not be found.

A message providing additional information about the error, including details to help resolve it when possible.

request_id string optional
Example: 4d9d8375-3c56-4925-a3e7-eb137fed17e9

Optionally, some endpoints may include a request ID that should be provided when reporting bugs or opening support tickets to help identify the issue.

500

Internal error.

ratelimit-limit integer

The default limit on number of requests that can be made per hour and per minute. Current rate limits are 5000 requests per hour and 250 requests per minute.

ratelimit-remaining integer

The number of requests in your hourly quota that remain before you hit your request limit. See https://docs.digitalocean.com/reference/api/reference/#rate-limit for information about how requests expire.

ratelimit-reset integer

The time when the oldest request will expire. The value is given in Unix epoch time. See https://docs.digitalocean.com/reference/api/reference/#rate-limit for information about how requests expire.

id string required
Example: not_found

A short identifier corresponding to the HTTP status code returned. For example, the ID for a response returning a 404 status code would be "not_found."

message string required
Example: The resource you were accessing could not be found.

A message providing additional information about the error, including details to help resolve it when possible.

request_id string optional
Example: 4d9d8375-3c56-4925-a3e7-eb137fed17e9

Optionally, some endpoints may include a request ID that should be provided when reporting bugs or opening support tickets to help identify the issue.

503

OHP cannot currently establish the caller's authorization or the session's location. Transient; retry after the Retry-After hint.

Retry-After integer

Seconds to wait before retrying.

ratelimit-limit integer

The default limit on number of requests that can be made per hour and per minute. Current rate limits are 5000 requests per hour and 250 requests per minute.

ratelimit-remaining integer

The number of requests in your hourly quota that remain before you hit your request limit. See https://docs.digitalocean.com/reference/api/reference/#rate-limit for information about how requests expire.

ratelimit-reset integer

The time when the oldest request will expire. The value is given in Unix epoch time. See https://docs.digitalocean.com/reference/api/reference/#rate-limit for information about how requests expire.

id string required
Example: not_found

A short identifier corresponding to the HTTP status code returned. For example, the ID for a response returning a 404 status code would be "not_found."

message string required
Example: The resource you were accessing could not be found.

A message providing additional information about the error, including details to help resolve it when possible.

request_id string optional
Example: 4d9d8375-3c56-4925-a3e7-eb137fed17e9

Optionally, some endpoints may include a request ID that should be provided when reporting bugs or opening support tickets to help identify the issue.

default

There was an unexpected error.

ratelimit-limit integer

The default limit on number of requests that can be made per hour and per minute. Current rate limits are 5000 requests per hour and 250 requests per minute.

ratelimit-remaining integer

The number of requests in your hourly quota that remain before you hit your request limit. See https://docs.digitalocean.com/reference/api/reference/#rate-limit for information about how requests expire.

ratelimit-reset integer

The time when the oldest request will expire. The value is given in Unix epoch time. See https://docs.digitalocean.com/reference/api/reference/#rate-limit for information about how requests expire.

id string required
Example: not_found

A short identifier corresponding to the HTTP status code returned. For example, the ID for a response returning a 404 status code would be "not_found."

message string required
Example: The resource you were accessing could not be found.

A message providing additional information about the error, including details to help resolve it when possible.

request_id string optional
Example: 4d9d8375-3c56-4925-a3e7-eb137fed17e9

Optionally, some endpoints may include a request ID that should be provided when reporting bugs or opening support tickets to help identify the issue.

{
  "id": "unauthorized",
  "message": "Unable to authenticate you."
}
{
  "id": "not_found",
  "message": "The resource you were accessing could not be found.",
  "request_id": "4d9d8375-3c56-4925-a3e7-eb137fed17e9"
}
{
  "id": "not_found",
  "message": "The resource you were accessing could not be found.",
  "request_id": "4d9d8375-3c56-4925-a3e7-eb137fed17e9"
}
{
  "id": "not_found",
  "message": "The resource you were accessing could not be found.",
  "request_id": "4d9d8375-3c56-4925-a3e7-eb137fed17e9"
}
{
  "id": "not_found",
  "message": "The resource you were accessing could not be found.",
  "request_id": "4d9d8375-3c56-4925-a3e7-eb137fed17e9"
}
{
  "id": "example_error",
  "message": "some error message"
}

GET PortForwardSession opens a WebSocket tunnel to a guest TCP port.

/v2/agents/sessions/{session_id}/port-forward/{port}
Authorizations: bearer_auth (1 scope)
Http: Bearer
Required scopes: agent_harness_session:operate

OAuth Authentication

In order to interact with the DigitalOcean API, you or your application must authenticate.

The DigitalOcean API handles this through OAuth, an open standard for authorization. OAuth allows you to delegate access to your account. Scopes can be used to grant full access, read-only access, or access to a specific set of endpoints.

You can generate an OAuth token by visiting the Apps & API section of the DigitalOcean control panel for your account.

An OAuth token functions as a complete authentication request. In effect, it acts as a substitute for a username and password pair.

Because of this, it is absolutely essential that you keep your OAuth tokens secure. In fact, upon generation, the web interface will only display each token a single time in order to prevent the token from being compromised.

DigitalOcean access tokens begin with an identifiable prefix in order to distinguish them from other similar tokens.

  • dop_v1_ for personal access tokens generated in the control panel
  • doo_v1_ for tokens generated by applications using the OAuth flow
  • dor_v1_ for OAuth refresh tokens

Scopes

Scopes act like permissions assigned to an API token. These permissions determine what actions the token can perform. You can create API tokens that grant read-only access, full access, or limited access to specific endpoints by using custom scopes.

Generally, scopes are designed to match HTTP verbs and common CRUD operations (Create, Read, Update, Delete).

HTTP Verb CRUD Operation Scope
GET Read <resource>:read
POST Create <resource>:create
PUT/PATCH Update <resource>:update
DELETE Delete <resource>:delete

For example, creating a new Droplet by making a POST request to the /v2/droplets endpoint requires the droplet:create scope while listing Droplets by making a GET request to the /v2/droplets endpoint requires the droplet:read scope.

Each endpoint below specifies which scope is required to access it when using custom scopes.

How to Authenticate with OAuth

In order to make an authenticated request, include a bearer-type Authorization header containing your OAuth token. All requests must be made over HTTPS.

Authenticate with a Bearer Authorization Header

curl -X $HTTP_METHOD -H "Authorization: Bearer $DIGITALOCEAN_TOKEN" "https://api.digitalocean.com/v2/$OBJECT"

Upgrades the request to a WebSocket and bridges it to one TCP connection on the session sandbox's guest port. Binary frames carry the opaque byte stream in both directions; the server closes with a descriptive WebSocket close code when the tunnel ends. This is the raw TCP tunnel; browser clients reaching the in-guest OpenHands Agent Server use the ingress URL (GET /v2/agents/sessions/{session_id}/ingress), which has replaced this bridge for them.

WebSocket is not expressible in OpenAPI; this documents the GET that initiates the upgrade handshake (HTTP 101 Switching Protocols). The handler dials the guest before upgrading, so a PAUSED session is woken and served rather than rejected. port must be between 1024 and 65535. A request without the WebSocket upgrade headers is answered 400 by the handshake layer.

Path Parameters

session_id string required
Example: a1b2c3d4-e5f6-7890-abcd-ef1234567890

The session UUID.

port integer 1024 – 65535 required
Example: 8000

The guest TCP port to connect to. Must be between 1024 and 65535.

curl -i -N \
  -H "Authorization: Bearer $DIGITALOCEAN_TOKEN" \
  -H "Connection: Upgrade" \
  -H "Upgrade: websocket" \
  -H "Sec-WebSocket-Version: 13" \
  -H "Sec-WebSocket-Key: $(openssl rand -base64 16)" \
  "https://api.digitalocean.com/v2/agents/sessions/{session_id}/port-forward/8000"
curl -X GET \
  -H "Authorization: Bearer $API_TOKEN" \
  "https://api.digitalocean.com/v2/agents/sessions/{session_id}/port-forward/{port}"

Responses

101

Switching Protocols. The WebSocket handshake succeeded and the connection is now a binary tunnel to the guest port.

ratelimit-limit integer

The default limit on number of requests that can be made per hour and per minute. Current rate limits are 5000 requests per hour and 250 requests per minute.

ratelimit-remaining integer

The number of requests in your hourly quota that remain before you hit your request limit. See https://docs.digitalocean.com/reference/api/reference/#rate-limit for information about how requests expire.

ratelimit-reset integer

The time when the oldest request will expire. The value is given in Unix epoch time. See https://docs.digitalocean.com/reference/api/reference/#rate-limit for information about how requests expire.

400

The request is not a valid WebSocket upgrade (missing Upgrade/Connection headers). Returned by the handshake layer as plain text.

ratelimit-limit integer

The default limit on number of requests that can be made per hour and per minute. Current rate limits are 5000 requests per hour and 250 requests per minute.

ratelimit-remaining integer

The number of requests in your hourly quota that remain before you hit your request limit. See https://docs.digitalocean.com/reference/api/reference/#rate-limit for information about how requests expire.

ratelimit-reset integer

The time when the oldest request will expire. The value is given in Unix epoch time. See https://docs.digitalocean.com/reference/api/reference/#rate-limit for information about how requests expire.

401

Authentication failed due to invalid credentials.

ratelimit-limit integer

The default limit on number of requests that can be made per hour and per minute. Current rate limits are 5000 requests per hour and 250 requests per minute.

ratelimit-remaining integer

The number of requests in your hourly quota that remain before you hit your request limit. See https://docs.digitalocean.com/reference/api/reference/#rate-limit for information about how requests expire.

ratelimit-reset integer

The time when the oldest request will expire. The value is given in Unix epoch time. See https://docs.digitalocean.com/reference/api/reference/#rate-limit for information about how requests expire.

id string required
Example: not_found

A short identifier corresponding to the HTTP status code returned. For example, the ID for a response returning a 404 status code would be "not_found."

message string required
Example: The resource you were accessing could not be found.

A message providing additional information about the error, including details to help resolve it when possible.

request_id string optional
Example: 4d9d8375-3c56-4925-a3e7-eb137fed17e9

Optionally, some endpoints may include a request ID that should be provided when reporting bugs or opening support tickets to help identify the issue.

402

The team is blocked by the prepayment gate.

ratelimit-limit integer

The default limit on number of requests that can be made per hour and per minute. Current rate limits are 5000 requests per hour and 250 requests per minute.

ratelimit-remaining integer

The number of requests in your hourly quota that remain before you hit your request limit. See https://docs.digitalocean.com/reference/api/reference/#rate-limit for information about how requests expire.

ratelimit-reset integer

The time when the oldest request will expire. The value is given in Unix epoch time. See https://docs.digitalocean.com/reference/api/reference/#rate-limit for information about how requests expire.

id string required
Example: not_found

A short identifier corresponding to the HTTP status code returned. For example, the ID for a response returning a 404 status code would be "not_found."

message string required
Example: The resource you were accessing could not be found.

A message providing additional information about the error, including details to help resolve it when possible.

request_id string optional
Example: 4d9d8375-3c56-4925-a3e7-eb137fed17e9

Optionally, some endpoints may include a request ID that should be provided when reporting bugs or opening support tickets to help identify the issue.

403

The port is outside 1024-65535, or the session belongs to another team.

ratelimit-limit integer

The default limit on number of requests that can be made per hour and per minute. Current rate limits are 5000 requests per hour and 250 requests per minute.

ratelimit-remaining integer

The number of requests in your hourly quota that remain before you hit your request limit. See https://docs.digitalocean.com/reference/api/reference/#rate-limit for information about how requests expire.

ratelimit-reset integer

The time when the oldest request will expire. The value is given in Unix epoch time. See https://docs.digitalocean.com/reference/api/reference/#rate-limit for information about how requests expire.

id string required
Example: not_found

A short identifier corresponding to the HTTP status code returned. For example, the ID for a response returning a 404 status code would be "not_found."

message string required
Example: The resource you were accessing could not be found.

A message providing additional information about the error, including details to help resolve it when possible.

request_id string optional
Example: 4d9d8375-3c56-4925-a3e7-eb137fed17e9

Optionally, some endpoints may include a request ID that should be provided when reporting bugs or opening support tickets to help identify the issue.

404

The resource was not found.

ratelimit-limit integer

The default limit on number of requests that can be made per hour and per minute. Current rate limits are 5000 requests per hour and 250 requests per minute.

ratelimit-remaining integer

The number of requests in your hourly quota that remain before you hit your request limit. See https://docs.digitalocean.com/reference/api/reference/#rate-limit for information about how requests expire.

ratelimit-reset integer

The time when the oldest request will expire. The value is given in Unix epoch time. See https://docs.digitalocean.com/reference/api/reference/#rate-limit for information about how requests expire.

id string required
Example: not_found

A short identifier corresponding to the HTTP status code returned. For example, the ID for a response returning a 404 status code would be "not_found."

message string required
Example: The resource you were accessing could not be found.

A message providing additional information about the error, including details to help resolve it when possible.

request_id string optional
Example: 4d9d8375-3c56-4925-a3e7-eb137fed17e9

Optionally, some endpoints may include a request ID that should be provided when reporting bugs or opening support tickets to help identify the issue.

409

The session has no sandbox.

ratelimit-limit integer

The default limit on number of requests that can be made per hour and per minute. Current rate limits are 5000 requests per hour and 250 requests per minute.

ratelimit-remaining integer

The number of requests in your hourly quota that remain before you hit your request limit. See https://docs.digitalocean.com/reference/api/reference/#rate-limit for information about how requests expire.

ratelimit-reset integer

The time when the oldest request will expire. The value is given in Unix epoch time. See https://docs.digitalocean.com/reference/api/reference/#rate-limit for information about how requests expire.

id string required
Example: not_found

A short identifier corresponding to the HTTP status code returned. For example, the ID for a response returning a 404 status code would be "not_found."

message string required
Example: The resource you were accessing could not be found.

A message providing additional information about the error, including details to help resolve it when possible.

request_id string optional
Example: 4d9d8375-3c56-4925-a3e7-eb137fed17e9

Optionally, some endpoints may include a request ID that should be provided when reporting bugs or opening support tickets to help identify the issue.

423

This session is unavailable; contact support.

ratelimit-limit integer

The default limit on number of requests that can be made per hour and per minute. Current rate limits are 5000 requests per hour and 250 requests per minute.

ratelimit-remaining integer

The number of requests in your hourly quota that remain before you hit your request limit. See https://docs.digitalocean.com/reference/api/reference/#rate-limit for information about how requests expire.

ratelimit-reset integer

The time when the oldest request will expire. The value is given in Unix epoch time. See https://docs.digitalocean.com/reference/api/reference/#rate-limit for information about how requests expire.

id string required
Example: not_found

A short identifier corresponding to the HTTP status code returned. For example, the ID for a response returning a 404 status code would be "not_found."

message string required
Example: The resource you were accessing could not be found.

A message providing additional information about the error, including details to help resolve it when possible.

request_id string optional
Example: 4d9d8375-3c56-4925-a3e7-eb137fed17e9

Optionally, some endpoints may include a request ID that should be provided when reporting bugs or opening support tickets to help identify the issue.

429

The API rate limit has been exceeded.

ratelimit-limit integer

The default limit on number of requests that can be made per hour and per minute. Current rate limits are 5000 requests per hour and 250 requests per minute.

ratelimit-remaining integer

The number of requests in your hourly quota that remain before you hit your request limit. See https://docs.digitalocean.com/reference/api/reference/#rate-limit for information about how requests expire.

ratelimit-reset integer

The time when the oldest request will expire. The value is given in Unix epoch time. See https://docs.digitalocean.com/reference/api/reference/#rate-limit for information about how requests expire.

id string required
Example: not_found

A short identifier corresponding to the HTTP status code returned. For example, the ID for a response returning a 404 status code would be "not_found."

message string required
Example: The resource you were accessing could not be found.

A message providing additional information about the error, including details to help resolve it when possible.

request_id string optional
Example: 4d9d8375-3c56-4925-a3e7-eb137fed17e9

Optionally, some endpoints may include a request ID that should be provided when reporting bugs or opening support tickets to help identify the issue.

500

There was a server error.

ratelimit-limit integer

The default limit on number of requests that can be made per hour and per minute. Current rate limits are 5000 requests per hour and 250 requests per minute.

ratelimit-remaining integer

The number of requests in your hourly quota that remain before you hit your request limit. See https://docs.digitalocean.com/reference/api/reference/#rate-limit for information about how requests expire.

ratelimit-reset integer

The time when the oldest request will expire. The value is given in Unix epoch time. See https://docs.digitalocean.com/reference/api/reference/#rate-limit for information about how requests expire.

id string required
Example: not_found

A short identifier corresponding to the HTTP status code returned. For example, the ID for a response returning a 404 status code would be "not_found."

message string required
Example: The resource you were accessing could not be found.

A message providing additional information about the error, including details to help resolve it when possible.

request_id string optional
Example: 4d9d8375-3c56-4925-a3e7-eb137fed17e9

Optionally, some endpoints may include a request ID that should be provided when reporting bugs or opening support tickets to help identify the issue.

502

Could not reach the guest port (nothing listening, or the guest dial failed).

ratelimit-limit integer

The default limit on number of requests that can be made per hour and per minute. Current rate limits are 5000 requests per hour and 250 requests per minute.

ratelimit-remaining integer

The number of requests in your hourly quota that remain before you hit your request limit. See https://docs.digitalocean.com/reference/api/reference/#rate-limit for information about how requests expire.

ratelimit-reset integer

The time when the oldest request will expire. The value is given in Unix epoch time. See https://docs.digitalocean.com/reference/api/reference/#rate-limit for information about how requests expire.

id string required
Example: not_found

A short identifier corresponding to the HTTP status code returned. For example, the ID for a response returning a 404 status code would be "not_found."

message string required
Example: The resource you were accessing could not be found.

A message providing additional information about the error, including details to help resolve it when possible.

request_id string optional
Example: 4d9d8375-3c56-4925-a3e7-eb137fed17e9

Optionally, some endpoints may include a request ID that should be provided when reporting bugs or opening support tickets to help identify the issue.

default

There was an unexpected error.

ratelimit-limit integer

The default limit on number of requests that can be made per hour and per minute. Current rate limits are 5000 requests per hour and 250 requests per minute.

ratelimit-remaining integer

The number of requests in your hourly quota that remain before you hit your request limit. See https://docs.digitalocean.com/reference/api/reference/#rate-limit for information about how requests expire.

ratelimit-reset integer

The time when the oldest request will expire. The value is given in Unix epoch time. See https://docs.digitalocean.com/reference/api/reference/#rate-limit for information about how requests expire.

id string required
Example: not_found

A short identifier corresponding to the HTTP status code returned. For example, the ID for a response returning a 404 status code would be "not_found."

message string required
Example: The resource you were accessing could not be found.

A message providing additional information about the error, including details to help resolve it when possible.

request_id string optional
Example: 4d9d8375-3c56-4925-a3e7-eb137fed17e9

Optionally, some endpoints may include a request ID that should be provided when reporting bugs or opening support tickets to help identify the issue.

{
  "id": "unauthorized",
  "message": "Unable to authenticate you."
}
{
  "id": "not_found",
  "message": "The resource you were accessing could not be found.",
  "request_id": "4d9d8375-3c56-4925-a3e7-eb137fed17e9"
}
{
  "id": "not_found",
  "message": "The resource you were accessing could not be found.",
  "request_id": "4d9d8375-3c56-4925-a3e7-eb137fed17e9"
}
{
  "id": "not_found",
  "message": "The resource you requested could not be found."
}
{
  "id": "not_found",
  "message": "The resource you were accessing could not be found.",
  "request_id": "4d9d8375-3c56-4925-a3e7-eb137fed17e9"
}
{
  "id": "not_found",
  "message": "The resource you were accessing could not be found.",
  "request_id": "4d9d8375-3c56-4925-a3e7-eb137fed17e9"
}
{
  "id": "too_many_requests",
  "message": "API rate limit exceeded."
}
{
  "id": "server_error",
  "message": "Unexpected server-side error"
}
{
  "id": "not_found",
  "message": "The resource you were accessing could not be found.",
  "request_id": "4d9d8375-3c56-4925-a3e7-eb137fed17e9"
}
{
  "id": "example_error",
  "message": "some error message"
}

GET GetIngressURL returns the public HTTPS URL of the session's OpenHands Agent Server.

/v2/agents/sessions/{session_id}/ingress
Authorizations: bearer_auth (1 scope)
Http: Bearer
Required scopes: agent_harness_session:read

OAuth Authentication

In order to interact with the DigitalOcean API, you or your application must authenticate.

The DigitalOcean API handles this through OAuth, an open standard for authorization. OAuth allows you to delegate access to your account. Scopes can be used to grant full access, read-only access, or access to a specific set of endpoints.

You can generate an OAuth token by visiting the Apps & API section of the DigitalOcean control panel for your account.

An OAuth token functions as a complete authentication request. In effect, it acts as a substitute for a username and password pair.

Because of this, it is absolutely essential that you keep your OAuth tokens secure. In fact, upon generation, the web interface will only display each token a single time in order to prevent the token from being compromised.

DigitalOcean access tokens begin with an identifiable prefix in order to distinguish them from other similar tokens.

  • dop_v1_ for personal access tokens generated in the control panel
  • doo_v1_ for tokens generated by applications using the OAuth flow
  • dor_v1_ for OAuth refresh tokens

Scopes

Scopes act like permissions assigned to an API token. These permissions determine what actions the token can perform. You can create API tokens that grant read-only access, full access, or limited access to specific endpoints by using custom scopes.

Generally, scopes are designed to match HTTP verbs and common CRUD operations (Create, Read, Update, Delete).

HTTP Verb CRUD Operation Scope
GET Read <resource>:read
POST Create <resource>:create
PUT/PATCH Update <resource>:update
DELETE Delete <resource>:delete

For example, creating a new Droplet by making a POST request to the /v2/droplets endpoint requires the droplet:create scope while listing Droplets by making a GET request to the /v2/droplets endpoint requires the droplet:read scope.

Each endpoint below specifies which scope is required to access it when using custom scopes.

How to Authenticate with OAuth

In order to make an authenticated request, include a bearer-type Authorization header containing your OAuth token. All requests must be made over HTTPS.

Authenticate with a Bearer Authorization Header

curl -X $HTTP_METHOD -H "Authorization: Bearer $DIGITALOCEAN_TOKEN" "https://api.digitalocean.com/v2/$OBJECT"

Publishes the URL on first call and returns it. Idempotent while the session runs: the same URL is returned until the session is paused, locked or rolled back, after which the next call returns a new hostname (pause and lock revoke the URL; rollback moves the session to a new sandbox, so re-fetch after resume, unlock or rollback). The URL fronts guest port 8000 (the OpenHands Agent Server, HTTP + WebSocket) and replaces the port-forward bridge for browser clients. Requests to the URL carry the caller's DO token as a Bearer header. Poll until state is INGRESS_URL_STATE_READY; there is no failed state. Only OpenHands sessions support ingress, and it is gated per team.

Path Parameters

session_id string required
Example: a1b2c3d4-e5f6-7890-abcd-ef1234567890

The session UUID.

curl -X GET \
  -H "Content-Type: application/json" \
  -H "Authorization: Bearer $DIGITALOCEAN_TOKEN" \
  "https://api.digitalocean.com/v2/agents/sessions/{session_id}/ingress"
curl -X GET \
  -H "Authorization: Bearer $API_TOKEN" \
  "https://api.digitalocean.com/v2/agents/sessions/{session_id}/ingress"

Responses

200

A successful response.

ratelimit-limit integer

The default limit on number of requests that can be made per hour and per minute. Current rate limits are 5000 requests per hour and 250 requests per minute.

ratelimit-remaining integer

The number of requests in your hourly quota that remain before you hit your request limit. See https://docs.digitalocean.com/reference/api/reference/#rate-limit for information about how requests expire.

ratelimit-reset integer

The time when the oldest request will expire. The value is given in Unix epoch time. See https://docs.digitalocean.com/reference/api/reference/#rate-limit for information about how requests expire.

ingress_url object optional

A publicly routable HTTPS URL to one guest port of the session's sandbox. The hostname is stable while the session runs; it is revoked on pause and lock, and rollback moves the session to a new sandbox, so re-fetch after resume, unlock or rollback. Requests must carry the caller's DO token as a Bearer header.

Show child properties
created_at string (date-time) optional
Example: 2026-07-27T12:00:00Z
ingress_url_id string optional
Example: 3f2a1b0c-9d8e-7f6a-5b4c-3d2e1f0a9b8c
port integer (int64) optional
Example: 8000

Guest port the URL fronts; 8000 (OpenHands Agent Server) today.

session_id string optional
Example: a1b2c3d4-e5f6-7890-abcd-ef1234567890
state string, one of: INGRESS_URL_STATE_PENDING, INGRESS_URL_STATE_READY optional
Example: INGRESS_URL_STATE_READY

PENDING: route not yet published, URL not servable. READY: servable. There is no failed state; the substrate retries until READY.

url string optional
Example: https://abc123.nyc3.sandbox.ondigitalocean.com

Immutable HTTPS origin, e.g. https://.nyc3.sandbox.ondigitalocean.com.

401

Authentication failed due to invalid credentials.

ratelimit-limit integer

The default limit on number of requests that can be made per hour and per minute. Current rate limits are 5000 requests per hour and 250 requests per minute.

ratelimit-remaining integer

The number of requests in your hourly quota that remain before you hit your request limit. See https://docs.digitalocean.com/reference/api/reference/#rate-limit for information about how requests expire.

ratelimit-reset integer

The time when the oldest request will expire. The value is given in Unix epoch time. See https://docs.digitalocean.com/reference/api/reference/#rate-limit for information about how requests expire.

id string required
Example: not_found

A short identifier corresponding to the HTTP status code returned. For example, the ID for a response returning a 404 status code would be "not_found."

message string required
Example: The resource you were accessing could not be found.

A message providing additional information about the error, including details to help resolve it when possible.

request_id string optional
Example: 4d9d8375-3c56-4925-a3e7-eb137fed17e9

Optionally, some endpoints may include a request ID that should be provided when reporting bugs or opening support tickets to help identify the issue.

403

Session belongs to another team.

ratelimit-limit integer

The default limit on number of requests that can be made per hour and per minute. Current rate limits are 5000 requests per hour and 250 requests per minute.

ratelimit-remaining integer

The number of requests in your hourly quota that remain before you hit your request limit. See https://docs.digitalocean.com/reference/api/reference/#rate-limit for information about how requests expire.

ratelimit-reset integer

The time when the oldest request will expire. The value is given in Unix epoch time. See https://docs.digitalocean.com/reference/api/reference/#rate-limit for information about how requests expire.

id string required
Example: not_found

A short identifier corresponding to the HTTP status code returned. For example, the ID for a response returning a 404 status code would be "not_found."

message string required
Example: The resource you were accessing could not be found.

A message providing additional information about the error, including details to help resolve it when possible.

request_id string optional
Example: 4d9d8375-3c56-4925-a3e7-eb137fed17e9

Optionally, some endpoints may include a request ID that should be provided when reporting bugs or opening support tickets to help identify the issue.

404

The resource was not found.

ratelimit-limit integer

The default limit on number of requests that can be made per hour and per minute. Current rate limits are 5000 requests per hour and 250 requests per minute.

ratelimit-remaining integer

The number of requests in your hourly quota that remain before you hit your request limit. See https://docs.digitalocean.com/reference/api/reference/#rate-limit for information about how requests expire.

ratelimit-reset integer

The time when the oldest request will expire. The value is given in Unix epoch time. See https://docs.digitalocean.com/reference/api/reference/#rate-limit for information about how requests expire.

id string required
Example: not_found

A short identifier corresponding to the HTTP status code returned. For example, the ID for a response returning a 404 status code would be "not_found."

message string required
Example: The resource you were accessing could not be found.

A message providing additional information about the error, including details to help resolve it when possible.

request_id string optional
Example: 4d9d8375-3c56-4925-a3e7-eb137fed17e9

Optionally, some endpoints may include a request ID that should be provided when reporting bugs or opening support tickets to help identify the issue.

409

Session is not running.

ratelimit-limit integer

The default limit on number of requests that can be made per hour and per minute. Current rate limits are 5000 requests per hour and 250 requests per minute.

ratelimit-remaining integer

The number of requests in your hourly quota that remain before you hit your request limit. See https://docs.digitalocean.com/reference/api/reference/#rate-limit for information about how requests expire.

ratelimit-reset integer

The time when the oldest request will expire. The value is given in Unix epoch time. See https://docs.digitalocean.com/reference/api/reference/#rate-limit for information about how requests expire.

id string required
Example: not_found

A short identifier corresponding to the HTTP status code returned. For example, the ID for a response returning a 404 status code would be "not_found."

message string required
Example: The resource you were accessing could not be found.

A message providing additional information about the error, including details to help resolve it when possible.

request_id string optional
Example: 4d9d8375-3c56-4925-a3e7-eb137fed17e9

Optionally, some endpoints may include a request ID that should be provided when reporting bugs or opening support tickets to help identify the issue.

423

This session is unavailable; contact support.

ratelimit-limit integer

The default limit on number of requests that can be made per hour and per minute. Current rate limits are 5000 requests per hour and 250 requests per minute.

ratelimit-remaining integer

The number of requests in your hourly quota that remain before you hit your request limit. See https://docs.digitalocean.com/reference/api/reference/#rate-limit for information about how requests expire.

ratelimit-reset integer

The time when the oldest request will expire. The value is given in Unix epoch time. See https://docs.digitalocean.com/reference/api/reference/#rate-limit for information about how requests expire.

id string required
Example: not_found

A short identifier corresponding to the HTTP status code returned. For example, the ID for a response returning a 404 status code would be "not_found."

message string required
Example: The resource you were accessing could not be found.

A message providing additional information about the error, including details to help resolve it when possible.

request_id string optional
Example: 4d9d8375-3c56-4925-a3e7-eb137fed17e9

Optionally, some endpoints may include a request ID that should be provided when reporting bugs or opening support tickets to help identify the issue.

429

The API rate limit has been exceeded.

ratelimit-limit integer

The default limit on number of requests that can be made per hour and per minute. Current rate limits are 5000 requests per hour and 250 requests per minute.

ratelimit-remaining integer

The number of requests in your hourly quota that remain before you hit your request limit. See https://docs.digitalocean.com/reference/api/reference/#rate-limit for information about how requests expire.

ratelimit-reset integer

The time when the oldest request will expire. The value is given in Unix epoch time. See https://docs.digitalocean.com/reference/api/reference/#rate-limit for information about how requests expire.

id string required
Example: not_found

A short identifier corresponding to the HTTP status code returned. For example, the ID for a response returning a 404 status code would be "not_found."

message string required
Example: The resource you were accessing could not be found.

A message providing additional information about the error, including details to help resolve it when possible.

request_id string optional
Example: 4d9d8375-3c56-4925-a3e7-eb137fed17e9

Optionally, some endpoints may include a request ID that should be provided when reporting bugs or opening support tickets to help identify the issue.

500

There was a server error.

ratelimit-limit integer

The default limit on number of requests that can be made per hour and per minute. Current rate limits are 5000 requests per hour and 250 requests per minute.

ratelimit-remaining integer

The number of requests in your hourly quota that remain before you hit your request limit. See https://docs.digitalocean.com/reference/api/reference/#rate-limit for information about how requests expire.

ratelimit-reset integer

The time when the oldest request will expire. The value is given in Unix epoch time. See https://docs.digitalocean.com/reference/api/reference/#rate-limit for information about how requests expire.

id string required
Example: not_found

A short identifier corresponding to the HTTP status code returned. For example, the ID for a response returning a 404 status code would be "not_found."

message string required
Example: The resource you were accessing could not be found.

A message providing additional information about the error, including details to help resolve it when possible.

request_id string optional
Example: 4d9d8375-3c56-4925-a3e7-eb137fed17e9

Optionally, some endpoints may include a request ID that should be provided when reporting bugs or opening support tickets to help identify the issue.

501

Public ingress is not supported for this agent kind or sandbox substrate.

ratelimit-limit integer

The default limit on number of requests that can be made per hour and per minute. Current rate limits are 5000 requests per hour and 250 requests per minute.

ratelimit-remaining integer

The number of requests in your hourly quota that remain before you hit your request limit. See https://docs.digitalocean.com/reference/api/reference/#rate-limit for information about how requests expire.

ratelimit-reset integer

The time when the oldest request will expire. The value is given in Unix epoch time. See https://docs.digitalocean.com/reference/api/reference/#rate-limit for information about how requests expire.

id string required
Example: not_found

A short identifier corresponding to the HTTP status code returned. For example, the ID for a response returning a 404 status code would be "not_found."

message string required
Example: The resource you were accessing could not be found.

A message providing additional information about the error, including details to help resolve it when possible.

request_id string optional
Example: 4d9d8375-3c56-4925-a3e7-eb137fed17e9

Optionally, some endpoints may include a request ID that should be provided when reporting bugs or opening support tickets to help identify the issue.

default

There was an unexpected error.

ratelimit-limit integer

The default limit on number of requests that can be made per hour and per minute. Current rate limits are 5000 requests per hour and 250 requests per minute.

ratelimit-remaining integer

The number of requests in your hourly quota that remain before you hit your request limit. See https://docs.digitalocean.com/reference/api/reference/#rate-limit for information about how requests expire.

ratelimit-reset integer

The time when the oldest request will expire. The value is given in Unix epoch time. See https://docs.digitalocean.com/reference/api/reference/#rate-limit for information about how requests expire.

id string required
Example: not_found

A short identifier corresponding to the HTTP status code returned. For example, the ID for a response returning a 404 status code would be "not_found."

message string required
Example: The resource you were accessing could not be found.

A message providing additional information about the error, including details to help resolve it when possible.

request_id string optional
Example: 4d9d8375-3c56-4925-a3e7-eb137fed17e9

Optionally, some endpoints may include a request ID that should be provided when reporting bugs or opening support tickets to help identify the issue.

{
  "ingress_url": {
    "created_at": "2026-07-27T12:00:00Z",
    "ingress_url_id": "3f2a1b0c-9d8e-7f6a-5b4c-3d2e1f0a9b8c",
    "port": 8000,
    "session_id": "a1b2c3d4-e5f6-7890-abcd-ef1234567890",
    "state": "INGRESS_URL_STATE_READY",
    "url": "https://abc123.nyc3.sandbox.ondigitalocean.com"
  }
}
{
  "id": "unauthorized",
  "message": "Unable to authenticate you."
}
{
  "id": "not_found",
  "message": "The resource you were accessing could not be found.",
  "request_id": "4d9d8375-3c56-4925-a3e7-eb137fed17e9"
}
{
  "id": "not_found",
  "message": "The resource you requested could not be found."
}
{
  "id": "not_found",
  "message": "The resource you were accessing could not be found.",
  "request_id": "4d9d8375-3c56-4925-a3e7-eb137fed17e9"
}
{
  "id": "not_found",
  "message": "The resource you were accessing could not be found.",
  "request_id": "4d9d8375-3c56-4925-a3e7-eb137fed17e9"
}
{
  "id": "too_many_requests",
  "message": "API rate limit exceeded."
}
{
  "id": "server_error",
  "message": "Unexpected server-side error"
}
{
  "id": "not_found",
  "message": "The resource you were accessing could not be found.",
  "request_id": "4d9d8375-3c56-4925-a3e7-eb137fed17e9"
}
{
  "id": "example_error",
  "message": "some error message"
}

GET ListTeamTemplates returns the caller's team custom templates.

/v2/agents/templates
Authorizations: bearer_auth (1 scope)
Http: Bearer
Required scopes: agent_harness_session:read

OAuth Authentication

In order to interact with the DigitalOcean API, you or your application must authenticate.

The DigitalOcean API handles this through OAuth, an open standard for authorization. OAuth allows you to delegate access to your account. Scopes can be used to grant full access, read-only access, or access to a specific set of endpoints.

You can generate an OAuth token by visiting the Apps & API section of the DigitalOcean control panel for your account.

An OAuth token functions as a complete authentication request. In effect, it acts as a substitute for a username and password pair.

Because of this, it is absolutely essential that you keep your OAuth tokens secure. In fact, upon generation, the web interface will only display each token a single time in order to prevent the token from being compromised.

DigitalOcean access tokens begin with an identifiable prefix in order to distinguish them from other similar tokens.

  • dop_v1_ for personal access tokens generated in the control panel
  • doo_v1_ for tokens generated by applications using the OAuth flow
  • dor_v1_ for OAuth refresh tokens

Scopes

Scopes act like permissions assigned to an API token. These permissions determine what actions the token can perform. You can create API tokens that grant read-only access, full access, or limited access to specific endpoints by using custom scopes.

Generally, scopes are designed to match HTTP verbs and common CRUD operations (Create, Read, Update, Delete).

HTTP Verb CRUD Operation Scope
GET Read <resource>:read
POST Create <resource>:create
PUT/PATCH Update <resource>:update
DELETE Delete <resource>:delete

For example, creating a new Droplet by making a POST request to the /v2/droplets endpoint requires the droplet:create scope while listing Droplets by making a GET request to the /v2/droplets endpoint requires the droplet:read scope.

Each endpoint below specifies which scope is required to access it when using custom scopes.

How to Authenticate with OAuth

In order to make an authenticated request, include a bearer-type Authorization header containing your OAuth token. All requests must be made over HTTPS.

Authenticate with a Bearer Authorization Header

curl -X $HTTP_METHOD -H "Authorization: Bearer $DIGITALOCEAN_TOKEN" "https://api.digitalocean.com/v2/$OBJECT"

team_id is stamped from the authenticated principal; never accepted from the client.

Query Parameters

page_size integer (int32) optional
Example: 50

Page size. Defaults to 50 when omitted or non-positive.

page_token string optional

Optional pagination cursor (opaque). Empty starts from the beginning.

curl -X GET \
  -H "Authorization: Bearer $DIGITALOCEAN_TOKEN" \
  "https://api.digitalocean.com/v2/agents/templates"
curl -X GET \
  -H "Authorization: Bearer $API_TOKEN" \
  "https://api.digitalocean.com/v2/agents/templates"

Responses

200

A successful response.

ratelimit-limit integer

The default limit on number of requests that can be made per hour and per minute. Current rate limits are 5000 requests per hour and 250 requests per minute.

ratelimit-remaining integer

The number of requests in your hourly quota that remain before you hit your request limit. See https://docs.digitalocean.com/reference/api/reference/#rate-limit for information about how requests expire.

ratelimit-reset integer

The time when the oldest request will expire. The value is given in Unix epoch time. See https://docs.digitalocean.com/reference/api/reference/#rate-limit for information about how requests expire.

next_page_token string optional
templates array of object optional
Show child properties
created_at string (date-time) required
Example: 2026-08-01T12:00:00Z
name string required
Example: my-custom-template
spec object optional
Show child properties
base_template string optional
Example: coding-opencode

Base template key. One of: coding-base, coding-claude-code, coding-codex, coding-hermes, coding-opencode, langgraph.

image object optional
Show child properties
digest string optional
Example: sha256:deadbeef
registry string optional
Example: registry.digitalocean.com
repository string optional
Example: my-team/agent-base
tag string optional
Example: latest
status string, one of: TEMPLATE_STATUS_UNSPECIFIED, TEMPLATE_STATUS_PENDING, TEMPLATE_STATUS_BUILDING, TEMPLATE_STATUS_READY, TEMPLATE_STATUS_FAILED required
Example: TEMPLATE_STATUS_READY
template_id string (uuid) required
Example: aaaaaaaa-bbbb-cccc-dddd-eeeeeeeeeeee
updated_at string (date-time) required
Example: 2026-08-01T12:05:00Z
401

Authentication failed due to invalid credentials.

ratelimit-limit integer

The default limit on number of requests that can be made per hour and per minute. Current rate limits are 5000 requests per hour and 250 requests per minute.

ratelimit-remaining integer

The number of requests in your hourly quota that remain before you hit your request limit. See https://docs.digitalocean.com/reference/api/reference/#rate-limit for information about how requests expire.

ratelimit-reset integer

The time when the oldest request will expire. The value is given in Unix epoch time. See https://docs.digitalocean.com/reference/api/reference/#rate-limit for information about how requests expire.

id string required
Example: not_found

A short identifier corresponding to the HTTP status code returned. For example, the ID for a response returning a 404 status code would be "not_found."

message string required
Example: The resource you were accessing could not be found.

A message providing additional information about the error, including details to help resolve it when possible.

request_id string optional
Example: 4d9d8375-3c56-4925-a3e7-eb137fed17e9

Optionally, some endpoints may include a request ID that should be provided when reporting bugs or opening support tickets to help identify the issue.

429

The API rate limit has been exceeded.

ratelimit-limit integer

The default limit on number of requests that can be made per hour and per minute. Current rate limits are 5000 requests per hour and 250 requests per minute.

ratelimit-remaining integer

The number of requests in your hourly quota that remain before you hit your request limit. See https://docs.digitalocean.com/reference/api/reference/#rate-limit for information about how requests expire.

ratelimit-reset integer

The time when the oldest request will expire. The value is given in Unix epoch time. See https://docs.digitalocean.com/reference/api/reference/#rate-limit for information about how requests expire.

id string required
Example: not_found

A short identifier corresponding to the HTTP status code returned. For example, the ID for a response returning a 404 status code would be "not_found."

message string required
Example: The resource you were accessing could not be found.

A message providing additional information about the error, including details to help resolve it when possible.

request_id string optional
Example: 4d9d8375-3c56-4925-a3e7-eb137fed17e9

Optionally, some endpoints may include a request ID that should be provided when reporting bugs or opening support tickets to help identify the issue.

500

There was a server error.

ratelimit-limit integer

The default limit on number of requests that can be made per hour and per minute. Current rate limits are 5000 requests per hour and 250 requests per minute.

ratelimit-remaining integer

The number of requests in your hourly quota that remain before you hit your request limit. See https://docs.digitalocean.com/reference/api/reference/#rate-limit for information about how requests expire.

ratelimit-reset integer

The time when the oldest request will expire. The value is given in Unix epoch time. See https://docs.digitalocean.com/reference/api/reference/#rate-limit for information about how requests expire.

id string required
Example: not_found

A short identifier corresponding to the HTTP status code returned. For example, the ID for a response returning a 404 status code would be "not_found."

message string required
Example: The resource you were accessing could not be found.

A message providing additional information about the error, including details to help resolve it when possible.

request_id string optional
Example: 4d9d8375-3c56-4925-a3e7-eb137fed17e9

Optionally, some endpoints may include a request ID that should be provided when reporting bugs or opening support tickets to help identify the issue.

default

There was an unexpected error.

ratelimit-limit integer

The default limit on number of requests that can be made per hour and per minute. Current rate limits are 5000 requests per hour and 250 requests per minute.

ratelimit-remaining integer

The number of requests in your hourly quota that remain before you hit your request limit. See https://docs.digitalocean.com/reference/api/reference/#rate-limit for information about how requests expire.

ratelimit-reset integer

The time when the oldest request will expire. The value is given in Unix epoch time. See https://docs.digitalocean.com/reference/api/reference/#rate-limit for information about how requests expire.

id string required
Example: not_found

A short identifier corresponding to the HTTP status code returned. For example, the ID for a response returning a 404 status code would be "not_found."

message string required
Example: The resource you were accessing could not be found.

A message providing additional information about the error, including details to help resolve it when possible.

request_id string optional
Example: 4d9d8375-3c56-4925-a3e7-eb137fed17e9

Optionally, some endpoints may include a request ID that should be provided when reporting bugs or opening support tickets to help identify the issue.

{
  "next_page_token": "string",
  "templates": [
    {
      "created_at": "2026-08-01T12:00:00Z",
      "name": "my-custom-template",
      "status": "TEMPLATE_STATUS_READY",
      "template_id": "aaaaaaaa-bbbb-cccc-dddd-eeeeeeeeeeee",
      "updated_at": "2026-08-01T12:05:00Z"
    }
  ]
}
{
  "id": "unauthorized",
  "message": "Unable to authenticate you."
}
{
  "id": "too_many_requests",
  "message": "API rate limit exceeded."
}
{
  "id": "server_error",
  "message": "Unexpected server-side error"
}
{
  "id": "example_error",
  "message": "some error message"
}

POST CreateTemplate creates a team custom template and kicks a build.

/v2/agents/templates
Authorizations: bearer_auth (1 scope)
Http: Bearer
Required scopes: agent_harness_session:manage

OAuth Authentication

In order to interact with the DigitalOcean API, you or your application must authenticate.

The DigitalOcean API handles this through OAuth, an open standard for authorization. OAuth allows you to delegate access to your account. Scopes can be used to grant full access, read-only access, or access to a specific set of endpoints.

You can generate an OAuth token by visiting the Apps & API section of the DigitalOcean control panel for your account.

An OAuth token functions as a complete authentication request. In effect, it acts as a substitute for a username and password pair.

Because of this, it is absolutely essential that you keep your OAuth tokens secure. In fact, upon generation, the web interface will only display each token a single time in order to prevent the token from being compromised.

DigitalOcean access tokens begin with an identifiable prefix in order to distinguish them from other similar tokens.

  • dop_v1_ for personal access tokens generated in the control panel
  • doo_v1_ for tokens generated by applications using the OAuth flow
  • dor_v1_ for OAuth refresh tokens

Scopes

Scopes act like permissions assigned to an API token. These permissions determine what actions the token can perform. You can create API tokens that grant read-only access, full access, or limited access to specific endpoints by using custom scopes.

Generally, scopes are designed to match HTTP verbs and common CRUD operations (Create, Read, Update, Delete).

HTTP Verb CRUD Operation Scope
GET Read <resource>:read
POST Create <resource>:create
PUT/PATCH Update <resource>:update
DELETE Delete <resource>:delete

For example, creating a new Droplet by making a POST request to the /v2/droplets endpoint requires the droplet:create scope while listing Droplets by making a GET request to the /v2/droplets endpoint requires the droplet:read scope.

Each endpoint below specifies which scope is required to access it when using custom scopes.

How to Authenticate with OAuth

In order to make an authenticated request, include a bearer-type Authorization header containing your OAuth token. All requests must be made over HTTPS.

Authenticate with a Bearer Authorization Header

curl -X $HTTP_METHOD -H "Authorization: Bearer $DIGITALOCEAN_TOKEN" "https://api.digitalocean.com/v2/$OBJECT"

Creates a team-owned template from a customer OCI ref rebased onto a base template. team_id is stamped from the authenticated principal.

Request Body: application/json

Template create body.

base_template string required

Base template key. One of: coding-base, coding-claude-code, coding-codex, coding-hermes, coding-opencode, langgraph.

name string required
source_oci_ref string required
Content type application/json
{
  "base_template": "string",
  "name": "string",
  "source_oci_ref": "string"
}
curl -X POST \
  -H "Content-Type: application/json" \
  -H "Authorization: Bearer $DIGITALOCEAN_TOKEN" \
  -d '{"name":"my-template","base_template":"coding-base","source_oci_ref":"registry.example.com/team/image:tag"}' \
  "https://api.digitalocean.com/v2/agents/templates"
curl -X POST \
  -H "Authorization: Bearer $API_TOKEN" \
  -H "Content-Type: application/json" \
  -d '{
  "base_template": "string",
  "name": "string",
  "source_oci_ref": "string"
}' \
  "https://api.digitalocean.com/v2/agents/templates"

Responses

201

Template created; build kicked.

ratelimit-limit integer

The default limit on number of requests that can be made per hour and per minute. Current rate limits are 5000 requests per hour and 250 requests per minute.

ratelimit-remaining integer

The number of requests in your hourly quota that remain before you hit your request limit. See https://docs.digitalocean.com/reference/api/reference/#rate-limit for information about how requests expire.

ratelimit-reset integer

The time when the oldest request will expire. The value is given in Unix epoch time. See https://docs.digitalocean.com/reference/api/reference/#rate-limit for information about how requests expire.

template object optional
Show child properties
created_at string (date-time) required
Example: 2026-08-01T12:00:00Z
name string required
Example: my-custom-template
spec object optional
Show child properties
base_template string optional
Example: coding-opencode

Base template key. One of: coding-base, coding-claude-code, coding-codex, coding-hermes, coding-opencode, langgraph.

image object optional
Show child properties
digest string optional
Example: sha256:deadbeef
registry string optional
Example: registry.digitalocean.com
repository string optional
Example: my-team/agent-base
tag string optional
Example: latest
status string, one of: TEMPLATE_STATUS_UNSPECIFIED, TEMPLATE_STATUS_PENDING, TEMPLATE_STATUS_BUILDING, TEMPLATE_STATUS_READY, TEMPLATE_STATUS_FAILED required
Example: TEMPLATE_STATUS_READY
template_id string (uuid) required
Example: aaaaaaaa-bbbb-cccc-dddd-eeeeeeeeeeee
updated_at string (date-time) required
Example: 2026-08-01T12:05:00Z
400

Invalid request.

ratelimit-limit integer

The default limit on number of requests that can be made per hour and per minute. Current rate limits are 5000 requests per hour and 250 requests per minute.

ratelimit-remaining integer

The number of requests in your hourly quota that remain before you hit your request limit. See https://docs.digitalocean.com/reference/api/reference/#rate-limit for information about how requests expire.

ratelimit-reset integer

The time when the oldest request will expire. The value is given in Unix epoch time. See https://docs.digitalocean.com/reference/api/reference/#rate-limit for information about how requests expire.

id string required
Example: not_found

A short identifier corresponding to the HTTP status code returned. For example, the ID for a response returning a 404 status code would be "not_found."

message string required
Example: The resource you were accessing could not be found.

A message providing additional information about the error, including details to help resolve it when possible.

request_id string optional
Example: 4d9d8375-3c56-4925-a3e7-eb137fed17e9

Optionally, some endpoints may include a request ID that should be provided when reporting bugs or opening support tickets to help identify the issue.

401

Authentication failed due to invalid credentials.

ratelimit-limit integer

The default limit on number of requests that can be made per hour and per minute. Current rate limits are 5000 requests per hour and 250 requests per minute.

ratelimit-remaining integer

The number of requests in your hourly quota that remain before you hit your request limit. See https://docs.digitalocean.com/reference/api/reference/#rate-limit for information about how requests expire.

ratelimit-reset integer

The time when the oldest request will expire. The value is given in Unix epoch time. See https://docs.digitalocean.com/reference/api/reference/#rate-limit for information about how requests expire.

id string required
Example: not_found

A short identifier corresponding to the HTTP status code returned. For example, the ID for a response returning a 404 status code would be "not_found."

message string required
Example: The resource you were accessing could not be found.

A message providing additional information about the error, including details to help resolve it when possible.

request_id string optional
Example: 4d9d8375-3c56-4925-a3e7-eb137fed17e9

Optionally, some endpoints may include a request ID that should be provided when reporting bugs or opening support tickets to help identify the issue.

402

The team is blocked by the prepayment gate.

ratelimit-limit integer

The default limit on number of requests that can be made per hour and per minute. Current rate limits are 5000 requests per hour and 250 requests per minute.

ratelimit-remaining integer

The number of requests in your hourly quota that remain before you hit your request limit. See https://docs.digitalocean.com/reference/api/reference/#rate-limit for information about how requests expire.

ratelimit-reset integer

The time when the oldest request will expire. The value is given in Unix epoch time. See https://docs.digitalocean.com/reference/api/reference/#rate-limit for information about how requests expire.

id string required
Example: not_found

A short identifier corresponding to the HTTP status code returned. For example, the ID for a response returning a 404 status code would be "not_found."

message string required
Example: The resource you were accessing could not be found.

A message providing additional information about the error, including details to help resolve it when possible.

request_id string optional
Example: 4d9d8375-3c56-4925-a3e7-eb137fed17e9

Optionally, some endpoints may include a request ID that should be provided when reporting bugs or opening support tickets to help identify the issue.

429

The API rate limit has been exceeded.

ratelimit-limit integer

The default limit on number of requests that can be made per hour and per minute. Current rate limits are 5000 requests per hour and 250 requests per minute.

ratelimit-remaining integer

The number of requests in your hourly quota that remain before you hit your request limit. See https://docs.digitalocean.com/reference/api/reference/#rate-limit for information about how requests expire.

ratelimit-reset integer

The time when the oldest request will expire. The value is given in Unix epoch time. See https://docs.digitalocean.com/reference/api/reference/#rate-limit for information about how requests expire.

id string required
Example: not_found

A short identifier corresponding to the HTTP status code returned. For example, the ID for a response returning a 404 status code would be "not_found."

message string required
Example: The resource you were accessing could not be found.

A message providing additional information about the error, including details to help resolve it when possible.

request_id string optional
Example: 4d9d8375-3c56-4925-a3e7-eb137fed17e9

Optionally, some endpoints may include a request ID that should be provided when reporting bugs or opening support tickets to help identify the issue.

500

There was a server error.

ratelimit-limit integer

The default limit on number of requests that can be made per hour and per minute. Current rate limits are 5000 requests per hour and 250 requests per minute.

ratelimit-remaining integer

The number of requests in your hourly quota that remain before you hit your request limit. See https://docs.digitalocean.com/reference/api/reference/#rate-limit for information about how requests expire.

ratelimit-reset integer

The time when the oldest request will expire. The value is given in Unix epoch time. See https://docs.digitalocean.com/reference/api/reference/#rate-limit for information about how requests expire.

id string required
Example: not_found

A short identifier corresponding to the HTTP status code returned. For example, the ID for a response returning a 404 status code would be "not_found."

message string required
Example: The resource you were accessing could not be found.

A message providing additional information about the error, including details to help resolve it when possible.

request_id string optional
Example: 4d9d8375-3c56-4925-a3e7-eb137fed17e9

Optionally, some endpoints may include a request ID that should be provided when reporting bugs or opening support tickets to help identify the issue.

default

There was an unexpected error.

ratelimit-limit integer

The default limit on number of requests that can be made per hour and per minute. Current rate limits are 5000 requests per hour and 250 requests per minute.

ratelimit-remaining integer

The number of requests in your hourly quota that remain before you hit your request limit. See https://docs.digitalocean.com/reference/api/reference/#rate-limit for information about how requests expire.

ratelimit-reset integer

The time when the oldest request will expire. The value is given in Unix epoch time. See https://docs.digitalocean.com/reference/api/reference/#rate-limit for information about how requests expire.

id string required
Example: not_found

A short identifier corresponding to the HTTP status code returned. For example, the ID for a response returning a 404 status code would be "not_found."

message string required
Example: The resource you were accessing could not be found.

A message providing additional information about the error, including details to help resolve it when possible.

request_id string optional
Example: 4d9d8375-3c56-4925-a3e7-eb137fed17e9

Optionally, some endpoints may include a request ID that should be provided when reporting bugs or opening support tickets to help identify the issue.

{
  "template": {
    "created_at": "2026-08-01T12:00:00Z",
    "name": "my-custom-template",
    "spec": {
      "base_template": "coding-opencode"
    },
    "status": "TEMPLATE_STATUS_READY",
    "template_id": "aaaaaaaa-bbbb-cccc-dddd-eeeeeeeeeeee",
    "updated_at": "2026-08-01T12:05:00Z"
  }
}
{
  "id": "not_found",
  "message": "The resource you were accessing could not be found.",
  "request_id": "4d9d8375-3c56-4925-a3e7-eb137fed17e9"
}
{
  "id": "unauthorized",
  "message": "Unable to authenticate you."
}
{
  "id": "not_found",
  "message": "The resource you were accessing could not be found.",
  "request_id": "4d9d8375-3c56-4925-a3e7-eb137fed17e9"
}
{
  "id": "too_many_requests",
  "message": "API rate limit exceeded."
}
{
  "id": "server_error",
  "message": "Unexpected server-side error"
}
{
  "id": "example_error",
  "message": "some error message"
}

GET GetTemplate returns a team custom template by public id.

/v2/agents/templates/{template_id}
Authorizations: bearer_auth (1 scope)
Http: Bearer
Required scopes: agent_harness_session:read

OAuth Authentication

In order to interact with the DigitalOcean API, you or your application must authenticate.

The DigitalOcean API handles this through OAuth, an open standard for authorization. OAuth allows you to delegate access to your account. Scopes can be used to grant full access, read-only access, or access to a specific set of endpoints.

You can generate an OAuth token by visiting the Apps & API section of the DigitalOcean control panel for your account.

An OAuth token functions as a complete authentication request. In effect, it acts as a substitute for a username and password pair.

Because of this, it is absolutely essential that you keep your OAuth tokens secure. In fact, upon generation, the web interface will only display each token a single time in order to prevent the token from being compromised.

DigitalOcean access tokens begin with an identifiable prefix in order to distinguish them from other similar tokens.

  • dop_v1_ for personal access tokens generated in the control panel
  • doo_v1_ for tokens generated by applications using the OAuth flow
  • dor_v1_ for OAuth refresh tokens

Scopes

Scopes act like permissions assigned to an API token. These permissions determine what actions the token can perform. You can create API tokens that grant read-only access, full access, or limited access to specific endpoints by using custom scopes.

Generally, scopes are designed to match HTTP verbs and common CRUD operations (Create, Read, Update, Delete).

HTTP Verb CRUD Operation Scope
GET Read <resource>:read
POST Create <resource>:create
PUT/PATCH Update <resource>:update
DELETE Delete <resource>:delete

For example, creating a new Droplet by making a POST request to the /v2/droplets endpoint requires the droplet:create scope while listing Droplets by making a GET request to the /v2/droplets endpoint requires the droplet:read scope.

Each endpoint below specifies which scope is required to access it when using custom scopes.

How to Authenticate with OAuth

In order to make an authenticated request, include a bearer-type Authorization header containing your OAuth token. All requests must be made over HTTPS.

Authenticate with a Bearer Authorization Header

curl -X $HTTP_METHOD -H "Authorization: Bearer $DIGITALOCEAN_TOKEN" "https://api.digitalocean.com/v2/$OBJECT"

GetTemplate returns a team custom template by public id.

Path Parameters

template_id string (uuid) required
Example: 11111111-2222-3333-4444-555555555555

The template UUID.

curl -X GET \
  -H "Authorization: Bearer $DIGITALOCEAN_TOKEN" \
  "https://api.digitalocean.com/v2/agents/templates/{template_id}"
curl -X GET \
  -H "Authorization: Bearer $API_TOKEN" \
  "https://api.digitalocean.com/v2/agents/templates/{template_id}"

Responses

200

A successful response.

ratelimit-limit integer

The default limit on number of requests that can be made per hour and per minute. Current rate limits are 5000 requests per hour and 250 requests per minute.

ratelimit-remaining integer

The number of requests in your hourly quota that remain before you hit your request limit. See https://docs.digitalocean.com/reference/api/reference/#rate-limit for information about how requests expire.

ratelimit-reset integer

The time when the oldest request will expire. The value is given in Unix epoch time. See https://docs.digitalocean.com/reference/api/reference/#rate-limit for information about how requests expire.

template object optional
Show child properties
created_at string (date-time) required
Example: 2026-08-01T12:00:00Z
name string required
Example: my-custom-template
spec object optional
Show child properties
base_template string optional
Example: coding-opencode

Base template key. One of: coding-base, coding-claude-code, coding-codex, coding-hermes, coding-opencode, langgraph.

image object optional
Show child properties
digest string optional
Example: sha256:deadbeef
registry string optional
Example: registry.digitalocean.com
repository string optional
Example: my-team/agent-base
tag string optional
Example: latest
status string, one of: TEMPLATE_STATUS_UNSPECIFIED, TEMPLATE_STATUS_PENDING, TEMPLATE_STATUS_BUILDING, TEMPLATE_STATUS_READY, TEMPLATE_STATUS_FAILED required
Example: TEMPLATE_STATUS_READY
template_id string (uuid) required
Example: aaaaaaaa-bbbb-cccc-dddd-eeeeeeeeeeee
updated_at string (date-time) required
Example: 2026-08-01T12:05:00Z
401

Authentication failed due to invalid credentials.

ratelimit-limit integer

The default limit on number of requests that can be made per hour and per minute. Current rate limits are 5000 requests per hour and 250 requests per minute.

ratelimit-remaining integer

The number of requests in your hourly quota that remain before you hit your request limit. See https://docs.digitalocean.com/reference/api/reference/#rate-limit for information about how requests expire.

ratelimit-reset integer

The time when the oldest request will expire. The value is given in Unix epoch time. See https://docs.digitalocean.com/reference/api/reference/#rate-limit for information about how requests expire.

id string required
Example: not_found

A short identifier corresponding to the HTTP status code returned. For example, the ID for a response returning a 404 status code would be "not_found."

message string required
Example: The resource you were accessing could not be found.

A message providing additional information about the error, including details to help resolve it when possible.

request_id string optional
Example: 4d9d8375-3c56-4925-a3e7-eb137fed17e9

Optionally, some endpoints may include a request ID that should be provided when reporting bugs or opening support tickets to help identify the issue.

404

The resource was not found.

ratelimit-limit integer

The default limit on number of requests that can be made per hour and per minute. Current rate limits are 5000 requests per hour and 250 requests per minute.

ratelimit-remaining integer

The number of requests in your hourly quota that remain before you hit your request limit. See https://docs.digitalocean.com/reference/api/reference/#rate-limit for information about how requests expire.

ratelimit-reset integer

The time when the oldest request will expire. The value is given in Unix epoch time. See https://docs.digitalocean.com/reference/api/reference/#rate-limit for information about how requests expire.

id string required
Example: not_found

A short identifier corresponding to the HTTP status code returned. For example, the ID for a response returning a 404 status code would be "not_found."

message string required
Example: The resource you were accessing could not be found.

A message providing additional information about the error, including details to help resolve it when possible.

request_id string optional
Example: 4d9d8375-3c56-4925-a3e7-eb137fed17e9

Optionally, some endpoints may include a request ID that should be provided when reporting bugs or opening support tickets to help identify the issue.

429

The API rate limit has been exceeded.

ratelimit-limit integer

The default limit on number of requests that can be made per hour and per minute. Current rate limits are 5000 requests per hour and 250 requests per minute.

ratelimit-remaining integer

The number of requests in your hourly quota that remain before you hit your request limit. See https://docs.digitalocean.com/reference/api/reference/#rate-limit for information about how requests expire.

ratelimit-reset integer

The time when the oldest request will expire. The value is given in Unix epoch time. See https://docs.digitalocean.com/reference/api/reference/#rate-limit for information about how requests expire.

id string required
Example: not_found

A short identifier corresponding to the HTTP status code returned. For example, the ID for a response returning a 404 status code would be "not_found."

message string required
Example: The resource you were accessing could not be found.

A message providing additional information about the error, including details to help resolve it when possible.

request_id string optional
Example: 4d9d8375-3c56-4925-a3e7-eb137fed17e9

Optionally, some endpoints may include a request ID that should be provided when reporting bugs or opening support tickets to help identify the issue.

500

There was a server error.

ratelimit-limit integer

The default limit on number of requests that can be made per hour and per minute. Current rate limits are 5000 requests per hour and 250 requests per minute.

ratelimit-remaining integer

The number of requests in your hourly quota that remain before you hit your request limit. See https://docs.digitalocean.com/reference/api/reference/#rate-limit for information about how requests expire.

ratelimit-reset integer

The time when the oldest request will expire. The value is given in Unix epoch time. See https://docs.digitalocean.com/reference/api/reference/#rate-limit for information about how requests expire.

id string required
Example: not_found

A short identifier corresponding to the HTTP status code returned. For example, the ID for a response returning a 404 status code would be "not_found."

message string required
Example: The resource you were accessing could not be found.

A message providing additional information about the error, including details to help resolve it when possible.

request_id string optional
Example: 4d9d8375-3c56-4925-a3e7-eb137fed17e9

Optionally, some endpoints may include a request ID that should be provided when reporting bugs or opening support tickets to help identify the issue.

default

There was an unexpected error.

ratelimit-limit integer

The default limit on number of requests that can be made per hour and per minute. Current rate limits are 5000 requests per hour and 250 requests per minute.

ratelimit-remaining integer

The number of requests in your hourly quota that remain before you hit your request limit. See https://docs.digitalocean.com/reference/api/reference/#rate-limit for information about how requests expire.

ratelimit-reset integer

The time when the oldest request will expire. The value is given in Unix epoch time. See https://docs.digitalocean.com/reference/api/reference/#rate-limit for information about how requests expire.

id string required
Example: not_found

A short identifier corresponding to the HTTP status code returned. For example, the ID for a response returning a 404 status code would be "not_found."

message string required
Example: The resource you were accessing could not be found.

A message providing additional information about the error, including details to help resolve it when possible.

request_id string optional
Example: 4d9d8375-3c56-4925-a3e7-eb137fed17e9

Optionally, some endpoints may include a request ID that should be provided when reporting bugs or opening support tickets to help identify the issue.

{
  "template": {
    "created_at": "2026-08-01T12:00:00Z",
    "name": "my-custom-template",
    "spec": {
      "base_template": "coding-opencode"
    },
    "status": "TEMPLATE_STATUS_READY",
    "template_id": "aaaaaaaa-bbbb-cccc-dddd-eeeeeeeeeeee",
    "updated_at": "2026-08-01T12:05:00Z"
  }
}
{
  "id": "unauthorized",
  "message": "Unable to authenticate you."
}
{
  "id": "not_found",
  "message": "The resource you requested could not be found."
}
{
  "id": "too_many_requests",
  "message": "API rate limit exceeded."
}
{
  "id": "server_error",
  "message": "Unexpected server-side error"
}
{
  "id": "example_error",
  "message": "some error message"
}

PUT UpdateTemplate updates a team template's source and kicks a new build.

/v2/agents/templates/{template_id}
Authorizations: bearer_auth (1 scope)
Http: Bearer
Required scopes: agent_harness_session:manage

OAuth Authentication

In order to interact with the DigitalOcean API, you or your application must authenticate.

The DigitalOcean API handles this through OAuth, an open standard for authorization. OAuth allows you to delegate access to your account. Scopes can be used to grant full access, read-only access, or access to a specific set of endpoints.

You can generate an OAuth token by visiting the Apps & API section of the DigitalOcean control panel for your account.

An OAuth token functions as a complete authentication request. In effect, it acts as a substitute for a username and password pair.

Because of this, it is absolutely essential that you keep your OAuth tokens secure. In fact, upon generation, the web interface will only display each token a single time in order to prevent the token from being compromised.

DigitalOcean access tokens begin with an identifiable prefix in order to distinguish them from other similar tokens.

  • dop_v1_ for personal access tokens generated in the control panel
  • doo_v1_ for tokens generated by applications using the OAuth flow
  • dor_v1_ for OAuth refresh tokens

Scopes

Scopes act like permissions assigned to an API token. These permissions determine what actions the token can perform. You can create API tokens that grant read-only access, full access, or limited access to specific endpoints by using custom scopes.

Generally, scopes are designed to match HTTP verbs and common CRUD operations (Create, Read, Update, Delete).

HTTP Verb CRUD Operation Scope
GET Read <resource>:read
POST Create <resource>:create
PUT/PATCH Update <resource>:update
DELETE Delete <resource>:delete

For example, creating a new Droplet by making a POST request to the /v2/droplets endpoint requires the droplet:create scope while listing Droplets by making a GET request to the /v2/droplets endpoint requires the droplet:read scope.

Each endpoint below specifies which scope is required to access it when using custom scopes.

How to Authenticate with OAuth

In order to make an authenticated request, include a bearer-type Authorization header containing your OAuth token. All requests must be made over HTTPS.

Authenticate with a Bearer Authorization Header

curl -X $HTTP_METHOD -H "Authorization: Bearer $DIGITALOCEAN_TOKEN" "https://api.digitalocean.com/v2/$OBJECT"

UpdateTemplate updates a team template's source and kicks a new build.

Path Parameters

template_id string (uuid) required
Example: 11111111-2222-3333-4444-555555555555

The template UUID.

Request Body: application/json

Template update body.

base_template string optional
source_oci_ref string optional
Content type application/json
{
  "base_template": "string",
  "source_oci_ref": "string"
}
curl -X PUT \
  -H "Content-Type: application/json" \
  -H "Authorization: Bearer $DIGITALOCEAN_TOKEN" \
  -d '{"source_oci_ref":"registry.example.com/team/image:v2"}' \
  "https://api.digitalocean.com/v2/agents/templates/{template_id}"
curl -X PUT \
  -H "Authorization: Bearer $API_TOKEN" \
  -H "Content-Type: application/json" \
  -d '{
  "base_template": "string",
  "source_oci_ref": "string"
}' \
  "https://api.digitalocean.com/v2/agents/templates/{template_id}"

Responses

200

Template updated; build kicked.

ratelimit-limit integer

The default limit on number of requests that can be made per hour and per minute. Current rate limits are 5000 requests per hour and 250 requests per minute.

ratelimit-remaining integer

The number of requests in your hourly quota that remain before you hit your request limit. See https://docs.digitalocean.com/reference/api/reference/#rate-limit for information about how requests expire.

ratelimit-reset integer

The time when the oldest request will expire. The value is given in Unix epoch time. See https://docs.digitalocean.com/reference/api/reference/#rate-limit for information about how requests expire.

template object optional
Show child properties
created_at string (date-time) required
Example: 2026-08-01T12:00:00Z
name string required
Example: my-custom-template
spec object optional
Show child properties
base_template string optional
Example: coding-opencode

Base template key. One of: coding-base, coding-claude-code, coding-codex, coding-hermes, coding-opencode, langgraph.

image object optional
Show child properties
digest string optional
Example: sha256:deadbeef
registry string optional
Example: registry.digitalocean.com
repository string optional
Example: my-team/agent-base
tag string optional
Example: latest
status string, one of: TEMPLATE_STATUS_UNSPECIFIED, TEMPLATE_STATUS_PENDING, TEMPLATE_STATUS_BUILDING, TEMPLATE_STATUS_READY, TEMPLATE_STATUS_FAILED required
Example: TEMPLATE_STATUS_READY
template_id string (uuid) required
Example: aaaaaaaa-bbbb-cccc-dddd-eeeeeeeeeeee
updated_at string (date-time) required
Example: 2026-08-01T12:05:00Z
401

Authentication failed due to invalid credentials.

ratelimit-limit integer

The default limit on number of requests that can be made per hour and per minute. Current rate limits are 5000 requests per hour and 250 requests per minute.

ratelimit-remaining integer

The number of requests in your hourly quota that remain before you hit your request limit. See https://docs.digitalocean.com/reference/api/reference/#rate-limit for information about how requests expire.

ratelimit-reset integer

The time when the oldest request will expire. The value is given in Unix epoch time. See https://docs.digitalocean.com/reference/api/reference/#rate-limit for information about how requests expire.

id string required
Example: not_found

A short identifier corresponding to the HTTP status code returned. For example, the ID for a response returning a 404 status code would be "not_found."

message string required
Example: The resource you were accessing could not be found.

A message providing additional information about the error, including details to help resolve it when possible.

request_id string optional
Example: 4d9d8375-3c56-4925-a3e7-eb137fed17e9

Optionally, some endpoints may include a request ID that should be provided when reporting bugs or opening support tickets to help identify the issue.

402

The team is blocked by the prepayment gate.

ratelimit-limit integer

The default limit on number of requests that can be made per hour and per minute. Current rate limits are 5000 requests per hour and 250 requests per minute.

ratelimit-remaining integer

The number of requests in your hourly quota that remain before you hit your request limit. See https://docs.digitalocean.com/reference/api/reference/#rate-limit for information about how requests expire.

ratelimit-reset integer

The time when the oldest request will expire. The value is given in Unix epoch time. See https://docs.digitalocean.com/reference/api/reference/#rate-limit for information about how requests expire.

id string required
Example: not_found

A short identifier corresponding to the HTTP status code returned. For example, the ID for a response returning a 404 status code would be "not_found."

message string required
Example: The resource you were accessing could not be found.

A message providing additional information about the error, including details to help resolve it when possible.

request_id string optional
Example: 4d9d8375-3c56-4925-a3e7-eb137fed17e9

Optionally, some endpoints may include a request ID that should be provided when reporting bugs or opening support tickets to help identify the issue.

404

The resource was not found.

ratelimit-limit integer

The default limit on number of requests that can be made per hour and per minute. Current rate limits are 5000 requests per hour and 250 requests per minute.

ratelimit-remaining integer

The number of requests in your hourly quota that remain before you hit your request limit. See https://docs.digitalocean.com/reference/api/reference/#rate-limit for information about how requests expire.

ratelimit-reset integer

The time when the oldest request will expire. The value is given in Unix epoch time. See https://docs.digitalocean.com/reference/api/reference/#rate-limit for information about how requests expire.

id string required
Example: not_found

A short identifier corresponding to the HTTP status code returned. For example, the ID for a response returning a 404 status code would be "not_found."

message string required
Example: The resource you were accessing could not be found.

A message providing additional information about the error, including details to help resolve it when possible.

request_id string optional
Example: 4d9d8375-3c56-4925-a3e7-eb137fed17e9

Optionally, some endpoints may include a request ID that should be provided when reporting bugs or opening support tickets to help identify the issue.

429

The API rate limit has been exceeded.

ratelimit-limit integer

The default limit on number of requests that can be made per hour and per minute. Current rate limits are 5000 requests per hour and 250 requests per minute.

ratelimit-remaining integer

The number of requests in your hourly quota that remain before you hit your request limit. See https://docs.digitalocean.com/reference/api/reference/#rate-limit for information about how requests expire.

ratelimit-reset integer

The time when the oldest request will expire. The value is given in Unix epoch time. See https://docs.digitalocean.com/reference/api/reference/#rate-limit for information about how requests expire.

id string required
Example: not_found

A short identifier corresponding to the HTTP status code returned. For example, the ID for a response returning a 404 status code would be "not_found."

message string required
Example: The resource you were accessing could not be found.

A message providing additional information about the error, including details to help resolve it when possible.

request_id string optional
Example: 4d9d8375-3c56-4925-a3e7-eb137fed17e9

Optionally, some endpoints may include a request ID that should be provided when reporting bugs or opening support tickets to help identify the issue.

500

There was a server error.

ratelimit-limit integer

The default limit on number of requests that can be made per hour and per minute. Current rate limits are 5000 requests per hour and 250 requests per minute.

ratelimit-remaining integer

The number of requests in your hourly quota that remain before you hit your request limit. See https://docs.digitalocean.com/reference/api/reference/#rate-limit for information about how requests expire.

ratelimit-reset integer

The time when the oldest request will expire. The value is given in Unix epoch time. See https://docs.digitalocean.com/reference/api/reference/#rate-limit for information about how requests expire.

id string required
Example: not_found

A short identifier corresponding to the HTTP status code returned. For example, the ID for a response returning a 404 status code would be "not_found."

message string required
Example: The resource you were accessing could not be found.

A message providing additional information about the error, including details to help resolve it when possible.

request_id string optional
Example: 4d9d8375-3c56-4925-a3e7-eb137fed17e9

Optionally, some endpoints may include a request ID that should be provided when reporting bugs or opening support tickets to help identify the issue.

default

There was an unexpected error.

ratelimit-limit integer

The default limit on number of requests that can be made per hour and per minute. Current rate limits are 5000 requests per hour and 250 requests per minute.

ratelimit-remaining integer

The number of requests in your hourly quota that remain before you hit your request limit. See https://docs.digitalocean.com/reference/api/reference/#rate-limit for information about how requests expire.

ratelimit-reset integer

The time when the oldest request will expire. The value is given in Unix epoch time. See https://docs.digitalocean.com/reference/api/reference/#rate-limit for information about how requests expire.

id string required
Example: not_found

A short identifier corresponding to the HTTP status code returned. For example, the ID for a response returning a 404 status code would be "not_found."

message string required
Example: The resource you were accessing could not be found.

A message providing additional information about the error, including details to help resolve it when possible.

request_id string optional
Example: 4d9d8375-3c56-4925-a3e7-eb137fed17e9

Optionally, some endpoints may include a request ID that should be provided when reporting bugs or opening support tickets to help identify the issue.

{
  "template": {
    "created_at": "2026-08-01T12:00:00Z",
    "name": "my-custom-template",
    "spec": {
      "base_template": "coding-opencode"
    },
    "status": "TEMPLATE_STATUS_READY",
    "template_id": "aaaaaaaa-bbbb-cccc-dddd-eeeeeeeeeeee",
    "updated_at": "2026-08-01T12:05:00Z"
  }
}
{
  "id": "unauthorized",
  "message": "Unable to authenticate you."
}
{
  "id": "not_found",
  "message": "The resource you were accessing could not be found.",
  "request_id": "4d9d8375-3c56-4925-a3e7-eb137fed17e9"
}
{
  "id": "not_found",
  "message": "The resource you requested could not be found."
}
{
  "id": "too_many_requests",
  "message": "API rate limit exceeded."
}
{
  "id": "server_error",
  "message": "Unexpected server-side error"
}
{
  "id": "example_error",
  "message": "some error message"
}

DELETE DeleteTemplate deletes a team custom template.

/v2/agents/templates/{template_id}
Authorizations: bearer_auth (1 scope)
Http: Bearer
Required scopes: agent_harness_session:manage

OAuth Authentication

In order to interact with the DigitalOcean API, you or your application must authenticate.

The DigitalOcean API handles this through OAuth, an open standard for authorization. OAuth allows you to delegate access to your account. Scopes can be used to grant full access, read-only access, or access to a specific set of endpoints.

You can generate an OAuth token by visiting the Apps & API section of the DigitalOcean control panel for your account.

An OAuth token functions as a complete authentication request. In effect, it acts as a substitute for a username and password pair.

Because of this, it is absolutely essential that you keep your OAuth tokens secure. In fact, upon generation, the web interface will only display each token a single time in order to prevent the token from being compromised.

DigitalOcean access tokens begin with an identifiable prefix in order to distinguish them from other similar tokens.

  • dop_v1_ for personal access tokens generated in the control panel
  • doo_v1_ for tokens generated by applications using the OAuth flow
  • dor_v1_ for OAuth refresh tokens

Scopes

Scopes act like permissions assigned to an API token. These permissions determine what actions the token can perform. You can create API tokens that grant read-only access, full access, or limited access to specific endpoints by using custom scopes.

Generally, scopes are designed to match HTTP verbs and common CRUD operations (Create, Read, Update, Delete).

HTTP Verb CRUD Operation Scope
GET Read <resource>:read
POST Create <resource>:create
PUT/PATCH Update <resource>:update
DELETE Delete <resource>:delete

For example, creating a new Droplet by making a POST request to the /v2/droplets endpoint requires the droplet:create scope while listing Droplets by making a GET request to the /v2/droplets endpoint requires the droplet:read scope.

Each endpoint below specifies which scope is required to access it when using custom scopes.

How to Authenticate with OAuth

In order to make an authenticated request, include a bearer-type Authorization header containing your OAuth token. All requests must be made over HTTPS.

Authenticate with a Bearer Authorization Header

curl -X $HTTP_METHOD -H "Authorization: Bearer $DIGITALOCEAN_TOKEN" "https://api.digitalocean.com/v2/$OBJECT"

Global templates cannot be deleted via this API.

Path Parameters

template_id string (uuid) required
Example: 11111111-2222-3333-4444-555555555555

The template UUID.

curl -X DELETE \
  -H "Authorization: Bearer $DIGITALOCEAN_TOKEN" \
  "https://api.digitalocean.com/v2/agents/templates/{template_id}"
curl -X DELETE \
  -H "Authorization: Bearer $API_TOKEN" \
  "https://api.digitalocean.com/v2/agents/templates/{template_id}"

Responses

200

Template deleted.

ratelimit-limit integer

The default limit on number of requests that can be made per hour and per minute. Current rate limits are 5000 requests per hour and 250 requests per minute.

ratelimit-remaining integer

The number of requests in your hourly quota that remain before you hit your request limit. See https://docs.digitalocean.com/reference/api/reference/#rate-limit for information about how requests expire.

ratelimit-reset integer

The time when the oldest request will expire. The value is given in Unix epoch time. See https://docs.digitalocean.com/reference/api/reference/#rate-limit for information about how requests expire.

deleted boolean optional
template_id string (uuid) optional
401

Authentication failed due to invalid credentials.

ratelimit-limit integer

The default limit on number of requests that can be made per hour and per minute. Current rate limits are 5000 requests per hour and 250 requests per minute.

ratelimit-remaining integer

The number of requests in your hourly quota that remain before you hit your request limit. See https://docs.digitalocean.com/reference/api/reference/#rate-limit for information about how requests expire.

ratelimit-reset integer

The time when the oldest request will expire. The value is given in Unix epoch time. See https://docs.digitalocean.com/reference/api/reference/#rate-limit for information about how requests expire.

id string required
Example: not_found

A short identifier corresponding to the HTTP status code returned. For example, the ID for a response returning a 404 status code would be "not_found."

message string required
Example: The resource you were accessing could not be found.

A message providing additional information about the error, including details to help resolve it when possible.

request_id string optional
Example: 4d9d8375-3c56-4925-a3e7-eb137fed17e9

Optionally, some endpoints may include a request ID that should be provided when reporting bugs or opening support tickets to help identify the issue.

404

The resource was not found.

ratelimit-limit integer

The default limit on number of requests that can be made per hour and per minute. Current rate limits are 5000 requests per hour and 250 requests per minute.

ratelimit-remaining integer

The number of requests in your hourly quota that remain before you hit your request limit. See https://docs.digitalocean.com/reference/api/reference/#rate-limit for information about how requests expire.

ratelimit-reset integer

The time when the oldest request will expire. The value is given in Unix epoch time. See https://docs.digitalocean.com/reference/api/reference/#rate-limit for information about how requests expire.

id string required
Example: not_found

A short identifier corresponding to the HTTP status code returned. For example, the ID for a response returning a 404 status code would be "not_found."

message string required
Example: The resource you were accessing could not be found.

A message providing additional information about the error, including details to help resolve it when possible.

request_id string optional
Example: 4d9d8375-3c56-4925-a3e7-eb137fed17e9

Optionally, some endpoints may include a request ID that should be provided when reporting bugs or opening support tickets to help identify the issue.

429

The API rate limit has been exceeded.

ratelimit-limit integer

The default limit on number of requests that can be made per hour and per minute. Current rate limits are 5000 requests per hour and 250 requests per minute.

ratelimit-remaining integer

The number of requests in your hourly quota that remain before you hit your request limit. See https://docs.digitalocean.com/reference/api/reference/#rate-limit for information about how requests expire.

ratelimit-reset integer

The time when the oldest request will expire. The value is given in Unix epoch time. See https://docs.digitalocean.com/reference/api/reference/#rate-limit for information about how requests expire.

id string required
Example: not_found

A short identifier corresponding to the HTTP status code returned. For example, the ID for a response returning a 404 status code would be "not_found."

message string required
Example: The resource you were accessing could not be found.

A message providing additional information about the error, including details to help resolve it when possible.

request_id string optional
Example: 4d9d8375-3c56-4925-a3e7-eb137fed17e9

Optionally, some endpoints may include a request ID that should be provided when reporting bugs or opening support tickets to help identify the issue.

500

There was a server error.

ratelimit-limit integer

The default limit on number of requests that can be made per hour and per minute. Current rate limits are 5000 requests per hour and 250 requests per minute.

ratelimit-remaining integer

The number of requests in your hourly quota that remain before you hit your request limit. See https://docs.digitalocean.com/reference/api/reference/#rate-limit for information about how requests expire.

ratelimit-reset integer

The time when the oldest request will expire. The value is given in Unix epoch time. See https://docs.digitalocean.com/reference/api/reference/#rate-limit for information about how requests expire.

id string required
Example: not_found

A short identifier corresponding to the HTTP status code returned. For example, the ID for a response returning a 404 status code would be "not_found."

message string required
Example: The resource you were accessing could not be found.

A message providing additional information about the error, including details to help resolve it when possible.

request_id string optional
Example: 4d9d8375-3c56-4925-a3e7-eb137fed17e9

Optionally, some endpoints may include a request ID that should be provided when reporting bugs or opening support tickets to help identify the issue.

default

There was an unexpected error.

ratelimit-limit integer

The default limit on number of requests that can be made per hour and per minute. Current rate limits are 5000 requests per hour and 250 requests per minute.

ratelimit-remaining integer

The number of requests in your hourly quota that remain before you hit your request limit. See https://docs.digitalocean.com/reference/api/reference/#rate-limit for information about how requests expire.

ratelimit-reset integer

The time when the oldest request will expire. The value is given in Unix epoch time. See https://docs.digitalocean.com/reference/api/reference/#rate-limit for information about how requests expire.

id string required
Example: not_found

A short identifier corresponding to the HTTP status code returned. For example, the ID for a response returning a 404 status code would be "not_found."

message string required
Example: The resource you were accessing could not be found.

A message providing additional information about the error, including details to help resolve it when possible.

request_id string optional
Example: 4d9d8375-3c56-4925-a3e7-eb137fed17e9

Optionally, some endpoints may include a request ID that should be provided when reporting bugs or opening support tickets to help identify the issue.

{
  "deleted": true,
  "template_id": "497f6eca-6276-4993-bfeb-53cbbbba6f08"
}
{
  "id": "unauthorized",
  "message": "Unable to authenticate you."
}
{
  "id": "not_found",
  "message": "The resource you requested could not be found."
}
{
  "id": "too_many_requests",
  "message": "API rate limit exceeded."
}
{
  "id": "server_error",
  "message": "Unexpected server-side error"
}
{
  "id": "example_error",
  "message": "some error message"
}

GET ListTemplateBuilds returns build history for a template.

/v2/agents/templates/{template_id}/builds
Authorizations: bearer_auth (1 scope)
Http: Bearer
Required scopes: agent_harness_session:read

OAuth Authentication

In order to interact with the DigitalOcean API, you or your application must authenticate.

The DigitalOcean API handles this through OAuth, an open standard for authorization. OAuth allows you to delegate access to your account. Scopes can be used to grant full access, read-only access, or access to a specific set of endpoints.

You can generate an OAuth token by visiting the Apps & API section of the DigitalOcean control panel for your account.

An OAuth token functions as a complete authentication request. In effect, it acts as a substitute for a username and password pair.

Because of this, it is absolutely essential that you keep your OAuth tokens secure. In fact, upon generation, the web interface will only display each token a single time in order to prevent the token from being compromised.

DigitalOcean access tokens begin with an identifiable prefix in order to distinguish them from other similar tokens.

  • dop_v1_ for personal access tokens generated in the control panel
  • doo_v1_ for tokens generated by applications using the OAuth flow
  • dor_v1_ for OAuth refresh tokens

Scopes

Scopes act like permissions assigned to an API token. These permissions determine what actions the token can perform. You can create API tokens that grant read-only access, full access, or limited access to specific endpoints by using custom scopes.

Generally, scopes are designed to match HTTP verbs and common CRUD operations (Create, Read, Update, Delete).

HTTP Verb CRUD Operation Scope
GET Read <resource>:read
POST Create <resource>:create
PUT/PATCH Update <resource>:update
DELETE Delete <resource>:delete

For example, creating a new Droplet by making a POST request to the /v2/droplets endpoint requires the droplet:create scope while listing Droplets by making a GET request to the /v2/droplets endpoint requires the droplet:read scope.

Each endpoint below specifies which scope is required to access it when using custom scopes.

How to Authenticate with OAuth

In order to make an authenticated request, include a bearer-type Authorization header containing your OAuth token. All requests must be made over HTTPS.

Authenticate with a Bearer Authorization Header

curl -X $HTTP_METHOD -H "Authorization: Bearer $DIGITALOCEAN_TOKEN" "https://api.digitalocean.com/v2/$OBJECT"

ListTemplateBuilds returns build history for a template.

Path Parameters

template_id string (uuid) required
Example: 11111111-2222-3333-4444-555555555555

The template UUID.

Query Parameters

page_size integer (int32) optional
Example: 50

Page size. Defaults to 50 when omitted or non-positive.

page_token string optional

Optional pagination cursor (opaque). Empty starts from the beginning.

curl -X GET \
  -H "Authorization: Bearer $DIGITALOCEAN_TOKEN" \
  "https://api.digitalocean.com/v2/agents/templates/{template_id}/builds"
curl -X GET \
  -H "Authorization: Bearer $API_TOKEN" \
  "https://api.digitalocean.com/v2/agents/templates/{template_id}/builds"

Responses

200

A successful response.

ratelimit-limit integer

The default limit on number of requests that can be made per hour and per minute. Current rate limits are 5000 requests per hour and 250 requests per minute.

ratelimit-remaining integer

The number of requests in your hourly quota that remain before you hit your request limit. See https://docs.digitalocean.com/reference/api/reference/#rate-limit for information about how requests expire.

ratelimit-reset integer

The time when the oldest request will expire. The value is given in Unix epoch time. See https://docs.digitalocean.com/reference/api/reference/#rate-limit for information about how requests expire.

builds array of object optional
Show child properties
build_id string (uuid) required
Example: 11111111-2222-3333-4444-555555555555
created_at string (date-time) required
Example: 2026-08-01T12:00:00Z
error string optional
name string optional
Example: my-custom-template
spec object optional
Show child properties
base_template string optional
Example: coding-opencode

Base template key. One of: coding-base, coding-claude-code, coding-codex, coding-hermes, coding-opencode, langgraph.

image object optional
Show child properties
digest string optional
Example: sha256:deadbeef
registry string optional
Example: registry.digitalocean.com
repository string optional
Example: my-team/agent-base
tag string optional
Example: latest
status string, one of: STATUS_UNSPECIFIED, PENDING, BUILDING, SUCCEEDED, FAILED required
Example: SUCCEEDED
template_id string (uuid) optional
Example: aaaaaaaa-bbbb-cccc-dddd-eeeeeeeeeeee
updated_at string (date-time) required
Example: 2026-08-01T12:05:00Z
next_page_token string optional
401

Authentication failed due to invalid credentials.

ratelimit-limit integer

The default limit on number of requests that can be made per hour and per minute. Current rate limits are 5000 requests per hour and 250 requests per minute.

ratelimit-remaining integer

The number of requests in your hourly quota that remain before you hit your request limit. See https://docs.digitalocean.com/reference/api/reference/#rate-limit for information about how requests expire.

ratelimit-reset integer

The time when the oldest request will expire. The value is given in Unix epoch time. See https://docs.digitalocean.com/reference/api/reference/#rate-limit for information about how requests expire.

id string required
Example: not_found

A short identifier corresponding to the HTTP status code returned. For example, the ID for a response returning a 404 status code would be "not_found."

message string required
Example: The resource you were accessing could not be found.

A message providing additional information about the error, including details to help resolve it when possible.

request_id string optional
Example: 4d9d8375-3c56-4925-a3e7-eb137fed17e9

Optionally, some endpoints may include a request ID that should be provided when reporting bugs or opening support tickets to help identify the issue.

404

The resource was not found.

ratelimit-limit integer

The default limit on number of requests that can be made per hour and per minute. Current rate limits are 5000 requests per hour and 250 requests per minute.

ratelimit-remaining integer

The number of requests in your hourly quota that remain before you hit your request limit. See https://docs.digitalocean.com/reference/api/reference/#rate-limit for information about how requests expire.

ratelimit-reset integer

The time when the oldest request will expire. The value is given in Unix epoch time. See https://docs.digitalocean.com/reference/api/reference/#rate-limit for information about how requests expire.

id string required
Example: not_found

A short identifier corresponding to the HTTP status code returned. For example, the ID for a response returning a 404 status code would be "not_found."

message string required
Example: The resource you were accessing could not be found.

A message providing additional information about the error, including details to help resolve it when possible.

request_id string optional
Example: 4d9d8375-3c56-4925-a3e7-eb137fed17e9

Optionally, some endpoints may include a request ID that should be provided when reporting bugs or opening support tickets to help identify the issue.

429

The API rate limit has been exceeded.

ratelimit-limit integer

The default limit on number of requests that can be made per hour and per minute. Current rate limits are 5000 requests per hour and 250 requests per minute.

ratelimit-remaining integer

The number of requests in your hourly quota that remain before you hit your request limit. See https://docs.digitalocean.com/reference/api/reference/#rate-limit for information about how requests expire.

ratelimit-reset integer

The time when the oldest request will expire. The value is given in Unix epoch time. See https://docs.digitalocean.com/reference/api/reference/#rate-limit for information about how requests expire.

id string required
Example: not_found

A short identifier corresponding to the HTTP status code returned. For example, the ID for a response returning a 404 status code would be "not_found."

message string required
Example: The resource you were accessing could not be found.

A message providing additional information about the error, including details to help resolve it when possible.

request_id string optional
Example: 4d9d8375-3c56-4925-a3e7-eb137fed17e9

Optionally, some endpoints may include a request ID that should be provided when reporting bugs or opening support tickets to help identify the issue.

500

There was a server error.

ratelimit-limit integer

The default limit on number of requests that can be made per hour and per minute. Current rate limits are 5000 requests per hour and 250 requests per minute.

ratelimit-remaining integer

The number of requests in your hourly quota that remain before you hit your request limit. See https://docs.digitalocean.com/reference/api/reference/#rate-limit for information about how requests expire.

ratelimit-reset integer

The time when the oldest request will expire. The value is given in Unix epoch time. See https://docs.digitalocean.com/reference/api/reference/#rate-limit for information about how requests expire.

id string required
Example: not_found

A short identifier corresponding to the HTTP status code returned. For example, the ID for a response returning a 404 status code would be "not_found."

message string required
Example: The resource you were accessing could not be found.

A message providing additional information about the error, including details to help resolve it when possible.

request_id string optional
Example: 4d9d8375-3c56-4925-a3e7-eb137fed17e9

Optionally, some endpoints may include a request ID that should be provided when reporting bugs or opening support tickets to help identify the issue.

default

There was an unexpected error.

ratelimit-limit integer

The default limit on number of requests that can be made per hour and per minute. Current rate limits are 5000 requests per hour and 250 requests per minute.

ratelimit-remaining integer

The number of requests in your hourly quota that remain before you hit your request limit. See https://docs.digitalocean.com/reference/api/reference/#rate-limit for information about how requests expire.

ratelimit-reset integer

The time when the oldest request will expire. The value is given in Unix epoch time. See https://docs.digitalocean.com/reference/api/reference/#rate-limit for information about how requests expire.

id string required
Example: not_found

A short identifier corresponding to the HTTP status code returned. For example, the ID for a response returning a 404 status code would be "not_found."

message string required
Example: The resource you were accessing could not be found.

A message providing additional information about the error, including details to help resolve it when possible.

request_id string optional
Example: 4d9d8375-3c56-4925-a3e7-eb137fed17e9

Optionally, some endpoints may include a request ID that should be provided when reporting bugs or opening support tickets to help identify the issue.

{
  "builds": [
    {
      "build_id": "11111111-2222-3333-4444-555555555555",
      "created_at": "2026-08-01T12:00:00Z",
      "error": "",
      "name": "my-custom-template",
      "status": "SUCCEEDED",
      "template_id": "aaaaaaaa-bbbb-cccc-dddd-eeeeeeeeeeee",
      "updated_at": "2026-08-01T12:05:00Z"
    }
  ],
  "next_page_token": "string"
}
{
  "id": "unauthorized",
  "message": "Unable to authenticate you."
}
{
  "id": "not_found",
  "message": "The resource you requested could not be found."
}
{
  "id": "too_many_requests",
  "message": "API rate limit exceeded."
}
{
  "id": "server_error",
  "message": "Unexpected server-side error"
}
{
  "id": "example_error",
  "message": "some error message"
}

GET GetTemplateBuild returns a single template build.

/v2/agents/templates/{template_id}/builds/{build_id}
Authorizations: bearer_auth (1 scope)
Http: Bearer
Required scopes: agent_harness_session:read

OAuth Authentication

In order to interact with the DigitalOcean API, you or your application must authenticate.

The DigitalOcean API handles this through OAuth, an open standard for authorization. OAuth allows you to delegate access to your account. Scopes can be used to grant full access, read-only access, or access to a specific set of endpoints.

You can generate an OAuth token by visiting the Apps & API section of the DigitalOcean control panel for your account.

An OAuth token functions as a complete authentication request. In effect, it acts as a substitute for a username and password pair.

Because of this, it is absolutely essential that you keep your OAuth tokens secure. In fact, upon generation, the web interface will only display each token a single time in order to prevent the token from being compromised.

DigitalOcean access tokens begin with an identifiable prefix in order to distinguish them from other similar tokens.

  • dop_v1_ for personal access tokens generated in the control panel
  • doo_v1_ for tokens generated by applications using the OAuth flow
  • dor_v1_ for OAuth refresh tokens

Scopes

Scopes act like permissions assigned to an API token. These permissions determine what actions the token can perform. You can create API tokens that grant read-only access, full access, or limited access to specific endpoints by using custom scopes.

Generally, scopes are designed to match HTTP verbs and common CRUD operations (Create, Read, Update, Delete).

HTTP Verb CRUD Operation Scope
GET Read <resource>:read
POST Create <resource>:create
PUT/PATCH Update <resource>:update
DELETE Delete <resource>:delete

For example, creating a new Droplet by making a POST request to the /v2/droplets endpoint requires the droplet:create scope while listing Droplets by making a GET request to the /v2/droplets endpoint requires the droplet:read scope.

Each endpoint below specifies which scope is required to access it when using custom scopes.

How to Authenticate with OAuth

In order to make an authenticated request, include a bearer-type Authorization header containing your OAuth token. All requests must be made over HTTPS.

Authenticate with a Bearer Authorization Header

curl -X $HTTP_METHOD -H "Authorization: Bearer $DIGITALOCEAN_TOKEN" "https://api.digitalocean.com/v2/$OBJECT"

GetTemplateBuild returns a single template build.

Path Parameters

template_id string (uuid) required
Example: 11111111-2222-3333-4444-555555555555

The template UUID.

build_id string (uuid) required
Example: 22222222-3333-4444-5555-666666666666

The build UUID.

curl -X GET \
  -H "Authorization: Bearer $DIGITALOCEAN_TOKEN" \
  "https://api.digitalocean.com/v2/agents/templates/{template_id}/builds/{build_id}"
curl -X GET \
  -H "Authorization: Bearer $API_TOKEN" \
  "https://api.digitalocean.com/v2/agents/templates/{template_id}/builds/{build_id}"

Responses

200

A successful response.

ratelimit-limit integer

The default limit on number of requests that can be made per hour and per minute. Current rate limits are 5000 requests per hour and 250 requests per minute.

ratelimit-remaining integer

The number of requests in your hourly quota that remain before you hit your request limit. See https://docs.digitalocean.com/reference/api/reference/#rate-limit for information about how requests expire.

ratelimit-reset integer

The time when the oldest request will expire. The value is given in Unix epoch time. See https://docs.digitalocean.com/reference/api/reference/#rate-limit for information about how requests expire.

build object optional
Show child properties
build_id string (uuid) required
Example: 11111111-2222-3333-4444-555555555555
created_at string (date-time) required
Example: 2026-08-01T12:00:00Z
error string optional
name string optional
Example: my-custom-template
spec object optional
Show child properties
base_template string optional
Example: coding-opencode

Base template key. One of: coding-base, coding-claude-code, coding-codex, coding-hermes, coding-opencode, langgraph.

image object optional
Show child properties
digest string optional
Example: sha256:deadbeef
registry string optional
Example: registry.digitalocean.com
repository string optional
Example: my-team/agent-base
tag string optional
Example: latest
status string, one of: STATUS_UNSPECIFIED, PENDING, BUILDING, SUCCEEDED, FAILED required
Example: SUCCEEDED
template_id string (uuid) optional
Example: aaaaaaaa-bbbb-cccc-dddd-eeeeeeeeeeee
updated_at string (date-time) required
Example: 2026-08-01T12:05:00Z
401

Authentication failed due to invalid credentials.

ratelimit-limit integer

The default limit on number of requests that can be made per hour and per minute. Current rate limits are 5000 requests per hour and 250 requests per minute.

ratelimit-remaining integer

The number of requests in your hourly quota that remain before you hit your request limit. See https://docs.digitalocean.com/reference/api/reference/#rate-limit for information about how requests expire.

ratelimit-reset integer

The time when the oldest request will expire. The value is given in Unix epoch time. See https://docs.digitalocean.com/reference/api/reference/#rate-limit for information about how requests expire.

id string required
Example: not_found

A short identifier corresponding to the HTTP status code returned. For example, the ID for a response returning a 404 status code would be "not_found."

message string required
Example: The resource you were accessing could not be found.

A message providing additional information about the error, including details to help resolve it when possible.

request_id string optional
Example: 4d9d8375-3c56-4925-a3e7-eb137fed17e9

Optionally, some endpoints may include a request ID that should be provided when reporting bugs or opening support tickets to help identify the issue.

404

The resource was not found.

ratelimit-limit integer

The default limit on number of requests that can be made per hour and per minute. Current rate limits are 5000 requests per hour and 250 requests per minute.

ratelimit-remaining integer

The number of requests in your hourly quota that remain before you hit your request limit. See https://docs.digitalocean.com/reference/api/reference/#rate-limit for information about how requests expire.

ratelimit-reset integer

The time when the oldest request will expire. The value is given in Unix epoch time. See https://docs.digitalocean.com/reference/api/reference/#rate-limit for information about how requests expire.

id string required
Example: not_found

A short identifier corresponding to the HTTP status code returned. For example, the ID for a response returning a 404 status code would be "not_found."

message string required
Example: The resource you were accessing could not be found.

A message providing additional information about the error, including details to help resolve it when possible.

request_id string optional
Example: 4d9d8375-3c56-4925-a3e7-eb137fed17e9

Optionally, some endpoints may include a request ID that should be provided when reporting bugs or opening support tickets to help identify the issue.

429

The API rate limit has been exceeded.

ratelimit-limit integer

The default limit on number of requests that can be made per hour and per minute. Current rate limits are 5000 requests per hour and 250 requests per minute.

ratelimit-remaining integer

The number of requests in your hourly quota that remain before you hit your request limit. See https://docs.digitalocean.com/reference/api/reference/#rate-limit for information about how requests expire.

ratelimit-reset integer

The time when the oldest request will expire. The value is given in Unix epoch time. See https://docs.digitalocean.com/reference/api/reference/#rate-limit for information about how requests expire.

id string required
Example: not_found

A short identifier corresponding to the HTTP status code returned. For example, the ID for a response returning a 404 status code would be "not_found."

message string required
Example: The resource you were accessing could not be found.

A message providing additional information about the error, including details to help resolve it when possible.

request_id string optional
Example: 4d9d8375-3c56-4925-a3e7-eb137fed17e9

Optionally, some endpoints may include a request ID that should be provided when reporting bugs or opening support tickets to help identify the issue.

500

There was a server error.

ratelimit-limit integer

The default limit on number of requests that can be made per hour and per minute. Current rate limits are 5000 requests per hour and 250 requests per minute.

ratelimit-remaining integer

The number of requests in your hourly quota that remain before you hit your request limit. See https://docs.digitalocean.com/reference/api/reference/#rate-limit for information about how requests expire.

ratelimit-reset integer

The time when the oldest request will expire. The value is given in Unix epoch time. See https://docs.digitalocean.com/reference/api/reference/#rate-limit for information about how requests expire.

id string required
Example: not_found

A short identifier corresponding to the HTTP status code returned. For example, the ID for a response returning a 404 status code would be "not_found."

message string required
Example: The resource you were accessing could not be found.

A message providing additional information about the error, including details to help resolve it when possible.

request_id string optional
Example: 4d9d8375-3c56-4925-a3e7-eb137fed17e9

Optionally, some endpoints may include a request ID that should be provided when reporting bugs or opening support tickets to help identify the issue.

default

There was an unexpected error.

ratelimit-limit integer

The default limit on number of requests that can be made per hour and per minute. Current rate limits are 5000 requests per hour and 250 requests per minute.

ratelimit-remaining integer

The number of requests in your hourly quota that remain before you hit your request limit. See https://docs.digitalocean.com/reference/api/reference/#rate-limit for information about how requests expire.

ratelimit-reset integer

The time when the oldest request will expire. The value is given in Unix epoch time. See https://docs.digitalocean.com/reference/api/reference/#rate-limit for information about how requests expire.

id string required
Example: not_found

A short identifier corresponding to the HTTP status code returned. For example, the ID for a response returning a 404 status code would be "not_found."

message string required
Example: The resource you were accessing could not be found.

A message providing additional information about the error, including details to help resolve it when possible.

request_id string optional
Example: 4d9d8375-3c56-4925-a3e7-eb137fed17e9

Optionally, some endpoints may include a request ID that should be provided when reporting bugs or opening support tickets to help identify the issue.

{
  "build": {
    "build_id": "11111111-2222-3333-4444-555555555555",
    "created_at": "2026-08-01T12:00:00Z",
    "error": "",
    "name": "my-custom-template",
    "spec": {
      "base_template": "coding-opencode"
    },
    "status": "SUCCEEDED",
    "template_id": "aaaaaaaa-bbbb-cccc-dddd-eeeeeeeeeeee",
    "updated_at": "2026-08-01T12:05:00Z"
  }
}
{
  "id": "unauthorized",
  "message": "Unable to authenticate you."
}
{
  "id": "not_found",
  "message": "The resource you requested could not be found."
}
{
  "id": "too_many_requests",
  "message": "API rate limit exceeded."
}
{
  "id": "server_error",
  "message": "Unexpected server-side error"
}
{
  "id": "example_error",
  "message": "some error message"
}

GET ListTriggers enumerates the calling team's triggers.

/v2/agents/triggers
Authorizations: bearer_auth (1 scope)
Http: Bearer
Required scopes: agent_harness_session:read

OAuth Authentication

In order to interact with the DigitalOcean API, you or your application must authenticate.

The DigitalOcean API handles this through OAuth, an open standard for authorization. OAuth allows you to delegate access to your account. Scopes can be used to grant full access, read-only access, or access to a specific set of endpoints.

You can generate an OAuth token by visiting the Apps & API section of the DigitalOcean control panel for your account.

An OAuth token functions as a complete authentication request. In effect, it acts as a substitute for a username and password pair.

Because of this, it is absolutely essential that you keep your OAuth tokens secure. In fact, upon generation, the web interface will only display each token a single time in order to prevent the token from being compromised.

DigitalOcean access tokens begin with an identifiable prefix in order to distinguish them from other similar tokens.

  • dop_v1_ for personal access tokens generated in the control panel
  • doo_v1_ for tokens generated by applications using the OAuth flow
  • dor_v1_ for OAuth refresh tokens

Scopes

Scopes act like permissions assigned to an API token. These permissions determine what actions the token can perform. You can create API tokens that grant read-only access, full access, or limited access to specific endpoints by using custom scopes.

Generally, scopes are designed to match HTTP verbs and common CRUD operations (Create, Read, Update, Delete).

HTTP Verb CRUD Operation Scope
GET Read <resource>:read
POST Create <resource>:create
PUT/PATCH Update <resource>:update
DELETE Delete <resource>:delete

For example, creating a new Droplet by making a POST request to the /v2/droplets endpoint requires the droplet:create scope while listing Droplets by making a GET request to the /v2/droplets endpoint requires the droplet:read scope.

Each endpoint below specifies which scope is required to access it when using custom scopes.

How to Authenticate with OAuth

In order to make an authenticated request, include a bearer-type Authorization header containing your OAuth token. All requests must be made over HTTPS.

Authenticate with a Bearer Authorization Header

curl -X $HTTP_METHOD -H "Authorization: Bearer $DIGITALOCEAN_TOKEN" "https://api.digitalocean.com/v2/$OBJECT"

Keyset-paginated on an opaque cursor. Excludes soft-deleted triggers. Scoped to the authenticated team.

Query Parameters

page_size integer (int32) >= 1 optional
Example: 50

Page size. Defaults to 50 when omitted or non-positive; server-clamped.

page_token string optional

Opaque keyset cursor returned by the previous page. Empty starts from the beginning.

kind string, one of: webhook, cron optional
Example: webhook

Optional filter by trigger kind.

status string, one of: active, paused optional
Example: active

Optional filter by trigger status.

curl -X GET \
  -H "Content-Type: application/json" \
  -H "Authorization: Bearer $DIGITALOCEAN_TOKEN" \
  "https://api.digitalocean.com/v2/agents/triggers?page_size=50"
curl -X GET \
  -H "Authorization: Bearer $API_TOKEN" \
  "https://api.digitalocean.com/v2/agents/triggers"

Responses

200

A successful response.

ratelimit-limit integer

The default limit on number of requests that can be made per hour and per minute. Current rate limits are 5000 requests per hour and 250 requests per minute.

ratelimit-remaining integer

The number of requests in your hourly quota that remain before you hit your request limit. See https://docs.digitalocean.com/reference/api/reference/#rate-limit for information about how requests expire.

ratelimit-reset integer

The time when the oldest request will expire. The value is given in Unix epoch time. See https://docs.digitalocean.com/reference/api/reference/#rate-limit for information about how requests expire.

next_page_token string optional

Opaque cursor for the next page. Empty when there are no further pages.

triggers array of object optional
Show child properties
agent_kind string (enum) optional
Example: AGENT_KIND_UNSPECIFIED

AgentKind identifies what runs inside the session sandbox. CreateSession accepts CLAUDE_CODE, OPENCODE, CODEX_CLI, CURSOR_CLI, OPENAI_CODEX, LANGGRAPH, and CREWAI (the supported set is overridable via HARNESS_SUPPORTED_AGENT_KINDS); other values are rejected with 400. AGENT_KIND_OPENAI_CODEX is the OpenAI sandbox-provider kind (DO runs codex exec-server; the agent loop lives at OpenAI). AGENT_KIND_LANGGRAPH is the LangGraph framework adapter. AGENT_KIND_CREWAI is the CrewAI Crew framework adapter: like LANGGRAPH the template bakes no agent code, so spec.env must supply FRAMEWORK_REPO and FRAMEWORK_REPO_SHA; a Crew kickoff is one-shot and exposes no HITL surface. CREWAI is additionally gated per team and returns 400 for teams it is not enabled for.

bound_session_id string (uuid) optional
Example: a1b2c3d4-e5f6-7890-abcd-ef1234567890

Present iff session_mode=reuse. UUID of the existing PAUSED session this trigger resumes; may be shared by multiple triggers.

created_at string (date-time) optional
Example: 2026-07-27T12:00:00Z
cron object optional

Present iff kind=cron.

Show child properties
cron_expr string optional
Example: 0 9 * * 1-5

Cron expression; must parse with the scanner's cron library.

next_run_at string (date-time) optional
Example: 2026-07-27T13:00:00Z

Read-only; server-computed next fire time.

timezone string optional
Example: America/New_York

IANA timezone (e.g. "America/New_York").

kind string, one of: webhook, cron optional
Example: webhook

How the trigger fires - on an event (webhook) or on a schedule (cron). Immutable after create.

name string optional
Example: nightly-deploy-check

Unique per team among non-deleted triggers. Same rules as session names; not UUID-form.

output object optional

Output-delivery configuration as seen on reads. The email address and Slack webhook URL are write-only and never returned.

Show child properties
email_configured boolean optional
Example: true

True when an email address is stored (mode=email).

mode string, one of: none, email, slack optional
Example: email

none = nothing pushed; the result stays in run history for self-serve. email = the collected run output is emailed to a configured address. slack = the collected run output is posted to a Slack incoming webhook URL (channel fixed by the webhook at install time).

slack_configured boolean optional
Example: false

True when a Slack incoming webhook URL is stored (mode=slack).

prompt_template string optional
Example: Review the latest push and summarize risks.

The prompt sent on each fire. Opaque to clients; payload-interpolation syntax is server-defined. For cron triggers it must not reference payload placeholders.

session_mode string, one of: fresh, reuse optional
Example: fresh

fresh = a new session is created from the trigger's spec on every firing and destroyed after. reuse = the trigger binds an existing PAUSED session, resumed on each firing and paused after; multiple triggers may bind one session.

session_template string optional

Present iff session_mode=fresh. The agents.yaml Agent manifest used to CREATE a session on each fire, returned with its env values REDACTED.

status string, one of: active, paused optional
Example: active

Trigger lifecycle state. Soft-deleted triggers are never returned (404).

trigger_id string optional
Example: b1a0c6de-1f2e-4a3b-9c8d-0e1f2a3b4c5d

Server-allocated UUID; opaque to clients.

updated_at string (date-time) optional
Example: 2026-07-27T12:00:00Z
webhook object optional

Present iff kind=webhook. The secret is never in this object (see create_trigger_response / rotate_secret_response).

Show child properties
provider string, one of: github, gitlab, custom optional
Example: github

Signature-verification scheme applied to a delivery. Omitted on create defaults to custom.

webhook_url string optional
Example: https://api.digitalocean.com/v2/agents/triggers/b1a0.../webhook

The Payload URL to configure in the external system.

400

Invalid page_token or filter value.

ratelimit-limit integer

The default limit on number of requests that can be made per hour and per minute. Current rate limits are 5000 requests per hour and 250 requests per minute.

ratelimit-remaining integer

The number of requests in your hourly quota that remain before you hit your request limit. See https://docs.digitalocean.com/reference/api/reference/#rate-limit for information about how requests expire.

ratelimit-reset integer

The time when the oldest request will expire. The value is given in Unix epoch time. See https://docs.digitalocean.com/reference/api/reference/#rate-limit for information about how requests expire.

id string required
Example: not_found

A short identifier corresponding to the HTTP status code returned. For example, the ID for a response returning a 404 status code would be "not_found."

message string required
Example: The resource you were accessing could not be found.

A message providing additional information about the error, including details to help resolve it when possible.

request_id string optional
Example: 4d9d8375-3c56-4925-a3e7-eb137fed17e9

Optionally, some endpoints may include a request ID that should be provided when reporting bugs or opening support tickets to help identify the issue.

401

Authentication failed due to invalid credentials.

ratelimit-limit integer

The default limit on number of requests that can be made per hour and per minute. Current rate limits are 5000 requests per hour and 250 requests per minute.

ratelimit-remaining integer

The number of requests in your hourly quota that remain before you hit your request limit. See https://docs.digitalocean.com/reference/api/reference/#rate-limit for information about how requests expire.

ratelimit-reset integer

The time when the oldest request will expire. The value is given in Unix epoch time. See https://docs.digitalocean.com/reference/api/reference/#rate-limit for information about how requests expire.

id string required
Example: not_found

A short identifier corresponding to the HTTP status code returned. For example, the ID for a response returning a 404 status code would be "not_found."

message string required
Example: The resource you were accessing could not be found.

A message providing additional information about the error, including details to help resolve it when possible.

request_id string optional
Example: 4d9d8375-3c56-4925-a3e7-eb137fed17e9

Optionally, some endpoints may include a request ID that should be provided when reporting bugs or opening support tickets to help identify the issue.

429

The API rate limit has been exceeded.

ratelimit-limit integer

The default limit on number of requests that can be made per hour and per minute. Current rate limits are 5000 requests per hour and 250 requests per minute.

ratelimit-remaining integer

The number of requests in your hourly quota that remain before you hit your request limit. See https://docs.digitalocean.com/reference/api/reference/#rate-limit for information about how requests expire.

ratelimit-reset integer

The time when the oldest request will expire. The value is given in Unix epoch time. See https://docs.digitalocean.com/reference/api/reference/#rate-limit for information about how requests expire.

id string required
Example: not_found

A short identifier corresponding to the HTTP status code returned. For example, the ID for a response returning a 404 status code would be "not_found."

message string required
Example: The resource you were accessing could not be found.

A message providing additional information about the error, including details to help resolve it when possible.

request_id string optional
Example: 4d9d8375-3c56-4925-a3e7-eb137fed17e9

Optionally, some endpoints may include a request ID that should be provided when reporting bugs or opening support tickets to help identify the issue.

500

There was a server error.

ratelimit-limit integer

The default limit on number of requests that can be made per hour and per minute. Current rate limits are 5000 requests per hour and 250 requests per minute.

ratelimit-remaining integer

The number of requests in your hourly quota that remain before you hit your request limit. See https://docs.digitalocean.com/reference/api/reference/#rate-limit for information about how requests expire.

ratelimit-reset integer

The time when the oldest request will expire. The value is given in Unix epoch time. See https://docs.digitalocean.com/reference/api/reference/#rate-limit for information about how requests expire.

id string required
Example: not_found

A short identifier corresponding to the HTTP status code returned. For example, the ID for a response returning a 404 status code would be "not_found."

message string required
Example: The resource you were accessing could not be found.

A message providing additional information about the error, including details to help resolve it when possible.

request_id string optional
Example: 4d9d8375-3c56-4925-a3e7-eb137fed17e9

Optionally, some endpoints may include a request ID that should be provided when reporting bugs or opening support tickets to help identify the issue.

default

There was an unexpected error.

ratelimit-limit integer

The default limit on number of requests that can be made per hour and per minute. Current rate limits are 5000 requests per hour and 250 requests per minute.

ratelimit-remaining integer

The number of requests in your hourly quota that remain before you hit your request limit. See https://docs.digitalocean.com/reference/api/reference/#rate-limit for information about how requests expire.

ratelimit-reset integer

The time when the oldest request will expire. The value is given in Unix epoch time. See https://docs.digitalocean.com/reference/api/reference/#rate-limit for information about how requests expire.

id string required
Example: not_found

A short identifier corresponding to the HTTP status code returned. For example, the ID for a response returning a 404 status code would be "not_found."

message string required
Example: The resource you were accessing could not be found.

A message providing additional information about the error, including details to help resolve it when possible.

request_id string optional
Example: 4d9d8375-3c56-4925-a3e7-eb137fed17e9

Optionally, some endpoints may include a request ID that should be provided when reporting bugs or opening support tickets to help identify the issue.

{
  "next_page_token": "",
  "triggers": [
    {
      "agent_kind": "AGENT_KIND_UNSPECIFIED",
      "bound_session_id": "a1b2c3d4-e5f6-7890-abcd-ef1234567890",
      "created_at": "2026-07-27T12:00:00Z",
      "kind": "webhook",
      "name": "nightly-deploy-check",
      "prompt_template": "Review the latest push and summarize risks.",
      "session_mode": "fresh",
      "session_template": "",
      "status": "active",
      "trigger_id": "b1a0c6de-1f2e-4a3b-9c8d-0e1f2a3b4c5d",
      "updated_at": "2026-07-27T12:00:00Z"
    }
  ]
}
{
  "id": "not_found",
  "message": "The resource you were accessing could not be found.",
  "request_id": "4d9d8375-3c56-4925-a3e7-eb137fed17e9"
}
{
  "id": "unauthorized",
  "message": "Unable to authenticate you."
}
{
  "id": "too_many_requests",
  "message": "API rate limit exceeded."
}
{
  "id": "server_error",
  "message": "Unexpected server-side error"
}
{
  "id": "example_error",
  "message": "some error message"
}

POST CreateTrigger creates a webhook or cron trigger.

/v2/agents/triggers
Authorizations: bearer_auth (1 scope)
Http: Bearer
Required scopes: agent_harness_session:create

OAuth Authentication

In order to interact with the DigitalOcean API, you or your application must authenticate.

The DigitalOcean API handles this through OAuth, an open standard for authorization. OAuth allows you to delegate access to your account. Scopes can be used to grant full access, read-only access, or access to a specific set of endpoints.

You can generate an OAuth token by visiting the Apps & API section of the DigitalOcean control panel for your account.

An OAuth token functions as a complete authentication request. In effect, it acts as a substitute for a username and password pair.

Because of this, it is absolutely essential that you keep your OAuth tokens secure. In fact, upon generation, the web interface will only display each token a single time in order to prevent the token from being compromised.

DigitalOcean access tokens begin with an identifiable prefix in order to distinguish them from other similar tokens.

  • dop_v1_ for personal access tokens generated in the control panel
  • doo_v1_ for tokens generated by applications using the OAuth flow
  • dor_v1_ for OAuth refresh tokens

Scopes

Scopes act like permissions assigned to an API token. These permissions determine what actions the token can perform. You can create API tokens that grant read-only access, full access, or limited access to specific endpoints by using custom scopes.

Generally, scopes are designed to match HTTP verbs and common CRUD operations (Create, Read, Update, Delete).

HTTP Verb CRUD Operation Scope
GET Read <resource>:read
POST Create <resource>:create
PUT/PATCH Update <resource>:update
DELETE Delete <resource>:delete

For example, creating a new Droplet by making a POST request to the /v2/droplets endpoint requires the droplet:create scope while listing Droplets by making a GET request to the /v2/droplets endpoint requires the droplet:read scope.

Each endpoint below specifies which scope is required to access it when using custom scopes.

How to Authenticate with OAuth

In order to make an authenticated request, include a bearer-type Authorization header containing your OAuth token. All requests must be made over HTTPS.

Authenticate with a Bearer Authorization Header

curl -X $HTTP_METHOD -H "Authorization: Bearer $DIGITALOCEAN_TOKEN" "https://api.digitalocean.com/v2/$OBJECT"

Validation is synchronous, so a mistake is a 400/409 at creation, not a silent miss at the first fire. Exactly one of webhook / cron must be present and match kind. kind=cron forbids a webhook block and requires a parseable cron.cron_expr and a valid IANA cron.timezone. session_mode=fresh requires session_template (a well-formed agents.yaml Agent manifest) and forbids bound_session_id; session_mode=reuse requires bound_session_id (an existing team-owned session) and forbids session_template. output.mode selects the destination block (email/slack), which is stored encrypted. name must be unique per team among non-deleted triggers.

For webhook triggers the response includes webhook_secret exactly ONCE - it is never returned again. Cron triggers return no secret and carry a computed trigger.cron.next_run_at. The team and user identity are taken from the authenticated principal, never the body.

Request Body: application/json

The trigger to create.

bound_session_id string (uuid) optional
Example: a1b2c3d4-e5f6-7890-abcd-ef1234567890

reuse only. UUID of an existing session owned by the team.

cron object optional

cron block on create.

Show child properties
cron_expr string required
Example: 0 9 * * 1-5
timezone string required
Example: America/New_York

IANA timezone.

kind string, one of: webhook, cron required
Example: webhook

How the trigger fires - on an event (webhook) or on a schedule (cron). Immutable after create.

name string required
Example: nightly-deploy-check

Team-unique (among non-deleted triggers) trigger name. Same rules as session names; not UUID-form.

output object required

Output-delivery configuration on create/update. Exactly one of email / slack is required for the matching mode and forbidden otherwise; destinations are stored encrypted and never returned.

Show child properties
email string optional

Destination address; required iff mode=email.

mode string, one of: none, email, slack required
Example: email

none = nothing pushed; the result stays in run history for self-serve. email = the collected run output is emailed to a configured address. slack = the collected run output is posted to a Slack incoming webhook URL (channel fixed by the webhook at install time).

slack object optional

Slack destination on create/update. webhook_url is required when mode=slack; must be https://hooks.slack.com/services/...; stored encrypted and never returned.

Show child properties
webhook_url string required
Example: https://hooks.slack.com/services/T0000/B0000/XXXX

Slack incoming webhook URL (https://hooks.slack.com/services/...). The channel is bound to this URL at install time.

prompt_template string required
Example: Review the latest push and summarize risks.

The prompt sent on each fire. For cron it must not contain payload-interpolation placeholders.

session_mode string, one of: fresh, reuse required
Example: fresh

fresh = a new session is created from the trigger's spec on every firing and destroyed after. reuse = the trigger binds an existing PAUSED session, resumed on each firing and paused after; multiple triggers may bind one session.

session_template string optional

fresh only. Full agents.yaml Agent manifest (YAML or JSON). Any embedded env values are split out and encrypted server-side.

webhook object optional

webhook block on create. Omitting provider defaults to custom.

Show child properties
provider string, one of: github, gitlab, custom optional
Example: github

Signature-verification scheme applied to a delivery. Omitted on create defaults to custom.

Content type application/json
{
  "bound_session_id": "a1b2c3d4-e5f6-7890-abcd-ef1234567890",
  "cron": {
    "cron_expr": "0 9 * * 1-5",
    "timezone": "America/New_York"
  },
  "kind": "webhook",
  "name": "nightly-deploy-check",
  "output": {
    "email": "[email protected]",
    "mode": "email",
    "slack": {
      "webhook_url": "https://hooks.slack.com/services/T0000/B0000/XXXX"
    }
  },
  "prompt_template": "Review the latest push and summarize risks.",
  "session_mode": "fresh",
  "session_template": "",
  "webhook": {
    "provider": "github"
  }
}
curl -X POST \
  -H "Content-Type: application/json" \
  -H "Authorization: Bearer $DIGITALOCEAN_TOKEN" \
  -d '{"kind":"webhook","name":"nightly-deploy-check","session_mode":"fresh","prompt_template":"Review the latest push.","output":{"mode":"none"},"session_template":"...","webhook":{"provider":"github"}}' \
  "https://api.digitalocean.com/v2/agents/triggers"
curl -X POST \
  -H "Authorization: Bearer $API_TOKEN" \
  -H "Content-Type: application/json" \
  -d '{
  "bound_session_id": "a1b2c3d4-e5f6-7890-abcd-ef1234567890",
  "cron": {
    "cron_expr": "0 9 * * 1-5",
    "timezone": "America/New_York"
  },
  "kind": "webhook",
  "name": "nightly-deploy-check",
  "output": {
    "email": "[email protected]",
    "mode": "email",
    "slack": {
      "webhook_url": "https://hooks.slack.com/services/T0000/B0000/XXXX"
    }
  },
  "prompt_template": "Review the latest push and summarize risks.",
  "session_mode": "fresh",
  "session_template": "",
  "webhook": {
    "provider": "github"
  }
}' \
  "https://api.digitalocean.com/v2/agents/triggers"

Responses

201

Trigger created. webhook_secret present for webhook triggers only, shown once.

ratelimit-limit integer

The default limit on number of requests that can be made per hour and per minute. Current rate limits are 5000 requests per hour and 250 requests per minute.

ratelimit-remaining integer

The number of requests in your hourly quota that remain before you hit your request limit. See https://docs.digitalocean.com/reference/api/reference/#rate-limit for information about how requests expire.

ratelimit-reset integer

The time when the oldest request will expire. The value is given in Unix epoch time. See https://docs.digitalocean.com/reference/api/reference/#rate-limit for information about how requests expire.

trigger object optional

A single automation bound to exactly one agent/session (agent == session in v1). The nested block present depends on kind (webhook xor cron) and session_mode (fresh => session_template; reuse => bound_session_id). agent_kind is read-only and derived; the webhook secret, the output email address / Slack webhook URL, and any env values inside session_template are write-only and never returned.

Show child properties
agent_kind string (enum) optional
Example: AGENT_KIND_UNSPECIFIED

AgentKind identifies what runs inside the session sandbox. CreateSession accepts CLAUDE_CODE, OPENCODE, CODEX_CLI, CURSOR_CLI, OPENAI_CODEX, LANGGRAPH, and CREWAI (the supported set is overridable via HARNESS_SUPPORTED_AGENT_KINDS); other values are rejected with 400. AGENT_KIND_OPENAI_CODEX is the OpenAI sandbox-provider kind (DO runs codex exec-server; the agent loop lives at OpenAI). AGENT_KIND_LANGGRAPH is the LangGraph framework adapter. AGENT_KIND_CREWAI is the CrewAI Crew framework adapter: like LANGGRAPH the template bakes no agent code, so spec.env must supply FRAMEWORK_REPO and FRAMEWORK_REPO_SHA; a Crew kickoff is one-shot and exposes no HITL surface. CREWAI is additionally gated per team and returns 400 for teams it is not enabled for.

bound_session_id string (uuid) optional
Example: a1b2c3d4-e5f6-7890-abcd-ef1234567890

Present iff session_mode=reuse. UUID of the existing PAUSED session this trigger resumes; may be shared by multiple triggers.

created_at string (date-time) optional
Example: 2026-07-27T12:00:00Z
cron object optional

Present iff kind=cron.

Show child properties
cron_expr string optional
Example: 0 9 * * 1-5

Cron expression; must parse with the scanner's cron library.

next_run_at string (date-time) optional
Example: 2026-07-27T13:00:00Z

Read-only; server-computed next fire time.

timezone string optional
Example: America/New_York

IANA timezone (e.g. "America/New_York").

kind string, one of: webhook, cron optional
Example: webhook

How the trigger fires - on an event (webhook) or on a schedule (cron). Immutable after create.

name string optional
Example: nightly-deploy-check

Unique per team among non-deleted triggers. Same rules as session names; not UUID-form.

output object optional

Output-delivery configuration as seen on reads. The email address and Slack webhook URL are write-only and never returned.

Show child properties
email_configured boolean optional
Example: true

True when an email address is stored (mode=email).

mode string, one of: none, email, slack optional
Example: email

none = nothing pushed; the result stays in run history for self-serve. email = the collected run output is emailed to a configured address. slack = the collected run output is posted to a Slack incoming webhook URL (channel fixed by the webhook at install time).

slack_configured boolean optional
Example: false

True when a Slack incoming webhook URL is stored (mode=slack).

prompt_template string optional
Example: Review the latest push and summarize risks.

The prompt sent on each fire. Opaque to clients; payload-interpolation syntax is server-defined. For cron triggers it must not reference payload placeholders.

session_mode string, one of: fresh, reuse optional
Example: fresh

fresh = a new session is created from the trigger's spec on every firing and destroyed after. reuse = the trigger binds an existing PAUSED session, resumed on each firing and paused after; multiple triggers may bind one session.

session_template string optional

Present iff session_mode=fresh. The agents.yaml Agent manifest used to CREATE a session on each fire, returned with its env values REDACTED.

status string, one of: active, paused optional
Example: active

Trigger lifecycle state. Soft-deleted triggers are never returned (404).

trigger_id string optional
Example: b1a0c6de-1f2e-4a3b-9c8d-0e1f2a3b4c5d

Server-allocated UUID; opaque to clients.

updated_at string (date-time) optional
Example: 2026-07-27T12:00:00Z
webhook object optional

Present iff kind=webhook. The secret is never in this object (see create_trigger_response / rotate_secret_response).

Show child properties
provider string, one of: github, gitlab, custom optional
Example: github

Signature-verification scheme applied to a delivery. Omitted on create defaults to custom.

webhook_url string optional
Example: https://api.digitalocean.com/v2/agents/triggers/b1a0.../webhook

The Payload URL to configure in the external system.

webhook_secret string optional
Example: whsec_a1b2c3d4e5f6

The generated webhook secret. Present for webhook triggers only and shown EXACTLY ONCE - it is never returned again. Paste it into the external system's webhook configuration.

400

Validation failed (bad manifest/cron/timezone, kind/block/mode mismatch, provider on cron, payload placeholder in a cron prompt, invalid email, etc.).

ratelimit-limit integer

The default limit on number of requests that can be made per hour and per minute. Current rate limits are 5000 requests per hour and 250 requests per minute.

ratelimit-remaining integer

The number of requests in your hourly quota that remain before you hit your request limit. See https://docs.digitalocean.com/reference/api/reference/#rate-limit for information about how requests expire.

ratelimit-reset integer

The time when the oldest request will expire. The value is given in Unix epoch time. See https://docs.digitalocean.com/reference/api/reference/#rate-limit for information about how requests expire.

id string required
Example: not_found

A short identifier corresponding to the HTTP status code returned. For example, the ID for a response returning a 404 status code would be "not_found."

message string required
Example: The resource you were accessing could not be found.

A message providing additional information about the error, including details to help resolve it when possible.

request_id string optional
Example: 4d9d8375-3c56-4925-a3e7-eb137fed17e9

Optionally, some endpoints may include a request ID that should be provided when reporting bugs or opening support tickets to help identify the issue.

401

Authentication failed due to invalid credentials.

ratelimit-limit integer

The default limit on number of requests that can be made per hour and per minute. Current rate limits are 5000 requests per hour and 250 requests per minute.

ratelimit-remaining integer

The number of requests in your hourly quota that remain before you hit your request limit. See https://docs.digitalocean.com/reference/api/reference/#rate-limit for information about how requests expire.

ratelimit-reset integer

The time when the oldest request will expire. The value is given in Unix epoch time. See https://docs.digitalocean.com/reference/api/reference/#rate-limit for information about how requests expire.

id string required
Example: not_found

A short identifier corresponding to the HTTP status code returned. For example, the ID for a response returning a 404 status code would be "not_found."

message string required
Example: The resource you were accessing could not be found.

A message providing additional information about the error, including details to help resolve it when possible.

request_id string optional
Example: 4d9d8375-3c56-4925-a3e7-eb137fed17e9

Optionally, some endpoints may include a request ID that should be provided when reporting bugs or opening support tickets to help identify the issue.

403

The caller is not permitted to create the backing agent config for this trigger.

ratelimit-limit integer

The default limit on number of requests that can be made per hour and per minute. Current rate limits are 5000 requests per hour and 250 requests per minute.

ratelimit-remaining integer

The number of requests in your hourly quota that remain before you hit your request limit. See https://docs.digitalocean.com/reference/api/reference/#rate-limit for information about how requests expire.

ratelimit-reset integer

The time when the oldest request will expire. The value is given in Unix epoch time. See https://docs.digitalocean.com/reference/api/reference/#rate-limit for information about how requests expire.

id string required
Example: not_found

A short identifier corresponding to the HTTP status code returned. For example, the ID for a response returning a 404 status code would be "not_found."

message string required
Example: The resource you were accessing could not be found.

A message providing additional information about the error, including details to help resolve it when possible.

request_id string optional
Example: 4d9d8375-3c56-4925-a3e7-eb137fed17e9

Optionally, some endpoints may include a request ID that should be provided when reporting bugs or opening support tickets to help identify the issue.

409

A non-deleted trigger with this name already exists for the team.

ratelimit-limit integer

The default limit on number of requests that can be made per hour and per minute. Current rate limits are 5000 requests per hour and 250 requests per minute.

ratelimit-remaining integer

The number of requests in your hourly quota that remain before you hit your request limit. See https://docs.digitalocean.com/reference/api/reference/#rate-limit for information about how requests expire.

ratelimit-reset integer

The time when the oldest request will expire. The value is given in Unix epoch time. See https://docs.digitalocean.com/reference/api/reference/#rate-limit for information about how requests expire.

id string required
Example: not_found

A short identifier corresponding to the HTTP status code returned. For example, the ID for a response returning a 404 status code would be "not_found."

message string required
Example: The resource you were accessing could not be found.

A message providing additional information about the error, including details to help resolve it when possible.

request_id string optional
Example: 4d9d8375-3c56-4925-a3e7-eb137fed17e9

Optionally, some endpoints may include a request ID that should be provided when reporting bugs or opening support tickets to help identify the issue.

422

The team's trigger limit has been reached.

ratelimit-limit integer

The default limit on number of requests that can be made per hour and per minute. Current rate limits are 5000 requests per hour and 250 requests per minute.

ratelimit-remaining integer

The number of requests in your hourly quota that remain before you hit your request limit. See https://docs.digitalocean.com/reference/api/reference/#rate-limit for information about how requests expire.

ratelimit-reset integer

The time when the oldest request will expire. The value is given in Unix epoch time. See https://docs.digitalocean.com/reference/api/reference/#rate-limit for information about how requests expire.

id string required
Example: not_found

A short identifier corresponding to the HTTP status code returned. For example, the ID for a response returning a 404 status code would be "not_found."

message string required
Example: The resource you were accessing could not be found.

A message providing additional information about the error, including details to help resolve it when possible.

request_id string optional
Example: 4d9d8375-3c56-4925-a3e7-eb137fed17e9

Optionally, some endpoints may include a request ID that should be provided when reporting bugs or opening support tickets to help identify the issue.

429

The API rate limit has been exceeded.

ratelimit-limit integer

The default limit on number of requests that can be made per hour and per minute. Current rate limits are 5000 requests per hour and 250 requests per minute.

ratelimit-remaining integer

The number of requests in your hourly quota that remain before you hit your request limit. See https://docs.digitalocean.com/reference/api/reference/#rate-limit for information about how requests expire.

ratelimit-reset integer

The time when the oldest request will expire. The value is given in Unix epoch time. See https://docs.digitalocean.com/reference/api/reference/#rate-limit for information about how requests expire.

id string required
Example: not_found

A short identifier corresponding to the HTTP status code returned. For example, the ID for a response returning a 404 status code would be "not_found."

message string required
Example: The resource you were accessing could not be found.

A message providing additional information about the error, including details to help resolve it when possible.

request_id string optional
Example: 4d9d8375-3c56-4925-a3e7-eb137fed17e9

Optionally, some endpoints may include a request ID that should be provided when reporting bugs or opening support tickets to help identify the issue.

500

There was a server error.

ratelimit-limit integer

The default limit on number of requests that can be made per hour and per minute. Current rate limits are 5000 requests per hour and 250 requests per minute.

ratelimit-remaining integer

The number of requests in your hourly quota that remain before you hit your request limit. See https://docs.digitalocean.com/reference/api/reference/#rate-limit for information about how requests expire.

ratelimit-reset integer

The time when the oldest request will expire. The value is given in Unix epoch time. See https://docs.digitalocean.com/reference/api/reference/#rate-limit for information about how requests expire.

id string required
Example: not_found

A short identifier corresponding to the HTTP status code returned. For example, the ID for a response returning a 404 status code would be "not_found."

message string required
Example: The resource you were accessing could not be found.

A message providing additional information about the error, including details to help resolve it when possible.

request_id string optional
Example: 4d9d8375-3c56-4925-a3e7-eb137fed17e9

Optionally, some endpoints may include a request ID that should be provided when reporting bugs or opening support tickets to help identify the issue.

502

The backing agent config service returned an unexpected error.

ratelimit-limit integer

The default limit on number of requests that can be made per hour and per minute. Current rate limits are 5000 requests per hour and 250 requests per minute.

ratelimit-remaining integer

The number of requests in your hourly quota that remain before you hit your request limit. See https://docs.digitalocean.com/reference/api/reference/#rate-limit for information about how requests expire.

ratelimit-reset integer

The time when the oldest request will expire. The value is given in Unix epoch time. See https://docs.digitalocean.com/reference/api/reference/#rate-limit for information about how requests expire.

id string required
Example: not_found

A short identifier corresponding to the HTTP status code returned. For example, the ID for a response returning a 404 status code would be "not_found."

message string required
Example: The resource you were accessing could not be found.

A message providing additional information about the error, including details to help resolve it when possible.

request_id string optional
Example: 4d9d8375-3c56-4925-a3e7-eb137fed17e9

Optionally, some endpoints may include a request ID that should be provided when reporting bugs or opening support tickets to help identify the issue.

503

An upstream dependency needed to validate the trigger is temporarily unavailable; retry.

ratelimit-limit integer

The default limit on number of requests that can be made per hour and per minute. Current rate limits are 5000 requests per hour and 250 requests per minute.

ratelimit-remaining integer

The number of requests in your hourly quota that remain before you hit your request limit. See https://docs.digitalocean.com/reference/api/reference/#rate-limit for information about how requests expire.

ratelimit-reset integer

The time when the oldest request will expire. The value is given in Unix epoch time. See https://docs.digitalocean.com/reference/api/reference/#rate-limit for information about how requests expire.

id string required
Example: not_found

A short identifier corresponding to the HTTP status code returned. For example, the ID for a response returning a 404 status code would be "not_found."

message string required
Example: The resource you were accessing could not be found.

A message providing additional information about the error, including details to help resolve it when possible.

request_id string optional
Example: 4d9d8375-3c56-4925-a3e7-eb137fed17e9

Optionally, some endpoints may include a request ID that should be provided when reporting bugs or opening support tickets to help identify the issue.

default

There was an unexpected error.

ratelimit-limit integer

The default limit on number of requests that can be made per hour and per minute. Current rate limits are 5000 requests per hour and 250 requests per minute.

ratelimit-remaining integer

The number of requests in your hourly quota that remain before you hit your request limit. See https://docs.digitalocean.com/reference/api/reference/#rate-limit for information about how requests expire.

ratelimit-reset integer

The time when the oldest request will expire. The value is given in Unix epoch time. See https://docs.digitalocean.com/reference/api/reference/#rate-limit for information about how requests expire.

id string required
Example: not_found

A short identifier corresponding to the HTTP status code returned. For example, the ID for a response returning a 404 status code would be "not_found."

message string required
Example: The resource you were accessing could not be found.

A message providing additional information about the error, including details to help resolve it when possible.

request_id string optional
Example: 4d9d8375-3c56-4925-a3e7-eb137fed17e9

Optionally, some endpoints may include a request ID that should be provided when reporting bugs or opening support tickets to help identify the issue.

{
  "trigger": {
    "agent_kind": "AGENT_KIND_UNSPECIFIED",
    "bound_session_id": "a1b2c3d4-e5f6-7890-abcd-ef1234567890",
    "created_at": "2026-07-27T12:00:00Z",
    "cron": {
      "cron_expr": "0 9 * * 1-5",
      "next_run_at": "2026-07-27T13:00:00Z",
      "timezone": "America/New_York"
    },
    "kind": "webhook",
    "name": "nightly-deploy-check",
    "output": {
      "email_configured": true,
      "mode": "email",
      "slack_configured": false
    },
    "prompt_template": "Review the latest push and summarize risks.",
    "session_mode": "fresh",
    "session_template": "",
    "status": "active",
    "trigger_id": "b1a0c6de-1f2e-4a3b-9c8d-0e1f2a3b4c5d",
    "updated_at": "2026-07-27T12:00:00Z",
    "webhook": {
      "provider": "github",
      "webhook_url": "https://api.digitalocean.com/v2/agents/triggers/b1a0.../webhook"
    }
  },
  "webhook_secret": "whsec_a1b2c3d4e5f6"
}
{
  "id": "not_found",
  "message": "The resource you were accessing could not be found.",
  "request_id": "4d9d8375-3c56-4925-a3e7-eb137fed17e9"
}
{
  "id": "unauthorized",
  "message": "Unable to authenticate you."
}
{
  "id": "not_found",
  "message": "The resource you were accessing could not be found.",
  "request_id": "4d9d8375-3c56-4925-a3e7-eb137fed17e9"
}
{
  "id": "not_found",
  "message": "The resource you were accessing could not be found.",
  "request_id": "4d9d8375-3c56-4925-a3e7-eb137fed17e9"
}
{
  "id": "not_found",
  "message": "The resource you were accessing could not be found.",
  "request_id": "4d9d8375-3c56-4925-a3e7-eb137fed17e9"
}
{
  "id": "too_many_requests",
  "message": "API rate limit exceeded."
}
{
  "id": "server_error",
  "message": "Unexpected server-side error"
}
{
  "id": "not_found",
  "message": "The resource you were accessing could not be found.",
  "request_id": "4d9d8375-3c56-4925-a3e7-eb137fed17e9"
}
{
  "id": "not_found",
  "message": "The resource you were accessing could not be found.",
  "request_id": "4d9d8375-3c56-4925-a3e7-eb137fed17e9"
}
{
  "id": "example_error",
  "message": "some error message"
}

GET GetTriggerBySession reverse-looks-up the trigger that produced or binds a session.

/v2/agents/triggers/by-session/{session_id}
Authorizations: bearer_auth (1 scope)
Http: Bearer
Required scopes: agent_harness_session:read

OAuth Authentication

In order to interact with the DigitalOcean API, you or your application must authenticate.

The DigitalOcean API handles this through OAuth, an open standard for authorization. OAuth allows you to delegate access to your account. Scopes can be used to grant full access, read-only access, or access to a specific set of endpoints.

You can generate an OAuth token by visiting the Apps & API section of the DigitalOcean control panel for your account.

An OAuth token functions as a complete authentication request. In effect, it acts as a substitute for a username and password pair.

Because of this, it is absolutely essential that you keep your OAuth tokens secure. In fact, upon generation, the web interface will only display each token a single time in order to prevent the token from being compromised.

DigitalOcean access tokens begin with an identifiable prefix in order to distinguish them from other similar tokens.

  • dop_v1_ for personal access tokens generated in the control panel
  • doo_v1_ for tokens generated by applications using the OAuth flow
  • dor_v1_ for OAuth refresh tokens

Scopes

Scopes act like permissions assigned to an API token. These permissions determine what actions the token can perform. You can create API tokens that grant read-only access, full access, or limited access to specific endpoints by using custom scopes.

Generally, scopes are designed to match HTTP verbs and common CRUD operations (Create, Read, Update, Delete).

HTTP Verb CRUD Operation Scope
GET Read <resource>:read
POST Create <resource>:create
PUT/PATCH Update <resource>:update
DELETE Delete <resource>:delete

For example, creating a new Droplet by making a POST request to the /v2/droplets endpoint requires the droplet:create scope while listing Droplets by making a GET request to the /v2/droplets endpoint requires the droplet:read scope.

Each endpoint below specifies which scope is required to access it when using custom scopes.

How to Authenticate with OAuth

In order to make an authenticated request, include a bearer-type Authorization header containing your OAuth token. All requests must be made over HTTPS.

Authenticate with a Bearer Authorization Header

curl -X $HTTP_METHOD -H "Authorization: Bearer $DIGITALOCEAN_TOKEN" "https://api.digitalocean.com/v2/$OBJECT"

Returns the trigger that produced (fresh) or binds (reuse) the given session. Resolves to the row even after the trigger is soft-deleted.

Path Parameters

session_id string required
Example: a1b2c3d4-e5f6-7890-abcd-ef1234567890

The session UUID.

curl -X GET \
  -H "Content-Type: application/json" \
  -H "Authorization: Bearer $DIGITALOCEAN_TOKEN" \
  "https://api.digitalocean.com/v2/agents/triggers/by-session/{session_id}"
curl -X GET \
  -H "Authorization: Bearer $API_TOKEN" \
  "https://api.digitalocean.com/v2/agents/triggers/by-session/{session_id}"

Responses

200

The trigger that produced (fresh) or binds (reuse) this session.

ratelimit-limit integer

The default limit on number of requests that can be made per hour and per minute. Current rate limits are 5000 requests per hour and 250 requests per minute.

ratelimit-remaining integer

The number of requests in your hourly quota that remain before you hit your request limit. See https://docs.digitalocean.com/reference/api/reference/#rate-limit for information about how requests expire.

ratelimit-reset integer

The time when the oldest request will expire. The value is given in Unix epoch time. See https://docs.digitalocean.com/reference/api/reference/#rate-limit for information about how requests expire.

trigger object optional

A single automation bound to exactly one agent/session (agent == session in v1). The nested block present depends on kind (webhook xor cron) and session_mode (fresh => session_template; reuse => bound_session_id). agent_kind is read-only and derived; the webhook secret, the output email address / Slack webhook URL, and any env values inside session_template are write-only and never returned.

Show child properties
agent_kind string (enum) optional
Example: AGENT_KIND_UNSPECIFIED

AgentKind identifies what runs inside the session sandbox. CreateSession accepts CLAUDE_CODE, OPENCODE, CODEX_CLI, CURSOR_CLI, OPENAI_CODEX, LANGGRAPH, and CREWAI (the supported set is overridable via HARNESS_SUPPORTED_AGENT_KINDS); other values are rejected with 400. AGENT_KIND_OPENAI_CODEX is the OpenAI sandbox-provider kind (DO runs codex exec-server; the agent loop lives at OpenAI). AGENT_KIND_LANGGRAPH is the LangGraph framework adapter. AGENT_KIND_CREWAI is the CrewAI Crew framework adapter: like LANGGRAPH the template bakes no agent code, so spec.env must supply FRAMEWORK_REPO and FRAMEWORK_REPO_SHA; a Crew kickoff is one-shot and exposes no HITL surface. CREWAI is additionally gated per team and returns 400 for teams it is not enabled for.

bound_session_id string (uuid) optional
Example: a1b2c3d4-e5f6-7890-abcd-ef1234567890

Present iff session_mode=reuse. UUID of the existing PAUSED session this trigger resumes; may be shared by multiple triggers.

created_at string (date-time) optional
Example: 2026-07-27T12:00:00Z
cron object optional

Present iff kind=cron.

Show child properties
cron_expr string optional
Example: 0 9 * * 1-5

Cron expression; must parse with the scanner's cron library.

next_run_at string (date-time) optional
Example: 2026-07-27T13:00:00Z

Read-only; server-computed next fire time.

timezone string optional
Example: America/New_York

IANA timezone (e.g. "America/New_York").

kind string, one of: webhook, cron optional
Example: webhook

How the trigger fires - on an event (webhook) or on a schedule (cron). Immutable after create.

name string optional
Example: nightly-deploy-check

Unique per team among non-deleted triggers. Same rules as session names; not UUID-form.

output object optional

Output-delivery configuration as seen on reads. The email address and Slack webhook URL are write-only and never returned.

Show child properties
email_configured boolean optional
Example: true

True when an email address is stored (mode=email).

mode string, one of: none, email, slack optional
Example: email

none = nothing pushed; the result stays in run history for self-serve. email = the collected run output is emailed to a configured address. slack = the collected run output is posted to a Slack incoming webhook URL (channel fixed by the webhook at install time).

slack_configured boolean optional
Example: false

True when a Slack incoming webhook URL is stored (mode=slack).

prompt_template string optional
Example: Review the latest push and summarize risks.

The prompt sent on each fire. Opaque to clients; payload-interpolation syntax is server-defined. For cron triggers it must not reference payload placeholders.

session_mode string, one of: fresh, reuse optional
Example: fresh

fresh = a new session is created from the trigger's spec on every firing and destroyed after. reuse = the trigger binds an existing PAUSED session, resumed on each firing and paused after; multiple triggers may bind one session.

session_template string optional

Present iff session_mode=fresh. The agents.yaml Agent manifest used to CREATE a session on each fire, returned with its env values REDACTED.

status string, one of: active, paused optional
Example: active

Trigger lifecycle state. Soft-deleted triggers are never returned (404).

trigger_id string optional
Example: b1a0c6de-1f2e-4a3b-9c8d-0e1f2a3b4c5d

Server-allocated UUID; opaque to clients.

updated_at string (date-time) optional
Example: 2026-07-27T12:00:00Z
webhook object optional

Present iff kind=webhook. The secret is never in this object (see create_trigger_response / rotate_secret_response).

Show child properties
provider string, one of: github, gitlab, custom optional
Example: github

Signature-verification scheme applied to a delivery. Omitted on create defaults to custom.

webhook_url string optional
Example: https://api.digitalocean.com/v2/agents/triggers/b1a0.../webhook

The Payload URL to configure in the external system.

401

Authentication failed due to invalid credentials.

ratelimit-limit integer

The default limit on number of requests that can be made per hour and per minute. Current rate limits are 5000 requests per hour and 250 requests per minute.

ratelimit-remaining integer

The number of requests in your hourly quota that remain before you hit your request limit. See https://docs.digitalocean.com/reference/api/reference/#rate-limit for information about how requests expire.

ratelimit-reset integer

The time when the oldest request will expire. The value is given in Unix epoch time. See https://docs.digitalocean.com/reference/api/reference/#rate-limit for information about how requests expire.

id string required
Example: not_found

A short identifier corresponding to the HTTP status code returned. For example, the ID for a response returning a 404 status code would be "not_found."

message string required
Example: The resource you were accessing could not be found.

A message providing additional information about the error, including details to help resolve it when possible.

request_id string optional
Example: 4d9d8375-3c56-4925-a3e7-eb137fed17e9

Optionally, some endpoints may include a request ID that should be provided when reporting bugs or opening support tickets to help identify the issue.

404

The resource was not found.

ratelimit-limit integer

The default limit on number of requests that can be made per hour and per minute. Current rate limits are 5000 requests per hour and 250 requests per minute.

ratelimit-remaining integer

The number of requests in your hourly quota that remain before you hit your request limit. See https://docs.digitalocean.com/reference/api/reference/#rate-limit for information about how requests expire.

ratelimit-reset integer

The time when the oldest request will expire. The value is given in Unix epoch time. See https://docs.digitalocean.com/reference/api/reference/#rate-limit for information about how requests expire.

id string required
Example: not_found

A short identifier corresponding to the HTTP status code returned. For example, the ID for a response returning a 404 status code would be "not_found."

message string required
Example: The resource you were accessing could not be found.

A message providing additional information about the error, including details to help resolve it when possible.

request_id string optional
Example: 4d9d8375-3c56-4925-a3e7-eb137fed17e9

Optionally, some endpoints may include a request ID that should be provided when reporting bugs or opening support tickets to help identify the issue.

429

The API rate limit has been exceeded.

ratelimit-limit integer

The default limit on number of requests that can be made per hour and per minute. Current rate limits are 5000 requests per hour and 250 requests per minute.

ratelimit-remaining integer

The number of requests in your hourly quota that remain before you hit your request limit. See https://docs.digitalocean.com/reference/api/reference/#rate-limit for information about how requests expire.

ratelimit-reset integer

The time when the oldest request will expire. The value is given in Unix epoch time. See https://docs.digitalocean.com/reference/api/reference/#rate-limit for information about how requests expire.

id string required
Example: not_found

A short identifier corresponding to the HTTP status code returned. For example, the ID for a response returning a 404 status code would be "not_found."

message string required
Example: The resource you were accessing could not be found.

A message providing additional information about the error, including details to help resolve it when possible.

request_id string optional
Example: 4d9d8375-3c56-4925-a3e7-eb137fed17e9

Optionally, some endpoints may include a request ID that should be provided when reporting bugs or opening support tickets to help identify the issue.

500

There was a server error.

ratelimit-limit integer

The default limit on number of requests that can be made per hour and per minute. Current rate limits are 5000 requests per hour and 250 requests per minute.

ratelimit-remaining integer

The number of requests in your hourly quota that remain before you hit your request limit. See https://docs.digitalocean.com/reference/api/reference/#rate-limit for information about how requests expire.

ratelimit-reset integer

The time when the oldest request will expire. The value is given in Unix epoch time. See https://docs.digitalocean.com/reference/api/reference/#rate-limit for information about how requests expire.

id string required
Example: not_found

A short identifier corresponding to the HTTP status code returned. For example, the ID for a response returning a 404 status code would be "not_found."

message string required
Example: The resource you were accessing could not be found.

A message providing additional information about the error, including details to help resolve it when possible.

request_id string optional
Example: 4d9d8375-3c56-4925-a3e7-eb137fed17e9

Optionally, some endpoints may include a request ID that should be provided when reporting bugs or opening support tickets to help identify the issue.

default

There was an unexpected error.

ratelimit-limit integer

The default limit on number of requests that can be made per hour and per minute. Current rate limits are 5000 requests per hour and 250 requests per minute.

ratelimit-remaining integer

The number of requests in your hourly quota that remain before you hit your request limit. See https://docs.digitalocean.com/reference/api/reference/#rate-limit for information about how requests expire.

ratelimit-reset integer

The time when the oldest request will expire. The value is given in Unix epoch time. See https://docs.digitalocean.com/reference/api/reference/#rate-limit for information about how requests expire.

id string required
Example: not_found

A short identifier corresponding to the HTTP status code returned. For example, the ID for a response returning a 404 status code would be "not_found."

message string required
Example: The resource you were accessing could not be found.

A message providing additional information about the error, including details to help resolve it when possible.

request_id string optional
Example: 4d9d8375-3c56-4925-a3e7-eb137fed17e9

Optionally, some endpoints may include a request ID that should be provided when reporting bugs or opening support tickets to help identify the issue.

{
  "trigger": {
    "agent_kind": "AGENT_KIND_UNSPECIFIED",
    "bound_session_id": "a1b2c3d4-e5f6-7890-abcd-ef1234567890",
    "created_at": "2026-07-27T12:00:00Z",
    "cron": {
      "cron_expr": "0 9 * * 1-5",
      "next_run_at": "2026-07-27T13:00:00Z",
      "timezone": "America/New_York"
    },
    "kind": "webhook",
    "name": "nightly-deploy-check",
    "output": {
      "email_configured": true,
      "mode": "email",
      "slack_configured": false
    },
    "prompt_template": "Review the latest push and summarize risks.",
    "session_mode": "fresh",
    "session_template": "",
    "status": "active",
    "trigger_id": "b1a0c6de-1f2e-4a3b-9c8d-0e1f2a3b4c5d",
    "updated_at": "2026-07-27T12:00:00Z",
    "webhook": {
      "provider": "github",
      "webhook_url": "https://api.digitalocean.com/v2/agents/triggers/b1a0.../webhook"
    }
  }
}
{
  "id": "unauthorized",
  "message": "Unable to authenticate you."
}
{
  "id": "not_found",
  "message": "The resource you requested could not be found."
}
{
  "id": "too_many_requests",
  "message": "API rate limit exceeded."
}
{
  "id": "server_error",
  "message": "Unexpected server-side error"
}
{
  "id": "example_error",
  "message": "some error message"
}

GET ListReusableSessions lists the team's PAUSED sessions for the reuse picker.

/v2/agents/triggers/reusable-sessions
Authorizations: bearer_auth (1 scope)
Http: Bearer
Required scopes: agent_harness_session:read

OAuth Authentication

In order to interact with the DigitalOcean API, you or your application must authenticate.

The DigitalOcean API handles this through OAuth, an open standard for authorization. OAuth allows you to delegate access to your account. Scopes can be used to grant full access, read-only access, or access to a specific set of endpoints.

You can generate an OAuth token by visiting the Apps & API section of the DigitalOcean control panel for your account.

An OAuth token functions as a complete authentication request. In effect, it acts as a substitute for a username and password pair.

Because of this, it is absolutely essential that you keep your OAuth tokens secure. In fact, upon generation, the web interface will only display each token a single time in order to prevent the token from being compromised.

DigitalOcean access tokens begin with an identifiable prefix in order to distinguish them from other similar tokens.

  • dop_v1_ for personal access tokens generated in the control panel
  • doo_v1_ for tokens generated by applications using the OAuth flow
  • dor_v1_ for OAuth refresh tokens

Scopes

Scopes act like permissions assigned to an API token. These permissions determine what actions the token can perform. You can create API tokens that grant read-only access, full access, or limited access to specific endpoints by using custom scopes.

Generally, scopes are designed to match HTTP verbs and common CRUD operations (Create, Read, Update, Delete).

HTTP Verb CRUD Operation Scope
GET Read <resource>:read
POST Create <resource>:create
PUT/PATCH Update <resource>:update
DELETE Delete <resource>:delete

For example, creating a new Droplet by making a POST request to the /v2/droplets endpoint requires the droplet:create scope while listing Droplets by making a GET request to the /v2/droplets endpoint requires the droplet:read scope.

Each endpoint below specifies which scope is required to access it when using custom scopes.

How to Authenticate with OAuth

In order to make an authenticated request, include a bearer-type Authorization header containing your OAuth token. All requests must be made over HTTPS.

Authenticate with a Bearer Authorization Header

curl -X $HTTP_METHOD -H "Authorization: Bearer $DIGITALOCEAN_TOKEN" "https://api.digitalocean.com/v2/$OBJECT"

Returns the team's sessions in status PAUSED, for binding a session_mode=reuse trigger. The item shape is the hosted-agents Session, so agent_kind and status use the AGENT_KIND_* / SESSION_STATUS_* spelling; status is always SESSION_STATUS_PAUSED here.

Query Parameters

page_size integer (int32) >= 1 optional
Example: 50

Page size. Defaults to 50 when omitted or non-positive; server-clamped.

page_token string optional

Opaque keyset cursor returned by the previous page. Empty starts from the beginning.

curl -X GET \
  -H "Content-Type: application/json" \
  -H "Authorization: Bearer $DIGITALOCEAN_TOKEN" \
  "https://api.digitalocean.com/v2/agents/triggers/reusable-sessions?page_size=50"
curl -X GET \
  -H "Authorization: Bearer $API_TOKEN" \
  "https://api.digitalocean.com/v2/agents/triggers/reusable-sessions"

Responses

200

A successful response.

ratelimit-limit integer

The default limit on number of requests that can be made per hour and per minute. Current rate limits are 5000 requests per hour and 250 requests per minute.

ratelimit-remaining integer

The number of requests in your hourly quota that remain before you hit your request limit. See https://docs.digitalocean.com/reference/api/reference/#rate-limit for information about how requests expire.

ratelimit-reset integer

The time when the oldest request will expire. The value is given in Unix epoch time. See https://docs.digitalocean.com/reference/api/reference/#rate-limit for information about how requests expire.

next_page_token string optional

Opaque cursor for the next page. Empty when there are no further pages.

sessions array of object optional
Show child properties
agent_kind string (enum) optional
Example: AGENT_KIND_UNSPECIFIED

AgentKind identifies what runs inside the session sandbox. CreateSession accepts CLAUDE_CODE, OPENCODE, CODEX_CLI, CURSOR_CLI, OPENAI_CODEX, LANGGRAPH, and CREWAI (the supported set is overridable via HARNESS_SUPPORTED_AGENT_KINDS); other values are rejected with 400. AGENT_KIND_OPENAI_CODEX is the OpenAI sandbox-provider kind (DO runs codex exec-server; the agent loop lives at OpenAI). AGENT_KIND_LANGGRAPH is the LangGraph framework adapter. AGENT_KIND_CREWAI is the CrewAI Crew framework adapter: like LANGGRAPH the template bakes no agent code, so spec.env must supply FRAMEWORK_REPO and FRAMEWORK_REPO_SHA; a Crew kickoff is one-shot and exposes no HITL surface. CREWAI is additionally gated per team and returns 400 for teams it is not enabled for.

created_at string (date-time) optional
Example: 2026-07-27T12:00:00Z
last_event_at string (date-time) optional
Example: 2026-07-27T12:00:00Z
name string optional
Example: demo-agent
session_id string optional
Example: a1b2c3d4-e5f6-7890-abcd-ef1234567890
status string (enum) optional
Example: SESSION_STATUS_UNSPECIFIED

SessionStatus is the lifecycle state of the sandbox + agent pair. SESSION_STATUS_ALL is a ListSessions status-filter value only -- no session is ever actually in this status. SESSION_STATUS_LOCKED is reserved for internal use and never appears in an end-user-facing response.

401

Authentication failed due to invalid credentials.

ratelimit-limit integer

The default limit on number of requests that can be made per hour and per minute. Current rate limits are 5000 requests per hour and 250 requests per minute.

ratelimit-remaining integer

The number of requests in your hourly quota that remain before you hit your request limit. See https://docs.digitalocean.com/reference/api/reference/#rate-limit for information about how requests expire.

ratelimit-reset integer

The time when the oldest request will expire. The value is given in Unix epoch time. See https://docs.digitalocean.com/reference/api/reference/#rate-limit for information about how requests expire.

id string required
Example: not_found

A short identifier corresponding to the HTTP status code returned. For example, the ID for a response returning a 404 status code would be "not_found."

message string required
Example: The resource you were accessing could not be found.

A message providing additional information about the error, including details to help resolve it when possible.

request_id string optional
Example: 4d9d8375-3c56-4925-a3e7-eb137fed17e9

Optionally, some endpoints may include a request ID that should be provided when reporting bugs or opening support tickets to help identify the issue.

429

The API rate limit has been exceeded.

ratelimit-limit integer

The default limit on number of requests that can be made per hour and per minute. Current rate limits are 5000 requests per hour and 250 requests per minute.

ratelimit-remaining integer

The number of requests in your hourly quota that remain before you hit your request limit. See https://docs.digitalocean.com/reference/api/reference/#rate-limit for information about how requests expire.

ratelimit-reset integer

The time when the oldest request will expire. The value is given in Unix epoch time. See https://docs.digitalocean.com/reference/api/reference/#rate-limit for information about how requests expire.

id string required
Example: not_found

A short identifier corresponding to the HTTP status code returned. For example, the ID for a response returning a 404 status code would be "not_found."

message string required
Example: The resource you were accessing could not be found.

A message providing additional information about the error, including details to help resolve it when possible.

request_id string optional
Example: 4d9d8375-3c56-4925-a3e7-eb137fed17e9

Optionally, some endpoints may include a request ID that should be provided when reporting bugs or opening support tickets to help identify the issue.

500

There was a server error.

ratelimit-limit integer

The default limit on number of requests that can be made per hour and per minute. Current rate limits are 5000 requests per hour and 250 requests per minute.

ratelimit-remaining integer

The number of requests in your hourly quota that remain before you hit your request limit. See https://docs.digitalocean.com/reference/api/reference/#rate-limit for information about how requests expire.

ratelimit-reset integer

The time when the oldest request will expire. The value is given in Unix epoch time. See https://docs.digitalocean.com/reference/api/reference/#rate-limit for information about how requests expire.

id string required
Example: not_found

A short identifier corresponding to the HTTP status code returned. For example, the ID for a response returning a 404 status code would be "not_found."

message string required
Example: The resource you were accessing could not be found.

A message providing additional information about the error, including details to help resolve it when possible.

request_id string optional
Example: 4d9d8375-3c56-4925-a3e7-eb137fed17e9

Optionally, some endpoints may include a request ID that should be provided when reporting bugs or opening support tickets to help identify the issue.

default

There was an unexpected error.

ratelimit-limit integer

The default limit on number of requests that can be made per hour and per minute. Current rate limits are 5000 requests per hour and 250 requests per minute.

ratelimit-remaining integer

The number of requests in your hourly quota that remain before you hit your request limit. See https://docs.digitalocean.com/reference/api/reference/#rate-limit for information about how requests expire.

ratelimit-reset integer

The time when the oldest request will expire. The value is given in Unix epoch time. See https://docs.digitalocean.com/reference/api/reference/#rate-limit for information about how requests expire.

id string required
Example: not_found

A short identifier corresponding to the HTTP status code returned. For example, the ID for a response returning a 404 status code would be "not_found."

message string required
Example: The resource you were accessing could not be found.

A message providing additional information about the error, including details to help resolve it when possible.

request_id string optional
Example: 4d9d8375-3c56-4925-a3e7-eb137fed17e9

Optionally, some endpoints may include a request ID that should be provided when reporting bugs or opening support tickets to help identify the issue.

{
  "next_page_token": "",
  "sessions": [
    {
      "agent_kind": "AGENT_KIND_UNSPECIFIED",
      "created_at": "2026-07-27T12:00:00Z",
      "last_event_at": "2026-07-27T12:00:00Z",
      "name": "demo-agent",
      "session_id": "a1b2c3d4-e5f6-7890-abcd-ef1234567890",
      "status": "SESSION_STATUS_UNSPECIFIED"
    }
  ]
}
{
  "id": "unauthorized",
  "message": "Unable to authenticate you."
}
{
  "id": "too_many_requests",
  "message": "API rate limit exceeded."
}
{
  "id": "server_error",
  "message": "Unexpected server-side error"
}
{
  "id": "example_error",
  "message": "some error message"
}

GET GetTrigger returns a single trigger by id.

/v2/agents/triggers/{trigger_id}
Authorizations: bearer_auth (1 scope)
Http: Bearer
Required scopes: agent_harness_session:read

OAuth Authentication

In order to interact with the DigitalOcean API, you or your application must authenticate.

The DigitalOcean API handles this through OAuth, an open standard for authorization. OAuth allows you to delegate access to your account. Scopes can be used to grant full access, read-only access, or access to a specific set of endpoints.

You can generate an OAuth token by visiting the Apps & API section of the DigitalOcean control panel for your account.

An OAuth token functions as a complete authentication request. In effect, it acts as a substitute for a username and password pair.

Because of this, it is absolutely essential that you keep your OAuth tokens secure. In fact, upon generation, the web interface will only display each token a single time in order to prevent the token from being compromised.

DigitalOcean access tokens begin with an identifiable prefix in order to distinguish them from other similar tokens.

  • dop_v1_ for personal access tokens generated in the control panel
  • doo_v1_ for tokens generated by applications using the OAuth flow
  • dor_v1_ for OAuth refresh tokens

Scopes

Scopes act like permissions assigned to an API token. These permissions determine what actions the token can perform. You can create API tokens that grant read-only access, full access, or limited access to specific endpoints by using custom scopes.

Generally, scopes are designed to match HTTP verbs and common CRUD operations (Create, Read, Update, Delete).

HTTP Verb CRUD Operation Scope
GET Read <resource>:read
POST Create <resource>:create
PUT/PATCH Update <resource>:update
DELETE Delete <resource>:delete

For example, creating a new Droplet by making a POST request to the /v2/droplets endpoint requires the droplet:create scope while listing Droplets by making a GET request to the /v2/droplets endpoint requires the droplet:read scope.

Each endpoint below specifies which scope is required to access it when using custom scopes.

How to Authenticate with OAuth

In order to make an authenticated request, include a bearer-type Authorization header containing your OAuth token. All requests must be made over HTTPS.

Authenticate with a Bearer Authorization Header

curl -X $HTTP_METHOD -H "Authorization: Bearer $DIGITALOCEAN_TOKEN" "https://api.digitalocean.com/v2/$OBJECT"

GetTrigger returns a single trigger by id. Write-only fields (webhook secret, output destination, session_template env values) are never included.

Path Parameters

trigger_id string required
Example: b1a0c6de-1f2e-4a3b-9c8d-0e1f2a3b4c5d

The trigger UUID.

curl -X GET \
  -H "Content-Type: application/json" \
  -H "Authorization: Bearer $DIGITALOCEAN_TOKEN" \
  "https://api.digitalocean.com/v2/agents/triggers/{trigger_id}"
curl -X GET \
  -H "Authorization: Bearer $API_TOKEN" \
  "https://api.digitalocean.com/v2/agents/triggers/{trigger_id}"

Responses

200

A successful response.

ratelimit-limit integer

The default limit on number of requests that can be made per hour and per minute. Current rate limits are 5000 requests per hour and 250 requests per minute.

ratelimit-remaining integer

The number of requests in your hourly quota that remain before you hit your request limit. See https://docs.digitalocean.com/reference/api/reference/#rate-limit for information about how requests expire.

ratelimit-reset integer

The time when the oldest request will expire. The value is given in Unix epoch time. See https://docs.digitalocean.com/reference/api/reference/#rate-limit for information about how requests expire.

trigger object optional

A single automation bound to exactly one agent/session (agent == session in v1). The nested block present depends on kind (webhook xor cron) and session_mode (fresh => session_template; reuse => bound_session_id). agent_kind is read-only and derived; the webhook secret, the output email address / Slack webhook URL, and any env values inside session_template are write-only and never returned.

Show child properties
agent_kind string (enum) optional
Example: AGENT_KIND_UNSPECIFIED

AgentKind identifies what runs inside the session sandbox. CreateSession accepts CLAUDE_CODE, OPENCODE, CODEX_CLI, CURSOR_CLI, OPENAI_CODEX, LANGGRAPH, and CREWAI (the supported set is overridable via HARNESS_SUPPORTED_AGENT_KINDS); other values are rejected with 400. AGENT_KIND_OPENAI_CODEX is the OpenAI sandbox-provider kind (DO runs codex exec-server; the agent loop lives at OpenAI). AGENT_KIND_LANGGRAPH is the LangGraph framework adapter. AGENT_KIND_CREWAI is the CrewAI Crew framework adapter: like LANGGRAPH the template bakes no agent code, so spec.env must supply FRAMEWORK_REPO and FRAMEWORK_REPO_SHA; a Crew kickoff is one-shot and exposes no HITL surface. CREWAI is additionally gated per team and returns 400 for teams it is not enabled for.

bound_session_id string (uuid) optional
Example: a1b2c3d4-e5f6-7890-abcd-ef1234567890

Present iff session_mode=reuse. UUID of the existing PAUSED session this trigger resumes; may be shared by multiple triggers.

created_at string (date-time) optional
Example: 2026-07-27T12:00:00Z
cron object optional

Present iff kind=cron.

Show child properties
cron_expr string optional
Example: 0 9 * * 1-5

Cron expression; must parse with the scanner's cron library.

next_run_at string (date-time) optional
Example: 2026-07-27T13:00:00Z

Read-only; server-computed next fire time.

timezone string optional
Example: America/New_York

IANA timezone (e.g. "America/New_York").

kind string, one of: webhook, cron optional
Example: webhook

How the trigger fires - on an event (webhook) or on a schedule (cron). Immutable after create.

name string optional
Example: nightly-deploy-check

Unique per team among non-deleted triggers. Same rules as session names; not UUID-form.

output object optional

Output-delivery configuration as seen on reads. The email address and Slack webhook URL are write-only and never returned.

Show child properties
email_configured boolean optional
Example: true

True when an email address is stored (mode=email).

mode string, one of: none, email, slack optional
Example: email

none = nothing pushed; the result stays in run history for self-serve. email = the collected run output is emailed to a configured address. slack = the collected run output is posted to a Slack incoming webhook URL (channel fixed by the webhook at install time).

slack_configured boolean optional
Example: false

True when a Slack incoming webhook URL is stored (mode=slack).

prompt_template string optional
Example: Review the latest push and summarize risks.

The prompt sent on each fire. Opaque to clients; payload-interpolation syntax is server-defined. For cron triggers it must not reference payload placeholders.

session_mode string, one of: fresh, reuse optional
Example: fresh

fresh = a new session is created from the trigger's spec on every firing and destroyed after. reuse = the trigger binds an existing PAUSED session, resumed on each firing and paused after; multiple triggers may bind one session.

session_template string optional

Present iff session_mode=fresh. The agents.yaml Agent manifest used to CREATE a session on each fire, returned with its env values REDACTED.

status string, one of: active, paused optional
Example: active

Trigger lifecycle state. Soft-deleted triggers are never returned (404).

trigger_id string optional
Example: b1a0c6de-1f2e-4a3b-9c8d-0e1f2a3b4c5d

Server-allocated UUID; opaque to clients.

updated_at string (date-time) optional
Example: 2026-07-27T12:00:00Z
webhook object optional

Present iff kind=webhook. The secret is never in this object (see create_trigger_response / rotate_secret_response).

Show child properties
provider string, one of: github, gitlab, custom optional
Example: github

Signature-verification scheme applied to a delivery. Omitted on create defaults to custom.

webhook_url string optional
Example: https://api.digitalocean.com/v2/agents/triggers/b1a0.../webhook

The Payload URL to configure in the external system.

401

Authentication failed due to invalid credentials.

ratelimit-limit integer

The default limit on number of requests that can be made per hour and per minute. Current rate limits are 5000 requests per hour and 250 requests per minute.

ratelimit-remaining integer

The number of requests in your hourly quota that remain before you hit your request limit. See https://docs.digitalocean.com/reference/api/reference/#rate-limit for information about how requests expire.

ratelimit-reset integer

The time when the oldest request will expire. The value is given in Unix epoch time. See https://docs.digitalocean.com/reference/api/reference/#rate-limit for information about how requests expire.

id string required
Example: not_found

A short identifier corresponding to the HTTP status code returned. For example, the ID for a response returning a 404 status code would be "not_found."

message string required
Example: The resource you were accessing could not be found.

A message providing additional information about the error, including details to help resolve it when possible.

request_id string optional
Example: 4d9d8375-3c56-4925-a3e7-eb137fed17e9

Optionally, some endpoints may include a request ID that should be provided when reporting bugs or opening support tickets to help identify the issue.

404

The resource was not found.

ratelimit-limit integer

The default limit on number of requests that can be made per hour and per minute. Current rate limits are 5000 requests per hour and 250 requests per minute.

ratelimit-remaining integer

The number of requests in your hourly quota that remain before you hit your request limit. See https://docs.digitalocean.com/reference/api/reference/#rate-limit for information about how requests expire.

ratelimit-reset integer

The time when the oldest request will expire. The value is given in Unix epoch time. See https://docs.digitalocean.com/reference/api/reference/#rate-limit for information about how requests expire.

id string required
Example: not_found

A short identifier corresponding to the HTTP status code returned. For example, the ID for a response returning a 404 status code would be "not_found."

message string required
Example: The resource you were accessing could not be found.

A message providing additional information about the error, including details to help resolve it when possible.

request_id string optional
Example: 4d9d8375-3c56-4925-a3e7-eb137fed17e9

Optionally, some endpoints may include a request ID that should be provided when reporting bugs or opening support tickets to help identify the issue.

429

The API rate limit has been exceeded.

ratelimit-limit integer

The default limit on number of requests that can be made per hour and per minute. Current rate limits are 5000 requests per hour and 250 requests per minute.

ratelimit-remaining integer

The number of requests in your hourly quota that remain before you hit your request limit. See https://docs.digitalocean.com/reference/api/reference/#rate-limit for information about how requests expire.

ratelimit-reset integer

The time when the oldest request will expire. The value is given in Unix epoch time. See https://docs.digitalocean.com/reference/api/reference/#rate-limit for information about how requests expire.

id string required
Example: not_found

A short identifier corresponding to the HTTP status code returned. For example, the ID for a response returning a 404 status code would be "not_found."

message string required
Example: The resource you were accessing could not be found.

A message providing additional information about the error, including details to help resolve it when possible.

request_id string optional
Example: 4d9d8375-3c56-4925-a3e7-eb137fed17e9

Optionally, some endpoints may include a request ID that should be provided when reporting bugs or opening support tickets to help identify the issue.

500

There was a server error.

ratelimit-limit integer

The default limit on number of requests that can be made per hour and per minute. Current rate limits are 5000 requests per hour and 250 requests per minute.

ratelimit-remaining integer

The number of requests in your hourly quota that remain before you hit your request limit. See https://docs.digitalocean.com/reference/api/reference/#rate-limit for information about how requests expire.

ratelimit-reset integer

The time when the oldest request will expire. The value is given in Unix epoch time. See https://docs.digitalocean.com/reference/api/reference/#rate-limit for information about how requests expire.

id string required
Example: not_found

A short identifier corresponding to the HTTP status code returned. For example, the ID for a response returning a 404 status code would be "not_found."

message string required
Example: The resource you were accessing could not be found.

A message providing additional information about the error, including details to help resolve it when possible.

request_id string optional
Example: 4d9d8375-3c56-4925-a3e7-eb137fed17e9

Optionally, some endpoints may include a request ID that should be provided when reporting bugs or opening support tickets to help identify the issue.

default

There was an unexpected error.

ratelimit-limit integer

The default limit on number of requests that can be made per hour and per minute. Current rate limits are 5000 requests per hour and 250 requests per minute.

ratelimit-remaining integer

The number of requests in your hourly quota that remain before you hit your request limit. See https://docs.digitalocean.com/reference/api/reference/#rate-limit for information about how requests expire.

ratelimit-reset integer

The time when the oldest request will expire. The value is given in Unix epoch time. See https://docs.digitalocean.com/reference/api/reference/#rate-limit for information about how requests expire.

id string required
Example: not_found

A short identifier corresponding to the HTTP status code returned. For example, the ID for a response returning a 404 status code would be "not_found."

message string required
Example: The resource you were accessing could not be found.

A message providing additional information about the error, including details to help resolve it when possible.

request_id string optional
Example: 4d9d8375-3c56-4925-a3e7-eb137fed17e9

Optionally, some endpoints may include a request ID that should be provided when reporting bugs or opening support tickets to help identify the issue.

{
  "trigger": {
    "agent_kind": "AGENT_KIND_UNSPECIFIED",
    "bound_session_id": "a1b2c3d4-e5f6-7890-abcd-ef1234567890",
    "created_at": "2026-07-27T12:00:00Z",
    "cron": {
      "cron_expr": "0 9 * * 1-5",
      "next_run_at": "2026-07-27T13:00:00Z",
      "timezone": "America/New_York"
    },
    "kind": "webhook",
    "name": "nightly-deploy-check",
    "output": {
      "email_configured": true,
      "mode": "email",
      "slack_configured": false
    },
    "prompt_template": "Review the latest push and summarize risks.",
    "session_mode": "fresh",
    "session_template": "",
    "status": "active",
    "trigger_id": "b1a0c6de-1f2e-4a3b-9c8d-0e1f2a3b4c5d",
    "updated_at": "2026-07-27T12:00:00Z",
    "webhook": {
      "provider": "github",
      "webhook_url": "https://api.digitalocean.com/v2/agents/triggers/b1a0.../webhook"
    }
  }
}
{
  "id": "unauthorized",
  "message": "Unable to authenticate you."
}
{
  "id": "not_found",
  "message": "The resource you requested could not be found."
}
{
  "id": "too_many_requests",
  "message": "API rate limit exceeded."
}
{
  "id": "server_error",
  "message": "Unexpected server-side error"
}
{
  "id": "example_error",
  "message": "some error message"
}

PATCH UpdateTrigger updates, pauses, or re-enables a trigger.

/v2/agents/triggers/{trigger_id}
Authorizations: bearer_auth (1 scope)
Http: Bearer
Required scopes: agent_harness_session:manage

OAuth Authentication

In order to interact with the DigitalOcean API, you or your application must authenticate.

The DigitalOcean API handles this through OAuth, an open standard for authorization. OAuth allows you to delegate access to your account. Scopes can be used to grant full access, read-only access, or access to a specific set of endpoints.

You can generate an OAuth token by visiting the Apps & API section of the DigitalOcean control panel for your account.

An OAuth token functions as a complete authentication request. In effect, it acts as a substitute for a username and password pair.

Because of this, it is absolutely essential that you keep your OAuth tokens secure. In fact, upon generation, the web interface will only display each token a single time in order to prevent the token from being compromised.

DigitalOcean access tokens begin with an identifiable prefix in order to distinguish them from other similar tokens.

  • dop_v1_ for personal access tokens generated in the control panel
  • doo_v1_ for tokens generated by applications using the OAuth flow
  • dor_v1_ for OAuth refresh tokens

Scopes

Scopes act like permissions assigned to an API token. These permissions determine what actions the token can perform. You can create API tokens that grant read-only access, full access, or limited access to specific endpoints by using custom scopes.

Generally, scopes are designed to match HTTP verbs and common CRUD operations (Create, Read, Update, Delete).

HTTP Verb CRUD Operation Scope
GET Read <resource>:read
POST Create <resource>:create
PUT/PATCH Update <resource>:update
DELETE Delete <resource>:delete

For example, creating a new Droplet by making a POST request to the /v2/droplets endpoint requires the droplet:create scope while listing Droplets by making a GET request to the /v2/droplets endpoint requires the droplet:read scope.

Each endpoint below specifies which scope is required to access it when using custom scopes.

How to Authenticate with OAuth

In order to make an authenticated request, include a bearer-type Authorization header containing your OAuth token. All requests must be made over HTTPS.

Authenticate with a Bearer Authorization Header

curl -X $HTTP_METHOD -H "Authorization: Bearer $DIGITALOCEAN_TOKEN" "https://api.digitalocean.com/v2/$OBJECT"

Partial update: only the supplied fields change. kind and webhook.provider are immutable (409 on change). Mutable: name (409 on duplicate), status (active<->paused), prompt_template, output, session_template (fresh), bound_session_id (reuse), cron.cron_expr / cron.timezone (recomputes next_run_at). Re-enabling never produces a catch-up run. PATCHing session_template is a full replacement, so every spec.secrets slot value the new manifest declares must be resupplied (secret values are never echoed back), or the request is a 400.

Path Parameters

trigger_id string required
Example: b1a0c6de-1f2e-4a3b-9c8d-0e1f2a3b4c5d

The trigger UUID.

Request Body: application/json

The fields to change.

bound_session_id string (uuid) optional
Example: a1b2c3d4-e5f6-7890-abcd-ef1234567890

reuse triggers only. UUID of an existing session owned by the team.

cron object optional

cron block on create.

Show child properties
cron_expr string required
Example: 0 9 * * 1-5
timezone string required
Example: America/New_York

IANA timezone.

name string optional
Example: nightly-deploy-check

New team-unique trigger name. Same charset/length rules as create.

output object optional

Output-delivery configuration on create/update. Exactly one of email / slack is required for the matching mode and forbidden otherwise; destinations are stored encrypted and never returned.

Show child properties
email string optional

Destination address; required iff mode=email.

mode string, one of: none, email, slack required
Example: email

none = nothing pushed; the result stays in run history for self-serve. email = the collected run output is emailed to a configured address. slack = the collected run output is posted to a Slack incoming webhook URL (channel fixed by the webhook at install time).

slack object optional

Slack destination on create/update. webhook_url is required when mode=slack; must be https://hooks.slack.com/services/...; stored encrypted and never returned.

Show child properties
webhook_url string required
Example: https://hooks.slack.com/services/T0000/B0000/XXXX

Slack incoming webhook URL (https://hooks.slack.com/services/...). The channel is bound to this URL at install time.

prompt_template string optional
Example: Review the latest push and summarize risks.
session_template string optional

fresh triggers only. A session_template PATCH is a full replacement of the stored template; you must resupply every spec.secrets slot value the new manifest declares, or the request is a 400.

status string, one of: active, paused optional
Example: active

Trigger lifecycle state. Soft-deleted triggers are never returned (404).

Content type application/json
{
  "bound_session_id": "a1b2c3d4-e5f6-7890-abcd-ef1234567890",
  "cron": {
    "cron_expr": "0 9 * * 1-5",
    "timezone": "America/New_York"
  },
  "name": "nightly-deploy-check",
  "output": {
    "email": "[email protected]",
    "mode": "email",
    "slack": {
      "webhook_url": "https://hooks.slack.com/services/T0000/B0000/XXXX"
    }
  },
  "prompt_template": "Review the latest push and summarize risks.",
  "session_template": "",
  "status": "active"
}
curl -X PATCH \
  -H "Content-Type: application/json" \
  -H "Authorization: Bearer $DIGITALOCEAN_TOKEN" \
  -d '{"status":"paused"}' \
  "https://api.digitalocean.com/v2/agents/triggers/{trigger_id}"
curl -X PATCH \
  -H "Authorization: Bearer $API_TOKEN" \
  -H "Content-Type: application/json" \
  -d '{
  "bound_session_id": "a1b2c3d4-e5f6-7890-abcd-ef1234567890",
  "cron": {
    "cron_expr": "0 9 * * 1-5",
    "timezone": "America/New_York"
  },
  "name": "nightly-deploy-check",
  "output": {
    "email": "[email protected]",
    "mode": "email",
    "slack": {
      "webhook_url": "https://hooks.slack.com/services/T0000/B0000/XXXX"
    }
  },
  "prompt_template": "Review the latest push and summarize risks.",
  "session_template": "",
  "status": "active"
}' \
  "https://api.digitalocean.com/v2/agents/triggers/{trigger_id}"

Responses

200

The updated trigger.

ratelimit-limit integer

The default limit on number of requests that can be made per hour and per minute. Current rate limits are 5000 requests per hour and 250 requests per minute.

ratelimit-remaining integer

The number of requests in your hourly quota that remain before you hit your request limit. See https://docs.digitalocean.com/reference/api/reference/#rate-limit for information about how requests expire.

ratelimit-reset integer

The time when the oldest request will expire. The value is given in Unix epoch time. See https://docs.digitalocean.com/reference/api/reference/#rate-limit for information about how requests expire.

trigger object optional

A single automation bound to exactly one agent/session (agent == session in v1). The nested block present depends on kind (webhook xor cron) and session_mode (fresh => session_template; reuse => bound_session_id). agent_kind is read-only and derived; the webhook secret, the output email address / Slack webhook URL, and any env values inside session_template are write-only and never returned.

Show child properties
agent_kind string (enum) optional
Example: AGENT_KIND_UNSPECIFIED

AgentKind identifies what runs inside the session sandbox. CreateSession accepts CLAUDE_CODE, OPENCODE, CODEX_CLI, CURSOR_CLI, OPENAI_CODEX, LANGGRAPH, and CREWAI (the supported set is overridable via HARNESS_SUPPORTED_AGENT_KINDS); other values are rejected with 400. AGENT_KIND_OPENAI_CODEX is the OpenAI sandbox-provider kind (DO runs codex exec-server; the agent loop lives at OpenAI). AGENT_KIND_LANGGRAPH is the LangGraph framework adapter. AGENT_KIND_CREWAI is the CrewAI Crew framework adapter: like LANGGRAPH the template bakes no agent code, so spec.env must supply FRAMEWORK_REPO and FRAMEWORK_REPO_SHA; a Crew kickoff is one-shot and exposes no HITL surface. CREWAI is additionally gated per team and returns 400 for teams it is not enabled for.

bound_session_id string (uuid) optional
Example: a1b2c3d4-e5f6-7890-abcd-ef1234567890

Present iff session_mode=reuse. UUID of the existing PAUSED session this trigger resumes; may be shared by multiple triggers.

created_at string (date-time) optional
Example: 2026-07-27T12:00:00Z
cron object optional

Present iff kind=cron.

Show child properties
cron_expr string optional
Example: 0 9 * * 1-5

Cron expression; must parse with the scanner's cron library.

next_run_at string (date-time) optional
Example: 2026-07-27T13:00:00Z

Read-only; server-computed next fire time.

timezone string optional
Example: America/New_York

IANA timezone (e.g. "America/New_York").

kind string, one of: webhook, cron optional
Example: webhook

How the trigger fires - on an event (webhook) or on a schedule (cron). Immutable after create.

name string optional
Example: nightly-deploy-check

Unique per team among non-deleted triggers. Same rules as session names; not UUID-form.

output object optional

Output-delivery configuration as seen on reads. The email address and Slack webhook URL are write-only and never returned.

Show child properties
email_configured boolean optional
Example: true

True when an email address is stored (mode=email).

mode string, one of: none, email, slack optional
Example: email

none = nothing pushed; the result stays in run history for self-serve. email = the collected run output is emailed to a configured address. slack = the collected run output is posted to a Slack incoming webhook URL (channel fixed by the webhook at install time).

slack_configured boolean optional
Example: false

True when a Slack incoming webhook URL is stored (mode=slack).

prompt_template string optional
Example: Review the latest push and summarize risks.

The prompt sent on each fire. Opaque to clients; payload-interpolation syntax is server-defined. For cron triggers it must not reference payload placeholders.

session_mode string, one of: fresh, reuse optional
Example: fresh

fresh = a new session is created from the trigger's spec on every firing and destroyed after. reuse = the trigger binds an existing PAUSED session, resumed on each firing and paused after; multiple triggers may bind one session.

session_template string optional

Present iff session_mode=fresh. The agents.yaml Agent manifest used to CREATE a session on each fire, returned with its env values REDACTED.

status string, one of: active, paused optional
Example: active

Trigger lifecycle state. Soft-deleted triggers are never returned (404).

trigger_id string optional
Example: b1a0c6de-1f2e-4a3b-9c8d-0e1f2a3b4c5d

Server-allocated UUID; opaque to clients.

updated_at string (date-time) optional
Example: 2026-07-27T12:00:00Z
webhook object optional

Present iff kind=webhook. The secret is never in this object (see create_trigger_response / rotate_secret_response).

Show child properties
provider string, one of: github, gitlab, custom optional
Example: github

Signature-verification scheme applied to a delivery. Omitted on create defaults to custom.

webhook_url string optional
Example: https://api.digitalocean.com/v2/agents/triggers/b1a0.../webhook

The Payload URL to configure in the external system.

400

Validation failed.

ratelimit-limit integer

The default limit on number of requests that can be made per hour and per minute. Current rate limits are 5000 requests per hour and 250 requests per minute.

ratelimit-remaining integer

The number of requests in your hourly quota that remain before you hit your request limit. See https://docs.digitalocean.com/reference/api/reference/#rate-limit for information about how requests expire.

ratelimit-reset integer

The time when the oldest request will expire. The value is given in Unix epoch time. See https://docs.digitalocean.com/reference/api/reference/#rate-limit for information about how requests expire.

id string required
Example: not_found

A short identifier corresponding to the HTTP status code returned. For example, the ID for a response returning a 404 status code would be "not_found."

message string required
Example: The resource you were accessing could not be found.

A message providing additional information about the error, including details to help resolve it when possible.

request_id string optional
Example: 4d9d8375-3c56-4925-a3e7-eb137fed17e9

Optionally, some endpoints may include a request ID that should be provided when reporting bugs or opening support tickets to help identify the issue.

401

Authentication failed due to invalid credentials.

ratelimit-limit integer

The default limit on number of requests that can be made per hour and per minute. Current rate limits are 5000 requests per hour and 250 requests per minute.

ratelimit-remaining integer

The number of requests in your hourly quota that remain before you hit your request limit. See https://docs.digitalocean.com/reference/api/reference/#rate-limit for information about how requests expire.

ratelimit-reset integer

The time when the oldest request will expire. The value is given in Unix epoch time. See https://docs.digitalocean.com/reference/api/reference/#rate-limit for information about how requests expire.

id string required
Example: not_found

A short identifier corresponding to the HTTP status code returned. For example, the ID for a response returning a 404 status code would be "not_found."

message string required
Example: The resource you were accessing could not be found.

A message providing additional information about the error, including details to help resolve it when possible.

request_id string optional
Example: 4d9d8375-3c56-4925-a3e7-eb137fed17e9

Optionally, some endpoints may include a request ID that should be provided when reporting bugs or opening support tickets to help identify the issue.

403

The caller is not permitted to create the backing agent config for this trigger.

ratelimit-limit integer

The default limit on number of requests that can be made per hour and per minute. Current rate limits are 5000 requests per hour and 250 requests per minute.

ratelimit-remaining integer

The number of requests in your hourly quota that remain before you hit your request limit. See https://docs.digitalocean.com/reference/api/reference/#rate-limit for information about how requests expire.

ratelimit-reset integer

The time when the oldest request will expire. The value is given in Unix epoch time. See https://docs.digitalocean.com/reference/api/reference/#rate-limit for information about how requests expire.

id string required
Example: not_found

A short identifier corresponding to the HTTP status code returned. For example, the ID for a response returning a 404 status code would be "not_found."

message string required
Example: The resource you were accessing could not be found.

A message providing additional information about the error, including details to help resolve it when possible.

request_id string optional
Example: 4d9d8375-3c56-4925-a3e7-eb137fed17e9

Optionally, some endpoints may include a request ID that should be provided when reporting bugs or opening support tickets to help identify the issue.

404

The resource was not found.

ratelimit-limit integer

The default limit on number of requests that can be made per hour and per minute. Current rate limits are 5000 requests per hour and 250 requests per minute.

ratelimit-remaining integer

The number of requests in your hourly quota that remain before you hit your request limit. See https://docs.digitalocean.com/reference/api/reference/#rate-limit for information about how requests expire.

ratelimit-reset integer

The time when the oldest request will expire. The value is given in Unix epoch time. See https://docs.digitalocean.com/reference/api/reference/#rate-limit for information about how requests expire.

id string required
Example: not_found

A short identifier corresponding to the HTTP status code returned. For example, the ID for a response returning a 404 status code would be "not_found."

message string required
Example: The resource you were accessing could not be found.

A message providing additional information about the error, including details to help resolve it when possible.

request_id string optional
Example: 4d9d8375-3c56-4925-a3e7-eb137fed17e9

Optionally, some endpoints may include a request ID that should be provided when reporting bugs or opening support tickets to help identify the issue.

409

Duplicate name, or an attempt to change an immutable field (kind, provider).

ratelimit-limit integer

The default limit on number of requests that can be made per hour and per minute. Current rate limits are 5000 requests per hour and 250 requests per minute.

ratelimit-remaining integer

The number of requests in your hourly quota that remain before you hit your request limit. See https://docs.digitalocean.com/reference/api/reference/#rate-limit for information about how requests expire.

ratelimit-reset integer

The time when the oldest request will expire. The value is given in Unix epoch time. See https://docs.digitalocean.com/reference/api/reference/#rate-limit for information about how requests expire.

id string required
Example: not_found

A short identifier corresponding to the HTTP status code returned. For example, the ID for a response returning a 404 status code would be "not_found."

message string required
Example: The resource you were accessing could not be found.

A message providing additional information about the error, including details to help resolve it when possible.

request_id string optional
Example: 4d9d8375-3c56-4925-a3e7-eb137fed17e9

Optionally, some endpoints may include a request ID that should be provided when reporting bugs or opening support tickets to help identify the issue.

422

The team's trigger limit has been reached.

ratelimit-limit integer

The default limit on number of requests that can be made per hour and per minute. Current rate limits are 5000 requests per hour and 250 requests per minute.

ratelimit-remaining integer

The number of requests in your hourly quota that remain before you hit your request limit. See https://docs.digitalocean.com/reference/api/reference/#rate-limit for information about how requests expire.

ratelimit-reset integer

The time when the oldest request will expire. The value is given in Unix epoch time. See https://docs.digitalocean.com/reference/api/reference/#rate-limit for information about how requests expire.

id string required
Example: not_found

A short identifier corresponding to the HTTP status code returned. For example, the ID for a response returning a 404 status code would be "not_found."

message string required
Example: The resource you were accessing could not be found.

A message providing additional information about the error, including details to help resolve it when possible.

request_id string optional
Example: 4d9d8375-3c56-4925-a3e7-eb137fed17e9

Optionally, some endpoints may include a request ID that should be provided when reporting bugs or opening support tickets to help identify the issue.

429

The API rate limit has been exceeded.

ratelimit-limit integer

The default limit on number of requests that can be made per hour and per minute. Current rate limits are 5000 requests per hour and 250 requests per minute.

ratelimit-remaining integer

The number of requests in your hourly quota that remain before you hit your request limit. See https://docs.digitalocean.com/reference/api/reference/#rate-limit for information about how requests expire.

ratelimit-reset integer

The time when the oldest request will expire. The value is given in Unix epoch time. See https://docs.digitalocean.com/reference/api/reference/#rate-limit for information about how requests expire.

id string required
Example: not_found

A short identifier corresponding to the HTTP status code returned. For example, the ID for a response returning a 404 status code would be "not_found."

message string required
Example: The resource you were accessing could not be found.

A message providing additional information about the error, including details to help resolve it when possible.

request_id string optional
Example: 4d9d8375-3c56-4925-a3e7-eb137fed17e9

Optionally, some endpoints may include a request ID that should be provided when reporting bugs or opening support tickets to help identify the issue.

500

There was a server error.

ratelimit-limit integer

The default limit on number of requests that can be made per hour and per minute. Current rate limits are 5000 requests per hour and 250 requests per minute.

ratelimit-remaining integer

The number of requests in your hourly quota that remain before you hit your request limit. See https://docs.digitalocean.com/reference/api/reference/#rate-limit for information about how requests expire.

ratelimit-reset integer

The time when the oldest request will expire. The value is given in Unix epoch time. See https://docs.digitalocean.com/reference/api/reference/#rate-limit for information about how requests expire.

id string required
Example: not_found

A short identifier corresponding to the HTTP status code returned. For example, the ID for a response returning a 404 status code would be "not_found."

message string required
Example: The resource you were accessing could not be found.

A message providing additional information about the error, including details to help resolve it when possible.

request_id string optional
Example: 4d9d8375-3c56-4925-a3e7-eb137fed17e9

Optionally, some endpoints may include a request ID that should be provided when reporting bugs or opening support tickets to help identify the issue.

502

The backing agent config service returned an unexpected error.

ratelimit-limit integer

The default limit on number of requests that can be made per hour and per minute. Current rate limits are 5000 requests per hour and 250 requests per minute.

ratelimit-remaining integer

The number of requests in your hourly quota that remain before you hit your request limit. See https://docs.digitalocean.com/reference/api/reference/#rate-limit for information about how requests expire.

ratelimit-reset integer

The time when the oldest request will expire. The value is given in Unix epoch time. See https://docs.digitalocean.com/reference/api/reference/#rate-limit for information about how requests expire.

id string required
Example: not_found

A short identifier corresponding to the HTTP status code returned. For example, the ID for a response returning a 404 status code would be "not_found."

message string required
Example: The resource you were accessing could not be found.

A message providing additional information about the error, including details to help resolve it when possible.

request_id string optional
Example: 4d9d8375-3c56-4925-a3e7-eb137fed17e9

Optionally, some endpoints may include a request ID that should be provided when reporting bugs or opening support tickets to help identify the issue.

503

An upstream dependency needed to validate the trigger is temporarily unavailable; retry.

ratelimit-limit integer

The default limit on number of requests that can be made per hour and per minute. Current rate limits are 5000 requests per hour and 250 requests per minute.

ratelimit-remaining integer

The number of requests in your hourly quota that remain before you hit your request limit. See https://docs.digitalocean.com/reference/api/reference/#rate-limit for information about how requests expire.

ratelimit-reset integer

The time when the oldest request will expire. The value is given in Unix epoch time. See https://docs.digitalocean.com/reference/api/reference/#rate-limit for information about how requests expire.

id string required
Example: not_found

A short identifier corresponding to the HTTP status code returned. For example, the ID for a response returning a 404 status code would be "not_found."

message string required
Example: The resource you were accessing could not be found.

A message providing additional information about the error, including details to help resolve it when possible.

request_id string optional
Example: 4d9d8375-3c56-4925-a3e7-eb137fed17e9

Optionally, some endpoints may include a request ID that should be provided when reporting bugs or opening support tickets to help identify the issue.

default

There was an unexpected error.

ratelimit-limit integer

The default limit on number of requests that can be made per hour and per minute. Current rate limits are 5000 requests per hour and 250 requests per minute.

ratelimit-remaining integer

The number of requests in your hourly quota that remain before you hit your request limit. See https://docs.digitalocean.com/reference/api/reference/#rate-limit for information about how requests expire.

ratelimit-reset integer

The time when the oldest request will expire. The value is given in Unix epoch time. See https://docs.digitalocean.com/reference/api/reference/#rate-limit for information about how requests expire.

id string required
Example: not_found

A short identifier corresponding to the HTTP status code returned. For example, the ID for a response returning a 404 status code would be "not_found."

message string required
Example: The resource you were accessing could not be found.

A message providing additional information about the error, including details to help resolve it when possible.

request_id string optional
Example: 4d9d8375-3c56-4925-a3e7-eb137fed17e9

Optionally, some endpoints may include a request ID that should be provided when reporting bugs or opening support tickets to help identify the issue.

{
  "trigger": {
    "agent_kind": "AGENT_KIND_UNSPECIFIED",
    "bound_session_id": "a1b2c3d4-e5f6-7890-abcd-ef1234567890",
    "created_at": "2026-07-27T12:00:00Z",
    "cron": {
      "cron_expr": "0 9 * * 1-5",
      "next_run_at": "2026-07-27T13:00:00Z",
      "timezone": "America/New_York"
    },
    "kind": "webhook",
    "name": "nightly-deploy-check",
    "output": {
      "email_configured": true,
      "mode": "email",
      "slack_configured": false
    },
    "prompt_template": "Review the latest push and summarize risks.",
    "session_mode": "fresh",
    "session_template": "",
    "status": "active",
    "trigger_id": "b1a0c6de-1f2e-4a3b-9c8d-0e1f2a3b4c5d",
    "updated_at": "2026-07-27T12:00:00Z",
    "webhook": {
      "provider": "github",
      "webhook_url": "https://api.digitalocean.com/v2/agents/triggers/b1a0.../webhook"
    }
  }
}
{
  "id": "not_found",
  "message": "The resource you were accessing could not be found.",
  "request_id": "4d9d8375-3c56-4925-a3e7-eb137fed17e9"
}
{
  "id": "unauthorized",
  "message": "Unable to authenticate you."
}
{
  "id": "not_found",
  "message": "The resource you were accessing could not be found.",
  "request_id": "4d9d8375-3c56-4925-a3e7-eb137fed17e9"
}
{
  "id": "not_found",
  "message": "The resource you requested could not be found."
}
{
  "id": "not_found",
  "message": "The resource you were accessing could not be found.",
  "request_id": "4d9d8375-3c56-4925-a3e7-eb137fed17e9"
}
{
  "id": "not_found",
  "message": "The resource you were accessing could not be found.",
  "request_id": "4d9d8375-3c56-4925-a3e7-eb137fed17e9"
}
{
  "id": "too_many_requests",
  "message": "API rate limit exceeded."
}
{
  "id": "server_error",
  "message": "Unexpected server-side error"
}
{
  "id": "not_found",
  "message": "The resource you were accessing could not be found.",
  "request_id": "4d9d8375-3c56-4925-a3e7-eb137fed17e9"
}
{
  "id": "not_found",
  "message": "The resource you were accessing could not be found.",
  "request_id": "4d9d8375-3c56-4925-a3e7-eb137fed17e9"
}
{
  "id": "example_error",
  "message": "some error message"
}

DELETE DeleteTrigger soft-deletes a trigger.

/v2/agents/triggers/{trigger_id}
Authorizations: bearer_auth (1 scope)
Http: Bearer
Required scopes: agent_harness_session:manage

OAuth Authentication

In order to interact with the DigitalOcean API, you or your application must authenticate.

The DigitalOcean API handles this through OAuth, an open standard for authorization. OAuth allows you to delegate access to your account. Scopes can be used to grant full access, read-only access, or access to a specific set of endpoints.

You can generate an OAuth token by visiting the Apps & API section of the DigitalOcean control panel for your account.

An OAuth token functions as a complete authentication request. In effect, it acts as a substitute for a username and password pair.

Because of this, it is absolutely essential that you keep your OAuth tokens secure. In fact, upon generation, the web interface will only display each token a single time in order to prevent the token from being compromised.

DigitalOcean access tokens begin with an identifiable prefix in order to distinguish them from other similar tokens.

  • dop_v1_ for personal access tokens generated in the control panel
  • doo_v1_ for tokens generated by applications using the OAuth flow
  • dor_v1_ for OAuth refresh tokens

Scopes

Scopes act like permissions assigned to an API token. These permissions determine what actions the token can perform. You can create API tokens that grant read-only access, full access, or limited access to specific endpoints by using custom scopes.

Generally, scopes are designed to match HTTP verbs and common CRUD operations (Create, Read, Update, Delete).

HTTP Verb CRUD Operation Scope
GET Read <resource>:read
POST Create <resource>:create
PUT/PATCH Update <resource>:update
DELETE Delete <resource>:delete

For example, creating a new Droplet by making a POST request to the /v2/droplets endpoint requires the droplet:create scope while listing Droplets by making a GET request to the /v2/droplets endpoint requires the droplet:read scope.

Each endpoint below specifies which scope is required to access it when using custom scopes.

How to Authenticate with OAuth

In order to make an authenticated request, include a bearer-type Authorization header containing your OAuth token. All requests must be made over HTTPS.

Authenticate with a Bearer Authorization Header

curl -X $HTTP_METHOD -H "Authorization: Bearer $DIGITALOCEAN_TOKEN" "https://api.digitalocean.com/v2/$OBJECT"

Marks the trigger deleted, fails any pending executions, and purges the webhook secret / cron schedule. A fresh trigger owns no session; a reuse trigger only UNBINDS - it never destroys the customer's session. Execution history and by-session lookups continue to resolve to the deleted row. Returns 204 No Content on success.

Path Parameters

trigger_id string required
Example: b1a0c6de-1f2e-4a3b-9c8d-0e1f2a3b4c5d

The trigger UUID.

curl -X DELETE \
  -H "Content-Type: application/json" \
  -H "Authorization: Bearer $DIGITALOCEAN_TOKEN" \
  "https://api.digitalocean.com/v2/agents/triggers/{trigger_id}"
curl -X DELETE \
  -H "Authorization: Bearer $API_TOKEN" \
  "https://api.digitalocean.com/v2/agents/triggers/{trigger_id}"

Responses

204

Trigger deleted; no response body.

ratelimit-limit integer

The default limit on number of requests that can be made per hour and per minute. Current rate limits are 5000 requests per hour and 250 requests per minute.

ratelimit-remaining integer

The number of requests in your hourly quota that remain before you hit your request limit. See https://docs.digitalocean.com/reference/api/reference/#rate-limit for information about how requests expire.

ratelimit-reset integer

The time when the oldest request will expire. The value is given in Unix epoch time. See https://docs.digitalocean.com/reference/api/reference/#rate-limit for information about how requests expire.

401

Authentication failed due to invalid credentials.

ratelimit-limit integer

The default limit on number of requests that can be made per hour and per minute. Current rate limits are 5000 requests per hour and 250 requests per minute.

ratelimit-remaining integer

The number of requests in your hourly quota that remain before you hit your request limit. See https://docs.digitalocean.com/reference/api/reference/#rate-limit for information about how requests expire.

ratelimit-reset integer

The time when the oldest request will expire. The value is given in Unix epoch time. See https://docs.digitalocean.com/reference/api/reference/#rate-limit for information about how requests expire.

id string required
Example: not_found

A short identifier corresponding to the HTTP status code returned. For example, the ID for a response returning a 404 status code would be "not_found."

message string required
Example: The resource you were accessing could not be found.

A message providing additional information about the error, including details to help resolve it when possible.

request_id string optional
Example: 4d9d8375-3c56-4925-a3e7-eb137fed17e9

Optionally, some endpoints may include a request ID that should be provided when reporting bugs or opening support tickets to help identify the issue.

404

The resource was not found.

ratelimit-limit integer

The default limit on number of requests that can be made per hour and per minute. Current rate limits are 5000 requests per hour and 250 requests per minute.

ratelimit-remaining integer

The number of requests in your hourly quota that remain before you hit your request limit. See https://docs.digitalocean.com/reference/api/reference/#rate-limit for information about how requests expire.

ratelimit-reset integer

The time when the oldest request will expire. The value is given in Unix epoch time. See https://docs.digitalocean.com/reference/api/reference/#rate-limit for information about how requests expire.

id string required
Example: not_found

A short identifier corresponding to the HTTP status code returned. For example, the ID for a response returning a 404 status code would be "not_found."

message string required
Example: The resource you were accessing could not be found.

A message providing additional information about the error, including details to help resolve it when possible.

request_id string optional
Example: 4d9d8375-3c56-4925-a3e7-eb137fed17e9

Optionally, some endpoints may include a request ID that should be provided when reporting bugs or opening support tickets to help identify the issue.

429

The API rate limit has been exceeded.

ratelimit-limit integer

The default limit on number of requests that can be made per hour and per minute. Current rate limits are 5000 requests per hour and 250 requests per minute.

ratelimit-remaining integer

The number of requests in your hourly quota that remain before you hit your request limit. See https://docs.digitalocean.com/reference/api/reference/#rate-limit for information about how requests expire.

ratelimit-reset integer

The time when the oldest request will expire. The value is given in Unix epoch time. See https://docs.digitalocean.com/reference/api/reference/#rate-limit for information about how requests expire.

id string required
Example: not_found

A short identifier corresponding to the HTTP status code returned. For example, the ID for a response returning a 404 status code would be "not_found."

message string required
Example: The resource you were accessing could not be found.

A message providing additional information about the error, including details to help resolve it when possible.

request_id string optional
Example: 4d9d8375-3c56-4925-a3e7-eb137fed17e9

Optionally, some endpoints may include a request ID that should be provided when reporting bugs or opening support tickets to help identify the issue.

500

There was a server error.

ratelimit-limit integer

The default limit on number of requests that can be made per hour and per minute. Current rate limits are 5000 requests per hour and 250 requests per minute.

ratelimit-remaining integer

The number of requests in your hourly quota that remain before you hit your request limit. See https://docs.digitalocean.com/reference/api/reference/#rate-limit for information about how requests expire.

ratelimit-reset integer

The time when the oldest request will expire. The value is given in Unix epoch time. See https://docs.digitalocean.com/reference/api/reference/#rate-limit for information about how requests expire.

id string required
Example: not_found

A short identifier corresponding to the HTTP status code returned. For example, the ID for a response returning a 404 status code would be "not_found."

message string required
Example: The resource you were accessing could not be found.

A message providing additional information about the error, including details to help resolve it when possible.

request_id string optional
Example: 4d9d8375-3c56-4925-a3e7-eb137fed17e9

Optionally, some endpoints may include a request ID that should be provided when reporting bugs or opening support tickets to help identify the issue.

default

There was an unexpected error.

ratelimit-limit integer

The default limit on number of requests that can be made per hour and per minute. Current rate limits are 5000 requests per hour and 250 requests per minute.

ratelimit-remaining integer

The number of requests in your hourly quota that remain before you hit your request limit. See https://docs.digitalocean.com/reference/api/reference/#rate-limit for information about how requests expire.

ratelimit-reset integer

The time when the oldest request will expire. The value is given in Unix epoch time. See https://docs.digitalocean.com/reference/api/reference/#rate-limit for information about how requests expire.

id string required
Example: not_found

A short identifier corresponding to the HTTP status code returned. For example, the ID for a response returning a 404 status code would be "not_found."

message string required
Example: The resource you were accessing could not be found.

A message providing additional information about the error, including details to help resolve it when possible.

request_id string optional
Example: 4d9d8375-3c56-4925-a3e7-eb137fed17e9

Optionally, some endpoints may include a request ID that should be provided when reporting bugs or opening support tickets to help identify the issue.

{
  "id": "unauthorized",
  "message": "Unable to authenticate you."
}
{
  "id": "not_found",
  "message": "The resource you requested could not be found."
}
{
  "id": "too_many_requests",
  "message": "API rate limit exceeded."
}
{
  "id": "server_error",
  "message": "Unexpected server-side error"
}
{
  "id": "example_error",
  "message": "some error message"
}

GET ListTriggerExecutions returns a trigger's execution history.

/v2/agents/triggers/{trigger_id}/executions
Authorizations: bearer_auth (1 scope)
Http: Bearer
Required scopes: agent_harness_session:read

OAuth Authentication

In order to interact with the DigitalOcean API, you or your application must authenticate.

The DigitalOcean API handles this through OAuth, an open standard for authorization. OAuth allows you to delegate access to your account. Scopes can be used to grant full access, read-only access, or access to a specific set of endpoints.

You can generate an OAuth token by visiting the Apps & API section of the DigitalOcean control panel for your account.

An OAuth token functions as a complete authentication request. In effect, it acts as a substitute for a username and password pair.

Because of this, it is absolutely essential that you keep your OAuth tokens secure. In fact, upon generation, the web interface will only display each token a single time in order to prevent the token from being compromised.

DigitalOcean access tokens begin with an identifiable prefix in order to distinguish them from other similar tokens.

  • dop_v1_ for personal access tokens generated in the control panel
  • doo_v1_ for tokens generated by applications using the OAuth flow
  • dor_v1_ for OAuth refresh tokens

Scopes

Scopes act like permissions assigned to an API token. These permissions determine what actions the token can perform. You can create API tokens that grant read-only access, full access, or limited access to specific endpoints by using custom scopes.

Generally, scopes are designed to match HTTP verbs and common CRUD operations (Create, Read, Update, Delete).

HTTP Verb CRUD Operation Scope
GET Read <resource>:read
POST Create <resource>:create
PUT/PATCH Update <resource>:update
DELETE Delete <resource>:delete

For example, creating a new Droplet by making a POST request to the /v2/droplets endpoint requires the droplet:create scope while listing Droplets by making a GET request to the /v2/droplets endpoint requires the droplet:read scope.

Each endpoint below specifies which scope is required to access it when using custom scopes.

How to Authenticate with OAuth

In order to make an authenticated request, include a bearer-type Authorization header containing your OAuth token. All requests must be made over HTTPS.

Authenticate with a Bearer Authorization Header

curl -X $HTTP_METHOD -H "Authorization: Bearer $DIGITALOCEAN_TOKEN" "https://api.digitalocean.com/v2/$OBJECT"

Keyset-paginated. The large payload field is omitted from list items; fetch a single execution to read it.

Path Parameters

trigger_id string required
Example: b1a0c6de-1f2e-4a3b-9c8d-0e1f2a3b4c5d

The trigger UUID.

Query Parameters

page_size integer (int32) >= 1 optional
Example: 50

Page size. Defaults to 50 when omitted or non-positive; server-clamped.

page_token string optional

Opaque keyset cursor returned by the previous page. Empty starts from the beginning.

status string, one of: pending, running, succeeded, failed optional
Example: succeeded

Optional filter by execution status.

curl -X GET \
  -H "Content-Type: application/json" \
  -H "Authorization: Bearer $DIGITALOCEAN_TOKEN" \
  "https://api.digitalocean.com/v2/agents/triggers/{trigger_id}/executions?page_size=50"
curl -X GET \
  -H "Authorization: Bearer $API_TOKEN" \
  "https://api.digitalocean.com/v2/agents/triggers/{trigger_id}/executions"

Responses

200

A successful response.

ratelimit-limit integer

The default limit on number of requests that can be made per hour and per minute. Current rate limits are 5000 requests per hour and 250 requests per minute.

ratelimit-remaining integer

The number of requests in your hourly quota that remain before you hit your request limit. See https://docs.digitalocean.com/reference/api/reference/#rate-limit for information about how requests expire.

ratelimit-reset integer

The time when the oldest request will expire. The value is given in Unix epoch time. See https://docs.digitalocean.com/reference/api/reference/#rate-limit for information about how requests expire.

executions array of object optional
Show child properties
created_at string (date-time) optional
Example: 2026-07-27T12:00:00Z
execution_id string optional
Example: 7c1f9e2a-3b4c-5d6e-7f80-91a2b3c4d5e6
failure_reason string optional

Client-safe reason when status=failed; absent otherwise. One of a fixed set of messages; do not parse it or match on substrings. Quote the execution_id when contacting support.

output_text string optional

The doctl-parity transcript rendered from the run's SPI events. Returned by GetTriggerExecution only; omitted from list items.

output_truncated boolean optional
Example: false

True when output_text is incomplete. Returned by GetTriggerExecution only; omitted from list items.

payload string optional

The raw webhook body or cron tick metadata. Returned by GetTriggerExecution only; omitted from list items. Cleared for terminal executions after the payload retention window (default 7 days from creation).

run_id string optional

Populated once SendInput acks; correlation/audit only. May be empty.

session_id string optional
Example: a1b2c3d4-e5f6-7890-abcd-ef1234567890

The run's session. Populated once the session is created (fresh) or is known (reuse); empty before then.

status string, one of: pending, running, succeeded, failed optional
Example: succeeded

Per-firing outcome.

trigger_id string optional
Example: b1a0c6de-1f2e-4a3b-9c8d-0e1f2a3b4c5d
updated_at string (date-time) optional
Example: 2026-07-27T12:00:05Z
next_page_token string optional

Opaque cursor for the next page. Empty when there are no further pages.

401

Authentication failed due to invalid credentials.

ratelimit-limit integer

The default limit on number of requests that can be made per hour and per minute. Current rate limits are 5000 requests per hour and 250 requests per minute.

ratelimit-remaining integer

The number of requests in your hourly quota that remain before you hit your request limit. See https://docs.digitalocean.com/reference/api/reference/#rate-limit for information about how requests expire.

ratelimit-reset integer

The time when the oldest request will expire. The value is given in Unix epoch time. See https://docs.digitalocean.com/reference/api/reference/#rate-limit for information about how requests expire.

id string required
Example: not_found

A short identifier corresponding to the HTTP status code returned. For example, the ID for a response returning a 404 status code would be "not_found."

message string required
Example: The resource you were accessing could not be found.

A message providing additional information about the error, including details to help resolve it when possible.

request_id string optional
Example: 4d9d8375-3c56-4925-a3e7-eb137fed17e9

Optionally, some endpoints may include a request ID that should be provided when reporting bugs or opening support tickets to help identify the issue.

404

The resource was not found.

ratelimit-limit integer

The default limit on number of requests that can be made per hour and per minute. Current rate limits are 5000 requests per hour and 250 requests per minute.

ratelimit-remaining integer

The number of requests in your hourly quota that remain before you hit your request limit. See https://docs.digitalocean.com/reference/api/reference/#rate-limit for information about how requests expire.

ratelimit-reset integer

The time when the oldest request will expire. The value is given in Unix epoch time. See https://docs.digitalocean.com/reference/api/reference/#rate-limit for information about how requests expire.

id string required
Example: not_found

A short identifier corresponding to the HTTP status code returned. For example, the ID for a response returning a 404 status code would be "not_found."

message string required
Example: The resource you were accessing could not be found.

A message providing additional information about the error, including details to help resolve it when possible.

request_id string optional
Example: 4d9d8375-3c56-4925-a3e7-eb137fed17e9

Optionally, some endpoints may include a request ID that should be provided when reporting bugs or opening support tickets to help identify the issue.

429

The API rate limit has been exceeded.

ratelimit-limit integer

The default limit on number of requests that can be made per hour and per minute. Current rate limits are 5000 requests per hour and 250 requests per minute.

ratelimit-remaining integer

The number of requests in your hourly quota that remain before you hit your request limit. See https://docs.digitalocean.com/reference/api/reference/#rate-limit for information about how requests expire.

ratelimit-reset integer

The time when the oldest request will expire. The value is given in Unix epoch time. See https://docs.digitalocean.com/reference/api/reference/#rate-limit for information about how requests expire.

id string required
Example: not_found

A short identifier corresponding to the HTTP status code returned. For example, the ID for a response returning a 404 status code would be "not_found."

message string required
Example: The resource you were accessing could not be found.

A message providing additional information about the error, including details to help resolve it when possible.

request_id string optional
Example: 4d9d8375-3c56-4925-a3e7-eb137fed17e9

Optionally, some endpoints may include a request ID that should be provided when reporting bugs or opening support tickets to help identify the issue.

500

There was a server error.

ratelimit-limit integer

The default limit on number of requests that can be made per hour and per minute. Current rate limits are 5000 requests per hour and 250 requests per minute.

ratelimit-remaining integer

The number of requests in your hourly quota that remain before you hit your request limit. See https://docs.digitalocean.com/reference/api/reference/#rate-limit for information about how requests expire.

ratelimit-reset integer

The time when the oldest request will expire. The value is given in Unix epoch time. See https://docs.digitalocean.com/reference/api/reference/#rate-limit for information about how requests expire.

id string required
Example: not_found

A short identifier corresponding to the HTTP status code returned. For example, the ID for a response returning a 404 status code would be "not_found."

message string required
Example: The resource you were accessing could not be found.

A message providing additional information about the error, including details to help resolve it when possible.

request_id string optional
Example: 4d9d8375-3c56-4925-a3e7-eb137fed17e9

Optionally, some endpoints may include a request ID that should be provided when reporting bugs or opening support tickets to help identify the issue.

default

There was an unexpected error.

ratelimit-limit integer

The default limit on number of requests that can be made per hour and per minute. Current rate limits are 5000 requests per hour and 250 requests per minute.

ratelimit-remaining integer

The number of requests in your hourly quota that remain before you hit your request limit. See https://docs.digitalocean.com/reference/api/reference/#rate-limit for information about how requests expire.

ratelimit-reset integer

The time when the oldest request will expire. The value is given in Unix epoch time. See https://docs.digitalocean.com/reference/api/reference/#rate-limit for information about how requests expire.

id string required
Example: not_found

A short identifier corresponding to the HTTP status code returned. For example, the ID for a response returning a 404 status code would be "not_found."

message string required
Example: The resource you were accessing could not be found.

A message providing additional information about the error, including details to help resolve it when possible.

request_id string optional
Example: 4d9d8375-3c56-4925-a3e7-eb137fed17e9

Optionally, some endpoints may include a request ID that should be provided when reporting bugs or opening support tickets to help identify the issue.

{
  "executions": [
    {
      "created_at": "2026-07-27T12:00:00Z",
      "execution_id": "7c1f9e2a-3b4c-5d6e-7f80-91a2b3c4d5e6",
      "failure_reason": "",
      "output_text": "",
      "output_truncated": false,
      "payload": "",
      "run_id": "",
      "session_id": "a1b2c3d4-e5f6-7890-abcd-ef1234567890",
      "status": "succeeded",
      "trigger_id": "b1a0c6de-1f2e-4a3b-9c8d-0e1f2a3b4c5d",
      "updated_at": "2026-07-27T12:00:05Z"
    }
  ],
  "next_page_token": ""
}
{
  "id": "unauthorized",
  "message": "Unable to authenticate you."
}
{
  "id": "not_found",
  "message": "The resource you requested could not be found."
}
{
  "id": "too_many_requests",
  "message": "API rate limit exceeded."
}
{
  "id": "server_error",
  "message": "Unexpected server-side error"
}
{
  "id": "example_error",
  "message": "some error message"
}

GET GetTriggerExecution returns a single execution, including its payload.

/v2/agents/triggers/{trigger_id}/executions/{execution_id}
Authorizations: bearer_auth (1 scope)
Http: Bearer
Required scopes: agent_harness_session:read

OAuth Authentication

In order to interact with the DigitalOcean API, you or your application must authenticate.

The DigitalOcean API handles this through OAuth, an open standard for authorization. OAuth allows you to delegate access to your account. Scopes can be used to grant full access, read-only access, or access to a specific set of endpoints.

You can generate an OAuth token by visiting the Apps & API section of the DigitalOcean control panel for your account.

An OAuth token functions as a complete authentication request. In effect, it acts as a substitute for a username and password pair.

Because of this, it is absolutely essential that you keep your OAuth tokens secure. In fact, upon generation, the web interface will only display each token a single time in order to prevent the token from being compromised.

DigitalOcean access tokens begin with an identifiable prefix in order to distinguish them from other similar tokens.

  • dop_v1_ for personal access tokens generated in the control panel
  • doo_v1_ for tokens generated by applications using the OAuth flow
  • dor_v1_ for OAuth refresh tokens

Scopes

Scopes act like permissions assigned to an API token. These permissions determine what actions the token can perform. You can create API tokens that grant read-only access, full access, or limited access to specific endpoints by using custom scopes.

Generally, scopes are designed to match HTTP verbs and common CRUD operations (Create, Read, Update, Delete).

HTTP Verb CRUD Operation Scope
GET Read <resource>:read
POST Create <resource>:create
PUT/PATCH Update <resource>:update
DELETE Delete <resource>:delete

For example, creating a new Droplet by making a POST request to the /v2/droplets endpoint requires the droplet:create scope while listing Droplets by making a GET request to the /v2/droplets endpoint requires the droplet:read scope.

Each endpoint below specifies which scope is required to access it when using custom scopes.

How to Authenticate with OAuth

In order to make an authenticated request, include a bearer-type Authorization header containing your OAuth token. All requests must be made over HTTPS.

Authenticate with a Bearer Authorization Header

curl -X $HTTP_METHOD -H "Authorization: Bearer $DIGITALOCEAN_TOKEN" "https://api.digitalocean.com/v2/$OBJECT"

Returns the full execution row, including the payload, output_text, and output_truncated fields omitted from list items.

Path Parameters

trigger_id string required
Example: b1a0c6de-1f2e-4a3b-9c8d-0e1f2a3b4c5d

The trigger UUID.

execution_id string required
Example: 7c1f9e2a-3b4c-5d6e-7f80-91a2b3c4d5e6

The execution UUID.

curl -X GET \
  -H "Content-Type: application/json" \
  -H "Authorization: Bearer $DIGITALOCEAN_TOKEN" \
  "https://api.digitalocean.com/v2/agents/triggers/{trigger_id}/executions/{execution_id}"
curl -X GET \
  -H "Authorization: Bearer $API_TOKEN" \
  "https://api.digitalocean.com/v2/agents/triggers/{trigger_id}/executions/{execution_id}"

Responses

200

A successful response.

ratelimit-limit integer

The default limit on number of requests that can be made per hour and per minute. Current rate limits are 5000 requests per hour and 250 requests per minute.

ratelimit-remaining integer

The number of requests in your hourly quota that remain before you hit your request limit. See https://docs.digitalocean.com/reference/api/reference/#rate-limit for information about how requests expire.

ratelimit-reset integer

The time when the oldest request will expire. The value is given in Unix epoch time. See https://docs.digitalocean.com/reference/api/reference/#rate-limit for information about how requests expire.

execution object optional

One row per firing (webhook delivery or cron tick).

Show child properties
created_at string (date-time) optional
Example: 2026-07-27T12:00:00Z
execution_id string optional
Example: 7c1f9e2a-3b4c-5d6e-7f80-91a2b3c4d5e6
failure_reason string optional

Client-safe reason when status=failed; absent otherwise. One of a fixed set of messages; do not parse it or match on substrings. Quote the execution_id when contacting support.

output_text string optional

The doctl-parity transcript rendered from the run's SPI events. Returned by GetTriggerExecution only; omitted from list items.

output_truncated boolean optional
Example: false

True when output_text is incomplete. Returned by GetTriggerExecution only; omitted from list items.

payload string optional

The raw webhook body or cron tick metadata. Returned by GetTriggerExecution only; omitted from list items. Cleared for terminal executions after the payload retention window (default 7 days from creation).

run_id string optional

Populated once SendInput acks; correlation/audit only. May be empty.

session_id string optional
Example: a1b2c3d4-e5f6-7890-abcd-ef1234567890

The run's session. Populated once the session is created (fresh) or is known (reuse); empty before then.

status string, one of: pending, running, succeeded, failed optional
Example: succeeded

Per-firing outcome.

trigger_id string optional
Example: b1a0c6de-1f2e-4a3b-9c8d-0e1f2a3b4c5d
updated_at string (date-time) optional
Example: 2026-07-27T12:00:05Z
401

Authentication failed due to invalid credentials.

ratelimit-limit integer

The default limit on number of requests that can be made per hour and per minute. Current rate limits are 5000 requests per hour and 250 requests per minute.

ratelimit-remaining integer

The number of requests in your hourly quota that remain before you hit your request limit. See https://docs.digitalocean.com/reference/api/reference/#rate-limit for information about how requests expire.

ratelimit-reset integer

The time when the oldest request will expire. The value is given in Unix epoch time. See https://docs.digitalocean.com/reference/api/reference/#rate-limit for information about how requests expire.

id string required
Example: not_found

A short identifier corresponding to the HTTP status code returned. For example, the ID for a response returning a 404 status code would be "not_found."

message string required
Example: The resource you were accessing could not be found.

A message providing additional information about the error, including details to help resolve it when possible.

request_id string optional
Example: 4d9d8375-3c56-4925-a3e7-eb137fed17e9

Optionally, some endpoints may include a request ID that should be provided when reporting bugs or opening support tickets to help identify the issue.

404

The resource was not found.

ratelimit-limit integer

The default limit on number of requests that can be made per hour and per minute. Current rate limits are 5000 requests per hour and 250 requests per minute.

ratelimit-remaining integer

The number of requests in your hourly quota that remain before you hit your request limit. See https://docs.digitalocean.com/reference/api/reference/#rate-limit for information about how requests expire.

ratelimit-reset integer

The time when the oldest request will expire. The value is given in Unix epoch time. See https://docs.digitalocean.com/reference/api/reference/#rate-limit for information about how requests expire.

id string required
Example: not_found

A short identifier corresponding to the HTTP status code returned. For example, the ID for a response returning a 404 status code would be "not_found."

message string required
Example: The resource you were accessing could not be found.

A message providing additional information about the error, including details to help resolve it when possible.

request_id string optional
Example: 4d9d8375-3c56-4925-a3e7-eb137fed17e9

Optionally, some endpoints may include a request ID that should be provided when reporting bugs or opening support tickets to help identify the issue.

429

The API rate limit has been exceeded.

ratelimit-limit integer

The default limit on number of requests that can be made per hour and per minute. Current rate limits are 5000 requests per hour and 250 requests per minute.

ratelimit-remaining integer

The number of requests in your hourly quota that remain before you hit your request limit. See https://docs.digitalocean.com/reference/api/reference/#rate-limit for information about how requests expire.

ratelimit-reset integer

The time when the oldest request will expire. The value is given in Unix epoch time. See https://docs.digitalocean.com/reference/api/reference/#rate-limit for information about how requests expire.

id string required
Example: not_found

A short identifier corresponding to the HTTP status code returned. For example, the ID for a response returning a 404 status code would be "not_found."

message string required
Example: The resource you were accessing could not be found.

A message providing additional information about the error, including details to help resolve it when possible.

request_id string optional
Example: 4d9d8375-3c56-4925-a3e7-eb137fed17e9

Optionally, some endpoints may include a request ID that should be provided when reporting bugs or opening support tickets to help identify the issue.

500

There was a server error.

ratelimit-limit integer

The default limit on number of requests that can be made per hour and per minute. Current rate limits are 5000 requests per hour and 250 requests per minute.

ratelimit-remaining integer

The number of requests in your hourly quota that remain before you hit your request limit. See https://docs.digitalocean.com/reference/api/reference/#rate-limit for information about how requests expire.

ratelimit-reset integer

The time when the oldest request will expire. The value is given in Unix epoch time. See https://docs.digitalocean.com/reference/api/reference/#rate-limit for information about how requests expire.

id string required
Example: not_found

A short identifier corresponding to the HTTP status code returned. For example, the ID for a response returning a 404 status code would be "not_found."

message string required
Example: The resource you were accessing could not be found.

A message providing additional information about the error, including details to help resolve it when possible.

request_id string optional
Example: 4d9d8375-3c56-4925-a3e7-eb137fed17e9

Optionally, some endpoints may include a request ID that should be provided when reporting bugs or opening support tickets to help identify the issue.

default

There was an unexpected error.

ratelimit-limit integer

The default limit on number of requests that can be made per hour and per minute. Current rate limits are 5000 requests per hour and 250 requests per minute.

ratelimit-remaining integer

The number of requests in your hourly quota that remain before you hit your request limit. See https://docs.digitalocean.com/reference/api/reference/#rate-limit for information about how requests expire.

ratelimit-reset integer

The time when the oldest request will expire. The value is given in Unix epoch time. See https://docs.digitalocean.com/reference/api/reference/#rate-limit for information about how requests expire.

id string required
Example: not_found

A short identifier corresponding to the HTTP status code returned. For example, the ID for a response returning a 404 status code would be "not_found."

message string required
Example: The resource you were accessing could not be found.

A message providing additional information about the error, including details to help resolve it when possible.

request_id string optional
Example: 4d9d8375-3c56-4925-a3e7-eb137fed17e9

Optionally, some endpoints may include a request ID that should be provided when reporting bugs or opening support tickets to help identify the issue.

{
  "execution": {
    "created_at": "2026-07-27T12:00:00Z",
    "execution_id": "7c1f9e2a-3b4c-5d6e-7f80-91a2b3c4d5e6",
    "failure_reason": "",
    "output_text": "",
    "output_truncated": false,
    "payload": "",
    "run_id": "",
    "session_id": "a1b2c3d4-e5f6-7890-abcd-ef1234567890",
    "status": "succeeded",
    "trigger_id": "b1a0c6de-1f2e-4a3b-9c8d-0e1f2a3b4c5d",
    "updated_at": "2026-07-27T12:00:05Z"
  }
}
{
  "id": "unauthorized",
  "message": "Unable to authenticate you."
}
{
  "id": "not_found",
  "message": "The resource you requested could not be found."
}
{
  "id": "too_many_requests",
  "message": "API rate limit exceeded."
}
{
  "id": "server_error",
  "message": "Unexpected server-side error"
}
{
  "id": "example_error",
  "message": "some error message"
}

POST CancelExecution ends a running execution and frees the trigger's in-flight slot.

/v2/agents/triggers/{trigger_id}/executions/{execution_id}/cancel
Authorizations: bearer_auth (1 scope)
Http: Bearer
Required scopes: agent_harness_session:operate

OAuth Authentication

In order to interact with the DigitalOcean API, you or your application must authenticate.

The DigitalOcean API handles this through OAuth, an open standard for authorization. OAuth allows you to delegate access to your account. Scopes can be used to grant full access, read-only access, or access to a specific set of endpoints.

You can generate an OAuth token by visiting the Apps & API section of the DigitalOcean control panel for your account.

An OAuth token functions as a complete authentication request. In effect, it acts as a substitute for a username and password pair.

Because of this, it is absolutely essential that you keep your OAuth tokens secure. In fact, upon generation, the web interface will only display each token a single time in order to prevent the token from being compromised.

DigitalOcean access tokens begin with an identifiable prefix in order to distinguish them from other similar tokens.

  • dop_v1_ for personal access tokens generated in the control panel
  • doo_v1_ for tokens generated by applications using the OAuth flow
  • dor_v1_ for OAuth refresh tokens

Scopes

Scopes act like permissions assigned to an API token. These permissions determine what actions the token can perform. You can create API tokens that grant read-only access, full access, or limited access to specific endpoints by using custom scopes.

Generally, scopes are designed to match HTTP verbs and common CRUD operations (Create, Read, Update, Delete).

HTTP Verb CRUD Operation Scope
GET Read <resource>:read
POST Create <resource>:create
PUT/PATCH Update <resource>:update
DELETE Delete <resource>:delete

For example, creating a new Droplet by making a POST request to the /v2/droplets endpoint requires the droplet:create scope while listing Droplets by making a GET request to the /v2/droplets endpoint requires the droplet:read scope.

Each endpoint below specifies which scope is required to access it when using custom scopes.

How to Authenticate with OAuth

In order to make an authenticated request, include a bearer-type Authorization header containing your OAuth token. All requests must be made over HTTPS.

Authenticate with a Bearer Authorization Header

curl -X $HTTP_METHOD -H "Authorization: Bearer $DIGITALOCEAN_TOKEN" "https://api.digitalocean.com/v2/$OBJECT"

Fails the execution and frees the trigger's in-flight slot. A fresh-mode session is destroyed outright. A reuse-mode session is only paused, not stopped - harness has no run-interrupt call, so the agent's turn may still be in flight server-side; this frees the queue, not necessarily the agent's work. A non-running execution is a no-op that still returns 200.

Path Parameters

trigger_id string required
Example: b1a0c6de-1f2e-4a3b-9c8d-0e1f2a3b4c5d

The trigger UUID.

execution_id string required
Example: 7c1f9e2a-3b4c-5d6e-7f80-91a2b3c4d5e6

The execution UUID.

Query Parameters

force boolean optional
Example: false

Cancel even if the execution has not started a run yet (the worker's own dispatch may still be in flight). Without this, that case returns 409; reclaim clears it automatically within 15m regardless.

curl -X POST \
  -H "Content-Type: application/json" \
  -H "Authorization: Bearer $DIGITALOCEAN_TOKEN" \
  "https://api.digitalocean.com/v2/agents/triggers/{trigger_id}/executions/{execution_id}/cancel"
curl -X POST \
  -H "Authorization: Bearer $API_TOKEN" \
  -H "Content-Type: application/json" \
  "https://api.digitalocean.com/v2/agents/triggers/{trigger_id}/executions/{execution_id}/cancel"

Responses

200

A successful response.

ratelimit-limit integer

The default limit on number of requests that can be made per hour and per minute. Current rate limits are 5000 requests per hour and 250 requests per minute.

ratelimit-remaining integer

The number of requests in your hourly quota that remain before you hit your request limit. See https://docs.digitalocean.com/reference/api/reference/#rate-limit for information about how requests expire.

ratelimit-reset integer

The time when the oldest request will expire. The value is given in Unix epoch time. See https://docs.digitalocean.com/reference/api/reference/#rate-limit for information about how requests expire.

execution object optional

One row per firing (webhook delivery or cron tick).

Show child properties
created_at string (date-time) optional
Example: 2026-07-27T12:00:00Z
execution_id string optional
Example: 7c1f9e2a-3b4c-5d6e-7f80-91a2b3c4d5e6
failure_reason string optional

Client-safe reason when status=failed; absent otherwise. One of a fixed set of messages; do not parse it or match on substrings. Quote the execution_id when contacting support.

output_text string optional

The doctl-parity transcript rendered from the run's SPI events. Returned by GetTriggerExecution only; omitted from list items.

output_truncated boolean optional
Example: false

True when output_text is incomplete. Returned by GetTriggerExecution only; omitted from list items.

payload string optional

The raw webhook body or cron tick metadata. Returned by GetTriggerExecution only; omitted from list items. Cleared for terminal executions after the payload retention window (default 7 days from creation).

run_id string optional

Populated once SendInput acks; correlation/audit only. May be empty.

session_id string optional
Example: a1b2c3d4-e5f6-7890-abcd-ef1234567890

The run's session. Populated once the session is created (fresh) or is known (reuse); empty before then.

status string, one of: pending, running, succeeded, failed optional
Example: succeeded

Per-firing outcome.

trigger_id string optional
Example: b1a0c6de-1f2e-4a3b-9c8d-0e1f2a3b4c5d
updated_at string (date-time) optional
Example: 2026-07-27T12:00:05Z
401

Authentication failed due to invalid credentials.

ratelimit-limit integer

The default limit on number of requests that can be made per hour and per minute. Current rate limits are 5000 requests per hour and 250 requests per minute.

ratelimit-remaining integer

The number of requests in your hourly quota that remain before you hit your request limit. See https://docs.digitalocean.com/reference/api/reference/#rate-limit for information about how requests expire.

ratelimit-reset integer

The time when the oldest request will expire. The value is given in Unix epoch time. See https://docs.digitalocean.com/reference/api/reference/#rate-limit for information about how requests expire.

id string required
Example: not_found

A short identifier corresponding to the HTTP status code returned. For example, the ID for a response returning a 404 status code would be "not_found."

message string required
Example: The resource you were accessing could not be found.

A message providing additional information about the error, including details to help resolve it when possible.

request_id string optional
Example: 4d9d8375-3c56-4925-a3e7-eb137fed17e9

Optionally, some endpoints may include a request ID that should be provided when reporting bugs or opening support tickets to help identify the issue.

404

The resource was not found.

ratelimit-limit integer

The default limit on number of requests that can be made per hour and per minute. Current rate limits are 5000 requests per hour and 250 requests per minute.

ratelimit-remaining integer

The number of requests in your hourly quota that remain before you hit your request limit. See https://docs.digitalocean.com/reference/api/reference/#rate-limit for information about how requests expire.

ratelimit-reset integer

The time when the oldest request will expire. The value is given in Unix epoch time. See https://docs.digitalocean.com/reference/api/reference/#rate-limit for information about how requests expire.

id string required
Example: not_found

A short identifier corresponding to the HTTP status code returned. For example, the ID for a response returning a 404 status code would be "not_found."

message string required
Example: The resource you were accessing could not be found.

A message providing additional information about the error, including details to help resolve it when possible.

request_id string optional
Example: 4d9d8375-3c56-4925-a3e7-eb137fed17e9

Optionally, some endpoints may include a request ID that should be provided when reporting bugs or opening support tickets to help identify the issue.

409

Execution has not started a run yet (the worker's dispatch is still in flight); retry shortly, or pass force=true.

ratelimit-limit integer

The default limit on number of requests that can be made per hour and per minute. Current rate limits are 5000 requests per hour and 250 requests per minute.

ratelimit-remaining integer

The number of requests in your hourly quota that remain before you hit your request limit. See https://docs.digitalocean.com/reference/api/reference/#rate-limit for information about how requests expire.

ratelimit-reset integer

The time when the oldest request will expire. The value is given in Unix epoch time. See https://docs.digitalocean.com/reference/api/reference/#rate-limit for information about how requests expire.

id string required
Example: not_found

A short identifier corresponding to the HTTP status code returned. For example, the ID for a response returning a 404 status code would be "not_found."

message string required
Example: The resource you were accessing could not be found.

A message providing additional information about the error, including details to help resolve it when possible.

request_id string optional
Example: 4d9d8375-3c56-4925-a3e7-eb137fed17e9

Optionally, some endpoints may include a request ID that should be provided when reporting bugs or opening support tickets to help identify the issue.

429

The API rate limit has been exceeded.

ratelimit-limit integer

The default limit on number of requests that can be made per hour and per minute. Current rate limits are 5000 requests per hour and 250 requests per minute.

ratelimit-remaining integer

The number of requests in your hourly quota that remain before you hit your request limit. See https://docs.digitalocean.com/reference/api/reference/#rate-limit for information about how requests expire.

ratelimit-reset integer

The time when the oldest request will expire. The value is given in Unix epoch time. See https://docs.digitalocean.com/reference/api/reference/#rate-limit for information about how requests expire.

id string required
Example: not_found

A short identifier corresponding to the HTTP status code returned. For example, the ID for a response returning a 404 status code would be "not_found."

message string required
Example: The resource you were accessing could not be found.

A message providing additional information about the error, including details to help resolve it when possible.

request_id string optional
Example: 4d9d8375-3c56-4925-a3e7-eb137fed17e9

Optionally, some endpoints may include a request ID that should be provided when reporting bugs or opening support tickets to help identify the issue.

500

There was a server error.

ratelimit-limit integer

The default limit on number of requests that can be made per hour and per minute. Current rate limits are 5000 requests per hour and 250 requests per minute.

ratelimit-remaining integer

The number of requests in your hourly quota that remain before you hit your request limit. See https://docs.digitalocean.com/reference/api/reference/#rate-limit for information about how requests expire.

ratelimit-reset integer

The time when the oldest request will expire. The value is given in Unix epoch time. See https://docs.digitalocean.com/reference/api/reference/#rate-limit for information about how requests expire.

id string required
Example: not_found

A short identifier corresponding to the HTTP status code returned. For example, the ID for a response returning a 404 status code would be "not_found."

message string required
Example: The resource you were accessing could not be found.

A message providing additional information about the error, including details to help resolve it when possible.

request_id string optional
Example: 4d9d8375-3c56-4925-a3e7-eb137fed17e9

Optionally, some endpoints may include a request ID that should be provided when reporting bugs or opening support tickets to help identify the issue.

default

There was an unexpected error.

ratelimit-limit integer

The default limit on number of requests that can be made per hour and per minute. Current rate limits are 5000 requests per hour and 250 requests per minute.

ratelimit-remaining integer

The number of requests in your hourly quota that remain before you hit your request limit. See https://docs.digitalocean.com/reference/api/reference/#rate-limit for information about how requests expire.

ratelimit-reset integer

The time when the oldest request will expire. The value is given in Unix epoch time. See https://docs.digitalocean.com/reference/api/reference/#rate-limit for information about how requests expire.

id string required
Example: not_found

A short identifier corresponding to the HTTP status code returned. For example, the ID for a response returning a 404 status code would be "not_found."

message string required
Example: The resource you were accessing could not be found.

A message providing additional information about the error, including details to help resolve it when possible.

request_id string optional
Example: 4d9d8375-3c56-4925-a3e7-eb137fed17e9

Optionally, some endpoints may include a request ID that should be provided when reporting bugs or opening support tickets to help identify the issue.

{
  "execution": {
    "created_at": "2026-07-27T12:00:00Z",
    "execution_id": "7c1f9e2a-3b4c-5d6e-7f80-91a2b3c4d5e6",
    "failure_reason": "",
    "output_text": "",
    "output_truncated": false,
    "payload": "",
    "run_id": "",
    "session_id": "a1b2c3d4-e5f6-7890-abcd-ef1234567890",
    "status": "succeeded",
    "trigger_id": "b1a0c6de-1f2e-4a3b-9c8d-0e1f2a3b4c5d",
    "updated_at": "2026-07-27T12:00:05Z"
  }
}
{
  "id": "unauthorized",
  "message": "Unable to authenticate you."
}
{
  "id": "not_found",
  "message": "The resource you requested could not be found."
}
{
  "id": "not_found",
  "message": "The resource you were accessing could not be found.",
  "request_id": "4d9d8375-3c56-4925-a3e7-eb137fed17e9"
}
{
  "id": "too_many_requests",
  "message": "API rate limit exceeded."
}
{
  "id": "server_error",
  "message": "Unexpected server-side error"
}
{
  "id": "example_error",
  "message": "some error message"
}

POST RotateTriggerSecret issues a new webhook secret.

/v2/agents/triggers/{trigger_id}/rotate-secret
Authorizations: bearer_auth (1 scope)
Http: Bearer
Required scopes: agent_harness_session:manage

OAuth Authentication

In order to interact with the DigitalOcean API, you or your application must authenticate.

The DigitalOcean API handles this through OAuth, an open standard for authorization. OAuth allows you to delegate access to your account. Scopes can be used to grant full access, read-only access, or access to a specific set of endpoints.

You can generate an OAuth token by visiting the Apps & API section of the DigitalOcean control panel for your account.

An OAuth token functions as a complete authentication request. In effect, it acts as a substitute for a username and password pair.

Because of this, it is absolutely essential that you keep your OAuth tokens secure. In fact, upon generation, the web interface will only display each token a single time in order to prevent the token from being compromised.

DigitalOcean access tokens begin with an identifiable prefix in order to distinguish them from other similar tokens.

  • dop_v1_ for personal access tokens generated in the control panel
  • doo_v1_ for tokens generated by applications using the OAuth flow
  • dor_v1_ for OAuth refresh tokens

Scopes

Scopes act like permissions assigned to an API token. These permissions determine what actions the token can perform. You can create API tokens that grant read-only access, full access, or limited access to specific endpoints by using custom scopes.

Generally, scopes are designed to match HTTP verbs and common CRUD operations (Create, Read, Update, Delete).

HTTP Verb CRUD Operation Scope
GET Read <resource>:read
POST Create <resource>:create
PUT/PATCH Update <resource>:update
DELETE Delete <resource>:delete

For example, creating a new Droplet by making a POST request to the /v2/droplets endpoint requires the droplet:create scope while listing Droplets by making a GET request to the /v2/droplets endpoint requires the droplet:read scope.

Each endpoint below specifies which scope is required to access it when using custom scopes.

How to Authenticate with OAuth

In order to make an authenticated request, include a bearer-type Authorization header containing your OAuth token. All requests must be made over HTTPS.

Authenticate with a Bearer Authorization Header

curl -X $HTTP_METHOD -H "Authorization: Bearer $DIGITALOCEAN_TOKEN" "https://api.digitalocean.com/v2/$OBJECT"

Webhook triggers only (409 for cron). Issues a new secret (shown once) and moves the old value to the previous slot, where it keeps verifying deliveries until previous_secret_expires_at. Default grace is 5 minutes when grace_period_seconds is omitted, so deliveries already in flight (signed with the old value) still succeed while the customer updates their external system. After that instant the old value is refused with 401. Pass grace_period_seconds=0 to retire the old secret on this call (breach response), or a positive value (up to the server max, default 1 hour) for a custom window; above the max is 400.

Path Parameters

trigger_id string required
Example: b1a0c6de-1f2e-4a3b-9c8d-0e1f2a3b4c5d

The trigger UUID.

Query Parameters

grace_period_seconds integer >= 0 optional
Example: 300

How long the outgoing secret keeps verifying deliveries. Omit for the default (5 minutes). 0 retires the old secret immediately (compromised-secret path). Positive values set a custom window up to the server max (default 1 hour); above the max is 400. Send at most once with an explicit non-negative integer - bare keys, empty values, non-integers, negatives, and duplicates are 400.

curl -X POST \
  -H "Content-Type: application/json" \
  -H "Authorization: Bearer $DIGITALOCEAN_TOKEN" \
  "https://api.digitalocean.com/v2/agents/triggers/{trigger_id}/rotate-secret?grace_period_seconds=300"
curl -X POST \
  -H "Authorization: Bearer $API_TOKEN" \
  -H "Content-Type: application/json" \
  "https://api.digitalocean.com/v2/agents/triggers/{trigger_id}/rotate-secret"

Responses

200

The new secret, shown once.

ratelimit-limit integer

The default limit on number of requests that can be made per hour and per minute. Current rate limits are 5000 requests per hour and 250 requests per minute.

ratelimit-remaining integer

The number of requests in your hourly quota that remain before you hit your request limit. See https://docs.digitalocean.com/reference/api/reference/#rate-limit for information about how requests expire.

ratelimit-reset integer

The time when the oldest request will expire. The value is given in Unix epoch time. See https://docs.digitalocean.com/reference/api/reference/#rate-limit for information about how requests expire.

previous_secret_expires_at string (date-time) optional
Example: 2026-07-27T12:05:00Z

The instant the outgoing secret stops verifying deliveries. Omitted when grace_period_seconds=0.

previous_secret_revoked boolean optional
Example: false

True when grace_period_seconds=0 retired the old secret on this call. Exactly one of this and previous_secret_expires_at is present.

webhook_secret string optional
Example: whsec_f6e5d4c3b2a1

The new webhook secret, shown once.

400

Invalid grace_period_seconds.

ratelimit-limit integer

The default limit on number of requests that can be made per hour and per minute. Current rate limits are 5000 requests per hour and 250 requests per minute.

ratelimit-remaining integer

The number of requests in your hourly quota that remain before you hit your request limit. See https://docs.digitalocean.com/reference/api/reference/#rate-limit for information about how requests expire.

ratelimit-reset integer

The time when the oldest request will expire. The value is given in Unix epoch time. See https://docs.digitalocean.com/reference/api/reference/#rate-limit for information about how requests expire.

id string required
Example: not_found

A short identifier corresponding to the HTTP status code returned. For example, the ID for a response returning a 404 status code would be "not_found."

message string required
Example: The resource you were accessing could not be found.

A message providing additional information about the error, including details to help resolve it when possible.

request_id string optional
Example: 4d9d8375-3c56-4925-a3e7-eb137fed17e9

Optionally, some endpoints may include a request ID that should be provided when reporting bugs or opening support tickets to help identify the issue.

401

Authentication failed due to invalid credentials.

ratelimit-limit integer

The default limit on number of requests that can be made per hour and per minute. Current rate limits are 5000 requests per hour and 250 requests per minute.

ratelimit-remaining integer

The number of requests in your hourly quota that remain before you hit your request limit. See https://docs.digitalocean.com/reference/api/reference/#rate-limit for information about how requests expire.

ratelimit-reset integer

The time when the oldest request will expire. The value is given in Unix epoch time. See https://docs.digitalocean.com/reference/api/reference/#rate-limit for information about how requests expire.

id string required
Example: not_found

A short identifier corresponding to the HTTP status code returned. For example, the ID for a response returning a 404 status code would be "not_found."

message string required
Example: The resource you were accessing could not be found.

A message providing additional information about the error, including details to help resolve it when possible.

request_id string optional
Example: 4d9d8375-3c56-4925-a3e7-eb137fed17e9

Optionally, some endpoints may include a request ID that should be provided when reporting bugs or opening support tickets to help identify the issue.

404

The resource was not found.

ratelimit-limit integer

The default limit on number of requests that can be made per hour and per minute. Current rate limits are 5000 requests per hour and 250 requests per minute.

ratelimit-remaining integer

The number of requests in your hourly quota that remain before you hit your request limit. See https://docs.digitalocean.com/reference/api/reference/#rate-limit for information about how requests expire.

ratelimit-reset integer

The time when the oldest request will expire. The value is given in Unix epoch time. See https://docs.digitalocean.com/reference/api/reference/#rate-limit for information about how requests expire.

id string required
Example: not_found

A short identifier corresponding to the HTTP status code returned. For example, the ID for a response returning a 404 status code would be "not_found."

message string required
Example: The resource you were accessing could not be found.

A message providing additional information about the error, including details to help resolve it when possible.

request_id string optional
Example: 4d9d8375-3c56-4925-a3e7-eb137fed17e9

Optionally, some endpoints may include a request ID that should be provided when reporting bugs or opening support tickets to help identify the issue.

409

The trigger is not a webhook trigger.

ratelimit-limit integer

The default limit on number of requests that can be made per hour and per minute. Current rate limits are 5000 requests per hour and 250 requests per minute.

ratelimit-remaining integer

The number of requests in your hourly quota that remain before you hit your request limit. See https://docs.digitalocean.com/reference/api/reference/#rate-limit for information about how requests expire.

ratelimit-reset integer

The time when the oldest request will expire. The value is given in Unix epoch time. See https://docs.digitalocean.com/reference/api/reference/#rate-limit for information about how requests expire.

id string required
Example: not_found

A short identifier corresponding to the HTTP status code returned. For example, the ID for a response returning a 404 status code would be "not_found."

message string required
Example: The resource you were accessing could not be found.

A message providing additional information about the error, including details to help resolve it when possible.

request_id string optional
Example: 4d9d8375-3c56-4925-a3e7-eb137fed17e9

Optionally, some endpoints may include a request ID that should be provided when reporting bugs or opening support tickets to help identify the issue.

429

The API rate limit has been exceeded.

ratelimit-limit integer

The default limit on number of requests that can be made per hour and per minute. Current rate limits are 5000 requests per hour and 250 requests per minute.

ratelimit-remaining integer

The number of requests in your hourly quota that remain before you hit your request limit. See https://docs.digitalocean.com/reference/api/reference/#rate-limit for information about how requests expire.

ratelimit-reset integer

The time when the oldest request will expire. The value is given in Unix epoch time. See https://docs.digitalocean.com/reference/api/reference/#rate-limit for information about how requests expire.

id string required
Example: not_found

A short identifier corresponding to the HTTP status code returned. For example, the ID for a response returning a 404 status code would be "not_found."

message string required
Example: The resource you were accessing could not be found.

A message providing additional information about the error, including details to help resolve it when possible.

request_id string optional
Example: 4d9d8375-3c56-4925-a3e7-eb137fed17e9

Optionally, some endpoints may include a request ID that should be provided when reporting bugs or opening support tickets to help identify the issue.

500

There was a server error.

ratelimit-limit integer

The default limit on number of requests that can be made per hour and per minute. Current rate limits are 5000 requests per hour and 250 requests per minute.

ratelimit-remaining integer

The number of requests in your hourly quota that remain before you hit your request limit. See https://docs.digitalocean.com/reference/api/reference/#rate-limit for information about how requests expire.

ratelimit-reset integer

The time when the oldest request will expire. The value is given in Unix epoch time. See https://docs.digitalocean.com/reference/api/reference/#rate-limit for information about how requests expire.

id string required
Example: not_found

A short identifier corresponding to the HTTP status code returned. For example, the ID for a response returning a 404 status code would be "not_found."

message string required
Example: The resource you were accessing could not be found.

A message providing additional information about the error, including details to help resolve it when possible.

request_id string optional
Example: 4d9d8375-3c56-4925-a3e7-eb137fed17e9

Optionally, some endpoints may include a request ID that should be provided when reporting bugs or opening support tickets to help identify the issue.

default

There was an unexpected error.

ratelimit-limit integer

The default limit on number of requests that can be made per hour and per minute. Current rate limits are 5000 requests per hour and 250 requests per minute.

ratelimit-remaining integer

The number of requests in your hourly quota that remain before you hit your request limit. See https://docs.digitalocean.com/reference/api/reference/#rate-limit for information about how requests expire.

ratelimit-reset integer

The time when the oldest request will expire. The value is given in Unix epoch time. See https://docs.digitalocean.com/reference/api/reference/#rate-limit for information about how requests expire.

id string required
Example: not_found

A short identifier corresponding to the HTTP status code returned. For example, the ID for a response returning a 404 status code would be "not_found."

message string required
Example: The resource you were accessing could not be found.

A message providing additional information about the error, including details to help resolve it when possible.

request_id string optional
Example: 4d9d8375-3c56-4925-a3e7-eb137fed17e9

Optionally, some endpoints may include a request ID that should be provided when reporting bugs or opening support tickets to help identify the issue.

{
  "previous_secret_expires_at": "2026-07-27T12:05:00Z",
  "previous_secret_revoked": false,
  "webhook_secret": "whsec_f6e5d4c3b2a1"
}
{
  "id": "not_found",
  "message": "The resource you were accessing could not be found.",
  "request_id": "4d9d8375-3c56-4925-a3e7-eb137fed17e9"
}
{
  "id": "unauthorized",
  "message": "Unable to authenticate you."
}
{
  "id": "not_found",
  "message": "The resource you requested could not be found."
}
{
  "id": "not_found",
  "message": "The resource you were accessing could not be found.",
  "request_id": "4d9d8375-3c56-4925-a3e7-eb137fed17e9"
}
{
  "id": "too_many_requests",
  "message": "API rate limit exceeded."
}
{
  "id": "server_error",
  "message": "Unexpected server-side error"
}
{
  "id": "example_error",
  "message": "some error message"
}

POST ReceiveTriggerWebhook accepts a signed delivery from an external system.

/v2/agents/triggers/{trigger_id}/webhook

The one public, un-team-authenticated endpoint. There is NO DO bearer token: the caller is the customer's external system. Authentication is the per-trigger HMAC secret, verified on every delivery; edge rate-limiting is mandatory.

The request body is the provider's RAW body, forwarded verbatim (the HMAC is computed over the exact bytes received); Content-Type is provider-defined and passed through. The signature header depends on the trigger's provider:

  • github: X-Hub-Signature-256: sha256=<hex> (HMAC-SHA256 of the raw body)
  • gitlab: X-Gitlab-Token: <token> (plaintext token equality; GitLab does not sign)
  • custom: X-DigitalOcean-Signature: t=<unix>,v1=<hex> (HMAC-SHA256 of {unix}.{raw body}; do-signature is also accepted as a transitional alias)

On success (including a provider retry that dedupes to an existing firing) it returns 202 with the execution_id. A delivery to a paused trigger returns 202 with no body and queues nothing (deliberately not 409, so providers do not auto-disable the webhook after repeated non-2xx).

Path Parameters

trigger_id string required
Example: b1a0c6de-1f2e-4a3b-9c8d-0e1f2a3b4c5d

The trigger UUID.

Request Body: application/octet-stream

The provider's raw webhook body, forwarded verbatim. The HMAC is computed over these exact bytes. Content-Type is provider-defined (GitHub sends application/json, some providers form-encode) and passed through; the handler reads the raw bytes regardless of type. Documented as a single application/octet-stream body so client generators can model the raw payload.

Content type application/octet-stream
"string"
curl -X POST \
  -H "Content-Type: application/json" \
  -H "X-DigitalOcean-Signature: t=1700000000,v1=<hmac-sha256-hex>" \
  -d '{"event":"push","ref":"refs/heads/main"}' \
  "https://api.digitalocean.com/v2/agents/triggers/{trigger_id}/webhook"
curl -X POST \
  -H "Content-Type: application/octet-stream" \
  -d '"string"' \
  "https://api.digitalocean.com/v2/agents/triggers/{trigger_id}/webhook"

Responses

202

Accepted and queued (also returned for a deduped retry, with the same execution_id). A paused trigger returns 202 with an empty body and queues nothing.

ratelimit-limit integer

The default limit on number of requests that can be made per hour and per minute. Current rate limits are 5000 requests per hour and 250 requests per minute.

ratelimit-remaining integer

The number of requests in your hourly quota that remain before you hit your request limit. See https://docs.digitalocean.com/reference/api/reference/#rate-limit for information about how requests expire.

ratelimit-reset integer

The time when the oldest request will expire. The value is given in Unix epoch time. See https://docs.digitalocean.com/reference/api/reference/#rate-limit for information about how requests expire.

execution_id string optional
Example: 7c1f9e2a-3b4c-5d6e-7f80-91a2b3c4d5e6

The queued (or deduped-existing) execution. Absent when the trigger is paused (202 with empty body).

400

The request body is too large or unreadable.

ratelimit-limit integer

The default limit on number of requests that can be made per hour and per minute. Current rate limits are 5000 requests per hour and 250 requests per minute.

ratelimit-remaining integer

The number of requests in your hourly quota that remain before you hit your request limit. See https://docs.digitalocean.com/reference/api/reference/#rate-limit for information about how requests expire.

ratelimit-reset integer

The time when the oldest request will expire. The value is given in Unix epoch time. See https://docs.digitalocean.com/reference/api/reference/#rate-limit for information about how requests expire.

id string required
Example: not_found

A short identifier corresponding to the HTTP status code returned. For example, the ID for a response returning a 404 status code would be "not_found."

message string required
Example: The resource you were accessing could not be found.

A message providing additional information about the error, including details to help resolve it when possible.

request_id string optional
Example: 4d9d8375-3c56-4925-a3e7-eb137fed17e9

Optionally, some endpoints may include a request ID that should be provided when reporting bugs or opening support tickets to help identify the issue.

401

Signature/token verification failed.

ratelimit-limit integer

The default limit on number of requests that can be made per hour and per minute. Current rate limits are 5000 requests per hour and 250 requests per minute.

ratelimit-remaining integer

The number of requests in your hourly quota that remain before you hit your request limit. See https://docs.digitalocean.com/reference/api/reference/#rate-limit for information about how requests expire.

ratelimit-reset integer

The time when the oldest request will expire. The value is given in Unix epoch time. See https://docs.digitalocean.com/reference/api/reference/#rate-limit for information about how requests expire.

id string required
Example: not_found

A short identifier corresponding to the HTTP status code returned. For example, the ID for a response returning a 404 status code would be "not_found."

message string required
Example: The resource you were accessing could not be found.

A message providing additional information about the error, including details to help resolve it when possible.

request_id string optional
Example: 4d9d8375-3c56-4925-a3e7-eb137fed17e9

Optionally, some endpoints may include a request ID that should be provided when reporting bugs or opening support tickets to help identify the issue.

404

The resource was not found.

ratelimit-limit integer

The default limit on number of requests that can be made per hour and per minute. Current rate limits are 5000 requests per hour and 250 requests per minute.

ratelimit-remaining integer

The number of requests in your hourly quota that remain before you hit your request limit. See https://docs.digitalocean.com/reference/api/reference/#rate-limit for information about how requests expire.

ratelimit-reset integer

The time when the oldest request will expire. The value is given in Unix epoch time. See https://docs.digitalocean.com/reference/api/reference/#rate-limit for information about how requests expire.

id string required
Example: not_found

A short identifier corresponding to the HTTP status code returned. For example, the ID for a response returning a 404 status code would be "not_found."

message string required
Example: The resource you were accessing could not be found.

A message providing additional information about the error, including details to help resolve it when possible.

request_id string optional
Example: 4d9d8375-3c56-4925-a3e7-eb137fed17e9

Optionally, some endpoints may include a request ID that should be provided when reporting bugs or opening support tickets to help identify the issue.

429

The API rate limit has been exceeded.

ratelimit-limit integer

The default limit on number of requests that can be made per hour and per minute. Current rate limits are 5000 requests per hour and 250 requests per minute.

ratelimit-remaining integer

The number of requests in your hourly quota that remain before you hit your request limit. See https://docs.digitalocean.com/reference/api/reference/#rate-limit for information about how requests expire.

ratelimit-reset integer

The time when the oldest request will expire. The value is given in Unix epoch time. See https://docs.digitalocean.com/reference/api/reference/#rate-limit for information about how requests expire.

id string required
Example: not_found

A short identifier corresponding to the HTTP status code returned. For example, the ID for a response returning a 404 status code would be "not_found."

message string required
Example: The resource you were accessing could not be found.

A message providing additional information about the error, including details to help resolve it when possible.

request_id string optional
Example: 4d9d8375-3c56-4925-a3e7-eb137fed17e9

Optionally, some endpoints may include a request ID that should be provided when reporting bugs or opening support tickets to help identify the issue.

500

There was a server error.

ratelimit-limit integer

The default limit on number of requests that can be made per hour and per minute. Current rate limits are 5000 requests per hour and 250 requests per minute.

ratelimit-remaining integer

The number of requests in your hourly quota that remain before you hit your request limit. See https://docs.digitalocean.com/reference/api/reference/#rate-limit for information about how requests expire.

ratelimit-reset integer

The time when the oldest request will expire. The value is given in Unix epoch time. See https://docs.digitalocean.com/reference/api/reference/#rate-limit for information about how requests expire.

id string required
Example: not_found

A short identifier corresponding to the HTTP status code returned. For example, the ID for a response returning a 404 status code would be "not_found."

message string required
Example: The resource you were accessing could not be found.

A message providing additional information about the error, including details to help resolve it when possible.

request_id string optional
Example: 4d9d8375-3c56-4925-a3e7-eb137fed17e9

Optionally, some endpoints may include a request ID that should be provided when reporting bugs or opening support tickets to help identify the issue.

default

There was an unexpected error.

ratelimit-limit integer

The default limit on number of requests that can be made per hour and per minute. Current rate limits are 5000 requests per hour and 250 requests per minute.

ratelimit-remaining integer

The number of requests in your hourly quota that remain before you hit your request limit. See https://docs.digitalocean.com/reference/api/reference/#rate-limit for information about how requests expire.

ratelimit-reset integer

The time when the oldest request will expire. The value is given in Unix epoch time. See https://docs.digitalocean.com/reference/api/reference/#rate-limit for information about how requests expire.

id string required
Example: not_found

A short identifier corresponding to the HTTP status code returned. For example, the ID for a response returning a 404 status code would be "not_found."

message string required
Example: The resource you were accessing could not be found.

A message providing additional information about the error, including details to help resolve it when possible.

request_id string optional
Example: 4d9d8375-3c56-4925-a3e7-eb137fed17e9

Optionally, some endpoints may include a request ID that should be provided when reporting bugs or opening support tickets to help identify the issue.

{
  "execution_id": "7c1f9e2a-3b4c-5d6e-7f80-91a2b3c4d5e6"
}
{
  "id": "not_found",
  "message": "The resource you were accessing could not be found.",
  "request_id": "4d9d8375-3c56-4925-a3e7-eb137fed17e9"
}
{
  "id": "not_found",
  "message": "The resource you were accessing could not be found.",
  "request_id": "4d9d8375-3c56-4925-a3e7-eb137fed17e9"
}
{
  "id": "not_found",
  "message": "The resource you requested could not be found."
}
{
  "id": "too_many_requests",
  "message": "API rate limit exceeded."
}
{
  "id": "server_error",
  "message": "Unexpected server-side error"
}
{
  "id": "example_error",
  "message": "some error message"
}

GET ListWebhookProviders lists supported webhook providers for the create-trigger UI.

/v2/agents/webhook-providers
Authorizations: bearer_auth (1 scope)
Http: Bearer
Required scopes: agent_harness_session:read

OAuth Authentication

In order to interact with the DigitalOcean API, you or your application must authenticate.

The DigitalOcean API handles this through OAuth, an open standard for authorization. OAuth allows you to delegate access to your account. Scopes can be used to grant full access, read-only access, or access to a specific set of endpoints.

You can generate an OAuth token by visiting the Apps & API section of the DigitalOcean control panel for your account.

An OAuth token functions as a complete authentication request. In effect, it acts as a substitute for a username and password pair.

Because of this, it is absolutely essential that you keep your OAuth tokens secure. In fact, upon generation, the web interface will only display each token a single time in order to prevent the token from being compromised.

DigitalOcean access tokens begin with an identifiable prefix in order to distinguish them from other similar tokens.

  • dop_v1_ for personal access tokens generated in the control panel
  • doo_v1_ for tokens generated by applications using the OAuth flow
  • dor_v1_ for OAuth refresh tokens

Scopes

Scopes act like permissions assigned to an API token. These permissions determine what actions the token can perform. You can create API tokens that grant read-only access, full access, or limited access to specific endpoints by using custom scopes.

Generally, scopes are designed to match HTTP verbs and common CRUD operations (Create, Read, Update, Delete).

HTTP Verb CRUD Operation Scope
GET Read <resource>:read
POST Create <resource>:create
PUT/PATCH Update <resource>:update
DELETE Delete <resource>:delete

For example, creating a new Droplet by making a POST request to the /v2/droplets endpoint requires the droplet:create scope while listing Droplets by making a GET request to the /v2/droplets endpoint requires the droplet:read scope.

Each endpoint below specifies which scope is required to access it when using custom scopes.

How to Authenticate with OAuth

In order to make an authenticated request, include a bearer-type Authorization header containing your OAuth token. All requests must be made over HTTPS.

Authenticate with a Bearer Authorization Header

curl -X $HTTP_METHOD -H "Authorization: Bearer $DIGITALOCEAN_TOKEN" "https://api.digitalocean.com/v2/$OBJECT"

A static, code-defined registry (not a database table), webhook-only. Cron triggers have no provider and never call this. Used to populate the provider dropdown with display name, docs link, paste hint, and the signature scheme.

curl -X GET \
  -H "Content-Type: application/json" \
  -H "Authorization: Bearer $DIGITALOCEAN_TOKEN" \
  "https://api.digitalocean.com/v2/agents/webhook-providers"
curl -X GET \
  -H "Authorization: Bearer $API_TOKEN" \
  "https://api.digitalocean.com/v2/agents/webhook-providers"

Responses

200

A successful response.

ratelimit-limit integer

The default limit on number of requests that can be made per hour and per minute. Current rate limits are 5000 requests per hour and 250 requests per minute.

ratelimit-remaining integer

The number of requests in your hourly quota that remain before you hit your request limit. See https://docs.digitalocean.com/reference/api/reference/#rate-limit for information about how requests expire.

ratelimit-reset integer

The time when the oldest request will expire. The value is given in Unix epoch time. See https://docs.digitalocean.com/reference/api/reference/#rate-limit for information about how requests expire.

providers array of object optional
Show child properties
description string optional
Example: Verify deliveries with an HMAC-SHA256 signature over the raw body.
display_name string optional
Example: GitHub
docs_url string optional
Example: https://docs.github.com/webhooks
key string, one of: github, gitlab, custom optional
Example: github

Signature-verification scheme applied to a delivery. Omitted on create defaults to custom.

paste_hint string optional
Example: Paste into the webhook's Secret field.

Per-provider instruction for where the generated secret goes in the external system.

signature object optional
Show child properties
header string optional
Example: X-Hub-Signature-256

HTTP header the external system sends the signature/token in.

scheme string, one of: hmac-sha256, plaintext, do-signature-v1 optional
Example: hmac-sha256

How the external system authenticates a delivery: hmac-sha256 over the raw body (github), a plaintext token replayed verbatim (gitlab), or do-signature-v1 (t=<unix>,v1=<hex> over {unix}.{body}, custom).

401

Authentication failed due to invalid credentials.

ratelimit-limit integer

The default limit on number of requests that can be made per hour and per minute. Current rate limits are 5000 requests per hour and 250 requests per minute.

ratelimit-remaining integer

The number of requests in your hourly quota that remain before you hit your request limit. See https://docs.digitalocean.com/reference/api/reference/#rate-limit for information about how requests expire.

ratelimit-reset integer

The time when the oldest request will expire. The value is given in Unix epoch time. See https://docs.digitalocean.com/reference/api/reference/#rate-limit for information about how requests expire.

id string required
Example: not_found

A short identifier corresponding to the HTTP status code returned. For example, the ID for a response returning a 404 status code would be "not_found."

message string required
Example: The resource you were accessing could not be found.

A message providing additional information about the error, including details to help resolve it when possible.

request_id string optional
Example: 4d9d8375-3c56-4925-a3e7-eb137fed17e9

Optionally, some endpoints may include a request ID that should be provided when reporting bugs or opening support tickets to help identify the issue.

429

The API rate limit has been exceeded.

ratelimit-limit integer

The default limit on number of requests that can be made per hour and per minute. Current rate limits are 5000 requests per hour and 250 requests per minute.

ratelimit-remaining integer

The number of requests in your hourly quota that remain before you hit your request limit. See https://docs.digitalocean.com/reference/api/reference/#rate-limit for information about how requests expire.

ratelimit-reset integer

The time when the oldest request will expire. The value is given in Unix epoch time. See https://docs.digitalocean.com/reference/api/reference/#rate-limit for information about how requests expire.

id string required
Example: not_found

A short identifier corresponding to the HTTP status code returned. For example, the ID for a response returning a 404 status code would be "not_found."

message string required
Example: The resource you were accessing could not be found.

A message providing additional information about the error, including details to help resolve it when possible.

request_id string optional
Example: 4d9d8375-3c56-4925-a3e7-eb137fed17e9

Optionally, some endpoints may include a request ID that should be provided when reporting bugs or opening support tickets to help identify the issue.

500

There was a server error.

ratelimit-limit integer

The default limit on number of requests that can be made per hour and per minute. Current rate limits are 5000 requests per hour and 250 requests per minute.

ratelimit-remaining integer

The number of requests in your hourly quota that remain before you hit your request limit. See https://docs.digitalocean.com/reference/api/reference/#rate-limit for information about how requests expire.

ratelimit-reset integer

The time when the oldest request will expire. The value is given in Unix epoch time. See https://docs.digitalocean.com/reference/api/reference/#rate-limit for information about how requests expire.

id string required
Example: not_found

A short identifier corresponding to the HTTP status code returned. For example, the ID for a response returning a 404 status code would be "not_found."

message string required
Example: The resource you were accessing could not be found.

A message providing additional information about the error, including details to help resolve it when possible.

request_id string optional
Example: 4d9d8375-3c56-4925-a3e7-eb137fed17e9

Optionally, some endpoints may include a request ID that should be provided when reporting bugs or opening support tickets to help identify the issue.

default

There was an unexpected error.

ratelimit-limit integer

The default limit on number of requests that can be made per hour and per minute. Current rate limits are 5000 requests per hour and 250 requests per minute.

ratelimit-remaining integer

The number of requests in your hourly quota that remain before you hit your request limit. See https://docs.digitalocean.com/reference/api/reference/#rate-limit for information about how requests expire.

ratelimit-reset integer

The time when the oldest request will expire. The value is given in Unix epoch time. See https://docs.digitalocean.com/reference/api/reference/#rate-limit for information about how requests expire.

id string required
Example: not_found

A short identifier corresponding to the HTTP status code returned. For example, the ID for a response returning a 404 status code would be "not_found."

message string required
Example: The resource you were accessing could not be found.

A message providing additional information about the error, including details to help resolve it when possible.

request_id string optional
Example: 4d9d8375-3c56-4925-a3e7-eb137fed17e9

Optionally, some endpoints may include a request ID that should be provided when reporting bugs or opening support tickets to help identify the issue.

{
  "providers": [
    {
      "description": "Verify deliveries with an HMAC-SHA256 signature over the raw body.",
      "display_name": "GitHub",
      "docs_url": "https://docs.github.com/webhooks",
      "key": "github",
      "paste_hint": "Paste into the webhook's Secret field."
    }
  ]
}
{
  "id": "unauthorized",
  "message": "Unable to authenticate you."
}
{
  "id": "too_many_requests",
  "message": "API rate limit exceeded."
}
{
  "id": "server_error",
  "message": "Unexpected server-side error"
}
{
  "id": "example_error",
  "message": "some error message"
}

We can't find any results for your search.

Try using different keywords or simplifying your search terms.