> ## Documentation Index
> Fetch the complete documentation index at: https://docs.vivix.ai/llms.txt
> Use this file to discover all available pages before exploring further.

# Sessions

Session endpoints allocate, inspect, reconnect, and close one continuous Streaming World experience. Runtime guidance is sent as open-ended Events over the control channel.

<h2 id="streaming-world-resource-model">
  Resource model
</h2>

A Session is the only top-level REST resource. The other types below are session-scoped inputs or connection records, not separate REST collections.

| Type | Address | What an API developer uses it for |
| - | - | - |
| `Session` | `session_id` | Allocate a persistent generation runtime, discover its effective capabilities, reconnect clients, inspect operational status, and release resources. |
| `Reference` | `name` inside one Session | Give related text, images, and audio a reusable name. An Event can select that name instead of sending the same grounding material again. |
| `Event` | `world_event_id` assigned on the control channel | Describe, in natural language and supported multimodal content, how the unpublished future should develop. Events are not created through a REST endpoint. |
| Connection descriptor | `control` or `media` | Authorize a client to connect to Vivix control messages or continuous media. Each descriptor is opaque and short-lived. |

<Note>
  **References are reusable anchors.** A Reference has no fixed semantic category. For example, a Reference named A can combine a portrait, an audio sample, and a short description. Events can then use A as a stable conditioning anchor.
</Note>

<h2 id="streaming-world-session-workflow">
  REST workflow
</h2>

1. Create a Session with `POST /v1/streaming-world/sessions` and save its `session_id`.
2. Read the returned `capabilities` before enabling runtime controls or sending Event content.
3. Pass the opaque `control` and `media` descriptors to the Vivix client.
4. Use `GET /v1/streaming-world/sessions/{session_id}` to recover the current operational snapshot after reconnecting.
5. Issue fresh descriptors with `POST /v1/streaming-world/sessions/{session_id}/client-secrets` when client credentials expire.
6. Close the Session with `POST /v1/streaming-world/sessions/{session_id}/close`.

<Note>
  **Response envelope.** All REST responses use `{code, message, data}`. `code = 0` means success; a non-zero `code` means failure. The fields below refer to values inside `data`.
</Note>

<h2 id="create-streaming-world-session">
  Create Session
</h2>

Creates a Streaming World Session and returns its effective configuration, capability contract, and initial client connection descriptors.

**POST** `/v1/streaming-world/sessions`

### Body Parameters

<ParamField body={"model"} type={"string"} required>
  Model to run. Use `vivix-w1-stream`.
</ParamField>

<ParamField body={"idempotency_key"} type={"string"}>
  Client-generated key that prevents duplicate Session allocation. Reuse the same key and identical body after a timeout, HTTP 429, or 5xx response.
</ParamField>

<ParamField body={"initial_prompt"} type={"object"} required>
  Persistent creative context that establishes the experience before generation starts.

  <Expandable title="properties">
    <ParamField body={"content"} type={"array"} required>
      Ordered content blocks. The initial v1 profile accepts one or more `input_text` blocks.
    </ParamField>
  </Expandable>
</ParamField>

<ParamField body={"opening_frame"} type={"object"}>
  A visual starting point for continuous generation.

  <Expandable title="properties">
    <ParamField body={"url"} type={"string"} required>
      HTTPS URL that Vivix can fetch without custom request headers.
    </ParamField>

    <ParamField body={"mime_type"} type={"string"}>
      Image MIME type, such as `image/jpeg` or `image/png`.
    </ParamField>
  </Expandable>
</ParamField>

<ParamField body={"references"} type={"array"}>
  Named multimodal anchors available throughout the Session.

  <Expandable title="properties">
    <ParamField body={"name"} type={"string"} required>
      Caller-defined name, unique within the Session. Prefer a short stable value that can be selected naturally, such as A, lobby, or red\_car.
    </ParamField>

    <ParamField body={"content"} type={"array"} required>
      One or more supported `input_text`, `input_image`, or `input_audio` blocks interpreted together.
    </ParamField>
  </Expandable>
