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

# API overview

> Authentication, rate limits, response format, and error handling for the ORCA API.

## Base URL

```bash theme={null}
https://orca-klavest.app/api/v1
```

## Authentication

ORCA uses two authentication methods depending on the context:

<Tabs>
  <Tab title="JWT tokens (dashboard)">
    Dashboard and frontend requests use JWT bearer tokens:

    ```bash theme={null}
    curl -H "Authorization: Bearer eyJ..." \
      https://orca-klavest.app/api/v1/files
    ```

    Get a token by logging in:

    ```bash theme={null}
    curl -X POST https://orca-klavest.app/api/v1/auth/login \
      -H "Content-Type: application/json" \
      -d '{"email": "you@company.com", "password": "your-password"}'
    ```

    Response:

    ```json theme={null}
    {
      "data": {
        "access_token": "eyJ...",
        "refresh_token": "abc...",
        "token_type": "bearer"
      }
    }
    ```

    If 2FA is enabled, the login response includes `requires_2fa: true` and a `temp_token`. Complete authentication with:

    ```bash theme={null}
    curl -X POST https://orca-klavest.app/api/v1/auth/totp/complete \
      -H "Content-Type: application/json" \
      -d '{"temp_token": "...", "code": "123456"}'
    ```
  </Tab>

  <Tab title="API keys (integrations)">
    For programmatic access and CI/CD integrations, use API keys. Create them in **Settings > API Keys** (admin only, max 10 per org).

    ```bash theme={null}
    curl -H "Authorization: Bearer orca_live_your_api_key_here" \
      https://orca-klavest.app/api/v1/public/health
    ```

    API keys use hierarchical permission scopes:

    | Scope     | Permissions                                             |
    | --------- | ------------------------------------------------------- |
    | **read**  | View results, alerts, and metadata                      |
    | **scan**  | Trigger scans and upload files (includes read)          |
    | **write** | Manage contracts and configurations (includes scan)     |
    | **admin** | Full API access including org settings (includes write) |
  </Tab>
</Tabs>

## Response format

All endpoints return a consistent envelope:

```json theme={null}
{
  "data": { ... },
  "error": null,
  "meta": {}
}
```

On error:

```json theme={null}
{
  "data": null,
  "error": {
    "code": "insufficient_scope",
    "message": "This endpoint requires the 'scan' scope."
  },
  "meta": {}
}
```

## Error codes

| HTTP status | Code                 | Description                                      |
| ----------- | -------------------- | ------------------------------------------------ |
| 400         | `bad_request`        | Invalid or missing request parameters            |
| 401         | `unauthorized`       | Missing or invalid token / API key               |
| 403         | `insufficient_scope` | API key lacks the required scope                 |
| 404         | `not_found`          | Resource doesn't exist or belongs to another org |
| 429         | `rate_limited`       | Too many requests, retry after cooldown          |
| 500         | `internal_error`     | Unexpected server error                          |

## Rate limits

| Endpoint category      | Limit                                     |
| ---------------------- | ----------------------------------------- |
| Authentication         | Strict per-IP (prevents brute-force)      |
| File uploads / prescan | 30/min per-user                           |
| Job creation / start   | 20/hour                                   |
| Billing (add credits)  | 10/hour                                   |
| Chat queries           | Per-user limiting                         |
| General API            | Standard per-user limiting                |
| WebSocket              | 30 connections/min per IP, 10-min timeout |

<Note>
  Every response includes rate limit headers:

  ```text theme={null}
  X-RateLimit-Limit: 60
  X-RateLimit-Remaining: 58
  X-RateLimit-Reset: 1700000060
  ```

  When rate-limited, you'll receive a `429` response. Wait and retry with exponential backoff.
</Note>

## Pagination

List endpoints support pagination via query parameters:

```bash theme={null}
GET /api/v1/files?limit=20&offset=0
```

| Parameter | Default | Max | Description               |
| --------- | ------- | --- | ------------------------- |
| `limit`   | 20      | 200 | Number of items to return |
| `offset`  | 0       | -   | Number of items to skip   |

## Organisation scoping

All data is scoped to your organisation. The `org_id` is derived from your JWT token — you cannot access resources belonging to other organisations. This is enforced at the database query level on every endpoint.

## WebSocket

Real-time job progress is available via WebSocket:

```text theme={null}
wss://orca-klavest.app/ws/jobs/{job_id}/progress
```

Requires JWT authentication. Messages include processing stage, percentage, and per-file status updates. Falls back to HTTP polling if WebSocket is unavailable.
