A per-contact CRM feed — a chronological view of messages, delivery status events, ticket workflow changes, spam complaints, and calendar events associated with one contact. Query it with a stable contact_id when available, or an email address when the contact is not linked yet. This endpoint does not return inbox-wide activity. Requires context:read.
context:read required for token auth.GET /v1/activity/?inbox_id=&contact_id= Per-contact activity feed scope: context:read
| Field | Type | Required | Description |
|---|---|---|---|
| events | array | optional | Message entry. |
contact_id or address. Prefer contact_id because it is stable across email address changes and future channel identities. Use address only for address-only history before a contact is linked.cursor value from the previous response as the cursor query param to fetch the next page. When cursor is null the last page has been reached. The since filter is honoured on every page — passing both cursor and since is safe and will not skip entries.metadata field is always present ({} if not applicable):
message.sent·message.received—thread_id,has_attachments,preview,is_readmessage.delivered·message.bounced—smtp_reply,bounce_categorymessage.spam_complaint—feedback_typecalendar_event.created—start,duration,time_zone,location
inbox_id + contact_address + type + resource_id — re-processing the same event is always idempotent. Entries are automatically pruned after 2 years (TTL on the occurred_at timestamp).A graph-based view of communication strength between contacts. Nodes are contacts; edge weight is derived from interaction frequency and recency. The full graph shows all contacts for an inbox; the subgraph endpoint centres on one contact. Read-only. Requires context:read.
context:read required for token auth.GET /v1/relationships/?inbox_id= Full relationship graph scope: context:read
| Field | Type | Required | Description |
|---|---|---|---|
| outbound_strength | number | optional | How actively inbox owner emails them. |
| inbound_strength | number | optional | How actively they email inbox owner. |
| communication_pattern | string | optional | One of: initiator, responder, balanced. |
| avg_response_time_hours | number | optional | Welford running avg; null if no data. |
| preferred_contact_hours | array | optional | Top-3 UTC hours by frequency. |
| reply_rate | number | optional | Reply rate — replies divided by received messages. Null if no received messages. |
| days_since_contact | number | optional | Integer days; null if no contact yet. |
| relationship_health | string | optional | One of: new, strong, at_risk, dormant. |
| llm | null | optional | Populated when LLM enrichment is enabled. |
| labels | string | optional | Contact labels from context groups. |
| dimensions | object | optional | External enrichment (e.g. LinkedIn) |
GET /v1/relationships/{contact_id_or_address}/?inbox_id= Subgraph for one contact scope: context:read
contact_id or a bare email address as the path segment. The intelligence block is always present. behavioral is derived from interaction history and requires no LLM features. llm is null when the inbox has no LLM plan or the contact has not yet been enriched — enable via the LLM settings and call ?enrich=true to trigger on-demand. labels lists contact-level context group labels.shared_thread— co-appeared in the same message thread.shared_calendar_event— shared a calendar invite.same_domain— same email domain, computed on read.same_company— identical organisation names on their contact cards.
weight— 0–1 score combining frequency (log(count+1)/log(50)) and recency decay (half-life 90 days). Use for edge thickness.0.0for domain/company-only edges with no co-occurrence.last_seen_at— most recent co-occurrence event;nullfor domain/company-only edges.- Full graph: only edges where both endpoints are on the current page. Subgraph: all edges for the focal contact.
intelligence feature tier to be lite or higher. Tenants on the free plan receive 403 Forbidden with {"detail": "intelligence lite or above required"}.true when an inbound email from this contact carried the X-Gent: 1 header, indicating they are also a gent.mx user. Populated automatically on inbound email processing — no action required. null when not yet detected.collaboration_enabled: true (team governance plan, admin-set) and the requesting inbox has collaboration_opt_in: true, each relationship node includes a collaboration field with an overlap list showing other opted-in team members who also know this contact. Each overlap entry includes inbox_id, inbox_address, strength, health, and last_contact_at. This powers both "who else on the team knows this contact?" (overlap detection) and "who knows this contact best?" (expertise discovery) — the same query, sorted by strength. Empty list when collaboration is disabled or the inbox has not opted in.Label-based cross-entity views. One context group per label — carries entity counts and lists, aggregate communication stats, a merged activity feed across all members, member suggestions based on co-occurrence, and a weekly AI-generated digest. All endpoints require intelligence: full plan tier.
GET /v1/context/?inbox_id= List context groups scope: context:read
GET /v1/context/{label_id}/?inbox_id= Group detail with full entity lists scope: context:read
?enrich=summary or ?enrich=next_step to trigger on-demand AI enrichment. Add &fresh=1 when you need a newly generated result instead of the recent cached result.GET /v1/context/{label_id}/activity/?inbox_id= Merged activity feed across all group contacts scope: context:read
?limit= max 200.GET /v1/context/{label_id}/stats/?inbox_id= Aggregate communication stats & health distribution scope: context:read
health_distribution counts each member's relationship health category (see Relationships for health definitions). Useful for identifying which contacts in the group need attention.GET /v1/context/{label_id}/suggestions/?inbox_id= Contacts to add, ranked by co-occurrence scope: context:read
| Field | Type | Required | Description |
|---|---|---|---|
| co_occurrence_count | number | optional | Combined shared-thread + calendar count with group members. |
POST /entities/. ?limit= max 20.POST /v1/context/{label_id}/entities/ Apply label to entity scope: context:write
| Field | Type | Required | Description |
|---|---|---|---|
| entity_type | string | optional | Contact · calendar_event. |
DEL /v1/context/{label_id}/entities/{entity_type}/{entity_id}/ Remove label from entity scope: context:write
label_id is the same ID used in the Labels API. Messages are included automatically when the label keyword is applied to a message via the Messages API.llm.sweep_group_digests scheduled task (runs weekly per inbox). null until the first run. Requires LLM config and tenant LLM consent.{"field": "sender_label_ids", "op": "includes", "value": "<label_id>"} as a condition. Example: fire a create_task action whenever anyone from your VIP Clients group emails you.Optional AI-powered enrichment on top of the intelligence layer. Inference runs in your tenant's region and is billed at provider token cost plus 5%. No API keys required. Each feature can be enabled individually per inbox, or triggered on-demand via ?enrich= on any supported endpoint.
GET /v1/enrichment/reference/ List enrichment models and features no auth required
id field as the model value in PUT /v1/enrichment/. Use feature feature values in enabled_features.GET /v1/enrichment/models/ List region-available model options no auth required
GET /v1/enrichment/features/ List enrichment feature options no auth required
PUT /v1/enrichment/ Create or replace LLM config scope: llm:write
| Field | Type | Required | Description |
|---|---|---|---|
| inbox_id | string | required | — |
| model | string | required | Region-dependent canonical key. Fetch available options from GET /v1/enrichment/reference/. |
| enabled_features | array | required | Feature keys from GET /v1/enrichment/reference/. |
| budget_limit | float | optional | Monthly spend cap in USD. null = unlimited |
GET /v1/enrichment/?inbox_id= Retrieve LLM config scope: llm:read
DEL /v1/enrichment/?inbox_id= Remove LLM config — disables all features scope: llm:write
phishing_detection fires on every inbound email; next_step and contact_digest re-run whenever the contact's activity timeline is updated. Results are cached on the resource until the next triggering event. budget_limit caps total monthly LLM spend (USD) across all features for the inbox — when reached all enrichment calls are silently skipped. For team tenants, LLM config is managed by admins and applies to all team inboxes.label_inference_threshold (default 0.65, configurable via Inbox Settings) are surfaced as suggestions. Suggestions appear in the label_suggestions field of every email response and fire a label.suggested event notification. Each suggestion includes label_id and label_name — confirm with POST /v1/messages/{id}/suggested-labels/{label_id}/ or dismiss with DELETE. This feature does not use AI credits.event.suggested alert fires. The suggestion appears as event_suggestion on the email response (includes title, start, duration, location, description, and participants). Confirm with POST /v1/messages/{id}/suggested-events/ (supply calendar_id to create the calendar event) or dismiss with DELETE. Requires tenant LLM consent.Reusable retrieval source buckets let agents and clients ground email replies, ticket prep, automations, and summaries in approved sources. Sources can include email history, Files folders, public company pages, contacts, calendar context, and configured intelligence records. Answer delivery still happens through email or the calling workflow; there is no separate chat surface.
retrieval:read to list buckets/runs, retrieval:write to manage source buckets, and retrieval:run to run retrieval tasks.tesseract and textract as initial options. Tesseract is packaged in the API runtime; Textract requires regional AWS availability and billable provider calls. Use the extraction test endpoint before indexing customer documents.sensitive_source_approved acknowledgement.GET /v1/retrieval/reference/ Retrieval builder contract no auth required
GET /v1/retrieval/models/ List embedding model options scope: retrieval:read
GET /v1/retrieval/config/ Get tenant retrieval configuration tenant admin, scope: retrieval:read
PATCH /v1/retrieval/config/ Update tenant retrieval configuration tenant admin, scope: retrieval:write
POST /v1/retrieval/extraction-tests/ Test document extraction before indexing scope: retrieval:read
status: "ocr_required". If OCR is selected but the provider fails, the response returns status: "ocr_failed".POST /v1/retrieval/source-buckets/ Create source bucket scope: retrieval:write
GET /v1/retrieval/source-buckets/ List source buckets scope: retrieval:read
GET /v1/retrieval/source-buckets/{bucket_id}/ Get source bucket scope: retrieval:read
PATCH /v1/retrieval/source-buckets/{bucket_id}/ Update source bucket scope: retrieval:write
DELETE /v1/retrieval/source-buckets/{bucket_id}/ Delete source bucket and indexed chunks scope: retrieval:write
POST /v1/retrieval/source-buckets/{bucket_id}/estimate/ Estimate source bucket indexing scope: retrieval:read
sensitive_source_approved: true only after showing the user which sensitive source categories will be indexed. Buckets without sensitive sources do not need this field.POST /v1/retrieval/source-buckets/{bucket_id}/index/ Queue source bucket indexing scope: retrieval:write
GET /v1/retrieval/runs/ List retrieval runs scope: retrieval:read
POST /v1/retrieval/runs/ Run retrieval scope: retrieval:run
GET /v1/retrieval/runs/{run_id}/ Get retrieval run scope: retrieval:read
refresh supports manual, daily, and weekly; successful indexing stores the next scheduled refresh and exposes it as refresh.next_refresh_at. Retrieval runs and indexed chunks are tracked in usage at zero direct retrieval unit cost; answer generation records normal AI token usage. Index summaries are exposed as last_index_summary; failed or incomplete runs include answer.reason_code, answer.action_required, and bucket index context.