Skip to the page
Get started

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 forRelease pipeline, Nagios check…
MayRun 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

CallReturns
GET /api/checksEvery Check in the key's workspace
GET /api/checks/<id>One Check
POST /api/checks/<id>/runThe full result: columns, rows, summary, Rules, warnings, hosts
GET /api/checks/<id>/historyRuns, newest first
GET /api/checks/<id>/runs/<runId>One stored run. result is null once the rows have expired
POST /api/checks/<id>/export.xlsxA spreadsheet. Re-runs the comparison rather than serialising a preview
POST /api/checks/<id>/export.pdfA PDF, capped at 20 000 rows
GET /api/checks/<id>/exportThe definition as JSON, for version control
GET /api/healthUnauthenticated. 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.

CodeMeansExtra
400Bad body, or no workspace
401Bad key, or session gone
402Over a tier ceilinglimit, allowed, current
402Feature not on this tierfeature
403Needs a higher role
404Not found, or not yours
409Conflict — e.g. compacting a shared database
429Sign-in throttle onlyretry-after
502An 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.