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

# API Integration

## Server-side API

The ScentBot API allows you to integrate conversational fragrance recommendations into your own chat interface. Instead of embedding the [widget](/scentbot/installation), your backend communicates directly with ScentBot, giving you full control over the UI while ScentBot handles the AI conversation.

The API is stateful — each conversation is tracked through a session ID that you generate and manage.

## Authentication

All requests require a Bearer token in the `Authorization` header:

```
Authorization: Bearer YOUR_API_KEY
```

<Note>
  The API key is provided by the ScentXP team. Contact your account manager to obtain one.
</Note>

## Base URL

All endpoints are relative to the ScentBot API base URL provided during onboarding.

***

## Endpoints

### Initialize a session

Creates a new conversation session. Call this before sending any user messages.

```
POST /v1/bootstrap
```

**Headers**

```
Authorization: Bearer YOUR_API_KEY
```

**Request body**

```json theme={null}
{
  "session_id": "abc123",
  "language": "en",
  "public_key": "YOUR_PUBLIC_KEY"
}
```

| Field        | Type     | Description                                                             |
| ------------ | -------- | ----------------------------------------------------------------------- |
| `session_id` | `string` | Alphanumeric session ID. Generated and stored by your application.      |
| `language`   | `string` | ISO 639-1 language code (e.g., `en`, `fr`, `es`).                       |
| `public_key` | `string` | Public key provided by ScentXP. Scopes recommendations to your catalog. |

**Response (200)**

```json theme={null}
{
  "message": "Welcome! I'm here to help you explore the world of perfumes."
}
```

The `message` field contains the welcome text to display to the user. The session is now active and ready to receive messages.

***

### Send a user message

Sends the user's input to ScentBot and returns the assistant's response with optional perfume recommendations and interactive elements.

```
POST /v1/recommend
```

**Headers**

```
Authorization: Bearer YOUR_API_KEY
```

**Request body**

```json theme={null}
{
  "session_id": "abc123",
  "language": "en",
  "user_input": "I'm looking for a fresh lemon fragrance"
}
```

| Field        | Type     | Description                                  |
| ------------ | -------- | -------------------------------------------- |
| `session_id` | `string` | The same session ID used in `/v1/bootstrap`. |
| `language`   | `string` | ISO 639-1 language code.                     |
| `user_input` | `string` | The user's message text.                     |

**Response (200)**

The response contains the assistant's `message` and an optional `metadata` array with interactive elements and perfume data.

```json theme={null}
{
  "message": "Here are some fragrances with lemon notes:\n\n<parfum\n  id=\"6428\"\n  why=\"A citrusy fragrance with bright lemon notes.\"\n  use_case=\"default\"\n/>\n\n<parfum\n  id=\"6404\"\n  why=\"A unisex blend with zesty lemon and floral balance.\"\n  use_case=\"default\"\n/>\n\nWould you like me to refine this search?",
  "metadata": [...]
}
```

ScentBot maintains conversation context through the `session_id`. Each subsequent call builds on previous messages, allowing follow-up questions and refinements.

***

## Parsing the response

### Perfume recommendations in the message

When ScentBot recommends fragrances, it embeds `<parfum />` XML tags inline in the `message` string. This allows you to render perfume cards at the correct position within the conversation text.

Each `<parfum />` tag contains:

| Attribute  | Description                                     |
| ---------- | ----------------------------------------------- |
| `id`       | WikiParfum fragrance ID                         |
| `why`      | Explanation for the recommendation              |
| `use_case` | Context of the recommendation (e.g., `default`) |

Parse the message to extract these tags and render them as product cards in your UI, preserving their position relative to the surrounding text.

### Product mapping via metadata

To map recommended fragrances to products in your catalog, look for metadata entries with `type: "tool_response"` and a result of type `OutputParfumSearch`. This contains the EAN codes for each fragrance:

```json theme={null}
{
  "content": {
    "errors": [],
    "result": {
      "items": [
        {
          "properties": {
            "eans": ["8411061000001", "8411061000002"],
            "gender": "F",
            "id": "6428",
            "name": "CH L'Eau"
          },
          "type": "Parfum"
        }
      ],
      "pagination": {
        "page": 1,
        "per_page": 3,
        "total": 3,
        "total_pages": 3
      },
      "type": "OutputParfumSearch"
    },
    "suggestions": [],
    "warnings": []
  },
  "name": "UsecaseSearchByIngredient",
  "type": "tool_response"
}
```

