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

# chat.embed@1 · OpenVibe.Services

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

# ChatEmbed `chat.embed@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: chat
- Visibility: public
- Status: active
- Compatibility: backward
- Schema: [`https://openvibe.network/contracts/chat/embed.v1.json`](/docs/contracts/chat.embed.json)

chat.embed@1: one address preview under a chat message, the same shape for every client (OpenVibe.Chat, Live's chat and the Dock). A message carries \`embeds\` in the order the addresses appeared in its text, at most three; it is empty while the background job is still reading, and the client draws each one as the same card. The fields are data, never markup: a client escapes them (title, description, site\_name, by) before drawing them. url is the address the writer sent, https only. image is an OpenVibe.Media address or null: another site's picture is never hot-linked. width and height are the picture's stated size, or 0. kind names what was found: an ordinary page (\`link\`), a video (\`video\`), a picture (\`image\`), a Live channel (\`live\`), a Pics picture (\`picture\`), a Design item (\`design\`), a Community post (\`post\`), a Network profile (\`profile\`) or a Games world (\`game\`). OpenVibe's own kinds are resolved through that service's public API, never by reading its page, and carry by (the person or channel the thing belongs to) and, for Live, live (whether the channel is broadcasting now); both are absent on an ordinary link. An agent-run embed carries the live run and event addresses, title and status.

## Fields

| Field | Type | Required | Description | Constraints |
| --- | --- | --- | --- | --- |
| `kind` | enum | yes | What the address turned out to be; a client may draw the same card for every value. | - `one of "link", "video", "image", "live", "picture", "design", "post", "profile", "game", "agent-run"` |
| `url` | string | yes | The https address the message carried, after the writer's trailing punctuation was dropped. | - `pattern ^https://`<br>- `format uri`<br>- `maxLength 2048` |
| `site_name` | string | yes | The site as it names itself (og:site\_name, the provider's name, or the host). | - `maxLength 80` |
| `title` | string | yes |  | - `minLength 1`<br>- `maxLength 240` |
| `description` | string | yes | A short plain-text description, or an empty string when the source states none. | - `maxLength 300` |
| `image` | string \| null | yes | The preview picture, only when it already lives on OpenVibe.Media; null when the source's picture would have to be hot-linked. | - `format uri`<br>- `maxLength 2048` |
| `width` | integer | yes | The picture's stated width in pixels, or 0. | - `minimum 0`<br>- `maximum 100000` |
| `height` | integer | yes | The picture's stated height in pixels, or 0. | - `minimum 0`<br>- `maximum 100000` |
| `by` | string |  | On OpenVibe's own kinds, the person or channel the thing belongs to (a Live channel's handle, a Video channel, a post's author, a profile's handle, a Games world's owner). Absent on an ordinary link. | - `maxLength 80` |
| `live` | boolean |  | On a Live channel kind, whether it is broadcasting now. Absent on the other kinds. |  |
| `run_url` | string |  |  | - `pattern ^https://`<br>- `format uri`<br>- `maxLength 2048` |
| `events_url` | string |  |  | - `pattern ^https://`<br>- `format uri`<br>- `maxLength 2048` |
| `status` | enum |  |  | - `one of "queued", "running", "waiting", "needs_you", "succeeded", "failed", "stopped", "cancelled"` |

## Examples

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

 Valid: agent-run

~~~~
{
  "kind": "agent-run",
  "url": "https://openvibe.codes/runs/run_1",
  "site_name": "OpenVibe.Codes",
  "title": "Review repositories",
  "description": "",
  "image": null,
  "width": 0,
  "height": 0,
  "run_url": "https://openvibe.codes/api/v1/runs/run_1",
  "events_url": "https://openvibe.codes/api/v1/runs/run_1/events",
  "status": "running"
}
~~~~

Valid: link

~~~~
{
  "kind": "link",
  "url": "https://example.com/a-story",
  "site_name": "Example",
  "title": "A story & its title",
  "description": "What happened, in one short paragraph.",
  "image": "https://openvibe.media/objects/pic.jpg",
  "width": 640,
  "height": 360
}
~~~~

Valid: live-channel

~~~~
{
  "kind": "live",
  "url": "https://openvibe.live/@streamer",
  "site_name": "OpenVibe.Live",
  "title": "The Streamer",
  "description": "Live every Friday",
  "image": "https://openvibe.media/avatars/s.jpg",
  "width": 0,
  "height": 0,
  "by": "streamer",
  "live": true
}
~~~~

Valid: picture-without-image

~~~~
{
  "kind": "picture",
  "url": "https://openvibe.pics/i/abcd2345",
  "site_name": "OpenVibe.Pics",
  "title": "Harbour at dusk",
  "description": "",
  "image": null,
  "width": 1200,
  "height": 800
}
~~~~

Rejected: agent-run

~~~~
{
  "kind": "agent-run",
  "url": "https://openvibe.codes/runs/run_1",
  "site_name": "OpenVibe.Codes",
  "title": "Review repositories",
  "description": "",
  "image": null,
  "width": 0,
  "height": 0,
  "run_url": "https://openvibe.codes/api/v1/runs/run_1",
  "events_url": "http://insecure.test/events",
  "status": "running"
}
~~~~

Rejected: bad-kind

~~~~
{
  "kind": "article",
  "url": "https://example.com/article",
  "site_name": "Example",
  "title": "An article",
  "description": "",
  "image": null,
  "width": 0,
  "height": 0
}
~~~~

Rejected: bad-live

~~~~
{
  "kind": "live",
  "url": "https://openvibe.live/@streamer",
  "site_name": "OpenVibe.Live",
  "title": "The Streamer",
  "description": "",
  "image": null,
  "width": 0,
  "height": 0,
  "live": "yes"
}
~~~~

Rejected: http-url

~~~~
{
  "kind": "link",
  "url": "http://example.com/plain",
  "site_name": "Example",
  "title": "Plain",
  "description": "",
  "image": null,
  "width": 0,
  "height": 0
}
~~~~

Rejected: no-title

~~~~
{
  "kind": "link",
  "url": "https://example.com/no-title",
  "site_name": "Example",
  "description": "",
  "image": null,
  "width": 0,
  "height": 0
}
~~~~

## Validate

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