# App: Recipes

**Page:** api/app/recipes

[Download Raw Markdown](./api/app/recipes.md)

---

{/* AUTO-GENERATED — Do not edit manually. Regenerate with: npm run docs:api:generate */}



# App: Recipes

The Recipes API manages named selector templates — called **recipes** — that bundle a selector template with an allow-list of overridable fields. Use these endpoints to list, create, fetch, update, delete, search, and execute saved recipes without re-sending the full selector on every run.

## List saved launch recipes

`GET /api/v1/run/recipes`

Returns all saved recipes that can be reused as named selector templates.

This endpoint takes no parameters.




```bash
curl -sS -X GET 'http://127.0.0.1:7682/api/v1/run/recipes'
```




```ts
const recipes = await client.app.recipes.list();
```




```json
[
  {
    "name": "firefox-stable",
    "description": "Stable Firefox via nixpkgs",
    "selector_template": {
      "app": "firefox",
      "os": "linux",
      "kind": "gui",
      "source": ["nix"],
      "arch": "amd64"
    },
    "allowed_overrides": ["version", "channel"]
  },
  {
    "name": "node-lts",
    "description": "Latest Node.js LTS",
    "selector_template": {
      "app": "node",
      "os": "any",
      "kind": "cli",
      "source": ["nix", "pkgx"]
    },
    "allowed_overrides": ["version"]
  }
]
```




## Get a saved recipe

`GET /api/v1/run/recipes/{name}`

Retrieves a single saved recipe by name.

### Parameters

| Name | In | Type | Required | Description |
|------|----|------|----------|-------------|
| name | path | string | Yes | Recipe name |




```bash
curl -sS -X GET 'http://127.0.0.1:7682/api/v1/run/recipes/firefox-stable'
```




```ts
const recipe = await client.app.recipes.get({
  name: "firefox-stable",
});
```




```json
{
  "name": "firefox-stable",
  "description": "Stable Firefox via nixpkgs",
  "selector_template": {
    "app": "firefox",
    "os": "linux",
    "kind": "gui",
    "source": ["nix"],
    "arch": "amd64"
  },
  "allowed_overrides": ["version", "channel"]
}
```




```json
{
  "error": "Recipe not found",
  "code": 404
}
```




## Create a saved recipe

`POST /api/v1/run/recipes`

Creates a new named selector template. The `allowed_overrides` array constrains which fields may be supplied at run time.

### Request Body

A `RecipeConfig` object describing the recipe.

| Field | Type | Required | Description |
|-------|------|----------|-------------|
| name | string | Yes | Recipe name (unique) |
| description | string | No | Human-readable description |
| selector_template | object | No | Partial selector template the recipe resolves against |
| allowed_overrides | array of string | No | Fields the caller may override at run time. Default: `[]` |

```json
{
  "name": "firefox-stable",
  "description": "Stable Firefox via nixpkgs",
  "selector_template": {
    "app": "firefox",
    "os": "linux",
    "kind": "gui",
    "source": ["nix"],
    "arch": "amd64"
  },
  "allowed_overrides": ["version", "channel"]
}
```




```bash
curl -sS -X POST 'http://127.0.0.1:7682/api/v1/run/recipes' \
  -H 'content-type: application/json' \
  -d '{
    "name": "firefox-stable",
    "description": "Stable Firefox via nixpkgs",
    "selector_template": {
      "app": "firefox",
      "os": "linux",
      "kind": "gui",
      "source": ["nix"],
      "arch": "amd64"
    },
    "allowed_overrides": ["version", "channel"]
  }'
```




```ts
const recipes = await client.app.recipes.create({
  data: {
    name: "firefox-stable",
    description: "Stable Firefox via nixpkgs",
    selector_template: {
      app: "firefox",
      os: "linux",
      kind: "gui",
      source: ["nix"],
      arch: "amd64",
    },
    allowed_overrides: ["version", "channel"],
  },
});
```




```json
[
  {
    "name": "firefox-stable",
    "description": "Stable Firefox via nixpkgs",
    "selector_template": {
      "app": "firefox",
      "os": "linux",
      "kind": "gui",
      "source": ["nix"],
      "arch": "amd64"
    },
    "allowed_overrides": ["version", "channel"]
  }
]
```




```json
{
  "error": "Invalid recipe configuration",
  "code": 400
}
```




```json
{
  "error": "Recipe already exists",
  "code": 409
}
```




## Run using a saved recipe

`POST /api/v1/run/recipes/{name}/run`

Resolves a saved recipe after applying allowed overrides, optionally selects a candidate, and returns a `RunResponse` that may include a shell command, terminal delegation result, or generated curl.

### Parameters

| Name | In | Type | Required | Description |
|------|----|------|----------|-------------|
| name | path | string | Yes | Recipe name |

### Request Body

A `RecipeExecutionRequest` containing optional `overrides` to apply on top of the saved selector template.

| Field | Type | Required | Description |
|-------|------|----------|-------------|
| overrides | object | No | Partial selector template overrides permitted by the recipe's `allowed_overrides` |

```json
{
  "overrides": {
    "version": "128.0.3"
  }
}
```




