TL;DR
DigitalOcean APIs manage droplets, volumes, firewalls, load balancers, Kubernetes clusters, and more. Authenticate with personal access tokens, call api.digitalocean.com/v2, and handle rate limits. For testing, use Apidog to validate configurations, test infrastructure provisioning, and document your automation workflows.
Introduction
DigitalOcean focuses on core cloud infrastructure: compute (Droplets), storage (Volumes), networking (Floating IPs and firewalls), managed Kubernetes, and App Platform. Its API follows the same straightforward model.
Use the DigitalOcean API to:
- Spin up development environments automatically
- Manage Kubernetes clusters
- Provision infrastructure through Terraform or Pulumi
- Create resources from CI/CD pipelines
- Deploy across multiple regions
If you are automating infrastructure, Apidog can help you test API calls, save infrastructure configurations as reusable templates, and collaborate on provisioning workflows.
Authentication
Create a personal access token
- Open the DigitalOcean Dashboard.
- Go to API.
- Select Generate New Token.
- Name the token, set its expiration, and copy it.
- Store the token securely—do not commit it to source control.
Set it as an environment variable:
export DIGITALOCEAN_TOKEN="YOUR_TOKEN"
Verify that the token works:
curl -X GET "https://api.digitalocean.com/v2/account" \
-H "Authorization: Bearer $DIGITALOCEAN_TOKEN"
Example response:
{
"account": {
"droplet_limit": 25,
"email": "you@example.com",
"name": "Your Name",
"uuid": "abc123xyz",
"email_verified": true,
"status": "active"
}
}
Droplets (virtual machines)
List all Droplets
curl -X GET "https://api.digitalocean.com/v2/droplets" \
-H "Authorization: Bearer $DIGITALOCEAN_TOKEN"
Create a Droplet
curl -X POST "https://api.digitalocean.com/v2/droplets" \
-H "Authorization: Bearer $DIGITALOCEAN_TOKEN" \
-H "Content-Type: application/json" \
-d '{
"name": "my-droplet",
"region": "nyc1",
"size": "s-2vcpu-4gb",
"image": "ubuntu-20-04-x64",
"ssh_keys": ["ssh-rsa AAAA..."],
"backups": false,
"ipv6": true,
"tags": ["web", "production"]
}'
Common Droplet sizes:
| Size | vCPUs | RAM | Price |
|---|---|---|---|
s-1vcpu-1gb |
1 | 1 GB | $5/mo |
s-2vcpu-2gb |
2 | 2 GB | $10/mo |
s-2vcpu-4gb |
2 | 4 GB | $20/mo |
s-4vcpu-8gb |
4 | 8 GB | $40/mo |
Example regions:
-
nyc1,nyc3— New York -
sfo3— San Francisco -
ams3— Amsterdam -
sgp1— Singapore
Get Droplet details
curl -X GET "https://api.digitalocean.com/v2/droplets/DROPLET_ID" \
-H "Authorization: Bearer $DIGITALOCEAN_TOKEN"
Delete a Droplet
curl -X DELETE "https://api.digitalocean.com/v2/droplets/DROPLET_ID" \
-H "Authorization: Bearer $DIGITALOCEAN_TOKEN"
Run Droplet actions
Reboot a Droplet:
curl -X POST "https://api.digitalocean.com/v2/droplets/DROPLET_ID/actions" \
-H "Authorization: Bearer $DIGITALOCEAN_TOKEN" \
-H "Content-Type: application/json" \
-d '{
"type": "reboot"
}'
Resize a Droplet:
curl -X POST "https://api.digitalocean.com/v2/droplets/DROPLET_ID/actions" \
-H "Authorization: Bearer $DIGITALOCEAN_TOKEN" \
-H "Content-Type: application/json" \
-d '{
"type": "resize",
"size": "s-4vcpu-8gb"
}'
Create a snapshot:
curl -X POST "https://api.digitalocean.com/v2/droplets/DROPLET_ID/actions" \
-H "Authorization: Bearer $DIGITALOCEAN_TOKEN" \
-H "Content-Type: application/json" \
-d '{
"type": "snapshot",
"name": "my-snapshot"
}'
Volumes (block storage)
Create a Volume
curl -X POST "https://api.digitalocean.com/v2/volumes" \
-H "Authorization: Bearer $DIGITALOCEAN_TOKEN" \
-H "Content-Type: application/json" \
-d '{
"size_gigabytes": 100,
"name": "my-volume",
"region": "nyc1",
"description": "Data volume for web servers"
}'
Attach a Volume to a Droplet
curl -X POST "https://api.digitalocean.com/v2/volumes/VOLUME_ID/actions" \
-H "Authorization: Bearer $DIGITALOCEAN_TOKEN" \
-H "Content-Type: application/json" \
-d '{
"type": "attach",
"droplet_id": DROPLET_ID
}'
List Volumes
curl -X GET "https://api.digitalocean.com/v2/volumes" \
-H "Authorization: Bearer $DIGITALOCEAN_TOKEN"
Networking
List Floating IPs
curl -X GET "https://api.digitalocean.com/v2/floating_ips" \
-H "Authorization: Bearer $DIGITALOCEAN_TOKEN"
Assign a Floating IP
curl -X POST "https://api.digitalocean.com/v2/floating_ips" \
-H "Authorization: Bearer $DIGITALOCEAN_TOKEN" \
-H "Content-Type: application/json" \
-d '{
"droplet_id": DROPLET_ID,
"region": "nyc1"
}'
Create a firewall
This firewall allows HTTP and HTTPS traffic from anywhere, while limiting SSH access to your IP address.
curl -X POST "https://api.digitalocean.com/v2/firewalls" \
-H "Authorization: Bearer $DIGITALOCEAN_TOKEN" \
-H "Content-Type: application/json" \
-d '{
"name": "web-firewall",
"inbound_rules": [
{
"protocol": "tcp",
"ports": "80",
"sources": {
"addresses": ["0.0.0.0/0"]
}
},
{
"protocol": "tcp",
"ports": "443",
"sources": {
"addresses": ["0.0.0.0/0"]
}
},
{
"protocol": "tcp",
"ports": "22",
"sources": {
"addresses": ["your-ip/32"]
}
}
],
"outbound_rules": [
{
"protocol": "tcp",
"ports": "80",
"destinations": {
"addresses": ["0.0.0.0/0"]
}
}
],
"droplet_ids": [DROPLET_ID]
}'
Load balancers
Create a load balancer
curl -X POST "https://api.digitalocean.com/v2/load_balancers" \
-H "Authorization: Bearer $DIGITALOCEAN_TOKEN" \
-H "Content-Type: application/json" \
-d '{
"name": "my-lb",
"region": "nyc1",
"algorithm": "round_robin",
"health_check": {
"protocol": "http",
"port": 80,
"path": "/",
"check_interval_seconds": 10,
"response_timeout_seconds": 5,
"healthy_threshold": 3,
"unhealthy_threshold": 3
},
"forwarding_rules": [
{
"entry_protocol": "http",
"entry_port": 80,
"target_protocol": "http",
"target_port": 80
},
{
"entry_protocol": "https",
"entry_port": 443,
"target_protocol": "https",
"target_port": 443,
"tls_passthrough": true
}
],
"droplet_ids": [DROPLET_ID_1, DROPLET_ID_2]
}'
Kubernetes clusters
Create a Kubernetes cluster
curl -X POST "https://api.digitalocean.com/v2/kubernetes/clusters" \
-H "Authorization: Bearer $DIGITALOCEAN_TOKEN" \
-H "Content-Type: application/json" \
-d '{
"name": "my-cluster",
"region": "nyc1",
"version": "1.28",
"node_pools": [
{
"name": "worker-pool",
"size": "s-2vcpu-4gb",
"count": 3,
"auto_scale": true,
"min_nodes": 2,
"max_nodes": 6
}
]
}'
List node pools
curl -X GET "https://api.digitalocean.com/v2/kubernetes/clusters/CLUSTER_ID/node_pools" \
-H "Authorization: Bearer $DIGITALOCEAN_TOKEN"
Scale a node pool
curl -X PUT "https://api.digitalocean.com/v2/kubernetes/clusters/CLUSTER_ID/node_pools/POOL_ID" \
-H "Authorization: Bearer $DIGITALOCEAN_TOKEN" \
-H "Content-Type: application/json" \
-d '{
"count": 5
}'
Delete a cluster
curl -X DELETE "https://api.digitalocean.com/v2/kubernetes/clusters/CLUSTER_ID" \
-H "Authorization: Bearer $DIGITALOCEAN_TOKEN"
Testing with Apidog
Infrastructure provisioning costs money, so validate requests before creating resources.
1. Configure environments
Create an environment with these variables:
DIGITALOCEAN_TOKEN: your_token
BASE_URL: https://api.digitalocean.com/v2
DEFAULT_REGION: nyc1
DEFAULT_SIZE: s-2vcpu-4gb
Use them in requests, for example:
{{BASE_URL}}/droplets
Authorization: Bearer {{DIGITALOCEAN_TOKEN}}
2. Validate API responses
Add tests after a create-Droplet request:
pm.test("Droplet created successfully", () => {
const response = pm.response.json()
pm.expect(response.droplet).to.have.property("id")
pm.expect(response.droplet.status).to.eql("new")
})
Test token validity with the account endpoint:
pm.test("Token is valid", () => {
const response = pm.response.json()
pm.expect(response.account).to.exist
pm.expect(response.account.status).to.eql("active")
})
3. Validate inputs before provisioning
DigitalOcean does not offer true dry runs, but you can validate request data before sending a provisioning request.
const validRegions = ["nyc1", "sfo3", "ams3", "sgp1"]
const validSizes = ["s-1vcpu-1gb", "s-2vcpu-2gb", "s-2vcpu-4gb"]
pm.test("Region is valid", () => {
const requestBody = JSON.parse(pm.request.body.raw)
pm.expect(validRegions).to.include(requestBody.region)
})
pm.test("Size is valid", () => {
const requestBody = JSON.parse(pm.request.body.raw)
pm.expect(validSizes).to.include(requestBody.size)
})
Test DigitalOcean infrastructure APIs with Apidog before running provisioning workflows.
Common errors and fixes
401 Unauthorized
Cause: Invalid or expired token.
Fix: Regenerate the token in the DigitalOcean dashboard and verify the header format:
Authorization: Bearer YOUR_TOKEN
422 Unprocessable Entity
Cause: Invalid parameters, such as an unsupported region, size, or image.
Fix: Check valid values in the DigitalOcean API documentation. Common causes include:
- The selected region does not support the requested size.
- The image ID does not exist.
- Your Droplet limit has been reached.
429 Too Many Requests
Cause: The rate limit was exceeded (default: 2000 requests per hour).
Fix: Retry with exponential backoff:
async function doRequest(url, options, retries = 3) {
for (let i = 0; i < retries; i++) {
const response = await fetch(url, options)
if (response.status === 429) {
await sleep(Math.pow(2, i) * 1000)
continue
}
return response
}
throw new Error("Rate limited")
}
Droplet limit reached
Cause: Your account has too many Droplets.
Fix: Delete unused Droplets or request a limit increase through support.
Alternatives and comparisons
| Feature | DigitalOcean | AWS | GCP |
|---|---|---|---|
| Droplet sizes | Fixed | Custom | Custom |
| Kubernetes | Managed DOKS | EKS | GKE |
| Object storage | Spaces | S3 | Cloud Storage |
| Block storage | Volumes | EBS | Persistent Disk |
| Load balancers | Built-in | ELB | Cloud Load Balancing |
| Free tier | $200 credit | Limited | $300 credit |
| API simplicity | ★★★★★ | ★★☆☆☆ | ★★★☆☆ |
DigitalOcean prioritizes simplicity. Most API operations work without navigating dozens of nested services.
Real-world use cases
Per-branch development environments
A startup creates an isolated development environment for every pull request:
- A PR triggers an API call that creates a Droplet with the latest code.
- Developers test against a production-like environment.
- The deployment pipeline deletes the Droplet after merge.
This reduces manual setup while keeping temporary infrastructure isolated.
Auto-scaling web servers
A web application monitors CPU load:
- When CPU exceeds 70%, automation creates additional Droplets.
- The new Droplets are added to the load balancer.
- When load falls, automation destroys unneeded Droplets.
This keeps capacity aligned with demand.
Database clusters
A managed database service can provision primary and replica Volumes across regions. The API handles replication configuration, backup scheduling, and failover setup automatically.
Conclusion
You can now:
- Authenticate with personal access tokens
- Create and manage Droplets programmatically
- Use Volumes for persistent storage
- Configure firewalls and load balancers
- Manage Kubernetes clusters
- Test infrastructure requests with Apidog before provisioning
FAQ
How much does a Droplet cost?
Prices start at $5/month for 1 vCPU and 1 GB RAM. Check the pricing page for current rates. Hourly billing is available.
Can I use SSH keys with API-created Droplets?
Yes. Include the SSH key fingerprint in the ssh_keys array when creating a Droplet.
What is the difference between Volumes and Spaces?
Volumes are block storage attached to Droplets. Spaces is object storage, similar to S3. Use Volumes for databases and Spaces for files.
How do I get the Kubernetes config?
curl -X GET "https://api.digitalocean.com/v2/kubernetes/clusters/CLUSTER_ID/kubeconfig" \
-H "Authorization: Bearer $DIGITALOCEAN_TOKEN"
Can I resize a Droplet?
Yes. Use the resize action. Downgrades require powering off the Droplet; upgrades can be done while it is running.
What is the difference between backups and snapshots?
Backups are automatic weekly or daily copies managed by DigitalOcean. Snapshots are manual, on-demand images that you create.
How long do Droplets take to create?
Usually 30–60 seconds. Some regions and sizes may take longer.
Can I use Terraform with DigitalOcean?
Yes. DigitalOcean has an official Terraform provider for infrastructure as code.

Top comments (0)