# API Reference — Agent Endpoints

> Complete API reference for Agent Endpoints — CRUD, execution, and templates.

All management endpoints require JWT authentication. The execution endpoint uses API key or public access.

## Management Endpoints

Base URL: `https://api.aerostack.dev/api/agent-endpoints`

### List Endpoints

```
GET /api/agent-endpoints
Authorization: Bearer 
```

Returns all agent endpoints owned by the authenticated user.

**Response (200):**

```json
{
  "endpoints": [
    {
      "id": "aep_7f3a2b9c1d4e5f6a8b",
      "owner_id": "usr_abc123",
      "workspace_id": "ws_def456",
      "name": "summarizer",
      "slug": "summarizer",
      "description": "Summarizes text input",
      "agent_type": "extractor",
      "system_prompt": "You are a concise summarizer...",
      "llm_provider": "openai",
      "llm_model": "gpt-4o-mini",
      "max_tokens": 4096,
      "temperature": 0.3,
      "output_format": "text",
      "max_tool_calls": 10,
      "timeout_ms": 30000,
      "enable_streaming": 0,
      "async_mode": 0,
      "auth_mode": "api_key",
      "price_per_run_cents": 0,
      "status": "active",
      "created_at": "2026-03-15T10:00:00Z",
      "updated_at": "2026-03-15T10:00:00Z"
    }
  ]
}
```

---

### Create Endpoint

```
POST /api/agent-endpoints
Authorization: Bearer 
Content-Type: application/json
```

**Request Body:**

| Field | Type | Required | Default | Description |
|-------|------|----------|---------|-------------|
| `name` | string | Yes | — | 1-100 characters |
| `workspace_id` | string | Yes | — | MCP workspace ID (1-100 chars) |
| `system_prompt` | string | Yes | — | Agent instructions (1-10000 chars) |
| `description` | string | No | `null` | Short description (max 500 chars) |
| `slug` | string | No | auto from name | URL slug (max 60 chars) |
| `agent_type` | string | No | `"extractor"` | `extractor`, `actor`, or `pipeline` (informational) |
| `llm_provider` | string | No | `"openai"` | `openai`, `anthropic`, `gemini`, `groq`, `workers-ai`, `custom` |
| `llm_model` | string | No | `"gpt-4o-mini"` | Model identifier (max 100 chars) |
| `llm_api_key` | string | No | platform key | Your LLM provider API key (stored securely) |
| `max_tokens` | integer | No | `4096` | 100-32768 |
| `temperature` | number | No | `0.3` | 0-2 |
| `input_schema` | object | No | `null` | JSON Schema for expected input (informational) |
| `output_schema` | object | No | `null` | JSON Schema for structured output (used with `json` format) |
| `output_format` | string | No | `"text"` | `text`, `json`, or `markdown` |
| `max_tool_calls` | integer | No | `10` | 1-50. Controls max agentic loop iterations |
| `timeout_ms` | integer | No | `30000` | 1000-120000 (hard cap at 60000 during execution) |
| `enable_streaming` | boolean | No | `false` | Return SSE stream instead of JSON |
| `async_mode` | boolean | No | `false` | Not yet implemented (returns 501) |
| `auth_mode` | string | No | `"api_key"` | `api_key` or `public` |
| `price_per_run_cents` | integer | No | `0` | 0-10000. Per-execution charge from owner's wallet |

**Response (201):**

```json
{
  "endpoint": { "id": "aep_...", "name": "...", "slug": "...", "..." : "..." },
  "api_key": "aek_a1b2c3d4e5f6a7b8c9d0e1f2a3b4c5d6",
  "run_url": "/api/run/summarizer"
}
```

The `api_key` is only returned in this response. Store it securely. Use the regenerate-key endpoint if you lose it.

---

### Get Endpoint

```
GET /api/agent-endpoints/:id
Authorization: Bearer 
```

Returns a single endpoint. Returns 404 if not found or not owned by the authenticated user.

**Response (200):**

```json
{
  "endpoint": { "id": "aep_...", "..." : "..." }
}
```

---

### Update Endpoint

```
PATCH /api/agent-endpoints/:id
Authorization: Bearer 
Content-Type: application/json
```

All fields from the create schema are optional. `workspace_id` cannot be changed after creation.

**Request Body (all fields optional):**

| Field | Type | Description |
|-------|------|-------------|
| `name` | string | 1-100 characters |
| `description` | string | Max 500 chars |
| `system_prompt` | string | 1-10000 chars |
| `agent_type` | string | `extractor`, `actor`, or `pipeline` |
| `llm_provider` | string | Provider enum |
| `llm_model` | string | Model identifier |
| `max_tokens` | integer | 100-32768 |
| `temperature` | number | 0-2 |
| `input_schema` | object | JSON Schema |
| `output_schema` | object | JSON Schema |
| `output_format` | string | `text`, `json`, or `markdown` |
| `max_tool_calls` | integer | 1-50 |
| `timeout_ms` | integer | 1000-120000 |
| `enable_streaming` | boolean | SSE mode |
| `async_mode` | boolean | Not yet implemented |
| `auth_mode` | string | `api_key` or `public` |
| `price_per_run_cents` | integer | 0-10000 |

**Response (200):**

```json
{
  "endpoint": { "id": "aep_...", "..." : "..." }
}
```

