Made Open

API Reference

The hub exposes a REST API on port 4101 with Swagger UI for interactive exploration.

Interactive Documentation

When the hub is running:

Route Groups

All routes require authentication via Supabase Auth JWT (passed as Authorization: Bearer <token>) unless noted.

Core Platform

Contacts and conversations are surfaced through the unified inbox and contact-timeline endpoints (see Unified Inbox and Contact Timeline & Notes below) rather than dedicated /api/persons or /api/conversations CRUD routes. Rules are managed via templates plus the rules analytics endpoints.

MethodPathDescription
POST/api/calling/placePlace outbound call
POST/api/calling/tokenGet Twilio WebRTC access token
GET/api/rule-templatesList rule templates
GET/api/rule-templates/:idRule template detail
POST/api/rules/from-template/:templateIdCreate rule from template
GET/api/rules/:id/executionsRule execution log
GET/api/rules/:id/statsRule execution stats
GET/api/rules/analytics/topTop rule analytics
GET/api/credentialsList credential metadata
POST/api/credentialsAdd credential to wallet
DELETE/api/credentials/:typeRemove credential
GET/api/capabilitiesActive capabilities
GET/api/capabilities/schemaCapability schema catalog
GET/api/capabilities/twilioTwilio-specific capabilities
GET/api/statsDashboard statistics
GET/api/statusHub status
GET/api/versionHub version
GET/api/auditBrowse audit log
GET/api/audit/summaryAudit summary
GET/api/search?q=Full-text search
GET/api/suggestSearch suggestions

Note: Contact CRUD (/api/persons), top-level conversation CRUD (/api/conversations), and dedicated rules CRUD (POST/PATCH/DELETE /api/rules) are aspirational and not yet exposed as REST endpoints at this commit. Messaging inbound flows use /api/messaging/conversations and /api/messaging/sms.

Webhooks (no auth required)

MethodPathDescription
POST/webhooks/calling/inboundTwilio inbound voice webhook
POST/webhooks/calling/statusTwilio call status callback
POST/webhooks/calling/voicemailTwilio voicemail status callback
POST/webhooks/whatsappWhatsApp Cloud API webhook
GET/webhooks/whatsappWhatsApp verification challenge

Note: An MS Graph change-notification webhook (/webhooks/ms-graph) is aspirational — MS Graph sync currently runs via the connector plugin, not an inbound webhook.

Intentions & Sensors

MethodPathDescription
GET/api/intentionsList intentions
POST/api/intentionsCreate intention
GET/api/intentions/:idIntention detail
PUT/api/intentions/:idUpdate intention
GET/api/intentions/:id/childrenChild intentions
GET/api/searchEnhanced search with filters
POST/api/sensor/activityDevice activity ingestion
POST/api/sensor/call-logDevice call-log ingestion
POST/api/sensor/locationDevice location ingestion
POST/api/location/batchBatch location upload

AI & Agents

MethodPathDescription
POST/api/ai/queryAI chat query
POST/api/agent/streamStreaming agent response (SSE)
GET/api/ai/conversationsList agent conversations
GET/api/ai/conversations/:idAgent conversation detail
GET/api/ai/toolsList registered agent tools
POST/api/ai/tools/:name/executeExecute a registered agent tool
POST/api/ai/agent/planCreate an agent plan
POST/api/ai/agent/runRun an agent plan
GET/api/ai/agent/sessions/:sid/memoryAgent session memory
GET/api/ai/agent/sessions/:sid/toolsAgent session tool calls

Note: /api/workflows, /api/workflows/:id/run, /api/ai/routing-rules, and a dedicated multi-agent /api/agent/orchestrate endpoint are aspirational at this commit.

Federation