Each item in `items` provides:

| Field               | Type       | Description                                                     |
| ------------------- | ---------- | --------------------------------------------------------------- |
| `properties.id`     | `string`   | WikiParfum fragrance ID (matches the `id` in `<parfum />` tags) |
| `properties.name`   | `string`   | Fragrance name                                                  |
| `properties.gender` | `string`   | Gender code: `M` (masculine), `F` (feminine), `U` (unisex)      |
| `properties.eans`   | `string[]` | EAN (barcode) codes associated with the fragrance               |
| `pagination`        | `object`   | Pagination info (`page`, `per_page`, `total`, `total_pages`)    |

Use the `eans` array to look up the product in your own catalog and link to the corresponding product page.

***

## Interactive elements

The `metadata` array may contain interactive elements that ScentBot uses to guide the conversation. These have `type: "tool_interactable"` and contain a `content` array of action items.

### Buttons

Displayed when ScentBot needs the user to make a choice (e.g., gender preference):

```json theme={null}
{
  "content": [
    { "action_id": "fd612a32...", "label": "Masculine", "type": "button" },
    { "action_id": "19a50cc7...", "label": "Feminine", "type": "button" },
    { "action_id": "6acb4398...", "label": "Unisex", "type": "button" },
    { "action_id": "f0be74bc...", "label": "No preference", "type": "button" }
  ],
  "header": "",
  "type": "tool_interactable"
}
```

### Family selection

Displayed when ScentBot asks the user to pick a fragrance family:

```json theme={null}
{
  "content": [
    { "action_id": "c42de8b6...", "id": "1", "label": "Citrus", "type": "family" },
    { "action_id": "3d8379e8...", "id": "5", "label": "Aromatic Fougere", "type": "family" },
    { "action_id": "634cdcec...", "id": "6", "label": "Floral", "type": "family" },
    { "action_id": "e3bd6d98...", "id": "10", "label": "Woody", "type": "family" },
    { "action_id": "29fed0c7...", "id": "8", "label": "Chypre", "type": "family" },
    { "action_id": "d7e5d1f8...", "id": "9", "label": "Oriental", "type": "family" },
    { "action_id": "3c339b53...", "id": "12", "label": "Leather", "type": "family" }
  ],
  "header": "",
  "type": "tool_interactable"
}
```

### Ending options

Displayed at the end of a recommendation flow:

```json theme={null}
{
  "content": [
    { "action_id": "d0e895da...", "id": "ending_1", "label": "I have more questions", "type": "ending" },
    { "action_id": "9ac7ef80...", "id": "ending_2", "label": "No, thank you", "type": "ending" }
  ],
  "header": "",
  "type": "tool_interactable"
}
```

When the user selects an interactive element, send the `label` text as the `user_input` in the next `/v1/recommend` call to continue the conversation.

### Interactive element fields

| Field       | Type     | Description                                                  |
| ----------- | -------- | ------------------------------------------------------------ |
| `action_id` | `string` | Unique identifier for the action                             |
| `label`     | `string` | Display text for the button                                  |
| `type`      | `string` | Element type: `button`, `family`, or `ending`                |
| `id`        | `string` | Optional identifier (present on `family` and `ending` types) |

***

## Integration flow

A typical integration follows this sequence:

<Steps>
  <Step title="Generate a session ID">
    Create a unique alphanumeric session ID for each user conversation. Store it on your server.
  </Step>

  <Step title="Initialize the session">
    Call `POST /v1/bootstrap` with the session ID, language, and public key. Display the returned welcome message.
  </Step>

  <Step title="Send user messages">
    Each time the user types a message or selects an interactive element, call `POST /v1/recommend` with the same session ID.
  </Step>

  <Step title="Render the response">
    Parse the `message` for `<parfum />` tags and render product cards inline. Display any interactive elements from `metadata` as buttons.
  </Step>

  <Step title="Map products to your catalog">
    Use the `OutputParfumSearch` metadata to map fragrance IDs to EAN codes, then look up the corresponding products in your catalog.
  </Step>
</Steps>

## Next steps

<CardGroup cols={2}>
  <Card title="Capabilities" icon="wand-magic-sparkles" href="/scentbot/capabilities">
    What ScentBot can do — search types, image search, multi-language.
  </Card>

  <Card title="Catalog Integration" icon="table" href="/catalog-integration/product-feed">
    Set up the Product Feed that scopes ScentBot recommendations.
  </Card>
</CardGroup>
