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

# Quick Start - AR Agent

> Send your first invoice using the conversational AR Agent

The Dolfin AR Agent lets your users create customers, products, and invoices through natural language. Instead of calling individual endpoints, you send a single user message to `POST /agent/ar` and the agent handles the rest.

This guide walks through the same invoice flow as the [Quick Start](/guides/quick-start-ar), but driven entirely through the agent.

## Prerequisites

* A Dolfin **API key**
* An **organisation** already provisioned (see [Client Integration](/guides/client-integration))
* A valid **session token** or API key for authentication

<Note>
  All requests below require the `x-dolfin-api-key` and `x-dolfin-organisation-id` headers. See [Authentication](/guides/authentication) for details.
</Note>

## How the Agent Works

Every turn is a **single POST** to `/agent/ar` with just two body fields:

| Field            | Type             | Notes                                                                               |
| ---------------- | ---------------- | ----------------------------------------------------------------------------------- |
| `message`        | string, required | The user's message for this turn                                                    |
| `conversationId` | UUID, optional   | Omit on the first turn. Supply on every subsequent turn to continue the same thread |

You do not send the full message history — Dolfin persists the conversation server-side and the agent loads it automatically from `conversationId`.

### Response format

The response is a `text/event-stream` (SSE). Read events as they arrive:

| Event          | Payload                       | When                                                       |
| -------------- | ----------------------------- | ---------------------------------------------------------- |
| `conversation` | `{ "id": "uuid" }`            | Fired **once**, on the first turn only, before any content |
| *(unnamed)*    | `{ "content": "text chunk" }` | Streamed assistant text, one chunk per data frame          |
| `action`       | Tool action object            | When the agent runs a tool (e.g. created a customer)       |
| *(unnamed)*    | `{ "done": true }`            | Final frame — stream is complete                           |

On error, the final frame is `{ "error": "message", "done": true }`.

### Persisting `conversationId`

On the first request, **read the `conversation` SSE event** and save its `data.id`. Echo that UUID back as `conversationId` on every follow-up POST to continue the same conversation.

```javascript theme={null}
async function chat(message, conversationId) {
  const res = await fetch('https://api.dolfinai.co/agent/ar', {
    method: 'POST',
    headers: {
      'x-dolfin-api-key': 'dol_live_abc123',
      'x-dolfin-organisation-id': '9a658587-fe02-402e-b1ac-bfaf53274ef8',
      'Content-Type': 'application/json',
      'Accept': 'text/event-stream',
    },
    body: JSON.stringify(conversationId ? { message, conversationId } : { message }),
  });

  let newConversationId;
  let assistantText = '';

  // Parse SSE frames
  const reader = res.body.getReader();
  const decoder = new TextDecoder();
  let buffer = '';
  for (;;) {
    const { value, done } = await reader.read();
    if (done) break;
    buffer += decoder.decode(value, { stream: true });

    let frameEnd;
    while ((frameEnd = buffer.indexOf('\n\n')) !== -1) {
      const frame = buffer.slice(0, frameEnd);
      buffer = buffer.slice(frameEnd + 2);

      let eventName = 'message';
      let dataLine = '';
      for (const line of frame.split('\n')) {
        if (line.startsWith('event: ')) eventName = line.slice(7);
        else if (line.startsWith('data: ')) dataLine = line.slice(6);
      }
      if (!dataLine) continue;
      const data = JSON.parse(dataLine);

      if (eventName === 'conversation') newConversationId = data.id;
      else if (eventName === 'action') handleAction(data);
      else if (data.content) assistantText += data.content;
      else if (data.done) return { conversationId: newConversationId, assistantText };
    }
  }
}
```

<Note>
  Once the first response returns a `conversationId`, the agent type is **frozen** on that conversation. Sending a request to `POST /agent/ap` with an AR conversation's `conversationId` (or vice versa) returns `409 Conflict`.
</Note>

### Conversation scoping

Conversations are scoped by:

* **Organisation** — always. A conversation belongs to the organisation in `x-dolfin-organisation-id` and can't be read or continued from another organisation.
* **User** — only when the call is authenticated with a Bearer JWT. API-key calls have no user binding, so any caller with the same API key and organisation can continue an API-key conversation.

***

## Step 1: Create a Customer

This is the first turn, so **omit `conversationId`**. The response's `conversation` event gives you the ID to use for every subsequent turn.

