# Introduction

> Your first request, IDs, lists, errors and retries.

Source: https://www.onlucra.com/docs/api-introduction

One REST API runs everything in Lucra, and the Lucra app is built on it. Call it from your server with the [SDK](https://www.onlucra.com/docs/sdk) or plain HTTP, or connect an AI assistant over [MCP](https://www.onlucra.com/docs/mcp).

## Your first request

Create a key in **Settings → Developers → API**, then call `GET /v1/account` to see the account it belongs to:

```bash
curl https://api.onlucra.com/v1/account \
  -H "Authorization: Bearer $LUCRA_API_KEY" \
  -H "Lucra-Version: 2026-10-01"
```

Every request sends two headers:

- `Authorization: Bearer …` with an API key or an OAuth access token. See [Authentication](https://www.onlucra.com/docs/authentication).
- `Lucra-Version`, so your integration keeps working as the API changes. The SDK sends it for you.

The same call with the SDK:

```ts
import { Lucra } from "@lucra/sdk"

const lucra = new Lucra(process.env.LUCRA_API_KEY!)
const { data: account } = await lucra.account.retrieve()
```

## IDs

Every ID starts with a prefix naming its resource, like `prog_00lhuAJjQgdtNt5WnqTBc95` for a program. Treat the rest as opaque.

| Prefix | Resource |
| --- | --- |
| `acct_` | account |
| `ad_` | ad |
| `adauth_` | ad authorization |
| `adset_` | ad set |
| `adtpl_` | ad template |
| `agac_` | agreement acceptance |
| `agr_` | agreement |
| `appl_` | application |
| `camp_` | campaign |
| `conn_` | connection |
| `conv_` | conversion |
| `crtr_` | creator |
| `emb_` | embed |
| `ern_` | earning |
| `evt_` | webhook event |
| `file_` | file |
| `key_` | key |
| `msg_` | message |
| `pay_` | payment |
| `post_` | post |
| `pout_` | payout |
| `prod_` | product |
| `prog_` | program |
| `pxev_` | pixel event |
| `pxl_` | pixel |
| `ret_` | retainer |
| `smpl_` | sample |
| `sub_` | submission |
| `thr_` | thread |
| `txn_` | transaction |
| `wdr_` | withdrawal |

## Objects

```json
{
  "id": "prog_00lhuAJjQgdtNt5WnqTBc95",
  "name": "Spring launch",
  "status": "open",
  "version": 3,
  "createdAt": "2026-10-01T15:04:05.000Z"
}
```

- A reference to another object is its bare ID, in a field named for it: `program`, `creator`, `account`.
- Money is an integer number of cents, next to a `currency`. Rates are percents.
- Times are UTC ISO 8601, in fields ending in `At`.
- Enums can gain values, so handle ones you don't recognize.

## Lists

A list returns `data` and a `nextCursor`. Pass that cursor back as `cursor` to get the next page; it's `null` on the last one. `limit` sets the page size (default 25, up to 100).

```json
{ "data": [{ "id": "prog_00lhuAJjQgdtNt5WnqTBc95" }], "nextCursor": "eyJpZCI6…" }
```

Filter by a field's name, with commas for several values, like `status=pending,approved`. Every list also takes `createdAfter` and `createdBefore`. The SDK's [`paginate`](https://www.onlucra.com/docs/sdk#every-page) walks every page for you.

Most objects aren't deleted. Set their `status` to `archived` instead; lists leave archived objects out unless you filter for them.

## Updates

`PATCH` changes only the fields you send. To make sure nobody changed the object since you read it, send its `version`; if it's stale you get `409 version_conflict`, and you read it again.

## Idempotency

Send an `Idempotency-Key` header on a write you might retry. A retry with the same key returns the first response instead of writing twice. Writes that move money require one: payments, retainer offers and withdrawals.

## Errors

A failed request returns a problem with a stable `code` to branch on, a readable `detail`, and a `fix` when there's a clear next step:

```json
{
  "status": 422,
  "code": "invalid_request",
  "detail": "type: expected one of \"organic\"|\"paid_ads\"",
  "fix": "Fix `type` in the request body.",
  "retryable": false,
  "errors": [{ "field": "type", "message": "Expected one of \"organic\"|\"paid_ads\"" }]
}
```

| Status | Means                                                              |
| ------ | ------------------------------------------------------------------ |
| 401    | Missing, invalid or expired key or token                           |
| 403    | The key can't do this, or can't reach that account                 |
| 404    | Not found, or not visible to this key                              |
| 409    | A conflict, or a setup step left first (`requirement_…` codes)     |
| 422    | Invalid request; its errors array lists every bad field            |
| 429    | Rate limited; wait `Retry-After` seconds                           |

`retryable` says whether sending the same request again can succeed. Every problem also has a `requestId`; include it when you contact support.

## OpenAPI

The full OpenAPI document is at `https://api.onlucra.com/v1/openapi.json`. Every endpoint, with its fields, is in [All endpoints](https://www.onlucra.com/docs/api-reference).
