---
title: "run.session@1 · OpenVibe.Services"
canonical: "https://openvibe.services/docs/contracts/run.session"
updated: null
---

# run.session@1 · OpenVibe.Services

HTML: [run.session@1 · OpenVibe.Services](https://openvibe.services/docs/contracts/run.session)

# RunSession `run.session@1`

Generated at 2026-11-13 06:25:48 UTC from [`openvibe-contracts v0.419.0`](https://github.com/OpenVibers/OpenVibe.Contracts/tree/v0.419.0) and [`openvibe-sdk v0.161.0`](https://github.com/OpenVibers/OpenVibe.SDK/tree/v0.161.0).

- Version: 1.0.0
- Owner: run
- Visibility: public
- Status: active
- Compatibility: backward
- Schema: [`https://openvibe.network/contracts/run/session.v1.json`](/docs/contracts/run.session.json)

run.session@1 (the Desks plan's D6): one session on OpenVibe.Run, a browser desk held for one person, as GET /api/v1/sessions/{id} answers it (capability run.session.read) and run.session-list-result@1, POST /api/v1/sessions (run.session.create) and POST /api/v1/sessions/{id}/end (run.session.control) carry it. A session is a desk (bot.command@1 kind desk, kind browser) that Run places on a machine and OpenVibe.Bot leases to it (bot.desk-lease@1): on one of the person's own machines where they let agents use it (trust user-owned, never another person's), or on a desk host that serves other people (trust first-party or community: the host's OpenVibe Link runs every desk in its own sandbox, desk\_isolation sandbox, and offers nothing else of the machine). STATES: placing (stored, looking for a machine) -> starting (the desk is leased and starting) -> running (the desk answered) -> ended. An ended session never changes; end.reason says why: ended (POST /api/v1/sessions/{id}/end), ttl (ttl\_s ran out), idle (no command for idle\_s), host\_lost (its machine went away or stopped the desk), unplaceable (no machine had room before ttl\_s, or none at all) or failed (the desk would not start). USAGE: desk\_seconds counts from started\_at to ended\_at (or now while running), metered to OpenVibe.Billing as one platform.usage-sample@1 per minute (service run, operation browser.desk, unit s, idempotency\_key run:<session id>:<minute>). Run mints the id (ses\_<ULID>).

## Fields

| Field | Type | Required | Description | Constraints |
| --- | --- | --- | --- | --- |
| `id` | `https://openvibe.network/contracts/run/session.v1.json#/$defs/session_id` | yes |  |  |
| `owner` | [identity.subject-ref](/docs/contracts/identity.subject-ref) | yes | The person the session is for: only they (or a first-party service acting for them) read, act on or end it. |  |
| `via` | string \| null | yes | The first-party service that asked for the person (service:actor), or null when they asked themselves. | - `pattern ^service:[a-z][a-z0-9-]{0,40}$` |
| `kind` | const | yes | A platform.runtime-class@1 name; browser (a headless browser driven over its pipe) is the only kind of session in v1. | - `= "browser"` |
| `state` | enum | yes |  | - `one of "placing", "starting", "running", "ended"` |
| `size` | `https://openvibe.network/contracts/run/session.v1.json#/$defs/size` | yes |  |  |
| `ttl_s` | integer | yes | The most the session lives, from created\_at. | - `minimum 60`<br>- `maximum 14400` |
| `idle_s` | integer | yes | A session no command used this long ends (end.reason idle). | - `minimum 60`<br>- `maximum 3600` |
| `placement` | one of | yes |  |  |
| `timings` | `https://openvibe.network/contracts/run/session.v1.json#/$defs/timings` | yes |  |  |
| `end` | one of | yes |  |  |
| `usage` | `https://openvibe.network/contracts/run/session.v1.json#/$defs/usage` | yes |  |  |
| `idempotency_key` | one of | yes |  |  |
| `task_id` | one of |  | The OpenVibe.Actor task that asked for this session (plan 2026-11-07: one id across Surf, Computer and Actor). Null when a person opened it themselves. The session is the Computer the task's record carries. |  |
| `curtain` | boolean |  | Curtain now (the privacy screen): while it is up the session's still answers the curtain picture, never the screen. The person raises and lifts it with POST /api/v1/sessions/{id}/curtain. | - `default false` |

## Examples

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

 Valid: ended-idle

~~~~
{
  "id": "ses_01JD2C3D4E5F6G7H8J9K0MNPQR",
  "owner": {
    "type": "user",
    "id": "usr_01JAB2C3D4E5F6G7H8J9K0MNPQ"
  },
  "via": "service:actor",
  "kind": "browser",
  "state": "ended",
  "size": {
    "width": 1280,
    "height": 800
  },
  "ttl_s": 3600,
  "idle_s": 900,
  "placement": {
    "machine": "dev_01J8Z4M2Q0R7T9YV3K6N8P1W2X",
    "desk": "desk-s0mnpqr",
    "trust": "community",
    "offer_id": "desk:dev_01J8Z4M2Q0R7T9YV3K6N8P1W2X",
    "region": "eu",
    "reasons": [
      "a shared desk host with room"
    ]
  },
  "timings": {
    "created_at": "2026-10-28T10:00:00Z",
    "started_at": "2026-10-28T10:00:04Z",
    "last_used_at": "2026-10-28T10:05:00Z",
    "ended_at": "2026-10-28T10:20:00Z"
  },
  "end": {
    "reason": "idle",
    "detail": "no command for 900 s"
  },
  "usage": {
    "desk_seconds": 1196
  },
  "idempotency_key": null
}
~~~~

Valid: ended-unplaceable

~~~~
{
  "id": "ses_01JD2C3D4E5F6G7H8J9K0MNPQR",
  "owner": {
    "type": "user",
    "id": "usr_01JAB2C3D4E5F6G7H8J9K0MNPQ"
  },
  "via": null,
  "kind": "browser",
  "state": "ended",
  "size": {
    "width": 1280,
    "height": 800
  },
  "ttl_s": 3600,
  "idle_s": 900,
  "placement": null,
  "timings": {
    "created_at": "2026-10-28T10:00:00Z",
    "started_at": null,
    "last_used_at": null,
    "ended_at": "2026-10-28T10:01:00Z"
  },
  "end": {
    "reason": "unplaceable",
    "detail": "no desk host had room"
  },
  "usage": {
    "desk_seconds": 0
  },
  "idempotency_key": "actor:tsk_01JD2C3D4E5F6G7H8J9K0MNPQR"
}
~~~~

Valid: placing

~~~~
{
  "id": "ses_01JD2C3D4E5F6G7H8J9K0MNPQR",
  "owner": {
    "type": "user",
    "id": "usr_01JAB2C3D4E5F6G7H8J9K0MNPQ"
  },
  "via": null,
  "kind": "browser",
  "state": "placing",
  "size": {
    "width": 1280,
    "height": 800
  },
  "ttl_s": 3600,
  "idle_s": 900,
  "placement": null,
  "timings": {
    "created_at": "2026-10-28T10:00:00Z",
    "started_at": null,
    "last_used_at": null,
    "ended_at": null
  },
  "end": null,
  "usage": {
    "desk_seconds": 0
  },
  "idempotency_key": "actor:tsk_01JD2C3D4E5F6G7H8J9K0MNPQR"
}
~~~~

Valid: running-own-machine

~~~~
{
  "id": "ses_01JD2C3D4E5F6G7H8J9K0MNPQR",
  "owner": {
    "type": "user",
    "id": "usr_01JAB2C3D4E5F6G7H8J9K0MNPQ"
  },
  "via": "service:actor",
  "kind": "browser",
  "state": "running",
  "size": {
    "width": 1280,
    "height": 800
  },
  "ttl_s": 3600,
  "idle_s": 900,
  "placement": {
    "machine": "dev_01J8Z4M2Q0R7T9YV3K6N8P1W2X",
    "desk": "desk-s0mnpqr",
    "trust": "user-owned",
    "offer_id": null,
    "region": null,
    "reasons": [
      "your own machine, as asked"
    ]
  },
  "timings": {
    "created_at": "2026-10-28T10:00:00Z",
    "started_at": "2026-10-28T10:00:04Z",
    "last_used_at": "2026-10-28T10:05:00Z",
    "ended_at": null
  },
  "end": null,
  "usage": {
    "desk_seconds": 296
  },
  "idempotency_key": null
}
~~~~

Valid: running-shared

~~~~
{
  "id": "ses_01JD2C3D4E5F6G7H8J9K0MNPQR",
  "owner": {
    "type": "user",
    "id": "usr_01JAB2C3D4E5F6G7H8J9K0MNPQ"
  },
  "via": "service:actor",
  "kind": "browser",
  "state": "running",
  "size": {
    "width": 1280,
    "height": 800
  },
  "ttl_s": 3600,
  "idle_s": 900,
  "placement": {
    "machine": "dev_01J8Z4M2Q0R7T9YV3K6N8P1W2X",
    "desk": "desk-s0mnpqr",
    "trust": "community",
    "offer_id": "desk:dev_01J8Z4M2Q0R7T9YV3K6N8P1W2X",
    "region": "eu",
    "reasons": [
      "a shared desk host with room"
    ]
  },
  "timings": {
    "created_at": "2026-10-28T10:00:00Z",
    "started_at": "2026-10-28T10:00:04Z",
    "last_used_at": "2026-10-28T10:05:00Z",
    "ended_at": null
  },
  "end": null,
  "usage": {
    "desk_seconds": 296
  },
  "idempotency_key": null
}
~~~~

Valid: running-task-session

~~~~
{
  "id": "ses_01JD2C3D4E5F6G7H8J9K0MNPQS",
  "owner": {
    "type": "user",
    "id": "usr_01JAB2C3D4E5F6G7H8J9K0MNPQ"
  },
  "via": "service:actor",
  "kind": "browser",
  "state": "running",
  "size": {
    "width": 1280,
    "height": 800
  },
  "ttl_s": 3600,
  "idle_s": 900,
  "placement": {
    "machine": "dev_01J8Z4M2Q0R7T9YV3K6N8P1W2X",
    "desk": "desk-s0mnpqs",
    "trust": "first-party",
    "offer_id": null,
    "region": null,
    "reasons": [
      "an OpenVibe desk host with room"
    ]
  },
  "timings": {
    "created_at": "2026-11-07T09:00:00Z",
    "started_at": "2026-11-07T09:00:04Z",
    "last_used_at": "2026-11-07T09:05:00Z",
    "ended_at": null
  },
  "end": null,
  "usage": {
    "desk_seconds": 296
  },
  "idempotency_key": "actor:tsk_01JAB2C3D4E5F6G7H8J9K0MNPT",
  "task_id": "tsk_01JAB2C3D4E5F6G7H8J9K0MNPT",
  "curtain": false
}
~~~~

Rejected: desktop-kind

~~~~
{
  "id": "ses_01JD2C3D4E5F6G7H8J9K0MNPQR",
  "owner": {
    "type": "user",
    "id": "usr_01JAB2C3D4E5F6G7H8J9K0MNPQ"
  },
  "via": "service:actor",
  "kind": "desktop",
  "state": "running",
  "size": {
    "width": 1280,
    "height": 800
  },
  "ttl_s": 3600,
  "idle_s": 900,
  "placement": {
    "machine": "dev_01J8Z4M2Q0R7T9YV3K6N8P1W2X",
    "desk": "desk-s0mnpqr",
    "trust": "community",
    "offer_id": "desk:dev_01J8Z4M2Q0R7T9YV3K6N8P1W2X",
    "region": "eu",
    "reasons": [
      "a shared desk host with room"
    ]
  },
  "timings": {
    "created_at": "2026-10-28T10:00:00Z",
    "started_at": "2026-10-28T10:00:04Z",
    "last_used_at": "2026-10-28T10:05:00Z",
    "ended_at": null
  },
  "end": null,
  "usage": {
    "desk_seconds": 296
  },
  "idempotency_key": null
}
~~~~

Rejected: ended-without-reason

~~~~
{
  "id": "ses_01JD2C3D4E5F6G7H8J9K0MNPQR",
  "owner": {
    "type": "user",
    "id": "usr_01JAB2C3D4E5F6G7H8J9K0MNPQ"
  },
  "via": "service:actor",
  "kind": "browser",
  "state": "ended",
  "size": {
    "width": 1280,
    "height": 800
  },
  "ttl_s": 3600,
  "idle_s": 900,
  "placement": {
    "machine": "dev_01J8Z4M2Q0R7T9YV3K6N8P1W2X",
    "desk": "desk-s0mnpqr",
    "trust": "community",
    "offer_id": "desk:dev_01J8Z4M2Q0R7T9YV3K6N8P1W2X",
    "region": "eu",
    "reasons": [
      "a shared desk host with room"
    ]
  },
  "timings": {
    "created_at": "2026-10-28T10:00:00Z",
    "started_at": "2026-10-28T10:00:04Z",
    "last_used_at": "2026-10-28T10:05:00Z",
    "ended_at": "2026-10-28T10:20:00Z"
  },
  "end": null,
  "usage": {
    "desk_seconds": 1196
  },
  "idempotency_key": null
}
~~~~

Rejected: main-screen

~~~~
{
  "id": "ses_01JD2C3D4E5F6G7H8J9K0MNPQR",
  "owner": {
    "type": "user",
    "id": "usr_01JAB2C3D4E5F6G7H8J9K0MNPQ"
  },
  "via": "service:actor",
  "kind": "browser",
  "state": "running",
  "size": {
    "width": 1280,
    "height": 800
  },
  "ttl_s": 3600,
  "idle_s": 900,
  "placement": {
    "machine": "dev_01J8Z4M2Q0R7T9YV3K6N8P1W2X",
    "desk": "main",
    "trust": "community",
    "offer_id": "desk:dev_01J8Z4M2Q0R7T9YV3K6N8P1W2X",
    "region": "eu",
    "reasons": [
      "a shared desk host with room"
    ]
  },
  "timings": {
    "created_at": "2026-10-28T10:00:00Z",
    "started_at": "2026-10-28T10:00:04Z",
    "last_used_at": "2026-10-28T10:05:00Z",
    "ended_at": null
  },
  "end": null,
  "usage": {
    "desk_seconds": 296
  },
  "idempotency_key": null
}
~~~~

Rejected: running-unplaced

~~~~
{
  "id": "ses_01JD2C3D4E5F6G7H8J9K0MNPQR",
  "owner": {
    "type": "user",
    "id": "usr_01JAB2C3D4E5F6G7H8J9K0MNPQ"
  },
  "via": "service:actor",
  "kind": "browser",
  "state": "running",
  "size": {
    "width": 1280,
    "height": 800
  },
  "ttl_s": 3600,
  "idle_s": 900,
  "placement": null,
  "timings": {
    "created_at": "2026-10-28T10:00:00Z",
    "started_at": "2026-10-28T10:00:04Z",
    "last_used_at": "2026-10-28T10:05:00Z",
    "ended_at": null
  },
  "end": null,
  "usage": {
    "desk_seconds": 296
  },
  "idempotency_key": null
}
~~~~

Rejected: running-with-end

~~~~
{
  "id": "ses_01JD2C3D4E5F6G7H8J9K0MNPQR",
  "owner": {
    "type": "user",
    "id": "usr_01JAB2C3D4E5F6G7H8J9K0MNPQ"
  },
  "via": "service:actor",
  "kind": "browser",
  "state": "running",
  "size": {
    "width": 1280,
    "height": 800
  },
  "ttl_s": 3600,
  "idle_s": 900,
  "placement": {
    "machine": "dev_01J8Z4M2Q0R7T9YV3K6N8P1W2X",
    "desk": "desk-s0mnpqr",
    "trust": "community",
    "offer_id": "desk:dev_01J8Z4M2Q0R7T9YV3K6N8P1W2X",
    "region": "eu",
    "reasons": [
      "a shared desk host with room"
    ]
  },
  "timings": {
    "created_at": "2026-10-28T10:00:00Z",
    "started_at": "2026-10-28T10:00:04Z",
    "last_used_at": "2026-10-28T10:05:00Z",
    "ended_at": null
  },
  "end": {
    "reason": "idle",
    "detail": null
  },
  "usage": {
    "desk_seconds": 296
  },
  "idempotency_key": null
}
~~~~

## Validate

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