| 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
{
"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"
}
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.
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. 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".
Use cases
- Outcome-mix dashboards (PTP rate, RPC rate, refusal rate).
- Agent productivity benchmarking.
- Cohort-level reach/contact analytics.
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.