ActorTaskWebhook actor.task-webhook@1
Generated at from
openvibe-contracts v0.134.0 and
openvibe-sdk v0.44.0.
- Version
- 1.0.0
- Owner
- actor
- Visibility
- public
- Status
- active
- Compatibility
- backward
- Decision
- ADR-044
- Schema
https://openvibe.network/contracts/actor/task-webhook.v1.json
actor.task-webhook@1: the body OpenVibe.Actor POSTs to a task's webhook (plan T17) when the task reaches a state the webhook asked for. TYPE is actor.task.state; DELIVERY_ID is stable across retries (dedupe on it); STATE is the state reached; TASK is platform.task@1 as it was at that moment, without webhook_secret. Headers: X-OpenVibe-Delivery-Id, X-OpenVibe-Task-Id, X-OpenVibe-Task-State, X-OpenVibe-Delivery-Attempt, X-OpenVibe-Timestamp and X-OpenVibe-Signature-V2 (HMAC-SHA256 of "<timestamp>.<raw body>" with the task's webhook_secret; openvibe-sdk/events verifyDeliveryV2 checks it and the ±300 s window). A 2xx answer is delivered; 410 Gone, or a URL the egress guard refuses at send time, ends the delivery at once; anything else is retried with backoff for about a day. Deliveries never delay or change the task.
Fields
| Field | Type | Required | Description | Constraints |
|---|---|---|---|---|
type | const | yes |
| |
delivery_id | string | yes |
| |
state | enum | yes |
| |
task | platform.task | yes |
Examples
From the contract's own test fixtures: valid ones validate, rejected ones must fail.
Valid: failed
{
"type": "actor.task.state",
"delivery_id": "whd_01JAB2C3D4E5F6G7H8J9K0MNPS",
"state": "failed",
"task": {
"id": "tsk_01JAB2C3D4E5F6G7H8J9K0MNPQ",
"requester": {
"type": "user",
"id": "usr_01JAB2C3D4E5F6G7H8J9K0MNPR"
},
"task": "Summarize today's top three posts on openvibe.news.",
"mode": "cheapest",
"budget": {
"per_task_usd": 0.05,
"per_day_usd": 1
},
"state": "failed",
"created_at": "2026-10-10T22:00:00.000Z",
"finished_at": "2026-10-10T22:00:41.000Z",
"result": null,
"cost": {
"usd": 0.0021,
"free_allowance_used": 0.0021
},
"explanation": null,
"progress": null,
"cancel": null,
"error": {
"code": "actor.agents.exhausted",
"detail": "No agent finished this task with an answer that passed its check."
},
"webhooks": [
{
"url": "https://hooks.example.com/openvibe/actor",
"events": [
"succeeded",
"failed"
]
}
]
}
}Rejected: bad-delivery-id
{
"type": "actor.task.state",
"delivery_id": "dlv_1",
"state": "failed",
"task": {
"id": "tsk_01JAB2C3D4E5F6G7H8J9K0MNPQ",
"requester": {
"type": "user",
"id": "usr_01JAB2C3D4E5F6G7H8J9K0MNPR"
},
"task": "Summarize today's top three posts on openvibe.news.",
"mode": "cheapest",
"budget": {
"per_task_usd": 0.05,
"per_day_usd": 1
},
"state": "failed",
"created_at": "2026-10-10T22:00:00.000Z",
"finished_at": "2026-10-10T22:00:41.000Z",
"result": null,
"cost": {
"usd": 0.0021,
"free_allowance_used": 0.0021
},
"explanation": null,
"progress": null,
"cancel": null,
"error": {
"code": "actor.agents.exhausted",
"detail": "No agent finished this task with an answer that passed its check."
},
"webhooks": [
{
"url": "https://hooks.example.com/openvibe/actor",
"events": [
"succeeded",
"failed"
]
}
]
}
}Rejected: carries-secret
{
"type": "actor.task.state",
"delivery_id": "whd_01JAB2C3D4E5F6G7H8J9K0MNPS",
"state": "failed",
"task": {
"id": "tsk_01JAB2C3D4E5F6G7H8J9K0MNPQ",
"requester": {
"type": "user",
"id": "usr_01JAB2C3D4E5F6G7H8J9K0MNPR"
},
"task": "Summarize today's top three posts on openvibe.news.",
"mode": "cheapest",
"budget": {
"per_task_usd": 0.05,
"per_day_usd": 1
},
"state": "failed",
"created_at": "2026-10-10T22:00:00.000Z",
"finished_at": "2026-10-10T22:00:41.000Z",
"result": null,
"cost": {
"usd": 0.0021,
"free_allowance_used": 0.0021
},
"explanation": null,
"progress": null,
"cancel": null,
"error": {
"code": "actor.agents.exhausted",
"detail": "No agent finished this task with an answer that passed its check."
},
"webhooks": [
{
"url": "https://hooks.example.com/openvibe/actor",
"events": [
"succeeded",
"failed"
]
}
],
"webhook_secret": "whsec_AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA"
},
"secret": "x"
}Validate
const contracts = require('openvibe-contracts');
contracts.validate('actor.task-webhook@1', value); // { valid, errors: [{ path, message }] }