</ParamField>

<ParamField body={"output"} type={"object"}>
  Requested continuous output settings.

  <Expandable title="properties">
    <ParamField body={"aspect_ratio"} type={"string enum"}>
      `16:9`, `9:16`, or `1:1`. Defaults to `16:9`.
    </ParamField>

    <ParamField body={"resolution"} type={"string enum"}>
      `480p` or `720p`. Defaults to `720p` when supported by the selected model.
    </ParamField>

    <ParamField body={"captions"} type={"boolean"}>
      Requests caption events on the control channel. Defaults to `false`.
    </ParamField>
  </Expandable>
</ParamField>

<ParamField body={"live_input"} type={"object"}>
  Optional realtime input accepted from an authorized client.

  <Expandable title="properties">
    <ParamField body={"audio.enabled"} type={"boolean"}>
      Requests live audio input. Confirm support through `capabilities.live_audio.supported`.
    </ParamField>

    <ParamField body={"audio.transcription"} type={"boolean"}>
      Requests transcription before a completed utterance is interpreted as an Event.
    </ParamField>

    <ParamField body={"audio.language"} type={"string"}>
      A BCP 47 language tag or `auto` for automatic detection.
    </ParamField>
  </Expandable>
</ParamField>

<ParamField body={"continuation"} type={"object"}>
  Controls when generation begins and how long it may continue without new guidance.

  <Expandable title="properties">
    <ParamField body={"start_mode"} type={"string enum"}>
      `manual` keeps output held until a client resumes it or creates an Event. `automatic` begins when the Session is ready. Defaults to `manual`.
    </ParamField>

    <ParamField body={"max_idle_ms"} type={"integer"}>
      Maximum time generation may continue without a new Event before entering held mode. The model can apply a lower limit.
    </ParamField>
  </Expandable>
</ParamField>

<ParamField body={"max_session_duration_seconds"} type={"integer"}>
  Requested maximum Session lifetime. The effective expiry can be lower and is returned by the server.
</ParamField>

<ParamField body={"metadata"} type={"object"}>
  Application-defined string keys and values. Metadata is returned with the Session and is not interpreted as generation input.
</ParamField>

### Content Blocks

Content arrays are ordered. Check `capabilities.event_content_types` and `capabilities.reference_content_types` before using a block type at runtime or in a Reference.

<ResponseField name={"input_text"} type={"object"}>
  Natural-language context or guidance.

  <Expandable title="properties">
    <ResponseField name={"type"} type={"string"}>
      Must be `input_text`.
    </ResponseField>

    <ResponseField name={"text"} type={"string"}>
      Non-empty UTF-8 text.
    </ResponseField>
  </Expandable>
</ResponseField>

<ResponseField name={"input_image"} type={"object"}>
  An image included in a Reference.

  <Expandable title="properties">
    <ResponseField name={"type"} type={"string"}>
      Must be `input_image`.
    </ResponseField>

    <ResponseField name={"url"} type={"string"}>
      HTTPS URL that Vivix can fetch without custom request headers.
    </ResponseField>

    <ResponseField name={"mime_type"} type={"optional string"}>
      Image MIME type.
    </ResponseField>
  </Expandable>
</ResponseField>

<ResponseField name={"input_audio"} type={"object"}>
  An audio sample included in a Reference.

  <Expandable title="properties">
    <ResponseField name={"type"} type={"string"}>
      Must be `input_audio`.
    </ResponseField>

    <ResponseField name={"url"} type={"string"}>
      HTTPS URL that Vivix can fetch without custom request headers.
    </ResponseField>

    <ResponseField name={"mime_type"} type={"optional string"}>
      Audio MIME type.
    </ResponseField>

    <ResponseField name={"transcript"} type={"optional string"}>
      Text associated with the sample when it is known to the application.
    </ResponseField>
  </Expandable>
