API Overview
The SendOps Public API lets you read events, manage configuration, and inspect account state programmatically. It is the same data plane your dashboard uses, exposed under https://api.sendops.dev and authenticated with an API key you create from your account settings.
This is not a send API
SendOps is a control plane on top of your AWS SES infrastructure. To send mail, call SES directly with your own AWS credentials. The SendOps API lets you read events, manage configuration, and inspect account state — it never relays or sends email on your behalf.
What the API gives you
- Message-level observability — list, search, and trace individual messages and the SES events they emit.
- Reporting — deliverability and engagement aggregates, plus per-template performance.
- Suppressions — read the account-level suppression list and look up individual recipients.
- Configuration introspection — channels (SES configuration sets), templates, tracking domains, and SES identities.
- Contacts & subscriptions — read your SES contact list, subscription topics, and contacts (attributes and per-topic preferences), and write them too: create, replace, patch, delete, upsert by external id, and bulk-import up to 5000 contacts per call.
- Lists & Segments — read static Lists and dynamic, SendQL-defined Segments with their members, and preview a predicate before saving it. List definitions are writable; Segments are read-only bar the preview dry-run.
- Attributes — read and write the custom-attribute registry (the schema Segment predicates compile against), with a dry-run that reports an edit’s impact on dependent Segments.
- Activities — read contact activity, and ingest free-form behavioral signals with
POST /v1/activities(single or batch). - Broadcasts — read broadcast definitions and delivery state, and create, send/schedule, test, and delete one-off bulk sends to a List or Segment.
- Workflows — read drip-workflow definitions, runs, exit/funnel analytics, and per-contact timelines, plus a dry-run simulation against a sample contact.
- Tags — read the org’s tag vocabulary (Gmail-style folders across Lists, Segments, and Templates).
- Assets — read your git-sourced image asset library: the images promoted to your Edge CDN, with their source paths, CDN URLs, and dimensions.
- Account state — the calling org’s onboarding state, AWS connection status, plan, send quota, and SES production-access state.
Every endpoint is documented in the sidebar, grouped by resource. The catalogue is generated from the live OpenAPI spec.
What the API does not do (in v1)
- No sending. Mail is sent by your application against SES directly. The API never accepts a send — even Broadcasts fire through your own SES account.
- No browser-origin calls. CORS is closed; the API is server-to-server only.
- No infrastructure writes. The audience surface (contacts, topics, Lists, attributes, Broadcasts) is writable, but AWS-facing configuration — channels, SES identities, tracking domains, and suppressions — stays read-only here and is changed in the dashboard.
- No git-owned writes. Definitions that originate from a connected git repo (git-backed Lists, Segments, and attributes) are read-only through the API and return
409 conflict— edit them in the repository. Segment membership is computed, never written; the/v1/segments/previewPOSTis a non-mutating dry-run that evaluates a predicate without saving anything.
Authentication at a glance
Every request carries an Authorization: Bearer sk_<env>_<...> header. Keys are scoped to a single organization and granted a subset of permissions (scopes) chosen when the key was created. Live and test keys share the same scope vocabulary; requests are unthrottled until a per-org rate limit is configured, and when one is, test keys run at 10% of the live ceiling.
See Authentication for the full key lifecycle.
Conventions
- All endpoints are versioned under
/v1/and use JSON request/response bodies. There is no XML or form-encoded alternative. - Timestamps are ISO 8601 in UTC (
2026-05-17T19:00:00Z). - IDs are UUIDs in canonical hyphenated form.
- Errors follow RFC 7807
application/problem+json. - Lists are cursor-paginated; offsets and totals are not exposed.
- Rate-limit headers (both
RateLimit-*and legacyX-RateLimit-*) appear on every response once a per-org limit is configured; until then requests are unthrottled. See Rate Limiting.
Getting your first response
You’ll need: a SendOps account, an API key with at least one scope (e.g., api.reports.view), and a terminal. Head to the Quickstart for a five-minute walk-through.