/v1/batches API. Send the model and prompts you want; Phaseo infers the upstream provider, creates files when the provider requires files, and uses inline native batch APIs when the provider supports them. Use provider only when you need an advanced routing constraint.
Inline request batches use one endpoint shape throughout the batch. Choose
/v1/chat/completions, /v1/responses, /v1/messages, or /v1/embeddings,
then submit request bodies in that endpoint’s normal format. The top-level
model is inherited by rows that omit body.model.
1. Create the batch
For an inline Responses batch:GET /v1/batches/capabilities before selecting an advanced endpoint and
provider combination.
For a prebuilt JSONL file:
2. Use the TypeScript SDK helper
The SDK keeps the create, poll, per-request result, and webhook verification steps together:client.batches.wait(...) only after you have persisted the batch id. It polls an existing job; it does not create a replacement job.
3. Poll status for recovery
Always keep your own polling path even when webhooks are enabled:lifecycle_statusfor a stable cross-job statuspolling_urlas the canonical status endpointcancel_urlwhen the batch is still cancellable
4. Recover owned jobs after restarts
Workers should list owned jobs during startup before creating replacements:id values. Provider-native ids are exposed for diagnostics, but they are not the durable handle for Phaseo polling or cancellation.
5. Cancel stale work when needed
If the batch is still pending or processing and your application no longer wants the result:6. Consume webhook deliveries
Gateway-managed async webhook payloads are normalized around:- the job id and job kind
lifecycle_status- sanitized webhook configuration
- delivery summary fields
- recent delivery attempts
- whether signing is enabled
- verify the signature
- process deliveries idempotently
- treat retries as normal
- fetch the latest batch status when the payload and local state disagree
webhook.secret, Phaseo signs each delivery with:
x-phaseo-timestamp: Unix timestamp in secondsx-phaseo-signature: hex HMAC-SHA256 of${timestamp}.${rawBody}using your webhook secretx-phaseo-event-id: stable event id for this batch/eventx-phaseo-event-type: event type such asbatch.progressorbatch.completedx-phaseo-delivery-key: idempotency key, including progress bucket when applicablex-phaseo-attemptandx-phaseo-max-attempts: retry attempt metadata
x-phaseo-delivery-key or the payload id before side effects. Return any 2xx status only after your durable state has been updated; non-2xx responses are retried with the same event id and an incremented attempt number.
Webhook subscriptions accept generic job.* events or matching batch.* events, including batch.progress / job.progress for request-count progress. Progress notifications are bucketed for idempotency and may be skipped when the provider has not reported usable request_counts yet. If you omit events, Phaseo subscribes the webhook to terminal job.completed, job.failed, job.cancelled, and job.expired notifications. If you provide events, at least one event must be valid for batch jobs; all-invalid or cross-kind-only lists such as ["video.completed"] are rejected instead of being broadened silently.
Webhook callback URLs must use HTTPS. Literal private, loopback, link-local, and wildcard hosts are rejected; http://localhost, http://127.0.0.1, and http://[::1] are accepted only for local development callbacks.
7. Fetch outputs and reconcile failures
Use the terminal batch object to decide the next step:- completed batches should move on to output retrieval and result ingestion
- failed batches should capture both the batch failure state and the webhook delivery state
- cancelled batches should stop downstream fan-out cleanly
- upstream batch execution failures
- cancellation requested by operators or automation
- webhook delivery failures after the batch itself already finished
8. What to monitor
- batch
lifecycle_status - provider and request correlation ids
- webhook delivery success and retry counts
- last delivery HTTP status
- last failure timestamp and message
- whether
cancel_urlwas still available when cancellation was requested