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

# Code snippets

> Versioned workspace logic a code tool pins; published versions never change.

A snippet is a small piece of logic a workspace writes once and runs from any number of `code` tools: "the deposit is 20% of the quote", "a Toronto postal code starts with M". Snippets are versioned. A published version never changes, and a tool pins one published version, so what an agent runs stays fixed until someone changes the tool.

## What a snippet holds

| Field | Rule |
| - | - |
| `name` | 2 to 64 lowercase letters, digits and underscores, starting with a letter (`deposit_amount`). Surrounding spaces are trimmed and capitals lowercased before the rule is checked. Unique in the workspace and fixed at create |
| `description` | Optional. Whitespace is collapsed and text past 500 characters is cut, not refused. Changing it with `PATCH` takes effect at once and opens no draft |
| `source` | One expression in Sempera's restricted transform language, the one Calculation tools use. It has no import, file or network primitive; source it cannot compile is refused with `400` |
| `inputs` | Up to 20 named values the source reads: `{"name", "type", "description", "required"}`, or just a name as a string. An input's description is cut at 500 characters. Names are 1 to 40 lowercase letters, digits and underscores, starting with a letter; `now` is reserved. `type` is `string` (default), `number` or `boolean`; `required` defaults to `true` |
| `output_schema` | Required. A subset of JSON Schema: `type`, `properties`, `required`, `additionalProperties`, `items`, `enum`, `minimum`, `maximum`, `minLength`, `maxLength`, `minItems`, `maxItems`, `description`, `title`, at most 8 levels deep and 16 KB. Any other keyword is refused rather than ignored |
| `timeout_ms` | 250 to 5000, default 1000 |

Every run happens in an isolated sandbox with the version's timeout. A result that does not match `output_schema` is an error, and the value is never returned to anyone, the agent included.

## Routes

| Route | Scope | Notes |
| - | - | - |
| `GET /v1/snippets` | `tools:read` | Active snippets by name; `?status=all` adds archived ones. A standard list page (`limit`, `cursor`) |
| `POST /v1/snippets` | `tools:write` | Creates the snippet and its first draft (version 1). `201`. Accepts `Idempotency-Key` |
| `GET /v1/snippets/{snippet_id}` | `tools:read` | The snippet, every version newest first, and `used_by` (the tools that pin it) |
| `PATCH /v1/snippets/{snippet_id}` | `tools:write` | Edits the open draft, or opens a new draft numbered after the highest version. A field you leave out keeps the draft's value, or else the latest published version's |
| `POST /v1/snippets/{snippet_id}/publish` | `tools:write` | Freezes the draft as an immutable version. Accepts `Idempotency-Key` |
| `GET /v1/snippets/{snippet_id}/versions/{version}` | `tools:read` | One version by number |
| `POST /v1/snippets/{snippet_id}/test` | `tools:write` | Runs the draft or a version on sample input |
| `DELETE /v1/snippets/{snippet_id}` | `tools:write` | Archives it; `?restore=1` restores it |

Reading is open to every role. Creating, editing, publishing, archiving and testing need the `operator` or `owner` role. Ids look like `snip_0123456789abcdef`; a snippet of another workspace answers `404` exactly like one that never existed.

A snippet reads `id`, `object` (`snippet`), `name`, `description`, `status` (`active` or `archived`), `archived_at`, `created_at`, `updated_at`, `created_by`, `latest_published` and `draft_version` (version numbers, or null). `GET /v1/snippets/{snippet_id}` adds `versions` and `used_by`, whose items are `{"id", "name", "label", "version"}` for each tool that pins it. A version reads `object` (`snippet_version`), `snippet_id`, `version`, `state` (`draft` or `published`), the body fields above, `content_hash`, `created_by`, `created_at`, `updated_at`, `published_by` and `published_at`; reading one version by number also carries `snippet_name` and `snippet_archived`.

## Create, publish, test

```http theme={null}
POST /v1/snippets
{"name": "deposit_amount",
 "source": "{'deposit': round(pct(quote, 20))}",
 "inputs": [{"name": "quote", "type": "number"}],
 "output_schema": {"type": "object", "properties": {"deposit": {"type": "number"}}, "required": ["deposit"]}}
```

`POST /v1/snippets/{id}/publish` takes no body. `POST /v1/snippets/{id}/test` takes `{"version": 1, "arguments": {"quote": 100}}`; `version` is a number or `"draft"`, and omitting it tests the draft. The answer is a `snippet_test` record: `object`, `snippet_id`, `version`, `state`, `status` (`succeeded` or `failed`), `input`, `output`, `error`, `error_code`, and on success `latency_ms` and `audit`. A failed run answers `409` with that same record, not the error envelope. Run-time `error_code` values are `arguments`, `timeout`, `sandbox`, `output_too_large`, `refused`, `schema` and `busy` (every sandbox slot stayed taken through a short wait, and nothing ran).

## Refusals

| Status | When |
| - | - |
| `400` | A body field breaks a rule above, a version number is not a whole number, or a test's `arguments` is not an object |
| `404` | No such snippet or version in this workspace, or a test of the draft when there is no draft |
| `409` | The name is taken; the workspace already keeps 200 snippets or the snippet 500 versions; the snippet is archived; there is no draft to publish; the draft is identical to the latest version; someone else published or opened the draft at the same moment; an archive while a tool still pins it |
| `503` | The deployment has no database to keep snippets in |

## Pinning a snippet from a tool

A `code` tool names a snippet and one published version:

```http theme={null}
POST /v1/tools
{"definition": {"kind": "code", "name": "deposit", "label": "Deposit",
                "description": "Works out the deposit for a quote.",
                "when_to_use": "When the caller asks how much the deposit is.",
                "config": {"snippet_id": "snip_0123456789abcdef", "snippet_version": 1, "result_label": "deposit"}}}
```

Sempera fills in a frozen copy of that version (its source, inputs, schema, timeout and hash) and ignores any body the request carried, so the tool and every agent version that uses it run exactly what was published. The version must be published and the snippet not archived, and a `code` tool is always a tool that reads (`access: read`). Creating or changing a tool needs the `owner` role.


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