Reference

API reference

prgd API 1. Generated from openapi.yaml, which you can also feed to any client generator. Read the API guide first for auth, idempotency and errors.

auth

POST/v1/auth/signupno auth

Create a user, team and default project

Request body
email*string
password*string
name*string
teamName*string
countrystring
localestringone of en, tr, ar
Responses
  • 201 Created
  • 409 Conflict
POST/v1/auth/loginno auth

Log in and receive a session token

When the user has two factor sign in, the first call answers 401 totp_required; repeat it with totp set to the six digit authenticator code or an unused recovery code. Team owners must enable two factor when REQUIRE_TOTP_FOR_OWNERS is on; until then console sessions get 403 totp_setup_required on every route except the account and two factor endpoints. API tokens are exempt.

Request body
email*string
password*string
totpstring
Responses
  • 200 OK
  • 401 Wrong email or password, `totp_required`, or `password_not_set` for an account that signs in only with Google or Microsoft (`details.providers` names them)
POST/v1/auth/verifyno auth

Confirm an email address with the token from the verification email

Request body
token*string
Responses
  • 200 OK
  • 400 Token invalid or expired (`token_invalid`)
POST/v1/auth/verify/request

Send the verification email again for the signed in user

Responses
  • 204 Sent (or already verified)
POST/v1/auth/password/forgotno auth

Send a password reset link

Always returns 204 so email addresses cannot be probed. Limited to 5 requests per 10 minutes per IP.

Request body
email*string
Responses
  • 204 Accepted
POST/v1/auth/password/resetno auth

Set a new password with the token from the reset email

Request body
token*string
password*string
Responses
  • 200 OK
  • 400 Token invalid or expired (`token_invalid`)
POST/v1/auth/totp/setup

Start two factor enrollment

Returns a new secret and an otpauth:// URL to show as a QR code. Nothing is enforced until /auth/totp/enable confirms a code.

Responses
  • 201 OK
  • 409 Already enabled (`totp_enabled`)
POST/v1/auth/totp/enable

Confirm the authenticator and turn two factor on

Returns ten recovery codes exactly once. Each recovery code signs the user in a single time.

Request body
code*stringSix digit authenticator code
Responses
  • 201 OK
  • 401 Code not valid (`totp_invalid`)
POST/v1/auth/totp/disable

Turn two factor off (needs a current code or a recovery code)

Request body
code*stringSix digit authenticator code
Responses
  • 201 OK
  • 401 Code not valid (`totp_invalid`)
GET/v1/auth/providersno auth

Social sign in providers that are configured (the console shows a button for each)

Responses
  • 200 OK
GET/v1/auth/oauth/{provider}/startno auth

Start sign in with Google or Microsoft (the browser navigates here)

Redirects to the provider with the authorization code flow, PKCE (S256), state and nonce, scopes openid email profile. Sets an HttpOnly, Secure, SameSite=Lax cookie that binds the sign in to this browser; the pending state lives on the server for 10 minutes. intent=link needs a ticket from POST /auth/oauth/link-ticket. Errors redirect to the console /auth/callback?error=<code>.

Parameters
provider (path)*stringone of google, microsoft
intent (query)stringone of login, signup, link
return (query)stringConsole path to land on afterwards
invite (query)stringInvitation token; a new account joins that team instead of creating one
ticket (query)stringOne time link ticket (intent link)
locale (query)stringone of en, tr, ar
Responses
  • 302 Redirect to the provider
GET/v1/auth/oauth/{provider}/callbackno auth

Provider redirect URI

Checks state and the browser cookie, exchanges the code with the PKCE verifier, verifies the id token (signature against the provider key set, audience, issuer, nonce) and redirects to the console /auth/callback?code=<one time code> (valid 60 seconds). Session tokens never appear in URLs. Error codes: state_invalid, cancelled, provider_error, token_invalid, link_from_security, identity_in_use, email_missing, account_exists, invite_email_mismatch, invite_invalid, link_session_invalid.

Parameters
provider (path)*stringone of google, microsoft
Responses
  • 302 Redirect to the console
POST/v1/auth/oauth/exchangeno auth

Redeem the one time code from the console callback

Same answer as /auth/login, plus created and returnTo. Accounts with two factor sign in get { totpRequired, ticket } instead; finish with /auth/oauth/totp.

Request body
code*string
Responses
  • 200 OK
  • 400 Code unknown
  • 403 Staff account without two factor sign in (`totp_setup_required`)
POST/v1/auth/oauth/totpno auth

Second factor for a social sign in

Request body
ticket*string
code*string
Responses
  • 200 OK
  • 400 Ticket expired or used (`ticket_invalid`); five wrong codes end it
  • 401 Code not valid (`totp_invalid`)
POST/v1/auth/oauth/link-ticket

One time ticket (60 seconds) to link Google or Microsoft to the signed in user

Console sessions only; API tokens get 403. Pass it to /auth/oauth/{provider}/start?intent=link&ticket=….

Responses
  • 201 OK

account

GET/v1/account/identities

Linked Google and Microsoft accounts, whether a password is set, and which providers can be linked

Responses
  • 200 OK
DELETE/v1/account/identities/{id}

Unlink a Google or Microsoft account