</ResponseField>

### Returns

<ResponseField name={"session_id"} type={"string"}>
  Stable identifier for the Session.
</ResponseField>

<ResponseField name={"status"} type={"string enum"}>
  One of `provisioning`, `active`, or `failed` at create time.
</ResponseField>

<ResponseField name={"control"} type={"object"}>
  Opaque descriptor for the Session control connection.

  <Expandable title="properties">
    <ResponseField name={"url"} type={"string"}>
      Vivix control connection URL.
    </ResponseField>

    <ResponseField name={"client_secret"} type={"string"}>
      Short-lived control credential.
    </ResponseField>

    <ResponseField name={"expires_at"} type={"timestamp"}>
      Expiration time for this descriptor.
    </ResponseField>
  </Expandable>
</ResponseField>

<ResponseField name={"media"} type={"object"}>
  Opaque descriptor used by the Vivix client to connect continuous media.

  <Expandable title="properties">
    <ResponseField name={"url"} type={"string"}>
      Vivix media connection URL.
    </ResponseField>

    <ResponseField name={"client_secret"} type={"string"}>
      Short-lived media credential.
    </ResponseField>

    <ResponseField name={"expires_at"} type={"timestamp"}>
      Expiration time for this descriptor.
    </ResponseField>
  </Expandable>
</ResponseField>

<ResponseField name={"output"} type={"object"}>
  Effective output settings, including `aspect_ratio`, `resolution`, `fps`, and `captions`.
</ResponseField>

<ResponseField name={"capabilities"} type={"object"}>
  Effective feature contract for this allocated Session.
</ResponseField>

<ResponseField name={"runtime"} type={"object"}>
  Latest operational snapshot, including media status, media time, and applied or pending world Event ids.
</ResponseField>

<ResponseField name={"created_at"} type={"timestamp"}>
  Session creation time.
</ResponseField>

<ResponseField name={"expires_at"} type={"timestamp"}>
  Time after which the Session can no longer be used.
</ResponseField>

```bash Request theme={null}
curl -X POST https://api.vivix.ai/v1/streaming-world/sessions \
  -H "Authorization: Bearer $VIVIX_API_KEY" \
  -H "Content-Type: application/json" \
  -d '{
  "model": "vivix-w1-stream",
  "idempotency_key": "hotel-demo-001",
  "initial_prompt": {
    "content": [
      {
        "type": "input_text",
        "text": "A rain-soaked old hotel at night. A is a young detective and B is the hotel owner. Preserve their appearances, voices, positions, relationships, and prior experience as events unfold."
      }
    ]
  },
  "opening_frame": {
    "url": "https://cdn.example.com/hotel/lobby.jpg",
    "mime_type": "image/jpeg"
  },
  "references": [
    {
      "name": "A",
      "content": [
        { "type": "input_image", "url": "https://cdn.example.com/a.jpg" },
        { "type": "input_audio", "url": "https://cdn.example.com/a.wav" },
        { "type": "input_text", "text": "Calm, observant, and concise." }
      ]
    },
    {
      "name": "B",
      "content": [
        { "type": "input_image", "url": "https://cdn.example.com/b.jpg" },
        { "type": "input_audio", "url": "https://cdn.example.com/b.wav" },
        { "type": "input_text", "text": "Friendly on the surface, but tense under pressure." }
      ]
    }
  ],
  "output": {
    "aspect_ratio": "16:9",
    "resolution": "720p",
    "captions": true
  },
  "live_input": {
    "audio": {
      "enabled": true,
      "transcription": true,
      "language": "auto"
    }
  },
  "continuation": {
    "start_mode": "manual",
    "max_idle_ms": 30000
  },
  "max_session_duration_seconds": 3600,
  "metadata": {
    "experience_id": "hotel-demo"
  }
}'
```

