Tasks and webhooks
Submit durable JSON jobs and retrieve results without paid resubmission.
POST /v1/ai/tasks requires ai:generate and a stable idempotency key. It accepts an endpoint and its JSON request body:
{
"endpoint": "images/generations",
"body": {"model":"MODEL_ID_FROM_CATALOG","prompt":"A blue ceramic cup","n":1}
}A 202 response contains the task ID. Poll GET /v1/ai/tasks/{id} with ai:read and the original project/tenant context. Statuses include created, queued, submitting, waiting, polling, settling, succeeded, failed and reconciliation_required. Preserve the task ID and key in your job record before retrying work.
If the connection closes before you receive the task ID, use GET /v1/ai/tasks?key=YOUR_ORIGINAL_KEY with ai:read and the original project/tenant. This read-only lookup returns the original task, or 404 task_not_found when that context has no matching request. It never admits another provider call. Keep the original key and frozen body; a revoked credential is not proof that an earlier submission was never accepted.
Tasks accept JSON requests without streaming. Multipart uploads use their direct endpoint. Native Google operations use google/generateContent, google/predict or google/predictLongRunning in the task envelope; the nested body retains Google's native format and includes the catalog model ID.
Tasks store their result and immutable billing snapshot. Binary task results can be represented with _cloud_binary containing a content type and base64 data; direct speech returns bytes instead. The HTTP reference exposes the contract; do not assume Feeef tasks share OpenAI Batch, Files or Responses retrieval semantics.
Register webhooks for ai.task.completed, ai.task.failed and ai.task.reconciliation_required. Callbacks identify the task; retrieve its result with a credential. No arbitrary per-request webhook URL is accepted.
Workers do not automatically repeat an uncertain paid provider submission. A reconciliation state keeps billing pending until verified evidence resolves the outcome; no funds are held for new requests.