# REST API integration

> A practical walkthrough of building on the Bookbag REST API: authenticate, send a chat message, stream the reply, continue conversations, and read history.

This guide walks through a typical backend integration end to end. For the exhaustive parameter-by-parameter contracts, jump to the [API reference](/docs/api/overview); here we focus on the happy path and the decisions you will make.

## 1. Get an API key

Create a key in the dashboard (admin role) and store the `oc_...` value in your secret manager. Scope the key to a single agent if the integration only touches one. Full details in [Authentication](/docs/api/authentication).

> **WARNING:** Call the API from your server, never from the browser. A key grants workspace-level access.

## 2. Pick a version

- **[API v2](/docs/api/v2/overview)** — recommended for new integrations. Modern REST, AI-SDK streaming, cursor pagination, rate-limit headers, and machine error codes.
- **[API v1](/docs/api/v1/chat)** — use it when you need drop-in Chatbase compatibility (especially [contacts](/docs/api/v1/contacts-create)).

## 3. Send a message

A v2 chat request is a single `POST`. Set `stream: false` while you are getting started so you can work with a plain JSON response:

```bash
curl https://app.bookbag.ai/api/v2/agents/123/chat \
  -H "Authorization: Bearer $BOOKBAG_API_KEY" \
  -H "Content-Type: application/json" \
  -d '{ "message": "Do you ship to Canada?", "stream": false }'
```

## 4. Continue the conversation

The first reply returns a `conversationId` in its metadata. Pass it back on the next message to keep context. Optionally pass a `userId` to group all of one person's conversations so you can later list them per user.

```javascript
const first = await ask(123, "Do you ship to Canada?");
const second = await ask(123, "How long does it take?", first.conversationId);
console.log(second.text);
```

## 5. Stream for responsiveness

In a user-facing UI you usually want tokens as they arrive. Drop `stream: false` (streaming is the default) and parse the [v2 streaming format](/docs/api/v2/streaming) — bare `data:` lines of `text-delta` frames ending in `data: [DONE]`.

## 6. Read history & set feedback

List conversations and messages with cursor pagination, export everything for analytics, and record thumbs up/down. See [List conversations](/docs/api/v2/conversations) and the feedback action on [Chat](/docs/api/v2/chat).

## Handle errors and limits

- Branch on the `error.code`, not the message. The codes are stable; messages are not.
- Respect rate limits: 100 requests / 10s per key. Watch the `X-RateLimit-Remaining` header and back off on `429`.
- Retry `429` and `5xx` with exponential backoff; fix and do not retry `4xx`.

The full error envelope and the code table live in [Errors](/docs/api/errors).

- [API overview](/docs/api/overview) — Base URL, versions, and conventions.
- [Chat (v2)](/docs/api/v2/chat) — Full request/response contract.
- [Streaming format](/docs/api/v2/streaming) — Parse the token stream.
- [Errors](/docs/api/errors) — Codes, statuses, and rate limiting.