<CodeGroup>
  ```bash cURL theme={null}
  curl -N -X POST https://api.dolfinai.co/agent/ar \
    -H "x-dolfin-api-key: dol_live_abc123" \
    -H "x-dolfin-organisation-id: 9a658587-fe02-402e-b1ac-bfaf53274ef8" \
    -H "Content-Type: application/json" \
    -H "Accept: text/event-stream" \
    -d '{
      "message": "can you help me create a customer?"
    }'
  ```

  ```javascript Node.js theme={null}
  const { conversationId, assistantText } = await chat(
    'can you help me create a customer?',
  );
  // Persist conversationId — you need it for every subsequent turn.
  ```
</CodeGroup>

**SSE stream (excerpt):**

```
event: conversation
data: {"id":"cf2d4a1e-7b39-4c82-a0d8-18a2b7c6d9e1"}

data: {"content":"I'd be happy to help"}

data: {"content":" you create a new customer!"}

data: {"content":" Please provide..."}

data: {"done":true}
```

The agent asks for details:

> I'd be happy to help you create a new customer! Please provide the following details:
>
> **Required:**
>
> * **Name** — The customer's full name or business name
>
> **Optional:**
>
> * **Email** address
> * **Phone** number
> * **Tax/VAT number**
> * **Address** (line 1, line 2, city, state/county, postal code, country)

Now continue the conversation by sending the **same `conversationId`** back:

<CodeGroup>
  ```bash cURL theme={null}
  curl -N -X POST https://api.dolfinai.co/agent/ar \
    -H "x-dolfin-api-key: dol_live_abc123" \
    -H "x-dolfin-organisation-id: 9a658587-fe02-402e-b1ac-bfaf53274ef8" \
    -H "Content-Type: application/json" \
    -H "Accept: text/event-stream" \
    -d '{
      "conversationId": "cf2d4a1e-7b39-4c82-a0d8-18a2b7c6d9e1",
      "message": "Joe Bloggs with email joebloggs@gmail.com"
    }'
  ```

  ```javascript Node.js theme={null}
  await chat('Joe Bloggs with email joebloggs@gmail.com', conversationId);
  ```
</CodeGroup>

The agent confirms before creating:

> Here's a summary of the customer I'll create:
>
> * **Name:** Joe Bloggs
> * **Email:** [joebloggs@gmail.com](mailto:joebloggs@gmail.com)
>
> Shall I go ahead and create this customer?

Confirm, and the agent runs the `createCustomer` tool and emits an `action` event:

```
event: action
data: {"type":"customer.created","customerId":"c3456789-abcd-ef01-2345-6789abcdef01", ...}

data: {"content":"Joe Bloggs has been created successfully!"}

data: {"done":true}
```

***

## Step 2: Create a Product

Same `conversationId`, next message.

<CodeGroup>
  ```bash cURL theme={null}
  curl -N -X POST https://api.dolfinai.co/agent/ar \
    -H "x-dolfin-api-key: dol_live_abc123" \
    -H "x-dolfin-organisation-id: 9a658587-fe02-402e-b1ac-bfaf53274ef8" \
    -H "Content-Type: application/json" \
    -H "Accept: text/event-stream" \
    -d '{
      "conversationId": "cf2d4a1e-7b39-4c82-a0d8-18a2b7c6d9e1",
      "message": "now create me a product called \"silver mirror\" of price 100 GBP"
    }'
  ```

  ```javascript Node.js theme={null}
  await chat(
    'now create me a product called "silver mirror" of price 100 GBP',
    conversationId,
  );
  ```
</CodeGroup>

The agent confirms the details:

> Here's a summary of the product I'll create:
>
> * **Name:** Silver Mirror
> * **Price:** £100.00 GBP
> * **Type:** Product
>
> Before I proceed, could you confirm:
>
> 1. Is the **type** correct as **Product** (rather than **Service**)?
> 2. Would you like to add a **description**?

After confirmation:

> The **Silver Mirror** product has been created successfully!

***

## Step 3: Create an Invoice

The agent remembers the customer and product from earlier in the conversation — you don't need to pass any IDs.

