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

# Project functions

> Create callable wrappers around pipelines and execute them via project-scoped endpoints.

Function endpoints live under `/:project/api/functions` and inherit project permissions. Most calls require at least `functions.read` or `functions.write` permissions for the slug.

## List & create

### GET `/:project/api/functions`

Returns all functions you can see inside the project. Each entry contains `{ id, name, slug, description, version, created, updated }` and, when you have read access to the current version, `{ metadata, parameters, outputs, outputType, sourcePipelineId, sourcePipelineVersionId }`.

### PUT `/:project/api/functions`

* **Body**

```json theme={null}
{
  "name": "Summarise Page",
  "description": "Wraps the marketing pipeline",
  "slug": "summarise-page",
  "definition": {
    "source": { "...": "pipeline graph" },
    "parameters": [{ "name": "url", "refType": "url", "description": "Target page" }],
    "outputs": [{ "name": "summary", "refType": "text" }],
    "metadata": { "title": "Summarise Page" },
    "outputType": "function"
  }
}
```

* **Behavior** – validates the slug, compiles the pipeline source (`@silyze/browsary-pipeline`), stores compiler errors (if any), creates the first function version, and sets it as `current_version_id`.

## Read / update / delete

| Endpoint                                      | Description                                                                                                                                            |
| --------------------------------------------- | ------------------------------------------------------------------------------------------------------------------------------------------------------ |
| `GET /:project/api/functions/{functionId}`    | Requires read permission. Returns the base fields plus the current version details and a list of previous versions (IDs, metadata, source references). |
| `PATCH /:project/api/functions/{functionId}`  | Accepts `name`, `description`, or `slug`. Slug updates automatically re-slugify the provided name. Colliding slugs are rejected.                       |
| `DELETE /:project/api/functions/{functionId}` | Removes the function and all versions.                                                                                                                 |

## Import from a pipeline

### POST `/:project/api/functions/{functionId}/import`

Copies the source from an existing pipeline version into a new function version.

* **Body**

```json theme={null}
{
  "pipelineId": "pipe_123",
  "pipelineVersionId": "pver_456",
  "metadata": { "title": "Summarise Page" },
  "parameters": [{ "name": "url", "refType": "url" }],
  "outputs": [{ "name": "summary", "refType": "text", "source": { "nodeName": "summarise", "outputName": "text" } }],
  "outputType": "function"
}
```

Any field you omit falls back to the previous function version (if it exists). The response is `{ version: "<new function version id>", errors: [ ...compiler errors... ] }`.

## Execute a function

### POST `/:project/api/functions/slug/{slug}/execute`

* **Body** – `{ "args": { "...": "function parameters" } }`.
* **Auth** – any identity with read access to the function and execute permission for the underlying pipeline version.
* **Response**

```json theme={null}
{
  "identifier": "run_123",
  "outputs": { "summary": "..." },
  "result": { "...": "raw pipeline execution payload" }
}
```

> The codebase also includes a `/functions/by-id/execute` route, but it currently expects a slug parameter. Prefer the slug-based endpoint above for reliable behavior.
