Skip to content

Job reports API

Job reports are part of Vaicoa Pro and Vaicoa Team. How to set one up: Get told when a job fails.

RequestPOST https://api.vaicoa.com/v1/ingest/job
AuthenticationHeader X-Agent-Token: <agent_token>, the per-server token of the monitored server the job belongs to
Content typeapplication/json
BodyAt most 4 KiB

The token decides which server a job belongs to. A job that runs somewhere else uses the token of the server it relates to. On a server with the agent, the token is CV_AGENT_TOKEN in /etc/cloudviewer-agent/agent.env.

{
"reports": [
{ "job_name": "backup-s3", "exit_code": 0, "duration_seconds": 412, "max_age_seconds": 93600 }
]
}
FieldTypeRequiredMeaning
reportsarray of 1 to 16 objectsyesOne object per job
reports[].job_namestring, ^[a-z0-9][a-z0-9-_.]{0,63}$yesThe job’s name on its server. The first report with a new name creates the job
reports[].exit_codeinteger, 32-bityes0 is a success, anything else a failure
reports[].duration_secondsnumber, 0 or morenoHow long the run took
reports[].max_age_secondsnumber, more than 0noHow old the last successful run may get before the job is stale. Leave it out for failure alerts only
  • job_name: lowercase letters, digits, -, _ and ., 1 to 64 characters, starting with a letter or a digit.
  • Unknown fields are refused. There is no message field and no time field: the time of the run is when Vaicoa receives the report.
  • A request is all or nothing: if one report is invalid, none is stored.
  • Each report replaces the job’s last state, including max_age_seconds. A report without it removes the job’s time limit.
  • Only a report with exit code 0 moves the time of the last success.
  • Vaicoa keeps the last state of each job, not a history of runs: last run, last success, last exit code, last duration and the time limit.
StatuscodeWhen
202Accepted. Body: {"accepted": <number of reports>}
401unauthorizedToken missing or unknown
401agent_revokedToken revoked
403entitlement_requiredThe team’s plan has no job reports
413validation_failedBody larger than 4 KiB
422invalid_schemaNot JSON, an unknown field, no exit_code, no or more than 16 reports, or a number out of range
422invalid_job_namejob_name does not match the pattern
422job_limit_reachedThe report would create a 17th job on the server
429rate_limitedMore than the request budget. Retry-After says when to retry
503internal, busyVaicoa is busy or unavailable. Retry after Retry-After

Errors are JSON: {"code": "…", "message": "…"}. The message names the field, for example reports[0].job_name must match [a-z0-9][a-z0-9-_.]{0,63}.

LimitValue
Body4 KiB
Reports per request1 to 16
Jobs per server16. Reports for jobs that already exist are always accepted
Requests per token2 a minute, bursts of up to 16

Many cron jobs that start on the hour fit into the burst, and one request can carry up to 16 jobs. A job stays as long as its server; there is no way yet to remove a single job.

Terminal window
cloudviewer-report --job <name> [--max-age <duration>] [--token-file <path>] -- <command> [arguments…]
FlagMeaning
--job <name>Required. The job_name
--max-age <duration>Seconds, or a number with m, h or d: 26h is 93600. Sent as max_age_seconds. Leave it out for failure alerts only
--token-file <path>Read the token from this file, which holds only the token. For a server without the agent, or a user who cannot read agent.env
--Ends the flags. Everything after it is the command
  • The wrapper is part of the agent package, at /usr/bin/cloudviewer-report.
  • It runs the command first, then sends its exit code and duration in whole seconds, and exits with the command’s exit code.
  • Token: --token-file, else CV_AGENT_TOKEN from the environment, else /etc/cloudviewer-agent/agent.env. Ordinary users cannot read that file, so a job that does not run as root needs --token-file.
  • API URL: CV_AGENT_FACADE_URL, else https://api.vaicoa.com. When the token comes from agent.env, the URL in that file.
  • Without a token it prints “job ran, not reported” and exits with the command’s exit code.
  • On 429 or 503 it retries once, after Retry-After (at most 60 seconds, 5 if the header is missing). Any other failure prints the HTTP status; the exit code stays the command’s. Each request times out after 15 seconds.
  • A missing --job, a missing command or a bad --max-age is a usage error: exit code 2, and the command does not run.
StatusWhen
SucceededThe last exit code is 0 and the job is not stale
FailedThe last exit code is not 0
StaleThe job has a max_age_seconds, and its last successful run is older than that. Stale wins over a last exit code of 0

A job that has never succeeded never goes stale, because there is no success to measure from. It shows as Failed, and its row says Never succeeded.

RuleSeverityFires when
UserJobFailedwarningThe last exit code is not 0, for 5 minutes
UserJobStalewarningThe last successful run is older than the job’s max_age_seconds, for 5 minutes
  • Vaicoa checks every job once a minute.
  • A job without max_age_seconds only gets UserJobFailed.
  • A failed run followed by a successful one within 5 minutes raises no alert. The next successful run resolves both alerts.
  • All rules: Alert rules.