beta
Documentation

API

The deploydiff API reads a project's environments, capture batches, diff batches, their tasks and its notifications as JSON, and starts capture and diff batches. It answers with the same data the dashboard shows.

The API comes with the paid plans. Each successful call is billed.

API keys

A key belongs to one project. An organization Owner or Admin creates it from the project's API page in the dashboard, which also shows the project id. The key's secret is shown once, when it is created: store it where your tool keeps its secrets.

A key holds a project role, and has that role's rights on its project:

RoleCan
ParticipantRead everything the API offers on the project
MemberRead, and start capture batches and diff batches

A key never has an organization role: it cannot change settings, members or keys, nor delete anything. A project has at most 25 active keys. Revoking a key takes effect on its next call. See Roles & Permissions.

Authentication

Send the key in the Authorization header of every call:

shell
curl https://deploydiff.com/api/v1/projects/{project_id}/environments \
  -H "Authorization: Bearer dd_…"

The API reads the key from this header only — never from a cookie or the address.

Addresses

Every endpoint is under one project:

endpoint
https://deploydiff.com/api/v1/projects/{project_id}/…

To see the API at work, follow Capture after a deploy.

Responses

Bodies are JSON. Every object says what it is in an object field ("environment", "capture_batch", …), carries its id, and ends with created_at and updated_at. Dates are ISO 8601 timestamps with their offset. A field with no value is present and null, never left out.

The page of each object in the dashboard shows its JSON, the same as the API returns.

Lists

A list answers one page at a time, newest first:

list
{
  "object": "list",
  "data": [
    {
      "object": "capture_batch",
      "id": "00000000-0000-0000-0000-000000000002"
    }
  ],
  "next_cursor": "WyIyMDI2LTExLTA2VDEwOjAwOjAwLjMxKzAwOjAwIiwiYTEuLi4iXQ"
}
ParameterValue
limitHow many items, from 1 to 100. Default 20.
cursorThe next_cursor of the page, to read the page after it.

next_cursor is null on the last page. A cursor does not expire: keep one to read on later from where you stopped. Send it back exactly as you received it: its format is ours and may change.

Errors

An error answers with its HTTP status and a body naming it:

json
{
  "error": {
    "code": "capture_interval",
    "message": "The organization's plan allows one capture on demand every minute per environment, clicks and calls together.",
    "retry_after": 42
  }
}

code is stable: test it, not the message, which is written for people. Some errors add a field beside them, listed below.

StatuscodeWhen
400invalid_parameterA query parameter is out of range, malformed, or sent twice.
400invalid_cursorcursor is not a next_cursor this API returned.
400invalid_bodyThe body of a POST is not a JSON object with the fields the endpoint takes, or is over 16 KB.
401missing_keyNo Authorization: Bearer header.
401invalid_keyThe key is unknown or revoked.
402usage_limit_reachedThe organization has reached its usage limit for the billing period: batches start again when it renews.
402billing_blockedThe organization has an unpaid invoice that was cancelled: contact support.
403wrong_projectThe key does not belong to the project in the address.
403plan_requiredThe organization is not on a paid plan.
403role_requiredThe endpoint needs a Member key.
404not_foundNo such endpoint, or nothing with this id in the project.
405method_not_allowedThe endpoint does not take this method. The Allow header lists those it takes.
409capture_not_doneA diff was asked between capture batches that are not both finished.
422not_runnableA capture batch was created but has nothing it can run. Adds capture_batch_id.
429capture_intervalA capture on demand came too soon after the last one in the environment. Adds retry_after.
500internal_errorSomething went wrong on our side.
504timeoutThe call took too long on our side.

After a 500 or a 504 on a POST, the batch may have been created all the same. Read the environment's latest batches (?limit=1) before sending the call again. A GET can simply be sent again.

Limits

Billing

Each successful call — a 2xx answer, HEAD included — is billed at the rate on the pricing page, drawn from your plan's included usage like the rest. A call that is refused or fails is not billed. The captures and diffs an API call starts are billed like any others.

Your organization's usage page shows the calls, hour by hour, under API Call.