execution_id back, and either poll for status or have Sinas POST the result to a URL you provide.
This is the right pattern when an app — like a custom UI or another service — needs to fan out work for a logged-in user. Every job is attributed to the user whose bearer token kicked it off, so audit trails remain intact.
When to use it
- Bulk workloads — ingestion runs, batch enrichment, anything that fans into N function calls.
- Long jobs — a function that legitimately runs minutes or longer; the client doesn’t want to hold an open HTTP connection.
- Cross-app workflows — a function on Sinas that calls back into your app’s API as the same user (Sinas-issued tokens are accepted by any app that validates via Sinas auth).
POST /functions/{ns}/{name}/execute instead.
Endpoint
| Field | Type | Required | Notes |
|---|---|---|---|
input | object | yes | Validated against the function’s input_schema. |
trigger_id | string | no | App-supplied correlation id stored on the execution record. Defaults to "runtime-api". |
delay_seconds | integer | no | Delay before the worker picks up the job. null = enqueue immediately. |
callback_url | string | no | HTTPS URL Sinas POSTs to once the execution terminates. See Callbacks. |
sub is the job’s user. There’s no user_id override and no “act-as-user” mode — every queued job is attributable to the human (or human-equivalent account) whose token initiated it. Audit-log integrity depends on this.
Permission: reuses the existing function-execute permissions — sinas.functions/{ns}/{name}.execute:own (or :all). No extra permission gates the queue path; anything you can execute synchronously, you can enqueue.
Response
GET /executions/{execution_id} (returns the current status, output_data, error, etc.).
Callbacks
Ifcallback_url is set, Sinas fires a single HTTP POST to that URL when the execution terminates (success, failure, or timeout). Fire-and-forget — no retries.
SinasAuth; JS SDK: client.auth.getMe()).
Delivery semantics
- Fire-and-forget: one POST attempt with a 10s timeout. No retry, no DLQ.
- No backpressure: Sinas does not wait for callback success before marking the execution complete.
- Resilience fallback: if the callback fails to deliver, poll
GET /executions/{execution_id}to reconcile. The execution row recordscallback_status(sent/failed) andcallback_response_codefor operator visibility.
Allowlist policy
Callback hosts are gated by theCALLBACK_URL_HOSTS environment variable:
| Value | Meaning |
|---|---|
| unset / empty | Callbacks disabled. Any callback_url in a request returns 400. |
* | Permissive — any HTTPS URL accepted (subject to SSRF guards). |
| comma-separated host list | Exact-host allowlist. |
https:// and resolve to a non-private address. Managed-service operators typically deploy with an explicit allowlist; self-hosted single-tenant operators flip to * once.
SDK helpers
Python
JavaScript
Worked example
Your app submits 50 documents for ingestion on behalf of a signed-in user.- The app’s backend, holding the user’s bearer, calls
client.functions.enqueue(...)once per document. - Each
execution_idlands in a queue. A Sinas worker dequeues and runsmyapp/ingest_documentunder the user’s identity. - The function calls the app’s
/api/v1/documents/{id}/mark-processedwith the per-execution access token. The app’sSinasAuthvalidates the token via Sinas’s/auth/me, applies the user’s permissions, persists the update. - When the function finishes, Sinas POSTs the result to
callback_url. The app updates the run’s progress and notifies the user.
ingest_document invokes a Sinas agent (client.chats.invoke(...)), the agent runs in-process under the same user; sub-agent fan-out is internal and doesn’t re-cross the app boundary, so the function token’s TTL never bites.
Batches
Submitting N executions one at a time works, but for genuine bulk workloads (50+ runs at once) you’d rather submit them as a single unit, store one id, and poll one aggregate. Thebatches API does that — for both functions
and agents.
Submit — function batch
Submit — agent batch
agent.initial_messages pre-populated
(templated with input_variables) followed by message. Agent batches
have an approval policy: if a child agent tries to call a tool that
requires approval, the execution is marked failed with an error — bulk
agent runs must use agents whose enabled tools don’t require approval.
Per-execution callback result for agent batches:
GET /chats/{chat_id}.
Poll a batch
status values:
completed— all children completed successfullypartial— all children terminal, ≥1 failedfailed— all children failedcancelled— batch cancelled before all children terminated
Drill in
Cancel
pending or awaiting_input become cancelled.
Running children must complete naturally; their results still count
toward the batch.
Batch callback
When the last child terminates, Sinas POSTs the batch summary once tobatch_callback_url:
callback_url) and the batch callback are
independent — both can be set, both fire.
Limits
MAX_BATCH_SIZE(env) caps how manyinputsa single batch can have (default1000).- Single-target batches only: every child in a batch hits the same function (or agent). For mixed targets, submit multiple batches.
SDK helpers
Python:Related
- Functions — defining the code that runs.
- API Overview — runtime vs. management surfaces.
- RBAC — how
sinas.functions/{ns}/{name}.executepermissions resolve.