Skip to main content

API Reference

Every endpoint lives under /api/v1, except /api/health. Responses use one envelope:

{
"data": {},
"error": null,
"meta": {}
}

All endpoints require a Bearer token except these: registration, login, the extension pairing poll (GET /api/v1/extension/pair), frontend error reporting, the health check, and the WhatsApp webhook (which is verified by HMAC signature instead). The OAuth URL endpoints for Google and Twitter need a logged-in user, because the provider account is attached to that user.

The tables below list every route in the FastAPI OpenAPI schema. backend/tests/test_api_doc.py runs backend/scripts/check_api_doc.py and fails when a route is missing from this page, so the backend test run (including the pre-push hook) catches drift. To check locally, run PYTHONPATH=. python3 scripts/check_api_doc.py from backend/.


Auth​

MethodEndpointDescription
POST/api/v1/auth/registerRegister a new account with email and password
POST/api/v1/auth/loginLogin with email and password
GET/api/v1/auth/meCurrent authenticated user
PUT/api/v1/auth/meUpdate profile fields
DELETE/api/v1/auth/meDelete the authenticated account
POST/api/v1/auth/change-passwordChange account password
GET/api/v1/auth/google/urlGoogle OAuth authorization URL (requires a logged-in user)
POST/api/v1/auth/google/callbackAttach the Google account to the logged-in user and return a fresh access token. The caller must be the user the OAuth state was issued to, otherwise 403
GET/api/v1/auth/google/accountsList connected Google accounts (Gmail, Calendar, and Contacts sync cover every linked account)
DELETE/api/v1/auth/google/accounts/{account_id}Remove a connected Google account
GET/api/v1/auth/twitter/urlTwitter OAuth authorization URL (requires a logged-in user)
POST/api/v1/auth/twitter/callbackTwitter OAuth callback handler
DELETE/api/v1/auth/twitter/disconnectDisconnect Twitter
POST/api/v1/auth/telegram/connectSend OTP code to Telegram
POST/api/v1/auth/telegram/verifyVerify the Telegram OTP code
POST/api/v1/auth/telegram/verify-2faSubmit Telegram 2FA password
POST/api/v1/auth/telegram/reset-sessionClear the stored Telegram session but keep the username for reconnecting
DELETE/api/v1/auth/telegram/disconnectDisconnect Telegram
POST/api/v1/auth/whatsapp/connectStart a WhatsApp link-device flow
GET/api/v1/auth/whatsapp/qrFetch the current WhatsApp QR payload
GET/api/v1/auth/whatsapp/statusWhatsApp session status
DELETE/api/v1/auth/whatsapp/disconnectTear down the WhatsApp session

Contacts​

CRUD and listing​

MethodEndpointDescription
GET/api/v1/contactsList contacts (paginated, searchable, filterable)
POST/api/v1/contactsCreate a new contact
GET/api/v1/contacts/idsBulk contact IDs for select-all
GET/api/v1/contacts/statsDashboard contact stats
GET/api/v1/contacts/birthdaysUpcoming birthdays
GET/api/v1/contacts/overdueOverdue follow-up contacts
GET/api/v1/contacts/mapContacts within a viewport (bbox query)
POST/api/v1/contacts/bulk-updateBulk update tags, priority, and other fields
POST/api/v1/contacts/reconcile-last-interactionRecompute last_interaction_at for all contacts
POST/api/v1/contacts/scores/recalculateTrigger relationship-score recompute
GET/api/v1/contacts/{contact_id}Get a contact
PUT/api/v1/contacts/{contact_id}Update a contact
DELETE/api/v1/contacts/{contact_id}Delete a contact
GET/api/v1/contacts/{contact_id}/activityActivity feed for a contact
GET/api/v1/contacts/{contact_id}/relatedRelated contacts (same org, etc.)
GET/api/v1/contacts/{contact_id}/duplicatesDuplicate candidates for a contact

2nd-tier (Telegram group members)​

MethodEndpointDescription
GET/api/v1/contacts/2nd-tier/countCount of 2nd-tier contacts
DELETE/api/v1/contacts/2nd-tierDelete all 2nd-tier contacts
POST/api/v1/contacts/{contact_id}/promotePromote 2nd-tier contact to 1st-tier

Enrichment, AI, messaging​

