API reference

Spaces

Create and manage spaces with an account key

These routes serve products that send email on behalf of their own customers: one space per blog, client or workspace, each with its own reputation, on a single bill. Spaces explained.

These routes require an account key (Account › Account API keys). A space key answers 403. Space and account keys.

The pattern

  1. Create the space the first time a customer needs to send, with your own id as externalId. The same externalId returns the existing space: safe to run on every send.
  2. Add their domain with POST /v1/domains and the header X-Space-Id, then show the DNS records to your customer (or publish them if you manage their DNS).
  3. Send with the same account key and X-Space-Id on every request: emails, contacts, campaigns.
# 1. Create (or find) the space of blog 42
curl https://api.kulamail.com/v1/spaces \
  -H "Authorization: Bearer ml_your_account_key" \
  -H "Content-Type: application/json" \
  -d '{ "name": "The Daily Fern", "externalId": "blog_42" }'

# 2. Add its domain
curl https://api.kulamail.com/v1/domains \
  -H "Authorization: Bearer ml_your_account_key" \
  -H "X-Space-Id: 9b8a7c6d-5e4f-4a3b-2c1d-0e9f8a7b6c5d" \
  -H "Content-Type: application/json" \
  -d '{ "domain": "dailyfern.com" }'

The space object

{
  "id": "9b8a7c6d-5e4f-4a3b-2c1d-0e9f8a7b6c5d",
  "name": "The Daily Fern",
  "externalId": "blog_42",
  "timezone": "UTC",
  "defaultFromName": "The Daily Fern",
  "defaultFromEmail": "hello@dailyfern.com",
  "defaultReplyTo": null,
  "trackOpens": true,
  "trackClicks": true,
  "reputationStatus": "OK",
  "marketingPaused": false,
  "createdAt": "2026-10-17T09:30:00Z"
}
FieldMeaning
externalIdYour own reference, unique in the account
defaultFromName, defaultFromEmail, defaultReplyToSender used when an email doesn't set one. The address must use a verified domain of the space
trackOpens, trackClicksOpen pixel and click tracking, on by default
reputationStatusOK, WATCH or ALERT, over the last 7 days. Reputation
marketingPausedtrue when campaigns and flows are paused. Transactional emails keep flowing

List spaces

GET /v1/spaces

Every space of the account, oldest first.

Create a space

POST /v1/spaces

name
string required
120 characters at most.
externalId
string
Your own reference, 120 characters at most. If a space of the account already has it, that space is returned unchanged.

Returns 201 with the space object, or 200 with the existing space when the externalId is already used.

The free plan includes one space: creating another answers 402 quota_exceeded. Plans.

Get a space

GET /v1/spaces/{id}

Update a space

PATCH /v1/spaces/{id}

Changes the fields sent; the others stay as they are.

name
string
120 characters at most.
defaultFromName
string
Default sender name.
defaultFromEmail
string
Default sender address, on a verified domain of the space.
defaultReplyTo
string
Default reply-to address.
trackOpens
boolean
Track opens.
trackClicks
boolean
Track clicks.
curl -X PATCH https://api.kulamail.com/v1/spaces/9b8a7c6d-5e4f-4a3b-2c1d-0e9f8a7b6c5d \
  -H "Authorization: Bearer ml_your_account_key" \
  -H "Content-Type: application/json" \
  -d '{ "defaultFromName": "The Daily Fern", "defaultFromEmail": "hello@dailyfern.com" }'

Delete a space

DELETE /v1/spaces/{id}

Deletes the space and everything in it: domains, contacts, lists, campaigns, flows and keys. Irreversible. Answers 204, or 400 for the last space of the account.