Triggers
Run a job by hand, on a schedule, from a token, or from the CLI, and get told when it finishes.
A job can start four ways. All of them produce the same kind of run.
By hand
Run now on the job page, or aq job run <job>.
On a schedule
A cron expression, always interpreted in UTC. The console previews the next five firings in both your timezone and UTC, so you can see which you are choosing.
Why UTC and not your timezone
A cron in a shifting local timezone silently moves by an hour twice a year. A nightly job that runs at 03:00 except on two nights is the kind of bug nobody attributes to the scheduler.
If the job is already at its machine limit when a firing comes due, the run is queued rather than skipped. Work you scheduled is not silently dropped; it waits, and the placement deadline is what eventually gives up out loud.
If a schedule cannot be parsed, we stop firing it and say so on the job, rather than leaving it looking scheduled while nothing happens.
From a token
Mint a token on the job, then:
curl -X POST https://server.aquanode.io/api/v1/run/<job-id> \
-H "x-job-token: aq_job_..." \
-H "content-type: application/json" \
-d '{"inputs": {"prompt": "a cat"}}'A token's entire vocabulary is "start a run of this one job and read it back". It can reach nothing else on your account, which is what makes handing one to someone else safe.
Every token carries a rate limit and a run cap, both required at mint time. They defend against different things (hammering, and a slow bleed), and a token without both is how an account gets drained.
Webhooks
Give the job a URL and we POST the run and every one of its attempts when it reaches a
final state, so a run that moved between providers shows you that it did.
The body is signed with a secret shown once, when you create it, as
X-Aquanode-Signature: sha256=<hex>, an HMAC-SHA256 over the exact bytes we sent.
Verify against the raw body, not a re-encoded version of it, or your digest will differ
from ours.
Delivery is attempted three times with backoff, and the outcome is stored on the run as one of three states:
| Value | Meaning |
|---|---|
delivered | Your endpoint returned a 2xx |
failed | Three attempts, none accepted |
not_configured | The job has no webhook, so we never tried |
not_configured is kept distinct from failed on purpose: "we never tried" and "we
tried and could not" are different facts, and collapsing them hides a broken integration
until someone goes looking.