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

FieldTypeRequiredDescriptionConstraints
typeconstyes
  • = "actor.task.state"
delivery_idstringyes
  • pattern ^whd_[0-9A-HJKMNP-TV-Z]{26}$
stateenumyes
  • one of "queued", "running", "verifying", "succeeded", "failed", "cancelled"
taskplatform.taskyes

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 }] }