```json Response theme={null}
{
  "code": 0,
  "message": "success",
  "data": {
    "session_id": "sws_01K4JH8X9M",
    "status": "active",
    "model": "vivix-w1-stream",
    "control": {
      "url": "wss://api.vivix.ai/v1/streaming-world/control?session_id=sws_01K4JH8X9M",
      "client_secret": "ctl_...",
      "expires_at": "2026-07-24T10:05:00Z"
    },
    "media": {
      "url": "https://media.vivix.ai/connect/sws_01K4JH8X9M",
      "client_secret": "med_...",
      "expires_at": "2026-07-24T10:05:00Z"
    },
    "output": {
      "aspect_ratio": "16:9",
      "resolution": "720p",
      "fps": 24,
      "captions": true
    },
    "live_input": {
      "audio": {
        "enabled": true,
        "transcription": true,
        "language": "auto"
      }
    },
    "continuation": {
      "start_mode": "manual",
      "max_idle_ms": 30000
    },
    "references": [
      { "name": "A" },
      { "name": "B" }
    ],
    "runtime": {
      "media_status": "held",
      "media_time_ms": 0,
      "applied_world_event_id": null,
      "pending_world_event_id": null
    },
    "capabilities": {
      "event_content_types": ["input_text", "input_reference"],
      "reference_content_types": ["input_text", "input_image", "input_audio"],
      "event_handling": ["steer"],
      "live_audio": {
        "supported": true,
        "interpretation": "transcription"
      },
      "runtime_references": false,
      "event_cancel": false,
      "continuation": {
        "hold": true,
        "resume": true,
        "automatic": true
      },
      "reconnect": {
        "snapshot": true,
        "event_replay": false
      },
      "limits": {
        "max_event_bytes": 65536,
        "max_references": 8,
        "max_reference_images": 8
      }
    },
    "metadata": {
      "experience_id": "hotel-demo"
    },
    "created_at": "2026-07-24T10:00:00Z",
    "expires_at": "2026-07-24T11:00:00Z"
  }
}
```

<h2 id="streaming-world-capability-negotiation">
  Capability negotiation
</h2>

Capabilities are resolved after Vivix validates and allocates the Session. Treat the returned object as the authoritative feature contract rather than assuming that every model or deployment accepts the same inputs.

| Field | Meaning | Client requirement |
| - | - | - |
| `event_content_types` | Content blocks accepted by runtime Events. | Do not submit a block type that is absent. |
| `reference_content_types` | Content blocks accepted inside create-time References. | Validate every Reference before creating the Session. |
| `event_handling` | Handling modes accepted by Event creation. | Use `steer` unless the returned list explicitly enables another mode. |
| `live_audio` | Whether live audio is supported and how it is interpreted. | Enable microphone controls only when supported. |
| `runtime_references` | Whether a Reference can be added after Session creation. | When `false`, include every required Reference in the create request. |
| `event_cancel` | Whether an accepted but unapplied Event can be cancelled by id. | Hide cancellation controls when false. |
| `continuation` | Available hold, resume, and automatic continuation controls. | Only expose controls whose values are true. |
| `reconnect` | Snapshot and disconnected-event recovery guarantees. | In v1, `snapshot` is true and `event_replay` is false. Recover from the latest snapshot rather than waiting for missed messages. |
| `limits` | Effective Event and Reference limits for the Session. | Validate locally and still handle server rejection. |

<Warning>
  **Unsupported content is rejected.** Vivix validates an Event or Reference as one input. It does not silently ignore unsupported blocks and apply the remainder.
</Warning>

<h2 id="get-streaming-world-session">
  Get Session
</h2>

Retrieves lifecycle status, effective configuration, capabilities, and the latest operational snapshot. Use it after reconnecting or while waiting for closure.

**GET** `/v1/streaming-world/sessions/{session_id}`

### Path Parameters

<ParamField path={"session_id"} type={"string"} required>
  Identifier of the Session to retrieve.
