Deltas & Changed Rows
Read a delta between two DB snapshot captures: per-table added/modified/removed counts, partial-vs-complete contract, examined flags, and paged changed rows.
A delta is the computed difference between two consecutive captures of one source: per table, how many rows were added, modified, and removed, plus schema drift (columns added or removed) and a column-transition profile of the modified values. GET /v1/db-snapshots/deltas/:deltaId returns the delta's totals, its per-table stats joined with examination facts from the capture manifest, the snapshot pair it compares, and the column profile.
The single most important field is status. A delta row is created when its capture starts and grows as tables finish, so a delta whose capture has not completed reports status: "partial" — and its counts are then a floor, not a result. By counts alone, "still scanning" is indistinguishable from "examined everything, found nothing"; partial is that distinction made explicit. When you need a number you can act on, follow last_complete_delta_id, which the response carries precisely for that hop.
The same discipline applies per table. A table the scan cadence deferred this capture appears in tables[] with examined: false — its zero counts mean "not looked at", not "unchanged" — along with last_full_scan_at so its staleness is readable. A table that is absent from tables[] was examined and found clean: absent means clean, present-but-unexamined means deferred, and the two are never confusable. mode says how an examined table was read (full, incremental, changefeed, or skipped), and fallback_reason names why a table lost its fastest configured path — diagnostic only.
GET /v1/db-snapshots/deltas/:deltaId/changes pages through the actual changed rows — id, table_key, pk, change_type (added | modified | removed), and full before/after values. The table query parameter is required: a whole-delta page would interleave tables whose row shapes differ, and the row counts you need to decide what to fetch already live on delta.tables[]. limit defaults to 50 and is clamped to 500; the response echoes the paging it actually applied (limit, offset) plus total, the changed-row count for this table only.
Two caps to know: persisted change rows are bounded per table, so a very large diff sets changes_truncated: true on that table's stats while the counts stay exact — you can trust added/modified/removed even when not every row was kept. And the column_profile summarizes modified values as the top discrete old→new transitions per column, collapsing free-text columns into one aggregate line — a quick shape-of-the-change read before you page rows.
/v1/db-snapshots/deltas/:deltaIdPath parameters
Response (200) — delta detail (abridged)
{
"delta": {
"id": "b4c6e8a0-1d3f-4b5c-9e7a-2f4d6b8c0e1a",
"connection_id": "8d2f1c4a-6b3e-4f7d-9a1c-5e8b2d4f6a0c",
"from_snapshot_id": "9e1c3a5f-7b9d-4e2c-8a4f-6b0d2e4c6a8f",
"to_snapshot_id": "3f9a7b1d-2c4e-4a6f-8b0d-1e3c5a7f9b2d",
"computed_at": "2026-08-29T02:03:41.508Z",
"status": "complete",
"last_complete_delta_id": "b4c6e8a0-1d3f-4b5c-9e7a-2f4d6b8c0e1a",
"totals": { "added": 12, "modified": 48, "removed": 3, "tables_touched": 4, "tables_total": 21, "tables_skipped": 2, "drift": false },
"tables": [
{
"table_key": "public.customers",
"added": 2, "modified": 41, "removed": 0,
"changes_truncated": false,
"examined": true,
"last_full_scan_at": "2026-08-27T02:00:11.020Z",
"mode": "incremental",
"fallback_reason": null,
"columns_added": [], "columns_removed": []
},
{
"table_key": "public.audit_log",
"added": 0, "modified": 0, "removed": 0,
"changes_truncated": false,
"examined": false,
"last_full_scan_at": "2026-08-22T02:00:09.410Z",
"mode": "skipped",
"fallback_reason": null,
"columns_added": [], "columns_removed": []
}
]
},
"from_snapshot": { "id": "9e1c3a5f-7b9d-4e2c-8a4f-6b0d2e4c6a8f", "captured_at": "2026-08-28T02:00:03.114Z" },
"to_snapshot": { "id": "3f9a7b1d-2c4e-4a6f-8b0d-1e3c5a7f9b2d", "captured_at": "2026-08-29T02:00:04.221Z", "status": "ready" },
"column_profile": [
{ "table_key": "public.customers", "column": "credit_limit", "before": "50000", "after": "75000", "count": 17, "aggregate": false },
{ "table_key": "public.customers", "column": "notes", "count": 24, "aggregate": true }
]
}Paged changed rows
/v1/db-snapshots/deltas/:deltaId/changesQuery parameters
500curl + response
curl -s "https://api.talonic.com/v1/db-snapshots/deltas/b4c6e8a0-1d3f-4b5c-9e7a-2f4d6b8c0e1a/changes?table=public.customers&limit=2" \
-H "Authorization: Bearer tlnc_your_api_key"
{
"data": [
{
"id": "5c7e9a1b-3d5f-4c8e-a0b2-4d6f8a0c2e4a",
"table_key": "public.customers",
"pk": "10442",
"change_type": "modified",
"before": { "id": 10442, "credit_limit": 50000, "status": "active" },
"after": { "id": 10442, "credit_limit": 75000, "status": "active" }
},
{
"id": "1e3a5c7d-9b1f-4a6c-8e0a-2c4e6a8d0b2f",
"table_key": "public.customers",
"pk": "10981",
"change_type": "added",
"before": null,
"after": { "id": 10981, "credit_limit": 20000, "status": "active" }
}
],
"table": "public.customers",
"total": 43,
"limit": 2,
"offset": 0
}Errors
Error responses