ToolsRun tools.run@1
Generated at from
openvibe-contracts v0.33.0 and
openvibe-sdk v0.5.0.
- Version
- 1.0.0
- Owner
- tools
- Visibility
- public
- Status
- active
- Compatibility
- backward
- Decision
- ADR-027
- Schema
https://openvibe.network/contracts/tools/run.v1.json
The answer of POST /api/v1/tools/{id}/run (tools.run-request@1; ADR-027). Finished: { state: succeeded, tool, result, took_ms } or { state: failed|cancelled, tool, error, took_ms }, with job set when the tool ran as a job. Not finished within wait_ms: { state: queued|running, tool, job, location }, sent with 202 and a Location header; follow the job there (GET, its events, its files; tools.job@1). result carries data (kind json, matching the descriptor's output schema), text (kind text) or files (kind file or files: the job's result files, downloaded from their url). took_ms runs from the request to the answer for an inline run, and from created_at to finished_at for a job. error is problem+json from the tool: tools.job.failed, tools.job.timeout, tools.job.cancelled, or a code the tool chose (tools.…). A request refused before the tool ran is a problem+json answer, not a run.
Fields
This schema has no named fields.
Examples
From the contract's own test fixtures: valid ones validate, rejected ones must fail.
Valid: failed-job
{
"state": "failed",
"tool": "mp3",
"error": {
"type": "https://openvibe.network/problems/tools.job.timeout",
"title": "Gateway Timeout",
"status": 504,
"code": "tools.job.timeout",
"detail": "The job ran longer than 900 s",
"error": "The job ran longer than 900 s"
},
"took_ms": 901000,
"job": {
"id": "job_01JAB2C3D4E5F6G7H8J9K0MNPQ",
"object": "tools.job",
"service": "audio",
"type": "audio.process",
"type_version": 1,
"state": "failed",
"progress": {
"percent": 42.5,
"message": "Encoding"
},
"attempts": 1,
"max_attempts": 3,
"cancel_requested": false,
"created_at": "2026-09-23T09:00:00.000Z",
"started_at": "2026-09-23T09:00:01.000Z",
"finished_at": "2026-09-23T09:15:01.000Z",
"expires_at": "2026-09-23T10:00:00.000Z",
"result": null,
"error": {
"type": "https://openvibe.network/problems/tools.job.timeout",
"title": "Gateway Timeout",
"status": 504,
"code": "tools.job.timeout",
"detail": "The job ran longer than 900 s",
"error": "The job ran longer than 900 s"
},
"retryable": true,
"retry_of": null,
"retried_by": null,
"references": [],
"links": {
"self": "/api/v1/jobs/job_01JAB2C3D4E5F6G7H8J9K0MNPQ",
"events": "/api/v1/jobs/job_01JAB2C3D4E5F6G7H8J9K0MNPQ/events",
"cancel": null,
"retry": "/api/v1/jobs/job_01JAB2C3D4E5F6G7H8J9K0MNPQ/retry",
"retried_by": null
}
}
}Valid: queued
{
"state": "queued",
"tool": "png",
"job": {
"id": "job_01JAB2C3D4E5F6G7H8J9K0MNPQ",
"object": "tools.job",
"service": "img",
"type": "img.process",
"type_version": 1,
"state": "queued",
"progress": {
"percent": null,
"message": null
},
"attempts": 0,
"max_attempts": 3,
"cancel_requested": false,
"created_at": "2026-09-23T09:00:00.000Z",
"started_at": null,
"finished_at": null,
"expires_at": "2026-09-23T10:00:00.000Z",
"result": null,
"error": null,
"retryable": false,
"retry_of": null,
"retried_by": null,
"references": [],
"links": {
"self": "/api/v1/jobs/job_01JAB2C3D4E5F6G7H8J9K0MNPQ",
"events": "/api/v1/jobs/job_01JAB2C3D4E5F6G7H8J9K0MNPQ/events",
"cancel": "/api/v1/jobs/job_01JAB2C3D4E5F6G7H8J9K0MNPQ",
"retry": null,
"retried_by": null
}
},
"location": "/api/v1/jobs/job_01JAB2C3D4E5F6G7H8J9K0MNPQ"
}Valid: running-absolute-location
{
"state": "running",
"tool": "png",
"job": {
"id": "job_01JAB2C3D4E5F6G7H8J9K0MNPQ",
"object": "tools.job",
"service": "img",
"type": "img.process",
"type_version": 1,
"state": "running",
"progress": {
"percent": 12,
"message": "Converting"
},
"attempts": 1,
"max_attempts": 3,
"cancel_requested": false,
"created_at": "2026-09-23T09:00:00.000Z",
"started_at": "2026-09-23T09:00:01.000Z",
"finished_at": null,
"expires_at": "2026-09-23T10:00:00.000Z",
"result": null,
"error": null,
"retryable": false,
"retry_of": null,
"retried_by": null,
"references": [],
"links": {
"self": "/api/v1/jobs/job_01JAB2C3D4E5F6G7H8J9K0MNPQ",
"events": "/api/v1/jobs/job_01JAB2C3D4E5F6G7H8J9K0MNPQ/events",
"cancel": "/api/v1/jobs/job_01JAB2C3D4E5F6G7H8J9K0MNPQ",
"retry": null,
"retried_by": null
}
},
"location": "https://openvibe.tools/api/v1/jobs/job_01JAB2C3D4E5F6G7H8J9K0MNPQ"
}Valid: succeeded-inline-json
{
"state": "succeeded",
"tool": "dns",
"result": {
"data": {
"name": "openvibe.tools",
"records": {
"A": [
"203.0.113.7"
]
}
}
},
"took_ms": 38
}Valid: succeeded-inline-text
{
"state": "succeeded",
"tool": "jsonminify",
"result": {
"text": "{\"a\":1}"
},
"took_ms": 2,
"job": null
}Valid: succeeded-job
{
"state": "succeeded",
"tool": "png",
"result": {
"files": [
{
"name": "photo.png",
"mime": "image/png",
"size": 90112,
"sha256": "9f86d081884c7d659a2feaa0c55ad015a3bf4f1b2b0b822cd15d6c15b0f00a08",
"storage": "media",
"media": {
"media_id": "med_01JAB2C3D4E5F6G7H8J9K0MNPS",
"role": "output",
"namespace": "tools",
"size_bytes": 90112,
"content_hash": "9f86d081884c7d659a2feaa0c55ad015a3bf4f1b2b0b822cd15d6c15b0f00a08",
"mime_type": "image/png",
"status": "ready"
},
"url": "/api/v1/jobs/job_01JAB2C3D4E5F6G7H8J9K0MNPQ/files/0"
}
],
"data": {
"width": 1024,
"height": 768
}
},
"took_ms": 4000,
"job": {
"id": "job_01JAB2C3D4E5F6G7H8J9K0MNPQ",
"object": "tools.job",
"service": "img",
"type": "img.process",
"type_version": 1,
"state": "succeeded",
"progress": {
"percent": 100,
"message": "Done"
},
"attempts": 1,
"max_attempts": 3,
"cancel_requested": false,
"created_at": "2026-09-23T09:00:00.000Z",
"started_at": "2026-09-23T09:00:01.000Z",
"finished_at": "2026-09-23T09:00:04.000Z",
"expires_at": null,
"result": {
"files": [
{
"name": "photo.png",
"mime": "image/png",
"size": 90112,
"sha256": "9f86d081884c7d659a2feaa0c55ad015a3bf4f1b2b0b822cd15d6c15b0f00a08",
"storage": "media",
"media": {
"media_id": "med_01JAB2C3D4E5F6G7H8J9K0MNPS",
"role": "output",
"namespace": "tools",
"size_bytes": 90112,
"content_hash": "9f86d081884c7d659a2feaa0c55ad015a3bf4f1b2b0b822cd15d6c15b0f00a08",
"mime_type": "image/png",
"status": "ready"
},
"url": "/api/v1/jobs/job_01JAB2C3D4E5F6G7H8J9K0MNPQ/files/0"
}
],
"data": {
"width": 1024,
"height": 768
}
},
"error": null,
"retryable": false,
"retry_of": null,
"retried_by": null,
"references": [
{
"ref": "community:paste:p_123",
"created_at": "2026-09-23T09:05:00.000Z"
}
],
"links": {
"self": "/api/v1/jobs/job_01JAB2C3D4E5F6G7H8J9K0MNPQ",
"events": "/api/v1/jobs/job_01JAB2C3D4E5F6G7H8J9K0MNPQ/events",
"cancel": null,
"retry": null,
"retried_by": null
},
"tool": "png"
}
}Rejected: failed-without-error
{
"state": "failed",
"tool": "dns",
"took_ms": 3
}Rejected: location-elsewhere
{
"state": "queued",
"tool": "png",
"job": {
"id": "job_01JAB2C3D4E5F6G7H8J9K0MNPQ",
"object": "tools.job",
"service": "img",
"type": "img.process",
"type_version": 1,
"state": "queued",
"progress": {
"percent": null,
"message": null
},
"attempts": 0,
"max_attempts": 3,
"cancel_requested": false,
"created_at": "2026-09-23T09:00:00.000Z",
"started_at": null,
"finished_at": null,
"expires_at": "2026-09-23T10:00:00.000Z",
"result": null,
"error": null,
"retryable": false,
"retry_of": null,
"retried_by": null,
"references": [],
"links": {
"self": "/api/v1/jobs/job_01JAB2C3D4E5F6G7H8J9K0MNPQ",
"events": "/api/v1/jobs/job_01JAB2C3D4E5F6G7H8J9K0MNPQ/events",
"cancel": "/api/v1/jobs/job_01JAB2C3D4E5F6G7H8J9K0MNPQ",
"retry": null,
"retried_by": null
}
},
"location": "/api/v1/jobs/job_01JAB2C3D4E5F6G7H8J9K0MNPR/files/0"
}Rejected: queued-without-location
{
"state": "queued",
"tool": "png",
"job": {
"id": "job_01JAB2C3D4E5F6G7H8J9K0MNPQ",
"object": "tools.job",
"service": "img",
"type": "img.process",
"type_version": 1,
"state": "queued",
"progress": {
"percent": null,
"message": null
},
"attempts": 0,
"max_attempts": 3,
"cancel_requested": false,
"created_at": "2026-09-23T09:00:00.000Z",
"started_at": null,
"finished_at": null,
"expires_at": "2026-09-23T10:00:00.000Z",
"result": null,
"error": null,
"retryable": false,
"retry_of": null,
"retried_by": null,
"references": [],
"links": {
"self": "/api/v1/jobs/job_01JAB2C3D4E5F6G7H8J9K0MNPQ",
"events": "/api/v1/jobs/job_01JAB2C3D4E5F6G7H8J9K0MNPQ/events",
"cancel": "/api/v1/jobs/job_01JAB2C3D4E5F6G7H8J9K0MNPQ",
"retry": null,
"retried_by": null
}
}
}Rejected: result-with-unknown-member
{
"state": "succeeded",
"tool": "dns",
"result": {
"html": "<b>x</b>"
},
"took_ms": 3
}Rejected: running-without-job
{
"state": "running",
"tool": "png",
"location": "/api/v1/jobs/job_01JAB2C3D4E5F6G7H8J9K0MNPQ"
}Rejected: succeeded-with-error
{
"state": "succeeded",
"tool": "dns",
"result": {},
"error": {
"type": "https://openvibe.network/problems/tools.job.timeout",
"title": "Gateway Timeout",
"status": 504,
"code": "tools.job.timeout",
"detail": "The job ran longer than 900 s",
"error": "The job ran longer than 900 s"
},
"took_ms": 3
}Validate
const contracts = require('openvibe-contracts');
contracts.validate('tools.run@1', value); // { valid, errors: [{ path, message }] }