Callbacks
Receive signed, idempotent server-to-server events and completed async results.
No current prepared translation is available. The English source is shown without machine translation.
Configure a callback URL in Profile → Callbacks and async results. Model Gate sends HTTPS POST requests for enabled account notifications and completed native async inference requests. Delivery continues independently of inference requests, so you do not need to make another model call to receive a completed result.
Callback URL and outbound security
Use a publicly reachable HTTPS endpoint. Callback URL validation is an outbound security boundary. Loopback, private, link-local, carrier-grade NAT, documentation/test, multicast, unspecified and reserved IP ranges are rejected. The hostname is validated when saved and again during delivery; redirects are revalidated. Do not point callbacks at internal services or redirects into private networks.
Common event envelope
Every callback uses the same envelope:
{
"event_id": "01J...",
"event": "account.balance_low",
"occurred_at": "2026-08-28T07:00:00Z",
"data": {}
}
event_id is stable for every retry of one logical event. Deduplicate deliveries by event_id; do not infer identity by comparing the rest of the payload. occurred_at is UTC RFC3339. Payloads may gain additional fields over time, so consumers must ignore unknown fields.
Every delivery also includes the same event ID in X-Model-Gate-Event-ID.
Event catalog
account.balance_low
{
"event_id": "01J...",
"event": "account.balance_low",
"occurred_at": "2026-08-28T07:00:00Z",
"data": {
"balance": "10.1234567890",
"threshold": "20.0000000000",
"currency": "USD"
}
}
key.spend_limit_threshold_reached
{
"event_id": "01J...",
"event": "key.spend_limit_threshold_reached",
"occurred_at": "2026-08-28T07:00:00Z",
"data": {
"key_id": "KEY_PUBLIC_ID",
"key_name": "Bank integration",
"usage": "80.1234567890",
"spend_limit": "100.0000000000",
"threshold_percent": 80,
"currency": "USD"
}
}
group.spend_limit_threshold_reached
The payload uses group_id, group_name, exact-decimal usage, exact-decimal spend_limit, integer threshold_percent, and currency = "USD".
request.completed
{
"event_id": "01J...",
"event": "request.completed",
"occurred_at": "2026-08-28T07:00:00.123456Z",
"data": {
"request_id": "01J...",
"status": "completed",
"response_status": 200,
"response": {"id":"msg_...","type":"message"}
}
}
response_status is nullable when no upstream HTTP status exists. Failed/canceled/expired async results may include data.error.
Financial values in callback payloads are exact decimal strings; they are not UI-rounded display values.
Threshold alerts are re-armed after the monitored value leaves its threshold condition. Conditions are checked approximately once per minute; callbacks are not a real-time millisecond crossing signal.
Request format
POST /model-gate/callback HTTP/1.1
Content-Type: application/json
X-Model-Gate-Event-ID: 01J...
X-Model-Gate-Signature: t=1710000000,v1=hex_hmac_sha256
Signature verification
Calculate HMAC-SHA256 over the exact string <timestamp>.<raw_body> using the callback secret generated in Profile. The full secret is shown only when generated or rotated and is stored encrypted at rest. Compare the hexadecimal signature in constant time and reject timestamps outside your accepted replay window. The HMAC timestamp is specific to a delivery attempt; the event_id remains stable across retries.
Delivery, response, and retries
Any HTTP 2xx response accepts the event. HTTP 200 with an empty body is recommended. Transport errors, timeouts, and every non-2xx response are failures.
Each event has at most 6 attempts total: the initial attempt plus five retries. Failed attempts 1–5 are followed by 5 seconds, 30 seconds, 2 minutes, 10 minutes, and 1 hour. Each attempt has a hard 15-second overall timeout. After the sixth failed attempt the event becomes terminal failed and there is no further automatic retry. Delivery can resume after interruptions; use the event identifier to handle duplicates safely.
Do not perform long-running work before responding. Verify the signature, persist/deduplicate by event_id, return 2xx, and process asynchronously.