# Public API Reference

## Authentication

FLORA uses **Clerk API keys** for authentication. Every request must include a valid API key in the `Authorization` header:

```
Authorization: Bearer sk_live_XXXX
```

Each API key is scoped to a single workspace. The key determines which workspace's credits and techniques are accessible.

**Error responses for auth failures:**

| Scenario                         | HTTP Status | Error Code        |
| -------------------------------- | ----------- | ----------------- |
| Missing/malformed key            | 401         | `unauthorized`    |
| Invalid or revoked key           | 401         | `invalid_api_key` |
| Key not authorized for workspace | 403         | `forbidden`       |

***

## Endpoints

### POST `/api/v1/techniques/{slug}/runs`

Creates and starts a new technique run.

**Path parameters:**

* `slug` (string) - The technique's URL slug (e.g., `"portrait-enhancer"`)

**Request body (JSON):**

```json
{
  "inputs": [
    {
      "id": "input_image",
      "type": "IMAGE_URL",
      "value": "https://example.com/photo.jpg"
    }
  ],
  "mode": "async",
  "callback_url": "https://your-server.com/webhook",
  "idempotency_key": "unique-request-id-123"
}
```

| Field             | Type   | Required | Description                                                            |
| ----------------- | ------ | -------- | ---------------------------------------------------------------------- |
| `inputs`          | array  | Yes      | Ordered array matching the technique's input schema                    |
| `inputs[].id`     | string | Yes      | Input identifier (must match technique definition)                     |
| `inputs[].type`   | string | Yes      | One of: `IMAGE_URL`, `VIDEO_URL`, `TEXT`                               |
| `inputs[].value`  | string | Yes      | The input value (URL or text content)                                  |
| `mode`            | string | Yes      | `"async"` (poll for results) or `"stream"` (not yet implemented)       |
| `callback_url`    | string | No       | Webhook URL for completion notification (stored but not yet delivered) |
| `idempotency_key` | string | No       | Prevents duplicate runs for the same request                           |

**Success response (200):**

```json
{
  "runId": "j57abc...",
  "createdAt": 1710000000000,
  "status": "pending",
  "pollUrl": "/api/v1/techniques/{slug}/runs/{runId}"
}
```

**Idempotency:** If a request with the same `idempotency_key` already exists, returns the existing run's current state (status, progress, outputs if complete) instead of creating a new one.

**Error responses:**

| HTTP Status | Error Code               | Cause                                                             |
| ----------- | ------------------------ | ----------------------------------------------------------------- |
| 400         | `input_validation_error` | Wrong number of inputs, mismatched IDs, or wrong types            |
| 400         | `invalid_json`           | Malformed request body                                            |
| 402         | `insufficient_credits`   | Not enough credits (response includes `required` and `available`) |
| 404         | `not_found`              | Technique slug doesn't exist                                      |

***

### GET `/api/v1/techniques/{slug}/runs/{runId}`

Polls the status of an existing run.

**Path parameters:**

* `slug` (string) - The technique's URL slug
* `runId` (string) - The run ID returned from the POST endpoint

**Success response (200):**

```json
{
  "runId": "j57abc...",
  "status": "completed",
  "progress": 100,
  "createdAt": 1710000000000,
  "startedAt": 1710000001000,
  "completedAt": 1710000030000,
  "chargedCost": 5,
  "outputs": [
    {
      "outputId": "output_image",
      "type": "IMAGE_URL",
      "url": "https://ik.imagekit.io/flora/..."
    }
  ]
}
```

**Run status lifecycle:** `pending` -> `running` -> `completed` | `failed`

For failed runs, the response includes `errorCode` and optionally `errorMessage`.

**Error responses:**

| HTTP Status | Error Code  | Cause                                                 |
| ----------- | ----------- | ----------------------------------------------------- |
| 404         | `not_found` | Run doesn't exist or belongs to a different workspace |

***

## Error Response Shape

All errors follow a consistent format:

```json
{
  "error": {
    "code": "insufficient_credits",
    "message": "Not enough credits. Required: 5, available: 2"
  }
}
```

## Complete Error Code Reference

| Code                     | HTTP Status | Description                                     |
| ------------------------ | ----------- | ----------------------------------------------- |
| `unauthorized`           | 401         | Missing or malformed authorization header       |
| `invalid_api_key`        | 401         | API key is invalid or revoked                   |
| `forbidden`              | 403         | API key not authorized for the target workspace |
| `invalid_json`           | 400         | Request body is not valid JSON                  |
| `input_validation_error` | 400         | Inputs don't match technique schema             |
| `not_found`              | 404         | Technique or run not found                      |
| `insufficient_credits`   | 402         | Workspace doesn't have enough credits           |


---

# Agent Instructions: Querying This Documentation

If you need additional information that is not directly available in this page, you can query the documentation dynamically by asking a question.

Perform an HTTP GET request on the current page URL with the `ask` query parameter:

```
GET https://docs.flora.ai/more/flora-public-api-reference.md?ask=<question>
```

The question should be specific, self-contained, and written in natural language.
The response will contain a direct answer to the question and relevant excerpts and sources from the documentation.

Use this mechanism when the answer is not explicitly present in the current page, you need clarification or additional context, or you want to retrieve related documentation sections.