<CodeGroup>
  ```bash cURL theme={null}
  curl -N -X POST https://api.dolfinai.co/agent/ar \
    -H "x-dolfin-api-key: dol_live_abc123" \
    -H "x-dolfin-organisation-id: 9a658587-fe02-402e-b1ac-bfaf53274ef8" \
    -H "Content-Type: application/json" \
    -H "Accept: text/event-stream" \
    -d '{
      "conversationId": "cf2d4a1e-7b39-4c82-a0d8-18a2b7c6d9e1",
      "message": "create an invoice for Joe with 5x silver mirrors"
    }'
  ```

  ```javascript Node.js theme={null}
  await chat('create an invoice for Joe with 5x silver mirrors', conversationId);
  ```
</CodeGroup>

The agent looks up the customer and product, then confirms:

> Here's a summary of the invoice I'll create:
>
> * **Customer:** Joe Bloggs
> * **Product:** Silver Mirror x5
> * **Total:** £500.00 GBP
>
> Shall I go ahead and create this invoice?

After confirmation:

> The invoice has been created successfully!
>
> * **Invoice Number:** INV-92631974
> * **Customer:** Joe Bloggs
> * **Items:** Silver Mirror x5
> * **Total:** £500.00 GBP
> * **Status:** Draft
>
> Would you like me to send the invoice to Joe at [joebloggs@gmail.com](mailto:joebloggs@gmail.com)?

<Note>
  Because the conversation history is loaded server-side from `conversationId`, the agent resolves "Joe" and "silver mirrors" to the correct customer and product without you having to track IDs client-side.
</Note>

***

## Step 4: Send the Invoice

<CodeGroup>
  ```bash cURL theme={null}
  curl -N -X POST https://api.dolfinai.co/agent/ar \
    -H "x-dolfin-api-key: dol_live_abc123" \
    -H "x-dolfin-organisation-id: 9a658587-fe02-402e-b1ac-bfaf53274ef8" \
    -H "Content-Type: application/json" \
    -H "Accept: text/event-stream" \
    -d '{
      "conversationId": "cf2d4a1e-7b39-4c82-a0d8-18a2b7c6d9e1",
      "message": "Sure, lets send it!"
    }'
  ```

  ```javascript Node.js theme={null}
  await chat('Sure, lets send it!', conversationId);
  ```
</CodeGroup>

The agent sends the invoice and confirms:

> Invoice sent successfully!
>
> * **Invoice:** INV-92631974
> * **Sent to:** [joebloggs@gmail.com](mailto:joebloggs@gmail.com)
> * **Amount:** £500.00 GBP
> * **Due Date:** 14th May 2026

***

## Full Conversation Flow

Here's the complete exchange from start to finish:

| Turn | `conversationId` sent? | User message                                                              |
| ---- | ---------------------- | ------------------------------------------------------------------------- |
| 1    | No (first turn)        | "can you help me create a customer?"                                      |
| 2    | Yes                    | "Joe Bloggs with email [joebloggs@gmail.com](mailto:joebloggs@gmail.com)" |
| 3    | Yes                    | "now create me a product called "silver mirror" of price 100 GBP"         |
| 4    | Yes                    | "create an invoice for Joe with 5x silver mirrors"                        |
| 5    | Yes                    | "Sure, lets send it!"                                                     |

## Managing Conversations

| Endpoint                                 | Purpose                                |
| ---------------------------------------- | -------------------------------------- |
| `GET /agent/conversations?agentType=Ar`  | List the caller's AR conversations     |
| `GET /agent/conversations/{id}`          | Get metadata for a single conversation |
| `GET /agent/conversations/{id}/messages` | Paged message history                  |
| `PATCH /agent/conversations/{id}`        | Rename a conversation                  |
| `DELETE /agent/conversations/{id}`       | Delete a conversation and its messages |

## Agent vs Direct API

|                   | Direct API                           | AR Agent                                       |
| ----------------- | ------------------------------------ | ---------------------------------------------- |
| **Interface**     | Individual REST endpoints            | Conversational messages                        |
| **ID management** | You track and pass IDs between calls | Agent resolves names from conversation history |
| **Confirmation**  | Immediate execution                  | Agent confirms before acting                   |
| **Best for**      | Programmatic automation              | Interactive user experiences                   |

## Next Steps

<CardGroup cols={2}>
  <Card title="Quick Start (Direct API)" icon="bolt" href="/guides/quick-start-ar">
    See the same flow using direct API calls.
  </Card>

  <Card title="API Reference" icon="code" href="/api-reference/introduction">
    Explore the full API reference for all endpoints.
  </Card>
</CardGroup>
