Spaces
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
- Create the space the first time a customer needs to send, with your own id as
externalId. The sameexternalIdreturns the existing space: safe to run on every send. - Add their domain with
POST /v1/domainsand the headerX-Space-Id, then show the DNS records to your customer (or publish them if you manage their DNS). - Send with the same account key and
X-Space-Idon 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"
}
| Field | Meaning |
|---|---|
externalId | Your own reference, unique in the account |
defaultFromName, defaultFromEmail, defaultReplyTo | Sender used when an email doesn't set one. The address must use a verified domain of the space |
trackOpens, trackClicks | Open pixel and click tracking, on by default |
reputationStatus | OK, WATCH or ALERT, over the last 7 days. Reputation |
marketingPaused | true 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
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.
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.