MethodPathDescription
GET/api/federation/inboxActivityPub inbox (server-to-server delivery uses /ap/actors/:username/inbox)
GET/api/federation/outboxActivityPub outbox
GET/ap/actors/:usernameActivityPub actor profile
GET/ap/actors/:username/followersActor followers collection
GET/ap/actors/:username/followingActor following collection
GET/ap/actors/:username/outboxActor outbox
POST/ap/actors/:username/inboxActivityPub inbox delivery
POST/api/federation/followFollow a remote actor
POST/api/federation/unfollowUnfollow a remote actor
GET/api/federation/followsList follows
POST/api/federation/notesPublish a federated note
GET/.well-known/webfingerWebFinger discovery
GET/.well-known/did.jsonDID document (well-known)
GET/api/federation/didCurrent DID document
POST/api/federation/didRotate / create DID
GET/api/federation/credentialsList federated verifiable credentials
GET/api/federation/hubsList subscribed hubs
POST/api/federation/hubs/subscribeSubscribe to a remote hub
POST/api/federation/hubs/:id/syncForce-sync a remote hub
DELETE/api/federation/hubs/:idUnsubscribe from a remote hub
GET/api/federation/marketplaceFederated marketplace feed
GET/api/federation/marketplace/searchSearch federated listings
POST/api/federation/marketplace/announce/:idAnnounce a listing

Marketplace & Coordination

MethodPathDescription
GET/api/marketplace/listingsList marketplace listings
POST/api/marketplace/listingsCreate listing
GET/api/marketplace/listings/:idListing detail
PATCH/api/marketplace/listings/:idUpdate listing
POST/api/marketplace/listings/:id/purchasePurchase a listing
GET/api/marketplace/data-productsData product catalog
POST/api/marketplace/data-productsCreate data product
GET/api/marketplace/data-products/:id/previewData product preview
GET/api/marketplace/data-products/:id/packageData product package
PATCH/api/marketplace/data-products/:id/privacyUpdate data product privacy
GET/api/marketplace/transactionsMarketplace transactions
GET/api/marketplace/transactions/:idTransaction detail
PATCH/api/marketplace/transactions/:id/statusUpdate transaction status
GET/api/coordination/declarationsList offer/need declarations
POST/api/coordination/declarationsCreate declaration
PATCH/api/coordination/declarations/:idUpdate declaration
DELETE/api/coordination/declarations/:idDelete declaration
GET/api/coordination/declarations/mineMy declarations
GET/api/coordination/matchesMatch offers to needs
GET/api/coordination/exchangesList exchange workflows
POST/api/coordination/exchangesStart exchange
GET/api/coordination/exchanges/:idExchange detail
PATCH/api/coordination/exchanges/:id/statusUpdate exchange status
POST/api/coordination/exchanges/:id/messagePost exchange message
GET/api/reputation/:userId/scoresReputation scores
GET/api/reputation/:userId/scores/:domainDomain-scoped reputation
GET/api/reputation/:userId/contextual/:domainContextual reputation
POST/api/reputation/issueIssue reputation credential
GET/api/reputation/trustTrust relationships
POST/api/reputation/trustAdd trust relationship
DELETE/api/reputation/trust/:trustedDidRemove trust relationship

Governance & Time Bank

MethodPathDescription
GET/api/governance/daosList DAOs
POST/api/governance/daosCreate DAO
GET/api/governance/daos/:idDAO detail
PATCH/api/governance/daos/:idUpdate DAO
DELETE/api/governance/daos/:id/members/:userIdRemove DAO member
GET/api/governance/daos/:id/membersDAO members
POST/api/governance/daos/:id/membersAdd DAO member
GET/api/governance/proposalsList proposals
POST/api/governance/proposalsCreate proposal
GET/api/governance/proposals/:idProposal detail
GET/api/governance/proposals/:id/tallyVote tally
GET/api/governance/proposals/:id/votesVotes cast
POST/api/governance/proposals/:id/votesCast a vote
POST/api/governance/proposals/:id/activateActivate proposal
POST/api/governance/proposals/:id/executeExecute proposal
POST/api/governance/proposals/:id/finalizeFinalize proposal
GET/api/timebank/balanceTime credit balance
GET/api/timebank/transactionsTime credit transactions
POST/api/timebank/creditCredit time
POST/api/timebank/debitDebit time
POST/api/timebank/transferTransfer credits
GET/api/disputesList disputes
POST/api/disputesCreate dispute
GET/api/disputes/:idDispute detail
GET/api/disputes/moderator/queueModerator queue
POST/api/disputes/:id/evidenceSubmit evidence
POST/api/disputes/:id/escalateEscalate dispute
POST/api/disputes/:id/moderatorAssign moderator
POST/api/disputes/:id/resolveResolve dispute

Browser Calling

