Developer docs

API reference

A small, stable JSON API for reading campaigns and issues, filing issues from your own tooling, and subscribing to events. It is the same surface the DeploySeal Zapier app is built on. Everything lives under /api/v1; the machine-readable contract is at /api/v1/openapi.json on the API host (use your own host if self-hosted).

Authentication

Create an organisation API key under Settings → Integrations → API keys (Owner or Admin). The key is shown once; DeploySeal keeps only a hash. Send it as a bearer token:

curl https://api.deployseal.com/api/v1/campaigns \
  -H "Authorization: Bearer ds_live_a1b2c3d4e5f6g7h8i9j0k1l2m3n4o5p6"

# X-Api-Key is accepted too
curl https://api.deployseal.com/api/v1/me -H "X-Api-Key: ds_live_…"
  • Keys start with ds_live_ in production and ds_test_ elsewhere.
  • A key authenticates only against /api/v1. It cannot sign in, manage members or billing, or reach the dashboard API — and a dashboard session cannot call /api/v1.
  • Revoking a key takes effect immediately; anything using it gets a 401.

GET /api/v1/me

{
  "organization": { "id": "0c2a…", "name": "Acme Commerce" },
  "key": { "id": "9d1f…", "name": "Zapier", "scopes": ["read", "write", "webhooks"] }
}

Scopes

A key carries any combination of three scopes. They are independent — write does not imply read. A call without the right scope gets a 403.

ScopeGrants
readList campaigns and issues, read issue detail and event samples.
writeCreate issues.
webhooksCreate, list and delete webhook endpoints — what the Zapier triggers use.

Endpoints

EndpointScopeWhat it does
GET /api/v1/meanyThe calling key and its organisation.
GET /api/v1/campaignsreadEvery campaign, newest first. Optional ?status=Active|Draft|Paused|Closed.
GET /api/v1/campaigns/{id}/issuesreadIssues of a campaign, most severe first. ?page=1&pageSize=50 (max 200), ?status=, ?severity=.
POST /api/v1/campaigns/{id}/issueswriteFile an issue. Reporter is recorded as "API key {name}".
GET /api/v1/issues/{id}readIssue detail with status history.
GET /api/v1/eventsreadNames of the webhook events emitted today.
GET /api/v1/events/{event}/samplereadA representative delivery envelope for one event (what Zapier shows while you build a Zap).
GET /api/v1/webhookswebhooksWebhook endpoints of the organisation.
POST /api/v1/webhookswebhooksSubscribe a URL (REST hook). Returns the signing secret once.
DELETE /api/v1/webhooks/{id}webhooksUnsubscribe.

GET /api/v1/campaigns

readinessLevel is the launch policy's verdict (ReadyToLaunch, ReadyWithIssues, AtRisk, DoNotLaunch); gate folds in required sign-offs (cleared, awaiting-signoff, not-cleared).

[
  {
    "id": "1a2b3c4d-5e6f-4a8b-9c0d-1e2f3a4b5c6d",
    "name": "Spring checkout release",
    "status": "Active",
    "siteId": "5f1c2d3e-4a5b-4c6d-8e7f-9a0b1c2d3e4f",
    "siteName": "acme-store.example",
    "readinessLevel": "ReadyWithIssues",
    "gate": "awaiting-signoff",
    "createdAt": "2026-08-30T09:12:44.101Z"
  }
]

GET /api/v1/campaigns/{id}/issues

{
  "items": [
    {
      "id": "9b2c5d4e-1f2a-4b3c-8d7e-6f5a4b3c2d1e",
      "seqNumber": 7,
      "title": "Checkout button unresponsive",
      "type": "Bug",
      "severity": "High",
      "status": "New",
      "assigneeName": null,
      "pageUrl": "https://staging.example.com/checkout",
      "createdAt": "2026-09-03T14:21:07.415Z"
    }
  ],
  "page": 1,
  "pageSize": 50,
  "total": 1,
  "hasMore": false
}

POST /api/v1/campaigns/{id}/issues

Goes through the same pipeline as an issue filed from the dashboard: it gets the next per-campaign number, fires IssueCreated to webhooks and chat channels, and syncs to connected issue trackers.

POST /api/v1/campaigns/{id}/issues
Content-Type: application/json

{
  "title": "Promo code field accepts whitespace",
  "description": "Entering \"  SPRING10 \" is rejected but the same code without spaces works.",
  "severity": "Medium",          // Low | Medium | High | Critical
  "type": "Bug",                 // Bug | Feedback | Question | Suggestion
  "pageUrl": "https://staging.example.com/cart"
}

201 Created
{ "id": "…", "seqNumber": 8 }

REST hooks (webhooks)

Subscribing through the API creates the same endpoint as the settings page, signed the same way and delivered through the same durable outbox. Endpoints created here are labelled via API in Settings → Integrations → Outbound Webhooks. Payloads, signature verification and retries are documented in the webhook events reference; GET /api/v1/events/{event}/sample returns a sample envelope for any emitted event, built by the same code as the real deliveries.

POST /api/v1/webhooks
Content-Type: application/json

{
  "url": "https://hooks.zapier.com/hooks/standard/…",
  "events": ["IssueCreated"],      // empty or omitted = every event
  "name": "Zapier — new issue"     // optional label for the settings page
}

201 Created
{
  "id": "…",
  "url": "https://hooks.zapier.com/hooks/standard/…",
  "events": ["IssueCreated"],
  "secret": "base64…"              // HMAC-SHA256 signing secret, shown once
}

Rate limits & errors

  • 600 requests per minute per key. Over the limit you get a 429 with a Retry-After header in seconds.
  • Errors are RFC 7807 application/problem+json with a traceId you can quote to support. Validation failures are 422 with a per-field errors map.
  • Enum values are the same strings the dashboard shows (High, InProgress, …). Timestamps are UTC ISO-8601.
HTTP/1.1 403 Forbidden
Content-Type: application/problem+json

{
  "status": 403,
  "title": "Access denied.",
  "detail": "This API key does not carry the scope this endpoint requires.",
  "traceId": "0HN4…"
}

HTTP/1.1 429 Too Many Requests
Retry-After: 37
Content-Type: application/problem+json

{ "status": 429, "title": "Too many requests.", "detail": "Rate limit exceeded. Retry after 37 seconds.", "traceId": "…" }

Zapier

The DeploySeal app for Zapier connects with an API key that has all three scopes. Triggers (new issue, issue status changed, campaign launched, report sealed, tester completed) are REST hooks on top of the endpoints above; the Create issue action and the Find campaign search use the campaign and issue endpoints. If you prefer not to install the app, Webhooks by Zapier → Catch Hook works with any endpoint you add in the settings page.

Ready to build? Keys live in your organisation settings.

Open API keys