Communication Service — API Contracts
Status: populated Owner: TBD Last updated: 2026-04-17 Companion: Service Template · API Path Conventions
All routes are mounted behind Kong at /v1/communication/*. Legacy prefixes /v1/digital-communication/* and /v1/messaging/* are maintained for backward-compatibility during migration.
1. Auth & common headers
| Header | Required | Purpose |
|---|---|---|
Authorization: Bearer <jwt> | All except join-token validation | Keycloak RS256 JWT |
Idempotency-Key: <uuid> | All POST mutations | See APPLICATION_LOGIC §6 |
X-Client-Mutation-Id: <uuid> | Optional | Offline replay |
X-Tenant-Id | Extracted from JWT tid (not from client) | Tenant scoping |
2. Error envelope
{ "success": false, "error": { "code": "STRING_CODE", "message": "...", "details": {} } }
Common error codes: MODULE_NOT_LICENSED, FORBIDDEN, NOT_FOUND, CONFLICT, ATTACHMENT_REJECTED, INVALID_STATE_TRANSITION, VALIDATION_ERROR, DEPENDENCY_UNAVAILABLE, RATE_LIMITED.
3. Messaging endpoints
| Method | Path | Scope | Description |
|---|---|---|---|
POST | /v1/communication/threads | messaging:write | Create thread |
GET | /v1/communication/threads | messaging:read | List threads (?patientId=, ?unreadOnly=, ?urgent=, ?cursor=) |
GET | /v1/communication/threads/{threadId} | messaging:read | Thread detail |
PATCH | /v1/communication/threads/{threadId}/archive | messaging:write | Archive |
POST | /v1/communication/threads/{threadId}/escalate | messaging:escalate | Escalate |
POST | /v1/communication/threads/{threadId}/messages | messaging:write | Send |
GET | /v1/communication/threads/{threadId}/messages | messaging:read | Paginate |
POST | /v1/communication/threads/{threadId}/read | messaging:read | Mark read (body {messageIds[]}) |
POST | /v1/communication/threads/{threadId}/attachments | messaging:write | Initiate upload |
3.1 POST /v1/communication/threads
Request:
{ "participantIds": ["usr_..."], "patientId": "pat_...?", "encounterId": "enc_...?", "subject": "..." }
Response 201:
{ "threadId": "thr_...", "createdAt": "ISO", "participantIds": [...] }
Errors: 400 validation, 403 MODULE_NOT_LICENSED, 403 FORBIDDEN (cross-tenant participants).
3.2 POST /v1/communication/threads/{threadId}/messages
Request:
{ "body": "string", "urgency": "routine|urgent|emergent", "attachmentIds": ["att_..."] }
Response 201:
{ "messageId": "msg_...", "threadId": "thr_...", "sentAt": "ISO" }
4. Notification endpoints
| Method | Path | Scope | Description |
|---|---|---|---|
POST | /v1/communication/notifications/intents | notifications:write | Submit intent (internal) |
GET | /v1/communication/notifications/intents/{id} | notifications:read | Get intent |
GET | /v1/communication/notifications/dispatch-status?correlationId= | notifications:read | Per-channel outcome (FR-COMMS-ENH-001) |
POST | /v1/communication/notifications/callbacks/sms | Provider-secret | Ghasi-SMS-Gateway / Twilio DLR |
POST | /v1/communication/notifications/callbacks/email | Provider-secret | Bounce / complaint |
POST | /v1/communication/notifications/callbacks/push | Provider-secret | FCM / APNs feedback |
GET | /v1/communication/notifications/health | notifications:ops | Per-adapter health |
5. Virtual session endpoints
| Method | Path | Scope | Description |
|---|---|---|---|
POST | /v1/communication/virtual-sessions | vc:write | Create session (typically auto from SCHEDULING event) |
GET | /v1/communication/virtual-sessions | vc:read | List (identity-bound for PATIENT) |
GET | /v1/communication/virtual-sessions/{id} | vc:read | Detail |
POST | /v1/communication/virtual-sessions/{id}/end | vc:write | End |
POST | /v1/communication/virtual-sessions/{id}/cancel | vc:write | Cancel |
POST | /v1/communication/virtual-sessions/{id}/fallback-message | vc:write | Spawn fallback thread |
GET | /v1/communication/virtual-sessions/{id}/join-token | vc:join | Issue one-time token |
GET | /v1/communication/virtual-sessions/join | token-in-query | Validate join token (anonymous) |
POST | /v1/communication/virtual-sessions/{id}/admit/{participantId} | vc:admit | Admit from waiting room |
POST | /v1/communication/virtual-sessions/{id}/remove/{participantId} | vc:write | Remove |
GET | /v1/communication/virtual-sessions/{id}/participants | vc:read | Participant list |
6. Configuration
| Method | Path | Description |
|---|---|---|
GET | /v1/communication/config/virtual-care | Get tenant VC config |
PUT | /v1/communication/config/virtual-care | Update (ADMIN) |
GET | /v1/communication/config/notifications/channels | Per-category channel policy |
PUT | /v1/communication/config/notifications/channels | Update (ADMIN) |
7. FHIR projection (via interop-service)
| Interaction | Resource |
|---|---|
POST /fhir/R4/Communication | New message |
GET /fhir/R4/Communication?patient=Patient/{id} | Chart-filtered |
POST /fhir/R4/CommunicationRequest | Escalation / triage |
GET /fhir/R4/Encounter?class=VR&patient= | Virtual encounters |
8. Pagination
Cursor-based: ?cursor=<opaque>&limit=25 (max 100). Responses include nextCursor?.
9. Rate limits
| Route family | Per-tenant | Per-user |
|---|---|---|
/messages POST | 1000/min | 60/min |
/notifications/intents POST | 10000/min | — |
/virtual-sessions POST | 500/min | 10/min |
| DLR callbacks | 20000/min | — (provider-secret) |
10. Deprecations
| Old | New | Sunset |
|---|---|---|
/v1/digital-communication/* | /v1/communication/* | M4 |
/v1/messaging/* | /v1/communication/* | M3 |
ghasi.messaging.* events | ghasi.digital_communication.* | M3 |
VIRTUAL_CARE.* subjects | ghasi.digital_communication.virtual_session.* | M3 |