Gent API Documentation

Contact Sharing

Share contact cards between inboxes within the same tenant. Supports two flows: offer (push a contact to a colleague) and request (ask a colleague for a contact with optional parameters). Accepting an offer or request copies the card into the recipient's address book and seeds the Relationship record. Requires startup+ plan.

Auth: Session auth or token auth with contacts:write scope. Both parties must belong to the same tenant.
TTL: Pending shares expire after 30 days. Accepted/declined shares are kept for 7 days as an audit window, then auto-deleted.
Events & notifications: When a share offer is created, a contact.share_received event fires on the recipient inbox. When a request is created, the event fires on the contact holder inbox. Both paths also create a pending task on the Tasks calendar (visible in the Agenda as a pending action, no due date). Subscribe an event notification to contact.share_received, or add it to the inbox's webhook_events, to get push notification when a share arrives.
GET /v1/contacts/shares/ List pending incoming shares  scope: contacts:read
Query params
ParameterDescription
inbox_idSession auth only; omit for token auth.
200 OK — array of share records
[{ "share_id": "<share-id>", "type": "offer", "status": "pending", "from_inbox_id": "<inbox-id>", "to_inbox_id": "<inbox-id>", "contact_address": "alice@example.com", "parameters": {}, "created_at": "2024-01-01T00:00:00Z", "resolved_at": null }]
POST /v1/contacts/shares/ Create a share offer or request  scope: contacts:write
Request body — offer a contact you already hold
{ "type": "offer", "to_inbox_id": "inb_account_manager", "contact_id": "<contact-id>" }
Request body — request a contact from another inbox
{ "type": "request", "to_inbox_id": "inb_sales", "contact_address": "alice@example.com", "note": "Need the latest relationship context", "labels": ["vip"] }
FieldTypeRequiredDescription
typestringrequiredOne of: offer, request.
to_inbox_idstringrequiredTarget inbox id in the same tenant.
contact_idstringconditionalOffer only: contact id in your address book. Gent derives the contact address from the card.
contact_addressstringconditionalRequest only: email address of the contact you want from the other inbox.
notestringoptionalRequest only: context for the contact holder.
labelsarrayoptionalRequest only: label names to apply on import.
201 Created — the share record
POST /v1/contacts/shares/{share_id}/accept/ Accept a share — copies contact card  scope: contacts:write
Query params
ParameterDescription
inbox_idSession auth only.
200 OK — updated share record (status: "accepted")
The source contact card is copied into the accepting inbox's address book. A Relationship record is seeded so the contact appears in the intelligence graph immediately.
POST /v1/contacts/shares/{share_id}/decline/ Decline a share  scope: contacts:write
200 OK — updated share record (status: "declined")
POST /v1/contacts/{id}/handoff/ Transfer a contact to another inbox  scope: contacts:write
Request body
{ "to_inbox_id": "inb_account_manager", "note": "Taking over this account" }
FieldTypeRequiredDescription
to_inbox_idstringrequiredTarget inbox id in the same tenant.
notestringoptional
200 OK
{ "contact_id": "<contact-id>" }
Handoff copies the full contact card to the target inbox's address book, transfers any open commitments referencing this contact, and seeds the Relationship record. The source inbox is unchanged.
Thread Notes & Assignment

Leave internal notes on email threads (invisible to external senders), @mention teammates to create tasks on their agenda, and assign threads to other inboxes in the same tenant. Requires startup+ plan.

