
# Summaries API

Two kinds of AI-written summary are available over the API:

- **Chat summaries** — a short recap of one contact's conversation, generated on demand. The same thing as the summary control in a chat (see [Chat Summary](../chats/chat-interface.md#chat-summary)).
- **Daily summaries** — the once-a-day roundup across all your conversations that [Daily Summaries](../daily-summaries/daily-summaries.md) builds every morning: stats, one markdown block per section, and any tasks the AI created from it.

- **Base URL** — `https://api.youraiconnector.com/v1`
- **Authentication** — your API key (see [Authentication](authentication.md)). A [scoped key](api-keys.md#scoped-keys) needs the `Summaries` section.
- **Errors & paging** — see [Errors & Pagination](errors-and-pagination.md)

All examples below show the `?apiKey=` query form in cURL and the `X-API-Key` header in JavaScript and Python — either works on every endpoint.

---

## Generate a chat summary

`POST /summaries` — send the contact's `phoneNumber` (with country code) or `email`; one of the two is required.

The AI reads the contact's most recently **closed** conversation, or the one that is still open if none has closed yet, and writes a recap of it. The recap is stored on the contact (it appears under **Summaries** in the contact panel in the app) and returned in the response, so you can forward it straight to a CRM, a Slack channel or an email.

**Cost:** the same as one AI reply at the Agent's AI Quality tier — Pro 1 credit, Max 0.25, Mini 0.15; with your own Anthropic key connected, Pro costs 0. The request is refused before anything is generated when the balance does not cover it.


**cURL**

```bash
curl -X POST "https://api.youraiconnector.com/v1/summaries?apiKey=YOUR_API_KEY" \
  -H "Content-Type: application/json" \
  -d '{"phoneNumber": "+31612345678"}'
```

**JavaScript**

```javascript
const res = await fetch("https://api.youraiconnector.com/v1/summaries", {
  method: "POST",
  headers: { "X-API-Key": "YOUR_API_KEY", "Content-Type": "application/json" },
  body: JSON.stringify({ email: "jane@example.com" }),
});
const { summary } = await res.json();
```

**Python**

```python
import requests

r = requests.post(
    "https://api.youraiconnector.com/v1/summaries",
    headers={"X-API-Key": "YOUR_API_KEY"},
    json={"phoneNumber": "+31612345678"},
)
print(r.json()["summary"])
```

**Response**

```json
{
  "success": true,
  "message": "Chat summary generated successfully",
  "summary": "Jane asked about the 10-session package for her two children (ages 6 and 9) and preferred Saturday mornings. She booked a trial lesson for Saturday at 10:00 and wants to know whether siblings get a discount."
}
```

| Status | Meaning |
|---|---|
| `400` | Neither `phoneNumber` nor `email` was sent. |
| `404` | No contact matches, the contact has no conversation yet, or the conversation has no messages. The body's `message` says which. |
| `500` | Generation failed (for example, not enough credits). |

> **Automation recipe: booking email with a recap.** In an [automation](../automations/automations.md) on the **Appointment booked** trigger, add an **HTTP request** step that calls this endpoint with `${trigger.contact.phone_number}` (or the contact's email), then an **Email** step that inserts the `summary` from the HTTP step's response together with a link to the chat (your app's address followed by `/chats/` and the contact ID from the trigger). Your team gets the context of the booking in the same email, without opening the inbox.

> **Reading summaries back.** There is no endpoint that lists stored chat summaries. Keep the text from the response if you need it later, or generate it again (each call is billed).

### Alternative: by contact ID

`POST /summaries/chat-summary` with `{"contactId": "..."}` does the same generation for a contact you already hold the ID of. It only confirms success (`{"success": true, "data": "Chat summary generated successfully"}`) and does **not** return the text, so use `POST /summaries` when you want the recap itself. A team member whose key is limited to their assigned contacts gets `404` for a contact outside that scope.

---

## Read the latest chat summaries for many contacts

`POST /contacts/summaries/latest` — send up to 500 contact IDs and get back each contact's most recent chat summary in one call. Nothing is generated, so it costs no credits. This is the read behind the **AI summary** column of the [contacts CSV export](../get-started/exporting-contacts.md).

```json
{ "contactIds": ["contact_abc123", "contact_def456"] }
```

**Response**

```json
{
  "success": true,
  "summaries": {
    "contact_abc123": {
      "summary": "Asked for a quote for 20 units, prefers delivery next week.",
      "end_date_time": "2026-09-15T14:02:11.000Z"
    }
  }
}
```

A contact that has no summary yet, is not on your account, or is outside a team member's visible contacts is simply left out of `summaries`. The IDs must be unique, and a list with more than 500 is refused with `400`: split it into batches. A team member needs at least **View** on Messages.

```bash
curl -X POST "https://api.youraiconnector.com/v1/contacts/summaries/latest?apiKey=YOUR_API_KEY" \
  -H "Content-Type: application/json" \
  -d '{"contactIds": ["contact_abc123", "contact_def456"]}'
```

---

## Get a daily summary

`GET /summaries/daily/{date}` — `date` is `YYYY-MM-DD`. Returns the summary for that day, or `null` under `summary` when none has been generated yet, plus your section configuration.

**cURL**

```bash
curl "https://api.youraiconnector.com/v1/summaries/daily/2026-09-08?apiKey=YOUR_API_KEY"
```

**Response**

```json
{
  "success": true,
  "data": {
    "summary": {
      "date": "2026-09-08",
      "status": "completed",
      "generated_at": "2026-09-09T05:02:11.000Z",
      "stats": {
        "total_conversations": 42,
        "total_messages_sent": 310,
        "total_messages_received": 268,
        "human_alerts": 3,
        "bookings": 5,
        "new_contacts": 11,
        "sales": 2
      },
      "sections": {
        "wins_losses_improvements": "## Wins\n- ...",
        "tasks_action_items": "- Call Jane back about the sibling discount",
        "human_alerts_reviews": "...",
        "sentiment_analysis": "...",
        "booked_meetings_sales": "..."
      },
      "contact_map": { "Jane Doe": "uid_whatsapp_31612345678" },
      "auto_tasks": [],
      "created_task_ids": []
    },
    "section_configs": [
      { "id": "wins_losses_improvements", "name": "Wins, Losses & Improvements", "enabled": true, "position": 0 }
    ]
  }
}
```

- **`status`** — `pending`, `generating`, `completed` or `failed` (with `error` set). Poll this endpoint after a regenerate until it reads `completed`.
- **`sections`** — one markdown string per section, keyed by the section id. The five standard sections are `wins_losses_improvements`, `tasks_action_items`, `human_alerts_reviews`, `sentiment_analysis` and `booked_meetings_sales`; sections you add under **Configure** on the Daily Summaries page get a `custom_…` id. Names and order are echoed in `section_configs`.
- **`contact_map`** — display name to contact ID, so you can turn the names in the text into links.
- **`auto_tasks`** / **`created_task_ids`** — the action items the AI extracted and the tasks it created from them (when **Create task cards from action items** is on).

| Status | Meaning |
|---|---|
| `400` | `date` is not `YYYY-MM-DD`, or is in the future. |
| `403` | Daily Summaries is switched off for the account. |

> Prefer a push over polling? The **Daily Summary Created** [webhook event](../integrations/webhooks.md) delivers the same payload the moment a morning summary finishes.

---

## Regenerate a daily summary

`POST /summaries/daily/{date}/regenerate` — starts a fresh generation for that day in the background and returns immediately with `status: "generating"` and empty `sections`. Poll `GET /summaries/daily/{date}` until it completes. The same rules apply as for the **Try again** link in the app.

Optional body `{"deleteTasks": false}` keeps the tasks the previous run created; by default they are deleted and recreated from the new summary. Send a real boolean — the string `"false"` is ignored and treated as the default.

```bash
curl -X POST "https://api.youraiconnector.com/v1/summaries/daily/2026-09-08/regenerate?apiKey=YOUR_API_KEY" \
  -H "Content-Type: application/json" \
  -d '{"deleteTasks": false}'
```

---

## Quick reference

| Task | Endpoint |
|---|---|
| Generate a chat summary and get the text | `POST /summaries` |
| Generate a chat summary by contact ID (no text returned) | `POST /summaries/chat-summary` |
| Read the latest chat summary for up to 500 contacts | `POST /contacts/summaries/latest` |
| Read a day's summary | `GET /summaries/daily/{date}` |
| Regenerate a day's summary | `POST /summaries/daily/{date}/regenerate` |