Parameters
id (path)*string
Responses
  • 204 Unlinked
  • 409 It is the only way left to sign in (`last_sign_in_method`)
GET/v1/account

Current user, team, role and scopes

Responses
  • 200 OK
GET/v1/projects

List projects

Responses
  • 200 OK
POST/v1/projects

Create a project

Request body
name*string
slug*string
spendLimitMinorinteger
Responses
  • 201 Created
GET/v1/tokens

List API tokens

Responses
  • 200 OK
POST/v1/tokens

Create an API token (human or AI agent)

Agent-safe tokens set isAgent: true and may carry spendCapMinor (monthly hard cap) and requireApprovalFor (e.g. ["servers:delete","servers:resize-down"]). A token can never carry scopes its creator does not have.

Request body
name*string
scopes*string[]
projectIdstring
isAgentboolean
spendCapMinorinteger
requireApprovalForstring[]e.g. ["servers:delete","servers:resize-down"]
expiresInDaysinteger
Responses
  • 201 Created — `token` is shown once
DELETE/v1/tokens/{id}

Revoke a token

Parameters
id (path)*string
Responses
  • 204 Revoked
GET/v1/audit

Team audit log (newest 200 entries)

Responses
  • 200 OK
POST/v1/interest

Register interest in a roadmap product ("notify me when this launches")

Request body
product*stringe.g. "inference"
notestring
Responses
  • 204 Recorded
GET/v1/ssh-keys

List SSH keys

Responses
  • 200 OK
POST/v1/ssh-keys

Add an SSH public key

Request body
name*string
publicKey*string
Responses
  • 201 Created
DELETE/v1/ssh-keys/{id}

Delete an SSH key

Parameters
id (path)*string
Responses
  • 204 Deleted

approvals

GET/v1/approvals

List approval requests (agents see only their own)

Parameters
status (query)stringone of pending, approved, denied, expired, failed
Responses
  • 200 OK
GET/v1/approvals/{id}

Get one approval request

Parameters
id (path)*string
Responses
  • 200 OK
  • 404 Not found
POST/v1/approvals/{id}/approve

Approve and run the parked request

Team owners and admins only, never an agent token. The request runs with the agent token's project scope and spending cap still applied; the audit log records both the person and the token.

Parameters
id (path)*string
Responses
  • 201 Ran
  • 403 Forbidden
  • 409 Already decided or expired (`invalid_state`)
POST/v1/approvals/{id}/deny

Deny the parked request

Parameters
id (path)*string
Request body
reasonstring
Responses
  • 201 Denied

monitoring

GET/v1/servers/{id}/metrics

Time series for a server