MethodPathDescription
POST/api/calling/tokenTwilio calling access token
POST/api/calling/placePlace outbound call
GET/api/calling/historyCall history

Notifications & Presence

MethodPathDescription
GET/api/notifications/subscriptionsList notification subscriptions
POST/api/notifications/subscriptionsCreate notification subscription
DELETE/api/notifications/subscriptions/:idDelete notification subscription
POST/api/notifications/sendSend a notification
GET/api/webhooksList outbound webhooks
POST/api/webhooksRegister outbound webhook
PATCH/api/webhooks/:idUpdate outbound webhook
DELETE/api/webhooks/:idDelete outbound webhook
GET/api/webhooks/:id/logsWebhook delivery logs
GET/api/presence/:userIdUser presence status
POST/api/presenceSet presence
POST/api/presence/bulkBulk presence query
POST/api/presence/heartbeatPresence heartbeat
GET/api/audit/reportsCompliance reports
POST/api/audit/reportsGenerate compliance report
GET/api/audit/alert-rulesAudit alert rules
POST/api/audit/alert-rulesCreate audit alert rule
POST/api/audit/check-alertsForce alert evaluation

Plugins, Documents & Scheduling

MethodPathDescription
GET/api/pluginsPlugin registry catalog
GET/api/plugins/meMy installed plugins
GET/api/plugins/:pluginIdPlugin detail
POST/api/plugins/:pluginId/installInstall a plugin
DELETE/api/plugins/:pluginId/installUninstall a plugin
POST/api/plugins/:pluginId/enableEnable a plugin
POST/api/plugins/:pluginId/disableDisable a plugin
POST/api/plugins/:pluginId/rateRate a plugin
GET/api/plugins/:pluginId/ratingsPlugin ratings
GET/api/plugins/capabilitiesPlugin capability catalog
GET/api/plugins/capabilities/findFind plugins by capability
POST/api/documents/:id/analyzeAnalyze a document
POST/api/documents/:id/jobsSubmit document job
GET/api/documents/:id/jobsDocument jobs
GET/api/documents/:id/chunksDocument chunks
GET/api/documents/:id/entitiesExtracted entities
GET/api/documents/:id/summaryDocument summary
GET/api/documents/entities/searchSearch extracted entities
GET/api/rule-templatesRule templates
GET/api/rules/analytics/topTop rule analytics
GET/api/schedulesScheduled jobs
POST/api/schedulesCreate scheduled job
GET/api/schedules/:idSchedule detail
PATCH/api/schedules/:idUpdate schedule
DELETE/api/schedules/:idDelete schedule
GET/api/schedules/:id/runsSchedule run history
POST/api/schedules/:id/pausePause schedule
POST/api/schedules/:id/resumeResume schedule
POST/api/schedules/:id/triggerTrigger schedule now
GET/api/scheduler/statusScheduler status
POST/api/scheduler/digest/generateGenerate daily digest
POST/api/scheduler/presence/syncRun presence sync
POST/api/scheduler/retention/runRun retention sweep

Observability & Streaming

MethodPathDescription
GET/metricsPrometheus metrics
GET/metrics/prometheusPrometheus metrics (alias)
GET/healthLiveness probe
GET/health/detailedDetailed health check
GET/api/event-store/streams/:streamIdEvent store stream
POST/api/event-store/streams/:streamId/eventsAppend events to stream
GET/api/event-store/streams/:streamId/snapshotLatest snapshot
POST/api/event-store/streams/:streamId/snapshotWrite snapshot
GET/api/event-store/types/:eventTypeEvents by type
GET/api/eventsEvent feed
GET/api/streamSSE stream subscription
GET/api/stream/statsSSE stream statistics
GET/api/activityActivity feed
GET/api/activity/unread-countUnread activity count
POST/api/activity/readMark activity as read

Note: /api/cache/stats, /api/events/store, /api/sse/subscribe, and /api/activity/feed as separate paths are aspirational — use the paths above.

Multi-Tenancy & Developer API

