API Overview
Everything you can do in the CloudPeek web app is backed by an HTTP API, and you can call that API directly from your own scripts, SOAR platform or integrations. This section is the developer reference. Start here, then read Authentication before calling any endpoint.
Base URL
All endpoints are served under the /api/v1 prefix. In a local/dev deployment the API listens on port 8000, so the base URL is:
http://localhost:8000/api/v1
In your deployment, replace the host with your CloudPeek API domain. Every path in this reference is shown including the /api/v1 prefix.
Request & response format
- Requests and responses are JSON (
Content-Type: application/json): except file uploads (multipart form data) and streaming endpoints (Server-Sent Events; see below). - Authenticate every request with a bearer token (see Authentication).
- Optionally scope a request to a specific tenant with the
X-Tenant-Idheader.
curl -s "http://localhost:8000/api/v1/health"
# → { "status": "ok", "timestamp": "..." }
GET /api/v1/health is public (no auth) and is the simplest way to check the API is reachable.
Interactive API docs (OpenAPI / Swagger)
Non-production deployments expose live, auto-generated documentation you can browse and try:
- Swagger UI:
GET /docs - OpenAPI spec (JSON):
GET /openapi.json
These are served at the root (not under /api/v1). They're the most up-to-date, exact reference for your specific deployment, this written reference covers the concepts and the common endpoints.
Pagination
List endpoints use limit and offset query parameters. Defaults and maximums vary by resource (for example incidents default to 50 with a max of 200; investigation actions default to 100 with a max of 500). Paginated lists return a wrapper with the total:
{ "incidents": [ /* … */ ], "total": 137, "offset": 0, "limit": 50 }
Some simpler lists return a bare JSON array. Where supported, sorting uses sort_by and sort_order (asc / desc).
Error format
Errors return a JSON envelope with an error message and an appropriate HTTP status:
{ "error": "Permission denied: requires incident:read" }
Validation failures include the offending fields:
{ "error": "Validation failed", "issues": [ { "path": "title", "message": "Required" } ] }
Rate-limited responses use { "detail": "Rate limit exceeded. Please try again later." }.
Status codes
| Code | Meaning |
|---|---|
| 200 | OK |
| 201 | Created (after a successful POST create) |
| 202 | Accepted (e.g. a webhook was queued) |
| 204 | No content (deletes, password change, logout) |
| 400 | Bad request / validation failed |
| 401 | Not authenticated (missing/invalid token) |
| 403 | Not authorised (missing permission or wrong tenant) |
| 404 | Not found |
| 409 | Conflict (e.g. duplicate) |
| 410 | Gone (e.g. legacy runbook endpoints: use the Wiki API) |
| 422 | Unprocessable (e.g. unsupported model, policy rejection) |
| 429 | Rate limited |
| 5xx | Server / upstream error |
Rate limiting
The API applies per-client rate limiting. When you exceed the limit you get a 429 with X-RateLimit-Limit, X-RateLimit-Remaining and Retry-After headers, honour Retry-After before retrying.
Conventions in this reference
- Paths include the
/api/v1prefix. - A path parameter is shown as
{name}. - "Permission" refers to the
resource:actionpermission the caller needs (see Authentication → Permissions). - Field names in request/response shapes are quoted exactly as the API uses them.
Endpoint map
| Resource | Reference |
|---|---|
| Auth, tenants, current user | Authentication |
| Incidents, comments, follow-ups | Incidents API |
| Investigations | Investigations API |
| AI responses (model calls, streaming) | AI Responses API |
| Tools & bundles | Tools API |
| Artifacts (files, semantic search) | Artifacts API |
| Wiki pages & sections | Wiki API |
| Runbooks (and migration to Wiki) | Runbooks API |
| Statistics & audit | Operations API |