</ParamField>

### Returns

Returns the effective Session object. For security, Get Session never returns either client\_secret. Use Create Client Secret when a client needs new credentials.

<ResponseField name={"status"} type={"string enum"}>
  One of `provisioning`, `active`, `closing`, `closed`, or `failed`.
</ResponseField>

<ResponseField name={"runtime.media_status"} type={"string enum"}>
  One of `connecting`, `running`, `held`, `stalled`, `disconnected`, or `failed`.
</ResponseField>

<ResponseField name={"runtime.media_time_ms"} type={"integer"}>
  Latest server-side media time in milliseconds.
</ResponseField>

<ResponseField name={"runtime.applied_world_event_id"} type={"optional string"}>
  Most recent world Event known to be influencing published media.
</ResponseField>

<ResponseField name={"runtime.pending_world_event_id"} type={"optional string"}>
  Newest accepted world Event that has not yet taken effect.
</ResponseField>

<ResponseField name={"last_sequence"} type={"integer"}>
  Latest control-event sequence included in this snapshot.
</ResponseField>

```bash Request theme={null}
curl https://api.vivix.ai/v1/streaming-world/sessions/sws_01K4JH8X9M \
  -H "Authorization: Bearer $VIVIX_API_KEY"
```

```json Response theme={null}
{
  "code": 0,
  "message": "success",
  "data": {
    "session_id": "sws_01K4JH8X9M",
    "status": "active",
    "model": "vivix-w1-stream",
    "control": {
      "url": "wss://api.vivix.ai/v1/streaming-world/control?session_id=sws_01K4JH8X9M",
      "expires_at": "2026-07-24T10:15:00Z"
    },
    "media": {
      "url": "https://media.vivix.ai/connect/sws_01K4JH8X9M",
      "expires_at": "2026-07-24T10:15:00Z"
    },
    "runtime": {
      "media_status": "running",
      "media_time_ms": 84320,
      "applied_world_event_id": "world_event_018",
      "pending_world_event_id": "world_event_019"
    },
    "last_sequence": 142,
    "usage": {
      "generated_video_ms": 84200,
      "generated_audio_ms": 60100
    },
    "capabilities": {
      "event_content_types": ["input_text", "input_reference"],
      "reference_content_types": ["input_text", "input_image", "input_audio"],
      "event_handling": ["steer"],
      "event_cancel": false,
      "reconnect": {
        "snapshot": true,
        "event_replay": false
      }
    },
    "created_at": "2026-07-24T10:00:00Z",
    "expires_at": "2026-07-24T11:00:00Z"
  }
}
```

<h2 id="create-streaming-world-client-secret">
  Create Client Secret
</h2>

Issues fresh, short-lived control and media descriptors for an active Session. Call this endpoint from a trusted server and return only the descriptors to the authorized client.

**POST** `/v1/streaming-world/sessions/{session_id}/client-secrets`

### Path Parameters

<ParamField path={"session_id"} type={"string"} required>
  Identifier of the active Session.
</ParamField>

### Body Parameters

<ParamField body={"idempotency_key"} type={"string"}>
  Client-generated key that makes credential issuance safe to retry.
</ParamField>

### Returns

<ResponseField name={"session_id"} type={"string"}>
  Identifier of the Session.
</ResponseField>

<ResponseField name={"control"} type={"object"}>
  Fresh opaque descriptor containing `url`, `client_secret`, and `expires_at`.
</ResponseField>

<ResponseField name={"media"} type={"object"}>
  Fresh opaque descriptor containing `url`, `client_secret`, and `expires_at`.
</ResponseField>

<Warning>
  **Keep API keys on your server.** Client secrets are intentionally short-lived and scoped to one Session. Never expose the workspace API key in a browser or mobile application.
</Warning>