MethodPathDescription
GET/api/orgsList organisations
POST/api/orgsCreate organisation
GET/api/orgs/:orgIdOrganisation detail
PUT/api/orgs/:orgIdUpdate organisation
DELETE/api/orgs/:orgIdDelete organisation
GET/api/orgs/:orgId/membersOrg members
PUT/api/orgs/:orgId/members/:targetUserIdUpdate org member role
DELETE/api/orgs/:orgId/members/:targetUserIdRemove org member
GET/api/orgs/:orgId/invitesOrg invites
POST/api/orgs/:orgId/invitesCreate org invite
DELETE/api/orgs/:orgId/invites/:inviteIdRevoke org invite
POST/api/invites/:token/acceptAccept invite
GET/api/orgs/:orgId/billingOrg billing info
POST/api/orgs/:orgId/billing/planUpdate org billing plan
GET/api/orgs/:orgId/usageOrg usage metrics
GET/api/oauth/:providerId/authorizeProvider OAuth authorize
GET/api/oauth/:providerId/callbackProvider OAuth callback

Note: Self-hosted OAuth2 authorization server (/api/oauth/apps, /api/oauth/authorize, /api/oauth/token) and the API key (/api/keys) endpoints are aspirational. The /api/oauth/:providerId/* routes are the OAuth2 client flow for third-party providers.

Search, Export & Preferences

MethodPathDescription
POST/api/search/hybridHybrid text + vector search
POST/api/search/semanticSemantic (vector) search
POST/api/search/similarFind similar items
GET/api/search/similar/:type/:idFind similar by entity
GET/api/search/savedList saved searches
POST/api/search/savedCreate saved search
DELETE/api/search/saved/:idDelete saved search
PUT/api/search/saved/:id/alertToggle saved-search alert
GET/api/recommendationsAI recommendations
POST/api/recommendations/generateGenerate recommendations
DELETE/api/recommendations/:idDismiss recommendation
POST/api/exportExport data (JSON/CSV/vCard/iCal)
GET/api/exportList export jobs
GET/api/export/:jobIdExport job status
GET/api/export/:jobId/downloadDownload export
POST/api/importImport data
GET/api/importList import jobs
GET/api/import/:jobIdImport job status
GET/api/preferencesUser preferences
PUT/api/preferencesUpdate preferences
POST/api/preferences/resetReset preferences

Monitoring, Billing & Security

MethodPathDescription
POST/api/errorsReport client error
GET/api/admin/errorsTracked errors
GET/api/admin/errors/:idError detail
GET/api/admin/errors/statsError statistics
POST/api/admin/errors/:id/resolveMark error resolved
GET/api/admin/usersAdmin: list users
GET/api/admin/orgsAdmin: list orgs
GET/api/admin/statsAdmin: platform stats
GET/api/admin/infrastructureAdmin: infra status
GET/api/admin/clientsAdmin: connected clients
GET/api/admin/email/historyAdmin: email history
GET/api/admin/email/queueAdmin: email queue
POST/api/admin/email/processAdmin: drain email queue
POST/api/email/sendSend transactional email
POST/api/email/unsubscribeUnsubscribe webhook
GET/api/privacy/dashboardPrivacy dashboard
GET/api/privacy/consentsList consents
POST/api/privacy/consentsRecord consent
DELETE/api/privacy/consents/:purposeRevoke consent
GET/api/privacy/retentionRetention policies
POST/api/privacy/retentionCreate retention policy
PATCH/api/privacy/retention/:idUpdate retention policy
DELETE/api/privacy/retention/:idDelete retention policy
POST/api/privacy/retention/:id/runRun retention now
GET/api/privacy/exportExport personal data
DELETE/api/privacy/dataDelete personal data
POST/api/privacy/scanPII scan

Note: /api/billing/*, /api/feature-flags, /api/sessions, and /api/analytics REST endpoints are aspirational at this commit. Billing today flows through Stripe directly from the web app.

Data Lineage, Tools, Audio & Devices

MethodPathDescription
GET/api/contacts/merge-suggestionsDuplicate contact candidates
POST/api/contacts/mergeMerge contacts
POST/api/tools/jobsSubmit a tool job
GET/api/tools/jobsList tool jobs
GET/api/tools/jobs/:idTool job status
POST/api/tools/jobs/:id/cancelCancel tool job
GET/api/tools/capabilitiesTool capabilities
GET/api/tools/fontsList available fonts
POST/api/tools/fontsUpload font
DELETE/api/tools/fonts/:idDelete font
POST/api/audio/session/startStart audio session
POST/api/audio/session/:sessionId/endEnd audio session
POST/api/audio/session/cleanupCleanup stale audio sessions
GET/api/audio/sessionsList audio sessions
POST/api/audio/transcriptIngest transcript chunk
GET/api/audio/intelligenceExtracted audio intelligence
GET/api/audio/brief/:dateDaily audio brief
POST/api/audio/commandDispatch audio voice command
GET/api/audio/commandsList voice commands
POST/api/device/commandsSend device command
GET/api/device/commandsList device commands
GET/api/device/commands/pendingPending device commands
POST/api/device/commands/:commandId/progressReport command progress
POST/api/device/commands/:commandId/resultReport command result

Note: /api/lineage/:entityType/:entityId is aspirational — the lineage route file exists but does not yet register HTTP handlers at this commit.

Unified Inbox

All endpoints require auth. Backed by InboxService.

MethodPathDescription
GET/api/inboxList inbox items (calls, SMS, email, video, voicemail, calendar)
GET/api/inbox/unread-countUnread counts per channel type
PUT/api/inbox/readBulk mark items as read
PUT/api/inbox/starredBulk star or unstar items
PUT/api/inbox/archiveBulk archive items
GET/api/contacts/:id/timelineChronological communication timeline for a contact

GET /api/inbox query params:

ParamTypeDescription
typecall|sms|email|video|calendar_event|voicemailFilter by channel type
readtrue|falseFilter by read status
starredtrue|falseFilter by starred status
archivedtrue|falseInclude archived items
contactIdUUIDFilter by contact
searchstringFull-text search
pageint (default 1)Page number
limitint 1-100 (default 20)Page size

PUT /api/inbox/read / /api/inbox/archive body:

{ "itemIds": ["uuid", "..."] }

PUT /api/inbox/starred body:

{ "itemIds": ["uuid", "..."], "starred": true }

Voice & Phone Lines

All endpoints require auth unless noted. Backed by PhoneLineService, VoicemailService, TranscriptionService.

MethodPathDescription
GET/api/calling/linesList user's Twilio phone lines
PUT/api/calling/lines/:idUpdate phone line settings
POST/api/calling/transferWarm or cold transfer an active call
POST/api/calling/parkPark a call in a numbered slot (1-99)
POST/api/calling/retrieveRetrieve a parked call by slot
GET/api/calling/voicemailsList voicemails
PUT/api/calling/voicemails/:id/listenedMark voicemail as listened
GET/api/calling/recordings/:idGet a call recording
GET/api/calling/:id/transcriptGet transcript for a call session
GET/api/calling/:id/analysisGet AI analysis for a call session
POST/api/calling/ivr-flowsCreate an IVR call-flow
GET/api/calling/ivr-flowsList IVR call-flows
PUT/api/calling/ivr-flows/:idUpdate an IVR call-flow
DELETE/api/calling/ivr-flows/:idDelete an IVR call-flow
POST/webhooks/calling/voicemailTwilio voicemail status callback (no auth)

PUT /api/calling/lines/:id body:

{
  "label": "Office",
  "isDefault": true,
  "settings": {
    "businessHours": { "start": "09:00", "end": "17:00", "timezone": "America/New_York" },
    "voicemailGreetingUrl": "https://...",
    "forwardingNumber": "+1...",
    "recordingEnabled": true,
    "dndSchedule": {
      "enabled": true,
      "days": [6, 7],
      "startTime": "22:00",
      "endTime": "08:00",
      "vipContactIds": []
    }
  }
}

POST /api/calling/transfer body:

{ "callSid": "CA...", "targetNumber": "+1...", "type": "warm|cold", "announceMessage": "..." }

POST /api/calling/park body: { "callSid": "CA...", "slot": 5 } (slot optional, auto-assigned if omitted)

POST /api/calling/ivr-flows body:

{
  "name": "Main Menu",
  "phoneLineId": "uuid",
  "isActive": true,
  "flowDefinition": {
    "entryNodeId": "node-1",
    "nodes": [{ "id": "node-1", "type": "greeting|menu|route_to_number|route_to_voicemail|time_check|play_message", "label": "...", "data": {}, "position": { "x": 0, "y": 0 } }],
    "edges": [{ "id": "edge-1", "source": "node-1", "target": "node-2", "digit": "1" }]
  }
}

Email

All endpoints require auth. Backed by EmailService (MS Graph).

MethodPathDescription
GET/api/email/foldersList folders with unread counts
GET/api/email/threadsList email threads (filterable)
GET/api/email/threads/:threadId/messagesAll messages in a thread
PUT/api/email/threads/readBulk mark threads as read
PUT/api/email/threads/starredBulk star / unstar threads
GET/api/email/messages/:idSingle email with full body
POST/api/email/sendCompose and send email
POST/api/email/replyReply or reply-all to a message
POST/api/email/forwardForward a message
PUT/api/email/draftsSave / auto-save a draft
DELETE/api/email/drafts/:idDelete a draft
POST/api/email/moveMove message(s) to a folder
DELETE/api/email/:idTrash a message
GET/api/email/messages/:id/attachmentsList attachments on a message
GET/api/email/signaturesList email signatures
POST/api/email/signaturesCreate email signature
PUT/api/email/signatures/:idUpdate email signature
DELETE/api/email/signatures/:idDelete email signature

GET /api/email/threads query params: folderId, unread, starred, search, page, limit

POST /api/email/send body:

{
  "to": [{ "name": "...", "email": "..." }],
  "cc": [], "bcc": [],
  "subject": "...",
  "bodyHtml": "<p>...</p>",
  "bodyText": "...",
  "signatureId": "uuid",
  "attachmentIds": []
}

POST /api/email/reply body:

{ "messageId": "uuid", "bodyHtml": "...", "replyAll": false, "cc": [], "bcc": [], "attachmentIds": [] }

POST /api/email/forward body:

{ "messageId": "uuid", "to": [{ "name": "...", "email": "..." }], "bodyHtml": "..." }

PUT /api/email/threads/starred body: { "threadIds": ["uuid"], "starred": true }

POST /api/email/move body: { "messageIds": ["uuid"], "targetFolderId": "uuid" }

POST /api/email/signatures body: { "name": "Work", "bodyHtml": "<p>...</p>", "isDefault": false }

Email AI

All endpoints require auth. Backed by EmailAIService.

MethodPathDescription
POST/api/email/threads/:threadId/summarizeSummarize thread into key points + action items
POST/api/email/threads/:threadId/suggest-repliesGenerate 2-3 AI reply suggestions
GET/api/email/threads/:threadId/priorityAI-scored priority (0-100) with factors
GET/api/email/threads/:threadId/follow-upsDetect follow-up commitments in outbound messages

Responses:

/summarize{ summary: { keyPoints: string[], actionItems: string[], ... } }

/suggest-replies{ replies: [{ subject: string, bodyHtml: string }, ...] }

/priority{ priority: { score: number, factors: string[] } }

/follow-ups{ followUps: [{ messageId, commitment, dueDate }, ...] }

Video Meetings

All endpoints require auth unless noted. Backed by MeetingService (Twilio Video).

MethodPathDescription
POST/api/video/meetingsCreate a meeting
GET/api/video/meetingsList meetings
GET/api/video/meetings/:idMeeting detail
POST/api/video/meetings/:id/joinJoin meeting — returns Twilio Video token
POST/api/video/meetings/:id/endEnd meeting for all participants
POST/api/video/meetings/:id/inviteSend email/SMS invites
POST/api/video/meetings/:id/recording/startStart room recording
POST/api/video/meetings/:id/recording/stopStop room recording
GET/api/video/meetings/:id/recordingGet recording details
GET/api/video/meetings/:id/analysisAI analysis (transcript, action items)
GET/api/video/join/:roomNamePublic room info — no auth required

POST /api/video/meetings body:

{
  "title": "Sprint Review",
  "scheduledStart": "2026-04-10T14:00:00Z",
  "scheduledEnd": "2026-04-10T15:00:00Z",
  "calendarEventId": "uuid",
  "settings": { "recording": true, "waitingRoom": false, "maxParticipants": 10, "locked": false }
}

GET /api/video/meetings query params: status (scheduled|active|ended), search, page, limit

POST /api/video/meetings/:id/join body: { "identity": "display-name" } (optional)

POST /api/video/meetings/:id/invite body:

{ "emails": ["alice@example.com"], "phoneNumbers": ["+1..."], "message": "Join us!" }

Contact Timeline & Notes

All endpoints require auth. Backed by ContactTimelineService.

MethodPathDescription
GET/api/contacts/:id/timelineFull chronological communication timeline
GET/api/contacts/:id/notesList notes for a contact
POST/api/contacts/:id/notesCreate a note
PUT/api/contacts/notes/:noteIdUpdate a note body
DELETE/api/contacts/notes/:noteIdDelete a note
POST/api/contacts/mergeMerge two contacts into one
POST/api/contacts/unmerge/:mergeIdUndo a contact merge
GET/api/contacts/merge-suggestionsAI-suggested duplicate contacts
GET/api/contacts/:id/merge-historyMerge audit history for a contact
PUT/api/contacts/:id/relationshipSet relationship label
GET/api/contacts/:id/relationshipGet relationship label
GET/api/dashboard/recent-contactsRecently communicated contacts
GET/api/dashboard/missed-commsMissed calls, unread messages, unread emails
GET/api/dashboard/comm-statsCommunication volume statistics

GET /api/contacts/:id/timeline query params: types (comma-separated: call,sms,email,video,voicemail,note), startDate, endDate, limit, offset

POST /api/contacts/:id/notes body: { "body": "Met at conference..." }

PUT /api/contacts/notes/:noteId body: { "body": "Updated text" }

POST /api/contacts/merge body: { "primaryId": "uuid", "mergedId": "uuid" }

PUT /api/contacts/:id/relationship body: { "label": "partner|close_friend|friend|colleague|acquaintance|family|vip|blocked" }

GET /api/dashboard/recent-contacts query: limit (default 5)

Push Notifications

All endpoints require auth. Backed by PushNotificationService (Firebase Cloud Messaging).

MethodPathDescription
POST/api/push/registerRegister a device FCM token
DELETE/api/push/unregisterDeactivate a device FCM token
GET/api/push/tokensList active FCM tokens for the user

POST /api/push/register body:

{
  "deviceId": "device-uuid",
  "fcmToken": "FCM_TOKEN_STRING",
  "platform": "android",
  "deviceName": "Pixel 8"
}

Response 201: full token record.

DELETE /api/push/unregister body: { "deviceId": "device-uuid" } — returns 204.

Projects & Tasks

All endpoints require auth. Backed by ProjectService.

MethodPathDescription
POST/api/projectsCreate a project
GET/api/projectsList projects (filterable by status, area)
GET/api/projects/:idGet project detail
PUT/api/projects/:idUpdate project
POST/api/projects/:id/milestonesAdd milestone to project
PUT/api/projects/:id/milestones/:milestoneIdUpdate milestone
GET/api/projects/:id/tasksList tasks for a project
POST/api/projects/:id/tasksAdd task to project
PUT/api/projects/:id/tasks/:taskId/statusUpdate task status
POST/api/projects/:id/time-entriesLog time entry against project

POST /api/projects body:

{
  "title": "Q2 Marketing Campaign",
  "description": "...",
  "status": "active",
  "area": "work",
  "targetDate": "2026-06-30T00:00:00Z",
  "tags": ["marketing"]
}

POST /api/projects/:id/milestones body:

{ "title": "Launch email blast", "dueDate": "2026-05-01T00:00:00Z", "description": "..." }

POST /api/projects/:id/tasks body:

{ "title": "Write copy", "status": "todo", "priority": "high", "dueDate": "2026-04-20T00:00:00Z", "assignedTo": "uuid" }

PUT /api/projects/:id/tasks/:taskId/status body: { "status": "todo|in_progress|done|cancelled" }

POST /api/projects/:id/time-entries body:

{ "taskId": "uuid", "durationMinutes": 90, "notes": "Wrote first draft", "loggedAt": "2026-04-10T14:00:00Z" }

Authentication

All authenticated endpoints expect a Supabase Auth JWT:

curl -H "Authorization: Bearer <supabase-jwt>" \
     http://localhost:4101/api/persons

For the demo user (demo@made-open.dev), obtain a token via:

curl -X POST http://localhost:54321/auth/v1/token?grant_type=password \
  -H "apikey: <supabase-anon-key>" \
  -H "Content-Type: application/json" \
  -d '{"email":"demo@made-open.dev","password":"demopassword"}'