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

# Runtime API

> The low-level API a hug's page runs on: connect, the Hug object, its methods and events, errors.

Hugs › Reference

Everything a page can know or do is in `@getcliqio/hug-frontend`. [`mount_hug`](https://docs.getcliq.io/hugs/mount-hug) and
[`useHug`](https://docs.getcliq.io/hugs/react) are built on this API; use it directly only when they don't fit, or through the `hug` they
hand you.

```ts theme={"theme":{"light":"github-light","dark":"one-dark-pro"}}
import { connect } from '@getcliqio/hug-frontend';

const hug = await connect<Params, Values>();
hug.theme.apply(document.documentElement);
hug.auto_resize();
```

## `connect(options?)`

Resolves once with everything the page needs, after the host's `init`. Rejects with `HugError`: `not_in_runtime`
(not in a Hug host — use `cliq hug dev`), `protocol_unsupported`, `timeout`.

| Option | |
| - | - |
| `timeout_ms` | How long to wait for the host |
| `transport` | For tests: `mock_host().transport` |

## The Hug

| Property | |
| - | - |
| `hug` | `{ id, name, title, summary?, status, expires_at, requester, run: { id, name } }` — `requester` is the run's phase that asked (e.g. `review`; `cliq hug dev` in development) |
| `params` | What it was asked |
| `mode` | `answer` or `view` — changes with the `mode` and `status` events |
| `viewer` | `{ name, via }` — who is looking, and the channels that reached them |
| `mine` | This viewer's latest answer, or null |
| `viewing` | In view mode, the answer to draw: `{ values, summary?, responder?, responded_at? }` |
| `draft` | Unsent values the host kept for this viewer, or null |
| `files` | Upload slots: `{ name, accept?, max_bytes?, required, multiple? }` |
| `attachments` | Files it may read: `{ artifact_id, name, size, content_type, sha256 }` |
| `progress` | The requester's status line ("1 answer couldn't be used; …"), or null |
| `theme` | `{ scheme, tokens, apply(el) }` — `apply` sets the `--cliq-*` variables |
| `locale` | The viewer's locale |
| `protocol` | The bridge protocol version in use |

| Method | |
| - | - |
| `set_values(values, { valid, problems?, submit?, summary? })` | The current answer — the host enables Submit while `valid`, shows `problems`, labels Submit (`{ label, tone? }`) and sends `values` and `summary` when pressed. Last call wins |
| `upload(key)` | The host's file picker for an upload slot → a file reference |
| `read_file(ref)` | A file's bytes, as a `Blob` |
| `file_url(ref)` | `read_file` + an object URL |
| `download(ref)` | The host saves the file for the person |
| `open_link(url)` | Opens an `http(s)` link (one not in the params is shown first) |
| `resize(height)` | Sets the frame's height |
| `auto_resize(el?)` | Keeps the frame fitted to `el` (default the body); returns a stop function |
| `on(event, fn)` | Listens; returns an unsubscribe function |
| `dispose()` | Stops listening to the host |

| Event | Payload | When |
| - | - | - |
| `update` | `{ progress?, expires_at? }` | The open Hug changes |
| `status` | `{ status, mode: 'view' }` | It closes, expires or is cancelled |
| `mode` | `{ mode, viewing, start }` | The page switches: after Submit (view), **Change answer** (answer, `start` = their answer) |
| `submitted` | the stored answer | Submit succeeded |
| `submit_failed` | problems | CliqHub refused the answer |

## Errors

`HugError` with a `code`:

| Code | |
| - | - |
| `not_in_runtime` | Not in a Hug host |
| `protocol_unsupported` | No bridge protocol both sides speak |
| `timeout` | The host didn't answer |
| `upload_cancelled`, `upload_failed` | The person closed the picker; the upload failed |
| `file_too_large`, `file_type` | The file breaks the slot's `max_bytes` or `accept` |
| `not_declared` | Not an upload slot of this Hug |
| `read_denied`, `read_failed` | The viewer may not read the file; the read failed |
| `rate_limited` | Too many messages, uploads or reads at once |

## Other exports

| | |
| - | - |
| `problems_from_zod(error)`, `problems_text(problems)` | A `ZodError`'s issues as `{ path, message }`; problems as lines (a definition's `check` already returns problems) |
| `parse_path`, `set_path` | The path helpers `set` uses (`verdicts[2].note`) |
| `default_view`, `view_model` | The default read-only view, drawn or as data |
| `format_bytes`, `humanize` | `1.2 MB`; `ship_date` → "Ship date" |

## The low level, for comparison

`review-batch` without `mount_hug`:

```ts theme={"theme":{"light":"github-light","dark":"one-dark-pro"}}
import { connect } from '@getcliqio/hug-frontend';
import review_batch from '../hug';

const hug = await connect();
hug.theme.apply(document.documentElement);
hug.auto_resize();
let state = hug.draft ?? hug.mine?.values ?? { verdicts: hug.params.documents.map((d) => ({ id: d.id, ok: true })) };

const change = (next) => {
    state = next;
    const checked = review_batch.check(state, hug.params);   // { ok, value } or { ok: false, problems }
    hug.set_values(state, {
        valid: checked.ok,
        problems: checked.ok ? [] : checked.problems,
        submit: { label: state.verdicts.every((v) => v.ok) ? 'Approve all' : 'Send verdicts' },
        summary: checked.ok ? review_batch.summary(checked.value, hug.params) : undefined,
    });
    draw();
};
const draw = () => (hug.mode === 'view' ? draw_answer(hug.viewing.values) : draw_editor(state, change));
hug.on('mode', (m) => { if (m.start) state = m.start; hug.mode === 'answer' ? change(state) : draw(); });
hug.on('status', draw);
hug.mode === 'answer' ? change(state) : draw();
// …plus draw_editor, draw_answer and uploads, by hand
```

The whole page is the [`low-level` example](https://github.com/getcliqio/cliq/tree/main/examples/hugs/low-level).


This documentation is built and hosted on [Mintlify](https://mintlify.com), a developer documentation platform.