Auth: Agent token or session auth. Token calls require email:read for listing notes and email:write for creating, deleting notes and assigning threads. Session callers pass inbox_id.
Mentions: mentions is a list of teammate email addresses. Each mentioned teammate receives a task on their agenda referencing the thread. The author is automatically excluded. Unknown or cross-tenant addresses are rejected with 400.
Retention: Thread notes auto-expire after 90 days.
Events & agenda: Thread assignments and @mention tasks have no due date — they appear at the top of GET /v1/agenda/ as "pending": true items, before any dated items. Subscribe an event notification to thread.assigned or add it to webhook_events to get push notification when a thread is assigned to your inbox. Contact handoffs fire contact.handoff_received and also create a pending task.
GET /v1/messages/threads/{thread_id}/notes/ List internal notes on a thread  scope: email:read
200 OK
[{ "note_id": "<note-id>", "author_inbox_id": "<inbox-id>", "body": "This contact needs a follow-up call by EOW", "mentions": ["alice@example.com"], "created_at": "2024-01-01T00:00:00Z" }]
POST /v1/messages/threads/{thread_id}/notes/ Add a note to a thread  scope: email:write
Request body
{ "body": "@alice@example.com review this before replying", "mentions": ["alice@example.com"] }
FieldTypeRequiredDescription
bodystringrequired
mentionsarrayoptionalEmail addresses of teammates to notify.
201 Created — the note record
DELETE /v1/messages/threads/{thread_id}/notes/{note_id}/ Delete a note  scope: email:write
Only the note author may delete their own note. Returns 204 No Content.
POST /v1/messages/threads/{thread_id}/assign/ Assign a thread to a teammate  scope: email:write
Request body
{ "to": "alice@example.com", "note": "Needs legal review" }
FieldTypeRequiredDescription
tostringrequiredTeam member email, same tenant.
notestringoptionalAdded to task description.
200 OK
{ "assigned": true, "to": "alice@example.com" }
Creates a [Assigned] {subject} task on the assignee's agenda. Both must be in the same tenant. Use GET /v1/inboxes/ to discover teammate email addresses.
Email Templates

Tenant-level email templates shared across all team members. Admins (tenant owner) create and manage templates; all members can list, retrieve, and render them. Templates support {placeholder} substitution with POST /v1/templates/{template_id}/. Requires startup+ plan.

GET /v1/templates/ List all templates for the tenant
200 OK
[{ "template_id": "<template-id>", "name": "Follow-up", "subject": "Following up on {topic}", "body": "Hi {first_name},\n\nJust following up...", "variables": ["first_name", "topic"], "created_by": "<user-id>", "created_at": "2024-01-01T00:00:00Z", "updated_at": "2024-01-01T00:00:00Z" }]
POST /v1/templates/ Create a template (admin only)
Request body
{ "name": "Follow-up", "subject": "Following up on {topic}", "body": "Hi {first_name}, just following up", "variables": ["first_name", "topic"] }
FieldTypeRequiredDescription
namestringoptional
subjectstringoptional
bodystringoptional
variablesarrayoptionalDeclared placeholders.
201 Created — the template record
PATCH /v1/templates/{template_id}/ Update a template (admin only)
Request body — all fields optional
{ "name": "Updated name", "subject": "New subject", "body": "New body", "variables": ["first_name"] }
DELETE /v1/templates/{template_id}/ Delete a template (admin only) — 204 No Content
POST /v1/templates/{template_id}/ Render a template with variable substitution
Request body
{ "context": { "first_name": "Alice", "topic": "your proposal" } }
200 OK
{ "subject": "Following up on your proposal", "body": "Hi Alice, just following up" }
Missing context keys are left as literal {placeholder} — no error is raised.
Distribution Lists

Shared email addresses (e.g. support@company.com) that fan out incoming mail to multiple team member inboxes. Each member inbox receives a copy of all messages sent to the list address. Requires team governance controls (governance: token_controls or higher). Tenant admin only for mutations.

GET /v1/distribution-lists/ List all distribution lists for the tenant
200 OK
[{ "list_id": "<list-id>", "address": "support@company.com", "name": "Support Team", "created_by": "<user-id>", "created_at": "2024-01-01T00:00:00Z" }]
POST /v1/distribution-lists/ Create a distribution list (admin only)
Request body
{ "address": "support@company.com", "name": "Support Team" }
FieldTypeRequiredDescription
addressstringrequiredMust be a verified domain.
namestringrequired
201 Created — the list record
PATCH /v1/distribution-lists/{list_id}/ Rename a list (admin only)
{ "name": "New name" }
DELETE /v1/distribution-lists/{list_id}/ Delete a list and remove all aliases (admin only) — 204 No Content
GET /v1/distribution-lists/{list_id}/members/ List members
[{ "member_id": "<member-id>", "inbox_id": "<inbox-id>", "inbox_address": "alice@company.com", "added_at": "2024-01-01T00:00:00Z" }]
POST /v1/distribution-lists/{list_id}/members/ Add a member inbox (admin only)
Request body
{ "inbox_id": "<inbox-id>" }
Idempotent — adding an already-member inbox returns the existing record. Adding a member registers the list address as an alias on the inbox; mail to the list address is delivered to the member's Inbox folder.
DELETE /v1/distribution-lists/{list_id}/members/{inbox_id}/ Remove a member (admin only) — 204 No Content