MethodEndpointDescription
POST/api/v1/contacts/{contact_id}/enrichEnrich via Apollo
POST/api/v1/contacts/{contact_id}/extract-bioAI-extract structured fields from bios
POST/api/v1/contacts/{contact_id}/auto-tagApply AI taxonomy tags to one contact
POST/api/v1/contacts/{contact_id}/refresh-avatarRe-download avatar from connected platforms
POST/api/v1/contacts/{contact_id}/refresh-biosRe-fetch Twitter/Telegram bios
POST/api/v1/contacts/{contact_id}/composeGenerate an AI-drafted message (default channel email)
POST/api/v1/contacts/{contact_id}/send-messageSend a Telegram message (optionally scheduled). Other channels return 400; the web app copies those drafts to the clipboard instead

Identity / merging​

MethodEndpointDescription
POST/api/v1/contacts/{contact_id}/merge/{other_id}Merge two contacts directly
POST/api/v1/contacts/{contact_id}/dismiss-duplicate/{other_id}Dismiss a duplicate hint

Imports​

MethodEndpointDescription
POST/api/v1/contacts/import/csvImport from a CSV file. Each row is saved on its own, and failed rows come back in the result
POST/api/v1/contacts/import/linkedinImport a LinkedIn Connections.csv export
POST/api/v1/contacts/import/linkedin-messagesImport a LinkedIn message export

Per-contact background syncs​

MethodEndpointDescription
POST/api/v1/contacts/{contact_id}/sync-emailsSync Gmail threads for a single contact
POST/api/v1/contacts/{contact_id}/sync-telegramSync Telegram DM for a single contact
POST/api/v1/contacts/{contact_id}/sync-twitterSync Twitter DM for a single contact
GET/api/v1/contacts/{contact_id}/telegram/common-groupsTelegram groups shared with a contact

Account-wide background syncs​

Each call returns immediately and the work runs in a Celery task. Google Contacts, Google Calendar, Telegram, and Twitter syncs post a notification when they finish, and a sync that fails after retries posts a failure notification.

MethodEndpointDescription
POST/api/v1/contacts/sync/gmailSync Gmail email threads
POST/api/v1/contacts/sync/googleImport from Google Contacts
POST/api/v1/contacts/sync/google-calendarSync Google Calendar events
POST/api/v1/contacts/sync/telegramSync Telegram chats, groups, and bios
POST/api/v1/contacts/sync/twitterSync Twitter DMs and mentions
POST/api/v1/contacts/sync/whatsappBackfill WhatsApp messages
GET/api/v1/telegram/sync-progressPoll Telegram sync progress

Tag taxonomy​

MethodEndpointDescription
GET/api/v1/contacts/tagsFlat list of in-use tags
GET/api/v1/contacts/tags/taxonomyTag taxonomy structure
PUT/api/v1/contacts/tags/taxonomyUpdate taxonomy
POST/api/v1/contacts/tags/discoverLLM-discover a draft taxonomy
POST/api/v1/contacts/tags/applyApply taxonomy to contacts

Interactions (timeline)​

MethodEndpointDescription
GET/api/v1/contacts/{contact_id}/interactionsList interactions
POST/api/v1/contacts/{contact_id}/interactionsAdd a manual note
PATCH/api/v1/contacts/{contact_id}/interactions/{interaction_id}Update a note
DELETE/api/v1/contacts/{contact_id}/interactions/{interaction_id}Delete a note

Suggestions​

MethodEndpointDescription
GET/api/v1/suggestionsList follow-up suggestions
GET/api/v1/suggestions/digestWeekly digest of suggestions
POST/api/v1/suggestions/generateGenerate new follow-up suggestions
PUT/api/v1/suggestions/{suggestion_id}Update suggestion status (snooze, dismiss, send)
POST/api/v1/suggestions/{suggestion_id}/regenerateRegenerate the AI-drafted message

Identity Resolution​

MethodEndpointDescription
GET/api/v1/identity/matchesList pending identity matches
POST/api/v1/identity/scanTrigger an identity resolution scan
POST/api/v1/identity/matches/{match_id}/mergeConfirm merge for a pair
POST/api/v1/identity/matches/{match_id}/rejectReject a match

Organizations​

