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

# Tools

> Reference for all tools available in the Subtotal Connector.

The Subtotal Connector provides tools for exploring and querying your purchase data, reading a connection's history, and configuring the retailers available for linking.

## ask

Ask a natural language question about your purchase data. The server translates it into SQL and returns the results — no SQL knowledge required.

**Parameters:**

| Name | Type | Required | Description |
| :- | :- | :- | :- |
| `question` | string | Yes | A natural language question about your purchase data |

**Example questions:**

* "Show me the top 5 retailers by purchase count this year"
* "How many active connections do I have?"
* "What are my highest-value purchases from the last 30 days?"
* "Which brands appear most frequently in my items?"

**Response format:**

```json theme={null}
{
  "fields": ["name", "purchase_count"],
  "results": [
    ["Amazon", 1523],
    ["Target", 892],
    ["Walmart", 641]
  ],
  "result_count": 3
}
```

**Constraints:**

* Questions must be plain English — embedded SQL will be rejected
* Only `SELECT` queries are generated — your data is never modified
* Results are limited to 100 rows and 5 MB
* A 5-second execution timeout is enforced

<Warning>
  If the question cannot be answered with the available data, or the generated query fails, the response will contain an `error` field:

  ```json theme={null}
  {
    "error": "This question cannot be answered with the available data."
  }
  ```

  Other possible errors include request timeouts and response size limits.
</Warning>

<Note>
  `ask` uses an AI model to translate your question into SQL. For best results, be specific about the data you want, time ranges, and how results should be grouped or sorted. To inspect the data model itself (entities, fields, relationships), use `get_data_model` instead.
</Note>

## get\_connection\_activity

Get a connection's whole activity log, newest first: when it was created and activated, when it became unauthenticated or was disconnected, and when its customer ID, email or mobile changed. Each entry says who made the change. Pass a `connection_id` from an `ask` result, for example after asking "Which of my connections became unauthenticated this week?".

**Parameters:**

| Name | Type | Required | Description |
| :- | :- | :- | :- |
| `connection_id` | string | Yes | The connection to read. |

**Response format:**

```json theme={null}
{
  "connection_id": "01J51S0JYV6N7K1030CV1ZKSCA",
  "activity": [
    {
      "timestamp": "2026-10-14T17:02:11Z",
      "event_source": "Retailer",
      "event": "connection_unauthenticated",
      "details": "Connection unauthenticated.",
      "source_id_type": null,
      "source_id_name": null,
      "connection_before": {
        "connection_id": "01J51S0JYV6N7K1030CV1ZKSCA",
        "customer_id": "8a46e581-48ba-498a-9ad0-2ee72582e1af",
        "retailer_id": "walmart",
        "status": "active",
        "email": null,
        "mobile": null
      },
      "connection_after": {
        "connection_id": "01J51S0JYV6N7K1030CV1ZKSCA",
        "customer_id": "8a46e581-48ba-498a-9ad0-2ee72582e1af",
        "retailer_id": "walmart",
        "status": "unauthenticated",
        "email": null,
        "mobile": null
      }
    }
  ]
}
```

**Fields:**

| Field | Description |
| :- | :- |
| `event` | What happened: `connection_created`, `connection_activated`, `connection_unauthenticated`, `connection_disconnected`, `customer_id_updated`, `email_updated`, or `mobile_updated`. |
| `event_source` | Who made the change: `API`, `Dashboard`, `Retailer`, `System`, or `Consumer`. |
| `source_id_name` | For `API` changes, the name of the API key that made them. For `System` backfills, where the data came from. For a consumer disconnecting their own connection, `Subtotal`. Otherwise `null`. |
| `connection_before` / `connection_after` | The connection's state before and after the change. `email` and `mobile` are always `null` here; use the API for contact details. |

<Note>
  These are the same entries as the Activity tab in the dashboard and the public `GET /connections/{connection_id}/activity` API. A connection that doesn't exist, belongs to another account, or has been deleted returns a "not found" error.
</Note>

## get\_retailers

List the retailers available to your account as structured rows. By default returns only the retailers enabled for your team (each with a Subtotal Link URL); pass `include="all"` to list every active retailer in the catalog, annotated with whether it's enabled for your team.

Requires the `retailers:read` OAuth scope. Connectors set up before this scope existed need to disconnect and reconnect to grant it; until then the tool returns `error_category: "insufficient_scope"`.

**Parameters:**

| Name | Type | Required | Description |
| :- | :- | :- | :- |
| `include` | string | No | `enabled` (default) — only the retailers enabled for your team, each with a `link_url`. `all` — every active retailer in the catalog, each annotated with an `enabled` flag and a `link_url` (present only when enabled). These are the only accepted values. |

**Response format:**

