API overview
Base URL, authentication, errors, and pagination for the REST API.
View as Markdown ↗Base URL & authentication
One base URL, one kind of credential. Every endpoint authenticates with an API key as a bearer token — create one under Developers → API Keys.
https://emailbump.com/api/v1curl https://emailbump.com/api/v1/contacts \
-H "Authorization: Bearer ebk_your_key"Start here
Two calls answer what is this API, and what may I do with it, so nothing has to be guessed at:
curl https://emailbump.com/api/v1 # the index — no key needed
curl https://emailbump.com/api/v1/me -H "Authorization: Bearer ebk_your_key"GET /v1/me is the one to make before your first send. It names the project the key belongs to, whether the account's email is confirmed, which sending domains are verified, the from address to use, and whether the compliance footer carries your own postal address or our placeholder. Every one of those can refuse a send, and reading them beforehand beats interpreting the refusal.
{
"project": { "id": "7a10f0f2-…", "name": "Main", "object": "project" },
"sending": {
"ready": true,
"email_confirmed": true,
"verified_domains": ["mail.acme.com"],
"default_from": "[email protected]",
"note": "Ready. `from` must be an address on one of the verified domains."
},
"footer": { "address": "12 Bridge Street, Austin TX", "is_your_own_address": true }
}No account yet
POST /v1/signup creates one from the command line — an email address, no password, no browser:
curl -X POST https://emailbump.com/api/v1/signup \
-H "Content-Type: application/json" \
-d '{ "email": "[email protected]", "name": "Dana", "accept_terms": true }'It returns a project key for sending and an account key for creating further projects and keys. The account cannot send until the six-character code we email is confirmed with POST /auth/verify-email/code. More on keys.
Two halves, one API
Everything lives under the same base URL, and every reference page says at the top which key reaches it. The split is only about what a resource belongs to:
What you send and who you send it to — contacts, events, lists, segments, templates, campaigns, flows, transactional email. A project key reaches these directly.
Project resourcesThe structure those projects live in — workspaces, projects, project keys, sending domains. Needs an all-access key, and is mostly for agents and CLIs setting an account up.
Account resourcesAn all-access key can do both: it reaches any project resource too, by naming the project per call with an X-Project-Id header. A project key stays inside its own project. How keys and scopes work.
One exception, because it was on the wrong side of the line: a project key manages its own project's sending domains at /v1/domains — list, add, check. Setting up sending is the first thing a project needs to do, and it shouldn't require the wider credential.
Pagination
Contacts, campaigns, flows, and flow enrollments are paginated: they accept ?limit= (max 100, default 25) and ?offset=, and return { "data": [...], "total", "limit", "offset" }. Lists, segments, and templates are small by nature and return the full set as { "data": [...] }. Every call you make appears under Developers → API Keys → Recent API calls.
Plan limits and usage
/v1/limitsWhat plan the project is on, how many contacts it holds, and how much of this month's sending allowance is left — so an integration can back off or prompt an upgrade before it hits the wall rather than after.
curl https://emailbump.com/api/v1/limits \
-H "Authorization: Bearer ebk_your_key"{
"plan": "growth",
"plan_name": "Growth",
"contacts": { "count": 8412, "limit": 25000 },
"sending": {
"this_month": 31204,
"included_per_month": 250000,
"remaining": 218796,
"over_limit": false
},
"features": { "automations": true, "custom_domains": true, "…": true }
}A 0 contact limit and a null included_per_month both mean unmetered.
Unrecognised fields
On /v1/emails, a field we don’t read is ignored but not silently — the response carries a warnings array naming it. from_name is the one that bites: it’s a real field on campaigns and flows, and here the display name belongs in from ("Acme <[email protected]>"). A typo that changes nothing is worth hearing about at the time.
A misspelled first_nmae on /v1/contacts returns 200 with nothing said, and the field it was meant to set is simply unchanged. Check the response body reflects what you sent rather than trusting the status code.
Errors
Errors always return a single consistent shape with the right HTTP status. Successful reads and writes return 200; deletes return 204.
{ "error": "Enter a valid email address" }400— invalid or malformed request body / validation failed401— missing or invalid API key402— upgrade required for a paid feature (addscode,feature, andupgrade_tofields)404— resource not found (or not in your project)409— conflict (e.g. a contact with that email exists)429— shared-domain daily send limit reached
Tracing a sent message
Every message Email Bump sends — API, SMTP, campaign, or flow — carries two headers that say where it came from, so a forwarded email, one sitting in a spam folder, or a bounce report a recipient sends you can be tied back to a project without a database lookup:
X-EmailBump-Project: 7a10f0f2-3b44-4c19-9c6e-2f81a6d4e0aa
X-EmailBump-Stream: transactionalX-EmailBump-Stream is transactional, marketing (campaigns), or automation (flows). The project id is the same value you'd pass as X-Project-Id, so it drops straight into an API call or a support ticket.
Inside Email Bump the same ids ride along as provider message tags — project, stream, and the campaign, flow, step, or A/B variation responsible — which is what the reports join on. To follow one message: Developers → Transactional has every API and SMTP send with its provider message id, rendered content, and event timeline; Developers → API Keys → Recent API calls has the request that caused it, and which key made it.
Project resources
One page per thing you can act on, all reachable with a project key.
Account resources
The provisioning half, for standing an account up. Needs an all-access key.
A typical agent onboarding: create a workspace and read its starter project id, add a sending domain and publish the DNS records, mint a project key, then use the project API with that key.
TOKEN=ebk_all_access_key
BASE=https://emailbump.com/api/v1
# 1. A workspace — the response includes its starter project
PROJ=$(curl -s -X POST $BASE/workspaces -H "Authorization: Bearer $TOKEN" \
-H "Content-Type: application/json" -d '{"name":"Acme Agency"}' | jq -r .project.id)
# 2. A sending domain (returns the DNS records to publish)
curl -s -X POST $BASE/projects/$PROJ/domains -H "Authorization: Bearer $TOKEN" \
-H "Content-Type: application/json" -d '{"domain":"mail.acme.com"}'
# 3. A project key for the application to send with
KEY=$(curl -s -X POST $BASE/projects/$PROJ/api-keys -H "Authorization: Bearer $TOKEN" \
-H "Content-Type: application/json" -d '{"name":"server"}' | jq -r .key)
# 4. From here it's the project API — a welcome flow, with the new key
curl -s -X POST $BASE/flows -H "Authorization: Bearer $KEY" \
-H "Content-Type: application/json" -d '{
"name": "Welcome",
"trigger": { "type": "contact_created" },
"steps": [{ "type": "send", "subject": "Welcome!", "html": "<p>Thanks for joining.</p>" }]
}'