API Overview
This guide explains how to use the kopernik.us API as a standalone service. For console-specific guidance, see the Web Application Documentation.
See Terms of Use before using the service.
Overview
The kopernik.us REST API provides a unified way to discover and manage cloud resources across Akamai, AWS, and DigitalOcean.
Base URL:
https://api.kopernik.us/v0
Documentation Map
The documentation is split into three layers:
- API guides: descriptive pages for API concepts such as authentication, machines, VPCs, container apps, and actions
- API reference: generated OpenAPI reference for paths, parameters, and schemas
- Web application documentation: console workflows and UI behavior
Authentication Quick Start
To call the API, exchange provider credentials for a kopernik.us bearer token.
Your provider credentials must be able to read account identity information, because kopernik.us uses the provider account ID to build stable resource identifiers.
Provider credential setup:
Exchange a provider token
Use POST /auth/authorize/{providerUid}. The optional accessLevel field is readwrite or readonly, and defaults to readwrite.
curl -sS \
-X POST "https://api.kopernik.us/v0/auth/authorize/digitalocean" \
-H "Content-Type: application/json" \
-d '{
"accessToken": "your-provider-token",
"accessLevel": "readwrite"
}'
Example response:
{
"metadata": {
"uid": "unique-request-id",
"timestamp": 1697500000
},
"signedAuth": "eyJhbGc..."
}
Use the returned token in later requests:
Authorization: Bearer eyJhbGc...
Access levels
readonlyallows listing and reading resourcesreadwriteadditionally allows create and delete requests
kopernik.us enforces the declared access level, but provider-side permissions still determine what the underlying cloud API will allow.
Core Request Patterns
See the generated API reference for full request and schema details. The patterns below cover the common workflow.
List resources
curl -sS \
"https://api.kopernik.us/v0/resource/machine/digitalocean?maxResults=20" \
-H "Authorization: Bearer eyJhbGc..."
Get one resource
curl -sS \
"https://api.kopernik.us/v0/resource/machine/digitalocean/12345678" \
-H "Authorization: Bearer eyJhbGc..."
Start a long-running create operation
Most POST and DELETE resource operations are asynchronous.
curl -sS \
-X POST "https://api.kopernik.us/v0/resource/machine/digitalocean?waitTime=5" \
-H "Authorization: Bearer eyJhbGc..." \
-H "Content-Type: application/json" \
-d '{
"name": "my-server",
"regionUid": "nyc1",
"imageUid": "ubuntu-22-04-x64",
"machineTypeUid": "s-1vcpu-1gb"
}'
If the action finishes within waitTime, the API returns 200.
If it is still running, the API returns 202.
In both cases the response body contains an Action.
Poll action status
curl -sS \
"https://api.kopernik.us/v0/action/digitalocean/<actionUid>" \
-H "Authorization: Bearer eyJhbGc..."
Resource Model
Most resources share these identity fields:
type: normalized kopernik.us resource typeproviderUid:akamai,aws, ordigitaloceanregionUid: provider region, when the resource is regionalaccountUid: provider account identifieruid: provider-side resource identifier within the account or provider scopegrid: globally unique kopernik.us resource identifier
Resource type map
| Resource type | Akamai | AWS | DigitalOcean |
|---|---|---|---|
account |
Account | IAM User | Account |
blockstorage |
Volume | EBS | Volume |
bucket |
Object Storage | S3 | Spaces |
containerapp |
Managed machine + Docker | EC2 + Docker | Droplet + Docker |
firewall |
Firewall | EC2 security group | Firewall |
image |
Image | EC2 image | Image |
kubernetes |
Linode Kubernetes Engine | EKS cluster | Kubernetes |
machine |
Linode | EC2 instance | Droplet |
machinetype |
Linode type | EC2 instance type | Droplet size |
region |
Region | Region | Region |
sshkey |
SSH key | EC2 key pair | SSH key |
vpc |
VPC | EC2 VPC | VPC |
Operation Model
Create and delete operations usually return Action objects rather than final resource payloads.
For the full asynchronous execution model, see Actions and asynchronous operations.
Filters, Pagination, and Metadata
Pagination
List endpoints commonly support:
nextTokento continue from a previous pagemaxResultsto cap page size
When more results are available, the response includes nextToken.
JQ filters
List endpoints support JQ 1.7 expressions through the jq query parameter.
Example:
curl -sS \
'https://api.kopernik.us/v0/resource/machinetype/akamai?jq=.name | contains("g7")' \
-H "Authorization: Bearer eyJhbGc..."
Response metadata
Successful and error responses include:
metadata.uid: request identifiermetadata.timestamp: Unix timestamp in seconds
Error responses also include:
reason: human-readable error details
Security Considerations
The API server has access only to resources provided by corresponding cloud provider’s API, and cannot access:
- your machine’s processes or memory,
- data stored on your accounts’s volumes, or machine disks,
- passwords or private SSH keys used for creating machine instances.
The server may log to disk request arguments and certain response fields, which may contain sensitive data, directly or indirectly. Example of such data includes: resource names, labels, tags, etc. Do not use sensitive data in your resource properties if this is a concern for you.
The API server never stores your API keys on disk or database. It also has no access to private keys when dealing with SSH key resources.
You can revoke Personal Access Token or OAuth token from your cloud provider’s account management page at any time. All tokens registered at the kopernik.us API server will be automatically invalidated.
Important: always provide least permissive access to your resources.
Provider Support
| Provider | Akamai | AWS | DigitalOcean |
|---|---|---|---|
| Provider uid for API use | akamai |
aws |
digitalocean |
| Access mechanism | Personal Access Token, OAuth (*) | IAM user access key | Personal Access Token, OAuth (*) |
Use in /auth/authorize endpoint |
Personal access token | access key or keypair | Personal access token |
(*) OAuth can be used via Console / Accounts interface.
Required Provider-Specific Permissions
| Resource type | Operation | Akamai | AWS | DigitalOcean | Notes |
|---|---|---|---|---|---|
account |
GET | Account:Read | iam:GetUser |
Read | REQUIRED - used to construct authentication token |
blockstorage |
GET | Volumes:Read | ec2:DescribeVolumes |
Read | |
| POST | Volumes:Write | ec2:CreateVolume |
Write | ||
| DELETE | Volumes:Write | ec2:DeleteVolume |
Write | ||
bucket |
GET | Object Storage:Read | s3:ListAllMyBuckets |
(*) | DigitalOcean uses separate credentials — see below |
| POST | Object Storage:Write | s3:CreateBucket |
(*) | ||
| DELETE | Object Storage:Write | s3:DeleteBucket |
(*) | Bucket must be empty | |
containerapp |
GET | Linodes:Read | ec2:DescribeInstances |
Read | Container apps are backed by provider machines |
| POST | Linodes:Write | ec2:RunInstances |
Write | Also needs machine-related dependencies below | |
| DELETE | Linodes:Write | ec2:TerminateInstances |
Write | ||
domainrecord |
GET | Domains:Read | route53:ListResourceRecordSets |
Read | |
| POST | Domains:Write | route53:CreateResourceRecordSet |
Write | ||
domainzone |
GET | Domains:Read | route53:ListHostedZones |
Read | |
route53:GetHostedZone |
|||||
| POST | Domains:Write | route53:CreateHostedZone |
Write | ||
firewall |
GET | Firewalls:Read | ec2:DescribeSecurityGroups |
Read | |
| POST | Firewalls:Write | ec2:CreateSecurityGroup |
Write | ||
| DELETE | Firewalls:Write | ec2:DeleteSecurityGroup |
Write | ||
image |
GET | Images:Read | ec2:DescribeImages |
Read | |
ssm:GetParametersByPath |
|||||
kubernetes |
GET | Kubernetes:Read | eks:ListClusters |
Read | |
eks:DescribeCluster |
|||||
eks:ListNodegroups |
|||||
eks:DescribeNodegroup |
|||||
| POST | Kubernetes:Write | eks:CreateCluster |
Write | ||
eks:CreateNodegroup |
|||||
iam:GetRole |
Applied to IAM Role selected for EKS cluster / node pool | ||||
iam:PassRole |
Applied to IAM Role selected for EKS cluster / node pool | ||||
| DELETE | Kubernetes:Write | eks:DeleteCluster |
Write | ||
eks:DeleteNodegroup |
|||||
machine |
GET | Linodes:Read | ec2:DescribeInstances |
Read | |
| POST | Linodes:Write | ec2:RunInstances |
Write | ||
ec2:DescribeSubnets |
REQUIRED to decide whether a machine is public | ||||
| DELETE | Linodes:Write | ec2:TerminateInstances |
Write | ||
machinetype |
GET | Not required | ec2:DescribeInstanceTypes |
Read | |
region |
GET | Not required | ec2:DescribeAvailabilityZones |
Not required | |
sshkey |
GET | Account:Read | ec2:DescribeKeyPairs |
Read | |
| POST | Account:Write | ec2:ImportKeyPair |
Write | ||
| DELETE | Account:Write | ec2:DeleteKeyPair |
Write | ||
vpc |
GET | VPCs:Read | ec2:DescribeVpcs,ec2:DescribeSubnets |
Read | |
ec2:DescribeRouteTables |
Optional; without it subnet access is unset |
||||
| POST | VPCs:Write | ec2:CreateVpc,ec2:CreateSubnet |
Write | ||
ec2:CreateInternetGateway |
REQUIRED to create a public subnet |
||||
ec2:AttachInternetGateway |
|||||
ec2:CreateRouteTable |
|||||
ec2:CreateRoute |
|||||
ec2:AssociateRouteTable |
|||||
ec2:ModifySubnetAttribute |
|||||
ec2:AllocateAddress |
REQUIRED to create a private subnet |
||||
ec2:CreateNatGateway |
|||||
ec2:DescribeNatGateways |
|||||
| DELETE | VPCs:Write | ec2:DeleteVpc,ec2:DeleteSubnet |
Write | ||
ec2:DeleteNatGateway |
Needed to delete a VPC holding a NAT gateway | ||||
ec2:ReleaseAddress |
|||||
ec2:DescribeAddresses |
|||||
* |
POST | ec2:CreateTags |
REQUIRED |
Notes:
(*) DigitalOcean Spaces authenticates with an S3 access key that is separate from the account’s main API
credentials (the personal access token or OAuth token used by every other resource type). That key cannot be derived
from the main credentials, so it must be attached to the account as its bucket service token — see
Service tokens; bucket operations are refused until it is. The key needs
Full Access: with a key limited to specific buckets, they fail with 403 and the error code
insufficientServiceCredentials. Akamai Object Storage is managed with the account’s main credentials, and AWS S3
reuses the account’s existing access key.
For AWS, it is highly recommended to always provide *.Delete<Resource> permission along with *.Create<Resource> so
that the API server can correctly rollback changes if Create operation succeeds partially.
Container apps also depend on the permissions needed to select images, machine types, regions, VPCs, SSH keys, and storage, because the API creates a backing machine on your behalf.
Supported Operations
| Resource type | Get | List | Delete | Create |
|---|---|---|---|---|
account |
✅ | ✅ | ❌ | ❌ |
blockstorage |
✅ | ✅ | ✅ | ✅ |
bucket (*) |
✅ | ✅ | ✅ | ✅ |
containerapp |
✅ | ✅ | ✅ | ✅ |
domainrecord |
✅ | ✅ | ✅ | ✅ |
domainzone |
✅ | ✅ | ✅ | ✅ |
firewall |
✅ | ✅ | ✅ | ✅ |
image |
✅ | ✅ | ❌ | ❌ |
kubernetes |
✅ | ✅ | ✅ | ✅ |
machine |
✅ | ✅ | ✅ | ✅ |
machinetype |
✅ | ✅ | ❌ | ❌ |
region |
✅ | ✅ | ❌ | ❌ |
sshkey |
✅ | ✅ | ✅ | ✅ |
vpc |
✅ | ✅ | ✅ | ✅ |
(*) DigitalOcean requires separate object storage credentials, as described in Required Provider-Specific Permissions.