# Getting started

Make a key, call the API, and learn the five rules that differ from most APIs.

Source: https://docs.leadarc.io/getting-started.html

## 1. Make a key

In the app: **Settings, Developers, API keys, Create key**. You pick three things:

- **Workspaces.** A key never reaches further than the person who made it.
- **Scopes.** Start from a preset, then trim. See [Scopes](scopes.html).
- **Expiry.** 365 days is a good default.

The secret is shown once. It is hashed, so nobody can read it back. Lost it? Make a new key, move the integration, revoke the old one.

### What a key looks like

```text
lak_live_k7m2p9qh_9fK2mQ7pL4vX8nT3bY6cZ1sD5fG0jH2k
│   │    │        └ the secret, 32 characters. Hashed on write and never stored
│   │    └ public lookup handle, 8 characters. Safe to log
│   └ environment. test keys are reserved and rejected in v1
└ fixed prefix, so one secret-scanner rule matches every key
```

Treat the whole string as the secret. Keep it in a secret manager.

## 2. Your first request

Call `/v1/me` first. It tells you what the key can reach right now.

```bash
curl -sS https://api.leadarc.io/v1/me -H "Authorization: Bearer $LEADARC_API_KEY"
```

```json
{
  "object": "me",
  "key": {
    "id": "k7m2p9qh",
    "name": "Claude inbox agent",
    "all_workspaces": false
  },
  "owner": {
    "email": "leon@leadarc.io",
    "role": "admin"
  },
  "scopes": [
    "leads:read",
    "leads:write",
    "notes:write",
    "tasks:read",
    "workspaces:read"
  ],
  "scopes_withheld": [],
  "workspaces": [
    {
      "object": "workspace",
      "slug": "airpay",
      "name": "AirPay"
    },
    {
      "object": "workspace",
      "slug": "cliniconex",
      "name": "Cliniconex"
    }
  ]
}
```

> **Check scopes_withheld before you debug a 403.**
>
> It lists scopes the key holds but its owner's role no longer allows. A key shrinks the moment its owner is demoted or offboarded.

## 3. Ask what the API accepts

`GET /v1/capabilities` needs no scope. It returns the live enum values, filters, limits and error codes. Fetch it at startup instead of hardcoding them.

```bash
curl -sS https://api.leadarc.io/v1/capabilities -H "Authorization: Bearer $LEADARC_API_KEY"
```

## 4. A real job

Get interested leads nobody has handled, read one conversation, leave a note.

```bash
WS=airpay
AUTH="Authorization: Bearer $LEADARC_API_KEY"

# leads a human has not handled yet
curl -sS "https://api.leadarc.io/v1/workspaces/$WS/leads?status=interested&responded=false&limit=25" -H "$AUTH"

# the full conversation for one of them
curl -sS "https://api.leadarc.io/v1/workspaces/$WS/leads/lead_2k8fq3a91c4e/messages" -H "$AUTH"

# leave a note for the rep who picks it up
curl -sS "https://api.leadarc.io/v1/workspaces/$WS/notes" -X POST -H "$AUTH" \
  -H "Content-Type: application/json" \
  -d '{"lead_id":"lead_2k8fq3a91c4e","body":"Wants a walkthrough before their board meeting."}'
```

## Scope presets

Three starting points in the create dialog. No preset grants everything.

| Preset | For | Scopes |
| --- | --- | --- |

## Five rules

1. **Ids are opaque.** Never parse, sort or build one. A task id cannot be used as a lead id.
2. **A wrong query parameter is a `400`.** The error names the parameter. Nothing is ignored.
3. **Page with the [`cursor`](pagination.html#cursors) we return.** Never an offset. See [Pagination](pagination.html).
4. **Read `effects` on every write.** Some writes also close other people's tasks.
5. **Accept unknown enum values on read.** New status values can appear. Only writes are strict.

---

Base URL `https://api.leadarc.io/v1`. Generated from the API source.
