Recipe API

HTTP API endpoints for recipe runner server

Recipe API

The Recipe API provides endpoints for listing, describing, and executing recipes.

Overview

Recipes are reusable agent configurations that can be invoked via HTTP. The recipe server provides both synchronous and streaming execution modes.

When to Use

  • Reusable workflows: Execute pre-defined agent workflows
  • Streaming output: Get real-time progress via SSE
  • Batch processing: Run multiple recipes programmatically

Base URL + Playground

bash
# Start recipe server
praisonai serve recipe --host 127.0.0.1 --port 8765

Base URL: http://127.0.0.1:8765

Endpoints

GET /v1/recipes

List all available recipes.

ParamField none

No parameters required.

curl
curl http://127.0.0.1:8765/v1/recipes
Python
import requests

response = requests.get("http://127.0.0.1:8765/v1/recipes")
recipes = response.json()
for recipe in recipes["recipes"]:
    print(f"- {recipe['name']}: {recipe['description']}")
JavaScript
const response = await fetch("http://127.0.0.1:8765/v1/recipes");
const { recipes } = await response.json();
recipes.forEach(r => console.log(`- ${r.name}: ${r.description}`));

Response:

json
{
  "recipes": [
    {"name": "research", "description": "Deep research agent"},
    {"name": "code-review", "description": "Code review agent"}
  ]
}

GET /v1/recipes/{name}

Get detailed information about a recipe.

name string

Recipe name

curl
curl http://127.0.0.1:8765/v1/recipes/research
Python
import requests

response = requests.get("http://127.0.0.1:8765/v1/recipes/research")
recipe = response.json()
print(recipe)

Response:

json
{
  "name": "research",
  "description": "Deep research agent",
  "schema": {
    "type": "object",
    "properties": {
      "topic": {"type": "string"}
    },
    "required": ["topic"]
  }
}

POST /v1/recipes/run

Execute a recipe synchronously.

ParamField string

Recipe name to execute

ParamField object

Input data for the recipe

curl
curl -X POST http://127.0.0.1:8765/v1/recipes/run \
  -H "Content-Type: application/json" \
  -d '{"recipe": "research", "input": {"topic": "AI agents"}}'
Python
import requests

response = requests.post(
    "http://127.0.0.1:8765/v1/recipes/run",
    json={"recipe": "research", "input": {"topic": "AI agents"}}
)
result = response.json()
print(result["result"])
JavaScript
const response = await fetch("http://127.0.0.1:8765/v1/recipes/run", {
  method: "POST",
  headers: {"Content-Type": "application/json"},
  body: JSON.stringify({recipe: "research", input: {topic: "AI agents"}})
});
const result = await response.json();
console.log(result.result);

Response:

json
{
  "result": "Research findings on AI agents...",
  "duration_ms": 5432
}

POST /v1/recipes/stream

Execute a recipe with SSE streaming.

ParamField string

Recipe name to execute

ParamField object

Input data for the recipe

curl
curl -X POST http://127.0.0.1:8765/v1/recipes/stream \
  -H "Content-Type: application/json" \
  -H "Accept: text/event-stream" \
  -d '{"recipe": "research", "input": {"topic": "AI agents"}}'
Python
import requests

response = requests.post(
    "http://127.0.0.1:8765/v1/recipes/stream",
    json={"recipe": "research", "input": {"topic": "AI agents"}},
    stream=True
)
for line in response.iter_lines():
    if line:
        print(line.decode())

SSE Events:

event: progress
data: {"step": "Researching...", "percentage": 25}

event: progress
data: {"step": "Analyzing...", "percentage": 50}

event: result
data: {"result": "Research findings..."}

POST /v1/recipes/validate

Validate recipe input without executing.

ParamField string

Recipe name

ParamField object

Input data to validate

bash
curl -X POST http://127.0.0.1:8765/v1/recipes/validate \
  -H "Content-Type: application/json" \
  -d '{"recipe": "research", "input": {"topic": "AI"}}'

Response:

json
{
  "valid": true,
  "errors": []
}

Errors

StatusDescription
200Success
400Invalid request or validation error
404Recipe not found
429Rate limit exceeded
500Server error

429 Rate limit exceeded responses include a Retry-After header. The client identity used for bucketing depends on the server’s auth mode — see Recipe Serve Advanced → Rate limiter internals.

CLI Equivalent

bash
# List recipes
praisonai recipes list

# Run a recipe
praisonai recipes run research --input '{"topic": "AI"}'

# Describe a recipe
praisonai recipes describe research

Configuration

Recipe server configuration via serve.yaml:

yaml
host: 127.0.0.1
port: 8765
auth: api-key
api_key: your-secret-key
recipes:
  - research
  - code-review
preload: true
rate_limit: 100      # per client (jwt sub / validated api-key / ip). Split across workers when workers > 1.

Notes

  • Streaming uses Server-Sent Events (SSE)
  • Rate limiting is configurable per server
  • Recipes are discovered from the template registry
  • Long-running recipes no longer starve /health, /metrics, or concurrent requests — sync recipe work is offloaded to a worker thread pool and SSE events are queued off the event loop

Related