API reference

The Django Cloud API

The HTTP API behind the djangocloud command line tool. Most people only need the CLI; the endpoints are here for scripting deploys yourself.

Authentication. Send a token as Authorization: Bearer <token>. Create one under Settings, Developer in the dashboard, or get one with the browser-approved login (/auth/device and /auth/token).

Errors. Every response is JSON, errors included: {"error": code, "message": text}.

Rate limits. Every signed-in caller may make 200 requests a minute, counted per user whatever token or address is used (callers without an account: 60 a minute per address). Some endpoints have stricter hourly limits. Over a limit you get 429 with {"error": "rate_limited", "retry_after": seconds} and a Retry-After header; reads are safe to repeat after that long.

The API is early and may change. Pin your CLI version in CI if you depend on its behaviour.

Prefer a machine-readable description? Download the OpenAPI schema. For the command line tool, see How it works.

Authentication

Start a browser-approved login

POST /api/v1/auth/device no token

Step 1 of djangocloud login. Show user_code and verification_uri to the user, then poll /auth/token every interval seconds. No token is needed.

Request body (application/json)

client_namestringShown to the user when they approve the login.

Example

curl -X POST https://djangocloud.dev/api/v1/auth/device \
  -H "Content-Type: application/json" \
  -d '{"client_name": "..."}'

Responses

200 OK
device_codestringA secret to poll with.
user_codestringA short code for the user to approve.
verification_uristring
verification_uri_completestring
intervalintegerSeconds between polls.
expires_inintegerSeconds until the code expires.
429 Rate limited. Try again later.

Exchange an approved code for a token

POST /api/v1/auth/token no token

Poll until the user has approved. While waiting it answers 400 with authorization_pending; slow_down means poll less often; expired_token and invalid_grant mean start again. The token is handed over exactly once.

Request body (application/json)

device_coderequiredstring

Example

curl -X POST https://djangocloud.dev/api/v1/auth/token \
  -H "Content-Type: application/json" \
  -d '{"device_code": "..."}'

Responses

200 OK
access_tokenstring
token_typestringAlways bearer.
400 The request is malformed. error says what is wrong.
429 Rate limited. Try again later.

Account

The signed-in user

GET /api/v1/me token required

Example

curl https://djangocloud.dev/api/v1/me \
  -H "Authorization: Bearer $TOKEN"

Responses

200 OK
emailstring
subscription_activeboolean
suspendedboolean
planstring
can_hostboolean
hosted_openboolean
aws_connectedboolean
setup_stepcard | hosting | ready* card - card * hosting - hosting * ready - ready
ready_to_deployboolean
401 Missing or invalid token.

Start putting a card on file

POST /api/v1/billing/checkout token required

Answers the Stripe Checkout page to open and the session id to confirm with. If a card is already on file it answers {"active": true}.

Example

curl -X POST https://djangocloud.dev/api/v1/billing/checkout \
  -H "Authorization: Bearer $TOKEN"

Responses

200 OK
activebooleanTrue when a card is already on file; there is nothing to open.
urlstringThe Stripe Checkout page to open.
session_idstringPass this to /billing/confirm.
401 Missing or invalid token.
429 Rate limited. Try again later.
502 An upstream service (GitHub, Stripe) is unavailable.
503 Billing is unavailable.

Has the checkout put a card on file?

POST /api/v1/billing/confirm token required

What the CLI polls while the user is on the Stripe page: has this checkout session put a card on file?

Request body (application/json)

session_idrequiredstring

Example

curl -X POST https://djangocloud.dev/api/v1/billing/confirm \
  -H "Authorization: Bearer $TOKEN" \
  -H "Content-Type: application/json" \
  -d '{"session_id": "..."}'

Responses

200 OK
subscription_activeboolean
suspendedboolean
401 Missing or invalid token.
429 Rate limited. Try again later.

Confirm where apps run

POST /api/v1/setup/hosting token required

hosted is Fully managed, self is your own AWS account. The plan follows the subscription, so this only confirms the plan the account already has.

Request body (application/json)

