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

# Manual Communication Logs

> Agent-logged outcomes from manual outreach attempts

| Property      | Value                                              |
| ------------- | -------------------------------------------------- |
| Dataset code  | `D23`                                              |
| Section code  | `S4` — Communications                              |
| Endpoint path | `/exports/S4/D23`                                  |
| Cursor field  | `communicated_at`                                  |
| Page size     | `1`–`1000` (default `500`)                         |
| Availability  | Phase 1 — generally available                      |
| Pagination    | Via (variable page size — joined through a parent) |

Each row is an outcome our agents logged after attempting contact — PTP captured, RPC achieved, no-answer, busy, settled, and so on. The `outcome_option` field uses a controlled vocabulary. Structured outcome details (PTP date, amount, callback date) live in D24, which is not yet enabled.

## Fields

| Field                | Type    | Description                                                                                                                                        | Notes                |
| -------------------- | ------- | -------------------------------------------------------------------------------------------------------------------------------------------------- | -------------------- |
| `public_id`          | string  | Stable unique identifier for this manual communication row. Use as the primary key for warehouse upserts. Derived from the underlying Mongo `_id`. | Available as of v1.1 |
| `communication_type` | string  | Channel of the manual attempt.                                                                                                                     |                      |
| `interaction_source` | string  | Where the interaction originated.                                                                                                                  |                      |
| `outcome_option`     | string  | Logged outcome from a controlled vocabulary (e.g. PTP, RPC, no-answer).                                                                            |                      |
| `is_active`          | boolean | Whether this log entry is active.                                                                                                                  |                      |
| `is_ptp_broken`      | boolean | Whether a promise-to-pay associated with this entry was broken.                                                                                    |                      |
| `communicated_at`    | string  | When the communication occurred (ISO-8601).                                                                                                        | Cursor field         |
| `created_at`         | string  | Row creation timestamp (ISO-8601).                                                                                                                 |                      |
| `updated_at`         | string  | Last-modified timestamp (ISO-8601).                                                                                                                |                      |

## Sample row

```json theme={null}
{
  "public_id": "664a1b2c3d4e5f6071829abc",
  "communication_type": "CALL",
  "interaction_source": "AGENT",
  "outcome_option": "PTP",
  "is_active": true,
  "is_ptp_broken": false,
  "communicated_at": "2026-05-21T12:05:44.000Z",
  "created_at": "2026-05-21T12:06:00.512Z",
  "updated_at": "2026-05-21T12:06:00.512Z"
}
```

## Pagination characteristics

This dataset is **via** — it is filtered to your tenant by joining through its parent (`user_lender_detail_id` → `UserLenderDetails`). It is also very large (tens of millions of rows in shared tenant DBs), so on multi-tenant databases a single response may contain **fewer rows than your `limit`** even when more data exists. The cursor still advances correctly — keep paging until `nextCursor` is `null`. See [Pagination → Variable page size](/api-reference/exports/pagination).

<Warning>
  **Always pull `D23` in time-windowed slices.** Because of the dataset's size, an **unbounded** request (no `since`/`until`) forces a scan across the entire collection and can exceed the API gateway timeout, returning a [`504`](/api-reference/exports/errors). To pull reliably:

  * Pass a `since` (and optionally `until`) window and walk forward in slices — for a full backfill, iterate month-by-month (or smaller for the busiest tenants).
  * Within each window, page with the cursor until `nextCursor` is `null`, then advance to the next window.
  * Consider a smaller `limit` (e.g. `200`–`500`) so each page does less work.
  * `?includeTotal=true` requires a time window on this dataset — without one it returns `totalNote: "window_required"`.
</Warning>

## Use cases

* Outcome-mix dashboards (PTP rate, RPC rate, refusal rate).
* Agent productivity benchmarking.
* Cohort-level reach/contact analytics.

<Note>
  Page size may be smaller than the requested `limit` on multi-tenant DBs. Rely on `nextCursor: null` to detect the end of data. Free-text notes, phone, and email are deliberately excluded.
</Note>

***

<Snippet file="snippets/support-info.mdx" />
