A reference guide for building AI agents: every method, how to authenticate, and the permissions each one needs.
The DigitalOcean API is how an app or AI agent works with a DigitalOcean account: listing and creating Droplets, rebooting or resizing a server, spinning up Kubernetes clusters and databases, and editing domains and DNS records. Access is granted through a token whose scopes decide what each call can do, each a resource and action pair like reading Droplets or creating a firewall, and an agent is limited to exactly the scopes its token carries. There is one continuously updated version, and long-running work runs as actions an agent polls until they finish.
How an app or AI agent connects to DigitalOcean determines what it can reach. There is a route for making calls and a hosted server that exposes DigitalOcean tools to agents, and each is governed by the token behind it and the scopes that token carries.
The REST API answers at https://api.digitalocean.com/v2. It is a single, continuously updated version, with no dated version header to pin.
DigitalOcean's official MCP server lets an agent call DigitalOcean through the Model Context Protocol. Remote endpoints are per service under mcp.digitalocean.com, such as https://droplets.mcp.digitalocean.com/mcp, and authenticate with a DigitalOcean API token. A local server is published as the npm package @digitalocean/mcp, with source at github.com/digitalocean-labs/mcp-digitalocean.
A personal access token with custom scopes grants only the chosen permissions, each a resource:action pair such as droplet:read or droplet:create. It is the least-privilege choice, and the scopes cannot be changed after the token is created.
A personal access token created as Read Only carries the api:read alias scope, and one created as Full Access carries api:write. These alias scopes expand to cover new endpoints automatically, so they grant more than a fixed list of custom scopes.
An OAuth 2.0 app obtains a token on behalf of a DigitalOcean user through the standard authorization flow, suited to a product that connects to many users' accounts. Tokens carry the doo_v1_ prefix and refresh tokens the dor_v1_ prefix.
The DigitalOcean API is split into areas an agent can act on, like Droplets, Kubernetes clusters, databases, domains, and storage. Each area has its own methods and its own scopes, and writes in some areas create or destroy real infrastructure that costs money.
List Droplets, read a single Droplet, create a Droplet, delete a Droplet, and read its backups and snapshots.
List the actions taken on a Droplet, read a single action, and initiate an action such as reboot, power off, power on, or snapshot.
List Kubernetes clusters, read a single cluster, create a cluster, and delete a cluster.
List managed database clusters, read a single cluster, and create a cluster.
List and read domains, create and delete a domain, and list, create, update, and delete the DNS records inside a domain.
List load balancers, read a single load balancer, create one, and delete one.
List block storage volumes, read a single volume, create a volume, and delete a volume.
List saved snapshots of Droplets and volumes, read a single snapshot, and delete a snapshot.
List cloud firewalls, read a single firewall, create a firewall, and delete one.
List apps, read a single app, create an app, create a deployment, and delete an app.
List projects, read a single project, and create a project.
List Spaces access keys, create a key, and delete a key.
Read the account behind the token, including its email, status, and resource limits.
Filter by method, access, or permission, or search any path. Select a row for version detail, rate limits, the related webhook event, and the source.
| Method | Endpoint | What it does | Access | Permission | Version | |
|---|---|---|---|---|---|---|
DropletsList Droplets, read a single Droplet, create a Droplet, delete a Droplet, and read its backups and snapshots.5 | ||||||
| GET | /v2/droplets | List the Droplets on the account. | read | droplet:read | Current | |
The alias scope api:read (Read Only) also covers this. A legacy read token works too. Acts ondroplet Permission (capability) droplet:readVersionAvailable since the API’s base version Webhook eventNone Rate limitStandard limits apply SourceOfficial documentation ↗ | ||||||
| GET | /v2/droplets/{droplet_id} | Retrieve a single Droplet by its ID. | read | droplet:read | Current | |
The alias scope api:read also covers this. Acts ondroplet Permission (capability) droplet:readVersionAvailable since the API’s base version Webhook eventNone Rate limitStandard limits apply SourceOfficial documentation ↗ | ||||||
| POST | /v2/droplets | Create one or more new Droplets. | write | droplet:create | Current | |
Creating a Droplet starts hourly billing. The alias scope api:write (Full Access) also covers this. Acts ondroplet Permission (capability) droplet:createVersionAvailable since the API’s base version Webhook eventNone Rate limitStandard limits apply SourceOfficial documentation ↗ | ||||||
| DELETE | /v2/droplets/{droplet_id} | Delete a Droplet, destroying the server. | write | droplet:delete | Current | |
Deleting by tag with DELETE /v2/droplets?tag_name=value also needs tag:read. Acts ondroplet Permission (capability) droplet:deleteVersionAvailable since the API’s base version Webhook eventNone Rate limitStandard limits apply SourceOfficial documentation ↗ | ||||||
| GET | /v2/droplets/{droplet_id}/snapshots | List the snapshots taken of a Droplet. | read | droplet:read | Current | |
Backups, kernels, and firewalls for a Droplet read with the same droplet:read scope. Acts ondroplet Permission (capability) droplet:readVersionAvailable since the API’s base version Webhook eventNone Rate limitStandard limits apply SourceOfficial documentation ↗ | ||||||
Droplet actionsList the actions taken on a Droplet, read a single action, and initiate an action such as reboot, power off, power on, or snapshot.3 | ||||||
| GET | /v2/droplets/{droplet_id}/actions | List the actions taken on a Droplet. | read | droplet:read | Current | |
The alias scope api:read also covers this. Acts ondroplet action Permission (capability) droplet:readVersionAvailable since the API’s base version Webhook eventNone Rate limitStandard limits apply SourceOfficial documentation ↗ | ||||||
| GET | /v2/droplets/{droplet_id}/actions/{action_id} | Retrieve a single Droplet action to check its status. | read | droplet:read | Current | |
An action runs asynchronously, so its status is polled here until it completes. Acts ondroplet action Permission (capability) droplet:readVersionAvailable since the API’s base version Webhook eventNone Rate limitStandard limits apply SourceOfficial documentation ↗ | ||||||
| POST | /v2/droplets/{droplet_id}/actions | Initiate an action on a Droplet, such as reboot, power off, power on, or snapshot. | write | droplet:update | Current | |
Most actions need droplet:update. Some need a second scope: snapshot also needs image:create, resize also needs droplet:create, and restore, rebuild, and password_reset also need droplet:admin. Acts ondroplet action Permission (capability) droplet:updateVersionAvailable since the API’s base version Webhook eventNone Rate limitStandard limits apply SourceOfficial documentation ↗ | ||||||
Kubernetes clustersList Kubernetes clusters, read a single cluster, create a cluster, and delete a cluster.4 | ||||||
| GET | /v2/kubernetes/clusters | List the Kubernetes clusters on the account. | read | kubernetes:read | Current | |
Fetching a cluster's kubeconfig uses kubernetes:access_cluster, which returns a credential with read-only Kubernetes access. Acts onkubernetes cluster Permission (capability) kubernetes:readVersionAvailable since the API’s base version Webhook eventNone Rate limitStandard limits apply SourceOfficial documentation ↗ | ||||||
| GET | /v2/kubernetes/clusters/{cluster_id} | Retrieve a single Kubernetes cluster by its ID. | read | kubernetes:read | Current | |
The alias scope api:read also covers this. Acts onkubernetes cluster Permission (capability) kubernetes:readVersionAvailable since the API’s base version Webhook eventNone Rate limitStandard limits apply SourceOfficial documentation ↗ | ||||||
| POST | /v2/kubernetes/clusters | Create a new Kubernetes cluster. | write | kubernetes:create | Current | |
Creating a cluster starts billing on the node pools. Acts onkubernetes cluster Permission (capability) kubernetes:createVersionAvailable since the API’s base version Webhook eventNone Rate limitStandard limits apply SourceOfficial documentation ↗ | ||||||
| DELETE | /v2/kubernetes/clusters/{cluster_id} | Delete a Kubernetes cluster. | write | kubernetes:delete | Current | |
Deleting a cluster destroys its nodes and the workloads running on them. Acts onkubernetes cluster Permission (capability) kubernetes:deleteVersionAvailable since the API’s base version Webhook eventNone Rate limitStandard limits apply SourceOfficial documentation ↗ | ||||||
DatabasesList managed database clusters, read a single cluster, and create a cluster.3 | ||||||
| GET | /v2/databases | List the managed database clusters on the account. | read | database:read | Current | |
Reading a cluster's connection credentials uses the separate database:view_credentials scope. Acts ondatabase cluster Permission (capability) database:readVersionAvailable since the API’s base version Webhook eventNone Rate limitStandard limits apply SourceOfficial documentation ↗ | ||||||
| GET | /v2/databases/{database_cluster_id} | Retrieve a single managed database cluster by its ID. | read | database:read | Current | |
The alias scope api:read also covers this. Acts ondatabase cluster Permission (capability) database:readVersionAvailable since the API’s base version Webhook eventNone Rate limitStandard limits apply SourceOfficial documentation ↗ | ||||||
| POST | /v2/databases | Create a new managed database cluster. | write | database:create | Current | |
Creating a cluster starts billing on the chosen engine, size, and node count. Acts ondatabase cluster Permission (capability) database:createVersionAvailable since the API’s base version Webhook eventNone Rate limitStandard limits apply SourceOfficial documentation ↗ | ||||||
Domains & DNSList and read domains, create and delete a domain, and list, create, update, and delete the DNS records inside a domain.7 | ||||||
| GET | /v2/domains | List the domains managed on the account. | read | domain:read | Current | |
The alias scope api:read also covers this. Acts ondomain Permission (capability) domain:readVersionAvailable since the API’s base version Webhook eventNone Rate limitStandard limits apply SourceOfficial documentation ↗ | ||||||
| POST | /v2/domains | Add a new domain to the account for DigitalOcean to manage DNS. | write | domain:create | Current | |
Passing an ip_address creates an A record for the domain automatically. Acts ondomain Permission (capability) domain:createVersionAvailable since the API’s base version Webhook eventNone Rate limitStandard limits apply SourceOfficial documentation ↗ | ||||||
| DELETE | /v2/domains/{domain_name} | Remove a domain and its DNS records from the account. | write | domain:delete | Current | |
Removing a domain drops every DNS record under it. Acts ondomain Permission (capability) domain:deleteVersionAvailable since the API’s base version Webhook eventNone Rate limitStandard limits apply SourceOfficial documentation ↗ | ||||||
| GET | /v2/domains/{domain_name}/records | List the DNS records in a domain. | read | domain:read | Current | |
The alias scope api:read also covers this. Acts ondns record Permission (capability) domain:readVersionAvailable since the API’s base version Webhook eventNone Rate limitStandard limits apply SourceOfficial documentation ↗ | ||||||
| POST | /v2/domains/{domain_name}/records | Create a DNS record in a domain, such as an A, CNAME, MX, or TXT record. | write | domain:create | Current | |
Adding or changing records steers where the domain's traffic goes. Acts ondns record Permission (capability) domain:createVersionAvailable since the API’s base version Webhook eventNone Rate limitStandard limits apply SourceOfficial documentation ↗ | ||||||
| PUT | /v2/domains/{domain_name}/records/{domain_record_id} | Update an existing DNS record in a domain. | write | domain:update | Current | |
PATCH on the same path also updates a record and uses domain:update. Acts ondns record Permission (capability) domain:updateVersionAvailable since the API’s base version Webhook eventNone Rate limitStandard limits apply SourceOfficial documentation ↗ | ||||||
| DELETE | /v2/domains/{domain_name}/records/{domain_record_id} | Delete a DNS record from a domain. | write | domain:delete | Current | |
Deleting a record can take part of the domain's traffic offline. Acts ondns record Permission (capability) domain:deleteVersionAvailable since the API’s base version Webhook eventNone Rate limitStandard limits apply SourceOfficial documentation ↗ | ||||||
Load balancersList load balancers, read a single load balancer, create one, and delete one.4 | ||||||
| GET | /v2/load_balancers | List the load balancers on the account. | read | load_balancer:read | Current | |
The alias scope api:read also covers this. Acts onload balancer Permission (capability) load_balancer:readVersionAvailable since the API’s base version Webhook eventNone Rate limitStandard limits apply SourceOfficial documentation ↗ | ||||||
| GET | /v2/load_balancers/{lb_id} | Retrieve a single load balancer by its ID. | read | load_balancer:read | Current | |
The alias scope api:read also covers this. Acts onload balancer Permission (capability) load_balancer:readVersionAvailable since the API’s base version Webhook eventNone Rate limitStandard limits apply SourceOfficial documentation ↗ | ||||||
| POST | /v2/load_balancers | Create a new load balancer. | write | load_balancer:create | Current | |
Creating a load balancer starts billing and routes traffic to the chosen Droplets. Acts onload balancer Permission (capability) load_balancer:createVersionAvailable since the API’s base version Webhook eventNone Rate limitStandard limits apply SourceOfficial documentation ↗ | ||||||
| DELETE | /v2/load_balancers/{lb_id} | Delete a load balancer. | write | load_balancer:delete | Current | |
Deleting a load balancer drops the traffic routing it provided. Acts onload balancer Permission (capability) load_balancer:deleteVersionAvailable since the API’s base version Webhook eventNone Rate limitStandard limits apply SourceOfficial documentation ↗ | ||||||
VolumesList block storage volumes, read a single volume, create a volume, and delete a volume.3 | ||||||
| GET | /v2/volumes | List the block storage volumes on the account. | read | block_storage:read | Current | |
The alias scope api:read also covers this. Acts onvolume Permission (capability) block_storage:readVersionAvailable since the API’s base version Webhook eventNone Rate limitStandard limits apply SourceOfficial documentation ↗ | ||||||
| POST | /v2/volumes | Create a new block storage volume. | write | block_storage:create | Current | |
A volume can be 1 GiB to 16 TiB and starts billing once created. Acts onvolume Permission (capability) block_storage:createVersionAvailable since the API’s base version Webhook eventNone Rate limitStandard limits apply SourceOfficial documentation ↗ | ||||||
| DELETE | /v2/volumes/{volume_id} | Delete a block storage volume. | write | block_storage:delete | Current | |
Deleting a volume destroys the data on it. Deleting by name uses DELETE /v2/volumes?name=NAME®ion=REGION. Acts onvolume Permission (capability) block_storage:deleteVersionAvailable since the API’s base version Webhook eventNone Rate limitStandard limits apply SourceOfficial documentation ↗ | ||||||
SnapshotsList saved snapshots of Droplets and volumes, read a single snapshot, and delete a snapshot.3 | ||||||
| GET | /v2/snapshots | List the saved snapshots of Droplets and volumes on the account. | read | snapshot:read | Current | |
The resource_type query parameter filters to droplet or volume snapshots. Acts onsnapshot Permission (capability) snapshot:readVersionAvailable since the API’s base version Webhook eventNone Rate limitStandard limits apply SourceOfficial documentation ↗ | ||||||
| GET | /v2/snapshots/{snapshot_id} | Retrieve a single snapshot by its ID. | read | snapshot:read | Current | |
The alias scope api:read also covers this. Acts onsnapshot Permission (capability) snapshot:readVersionAvailable since the API’s base version Webhook eventNone Rate limitStandard limits apply SourceOfficial documentation ↗ | ||||||
| DELETE | /v2/snapshots/{snapshot_id} | Delete a snapshot. | write | snapshot:delete | Current | |
Deleting a snapshot removes a saved restore point. Acts onsnapshot Permission (capability) snapshot:deleteVersionAvailable since the API’s base version Webhook eventNone Rate limitStandard limits apply SourceOfficial documentation ↗ | ||||||
FirewallsList cloud firewalls, read a single firewall, create a firewall, and delete one.4 | ||||||
| GET | /v2/firewalls | List the cloud firewalls on the account. | read | firewall:read | Current | |
The alias scope api:read also covers this. Acts onfirewall Permission (capability) firewall:readVersionAvailable since the API’s base version Webhook eventNone Rate limitStandard limits apply SourceOfficial documentation ↗ | ||||||
| POST | /v2/firewalls | Create a cloud firewall with inbound and outbound access rules. | write | firewall:create | Current | |
The request must contain at least one inbound or outbound rule. Acts onfirewall Permission (capability) firewall:createVersionAvailable since the API’s base version Webhook eventNone Rate limitStandard limits apply SourceOfficial documentation ↗ | ||||||
| PUT | /v2/firewalls/{firewall_id} | Update a cloud firewall by sending its complete representation. | write | firewall:update | Current | |
Any attribute left out of the request resets to its default, so the full firewall must be sent. Changing rules changes which traffic reaches the Droplets behind it. Acts onfirewall Permission (capability) firewall:updateVersionAvailable since the API’s base version Webhook eventNone Rate limitStandard limits apply SourceOfficial documentation ↗ | ||||||
| DELETE | /v2/firewalls/{firewall_id} | Delete a cloud firewall. | write | firewall:delete | Current | |
Deleting a firewall removes the traffic rules protecting its Droplets. Acts onfirewall Permission (capability) firewall:deleteVersionAvailable since the API’s base version Webhook eventNone Rate limitStandard limits apply SourceOfficial documentation ↗ | ||||||
Apps (App Platform)List apps, read a single app, create an app, create a deployment, and delete an app.5 | ||||||
| GET | /v2/apps | List the apps on the account running on App Platform. | read | app:read | Current | |
The alias scope api:read also covers this. Acts onapp Permission (capability) app:readVersionAvailable since the API’s base version Webhook eventNone Rate limitStandard limits apply SourceOfficial documentation ↗ | ||||||
| GET | /v2/apps/{id} | Retrieve a single App Platform app by its ID. | read | app:read | Current | |
Reading an app's live logs uses the same app:read scope. Acts onapp Permission (capability) app:readVersionAvailable since the API’s base version Webhook eventNone Rate limitStandard limits apply SourceOfficial documentation ↗ | ||||||
| POST | /v2/apps | Create a new App Platform app from a spec. | write | app:create | Current | |
Creating an app builds and runs code, and starts billing on its components. Acts onapp Permission (capability) app:createVersionAvailable since the API’s base version Webhook eventNone Rate limitStandard limits apply SourceOfficial documentation ↗ | ||||||
| POST | /v2/apps/{id}/deployments | Start a new deployment of an app, shipping the latest build to production. | write | app:update | Current | |
A deployment rolls new code live for the app. Acts onapp Permission (capability) app:updateVersionAvailable since the API’s base version Webhook eventNone Rate limitStandard limits apply SourceOfficial documentation ↗ | ||||||
| DELETE | /v2/apps/{id} | Delete an App Platform app. | write | app:delete | Current | |
Deleting an app takes its running services offline. Acts onapp Permission (capability) app:deleteVersionAvailable since the API’s base version Webhook eventNone Rate limitStandard limits apply SourceOfficial documentation ↗ | ||||||
ProjectsList projects, read a single project, and create a project.3 | ||||||
| GET | /v2/projects | List the projects on the account. | read | project:read | Current | |
The alias scope api:read also covers this. Acts onproject Permission (capability) project:readVersionAvailable since the API’s base version Webhook eventNone Rate limitStandard limits apply SourceOfficial documentation ↗ | ||||||
| GET | /v2/projects/{project_id} | Retrieve a single project by its ID. | read | project:read | Current | |
The alias scope api:read also covers this. Acts onproject Permission (capability) project:readVersionAvailable since the API’s base version Webhook eventNone Rate limitStandard limits apply SourceOfficial documentation ↗ | ||||||
| POST | /v2/projects | Create a new project to group resources on the account. | write | project:create | Current | |
A project organizes resources but does not itself start billing. Acts onproject Permission (capability) project:createVersionAvailable since the API’s base version Webhook eventNone Rate limitStandard limits apply SourceOfficial documentation ↗ | ||||||
Spaces keysList Spaces access keys, create a key, and delete a key.3 | ||||||
| GET | /v2/spaces/keys | List the Spaces access keys on the account. | read | spaces_key:read | Current | |
A Spaces access key is an S3-compatible credential for object storage. The secret is shown only once, at creation. Acts onspaces key Permission (capability) spaces_key:readVersionAvailable since the API’s base version Webhook eventNone Rate limitStandard limits apply SourceOfficial documentation ↗ | ||||||
| POST | /v2/spaces/keys | Create a new Spaces access key for S3-compatible object storage. | write | spaces_key:create | Current | |
A key can be read, readwrite, or fullaccess on a bucket, and fullaccess cannot be mixed with scoped permissions. Acts onspaces key Permission (capability) spaces_key:createVersionAvailable since the API’s base version Webhook eventNone Rate limitStandard limits apply SourceOfficial documentation ↗ | ||||||
| DELETE | /v2/spaces/keys/{access_key} | Delete a Spaces access key. | write | spaces_key:delete | Current | |
Deleting a key revokes the object storage credential it represents. Acts onspaces key Permission (capability) spaces_key:deleteVersionAvailable since the API’s base version Webhook eventNone Rate limitStandard limits apply SourceOfficial documentation ↗ | ||||||
AccountRead the account behind the token, including its email, status, and resource limits.1 | ||||||
| GET | /v2/account | Retrieve the account behind the token, including email, status, and resource limits. | read | account:read | Current | |
Returns the account holder's email, verification state, Droplet and floating IP limits, and team details. The alias scope api:read also covers this. Acts onaccount Permission (capability) account:readVersionAvailable since the API’s base version Webhook eventNone Rate limitStandard limits apply SourceOfficial documentation ↗ | ||||||
DigitalOcean does not push general resource events to a webhook URL the way some APIs do. An agent that needs current state polls the relevant endpoint, and the Monitoring and Uptime products can send alerts on their own channels.
| Event | What it signals | Triggered by |
|---|
DigitalOcean limits how fast an app or AI agent can call, through an hourly request quota and a per-minute burst quota counted against each token.
DigitalOcean limits each OAuth or personal access token to 5,000 requests per hour and 250 requests per minute as a burst ceiling. Every response carries the headers ratelimit-limit, ratelimit-remaining, and ratelimit-reset, where ratelimit-reset is a Unix timestamp for when the oldest request expires. Going over returns HTTP 429, and a burst-limit hit also carries a Retry-After header giving the seconds to wait. Some product areas, such as Functions, document their own additional limits.
List endpoints page through the page and per_page query parameters, where per_page defaults to 20 and tops out at 200. Each response includes a links object whose pages.next holds the URL of the next page, which should be followed rather than built by hand, and a meta object with the total count.
Requests and responses are JSON over HTTPS. There is no single documented payload size limit across the whole API; individual resources set their own bounds, such as a block storage volume ranging from 1 GiB to 16 TiB.
The status codes an agent should handle, and what to do about each.
| Status | Code | Meaning | What to do |
|---|---|---|---|
| 401 | unauthorized | Authentication is missing, or the token is invalid or expired. | Send a valid token in the Authorization header as a bearer credential. |
| 403 | forbidden | The token is valid but lacks the scope or team role for this call, such as a read-only token attempting a write. | Recreate the token with the scope the call needs, since scopes cannot be edited after creation. |
| 404 | not_found | The resource does not exist, or the token cannot see it. | Confirm the ID in the path and that the token has access to the resource. |
| 422 | unprocessable_entity | The request was well-formed but a field is missing or invalid, such as a firewall created with no rules. | Read the message field, correct the named input, and resend. |
| 429 | too_many_requests | A rate limit was exceeded, either the hourly quota or the per-minute burst. | Wait for the window to reset, using the ratelimit-reset header, or honor the Retry-After header on a burst limit before retrying. |
| 500 | server_error | An unexpected error occurred on DigitalOcean's side. | Retry after a short delay, and quote the request_id from the error body if contacting support. |
DigitalOcean exposes a single, continuously updated version of its API at the v2 path. There is no dated version header to pin, and changes ship through release notes.
The v2 API is the single, continuously updated version, served at the v2 path with no dated version header to pin. It left beta in 2015, replacing the retired v1, and has shipped features since through dated release notes rather than new version numbers. Recent additions include custom scopes for personal access tokens and identifiable token prefixes.
Custom scopes for personal access tokens reached general availability, after a feature preview that began on 15 March 2024. A token can now be created with granular resource:action permissions, such as droplet:create or firewall:update, rather than only the broad Read Only or Full Access options. Kubernetes kubeconfig and credentials endpoints began returning tokens scoped for read-only cluster access on 8 April 2024.
DigitalOcean added a Retry-After header to the 429 responses returned when the per-minute burst rate limit is hit, so a client can read exactly how many seconds to wait before retrying. It was released on 24 August 2023.
API tokens gained identifiable prefixes so the type of a credential is clear at a glance: dop_v1_ for a personal access token, doo_v1_ for an OAuth token, and dor_v1_ for a refresh token. It was released on 29 March 2022.
There is one live version, so an integration tracks the release notes rather than pinning a date.
DigitalOcean API release notes ↗Bollard AI sits between a team's AI agents and DigitalOcean. Grant each agent exactly the access it needs, read or write, resource by resource, and every call is checked and logged.