hostingrequiredobjecthosted is Fully managed, self your own AWS. * hosted - hosted * self - self

Example

curl -X POST https://djangocloud.dev/api/v1/setup/hosting \
  -H "Authorization: Bearer $TOKEN" \
  -H "Content-Type: application/json" \
  -d '{"hosting": {}}'

Responses

200 OK
emailstring
subscription_activeboolean
suspendedboolean
planstring
can_hostboolean
hosted_openboolean
aws_connectedboolean
setup_stepcard | hosting | ready* card - card * hosting - hosting * ready - ready
ready_to_deployboolean
400 The request is malformed. error says what is wrong.
401 Missing or invalid token.
402 No card on file yet.
403 Not allowed, for example the account is suspended.
409 Conflicts with the current state, for example a deploy is already running.

Your AWS connection and how to set up the role

GET /api/v1/aws token required

Returns your ExternalId, the role trust policy, a CloudFormation template and the permissions policy. Never returns a secret key.

Example

curl https://djangocloud.dev/api/v1/aws \
  -H "Authorization: Bearer $TOKEN"

Responses

200 OK
connectedboolean
regionstring
account_idstring
methodobjectHow we reach your account; empty if not connected. * ` - * role - role * key` - key
role_arnstringThe IAM role we assume (empty when connected with an access key).
access_keystringThe access key id, masked. The secret is never returned.
regionsarray of object
regions.[]codestring
regions.[]labelstring
policyobjectThe IAM permissions policy the role (or the access key's user) needs.
role_supportedbooleanFalse if this deployment can't offer the role option.
external_idstringYours alone. Put it in the role's trust policy. Not a secret.
trust_policyobjectThe role's trust policy: our principal, with your ExternalId.
cloudformation_templateobjectDeploy as a stack in your account to create the role, trust policy and permissions in one go.
401 Missing or invalid token.

Connect your AWS account

PUT /api/v1/aws token required

Send role_arn and region. We assume the role with your ExternalId and store no secret; this answers 202 and checks the role in the background, so poll GET /aws until connected is true or error is set. POST does the same.

Request body (application/json)

role_arnrequiredstringThe ARN of the djangocloud-deployer role your CloudFormation stack made.
regionrequiredstringFor example eu-west-1.

Example

curl -X PUT https://djangocloud.dev/api/v1/aws \
  -H "Authorization: Bearer $TOKEN" \
  -H "Content-Type: application/json" \
  -d '{"role_arn": "...", "region": "..."}'

Responses

200 OK
connectedboolean
regionstring
account_idstring
methodobjectHow we reach your account; empty if not connected. * ` - * role - role * key` - key
role_arnstringThe IAM role we assume (empty when connected with an access key).
access_keystringThe access key id, masked. The secret is never returned.
regionsarray of object
regions.[]codestring
regions.[]labelstring
202 Accepted: it continues in the background
connectedboolean
regionstring
account_idstring
methodobjectHow we reach your account; empty if not connected. * ` - * role - role * key` - key
role_arnstringThe IAM role we assume (empty when connected with an access key).
access_keystringThe access key id, masked. The secret is never returned.
regionsarray of object
regions.[]codestring
regions.[]labelstring
statusstringverifying: poll GET /aws until connected or error.
400 The request is malformed. error says what is wrong.
401 Missing or invalid token.
429 Rate limited. Try again later.

Projects

List your projects

GET /api/v1/projects token required

Example

curl https://djangocloud.dev/api/v1/projects \
  -H "Authorization: Bearer $TOKEN"

Responses

200 OK
projectsarray of object
projects.[]idinteger
projects.[]slugstring
projects.[]namestring
projects.[]hostedbooleanTrue on Fully managed, false when it runs in your own AWS account.
projects.[]regionstring
projects.[]powerobjectThe server size. * nano - nano * micro - micro * small - small * medium - medium * large - large * xlarge - xlarge
projects.[]scaleintegerThe number of instances.
projects.[]resizeobject
projects.[]resize.statusidle | pending | applying | failed* idle - idle * pending - pending * applying - applying * failed - failed
projects.[]resize.powerstringThe size being applied.
projects.[]resize.scaleintegerThe instance count being applied.
projects.[]resize.errorstringWhy the last size change failed, if it did.
401 Missing or invalid token.

Create a project

POST /api/v1/projects token required

Request body (application/json)

namerequiredstring
powerobject* nano - nano * micro - micro * small - small * medium - medium * large - large * xlarge - xlarge
hostedbooleanRun it on the Fully managed plan.
regionstringFully managed only: where to run it.

Example

curl -X POST https://djangocloud.dev/api/v1/projects \
  -H "Authorization: Bearer $TOKEN" \
  -H "Content-Type: application/json" \
  -d '{"name": "...", "power": {}, "hosted": true, "region": "..."}'

Responses

201 Created
idinteger
slugstring
namestring
hostedbooleanTrue on Fully managed, false when it runs in your own AWS account.
regionstring
powerobjectThe server size. * nano - nano * micro - micro * small - small * medium - medium * large - large * xlarge - xlarge
scaleintegerThe number of instances.
resizeobject
resize.statusidle | pending | applying | failed* idle - idle * pending - pending * applying - applying * failed - failed
resize.powerstringThe size being applied.
resize.scaleintegerThe instance count being applied.
resize.errorstringWhy the last size change failed, if it did.
400 The request is malformed. error says what is wrong.
401 Missing or invalid token.
402 No card on file yet.
403 Not allowed, for example the account is suspended.
409 Conflicts with the current state, for example a deploy is already running.

The price list

GET /api/v1/sizes no token

The server sizes and what they cost. No token is needed.

Example

curl https://djangocloud.dev/api/v1/sizes

Responses

200 OK
sizesarray of object
sizes.[]powernano | micro | small | medium | large | xlarge* nano - nano * micro - micro * small - small * medium - medium * large - large * xlarge - xlarge
sizes.[]labelstring
sizes.[]vcpunumber
sizes.[]ram_gbnumber
sizes.[]price_centsintegerWhat DjangoCloud charges per instance on Fully managed.
sizes.[]aws_centsintegerWhat AWS charges you per instance in your own account.
sizes.[]descriptionstring

Every build setting

GET /api/v1/build-config no token

Each setting with its default and description. No token is needed.

Example

curl https://djangocloud.dev/api/v1/build-config

Responses

200 OK
pathstringWhere the settings live in a repository.
defaultsobject
fieldsarray of object

Tear a project down

DELETE /api/v1/projects/{project_id} token required

Deletes the project and everything it left in AWS. This cannot be undone, so the body must repeat the project's slug. A database is deleted after a final snapshot is saved in your AWS account.

Parameters

project_idrequiredinteger · path

Example

curl -X DELETE https://djangocloud.dev/api/v1/projects/{project_id} \
  -H "Authorization: Bearer $TOKEN"

Responses

202 Accepted: it continues in the background
slugstring
deletedboolean
400 The request is malformed. error says what is wrong.
401 Missing or invalid token.
404 No such project or release, or it belongs to someone else.
429 Rate limited. Try again later.

A project, whether it is live, and its latest releases

GET /api/v1/projects/{project_id} token required

GET: the project, whether it is live and answering, and its latest releases. DELETE: tear it down.

Parameters

project_idrequiredinteger · path

Example

curl https://djangocloud.dev/api/v1/projects/{project_id} \
  -H "Authorization: Bearer $TOKEN"

Responses

200 OK
idinteger
slugstring
namestring
hostedbooleanTrue on Fully managed, false when it runs in your own AWS account.
regionstring
powerobjectThe server size. * nano - nano * micro - micro * small - small * medium - medium * large - large * xlarge - xlarge
scaleintegerThe number of instances.
resizeobject
resize.statusidle | pending | applying | failed* idle - idle * pending - pending * applying - applying * failed - failed
resize.powerstringThe size being applied.
resize.scaleintegerThe instance count being applied.
resize.errorstringWhy the last size change failed, if it did.
tierconnect | hosted* connect - connect * hosted - hosted
urlstringThe app's public HTTPS address.
statusobject
status.labelstring
status.tonestring
status.detailstring
healthobject
health.statestring
health.checked_atdatetime
health.sincedatetime
health.errorstring
live_releaseobject or null
live_release.idinteger
live_release.project_idinteger
live_release.versionintegerThe release number: v1, v2, ...
live_release.statusqueued | building | pushed | deploying | active | superseded | failed* queued - queued * building - building * pushed - pushed * deploying - deploying * active - active * superseded - superseded * failed - failed
live_release.donebooleanTrue once the release is active, superseded or failed.
live_release.okbooleanTrue when the release is, or was, serving traffic.
live_release.git_shastring
live_release.testsobjectWhat the CLI reported about the tests it ran before the upload: status (none, passed or skipped), command and seconds. Self-reported.
live_release.created_atdatetime
releasesarray of objectThe latest five releases.
releases.[]idinteger
releases.[]project_idinteger
releases.[]versionintegerThe release number: v1, v2, ...
releases.[]statusqueued | building | pushed | deploying | active | superseded | failed* queued - queued * building - building * pushed - pushed * deploying - deploying * active - active * superseded - superseded * failed - failed
releases.[]donebooleanTrue once the release is active, superseded or failed.
releases.[]okbooleanTrue when the release is, or was, serving traffic.
releases.[]git_shastring
releases.[]testsobjectWhat the CLI reported about the tests it ran before the upload: status (none, passed or skipped), command and seconds. Self-reported.
releases.[]created_atdatetime
401 Missing or invalid token.
404 No such project or release, or it belongs to someone else.

Change the server size or the number of instances

POST /api/v1/projects/{project_id}/scale token required

Leave a field out to keep its current value. Poll GET /projects/{project_id} and watch resize.status until it is idle or failed.

Parameters

project_idrequiredinteger · path

Request body (application/json)

powernano | micro | small | medium | large | xlarge* nano - nano * micro - micro * small - small * medium - medium * large - large * xlarge - xlarge
scaleinteger

Example

curl -X POST https://djangocloud.dev/api/v1/projects/{project_id}/scale \
  -H "Authorization: Bearer $TOKEN" \
  -H "Content-Type: application/json" \
  -d '{"power": "nano", "scale": 1}'

Responses

200 OK
idinteger
slugstring
namestring
hostedbooleanTrue on Fully managed, false when it runs in your own AWS account.
regionstring
powerobjectThe server size. * nano - nano * micro - micro * small - small * medium - medium * large - large * xlarge - xlarge
scaleintegerThe number of instances.
resizeobject
resize.statusidle | pending | applying | failed* idle - idle * pending - pending * applying - applying * failed - failed
resize.powerstringThe size being applied.
resize.scaleintegerThe instance count being applied.
resize.errorstringWhy the last size change failed, if it did.
202 Accepted: it continues in the background
idinteger
slugstring
namestring
hostedbooleanTrue on Fully managed, false when it runs in your own AWS account.
regionstring
powerobjectThe server size. * nano - nano * micro - micro * small - small * medium - medium * large - large * xlarge - xlarge
scaleintegerThe number of instances.
resizeobject
resize.statusidle | pending | applying | failed* idle - idle * pending - pending * applying - applying * failed - failed
resize.powerstringThe size being applied.
resize.scaleintegerThe instance count being applied.
resize.errorstringWhy the last size change failed, if it did.
400 The request is malformed. error says what is wrong.
401 Missing or invalid token.
402 No card on file yet.
404 No such project or release, or it belongs to someone else.
409 Conflicts with the current state, for example a deploy is already running.
429 Rate limited. Try again later.

Releases

Start a deploy

POST /api/v1/projects/{project_id}/releases token required

Upload the source as a .tar.gz in the multipart field source. Without an upload, the latest commit of the project's connected GitHub repository is deployed. Poll /releases/{release_id} until done.

Parameters

project_idrequiredinteger · path

Request body (multipart/form-data)

sourcefileThe project's source as a .tar.gz. Without it, the latest commit of the connected GitHub repository is deployed.
git_shastring
testsobjectWhether the CLI ran the tests first. Projects that require passing tests refuse anything else. * none - none * passed - passed * skipped - skipped
tests_commandstring
tests_secondsinteger

Example

curl -X POST https://djangocloud.dev/api/v1/projects/{project_id}/releases \
  -H "Authorization: Bearer $TOKEN" \
  -F source=@project.tar.gz

Responses

202 Accepted: it continues in the background
idinteger
project_idinteger
versionintegerThe release number: v1, v2, ...
statusqueued | building | pushed | deploying | active | superseded | failed* queued - queued * building - building * pushed - pushed * deploying - deploying * active - active * superseded - superseded * failed - failed
donebooleanTrue once the release is active, superseded or failed.
okbooleanTrue when the release is, or was, serving traffic.
git_shastring
testsobjectWhat the CLI reported about the tests it ran before the upload: status (none, passed or skipped), command and seconds. Self-reported.
created_atdatetime
400 The request is malformed. error says what is wrong.
401 Missing or invalid token.
402 No card on file yet.
404 No such project or release, or it belongs to someone else.
409 Conflicts with the current state, for example a deploy is already running.
413 The upload is too large.
422
429 Rate limited. Try again later.
502 An upstream service (GitHub, Stripe) is unavailable.

Go back to an older release

POST /api/v1/projects/{project_id}/rollback token required

Redeploys that release's image as a new release. Code and environment variables go back; database migrations do not. Poll the returned release like a deploy.

Parameters

project_idrequiredinteger · path

Request body (application/json)

versionrequiredintegerThe release number to go back to.

Example

curl -X POST https://djangocloud.dev/api/v1/projects/{project_id}/rollback \
  -H "Authorization: Bearer $TOKEN" \
  -H "Content-Type: application/json" \
  -d '{"version": 1}'

Responses

202 Accepted: it continues in the background
idinteger
project_idinteger
versionintegerThe release number: v1, v2, ...
statusqueued | building | pushed | deploying | active | superseded | failed* queued - queued * building - building * pushed - pushed * deploying - deploying * active - active * superseded - superseded * failed - failed
donebooleanTrue once the release is active, superseded or failed.
okbooleanTrue when the release is, or was, serving traffic.
git_shastring
testsobjectWhat the CLI reported about the tests it ran before the upload: status (none, passed or skipped), command and seconds. Self-reported.
created_atdatetime
400 The request is malformed. error says what is wrong.
401 Missing or invalid token.
404 No such project or release, or it belongs to someone else.
409 Conflicts with the current state, for example a deploy is already running.
429 Rate limited. Try again later.

A release and the log lines since a cursor

GET /api/v1/releases/{release_id} token required

Status plus the log lines since ?after=<cursor>; the CLI polls until done.

Parameters

afterinteger · queryA cursor from an earlier answer: only newer lines come back.
release_idrequiredinteger · path

Example

curl https://djangocloud.dev/api/v1/releases/{release_id} \
  -H "Authorization: Bearer $TOKEN"

Responses

200 OK
idinteger
project_idinteger
versionintegerThe release number: v1, v2, ...
statusqueued | building | pushed | deploying | active | superseded | failed* queued - queued * building - building * pushed - pushed * deploying - deploying * active - active * superseded - superseded * failed - failed
donebooleanTrue once the release is active, superseded or failed.
okbooleanTrue when the release is, or was, serving traffic.
git_shastring
testsobjectWhat the CLI reported about the tests it ran before the upload: status (none, passed or skipped), command and seconds. Self-reported.
created_atdatetime
logsarray of objectUp to 500 new lines.
logs.[]idinteger
logs.[]atdatetime
logs.[]levelstring
logs.[]messagestring
cursorintegerPass as after next time.
401 Missing or invalid token.
404 No such project or release, or it belongs to someone else.

Environment

Remove environment variables by name

DELETE /api/v1/projects/{project_id}/env token required

Unknown names are ignored. The variables DjangoCloud manages (the database's) are never removed. Applied from the next deploy.

Parameters

project_idrequiredinteger · path

Example

curl -X DELETE https://djangocloud.dev/api/v1/projects/{project_id}/env \
  -H "Authorization: Bearer $TOKEN"

Responses

200 OK
createdarray of string
updatedarray of string
removedarray of string
400 The request is malformed. error says what is wrong.
401 Missing or invalid token.
404 No such project or release, or it belongs to someone else.
429 Rate limited. Try again later.

The names of the environment variables

GET /api/v1/projects/{project_id}/env token required

Never returns values.

Parameters

project_idrequiredinteger · path

Example

curl https://djangocloud.dev/api/v1/projects/{project_id}/env \
  -H "Authorization: Bearer $TOKEN"

Responses

200 OK
variablesarray of object
variables.[]keystring
variables.[]updated_atdatetime
maxintegerThe most variables one project can hold.
401 Missing or invalid token.
404 No such project or release, or it belongs to someone else.

Set environment variables

PUT /api/v1/projects/{project_id}/env token required

Encrypted, all or nothing, and applied from the next deploy. With replace the others are removed, except the ones DjangoCloud manages.

Parameters

project_idrequiredinteger · path

Request body (application/json)

variablesrequiredobjectKEY: value pairs.
replacebooleanRemove the other variables.

Example

curl -X PUT https://djangocloud.dev/api/v1/projects/{project_id}/env \
  -H "Authorization: Bearer $TOKEN" \
  -H "Content-Type: application/json" \
  -d '{"variables": {}, "replace": true}'

Responses

200 OK
createdarray of string
updatedarray of string
removedarray of string
400 The request is malformed. error says what is wrong.
401 Missing or invalid token.
404 No such project or release, or it belongs to someone else.
429 Rate limited. Try again later.

Logs

Log lines, oldest first

GET /api/v1/projects/{project_id}/logs token required

Without after it returns the latest lines. With after=<cursor> it returns everything newer, which is how djangocloud logs -f follows.

Parameters

afterinteger · queryA cursor from an earlier answer: only newer lines come back.
linesinteger · queryHow many lines, 1 to 500 (default 100).
project_idrequiredinteger · path
sincestring · queryHow far back, for example 90s, 30m, 2h or 7d (at most 30 days).
sourceapp | build | release · queryOnly this kind of line.

Example

curl https://djangocloud.dev/api/v1/projects/{project_id}/logs \
  -H "Authorization: Bearer $TOKEN"

Responses

200 OK
linesarray of object
lines.[]idinteger
lines.[]atdatetime
lines.[]sourceapp | build | release* app - app * build - build * release - release
lines.[]levelstring
lines.[]messagestring
cursorintegerPass as after to get only newer lines.
400 The request is malformed. error says what is wrong.
401 Missing or invalid token.
404 No such project or release, or it belongs to someone else.

Operations

The autoscaling settings

GET /api/v1/projects/{project_id}/autoscale token required

GET the autoscaling settings. PUT {"enabled": true, "min": 2, "max": 6}; turning it off keeps the range.

Parameters

project_idrequiredinteger · path

Example

curl https://djangocloud.dev/api/v1/projects/{project_id}/autoscale \
  -H "Authorization: Bearer $TOKEN"

Responses

200 OK
enabledboolean
mininteger
maxinteger
notestringWhat autoscaling is doing right now, if anything.
max_allowedintegerThe most instances one project can have.
401 Missing or invalid token.
404 No such project or release, or it belongs to someone else.

Turn autoscaling on or off, and set its range

PUT /api/v1/projects/{project_id}/autoscale token required

GET the autoscaling settings. PUT {"enabled": true, "min": 2, "max": 6}; turning it off keeps the range.

Parameters

project_idrequiredinteger · path

Request body (application/json)

enabledrequiredbooleanTurning it off keeps the range.
mininteger
maxinteger

Example

curl -X PUT https://djangocloud.dev/api/v1/projects/{project_id}/autoscale \
  -H "Authorization: Bearer $TOKEN" \
  -H "Content-Type: application/json" \
  -d '{"enabled": true, "min": 1, "max": 1}'

Responses

200 OK
enabledboolean
mininteger
maxinteger
notestringWhat autoscaling is doing right now, if anything.
max_allowedintegerThe most instances one project can have.
400 The request is malformed. error says what is wrong.
401 Missing or invalid token.
404 No such project or release, or it belongs to someone else.

The usage alert settings

GET /api/v1/projects/{project_id}/alerts token required

GET the alert settings. PUT {"enabled": true, "cpu": 80, "memory": 85, "downtime": true}; any may be left out to keep what is there. Limits are percent of the allocated size.

Parameters

project_idrequiredinteger · path

Example

curl https://djangocloud.dev/api/v1/projects/{project_id}/alerts \
  -H "Authorization: Bearer $TOKEN"

Responses

200 OK
enabledboolean
cpuintegerPercent of the allocated size.
memoryintegerPercent of the allocated size.
downtimebooleanAlso alert when the app stops answering.
firingbooleanTrue while a usage alert is active.
401 Missing or invalid token.
404 No such project or release, or it belongs to someone else.

Change the usage alert settings

PUT /api/v1/projects/{project_id}/alerts token required

Leave a field out to keep what is there. Limits are percent of the allocated size.

Parameters

project_idrequiredinteger · path

Request body (application/json)

enabledboolean
cpuinteger
memoryinteger
downtimeboolean

Example

curl -X PUT https://djangocloud.dev/api/v1/projects/{project_id}/alerts \
  -H "Authorization: Bearer $TOKEN" \
  -H "Content-Type: application/json" \
  -d '{"enabled": true, "cpu": 1, "memory": 1, "downtime": true}'

Responses

200 OK
enabledboolean
cpuintegerPercent of the allocated size.
memoryintegerPercent of the allocated size.
downtimebooleanAlso alert when the app stops answering.
firingbooleanTrue while a usage alert is active.
400 The request is malformed. error says what is wrong.
401 Missing or invalid token.
404 No such project or release, or it belongs to someone else.

Whether deploys must have passing tests

GET /api/v1/projects/{project_id}/tests token required

GET the policy and the latest reported test run. PUT {"require": true} refuses deploys unless the CLI reports that the tests passed. The report is self-reported: this guards against mistakes, not against a person who sends the flag without running anything.

Parameters

project_idrequiredinteger · path

Example

curl https://djangocloud.dev/api/v1/projects/{project_id}/tests \
  -H "Authorization: Bearer $TOKEN"

Responses

200 OK
requirebooleanDeploys are refused unless the CLI reports that the tests passed.
lastobject or nullThe latest release that reported a test run: its version, status, command.
401 Missing or invalid token.
404 No such project or release, or it belongs to someone else.

Require passing tests for deploys, or stop requiring them

PUT /api/v1/projects/{project_id}/tests token required

The CLI reports the result of the tests it ran; this is self-reported, so it guards against mistakes rather than against someone who sends the flag without running anything.

Parameters

project_idrequiredinteger · path

Request body (application/json)

requirerequiredboolean

Example

curl -X PUT https://djangocloud.dev/api/v1/projects/{project_id}/tests \
  -H "Authorization: Bearer $TOKEN" \
  -H "Content-Type: application/json" \
  -d '{"require": true}'

Responses

200 OK
requirebooleanDeploys are refused unless the CLI reports that the tests passed.
lastobject or nullThe latest release that reported a test run: its version, status, command.
400 The request is malformed. error says what is wrong.
401 Missing or invalid token.
404 No such project or release, or it belongs to someone else.

CPU and memory, as percent of the server size

GET /api/v1/projects/{project_id}/metrics token required

CPU and memory (percent of the allocated size) for since (default 1h, e.g. 30m, 6h, 7d; at most 30d), oldest first, thinned to at most 500 points. latest is the newest sample, whatever its age.

Parameters

project_idrequiredinteger · path
sincestring · queryHow far back, for example 30m, 6h or 7d (default 1h, at most 30 days).

Example

curl https://djangocloud.dev/api/v1/projects/{project_id}/metrics \
  -H "Authorization: Bearer $TOKEN"

Responses

200 OK
powerstring
scaleinteger
alertsobject
alerts.enabledboolean
alerts.cpuintegerPercent of the allocated size.
alerts.memoryintegerPercent of the allocated size.
alerts.downtimebooleanAlso alert when the app stops answering.
alerts.firingbooleanTrue while a usage alert is active.
latestobject or nullThe newest sample, whatever its age.
latest.atdatetime
latest.cpunumberPercent of the allocated size.
latest.memorynumberPercent of the allocated size.
pointsarray of objectOldest first, thinned to at most 500 points.
points.[]atdatetime
points.[]cpunumberPercent of the allocated size.
points.[]memorynumberPercent of the allocated size.
400 The request is malformed. error says what is wrong.
401 Missing or invalid token.
404 No such project or release, or it belongs to someone else.

Database

The project's database

GET /api/v1/projects/{project_id}/database token required

Parameters

project_idrequiredinteger · path

Example

curl https://djangocloud.dev/api/v1/projects/{project_id}/database \
  -H "Authorization: Bearer $TOKEN"

Responses

200 OK
sizestring
habooleanHigh availability: a standby in a second zone.
readyboolean
removingboolean
open_untildatetimeWhen the public endpoint locks again.
network_pendingobject
snapshot_pendingboolean
aws_errorstring
statestring
publicboolean
endpointstring
last_snapshotobject or null
last_snapshot.namestring
last_snapshot.created_atdatetime
last_snapshot.statestring
latest_restorabledatetime
401 Missing or invalid token.
404 No such project or release, or it belongs to someone else.

Open or lock the database's public endpoint

POST /api/v1/projects/{project_id}/database/network token required

{"public": true} opens the database's public endpoint for an hour (it locks again by itself, see projects.tasks.lock_databases); {"public": false} locks it now, which also cuts off the app until it is opened.

Parameters

project_idrequiredinteger · path

Request body (application/json)

publicrequiredbooleantrue opens the public endpoint for an hour, then it locks by itself. false locks it now, which also cuts off the app until it is opened.

Example

curl -X POST https://djangocloud.dev/api/v1/projects/{project_id}/database/network \
  -H "Authorization: Bearer $TOKEN" \
  -H "Content-Type: application/json" \
  -d '{"public": true}'

Responses

202 Accepted: it continues in the background
sizestring
habooleanHigh availability: a standby in a second zone.
readyboolean
removingboolean
open_untildatetimeWhen the public endpoint locks again.
network_pendingobject
snapshot_pendingboolean
aws_errorstring
statestring
publicboolean
endpointstring
last_snapshotobject or null
last_snapshot.namestring
last_snapshot.created_atdatetime
last_snapshot.statestring
latest_restorabledatetime
400 The request is malformed. error says what is wrong.
401 Missing or invalid token.
404 No such project or release, or it belongs to someone else.
409 Conflicts with the current state, for example a deploy is already running.
429 Rate limited. Try again later.

Take a manual snapshot

POST /api/v1/projects/{project_id}/database/snapshot token required

snapshot_pending is true until it is done, then last_snapshot shows it. One at a time.

Parameters

project_idrequiredinteger · path

Example

curl -X POST https://djangocloud.dev/api/v1/projects/{project_id}/database/snapshot \
  -H "Authorization: Bearer $TOKEN"

Responses

202 Accepted: it continues in the background
sizestring
habooleanHigh availability: a standby in a second zone.
readyboolean
removingboolean
open_untildatetimeWhen the public endpoint locks again.
network_pendingobject
snapshot_pendingboolean
aws_errorstring
statestring
publicboolean
endpointstring
last_snapshotobject or null
last_snapshot.namestring
last_snapshot.created_atdatetime
last_snapshot.statestring
latest_restorabledatetime
401 Missing or invalid token.
404 No such project or release, or it belongs to someone else.
409 Conflicts with the current state, for example a deploy is already running.
429 Rate limited. Try again later.

Errors

Every error is JSON with a stable error code and a human message. Some add hints such as billing_url, aws_url or regions.

{
  "error": "not_found",
  "message": "No such project."
}