---

### Delete Endpoint

```
DELETE /api/agent-endpoints/:id
Authorization: Bearer 
```

Permanently deletes the endpoint and all its run history.

**Response (200):**

```json
{
  "deleted": true
}
```

---

### Activate Endpoint

```
POST /api/agent-endpoints/:id/activate
Authorization: Bearer 
```

Sets the endpoint status to `active`. Only active endpoints can be executed.

**Response (200):**

```json
{
  "status": "active"
}
```

---

### Regenerate API Key

```
POST /api/agent-endpoints/:id/regenerate-key
Authorization: Bearer 
```

Generates a new API key and invalidates the previous one.

**Response (200):**

```json
{
  "api_key": "aek_new_key_shown_once"
}
```

---

### List Runs

```
GET /api/agent-endpoints/:id/runs?limit=50
Authorization: Bearer 
```

| Query Param | Type | Default | Max |
|-------------|------|---------|-----|
| `limit` | integer | 50 | 100 |

**Response (200):**

```json
{
  "runs": [
    {
      "id": "run_8e4f2a1b3c5d7e9f0a",
      "endpoint_id": "aep_7f3a2b9c1d4e5f6a8b",
      "input": "Summarize this...",
      "output": "The article covers...",
      "tool_calls": "[{\"name\":\"search\",\"success\":true}]",
      "tokens_input": 312,
      "tokens_output": 67,
      "cost_cents": 0.08,
      "latency_ms": 1456,
      "status": "success",
      "caller_ip": "203.0.113.42",
      "created_at": "2026-03-15T10:23:45Z"
    }
  ]
}
```

---

### Test Endpoint

```
POST /api/agent-endpoints/:id/test
Authorization: Bearer 
Content-Type: application/json
```

Executes the endpoint using your JWT session (no API key needed). Rate limited to 10 per minute. Logged with `status: "test"` and `caller_ip: "dashboard"`.

**Request Body:**

```json
{
  "input": "Your test input here"
}
```

**Response (200):**

```json
{
  "output": "Agent response...",
  "usage": {
    "tokens_input": 245,
    "tokens_output": 89,
    "cost_cents": 0.12,
    "latency_ms": 1823
  }
}
```

---

## Templates

### List Templates

```
GET /api/agent-endpoints/templates/list?type=agent
```

No authentication required.

| Query Param | Type | Values |
|-------------|------|--------|
| `type` | string | `agent` or `webhook` |

**Response (200):**

```json
{
  "templates": [
    {
      "id": "tpl_invoice_parser",
      "name": "Invoice Parser",
      "description": "Extract structured data from invoice text",
      "type": "agent",
      "category": "extractor",
      "system_prompt": "You are an invoice parser...",
      "suggested_mcps": "[\"storage\"]",
      "input_schema": null,
      "output_schema": "{\"type\":\"object\",\"properties\":{...}}",
      "popularity": 95,
      "created_at": "2026-03-01T00:00:00Z"
    }
  ]
}
```

Pre-built agent templates include: Invoice Parser, Lead Enricher, Support Ticket Classifier, PR Code Reviewer, Resume Screener, SQL Query Generator, and Email Drafter.

---

## Execution Endpoint

### Execute Agent

```
POST /api/run/:slug
Authorization: Bearer   (or X-API-Key header, or no auth for public)
Content-Type: application/json
```

**Request Body:**

```json
{
  "input": "Your input text or prompt"
}
```

Alternative input fields (all equivalent): `message`, `text`, `prompt`. If none are present, the entire body is stringified.

Maximum request body size: 2 MB.

**Response (200) — Sync Mode:**

```json
{
  "output": "Agent response text or parsed JSON object",
  "raw_output": "Original LLM text (only present when output is parsed JSON)",
  "tool_calls": [
    {
      "tool": "github_list_issues",
      "success": true,
      "latency_ms": 234
    }
  ],
  "usage": {
    "tokens_input": 1245,
    "tokens_output": 189,
    "cost_cents": 0.34,
    "latency_ms": 2891,
    "iterations": 2
  }
}
```

**Response — Streaming Mode (SSE):**

See [SSE Streaming](/agent-endpoints/streaming) for the full event format.

**Error Responses:**

| Status | Body | Condition |
|--------|------|-----------|
| 400 | `{"error": "Input required..."}` | No input provided |
| 401 | `{"error": "API key required..."}` | Missing API key (api_key mode) |
| 401 | `{"error": "Invalid API key"}` | Wrong API key |
| 403 | `{"error": "...unsupported auth mode"}` | Auth mode not in allowlist |
| 404 | `{"error": "Agent endpoint not found or not active"}` | Invalid slug or inactive |
| 413 | `{"error": "Request body too large (max 2MB)"}` | Body exceeds 2 MB |
| 429 | `{"error": "Rate limited..."}` | Rate limit exceeded |
| 501 | `{"error": "Async mode is not yet available..."}` | async_mode enabled |

---

## Error Codes Summary

| Code | Meaning |
|------|---------|
| 400 | Validation failed or missing input |
| 401 | Authentication failed |
| 403 | Unsupported auth mode |
| 404 | Not found or not owner |
| 413 | Request body too large |
| 429 | Rate limited |
| 501 | Feature not yet implemented |
