Documentation menu
Report API
Report a backup run with one HTTP request.
Last updated
The Report API lets a script tell BackupSentinel how a backup went, instead of sending a report email. Use it for backup tools that can run a command after a job but cannot send a useful email. An API report goes through the same steps as an email report: it sets the job's status, opens or resolves alerts, and resets the clock for missing reports.
The endpoint
There is one endpoint:
POST https://app.backupsentinel.io/api/v1/jobs/{jobId}/report
jobId is the ID of a backup job in your workspace. Copy it from the job's page or the job's details panel under Job ID. The job must exist first: the API reports on jobs, it does not create them.
Authentication
Every request carries an API key in the Authorization header:
Authorization: Bearer bsk_live_<48 hex characters>
Owners and admins create keys in Settings → API keys:
- Choose Create key and give it a name, such as the server or pipeline that will use it.
- Copy the key straight away. It is shown once and only its hash is stored, so it cannot be shown again.
- Settings lists each key by name with its first characters, when it was created and when it was last used.
Revoke deletes a key. Anything still using it gets 401 from then on. Creating and revoking keys are recorded in the activity log. A key can report on any job in the workspace.
Request body
Send JSON with Content-Type: application/json.
| Field | Type | Rules |
|---|---|---|
status | string | Required. ok, warn or failed. These become Healthy, Warning and Failed. |
size_bytes | number | Optional. The backup size in bytes, 0 or more. A size of 0 is accepted but not recorded. |
duration_seconds | number | Optional. How long the backup ran, from 0 to 604800 (seven days). Rounded to whole seconds. |
timestamp | string | Optional. When the backup ran, in ISO 8601. Ignored, and the time of receipt used instead, when it is missing, cannot be read, is more than 5 minutes in the future or is more than 30 days old. |
idempotency_key | string | Optional. A fallback for the Idempotency-Key header. When both are sent, the header wins. |
Other fields are ignored.
Idempotency
Networks fail, and a script that retries a request should not report the same backup twice. Send an Idempotency-Key header with a value that is unique to that backup run, such as the tool's session ID.
- Keys are per job. The same key on two different jobs is two different reports.
- Sending a key that the job has already recorded returns
200with"duplicate": true. Nothing else happens: no status change, no alert, no second entry in the history. - If a request with the same key is still being processed, the API answers
503with aRetry-After: 30header. Wait and send it again. - If a request with that key started but never finished, a retry more than 60 seconds later processes it again.
Without a key, every request is a new report.
Response
A report that is accepted returns 200 with:
{
"ok": true,
"status": "failed",
"alert_id": "8d3f2a61-4b7e-4c2d-9a10-5e6f7a8b9c0d",
"duplicate": false,
"superseded": false
}
| Field | Meaning |
|---|---|
ok | Always true on success. |
status | The status you sent. |
alert_id | The alert this report opened or updated, for a warn or failed report. null otherwise. |
duplicate | true when the idempotency key was already recorded for this job, so nothing was done. |
superseded | true when the report's timestamp is not newer than the job's latest report. The report is kept, but the job's status does not change and no alert is sent. |
Errors return the status code below and a JSON body with one field, error, holding the message.
Errors
| Code | Message | What to do |
|---|---|---|
| 400 | "Invalid JSON body", "status must be one of: ok, warn, failed", "size_bytes must be a non-negative number" or "duration_seconds must be a number of seconds between 0 and 604800" | Fix the request body. Retrying the same body fails again. |
| 401 | "Missing or malformed Authorization header", "Invalid API key" or "API key has expired" | Check the header reads Bearer followed by the full key, and that the key has not been revoked. |
| 403 | "Workspace suspended" | The workspace is suspended or cancelled and is not monitored. See Billing and plans. |
| 404 | "Job not found" | The job ID does not exist in the key's workspace. Copy it again from the job. |
| 429 | "Rate limit exceeded — max 60 requests/minute" | Slow down. The limit is per key. |
| 429 | "Daily ingest cap (100 reports/job) reached — try again after the trailing 24h window rolls over" | The job has had 100 reports in the last 24 hours. This one was not recorded. |
| 500 | For example "Failed to record report" | Something failed on our side. Retry with the same Idempotency-Key. |
| 503 | "A report with this Idempotency-Key is still being processed — retry shortly" | Wait for the Retry-After seconds and retry. |
Limits on requests
- 60 requests a minute per API key. Use one key per server or pipeline if you report many jobs at once.
- 100 reports per job in a trailing 24 hours. The same cap applies to report emails.
Examples
Report a successful backup with its size and run time:
curl -X POST https://app.backupsentinel.io/api/v1/jobs/3c1e9b52-7d4a-4f80-b6a2-1f0e9d8c7b6a/report \
-H "Authorization: Bearer $BACKUPSENTINEL_KEY" \
-H "Content-Type: application/json" \
-H "Idempotency-Key: nightly-2026-10-06" \
-d '{"status":"ok","size_bytes":53687091200,"duration_seconds":2710,"timestamp":"2026-10-06T02:14:00Z"}'
{ "ok": true, "status": "ok", "alert_id": null, "duplicate": false, "superseded": false }
Sending the same request again returns:
{ "ok": true, "status": "ok", "alert_id": null, "duplicate": true, "superseded": false }
A request with a wrong status:
{ "error": "status must be one of: ok, warn, failed" }
Keep the key out of the script itself: read it from an environment variable or your secret store.
How API reports appear
An API report is handled like an email report:
- It sets the job's status. A
failedorwarnreport opens an alert (or raises the job's open one) that goes to your channels and follows your escalation rules, and the nextokreport resolves it and sends a recovery notice. - The due time for the next report counts from when the API report was received, as for email. See Job statuses.
- If the client is paused or archived, the report is stored and updates the status, but no alert is sent.
- In the job's history the report's source is shown as
api:followed by the key's first characters, so you can tell which key sent it.
Limits
- There is one endpoint, for sending reports. There are no endpoints to read jobs, statuses, alerts or reports.
- The API cannot create, change or delete backup jobs. Create the job in the dashboard first.
- API keys have no scopes: a key can report on every job in the workspace.
- A size_bytes of 0 is not recorded.