One point per minute for 1h, 6h and 24h; hourly averages (with the hour's CPU peak) for 7d and 30d. Network and disk are bytes per second; multiply by 8 and divide by a million for Mbps.

Parameters
id (path)*string
period (query)stringone of 1h, 6h, 24h, 7d, 30d
Responses
  • 200 OK
GET/v1/alerts

List alert rules

Responses
  • 200 OK
POST/v1/alerts

Create an alert rule

Fires when the metric, averaged over windowMinutes, is above or below the threshold on any matching server. Empty serverIds and tags means every server in the team. Owners and admins are emailed, plus any addresses in emails; webhooks get alert.triggered and alert.resolved.

Request body
namestring
metricstringone of cpu, memory, disk, net_in, net_out
comparatorstringone of above, below
thresholdnumberpercent for cpu
windowMinutesinteger
serverIdsstring[]
tagsstring[]
emailsstring[]
enabledboolean
Responses
  • 201 Created
GET/v1/alerts/incidents

Incidents (open and recent)

Parameters
open (query)boolean
Responses
  • 200 OK
GET/v1/alerts/{id}

Get an alert rule with recent incidents

Parameters
id (path)*string
Responses
  • 200 OK
  • 404 Not found
PATCH/v1/alerts/{id}

Update an alert rule (any field, including enabled to mute)

Parameters
id (path)*string
Request body
namestring
metricstringone of cpu, memory, disk, net_in, net_out
comparatorstringone of above, below
thresholdnumberpercent for cpu
windowMinutesinteger
serverIdsstring[]
tagsstring[]
emailsstring[]
enabledboolean
Responses
  • 200 OK
DELETE/v1/alerts/{id}

Delete an alert rule

Parameters
id (path)*string
Responses
  • 204 Deleted

servers

GET/v1/servers

List servers

Parameters
project (query)stringProject id or slug (default `default`)
limit (query)integer
cursor (query)string
status (query)stringone of new, provisioning, active, off, rebooting, resizing, rebuilding, deleting, deleted, failed, suspended
tag (query)string
Responses
  • 200 OK
POST/v1/servers

Create a server

Returns 202 immediately with status: new. A durable workflow places the server, reserves a public IP, clones the image, waits for cloud-init, applies the firewall and starts metering. Watch status become active (30–60 s) or subscribe to server.active. The server is never billed unless it reaches active.

Parameters
Idempotency-Key (header)string
Request body
name*string
size*stringe.g. "s-2vcpu-4gb"
image*stringImage id or marketplace app slug
regionstring
projectstring
sshKeysstring[]
userDatastringcloud-init user-data
tagsstring[]
backupsboolean
managedbooleanManaged tier
firewallsstring[]
appVariablesobjectMarketplace app variables
avoidstring[]Server ids to anti-affine from
Responses
  • 202 Accepted
  • 402 Spend limit reached (`spend_limit_reached`)
  • 403 Quota exceeded (`quota_exceeded`)
  • 422 Validation error
GET/v1/servers/{id}

Get a server

Parameters
id (path)*string
Responses
  • 200 OK
  • 404 Not found
PATCH/v1/servers/{id}

Rename, retag, or turn backups or the managed tier on or off

Turning managed on also turns backups on. A server that never had the care agent gets it on its next rebuild, or right away with the install command from GET /servers/{id}/managed.

Parameters
id (path)*string
Request body
namestring
tagsstring[]
backupsbooleanDaily platform snapshot
managedbooleanManaged tier
Responses
  • 200 OK
DELETE/v1/servers/{id}

Delete a server

Returns 202; the server moves to deleting and is removed by a workflow. Metering stops immediately.

Parameters
id (path)*string
Idempotency-Key (header)string
Responses
  • 202 Accepted
  • 409 Invalid state (`invalid_state`)
GET/v1/servers/{id}/managed

Managed tier status

Health from the care agent's last report, the report itself, and the install command while the agent is not reporting.

Parameters
id (path)*string
Responses
  • 200 OK
GET/v1/managed/install/{token}no auth

Care agent install script

Public, keyed by the server's managed token. Served as a shell script for curl | sh.

Parameters
token (path)*string
Responses
  • 200 OK
  • 401 Unknown token
POST/v1/managed/reportno auth

Care agent report

Posted by the agent inside a managed server every five minutes, authenticated by the X-Prgd-Managed-Token header.

Parameters
X-Prgd-Managed-Token (header)*string
Request body
agentVersioninteger
hostnamestring
kernelstring
uptimeSecinteger
load1number
memTotalMbinteger
memUsedMbinteger
diskTotalGbnumber
diskUsedGbnumber
diskUsedPctinteger
pendingUpdatesinteger
securityUpdatesinteger
rebootRequiredboolean
lastUpgradeAtstringnull
failedUnitsstring[]
sshBannedinteger
sshPasswordAuthboolean
Responses
  • 200 OK
  • 401 Unknown token
GET/v1/servers/{id}/actions

List recent actions on a server

Parameters
id (path)*string
Responses
  • 200 OK
POST/v1/servers/{id}/actions

Run a lifecycle action

Parameters
id (path)*string
Idempotency-Key (header)string
Request body
type*stringone of start, stop, reboot, resize, rebuild, snapshot
sizestringresize: target size id (disk cannot shrink)
imagestringrebuild: image id (defaults to current)
namestringsnapshot: name
forcebooleanstop: power off without ACPI shutdown
Responses
  • 202 Accepted
  • 409 Invalid state (`invalid_state`)

catalog

GET/v1/regionsno auth

List regions

Responses
  • 200 OK
GET/v1/sizesno auth

List server sizes

Responses
  • 200 OK
GET/v1/imagesno auth

List images

Parameters
kind (query)stringone of distribution, marketplace
Responses
  • 200 OK
GET/v1/pricingno auth

Public price list (USD base; SAR converted at the current exchange rate)

Parameters
currency (query)stringone of USD, SAR
Responses
  • 200 OK

deploys

GET/v1/deploys

List Git deployments

Parameters
project (query)stringProject id or slug (default `default`)
Responses
  • 200 OK
POST/v1/deploys

Deploy a Git repository onto a new server

Creates a server whose cloud-init installs Docker, clones the repo, builds (Dockerfile or docker-compose) and serves it on :80. Two ways to name the repository: repoUrl (public, or private with gitToken) returns a per deployment GitHub webhook URL and secret (shown once) to add to the repository; installationId + repo ("owner/name") uses the team's GitHub App installation, needs no token, and redeploys on every push through the app webhook (webhook is null).

Parameters
Idempotency-Key (header)string
Request body
repoUrlstring
installationIdstring
repostringe.g. "acme/app"
branchstring
namestring
portinteger
sizestring
projectstring
sshKeysstring[]
envobject
gitTokenstringFor private repos; stored only in the server's cloud-init
Responses
  • 202 Accepted; includes `webhook` (url and secret) for URL based deployments
GET/v1/deploys/{id}

Get a deployment (refreshes status from the server)

Parameters
id (path)*string
Responses
  • 200 OK
POST/v1/deploys/{id}/redeploy

Redeploy now

Parameters
id (path)*string
Responses
  • 202 Accepted
POST/v1/deploys/{id}/hookno auth

GitHub push webhook (verified with X-Hub-Signature-256)

Parameters
id (path)*string
X-Hub-Signature-256 (header)*string
X-GitHub-Event (header)string
Responses
  • 200 OK
  • 401 Unauthorized
GET/v1/deploys/{id}/logs

Tail of the last build log

Fetched live from the server when it is reachable, otherwise the last cached copy. Capped at 32 KB.

Parameters
id (path)*string
Responses
  • 200 OK

github

GET/v1/github/app

Whether the GitHub App integration is configured

Responses
  • 200 OK
GET/v1/github/connect

URL to install the GitHub App for this team

Send the user there. GitHub returns them to the console callback with installation_id and the signed state, which the console posts to /github/installations.

Responses
  • 200 OK
  • 503 Not configured (`github_app_unavailable`)
GET/v1/github/installations

GitHub App installations linked to the team

Responses
  • 200 OK
POST/v1/github/installations

Link an installation after the GitHub redirect

Request body
installationId*integer
state*string
Responses
  • 201 Linked
  • 401 State invalid or expired
DELETE/v1/github/installations/{id}

Unlink and uninstall

Parameters
id (path)*string
Responses
  • 204 Removed
GET/v1/github/installations/{id}/repos

Repositories the installation can reach

Parameters
id (path)*string
Responses
  • 200 OK
POST/v1/github/webhookno auth

GitHub App webhook (push, installation)

One URL for every installation, verified with X-Hub-Signature-256 and the app webhook secret. A push redeploys every deployment on that repository and branch.

Responses
  • 200 OK

network

GET/v1/firewalls

List firewalls

Parameters
project (query)stringProject id or slug (default `default`)
Responses
  • 200 OK
POST/v1/firewalls

Create a firewall

Request body
name*string
projectstring
rules*object[]
Responses
  • 201 Created
GET/v1/firewalls/{id}

Get a firewall

Parameters
id (path)*string
Responses
  • 200 OK
DELETE/v1/firewalls/{id}

Delete a firewall

Parameters
id (path)*string
Responses
  • 204 Deleted
PUT/v1/firewalls/{id}/rules

Replace all rules (re-applied to attached servers immediately)

Parameters
id (path)*string
Request body
rules*object[]
Responses
  • 200 OK
POST/v1/firewalls/{id}/servers

Attach a server

Parameters
id (path)*string
Request body
serverId*string
Responses
  • 204 Attached
DELETE/v1/firewalls/{id}/servers/{serverId}

Detach a server

Parameters
id (path)*string
serverId (path)*string
Responses
  • 204 Detached
GET/v1/public-ips

List public IPs in a project

Parameters
project (query)stringProject id or slug (default `default`)
Responses
  • 200 OK

snapshots

GET/v1/snapshots

List snapshots

Parameters
project (query)stringProject id or slug (default `default`)
Responses
  • 200 OK
DELETE/v1/snapshots/{id}

Delete a snapshot

Parameters
id (path)*string
Responses
  • 202 Accepted

volumes

GET/v1/volumes

List volumes

Parameters
project (query)stringProject id or slug (default `default`)
server (query)stringOnly volumes attached to this server
Responses
  • 200 OK
POST/v1/volumes

Create a volume

Allocates a block volume in the region. Returns 202; the volume becomes available within seconds, or attached when serverId is given.

Parameters
Idempotency-Key (header)string
Request body
name*string
sizeGb*integer
regionstringDefaults to the platform region
projectstring
serverIdstringAttach right after creation
Responses
  • 202 Accepted
  • 403 Forbidden
GET/v1/volumes/{id}

Get a volume

Parameters
id (path)*string
Responses
  • 200 OK
  • 404 Not found
DELETE/v1/volumes/{id}

Delete a volume

The volume must be detached. Data is gone for good.

Parameters
id (path)*string
Responses
  • 202 Accepted
  • 409 Still attached
POST/v1/volumes/{id}/attach

Attach to a server

Hot plugs the volume. The server must be in the same region and active or off. The guest sees the disk at device.

Parameters
id (path)*string
Request body
serverId*string
Responses
  • 202 Accepted
POST/v1/volumes/{id}/detach

Detach from its server

Unmount the file system in the guest first.

Parameters
id (path)*string
Responses
  • 202 Accepted
POST/v1/volumes/{id}/resize

Grow a volume

Volumes only grow. An attached volume grows live; extend the file system in the guest afterwards.

Parameters
id (path)*string
Request body
sizeGb*integer
Responses
  • 202 Accepted

load-balancers

GET/v1/load-balancers

List load balancers

Parameters
project (query)stringProject id or slug (default `default`)
Responses
  • 200 OK
POST/v1/load-balancers

Create a load balancer

Reserves a public IP, creates one to three HAProxy nodes and pushes the forwarding rules. Returns 202; status becomes active once every node runs the config.

Parameters
Idempotency-Key (header)string
Request body
name*string
regionstring
projectstring
nodesinteger
algorithmstringone of round_robin, least_conn
forwardingRules*object[]
healthCheckobject
stickySessionsobject
redirectHttpToHttpsboolean
proxyProtocolboolean
serverIdsstring[]
tagstring
Responses
  • 202 Accepted
  • 403 Forbidden
GET/v1/load-balancers/{id}

Get a load balancer with target health

Parameters
id (path)*string
Responses
  • 200 OK
  • 404 Not found
PATCH/v1/load-balancers/{id}

Change rules

Parameters
id (path)*string
Request body
namestring
algorithmstringone of round_robin, least_conn
forwardingRulesobject[]
healthCheckobject
stickySessionsobject
redirectHttpToHttpsboolean
proxyProtocolboolean
tagstring
Responses
  • 202 Accepted
DELETE/v1/load-balancers/{id}

Delete a load balancer

Deletes the nodes and releases the IP.

Parameters
id (path)*string
Responses
  • 202 Accepted
POST/v1/load-balancers/{id}/servers

Add target servers

Parameters
id (path)*string
Request body
serverIds*string[]
Responses
  • 202 Accepted
DELETE/v1/load-balancers/{id}/servers/{serverId}

Remove a target server

Parameters
id (path)*string
serverId (path)*string
Responses
  • 202 Accepted
GET/v1/certificates

List certificates

Parameters
project (query)stringProject id or slug (default `default`)
Responses
  • 200 OK
POST/v1/certificates

Add a certificate

Either an uploaded PEM pair (custom) or a list of domains the load balancer gets issued by Let's Encrypt (letsencrypt). Point the domains at the load balancer IP first.

Request body
name*string
type*stringone of custom, letsencrypt
certPemstring
keyPemstring
domainsstring[]
projectstring
Responses
  • 201 Created
DELETE/v1/certificates/{id}

Delete a certificate

Parameters
id (path)*string
Responses
  • 200 Deleted
  • 409 In use by a load balancer

dns

GET/v1/domains

List hosted zones

Parameters
project (query)stringProject id or slug (default `default`)
Responses
  • 200 OK
POST/v1/domains

Add a domain

Creates the zone on our nameservers. Set the domain's nameservers at the registrar to the ones returned. Free.

Request body
name*stringe.g. "example.com"
ipstringCreates an apex A record
projectstring
Responses
  • 201 Created
  • 409 Name taken
GET/v1/domains/{name}

Get a zone with its records

Parameters
name (path)*string
Responses
  • 200 OK
  • 404 Not found
DELETE/v1/domains/{name}

Delete a zone and its records

Parameters
name (path)*string
Responses
  • 200 Deleted
GET/v1/domains/{name}/zone-file

The zone in BIND format

Parameters
name (path)*string
Responses
  • 200 OK
POST/v1/domains/{name}/records

Add a record

Parameters
name (path)*string
Request body
name*stringe.g. "www"
type*stringone of A, AAAA, CNAME, MX, TXT, NS, SRV, CAA
content*stringA: IPv4; CNAME/MX/NS: hostname; SRV: weight port target; CAA: flags tag value; TXT: text
ttlinteger
priorityintegerMX and SRV
Responses
  • 201 Created
  • 409 CNAME conflict
PATCH/v1/domains/{name}/records/{id}

Change a record

Parameters
name (path)*string
id (path)*string
Request body
namestring
contentstring
ttlinteger
priorityinteger
Responses
  • 200 OK
DELETE/v1/domains/{name}/records/{id}

Delete a record

Parameters
name (path)*string
id (path)*string
Responses
  • 200 Deleted
PUT/v1/public-ips/{id}/reverse-dns

Set reverse DNS (PTR) for a public IP

Parameters
id (path)*string
Request body
namestringHostname
Responses
  • 200 OK

object-storage

GET/v1/buckets

List buckets

Parameters
project (query)stringProject id or slug (default `default`)
Responses
  • 200 OK
POST/v1/buckets

Create a bucket

Names are global and DNS safe (3 to 63 lowercase letters, digits, hyphens). Billed per GB per month.

Request body
name*string
regionstring
projectstring
publicbooleanAnyone can read objects
Responses
  • 201 Created
  • 409 Name taken
GET/v1/buckets/{name}

Get a bucket

Parameters
name (path)*string
Responses
  • 200 OK
  • 404 Not found
PATCH/v1/buckets/{name}

Change public read

Parameters
name (path)*string
Request body
publicboolean
Responses
  • 200 OK
DELETE/v1/buckets/{name}

Delete an empty bucket

Parameters
name (path)*string
Responses
  • 200 Deleted
  • 409 Not empty
GET/v1/buckets/{name}/objects

List objects under a prefix

Parameters
name (path)*string
prefix (query)string
token (query)string
Responses
  • 200 OK
DELETE/v1/buckets/{name}/objects

Delete one object

Parameters
name (path)*string
key (query)*string
Responses
  • 200 Deleted
POST/v1/buckets/{name}/presign

Presigned URL for GET

Parameters
name (path)*string
Request body
key*string
methodstringone of GET, PUT, DELETE
expiresSecondsinteger
contentTypestring
Responses
  • 200 OK
GET/v1/storage-keys

List S3 access keys (no secrets)

Parameters
project (query)stringProject id or slug (default `default`)
Responses
  • 200 OK
POST/v1/storage-keys

Create an access key; the secret is returned once

Request body
name*string
projectstring
Responses
  • 201 Created
DELETE/v1/storage-keys/{id}

Revoke an access key

Parameters
id (path)*string
Responses
  • 200 Revoked

databases

GET/v1/databases

List managed database clusters

Parameters
project (query)stringProject id or slug (default `default`)
Responses
  • 200 OK
POST/v1/databases

Create a cluster

One node, or three nodes with automatic failover. Returns 202; the cluster becomes active in a few minutes. Priced per node per month.

Parameters
Idempotency-Key (header)string
Request body
name*string
engine*stringone of postgres, valkey, mysql
versionstring
size*stringA server size id with at least 1 GB of memory
nodesintegerone of 1, 3
regionstring
projectstring
trustedSourcesstring[]
backupHourUtcinteger
Responses
  • 202 Accepted
GET/v1/databases/engines

Engines and versions on offer

Responses
  • 200 OK
GET/v1/databases/{id}

Get a cluster with connection details and secrets

Parameters
id (path)*string
Responses
  • 200 OK
  • 404 Not found
PATCH/v1/databases/{id}

Change trusted sources or the backup hour

Parameters
id (path)*string
Request body
trustedSourcesstring[]
backupHourUtcinteger
Responses
  • 202 Accepted
DELETE/v1/databases/{id}

Delete a cluster and its nodes

Parameters
id (path)*string
Responses
  • 202 Accepted
POST/v1/databases/{id}/users

Add a user (password returned once)

Parameters
id (path)*string
Request body
name*string
Responses
  • 201 Created
DELETE/v1/databases/{id}/users/{userId}

Delete a user

Parameters
id (path)*string
userId (path)*string
Responses
  • 200 Deleted
POST/v1/databases/{id}/users/{userId}/reset-password

Reset a user's password (returned once)

Parameters
id (path)*string
userId (path)*string
Responses
  • 200 OK
POST/v1/databases/{id}/dbs

Add a database

Parameters
id (path)*string
Request body
name*string
Responses
  • 201 Created
DELETE/v1/databases/{id}/dbs/{dbId}

Remove a database from the cluster

Parameters
id (path)*string
dbId (path)*string
Responses
  • 200 Deleted
GET/v1/databases/{id}/backups

List backups

Parameters
id (path)*string
Responses
  • 200 OK
POST/v1/databases/{id}/backups

Take a backup now

Parameters
id (path)*string
Responses
  • 202 Accepted

kubernetes

GET/v1/kubernetes/versions

Kubernetes versions on offer

Responses
  • 200 OK
GET/v1/kubernetes/clusters

List clusters

Parameters
project (query)stringProject id or slug (default `default`)
Responses
  • 200 OK
POST/v1/kubernetes/clusters

Create a cluster

Returns 202 with status creating. One control plane node is included; ha gives three behind one address for a flat monthly fee. Worker pools are sized like servers (at least 2 GB of memory) and billed as servers. Bootstrapping takes about ten minutes; poll until active, then fetch the kubeconfig.

Parameters
Idempotency-Key (header)string
Request body
name*string
versionstringe.g. "1.31"
regionstring
projectstring
haboolean
controlSizestring
pools*object[]
Responses
  • 202 Accepted
  • 402 Spend limit (`spend_limit_reached`)
  • 429 Quota (`quota_exceeded`)
GET/v1/kubernetes/clusters/{id}

Get a cluster with its pools

Parameters
id (path)*string
Responses
  • 200 OK
  • 404 Not found
PATCH/v1/kubernetes/clusters/{id}

Rename a cluster

Parameters
id (path)*string
Request body
namestring
Responses
  • 200 OK
DELETE/v1/kubernetes/clusters/{id}

Delete a cluster with its nodes and the load balancers and volumes it created

Parameters
id (path)*string
Responses
  • 202 Accepted
GET/v1/kubernetes/clusters/{id}/kubeconfig

Admin kubeconfig as YAML

Needs kubernetes:write. Treat it like a password.

Parameters
id (path)*string
Responses
  • 200 OK
  • 409 Cluster not bootstrapped yet (`invalid_state`)
POST/v1/kubernetes/clusters/{id}/pools

Add a worker pool

Parameters
id (path)*string
Request body
name*string
size*stringServer size id with at least 2 GB of memory
count*integer
labelsobject
taintsobject[]
Responses
  • 202 Accepted
PATCH/v1/kubernetes/clusters/{id}/pools/{poolId}

Scale a pool

Growing adds servers; shrinking drains and removes the highest numbered nodes first.

Parameters
id (path)*string
poolId (path)*string
Request body
count*integer
Responses
  • 202 Accepted
DELETE/v1/kubernetes/clusters/{id}/pools/{poolId}

Remove a pool and its nodes

Parameters
id (path)*string
poolId (path)*string
Responses
  • 202 Accepted
  • 400 The last pool cannot be removed

app-platform

GET/v1/app-platform/sizes

Container sizes

Responses
  • 200 OK
GET/v1/app-platform/apps

List apps

Parameters
project (query)stringProject id or slug (default `default`)
Responses
  • 200 OK
POST/v1/app-platform/apps

Create an app

Push code, get a URL. Returns 202 with status creating; the platform picks a shared host (or starts one), builds the repository (a Dockerfile at the root, or a generated one for Node, Python, Go and static projects), runs instances containers of size and serves them at https://<name>.<apps domain> with TLS. Name the repository with repoUrl (and gitToken for a private one) or with installationId and repo from the GitHub App, which also redeploys on every push. Poll until live; on failed, read the build log.

Parameters
Idempotency-Key (header)string
Request body
name*stringHostname label
repoUrlstring
installationIdstring
repostringe.g. "acme/app"
gitTokenstring
branchstring
portinteger
sizestringone of app-xs, app-s, app-m, app-l
instancesinteger
envobject
healthPathstring
regionstring
projectstring
Responses
  • 202 Accepted
  • 409 Name taken (`name_taken`)
GET/v1/app-platform/apps/{id}

Get an app

Parameters
id (path)*string
Responses
  • 200 OK
  • 404 Not found
PATCH/v1/app-platform/apps/{id}

Change configuration and deploy again

env replaces the whole set. A bigger size or more instances checks the spend limit and the host's room.

Parameters
id (path)*string
Request body
branchstring
portinteger
sizestringone of app-xs, app-s, app-m, app-l
instancesinteger
envobject
healthPathstring
gitTokenstring
Responses
  • 202 Accepted
DELETE/v1/app-platform/apps/{id}

Delete an app

Parameters
id (path)*string
Responses
  • 202 Accepted
POST/v1/app-platform/apps/{id}/deploy

Build and deploy the branch head now

Parameters
id (path)*string
Responses
  • 202 Accepted
POST/v1/app-platform/apps/{id}/stop

Stop the instances and the charge

Parameters
id (path)*string
Responses
  • 200 OK
POST/v1/app-platform/apps/{id}/start

Start a stopped app

Parameters
id (path)*string
Responses
  • 200 OK
GET/v1/app-platform/apps/{id}/deploys

Deploy history

Parameters
id (path)*string
Responses
  • 200 OK
GET/v1/app-platform/apps/{id}/logs

Build or runtime log

Fetched live from the host when reachable; the build log is cached on the app otherwise. Capped at 32 KB.

Parameters
id (path)*string
type (query)stringone of build, runtime
Responses
  • 200 OK
POST/v1/app-platform/apps/{id}/domains

Attach a custom domain

Point a CNAME at the app hostname; the certificate is issued on the first request.

Parameters
id (path)*string
Request body
domain*string
Responses
  • 200 OK
  • 409 Domain attached to another app (`domain_taken`)
DELETE/v1/app-platform/apps/{id}/domains/{domain}

Detach a custom domain

Parameters
id (path)*string
domain (path)*string
Responses
  • 200 OK

marketplace

GET/v1/appsno auth

List marketplace apps

Parameters
category (query)string
Responses
  • 200 OK
GET/v1/apps/categoriesno auth

App categories with counts

Responses
  • 200 OK
GET/v1/apps/{slug}no auth

Get an app (its `variables` describe the one-click form)

Parameters
slug (path)*string
Responses
  • 200 OK
  • 404 Not found

billing

POST/v1/billing/topup

Start a card payment that becomes prepaid credit

Returns the hosted Moyasar payment page (mada, Visa, Mastercard, Apple Pay) to send the person to. Agents cannot call this.

Request body
amountMinor*integerUSD 5 to 5000, SAR 200 to 200000
Responses
  • 201 Created
POST/v1/billing/invoices/{id}/pay

Pay an open invoice by card

Parameters
id (path)*string
Responses
  • 201 Created
  • 409 Invoice is not open (`invalid_state`)
GET/v1/billing/invoices/{id}/pdf

Invoice as PDF

Parameters
id (path)*string
Responses
  • 200 PDF
GET/v1/billing/payments

Card payments of the team

Responses
  • 200 OK
POST/v1/billing/payments/moyasar/webhookno auth

Moyasar webhook (payment events

Responses
  • 200 OK
GET/v1/billing/payments/moyasar/callbackno auth

Moyasar callback after the hosted page (result verified by retrieving the invoice)

Responses
  • 302 Redirect to the console
GET/v1/billing/balance

Credit balance

Responses
  • 200 OK
GET/v1/billing/usage

Rated usage per resource

Parameters
project (query)stringProject id or slug (default `default`)
from (query)string
to (query)string
Responses
  • 200 OK
GET/v1/billing/invoices

List invoices

Responses
  • 200 OK
GET/v1/billing/invoices/{id}

Get an invoice with its usage lines

Parameters
id (path)*string
Responses
  • 200 OK

support

GET/v1/support/plansno auth

Support plan catalog

Public. Plans with first response targets per priority (hours, null when the priority is not allowed on the plan) and the monthly price in the requested currency.

Parameters
currency (query)stringone of USD, SAR
Responses
  • 200 OK
GET/v1/support/plan

The team's support plan

Responses
  • 200 OK
PUT/v1/support/plan

Change the support plan

Needs billing:write. An upgrade checks the spend limit on the team's oldest project; a downgrade applies at once. Open tickets keep the targets of the plan they were opened under.

Request body
plan*stringone of free, developer, standard, premium
Responses
  • 200 OK
GET/v1/support/tickets

List tickets

Parameters
status (query)stringone of open, answered, closed, all
limit (query)integer
cursor (query)string
Responses
  • 200 OK
POST/v1/support/tickets

Open a ticket

Priority must be allowed on the team's plan (400 with the allowed list otherwise). resource names what the ticket is about and must belong to the team. Owners and the opener get every answer by email.

Request body
subject*string
body*string
prioritystringone of low, normal, high, urgent
resourcestring"server:<id>", "database:<id>", "load_balancer:<id>", "volume:<id>", "domain:<id>", "bucket:<id>" or "invoice:<id>"
Responses
  • 201 Created
  • 429 Open ticket limit for the plan (`quota_exceeded`)
GET/v1/support/tickets/{id}

Get a ticket with its messages

Parameters
id (path)*string
Responses
  • 200 OK
  • 404 Not found
POST/v1/support/tickets/{id}/messages

Reply on a ticket

Reopens a closed ticket for up to 14 days after it was closed.

Parameters
id (path)*string
Request body
body*string
Responses
  • 201 Created
POST/v1/support/tickets/{id}/close

Close a ticket

Parameters
id (path)*string
Responses
  • 200 OK

managed-cloud

GET/v1/managed/plans

Active managed cloud plans

Prices exclude VAT. priceMinor is null for a custom plan. Targets are minutes per priority; on BUSINESS_HOURS plans they count working minutes (09:00 to 17:00 on working days of the contract calendar, public holidays excluded).

Responses
  • 200 OK
GET/v1/managed/contracts

The team's contracts

Team owners only.

Responses
  • 200 OK
  • 403 Forbidden
POST/v1/managed/contracts

Request a managed cloud plan

Team owners only. Creates a DRAFT contract with the default responsibility matrix. A support lead reviews it, signs it and starts onboarding; the contract becomes ACTIVE, and billing starts, when onboarding is complete. One pending request per team.

Request body
plan*stringe.g. "ESSENTIAL"
calendarstringBusiness hours calendar; defaults from the team countryone of SA, TR
notesstring
Responses
  • 201 Created
  • 409 A request is already pending (`request_pending`)
  • 422 Validation error
GET/v1/managed/contracts/{id}

Contract detail with SLA, responsibility matrix, onboarding progress and this month's engineer time

Team owners only.

Parameters
id (path)*string
Responses
  • 200 OK
  • 404 Not found
GET/v1/managed/contracts/{id}/assets

Assets under management with health

Parameters
id (path)*string
Responses
  • 200 OK
  • 404 Not found
POST/v1/managed/contracts/{id}/assets

Ask for an asset to be managed

Team owners only. The asset stays PENDING until an engineer approves it. PLATFORM_SERVER needs serverId; EXTERNAL_SERVER and SITE need address. Limited by the plan's maxAssets.

Parameters
id (path)*string
Request body
kind*stringone of PLATFORM_SERVER, EXTERNAL_SERVER, SITE
name*string
serverIdstring
addressstringPublic IP, hostname or site URL
providerstring
osstring
notesstring
Responses
  • 201 Created
  • 403 Not an owner, or the plan's asset limit is reached (`quota_exceeded`)
GET/v1/managed/assets

Every managed asset of the team

Responses
  • 200 OK
GET/v1/managed/contracts/{id}/reports

Monthly reports that were sent

Team owners only. Reports are drafted on the 1st and sent by the 3rd.

Parameters
id (path)*string
Responses
  • 200 OK
GET/v1/managed/contracts/{id}/reports/{reportId}/pdf

Download a monthly report as PDF

Parameters
id (path)*string
reportId (path)*string
Responses
  • 200 OK
  • 404 Not found
GET/v1/managed/tickets

Managed cloud tickets

Parameters
status (query)stringone of open, answered, closed, all
priority (query)stringone of P1, P2, P3, P4
contractId (query)string
limit (query)integer
cursor (query)string
Responses
  • 200 OK
POST/v1/managed/tickets

Open a ticket

Due times come from the plan's targets and the contract calendar. P1 and P2 page the engineer on call. contractId is needed only when the team has more than one contract; assetId implies it. Not allowed while the contract is suspended.

Request body
subject*string
body*string
priorityobject
contractIdstring
assetIdstring
Responses
  • 201 Created
  • 409 The contract is not onboarding or active (`invalid_state`)
GET/v1/managed/tickets/{id}

A ticket with its messages

Internal engineer notes are never included.

Parameters
id (path)*string
Responses
  • 200 OK
  • 404 Not found
POST/v1/managed/tickets/{id}/messages

Reply on a ticket

Reopens a closed ticket for up to 14 days after it was closed.

Parameters
id (path)*string
Request body
body*string
Responses
  • 201 Created
POST/v1/managed/tickets/{id}/close

Close a ticket

Parameters
id (path)*string
Responses
  • 200 OK

webhooks

GET/v1/webhooks

List webhooks

Responses
  • 200 OK
POST/v1/webhooks

Create a webhook

Deliveries are signed with X-Prgd-Signature: sha256=<hmac> using the secret returned once at creation.

Request body
url*string
events*string[]
Responses
  • 201 Created
GET/v1/webhooks/events

List subscribable event names

Responses
  • 200 OK
DELETE/v1/webhooks/{id}

Delete a webhook

Parameters
id (path)*string
Responses
  • 204 Deleted

Error codes

Every error is { "error": { "code", "message", "details?" } } with one of these codes.

  • invalid_request
  • unauthorized
  • forbidden
  • approval_required
  • not_found
  • conflict
  • invalid_state
  • quota_exceeded
  • spend_limit_reached
  • verification_required
  • account_suspended
  • idempotency_key_reused
  • rate_limited
  • workflow_unavailable
  • internal_error