Docs · Automating
The HTTP API
API keys, running a Check from a pipeline, and the shape of every response.
For the callers that have no browser — a pipeline, a deploy gate, a monitor.
#API keys
Created under Settings → Keys, by an admin.
| Field | |
|---|---|
| What it is for | Release pipeline, Nagios check… |
| May | Run and read, or Run, read and edit |
A key is capped at editor, whatever the person issuing it can do. It runs Checks and reads what they found; it can never publish one or reach the integrations.
The token is shown once:
This is the only time it will be shown. Mosaic keeps a one-way hash and cannot show it again — not to you, and not to anybody who takes the database.
Revoked keys stay on the list, struck through. The row is the only record that the key was ever issued, so it is never deleted.
#Authenticating
Authorization: Bearer mosaic_Ab3xYz_9f4k…There is no X-Api-Key header. A key is tried before the session cookie, so a request carrying both is treated as a key request.
A key belongs to exactly one workspace, taken from the key itself — nothing the caller sends can move it. An entity in another workspace answers 404, not 403: not-found and not-yours are deliberately indistinguishable.
An invalid, revoked or expired key gets 401 {"error": "That key is not valid."}.
#Which address to use
Use /api/checks/…. /api/reports/… is a permanent alias kept working for scripts written before the rename, with no notice period — but new work should use checks.
#Running a Check from a pipeline
The verdict-only shape, which is what a deploy gate wants:
POST /api/checks/<id>/check
Authorization: Bearer mosaic_…
Content-Type: application/json
{ "parameters": { "store": "0421", "date": "2026-09-18" }, "refresh": true }{
"status": "fail",
"report": "Nightly till reconciliation",
"runId": "6f2b1d0a-…",
"at": "2026-09-19T01:04:22.117Z",
"total": 1204,
"matched": 1157,
"diff": 44,
"onlyIn": 3,
"changes": { "added": 3, "changed": 1, "unchanged": 40, "cleared": 0 },
"failures": ["44 differing rows, expected at most 0"],
"exceptions": { "open": 12, "critical": 2, "untriaged": 5 }
}status is pass or fail, and it is the Check's own Rules and nothing else. A Check with no Rules always passes.
changes is the field a deploy gate should read. It distinguishes this deployment introduced a problem from the same standing problem is still there — which is the difference between blocking a release and not.
The run is recorded exactly as any other run, so it appears in history and in the bell.
#The rest of the surface
| Call | Returns |
|---|---|
GET /api/checks | Every Check in the key's workspace |
GET /api/checks/<id> | One Check |
POST /api/checks/<id>/run | The full result: columns, rows, summary, Rules, warnings, hosts |
GET /api/checks/<id>/history | Runs, newest first |
GET /api/checks/<id>/runs/<runId> | One stored run. result is null once the rows have expired |
POST /api/checks/<id>/export.xlsx | A spreadsheet. Re-runs the comparison rather than serialising a preview |
POST /api/checks/<id>/export.pdf | A PDF, capped at 20 000 rows |
GET /api/checks/<id>/export | The definition as JSON, for version control |
GET /api/health | Unauthenticated. Status, version, runtime and job counts — no hostnames, no workspace names |
POST /api/checks/import takes the exported JSON back, which is how a Check moves between installations. That needs an editor key.
Not reachable by any key: publishing, integrations, triggers, key management, deleting a workspace.
#Error shapes
Every error body is {"error": "<sentence>"}. Some carry extra fields.
| Code | Means | Extra |
|---|---|---|
| 400 | Bad body, or no workspace | |
| 401 | Bad key, or session gone | |
| 402 | Over a tier ceiling | limit, allowed, current |
| 402 | Feature not on this tier | feature |
| 403 | Needs a higher role | |
| 404 | Not found, or not yours | |
| 409 | Conflict — e.g. compacting a shared database | |
| 429 | Sign-in throttle only | retry-after |
| 502 | An upstream model or Mosaic Cloud refused |
A 402 reads in full sentences, which makes it safe to surface straight into a pipeline log:
{ "error": "Pro includes 15 schedules, and this installation has 15. Business raises it. Data sources, drivers and the rows they hold are never counted, runs you start yourself are never refused, and nothing you already have is affected.",
"limit": "schedules", "allowed": 15, "current": 15 }The request body limit is 32 MB.