Check your workspace from code: Koltrix API health, domains and usage
Four read-only Koltrix API calls tell a script which workspace a key belongs to, whether it can send, if domains are ready and how close you are to limits.

On this page(9 sections)
Most email problems in an application show up late. A domain record gets removed during a DNS cleanup, a workspace slips into read-only mode after a payment issue, or a monthly send limit is reached on the busiest day. Your code only finds out when a customer asks why the receipt never came.
The Koltrix REST API has a few small read-only calls that let your own code ask these questions first. This post walks through each one, what it returns, and a simple routine that turns them into a health check you can run on a schedule.
What you can ask
All of these live under https://api.koltrix.com/api/v2 and use the same API key as sending. Send it as a bearer token: Authorization: Bearer kx_….
| Call | What it tells you | Scope needed |
|---|---|---|
GET /me |
Which workspace the key belongs to, its plan and whether it can send | Any valid key |
GET /domains |
For each sending domain, whether MX, SPF, DKIM and DMARC are confirmed | read |
GET /usage |
How much of the plan is used: storage, sends, AI actions, mailboxes, seats | read |
GET /templates |
The workspace's saved templates, and GET /templates/:id for one |
read |
None of them change anything. The full field list is in the API reference and the key and scope rules are on the same page.
Call one: who am I?
GET /me is the cheapest check there is, and it works with any valid key.
curl https://api.koltrix.com/api/v2/me \
-H "Authorization: Bearer $KOLTRIX_API_KEY"
{
"tenant": "acme",
"permissions": ["read", "send"],
"id": "0d3f6a52-91c4-4b7e-8e2a-6f1b3c9d4a10",
"name": "Acme",
"plan": "growth",
"read_only_reason": ""
}
Three fields matter most:
tenantis the workspace's short name. A key belongs to exactly one workspace, so this answers the question "did I paste the staging key into production?" before you send anything.permissionslists the key's scopes. If your health check needsreadand the key only hassend, you find out here with a clear message rather than a confusing 403 later.read_only_reasonis empty when the workspace can send. If it holds a value, the workspace cannot send right now, and the text says why. Treat anything non-empty as an alert, because every send will fail until someone fixes the plan.
If you run more than one workspace, make one key in each. The tenant in the response tells you which is which. The same one-workspace rule applies to AI assistants, as described in two workspaces in Claude.
Call two: are my domains ready?
GET /domains lists the workspace's sending domains.
{
"data": [
{
"domain": "acme.com",
"ready": true,
"mx": true,
"spf": true,
"dkim": true,
"dmarc": true,
"last_checked_at": "2026-10-22T08:00:00Z"
}
]
}
ready is true when the domain can send and receive. The four booleans show which record is missing when it is not. A check that loops through data and alerts on any ready: false catches the most common silent failure: someone edited DNS and a record disappeared.
Two habits make this more useful:
- Alert on the specific record. "acme.com: dkim missing" is something a person can fix in a minute. "A domain is not ready" is not.
- Look at
last_checked_at. If it is old, the status may be stale. Treat a very old timestamp as a warning on its own.
When a record is missing, the background in domain verification flows explains how to word the message so the right person can act on it.
Call three: how close am I to the limits?
GET /usage shows how much of the plan the workspace has used.
{
"plan": "growth",
"trial": false,
"storage": { "used": 1288490188, "limit": 53687091200, "percent": 2 },
"api_sends_monthly": { "used": 3120, "limit": 50000, "window": "month", "percent": 6 },
"mailboxes": { "used": 4, "limit": 10, "percent": 40 },
"seats": { "used": 3, "limit": 5, "percent": 60 }
}
Each figure has used, limit and percent, and the sending figures also have a window (a day or a month). Two details to handle in code:
- A
limitof-1means unlimited. Check for it before you divide, or you will report nonsense percentages. trialtells you the workspace is still on a trial. A trial workspace is the one most likely to hit a wall, so it deserves a lower alert threshold.
A reasonable rule is a warning at 80 percent and an alert at 95 percent, using the percent field the API already gives you. Warn early enough that a person can add capacity or clean up before it matters. For what to do when a send is refused by a limit, see handling 429 errors.
Call four: are my templates there?
GET /templates returns the saved templates, with name, category, subject, body_html, body_text and timestamps, and GET /templates/:id returns one. This is useful in two places:
- A deploy check. If your application expects a template named "Pricing question" and it is missing, you want to know before a customer replies.
- A backup. The response contains the full text, so a nightly job can save it to your own storage.
Pass a malformed id to /templates/:id and you get a 404, not a server error, so a bad id from a stale config is easy to recognize.
Putting it together: a small health check
Here is a shell sketch that combines the first three calls. It prints one line per problem and exits non-zero when something needs attention, so a scheduler or a monitoring tool can act on it.
#!/usr/bin/env bash
set -u
api=https://api.koltrix.com/api/v2
auth="Authorization: Bearer $KOLTRIX_API_KEY"
bad=0
me=$(curl -sf -H "$auth" "$api/me") || { echo "me: request failed"; exit 2; }
[ -n "$(echo "$me" | jq -r .read_only_reason)" ] && { echo "workspace is read-only: $(echo "$me" | jq -r .read_only_reason)"; bad=1; }
curl -sf -H "$auth" "$api/domains" | jq -r '.data[] | select(.ready|not) | "domain not ready: \(.domain)"' | grep . && bad=1
curl -sf -H "$auth" "$api/usage" | jq -r 'to_entries[] | select(.value|type=="object" and .percent != null) | select(.value.limit != -1 and .value.percent >= 90) | "usage \(.key) at \(.value.percent)%"' | grep . && bad=1
exit $bad
Run it every hour from a scheduler, and send the output to wherever your team already looks. Keep the key in a secret store, and give it only the scopes it needs. A key for this job needs read and nothing more, which is the principle behind API key security.
What this does not do
It is worth being clear about the limits of these calls.
- They do not send mail. Sending is a separate call with the
sendscope, and it should always carry an idempotency key, as covered in idempotency keys for email sends. - They do not prove a message arrived. A ready domain means your records are in place, not that a particular message reached an inbox. For delivery of one message, read the message log and its events.
- They show the workspace, not other workspaces. One key sees one workspace.
A short checklist
- Make a key with only the
readscope for monitoring. - Call
/mefirst, and checktenant,permissionsandread_only_reason. - Loop through
/domainsand alert on the exact record that is missing. - Read
/usage, handle alimitof-1, and warn before 100 percent. - Check that the templates your code depends on still exist.
- Run the check on a schedule and send failures to a place people read.
- Keep the key in a secret store and rotate it if it leaks.
Key takeaways
A few read-only calls give your own code the same view a person gets in the Koltrix settings: who the key is, whether the workspace can send, whether each domain is ready and how much of the plan is left. Check them on a schedule, alert on the specific problem and give the monitoring key only the read scope. You will hear about a lost DNS record or a nearly full limit from your own script, not from a customer.
Start with Koltrix
Your domain, one inbox, and an API that sends.
A team inbox where AI sorts and drafts (nothing is sent without your click), plus the transactional API and SMTP relay your product sends with. 7 days free, no card.