```bash Request theme={null}
curl -X POST https://api.vivix.ai/v1/streaming-world/sessions/sws_01K4JH8X9M/client-secrets \
  -H "Authorization: Bearer $VIVIX_API_KEY" \
  -H "Content-Type: application/json" \
  -d '{
  "idempotency_key": "refresh-hotel-demo-002"
}'
```

```json Response theme={null}
{
  "code": 0,
  "message": "success",
  "data": {
    "session_id": "sws_01K4JH8X9M",
    "control": {
      "url": "wss://api.vivix.ai/v1/streaming-world/control?session_id=sws_01K4JH8X9M",
      "client_secret": "ctl_...",
      "expires_at": "2026-07-24T10:15:00Z"
    },
    "media": {
      "url": "https://media.vivix.ai/connect/sws_01K4JH8X9M",
      "client_secret": "med_...",
      "expires_at": "2026-07-24T10:15:00Z"
    }
  }
}
```

<h2 id="close-streaming-world-session">
  Close Session
</h2>

Stops accepting new Events and begins asynchronous cleanup. Media already published to a client is not withdrawn. Repeating the request with the same idempotency key is safe.

**POST** `/v1/streaming-world/sessions/{session_id}/close`

### Path Parameters

<ParamField path={"session_id"} type={"string"} required>
  Identifier of the Session to close.
</ParamField>

### Body Parameters

<ParamField body={"idempotency_key"} type={"string"}>
  Client-generated key that makes the close request safe to retry.
</ParamField>

### Returns

<ResponseField name={"session_id"} type={"string"}>
  Identifier of the closing Session.
</ResponseField>

<ResponseField name={"status"} type={"string enum"}>
  `closing` while cleanup is in progress or `closed` if cleanup has already completed.
</ResponseField>

```bash Request theme={null}
curl -X POST https://api.vivix.ai/v1/streaming-world/sessions/sws_01K4JH8X9M/close \
  -H "Authorization: Bearer $VIVIX_API_KEY" \
  -H "Content-Type: application/json" \
  -d '{
  "idempotency_key": "close-hotel-demo-001"
}'
```

```json Response theme={null}
{
  "code": 0,
  "message": "success",
  "data": {
    "session_id": "sws_01K4JH8X9M",
    "status": "closing"
  }
}
```

<h2 id="streaming-world-session-status">
  Session status
</h2>

| Status | Meaning | Client guidance |
| - | - | - |
| `provisioning` | Vivix is preparing the runtime and connection descriptors. | Wait for active status before connecting. |
| `active` | The Session accepts connections and Events. | Connect or continue using the Session. |
| `closing` | No new Events are accepted and cleanup is in progress. | Poll Get Session only when closure confirmation is required. |
| `closed` | Cleanup is complete. | Discard credentials and create another Session to continue. |
| `failed` | The Session cannot continue. | Inspect the error and create another Session when retryable. |

<h2 id="streaming-world-session-errors">
  Session error cases
</h2>

| Condition | API error code | Retry guidance |
| - | - | - |
| A required field is missing, a Reference name is duplicated, or a URL is invalid. | `30004 invalid argument` | Correct the request before retrying. |
| The selected model does not support the requested output or live input configuration. | `30004 invalid argument` | Remove the unsupported option or select a compatible model. |
| An idempotency key is reused with a different request body. | `30004 idempotency conflict` | Use the original body or generate a new key. |
| The Session does not exist, is closed, or has expired. | `20005 not found` | Create another Session. |
| The API key is missing or invalid. | `10001 missing api key` or `10003 invalid api key` | Correct server authentication before retrying. |
| Workspace billing is inactive or the balance is insufficient. | `10004 workspace billing is not active` or `10005 insufficient workspace balance` | Resolve the workspace billing issue before retrying. |
| The request exceeded the API key rate limit. | `10008 API rate limit exceeded` | Honor `Retry-After` and reuse the same idempotency key for the same request. |

Error responses use the same `{code, message, data}` envelope. A non-zero `code` indicates failure, and `message` contains an English description.
