Read
Every read endpoint: one company, events, people, content, tables.
One company
Does this id resolve? Always 200: matched, seen-but-unresolved, or never seen.
curl -s "$ACKDB_URL/entities/lookup?externalIdType=domain&externalIdValue=piedpiper.com" \
-H "Authorization: Bearer $ACKDB_API_KEY"{
"data": {
"match": {
"entityId": "01HXYZ123456789ABCDEFGH",
"entityName": "acme.com",
"domain": "acme.com",
"linkedAt": "2026-08-01T00:00:00Z"
},
"unresolvedMatches": [
{
"unresolvedContentId": "…",
"source": "…",
"timestamp": "2026-08-01T00:00:00Z"
}
]
}
}Get aggregated entity profile
curl -s "$ACKDB_URL/entities/{entityId}/profile" \
-H "Authorization: Bearer $ACKDB_API_KEY"{
"data": {
"entity": {
"entityId": "01HXYZ123456789ABCDEFGH",
"name": "Acme Corp",
"createdAt": "2026-08-01T00:00:00Z",
"updatedAt": "2026-08-01T00:00:00Z"
},
"identityLinks": [
{
"entityId": "01HXYZ123456789ABCDEFGH",
"source": "slack",
"externalIdType": "slack_channel_id",
"externalIdValue": "C04ABC",
"confidence": 1,
"linkedAt": "2026-08-01T00:00:00Z"
}
],
"traits": [
{
"entityId": "01HXYZ123456789ABCDEFGH",
"traitKey": "slack_message_count",
"valueString": null,
"valueNumber": 42,
"valueBool": null,
"valueDate": null,
"source": "slack",
"workflow": "slack-ingestion",
"confidence": 1,
"updatedAt": "2026-08-01T00:00:00Z"
}
],
"recentEvents": [
{
"id": "01HXYZ123456789ABCDEFGH",
"entityId": "01HXYZ123456789ABCDEFGI",
"source": "slack",
"eventType": "message",
"summary": "Customer asked about pricing in #acme-corp",
"metadata": {},
"timestamp": "2026-08-01T00:00:00Z",
"createdAt": "2026-08-01T00:00:00Z"
}
]
}
}Get the full entity object by identity link
curl -s "$ACKDB_URL/entities/full?externalIdType=domain&eventsLimit=50&eventsOffset=0&rawLimit=20&rawOffset=0&conversationsLimit=20&conversationsOffset=0&filesLimit=50&filesOffset=0&contacts=true&conversationSummary=true" \
-H "Authorization: Bearer $ACKDB_API_KEY"{
"data": {
"entity": {
"entityId": "01HXYZ123456789ABCDEFGH",
"name": "Acme Corp",
"createdAt": "2026-08-01T00:00:00Z",
"updatedAt": "2026-08-01T00:00:00Z"
},
"identityLinks": [
{
"entityId": "01HXYZ123456789ABCDEFGH",
"source": "slack",
"externalIdType": "slack_channel_id",
"externalIdValue": "C04ABC",
"confidence": 1,
"linkedAt": "2026-08-01T00:00:00Z"
}
],
"traits": [
{
"entityId": "01HXYZ123456789ABCDEFGH",
"traitKey": "slack_message_count",
"valueString": null,
"valueNumber": 42,
"valueBool": null,
"valueDate": null,
"source": "slack",
"workflow": "slack-ingestion"
}
],
"contacts": [
{}
],
"events": {
"data": [
{}
],
"total": 0,
"limit": 0,
"offset": 0
},
"rawPayloads": {
"data": [
{}
],
"total": 0,
"limit": 0,
"offset": 0
},
"conversations": {
"data": [
{}
],
"total": 0,
"limit": 0,
"offset": 0
},
"files": {
"data": [
{}
],
"total": 0,
"limit": 0,
"offset": 0
}
},
"resolvedBy": {
"externalIdValue": "…",
"externalIdType": "…",
"source": "…"
}
}Fuzzy search → the single closest company (hydrated like /full)
curl -s "$ACKDB_URL/entities/search" \
-H "Authorization: Bearer $ACKDB_API_KEY"{
"data": {},
"matchedOn": {
"field": "name",
"value": "…",
"tier": "exact"
}
}List and filter entities
curl -s "$ACKDB_URL/entities?limit=50&offset=0&includeReference=false" \
-H "Authorization: Bearer $ACKDB_API_KEY"{
"data": [
{
"entityId": "01HXYZ123456789ABCDEFGH",
"name": "Acme Corp",
"createdAt": "2026-08-01T00:00:00Z",
"updatedAt": "2026-08-01T00:00:00Z"
}
],
"pagination": {
"total": 150,
"limit": 50,
"offset": 0,
"totalIsLowerBound": true
}
}/full needs no externalIdType — a value maps to one company. /search ranks substrings (exact beats prefix beats contains), no typo tolerance. GET /entities with traitFilter= returns bare rows — hydrate via /profile.
Events
Get activity timeline for an entity
curl -s "$ACKDB_URL/entities/{entityId}/events?limit=20&offset=0" \
-H "Authorization: Bearer $ACKDB_API_KEY"{
"data": [
{
"id": "01HXYZ123456789ABCDEFGH",
"entityId": "01HXYZ123456789ABCDEFGI",
"source": "slack",
"eventType": "message",
"summary": "Customer asked about pricing in #acme-corp",
"metadata": {},
"timestamp": "2026-08-01T00:00:00Z",
"createdAt": "2026-08-01T00:00:00Z"
}
],
"pagination": {
"total": 150,
"limit": 50,
"offset": 0,
"totalIsLowerBound": true
}
}Cross-entity event search
curl -s "$ACKDB_URL/entities/events?limit=50&offset=0" \
-H "Authorization: Bearer $ACKDB_API_KEY"{
"data": [
{
"id": "01HXYZ123456789ABCDEFGH",
"entityId": "01HXYZ123456789ABCDEFGI",
"entityName": "acme.com",
"source": "stripe",
"eventType": "stripe_charge.refunded",
"summary": "Stripe refund: $50.00 USD",
"metadata": {
"refund_amount_cents": 5000,
"currency": "usd",
"refund_full": true
},
"timestamp": "2026-02-15T14:30:00.000Z",
"createdAt": "2026-02-15T14:30:01.000Z"
}
],
"pagination": {
"total": 1,
"limit": 50,
"offset": 0
}
}Counts and sums across every company, no rows retrieved.
curl -s "$ACKDB_URL/entities/events/aggregate?source=stripe&sumField=amount_paid_cents&groupBy=month" \
-H "Authorization: Bearer $ACKDB_API_KEY"{
"data": {
"count": 45,
"distinctEntities": 12,
"sum": 1250000,
"avg": 27777.78,
"min": 5000,
"max": 99000,
"groups": [
{
"key": "stripe_charge.succeeded",
"count": 30,
"distinctEntities": 10,
"sum": 0,
"avg": 0,
"min": 0,
"max": 0
}
]
}
}Find cross-source temporal event sequences
curl -s "$ACKDB_URL/entities/events/sequence?windowDays=7&limit=50&offset=0" \
-H "Authorization: Bearer $ACKDB_API_KEY"{
"data": [
{
"entityId": "…",
"entityName": "…",
"daysBetween": 0,
"firstEvent": {
"id": "01HXYZ123456789ABCDEFGH",
"entityId": "01HXYZ123456789ABCDEFGI",
"source": "slack",
"eventType": "message",
"summary": "Customer asked about pricing in #acme-corp",
"metadata": {},
"timestamp": "2026-08-01T00:00:00Z",
"createdAt": "2026-08-01T00:00:00Z"
},
"secondEvent": {
"id": "01HXYZ123456789ABCDEFGH",
"entityId": "01HXYZ123456789ABCDEFGI",
"source": "slack",
"eventType": "message",
"summary": "Customer asked about pricing in #acme-corp",
"metadata": {},
"timestamp": "2026-08-01T00:00:00Z",
"createdAt": "2026-08-01T00:00:00Z"
}
}
],
"pagination": {
"total": 150,
"limit": 50,
"offset": 0,
"totalIsLowerBound": true
}
}Event type params take the bare name (invoice.paid); stored names are source-prefixed. On the timeline, source= / sources= / excludeSources= are mutually exclusive; excludeSources=system,custom,member hides bookkeeping.
People
A person is the human; a contact is that human at one company.
List a company's people
curl -s "$ACKDB_URL/entities/{entityId}/contacts?status=active" \
-H "Authorization: Bearer $ACKDB_API_KEY"{
"data": "…"
}Fuzzy contact search → the single closest contact (cross-entity)
curl -s "$ACKDB_URL/contacts/search" \
-H "Authorization: Bearer $ACKDB_API_KEY"{
"data": "…"
}Find the single closest person (per-field)
curl -s "$ACKDB_URL/persons/search?contactLimit=25&eventLimit=10" \
-H "Authorization: Bearer $ACKDB_API_KEY"{
"data": "…"
}Person profile
curl -s "$ACKDB_URL/persons/{personId}?contactLimit=25&eventLimit=20" \
-H "Authorization: Bearer $ACKDB_API_KEY"{
"data": "…"
}The person timeline (cross-company)
curl -s "$ACKDB_URL/persons/{personId}/events?limit=20&offset=0" \
-H "Authorization: Bearer $ACKDB_API_KEY"{
"data": "…"
}The person timeline is what answers "have we talked to them before?" — contact at a previous employer still counts, and only that timeline shows it.
Content & evidence
Semantic search over entity content
curl -s "$ACKDB_URL/entities/{entityId}/search?limit=10" \
-H "Authorization: Bearer $ACKDB_API_KEY"{
"data": [
{
"source": "…",
"text": "…",
"score": 0,
"timestamp": "2026-08-01T00:00:00Z",
"metadata": {}
}
],
"query": "…",
"total": 0
}List or search entity conversations
curl -s "$ACKDB_URL/entities/{entityId}/conversations?limit=20&offset=0" \
-H "Authorization: Bearer $ACKDB_API_KEY"{
"data": [
{
"id": "…",
"entityId": "…",
"source": "slack",
"sourceThreadKey": "…",
"messageCount": 0,
"participantNames": [
"…"
],
"hasExternal": true,
"sourceMetadata": {},
"summary": "…",
"topics": [
"…"
],
"sentiment": "positive",
"actionItems": [
"…"
],
"fileIds": [
"…"
],
"hasFiles": true
}
],
"pagination": {
"total": 0,
"limit": 0,
"offset": 0
}
}Get raw payloads for an entity
curl -s "$ACKDB_URL/entities/{entityId}/raw?limit=20&offset=0" \
-H "Authorization: Bearer $ACKDB_API_KEY"{
"data": [
{
"id": "01HXYZ123456789ABCDEFGH",
"source": "slack",
"payload": {},
"createdAt": "2026-08-01T00:00:00Z"
}
],
"pagination": {
"total": 150,
"limit": 50,
"offset": 0,
"totalIsLowerBound": true
}
}List files for an entity
curl -s "$ACKDB_URL/entities/{entityId}/files?limit=50&offset=0" \
-H "Authorization: Bearer $ACKDB_API_KEY"{
"data": [
{
"id": "…",
"entityId": "…",
"eventId": "…",
"source": "slack",
"fileName": "q4-proposal.pdf",
"fileType": "application/pdf",
"fileSizeBytes": 2048576,
"sourceFileId": "…",
"sourceUrl": "…",
"metadata": {},
"description": "…",
"processed": true,
"createdAt": "2026-08-01T00:00:00Z"
}
],
"pagination": {
"total": 0,
"limit": 0,
"offset": 0
}
}Get file metadata
curl -s "$ACKDB_URL/files/{fileId}" \
-H "Authorization: Bearer $ACKDB_API_KEY"{
"data": {
"id": "…",
"entityId": "…",
"eventId": "…",
"source": "…",
"fileName": "…",
"fileType": "…",
"fileSizeBytes": 0,
"sourceFileId": "…",
"sourceUrl": "…",
"metadata": {},
"description": "…",
"extractedText": "…",
"contentChunkId": "…",
"processed": true
}
}Download file content
curl -s "$ACKDB_URL/files/{fileId}/content" \
-H "Authorization: Bearer $ACKDB_API_KEY"Get a company logo (public)
curl -s "$ACKDB_URL/entities/{id}/logo" \
-H "Authorization: Bearer $ACKDB_API_KEY"Semantic search answers 501 until an embedding provider is configured. q= on conversations switches list mode to search mode. More: Search and files.
Tables
The console's column surface — every computed column (evc__ counts, emf__ fields, sc__ scores, account_owner), the same grammar segments save:
List Observe company fields
curl -s "$ACKDB_URL/observe/companies/fields" \
-H "Authorization: Bearer $ACKDB_API_KEY"{
"data": [
{
"key": "event_count",
"label": "Event Count",
"group": "system",
"valueType": "string",
"source": "system",
"coverage": 1280,
"sortable": true,
"filterable": true,
"operators": [
"…"
],
"allowedValues": [
"…"
],
"distinctValuesUrl": "/observe/companies/fields/hubspot_lifecycle_stage/values"
}
]
}Query companies
{
"filter": {
"type": "group",
"op": "and",
"children": [
{
"type": "group",
"op": "and",
"children": [
{}
]
}
]
},
"sort": [
{
"field": "event_count",
"dir": "asc"
}
],
"columns": [
{
"field": "name",
"frozen": true,
"width": 200
}
],
"limit": 50,
"offset": 0,
"ids": [
"…"
]
}curl -s -X POST "$ACKDB_URL/observe/companies/query" \
-H "Authorization: Bearer $ACKDB_API_KEY" \
-H "Content-Type: application/json" \
-d '{ "filter": { "type": "group", "op": "and", "children": [ { "type": "group", "op": "and", "children": [ {} ] } ] }, "sort": [ { "field": "event_count", "dir": "asc" } ], "columns": [ { "field": "name", "frozen": true, "width": 200 } ], "limit": 50, "offset": 0, "ids": [ "…" ] }'{
"data": [
{
"entityId": "…",
"name": "…",
"domain": "…"
}
],
"pagination": {
"total": 150,
"limit": 50,
"offset": 0,
"totalIsLowerBound": true
}
}Export companies as CSV
{
"filter": {
"type": "group",
"op": "and",
"children": [
{
"type": "group",
"op": "and",
"children": [
{}
]
}
]
},
"sort": [
{
"field": "event_count",
"dir": "asc"
}
],
"columns": [
{
"field": "name",
"frozen": true,
"width": 200
}
],
"limit": 50,
"offset": 0,
"ids": [
"…"
]
}curl -s -X POST "$ACKDB_URL/observe/companies/export" \
-H "Authorization: Bearer $ACKDB_API_KEY" \
-H "Content-Type: application/json" \
-d '{ "filter": { "type": "group", "op": "and", "children": [ { "type": "group", "op": "and", "children": [ {} ] } ] }, "sort": [ { "field": "event_count", "dir": "asc" } ], "columns": [ { "field": "name", "frozen": true, "width": 200 } ], "limit": 50, "offset": 0, "ids": [ "…" ] }'Contacts and persons have twin surfaces under /observe/contacts/* and /observe/persons/*.
Ask
Ask a question (built-in AI agent)
{
"question": "What companies do we have data on?",
"sessionId": "…",
"entityId": "…"
}curl -s -X POST "$ACKDB_URL/ask" \
-H "Authorization: Bearer $ACKDB_API_KEY" \
-H "Content-Type: application/json" \
-d '{ "question": "What companies do we have data on?", "sessionId": "…", "entityId": "…" }'{
"answer": "…",
"citations": [
{
"claim": "…",
"source": "…",
"eventType": "…",
"timestamp": "…"
}
],
"steps": [
{
"type": "thinking",
"content": "…",
"toolName": "…",
"durationMs": 0
}
],
"toolCallCount": 0,
"totalDurationMs": 0,
"sessionId": "…"
}/mcp serves the same tools to your own AI client: Connect your AI client.