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

# Recipe Serve

> HTTP server for recipe endpoints

# Recipe Serve

The `praisonai serve recipe` command starts an HTTP server that exposes recipe endpoints for remote invocation.

## Quick Start

```bash theme={"theme":{"light":"vitesse-light","dark":"vitesse-dark"}}
# Start server on default port (8765)
praisonai serve recipe

# Start on custom port
praisonai serve recipe --port 8000

# Start with authentication
praisonai serve recipe --auth api-key
```

## Command Options

| Option             | Description                           | Default   |
| ------------------ | ------------------------------------- | --------- |
| `--port <num>`     | Server port                           | 8765      |
| `--host <addr>`    | Server host                           | 127.0.0.1 |
| `--auth <type>`    | Auth type: none, api-key, jwt         | none      |
| `--api-key <key>`  | API key for authentication            | -         |
| `--reload`         | Enable hot reload (dev mode)          | false     |
| `--preload`        | Preload all recipes on startup        | false     |
| `--recipes <list>` | Comma-separated recipe names to serve | all       |
| `--config <path>`  | Path to serve.yaml config file        | -         |

## Security

### Host Binding Safety

By default, the server binds to `127.0.0.1` (localhost only). **Binding to `0.0.0.0` (all interfaces) requires authentication.**

```bash theme={"theme":{"light":"vitesse-light","dark":"vitesse-dark"}}
# This will be REFUSED (no auth on public interface)
praisonai serve recipe --host 0.0.0.0

# This works (auth enabled)
praisonai serve recipe --host 0.0.0.0 --auth api-key
```

### Authentication Modes

#### API Key Authentication

```bash theme={"theme":{"light":"vitesse-light","dark":"vitesse-dark"}}
# Start with API key auth
praisonai serve recipe --auth api-key --api-key my-secret-key

# Or use environment variable
export PRAISONAI_API_KEY=my-secret-key
praisonai serve recipe --auth api-key
```

Clients must include the `X-API-Key` header:

```bash theme={"theme":{"light":"vitesse-light","dark":"vitesse-dark"}}
curl -H "X-API-Key: my-secret-key" http://localhost:8765/v1/recipes
```

## Configuration File

Create a `serve.yaml` file for persistent configuration:

```yaml theme={"theme":{"light":"vitesse-light","dark":"vitesse-dark"}}
# serve.yaml
host: 127.0.0.1
port: 8765
auth: api-key
api_key: your-secret-key  # or use PRAISONAI_API_KEY env var

# Optional: limit which recipes are served
recipes:
  - my-recipe
  - another-recipe

# Optional: preload recipes on startup
preload: true

# Optional: CORS configuration
cors_origins: "*"
```

Use the config file:

```bash theme={"theme":{"light":"vitesse-light","dark":"vitesse-dark"}}
praisonai serve recipe --config ./serve.yaml
```

### Configuration Precedence

1. CLI flags (highest priority)
2. Environment variables
3. Config file
4. Defaults (lowest priority)

## API Endpoints

### Health Check

```
GET /health
```

Response:

```json theme={"theme":{"light":"vitesse-light","dark":"vitesse-dark"}}
{
  "status": "healthy",
  "service": "praisonai-recipe-runner",
  "version": "2.7.1"
}
```

### List Recipes

```
GET /v1/recipes
GET /v1/recipes?tags=audio,video
```

Response:

```json theme={"theme":{"light":"vitesse-light","dark":"vitesse-dark"}}
{
  "recipes": [
    {
      "name": "my-recipe",
      "version": "1.0.0",
      "description": "Recipe description",
      "tags": ["audio", "video"]
    }
  ]
}
```

### Describe Recipe

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

Response:

```json theme={"theme":{"light":"vitesse-light","dark":"vitesse-dark"}}
{
  "name": "my-recipe",
  "version": "1.0.0",
  "description": "Recipe description",
  "requires": {
    "packages": [],
    "env": ["OPENAI_API_KEY"]
  },
  "config_schema": {},
  "outputs": []
}
```

### Get Recipe Schema

```
GET /v1/recipes/{name}/schema
```

Response:

```json theme={"theme":{"light":"vitesse-light","dark":"vitesse-dark"}}
{
  "name": "my-recipe",
  "version": "1.0.0",
  "input_schema": {},
  "output_schema": []
}
```

### Run Recipe

```
POST /v1/recipes/run
Content-Type: application/json

{
  "recipe": "my-recipe",
  "input": {"query": "Hello"},
  "config": {},
  "options": {"dry_run": false}
}
```

Response:

