REST API v1
Everything the app can do, as an endpoint.
Manage contacts, build and send campaigns, read reporting, subscribe to webhooks, and call the AI copy tools, from your own systems.
Base URL
https://launch.email/api/v1
Authentication
Authorization: Bearer <your-api-key>
Or the X-Api-Key header. API access is on the Business plan; generate a key in Settings.
Your first call
Confirm the credential works and see what it can reach:
curl https://launch.email/api/v1/me \
-H "Authorization: Bearer $TWEAK_API_KEY"
Add a contact. The write is an upsert on email address, so re-running it is safe:
curl -X POST https://launch.email/api/v1/contacts \
-H "Authorization: Bearer $TWEAK_API_KEY" \
-H "Content-Type: application/json" \
-d '{"email":"jane@example.com","first_name":"Jane","tag_ids":[3]}'
A contact who has already unsubscribed keeps that status no matter what you send, so a full-address-book re-sync can never quietly resubscribe someone.
Contacts
Contacts, lists, tags, and saved segments. Upserts key on email address, so a sync job never needs to hold our ids.
/contacts
List contacts. Filter by status, tag, list, segment, or modification time
/contacts
Create or upsert by email
/contacts/bulk
Upsert up to 1,000 at once
/contacts/{id|email}
Fetch by id or email address
/contacts/{id|email}
Update fields, status, tags, or list membership
/contacts/{id|email}
Soft delete
/contacts/{id}/tags
Add tags, firing tag-triggered sequences
/contacts/{id}/erase
GDPR Article 17 erasure
/lists
Contact lists, with membership endpoints
/tags
Tags
/segments/preview
Resolve a segment definition to a count and a sample
Campaigns
Author, review, and send. Every send runs the same gates as the app: verified sending domain, unsubscribe link, plan allowance, abuse screening.
/campaigns
List campaigns
/campaigns
Create a draft
/campaigns/{id}/content
Set the body, or seed it from a template
/campaigns/{id}/variants
Configure A/B variants
/campaigns/{id}/preflight
Dry-run every send check, read-only
/campaigns/{id}/test
Send test messages to named addresses
/campaigns/{id}/send
Send now
/campaigns/{id}/schedule
Send at a future time
/campaigns/{id}/cancel
Cancel a draft, scheduled, or paused campaign
/templates
Your templates plus the starter library
/sequences
Sequences, with enrolment endpoints
Reporting
The read side of the event pipeline. Machine opens (Apple MPP) are excluded by default, so the rates reflect human engagement.
/events
Every delivery event. Filter by type, campaign, contact, or date
/events
Ingest events from your own systems
/campaigns/{id}/report
Delivery and engagement metrics
/campaigns/{id}/report/links
Per-link click breakdown, bot traffic separated
/campaigns/{id}/report/variants
Per-variant A/B results
/campaigns/{id}/recipients
Per-recipient delivery detail
/suppressions
The do-not-mail list
Transactional & AI
One-off sends through the same infrastructure as campaigns, plus the AI tooling as callable endpoints.
/send
Send a transactional message with merge variables
/ai/polish
Rewrite copy for a tone and goal
/ai/subject-lines
Generate and score subject lines
/ai/deliverability
Spam score, issues, and a pass/warn/fail verdict
/ai/usage
Remaining AI and email allowance this period
Webhooks & keys
Subscribe a URL to platform events instead of polling. Manage credentials programmatically for automated rotation.
/webhooks/event-types
Everything you can subscribe to
/webhooks
Register an endpoint, returning the signing secret once
/webhooks/{id}/deliveries
What we sent and what your endpoint answered
/webhooks/{id}/test
Fire a synthetic event to verify your signature check
/api-keys
List keys, with masked prefixes
/api-keys
Mint a scoped key
/api-keys/{id}
Revoke
Cursor pagination
Every collection is keyset-paginated. Pass next_cursor back as ?cursor= and stop when has_more is false.
{
"data": [ ... ],
"per_page": 25,
"next_cursor": "eyJpZCI6MTAwfQ",
"has_more": true
}
Deep pages stay fast, and rows arriving mid-walk can't cause a sync to skip records the way shifting offsets do.
Idempotency
Send an Idempotency-Key header on any write. A retry with the same key replays the original response instead of executing again.
-H "Idempotency-Key: order-4417-receipt"
Use it on campaign sends especially: a duplicated send is the one mistake here you can't undo. Keys are honoured for 24 hours.
Scoped keys
Issue one key per integration with only the scopes it needs, then revoke that one without disturbing the others.
contacts:read
contacts:write
campaigns:read
campaigns:write
campaigns:send
events:read
events:write
suppressions:read
suppressions:write
transactional:send
ai:write
webhooks:read
webhooks:write
A :write grant implies the matching :read. Sending is its own scope, so a key that drafts campaigns can't put mail in front of customers.
Webhook signatures
Every delivery carries a Tweak-Signature header. Verify it against the raw request body before trusting the payload.
Tweak-Signature: t=1754835600,v1=9f86d0818...
hmac_sha256(secret, "{t}.{raw_body}") == v1
The timestamp is inside the signed material, so a captured payload can't be replayed at you indefinitely. Reject anything older than a few minutes.
Unified event pipeline
Every delivery event, whether from provider webhooks, native sends, or your own API calls, flows through one pipeline, and back out again over GET /events and your webhooks.
- Campaign stats updated automatically
- Auto-suppress on bounce, spam, unsubscribe
- Contact statuses synced in real time
- Switch providers, keep your history
Reverse ETL
Connect BigQuery, pick an audience without a CSV, and use approved warehouse fields as merge tags at send time.
- OAuth with read-only BigQuery scope
- Browse datasets, tables, and columns
- Map columns to email placeholders
- Approved fields resolved during sending
Rate limits
Counted per API key, so one integration's burst never eats another's headroom. Every response carries X-RateLimit-Limit and X-RateLimit-Remaining.
| Requests (Business) | 600/min |
| Events per request | 1,000 |
| Contacts per bulk call | 1,000 |
| Records per page | 100 |
Error responses
Standard HTTP status codes with JSON error bodies.
| 401 | Missing, invalid, revoked, or expired key |
| 403 | Missing scope, or plan excludes API access |
| 404 | No such record on your team |
| 422 | Validation error, or a send gate failed |
| 429 | Rate limited, see Retry-After |
A refused send returns a blockers array naming each unmet requirement. POST /campaigns/{id}/preflight returns the same list without attempting to send.
Business plan
Build on it today
Generate a scoped API key in Settings, point your client at the OpenAPI spec, and ship.
Start free