Signed callbacks and receiver acknowledgement
A scheduler callback carries the configured body and a signed identity token. Receivers verify the claims, bind accepted work to the registered payload and deduplicate retries.
Callback envelope
The body is exactly the payload you configured — there is no envelope wrapping it. Identity
does not travel in plaintext headers: there are no X-Tenant-Id or X-Schedule-Id
headers to read. The scheduler's identity and firing claims are inside the signed token.
The signature authenticates the token claims. It does not automatically bind the raw HTTP body; validate the payload against the schedule registered in your system before accepting work.
Signing keys and claim verification
| Token or key property | Receiver behavior |
|---|---|
| Signing algorithm | Require RS256. |
kid header | Select the matching public key from the deployment's JWKS. |
| Key rotation | Refresh the key set as needed; do not pin one key permanently. |
| JWKS caching | Honor Cache-Control: max-age=300 rather than fetching keys for every callback. |
Verification uses public keys. The receiver needs no shared secret or private signing key.
Signed claims
{
"iss": "https://api.travila.ai",
"sub": "<the schedule owner>",
"aud": "your-host.example.com/your/endpoint",
"iat": 1754500000,
"exp": 1754500300,
"jti": "sched:sched_abc123:1754500000000",
"trigger": "scheduled",
"schedule_id": "sched_abc123",
"tenant_id": "your-tenant",
"project_id": "default"
}
| Claim | Check |
|---|---|
iss | Must equal https://api.travila.ai |
aud | Must match the expected normalized host + path |
exp / iat | Require both; reject expired tokens, implausible future issuance and lifetimes outside your allowed window |
jti | Required non-empty firing identity; deduplicate within verified scope |
trigger | scheduled for a scheduler dispatch |
schedule_id | Required schedule identity; match your registered schedule |
tenant_id, project_id, sub | Required scope and owner; compare with the schedule you accept |
An act.sub claim appears when the dispatch acts on behalf of another subject.
Configure the issuer and JWKS endpoint for the deployment you use. Do not accept an old issuer or alternate hostname merely because it once served the platform. Treat issuer changes as a deliberate trust-configuration migration.
Audience normalization
aud is your target URL reduced to host + path — no scheme, no query string, and the
scheme's default port dropped. A target of https://api.example.com/hooks/daily-digest
produces:
api.example.com/hooks/daily-digest
Verify against the value you expect rather than accepting any audience. This is what stops a token minted for one of your endpoints being replayed against another.
Retry identity and body binding
Retries of one firing reuse jti = sched:<schedule_id>:<scheduled_time_unix_ms>. The Idempotency-Key header is a convenience copy; use the verified claim for authority and reject a mismatched header.
Bind the acceptance record to the verified issuer, tenant, project, owner, schedule, audience and firing ID, and to a canonical payload digest. Retain it longer than the complete retry/replay window configured for your deployment. A signed token alone does not prove that someone holding it has left the request body unchanged. Compare the body with the schedule configuration saved in your application; the current token does not supply a signed body digest.
Receiver acknowledgement
| Receiver outcome | Scheduler behavior for that firing |
|---|---|
| HTTP status below 400 | Records successful delivery; this does not establish completion of downstream work. |
408, 425, 429, 5xx, or a network failure | Records failure and retries within the configured attempt limit. |
Other 4xx | Records failure and stops retrying that firing. |
A later scheduled firing remains independent of the previous delivery outcome. Consecutive failures can auto-pause the schedule.
Respond promptly after durable acceptance and process slow business work out of band. A delivery acknowledgement records receiver acceptance, not completion of the business action.
Agent callback verification
Scheduled-agent callbacks use the same signed claims, audience normalization and firing identity as other scheduled callbacks.
| Verification step | Required result |
|---|---|
| Verify the token | Trusted deployment issuer, valid signature and acceptable issuance/expiry window. |
| Match the registration | Expected audience, tenant, project, owner and schedule. |
| Check the payload | Body agrees with the trusted schedule registration; the JWT does not contain a signed body digest. |
| Accept once | Atomically store the scoped firing identity and payload digest with a pending work item. |
Use the complete receiver algorithm before starting the agent.
Scheduled agent completion
Interpret the generation result using the canonical conversation outcome contract. Only a completed result permits consuming its completed output; unsuccessful and nonterminal responses can omit messages. A scheduler delivery acknowledgement does not establish agent completion.
Result webhook subscription
The current platform permits one live subscription per endpoint; a second is rejected with ALREADY_EXISTS. Separate endpoints with overlapping filters can receive the same event, so deduplicate shared business effects across those receivers. See Endpoints and subscriptions for changes and cutover guidance.