Bragi API
Bragi exposes a small HTTP API so another system can trigger a Job, ask when one last finished, and register Job Callbacks to be told when a run ends.
Where it runs
The same endpoints are served by both the Bragi web application and the Scheduler Web API host, so point at whichever of the two is reachable from the calling system. The Scheduler API URL setting (Admin > Settings) records the Scheduler Web API address for an Environment.
Authentication
Every endpoint except GET /System/health requires a JWT bearer token.
API keys
A key is a row in bragi.scheduler_web_api_key: a ClientId, a ClientSecret, an Issuer, an Audience and a Type. For this API the Type, Issuer and Audience are all Bragi.
The same table also holds keys for the separate Bragi External API, which serves client data rather than Job control. Those carry External in all three fields and are not interchangeable with these: a token issued for one will not be accepted by the other.
Building a token
Bragi does not hand out tokens. POST /System/Login exists only in development builds, for Swagger's convenience, and is compiled out of a release build. The calling system signs its own token using the client secret it was given.
Part | Value |
|---|---|
Algorithm |
|
Signing key | The client secret, as UTF-8 bytes |
| The key's |
| The key's |
| Who or what the call is on behalf of. Bragi does not enforce this, so use it to attribute the call in your own logs |
| A fresh GUID for each token |
| The key's |
Lifetime | Keep it short. Bragi's own tokens last 30 minutes |
In C#:
Send it on every request as Authorization: Bearer <token>.
Bragi validates the issuer, the audience, the expiry and the signature. It accepts a signature made with any configured API key secret rather than looking one up by ClientId, so every key issued for this API can reach every endpoint. There is no per-key restriction on what a token may do.
Calling convention
Two things are easy to get wrong:
Parameters go in the query string, including on the POSTs. None of these endpoints read a JSON request body.
POST /Jobs/RunJobNow?environmentName=Production&jobName=Daily%20Loadis a complete request; a body would be ignored.A refused call still answers
200 OK. Errors are reported in the response, not by the HTTP status. Checksuccess, do not rely on the status code.
Responses
Every endpoint returns the same envelope:
Endpoints that return data add a result:
When success is false, message says why: the Environment or Job was not found, the Job is not configured for API triggering, the Job is already running and no callbackUrl was given, or an unexpected error occurred.
Allow API Trigger
A Job carries an Allow API Trigger flag, set on the Job configuration screen. It gates the endpoints that cause work or change configuration. The read-only ones do not check it.
Endpoint | Needs Allow API Trigger |
|---|---|
| Yes |
| Yes |
| Yes |
| Yes, unless removing by |
| No |
| No |
Endpoints
System
Endpoint | Description |
|---|---|
| Liveness check. The only endpoint that needs no token, so it is the one to point a monitor at. |
| The same answer, but requires a valid token. Useful for checking your key and token signing work before debugging anything else. |
Jobs
Endpoint | Parameters | Description |
|---|---|---|
|
| Queues the Job to run immediately. See Job Callbacks for the callback parameters and Job Run Modes for the run mode ones. |
|
| Sets the Job's next scheduled run to |
|
| Returns the Job's last successful completion time, or |
|
| Registers a persistent Job Callback. Returns the new callback id. |
|
| Removes a persistent callback. |
|
| Lists the persistent callbacks for an Environment. One shot callbacks are not listed. |
Knowing when a Job has finished
RunJobNow returns as soon as the run is queued, not when it finishes. Two ways to find out the outcome:
Callbacks. Give
RunJobNowacallbackUrland Bragi posts the run outcome to it. This is the recommended approach, and Waiting for a Job: a worked example walks through a full implementation.Polling
LastCompletedJob. Record the time before triggering, then poll until the returned completion time moves past it. Slower and chattier, but it needs nothing of the calling system beyond the ability to make outbound calls, so it suits a system Bragi cannot reach back into.