```bash
curl -sS -X POST 'http://127.0.0.1:7682/api/v1/run/recipes/firefox-stable/run' \
  -H 'content-type: application/json' \
  -d '{
    "overrides": {
      "version": "128.0.3"
    }
  }'
```




```ts
const result = await client.app.recipes.run({
  name: "firefox-stable",
  data: {
    overrides: {
      version: "128.0.3",
    },
  },
});
```




```json
{
  "status": "dry-run",
  "set_id": "a1b2c3d4e5f6",
  "candidates": [
    {
      "candidate_id": "nix-firefox-128",
      "title": "Firefox (nixpkgs)",
      "description": "Mozilla Firefox web browser via nixpkgs",
      "provider": "nix",
      "source_id": "nixpkgs",
      "score": 95,
      "run_plan": {
        "command": "nix run nixpkgs#firefox"
      }
    }
  ],
  "selected": {
    "candidate_id": "nix-firefox-128",
    "title": "Firefox (nixpkgs)",
    "description": "Mozilla Firefox web browser via nixpkgs",
    "provider": "nix",
    "source_id": "nixpkgs",
    "score": 95,
    "run_plan": {
      "command": "nix run nixpkgs#firefox"
    }
  },
  "shell_command": "nix run nixpkgs#firefox"
}
```




```json
{
  "error": "Override not permitted by recipe",
  "code": 400
}
```




```json
{
  "error": "Recipe not found",
  "code": 404
}
```




```json
{
  "error": "Required local tools are unavailable",
  "code": 503
}
```




## Search using a saved recipe

`POST /api/v1/run/recipes/{name}/search`

Resolves a saved recipe to a candidate set after applying allowed overrides. Returns a `set_id` and ranked candidates for race-free selection.

### Parameters

| Name | In | Type | Required | Description |
|------|----|------|----------|-------------|
| name | path | string | Yes | Recipe name |

### Request Body

A `RecipeExecutionRequest` containing optional `overrides` permitted by the recipe.

| Field | Type | Required | Description |
|-------|------|----------|-------------|
| overrides | object | No | Partial selector template overrides permitted by the recipe's `allowed_overrides` |

```json
{
  "overrides": {
    "channel": "stable"
  }
}
```




```bash
curl -sS -X POST 'http://127.0.0.1:7682/api/v1/run/recipes/firefox-stable/search' \
  -H 'content-type: application/json' \
  -d '{
    "overrides": {
      "channel": "stable"
    }
  }'
```




```ts
const result = await client.app.recipes.search({
  name: "firefox-stable",
  data: {
    overrides: {
      channel: "stable",
    },
  },
});
```




```json
{
  "set_id": "a1b2c3d4e5f6",
  "candidates": [
    {
      "candidate_id": "nix-firefox-128",
      "title": "Firefox (nixpkgs)",
      "description": "Mozilla Firefox web browser via nixpkgs",
      "provider": "nix",
      "source_id": "nixpkgs",
      "score": 95,
      "run_plan": {
        "command": "nix run nixpkgs#firefox"
      }
    }
  ]
}
```




```json
{
  "error": "Override not permitted by recipe",
  "code": 400
}
```




```json
{
  "error": "Recipe not found",
  "code": 404
}
```




## Update a saved recipe

`PATCH /api/v1/run/recipes/{name}`

Partially updates an existing recipe.

### Parameters

| Name | In | Type | Required | Description |
|------|----|------|----------|-------------|
| name | path | string | Yes | Recipe name |

### Request Body

A partial recipe configuration. Only the fields you supply are modified; all others are left unchanged.

```json
{
  "description": "Updated description",
  "allowed_overrides": ["version", "channel", "variant"]
}
```




```bash
curl -sS -X PATCH 'http://127.0.0.1:7682/api/v1/run/recipes/firefox-stable' \
  -H 'content-type: application/json' \
  -d '{
    "description": "Updated description",
    "allowed_overrides": ["version", "channel", "variant"]
  }'
```




```ts
const updated = await client.app.recipes.update({
  name: "firefox-stable",
  data: {
    description: "Updated description",
    allowed_overrides: ["version", "channel", "variant"],
  },
});
```




```json
{
  "name": "firefox-stable",
  "description": "Updated description",
  "selector_template": {
    "app": "firefox",
    "os": "linux",
    "kind": "gui",
    "source": ["nix"],
    "arch": "amd64"
  },
  "allowed_overrides": ["version", "channel", "variant"]
}
```




```json
{
  "error": "Recipe not found",
  "code": 404
}
```




## Delete a saved recipe

`DELETE /api/v1/run/recipes/{name}`

Removes a saved recipe by name.

### Parameters

| Name | In | Type | Required | Description |
|------|----|------|----------|-------------|
| name | path | string | Yes | Recipe name |




```bash
curl -sS -X DELETE 'http://127.0.0.1:7682/api/v1/run/recipes/firefox-stable'
```




```ts
await client.app.recipes.delete({
  name: "firefox-stable",
});
```




Recipe deleted successfully. No response body is returned.




```json
{
  "error": "Recipe not found",
  "code": 404
}
```