MethodEndpointDescription
GET/api/v1/organizationsList organizations (excludes those with zero active contacts)
POST/api/v1/organizationsCreate an organization
POST/api/v1/organizations/mergeMerge two or more organizations
POST/api/v1/organizations/backfill-logosBackfill favicon-derived logos for orgs missing one
POST/api/v1/organizations/scan-duplicatesRun a dedup scan; auto-merges deterministic pairs, queues fuzzy ones
GET/api/v1/organizations/duplicatesList pending_review duplicate pairs
POST/api/v1/organizations/duplicates/{match_id}/mergeMerge a pending pair (target_id body)
POST/api/v1/organizations/duplicates/{match_id}/dismissMark a pending pair as 'not the same'
GET/api/v1/organizations/{org_id}Get organization detail
PATCH/api/v1/organizations/{org_id}Update an organization
DELETE/api/v1/organizations/{org_id}Delete an organization
GET/api/v1/organizations/{org_id}/statsPer-organization stats from the materialized view
POST/api/v1/organizations/{org_id}/refresh-logoRe-fetch favicon for the org

Notifications​

MethodEndpointDescription
GET/api/v1/notificationsList notifications (page, page_size up to 100, optional link filter)
GET/api/v1/notifications/unread-countUnread count
PUT/api/v1/notifications/{notification_id}/readMark a notification read
PUT/api/v1/notifications/read-allMark all read

Settings​

MethodEndpointDescription
GET/api/v1/settings/priorityFollow-up intervals (high, medium, low)
PUT/api/v1/settings/priorityUpdate follow-up intervals (7-365 days)
GET/api/v1/settings/syncPer-platform auto-sync and schedule (manual, 6h, 12h, daily)
PUT/api/v1/settings/syncUpdate per-platform auto-sync and schedule
GET/api/v1/settings/telegramTelegram-specific settings (the 2nd-tier import toggle)
PUT/api/v1/settings/telegramUpdate Telegram settings
GET/api/v1/settings/suggestionsSuggestion preferences: max_suggestions (5-20), include_dormant, birthday_reminders, preferred_channel, dormancy_threshold_days (30-3650)
PUT/api/v1/settings/suggestionsUpdate suggestion preferences
GET/api/v1/settings/mcp-keyMCP API key status
POST/api/v1/settings/mcp-keyGenerate a new MCP API key (shown once; only an HMAC-SHA256 hash is stored)
DELETE/api/v1/settings/mcp-keyRevoke the MCP API key

Activity​

MethodEndpointDescription
GET/api/v1/activity/recentRecent interactions (last 7 days, deduped per contact)

Sync History​

MethodEndpointDescription
GET/api/v1/sync-historyRecent sync events with record counts
GET/api/v1/sync-history/statsAggregate stats per platform

Map​

MethodEndpointDescription
GET/api/v1/map/configPublic Mapbox token for the browser

See also GET /api/v1/contacts/map above for the viewport query.


LinkedIn (Chrome extension push)​

MethodEndpointDescription
POST/api/v1/linkedin/pushPush profiles and messages from the extension

Twitter (per-user cookies)​

Cookies are stored per user. The Chrome extension pushes fresh cookies, and the Settings page reads the status and clears them. Both the web token and the extension token are accepted.

MethodEndpointDescription
GET/api/v1/integrations/twitter/cookiesStatus of stored cookies for the user
POST/api/v1/integrations/twitter/cookiesPush fresh cookies (encrypted at rest) and verify them
DELETE/api/v1/integrations/twitter/cookiesClear stored cookies

Meta (Messenger / Instagram)​

MethodEndpointDescription
POST/api/v1/meta/pushPush Messenger / Instagram DM data from the extension

Extension Pairing​

The pairing poll is unauthenticated; everything else requires the extension JWT.

MethodEndpointDescription
POST/api/v1/extension/pairSubmit a pairing code from the extension popup
GET/api/v1/extension/pairPoll for token (unauthenticated, used by extension)
DELETE/api/v1/extension/pairDisconnect the extension
POST/api/v1/extension/refreshSilent token refresh (extension exchanges expiring JWT for a fresh 30-day one)

Webhooks​

MethodEndpointDescription
POST/api/v1/webhooks/whatsappWhatsApp sidecar webhook (HMAC-signed)

Diagnostics​

MethodEndpointDescription
GET/api/healthLiveness probe
POST/api/v1/errorsFrontend error reporting
GET/api/v1/versionCurrent app version and latest GitHub release (for self-hoster update banner)