```json theme={"theme":{"light":"vitesse-light","dark":"vitesse-dark"}}
{
  "ok": true,
  "run_id": "run-abc123",
  "recipe": "my-recipe",
  "version": "1.0.0",
  "status": "success",
  "output": {"result": "..."},
  "metrics": {"duration_sec": 1.5},
  "trace": {
    "run_id": "run-abc123",
    "session_id": "session-xyz",
    "trace_id": "trace-123"
  }
}
```

### Stream Recipe (SSE)

```
POST /v1/recipes/stream
Content-Type: application/json

{
  "recipe": "my-recipe",
  "input": {"query": "Hello"}
}
```

Response (Server-Sent Events):

```
event: started
data: {"run_id": "run-abc123", "recipe": "my-recipe"}

event: progress
data: {"step": "loading", "message": "Loading recipe..."}

event: progress
data: {"step": "executing", "message": "Running workflow..."}

event: completed
data: {"run_id": "run-abc123", "status": "success"}
```

## Examples

### Development Mode

```bash theme={"theme":{"light":"vitesse-light","dark":"vitesse-dark"}}
# Start with hot reload for development
praisonai serve recipe --reload
```

### Production Mode

```bash theme={"theme":{"light":"vitesse-light","dark":"vitesse-dark"}}
# Production with auth and preloading
praisonai serve recipe \
  --host 0.0.0.0 \
  --port 8000 \
  --auth api-key \
  --preload
```

### Using with Docker

```dockerfile theme={"theme":{"light":"vitesse-light","dark":"vitesse-dark"}}
FROM python:3.11-slim
RUN pip install praisonai[serve]
COPY serve.yaml /app/
WORKDIR /app
CMD ["praisonai", "recipe", "serve", "--config", "serve.yaml"]
```

### Client Examples

#### curl

```bash theme={"theme":{"light":"vitesse-light","dark":"vitesse-dark"}}
# Health check
curl http://localhost:8765/health

# List recipes
curl http://localhost:8765/v1/recipes

# Run recipe
curl -X POST http://localhost:8765/v1/recipes/run \
  -H "Content-Type: application/json" \
  -d '{"recipe": "my-recipe", "input": {"query": "Hello"}}'

# With auth
curl -X POST http://localhost:8765/v1/recipes/run \
  -H "Content-Type: application/json" \
  -H "X-API-Key: my-secret-key" \
  -d '{"recipe": "my-recipe", "input": {"query": "Hello"}}'
```

#### Python

```python theme={"theme":{"light":"vitesse-light","dark":"vitesse-dark"}}
import requests

# Run recipe
response = requests.post(
    "http://localhost:8765/v1/recipes/run",
    json={
        "recipe": "my-recipe",
        "input": {"query": "Hello"}
    },
    headers={"X-API-Key": "my-secret-key"}
)
result = response.json()
print(result["output"])
```

#### JavaScript

```javascript theme={"theme":{"light":"vitesse-light","dark":"vitesse-dark"}}
const response = await fetch("http://localhost:8765/v1/recipes/run", {
  method: "POST",
  headers: {
    "Content-Type": "application/json",
    "X-API-Key": "my-secret-key"
  },
  body: JSON.stringify({
    recipe: "my-recipe",
    input: { query: "Hello" }
  })
});
const result = await response.json();
console.log(result.output);
```

## Environment Variables

| Variable               | Description                |
| ---------------------- | -------------------------- |
| `PRAISONAI_API_KEY`    | API key for authentication |
| `PRAISONAI_SERVE_HOST` | Default host               |
| `PRAISONAI_SERVE_PORT` | Default port               |

## Troubleshooting

### Port Already in Use

```
Error: [Errno 48] Address already in use
```

**Solution**: Use a different port or stop the existing process:

```bash theme={"theme":{"light":"vitesse-light","dark":"vitesse-dark"}}
praisonai serve recipe --port 8766
# Or
lsof -i :8765 | grep LISTEN | awk '{print $2}' | xargs kill
```

### Missing Dependencies

```
Error: Serve dependencies not installed. Run: pip install praisonai[serve]
```

**Solution**: Install serve extras:

```bash theme={"theme":{"light":"vitesse-light","dark":"vitesse-dark"}}
pip install praisonai[serve]
```

### Auth Required for Public Binding

```
Error: Auth required for non-localhost binding. Use --auth api-key or --auth jwt
```

**Solution**: Enable authentication:

```bash theme={"theme":{"light":"vitesse-light","dark":"vitesse-dark"}}
praisonai serve recipe --host 0.0.0.0 --auth api-key
```
