ToolsUsageRecordedPayload tools.usage.recorded@1

Generated at from openvibe-contracts v0.76.0 and openvibe-sdk v0.20.1.

Version
1.0.0
Owner
tools
Visibility
first-party
Status
active
Compatibility
backward
Decision
ADR-014
Schema
https://openvibe.network/contracts/events/payloads/tools.usage.recorded.v1.json

tools.usage.recorded v1 (roadmap WS-N task 4, OpenVibe.Tools apps/_shared/jobs/usage.js). One hour of a developer project's jobs on one Tools satellite, per capability (tools.job.create for POST /api/v1/jobs, tools.tool.run for a tool run) and job type or tool (dimension), in unit jobs: quantity counts the jobs that ended (succeeded or failed; a cancelled job is not counted), errors the failed ones, by code, with the last failures' job ids and trace ids. Counted in the transaction that records a job's end; written to the satellite's outbox after the hour closes. Only jobs of developer-app tokens (they carry a project) are counted; sandbox jobs are counted under env sandbox. The payload is common.usage-recorded@1. Envelope: subject { type: project, id: <project_id> }, visibility internal, priority low, actor service:tools.

Fields

This schema has no named fields.

Examples

From the contract's own test fixtures: valid ones validate, rejected ones must fail.

Valid: img-process-hour
{
  "project_id": "prj_01JAB2C3D4E5F6G7H8J9K0MNPQ",
  "env": "production",
  "capability": "tools.job.create",
  "dimension": "img.process",
  "unit": "jobs",
  "window": "hour",
  "window_start": "2026-09-26T14:00:00.000Z",
  "window_end": "2026-09-26T15:00:00.000Z",
  "quantity": 42,
  "errors": 3,
  "error_codes": {
    "tools.job.failed": 2,
    "tools.job.timeout": 1
  },
  "samples": [
    {
      "at": "2026-09-26T14:51:07.412Z",
      "code": "tools.job.timeout",
      "status": 504,
      "trace_id": "4bf92f3577b34da6a3ce929d0e0e4736",
      "ref": "job_01JAB2C3D4E5F6G7H8J9K0MNPR"
    },
    {
      "at": "2026-09-26T14:20:13.001Z",
      "code": "tools.job.failed",
      "status": 422,
      "ref": "job_01JAB2C3D4E5F6G7H8J9K0MNPS"
    }
  ]
}
Valid: tool-run-sandbox
{
  "project_id": "prj_01JAB2C3D4E5F6G7H8J9K0MNPQ",
  "env": "sandbox",
  "capability": "tools.tool.run",
  "unit": "jobs",
  "window": "hour",
  "window_start": "2026-09-26T08:00:00.000Z",
  "window_end": "2026-09-26T09:00:00.000Z",
  "quantity": 5,
  "errors": 0,
  "dimension": "image-resize"
}
Rejected: job-owner
{
  "project_id": "prj_01JAB2C3D4E5F6G7H8J9K0MNPQ",
  "env": "production",
  "capability": "tools.job.create",
  "dimension": "img.process",
  "unit": "jobs",
  "window": "hour",
  "window_start": "2026-09-26T14:00:00.000Z",
  "window_end": "2026-09-26T15:00:00.000Z",
  "quantity": 42,
  "errors": 3,
  "error_codes": {
    "tools.job.failed": 2,
    "tools.job.timeout": 1
  },
  "samples": [
    {
      "at": "2026-09-26T14:51:07.412Z",
      "code": "tools.job.timeout",
      "status": 504,
      "trace_id": "4bf92f3577b34da6a3ce929d0e0e4736",
      "ref": "job_01JAB2C3D4E5F6G7H8J9K0MNPR"
    },
    {
      "at": "2026-09-26T14:20:13.001Z",
      "code": "tools.job.failed",
      "status": 422,
      "ref": "job_01JAB2C3D4E5F6G7H8J9K0MNPS"
    }
  ],
  "owner": {
    "type": "app",
    "id": "app_01JAB2C3D4E5F6G7H8J9K0MNPQ"
  }
}
Rejected: no-project
{
  "env": "production",
  "capability": "tools.job.create",
  "dimension": "img.process",
  "unit": "jobs",
  "window": "hour",
  "window_start": "2026-09-26T14:00:00.000Z",
  "window_end": "2026-09-26T15:00:00.000Z",
  "quantity": 42,
  "errors": 3,
  "error_codes": {
    "tools.job.failed": 2,
    "tools.job.timeout": 1
  },
  "samples": [
    {
      "at": "2026-09-26T14:51:07.412Z",
      "code": "tools.job.timeout",
      "status": 504,
      "trace_id": "4bf92f3577b34da6a3ce929d0e0e4736",
      "ref": "job_01JAB2C3D4E5F6G7H8J9K0MNPR"
    },
    {
      "at": "2026-09-26T14:20:13.001Z",
      "code": "tools.job.failed",
      "status": 422,
      "ref": "job_01JAB2C3D4E5F6G7H8J9K0MNPS"
    }
  ]
}

Validate

const contracts = require('openvibe-contracts');
contracts.validate('tools.usage.recorded@1', value);   // { valid, errors: [{ path, message }] }