```json theme={null}
{
  "retailers": [
    {
      "retailer_id": "walmart",
      "name": "Walmart",
      "images": {
        "logo": { "light": ".../light/logo.svg", "dark": ".../dark/logo.svg" },
        "icon": { "light": ".../light/icon.svg", "dark": ".../dark/icon.svg" }
      },
      "status": "active",
      "enabled": true,
      "link_url": "https://link.subtotal.com/a1b2c3d4",
      "link_visibility": "restricted",
      "link_audience": { "allowed_emails": [], "allowed_domains": ["example.com"] }
    }
  ]
}
```

**Fields:**

| Field | Description |
| :- | :- |
| `retailer_id` | Retailer slug — the exact value used to filter purchase data by retailer (e.g. in `ask`). |
| `name` | Retailer display name. |
| `images` | Logo and icon URLs, each with a `light` and `dark` theme. |
| `status` | Platform status: `active`, `limited`, or `inactive`. |
| `enabled` | Whether this retailer is enabled for your team. |
| `link_url` | URL to launch Subtotal Link for the retailer. Present only when the retailer is enabled; `null` otherwise. |
| `link_visibility` | Who sees the retailer on the Subtotal Link retailer-selection page: `everyone`, `restricted` (only consumers matching `link_audience`), or `hidden`. `link_url` works regardless. `null` when not enabled. |
| `link_audience` | `{allowed_emails, allowed_domains}` applied when `link_visibility` is `restricted`. `null` when not enabled. |

<Note>
  This is the same retailer contract returned by the public `GET /retailers` API. With `include="all"`, `link_url` is `null` for retailers not enabled for your team.
</Note>

## update\_retailer

Update a retailer for your account: enable or disable it, and set who sees it on the Subtotal Link retailer-selection page. Every argument except `retailer_id` is optional, and omitted ones are left unchanged, but a call must set at least one of `enabled`, `link_visibility` or `link_audience`. Requires the `retailers:write` OAuth scope; a connector without it gets `error_category: "insufficient_scope"`.

* **Visibility needs the retailer enabled:** either already, or with `enabled: true` in the same call.
* **`link_audience` replaces the stored lists.** Send both lists to keep entries you want.
* **`restricted` needs an audience:** at least one email or domain, counting lists already stored.
* **Disabling takes no visibility settings:** `enabled: false` can't be combined with `link_visibility` or `link_audience`.

<Warning>
  Disabling is destructive: it removes your configuration for the retailer. Links you've already shared stop working, and re-enabling issues a new `link_url` with `link_visibility` reset to `everyone`.
</Warning>

**Parameters:**

| Name | Type | Required | Description |
| :- | :- | :- | :- |
| `retailer_id` | string | Yes | Retailer slug to update — the `retailer_id` from `get_retailers` (e.g. `walmart`). |
| `enabled` | boolean | No | `true` to enable the retailer for your account, `false` to disable it. |
| `link_visibility` | string | No | `everyone`, `restricted` (only consumers matching `link_audience`), or `hidden`. `link_url` works regardless. |
| `link_audience` | object | No | `{allowed_emails, allowed_domains}` for `restricted`. Domains match exactly; subdomains are separate. |

**Example — enable and restrict to one domain in a single call:**

```json theme={null}
{
  "retailer_id": "walmart",
  "enabled": true,
  "link_visibility": "restricted",
  "link_audience": { "allowed_emails": [], "allowed_domains": ["example.com"] }
}
```

**Response format:**

```json theme={null}
{
  "retailer_id": "walmart",
  "name": "Walmart",
  "images": { "logo": { "light": "…", "dark": "…" }, "icon": { "light": "…", "dark": "…" } },
  "status": "active",
  "enabled": true,
  "link_url": "https://link.subtotal.com/a1b2c3d4",
  "link_visibility": "restricted",
  "link_audience": { "allowed_emails": [], "allowed_domains": ["example.com"] }
}
```

With `enabled: false`, `link_url`, `link_visibility` and `link_audience` come back `null`.

<Note>
  Returns the same row shape as `get_retailers` and the public `PATCH /retailers/{retailer_id}` API. Repeating a call returns the current row. These return an `error` field with `error_category: "invalid_input"`: an unknown `retailer_id`, no fields to update, visibility settings for a retailer that isn't enabled, visibility settings with `enabled: false`, or `restricted` with no audience. Invalid emails or domains, more than 100 entries in a list, or a `link_visibility` other than the three values are also rejected.
</Note>

## get\_data\_model

Returns the data model for your purchase data, including entities, fields, types, and relationships.

**Parameters:** None

**Returns:** A plain-text data model describing six entities: `connection`, `purchase`, `item`, `retailer`, `product`, and `brand`.

<Note>
  If you're using `ask`, you typically don't need to call `get_data_model` — the server already has the data model when answering questions.
</Note>

## Purchase status

The `purchase` entity includes a `status` field. Use `ask` to query purchases by status, for example: "How many purchases are shipped?"

<Snippet file="snippets/purchase-status.mdx" />


This documentation is built and hosted on [Mintlify](https://mintlify.com), a developer documentation platform.