|
| 1 | +--- |
| 2 | +title: REST API |
| 3 | +description: The worker's HTTP endpoints — request/response shapes, error codes, and rate limiting. |
| 4 | +sidebar: |
| 5 | + order: 1 |
| 6 | +--- |
| 7 | + |
| 8 | +Base URL: your deployed worker, e.g. |
| 9 | +`https://claudius-chat-worker.<you>.workers.dev`. CORS restricts callers to |
| 10 | +the configured [`ALLOWED_ORIGIN`](/configuration/worker/) list (plus |
| 11 | +`http://localhost:*`). Allowed methods: `POST`, `OPTIONS`; |
| 12 | +allowed header: `Content-Type`. |
| 13 | + |
| 14 | +## POST /api/chat |
| 15 | + |
| 16 | +Send the conversation so far; receive the assistant's reply. |
| 17 | + |
| 18 | +### Request |
| 19 | + |
| 20 | +```json |
| 21 | +{ |
| 22 | + "messages": [ |
| 23 | + { "role": "user", "content": "Hello" }, |
| 24 | + { "role": "assistant", "content": "Hi there!" }, |
| 25 | + { "role": "user", "content": "What are your hours?" } |
| 26 | + ], |
| 27 | + "conversationId": "optional-opaque-id" |
| 28 | +} |
| 29 | +``` |
| 30 | + |
| 31 | +| Field | Type | Notes | |
| 32 | +|-------|------|-------| |
| 33 | +| `messages` | array, required | Full conversation history, oldest first. Max **100** messages; each `content` is truncated to **2,000** characters | |
| 34 | +| `messages[].role` | `"user" \| "assistant"` | Other roles are rejected | |
| 35 | +| `conversationId` | string, optional | Opaque id used only for [analytics](/deployment/worker/#analytics-with-d1-optional) correlation | |
| 36 | + |
| 37 | +### Response `200` |
| 38 | + |
| 39 | +```json |
| 40 | +{ |
| 41 | + "reply": "We're available Monday through Friday, 9am to 5pm.", |
| 42 | + "sources": [ |
| 43 | + { "url": "https://example.com/contact", "title": "Contact", "type": "page" } |
| 44 | + ] |
| 45 | +} |
| 46 | +``` |
| 47 | + |
| 48 | +`sources` is optional and reserved for retrieval-backed backends — the |
| 49 | +bundled worker returns only `reply` today (see [RAG](/rag/)). |
| 50 | + |
| 51 | +### Errors |
| 52 | + |
| 53 | +All errors share one envelope: |
| 54 | + |
| 55 | +```json |
| 56 | +{ "error": "Human-readable message", "code": "MACHINE_CODE", "limitType": "minute" } |
| 57 | +``` |
| 58 | + |
| 59 | +| Status | `code` | When | Extra | |
| 60 | +|--------|--------|------|-------| |
| 61 | +| `400` | `VALIDATION_ERROR` | Empty/missing `messages`, more than 100 messages, invalid role | | |
| 62 | +| `429` | `RATE_LIMITED` | Per-IP limit exceeded (default 10/min, 50/hr) | `Retry-After` header (seconds); `limitType`: `"minute"` or `"hour"` | |
| 63 | +| `500` | `CONFIG_ERROR` | Worker misconfiguration (e.g. bad API key) | | |
| 64 | +| `503` | `SERVICE_ERROR` | Claude temporarily unavailable/overloaded | | |
| 65 | +| `500` | `UNKNOWN_ERROR` | Anything else | | |
| 66 | + |
| 67 | +## GET /api/health |
| 68 | + |
| 69 | +```json |
| 70 | +{ "ok": true } |
| 71 | +``` |
| 72 | + |
| 73 | +Use for uptime checks; it does not call Claude. |
| 74 | + |
| 75 | +## Client retry behavior |
| 76 | + |
| 77 | +The widget's built-in API client retries up to 2 times (3 attempts total): |
| 78 | +`429` waits for the server's `Retry-After`; `503` backs off exponentially |
| 79 | +(1 s, then 3 s). Sends are debounced (300 ms default). If you build your own |
| 80 | +client, mirroring this behavior plays well with the worker's limits. |
0 commit comments