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

# API Reference

> REST API reference - the surface both SDKs wrap.

This page lists the customer-facing REST API. For internal admin endpoints, see the platform's `MIGRATION_RUNBOOK.md`. The MCP server (`@rayify-ai/mcp`) is a higher-level slim-8 surface layered over these endpoints.

> **Auto-generated OpenAPI:** a full `openapi.json` will be generated from the platform backend once the v2 spec stabilizes. Until then, this page lists the customer-facing endpoints by hand.

## Base URL

```
https://rayify.ai/api
```

Override with `RAYIFY_API_URL` for self-hosted / staging.

## Authentication

All endpoints require a Bearer token:

```http theme={null}
Authorization: Bearer sk_your_key
```

Provision keys via Settings → API Keys on [rayify.ai](https://rayify.ai). Per-user keys are recommended - actions are recorded under the key's owner in the audit log.

## Projects

### List projects

```http theme={null}
GET /api/projects
```

Query params: `status` (`active` / `completed` / `archived`), `kind` (`research` / `survey` / `audience` / `simulation`), `limit` (default 50, max 200).

### Get a project

```http theme={null}
GET /api/projects/:id
```

Returns the full project state: questions, agent reasonings, DecisionPacket, status. Use this when you need to drag full context into your AI client.

### Get project status (lightweight)

```http theme={null}
GET /api/projects/:id/status
```

Returns `{ id, status, last_updated_at, question_count, reasoning_count }`. Use this for polling without the body weight of full state.

### Create a research project

```http theme={null}
POST /api/projects/research
Content-Type: application/json

{
  "brief": "...",
  "audience": "fo_principal" | "vc_partner" | "corp_strategist" | null
}
```

The brief should be 50-2000 chars. `audience` tunes the Reasoning fleet's specialist composition.

### Create a survey

```http theme={null}
POST /api/projects/survey
Content-Type: application/json

{
  "title": "...",
  "questions": ["...", "...", "..."]
}
```

`questions` accepts string arrays only. For richer question types (matrix / likert / star\_rating), use the web app.

## Questions

### Add a question

```http theme={null}
POST /api/projects/:id/questions
Content-Type: application/json

{
  "text": "...",
  "kind": "binary" | "multi" | "matrix" | "likert" | "star_rating",
  "resolution_signal": "press_release" | "founder_email" | "filing" | ...,
  "resolution_date": "2026-09-30",
  "resolution_threshold": "..."
}
```

CP1 (Defender checkpoint 1) validates the question shape at submit time per the framing-rules registry. Invalid shapes return `400` with a structured error.

## Sources

### Attach a source

```http theme={null}
POST /api/projects/:id/sources
Content-Type: application/json

{
  "uri": "https://example.com/article",
  "title": "..."
}
```

Sources are pulled into the project's evidence pack and made available to the Reasoning fleet.

## Findings

### Search findings

```http theme={null}
GET /api/findings/search?q=...&limit=10
```

Semantic search across the workspace's project corpus. Returns ranked findings with citation provenance.

## Error responses

All endpoints return JSON errors:

```json theme={null}
{
  "error": {
    "code": "validation_error",
    "message": "Question text must be at least 10 characters",
    "field": "text"
  }
}
```

Status codes:

* `400` - validation error
* `401` - missing / invalid API key
* `403` - insufficient permissions (admin route, wrong workspace)
* `404` - resource not found
* `429` - rate limited
* `500` - platform error (report to [support@rayify.ai](mailto:support@rayify.ai))

## Rate limits

Default: 100 requests/minute per API key. Enterprise tier raises this. `429` responses include a `Retry-After` header.

## Webhooks

Webhook configuration lives on the web app: Settings → Webhooks. Subscribed events include `project.created` / `project.completed` / `decision_packet.published`. Payloads are signed with HMAC-SHA256; verify against the secret you provisioned at subscription time.

## What's next

* [SDK Setup](/sdk-setup) - Python + TypeScript wrappers over this API
* [MCP Setup](/mcp-setup) - slim-8 surface for AI clients
