UC-018 — Manage the Inbox
| Field | Value |
|---|---|
| ID | UC-018 |
| Goal | Manage inbound conversations: triage, reading, archiving |
| Channel | All (SMS, RCS, WhatsApp, Messenger) |
| Complexity | Intermediate |
| Estimated time | 15 minutes |
| APIs involved | GET /api/partner-gateway/v1/inbox/conversations, GET /api/partner-gateway/v1/inbox/conversations/{chatId}, GET /api/partner-gateway/v1/inbox/conversations/{chatId}/messages, PATCH /api/partner-gateway/v1/inbox/conversations/{chatId}/archive, PATCH /api/partner-gateway/v1/inbox/conversations/{chatId}/unarchive, PATCH /api/partner-gateway/v1/inbox/conversations/{chatId}/read, POST /api/partner-gateway/v1/inbox/conversations/{chatId}/assignee, DELETE /api/partner-gateway/v1/inbox/conversations/{chatId}/assignee, GET /api/partner-gateway/v1/inbox/conversations/assignable-users |
Real-world scenarios
- Customer support triage: The ShopOnline support team uses the API to feed their internal dashboard and assign conversations to available operators.
- Archive resolved conversations: After closing a ticket, the operator archives the conversation to keep the inbox clean and focused on open cases.
- Monitor unread messages: The supervisor checks how many unread conversations there are to assess team workload.
- Workload distribution: The supervisor lists assignable team members and assigns each conversation to a specific agent via API; the agent is notified of the new work and the assignment shows up in their personalised inbox view.
Inbox management flow
The diagram shows the typical workflow: listing, reading, marking, archiving, and optionally assigning the conversation to a teammate.
Prerequisites
- Active API Key with inbox management permissions
- At least one active channel with inbound messages configured
- Receiving webhook configured (optional, for real-time notifications)
Step 1 — Retrieve active conversations
List conversations in the inbox, with filters for status and channel.
curl -X GET "https://lora-api.agiletelecom.com/api/partner-gateway/v1/inbox/conversations?status=active&limit=20" \
-H "X-Api-Key: YOUR_API_KEY"
Response — Conversation list
{
"conversations": [
{
"chatId": "chat_abc123",
"channel": "WHATSAPP",
"contact": {
"phoneNumber": "+393471234567",
"name": "Marco Rossi"
},
"lastMessage": {
"body": "Buongiorno, vorrei informazioni sulla spedizione del mio ordine",
"direction": "INBOUND",
"timestamp": "2026-04-09T14:30:00+02:00"
},
"unreadCount": 3,
"status": "ACTIVE",
"createdAt": "2026-04-09T14:25:00+02:00"
},
{
"chatId": "chat_def456",
"channel": "SMS",
"contact": {
"phoneNumber": "+393489876543",
"name": "Giulia Bianchi"
},
"lastMessage": {
"body": "STOP",
"direction": "INBOUND",
"timestamp": "2026-04-09T13:45:00+02:00"
},
"unreadCount": 1,
"status": "ACTIVE",
"createdAt": "2026-04-09T13:45:00+02:00"
}
],
"total": 2,
"hasMore": false
}
:::tip Filter for unread
Add &unreadOnly=true to the query to display only conversations with unread messages, useful for triage.
:::
Behind the scenes — How the inbox works
- Aggregation: The inbox aggregates messages from all active channels (SMS, RCS, WhatsApp, Messenger) into a single unified view.
- Threading: Messages are grouped into conversations based on the contact's phone number. A channel switch from the same number creates a new conversation.
- Sorting: Conversations are sorted by last message timestamp (most recent first).
- Pagination: The endpoint supports
limitandoffsetfor pagination. ThehasMorefield indicates whether there are additional results.
Step 2 — Read messages in a conversation
Retrieve the complete message history of a specific conversation.
curl -X GET "https://lora-api.agiletelecom.com/api/partner-gateway/v1/inbox/conversations/chat_abc123/messages?limit=50" \
-H "X-Api-Key: YOUR_API_KEY"
Response — Thread messages
{
"chatId": "chat_abc123",
"messages": [
{
"messageId": "msg_001",
"direction": "INBOUND",
"body": "Buongiorno, vorrei informazioni sulla spedizione del mio ordine",
"timestamp": "2026-04-09T14:25:00+02:00",
"status": "RECEIVED"
},
{
"messageId": "msg_002",
"direction": "INBOUND",
"body": "Il numero ordine e #ORD-20260405",
"timestamp": "2026-04-09T14:26:00+02:00",
"status": "RECEIVED"
},
{
"messageId": "msg_003",
"direction": "INBOUND",
"body": "Potete aiutarmi?",
"timestamp": "2026-04-09T14:30:00+02:00",
"status": "RECEIVED"
}
],
"total": 3,
"hasMore": false
}
Step 3 — Mark as read and archive
After handling the conversation, mark it as read and then archive it.
# Mark as read
curl -X PATCH https://lora-api.agiletelecom.com/api/partner-gateway/v1/inbox/conversations/chat_abc123/read \
-H "X-Api-Key: YOUR_API_KEY"
Response — Marked as read
{
"chatId": "chat_abc123",
"unreadCount": 0,
"updatedAt": "2026-04-09T15:00:00+02:00"
}
# Archive the resolved conversation
curl -X PATCH https://lora-api.agiletelecom.com/api/partner-gateway/v1/inbox/conversations/chat_abc123/archive \
-H "X-Api-Key: YOUR_API_KEY"
Response — Conversation archived
{
"chatId": "chat_abc123",
"status": "ARCHIVED",
"archivedAt": "2026-04-09T15:01:00+02:00"
}
Behind the scenes — Archiving and restoring
- Archiving: The conversation is moved to the archive and no longer appears in the active list. Messages remain accessible.
- Restoring: Use
PATCH /conversations/{chatId}/unarchiveto bring a conversation back to the active inbox. - New message: If a contact with an archived conversation sends a new message, the conversation is automatically restored to the active inbox.
- Retention: Archived conversations are kept for 12 months, then moved to long-term storage.
Step 4 — Assign or release a conversation
Distribute the inbox workload by assigning a conversation to a specific team member, or release it back to the unassigned queue.
List assignable team members
curl -X GET https://lora-api.agiletelecom.com/api/partner-gateway/v1/inbox/conversations/assignable-users \
-H "X-Api-Key: YOUR_API_KEY"
Response — Team members
[
{
"id": 4521,
"fullName": "Anna Bianchi",
"profilePicture": "https://cdn.example.com/users/4521/avatar.png"
},
{
"id": 4522,
"fullName": "Luca Verdi",
"profilePicture": "https://cdn.example.com/users/4522/avatar.png"
},
{
"id": 4523,
"fullName": "Marco Rossi",
"profilePicture": null
}
]
Assign the conversation to a user
curl -X POST https://lora-api.agiletelecom.com/api/partner-gateway/v1/inbox/conversations/98765/assignee \
-H "X-Api-Key: YOUR_API_KEY" \
-H "Content-Type: application/json" \
-d '{"userId": 4521}'
Response
204 No Content — the conversation is now owned by user 4521. A subsequent GET /inbox/conversations/98765 will reflect the new assignedUserId.
Release the conversation
curl -X DELETE https://lora-api.agiletelecom.com/api/partner-gateway/v1/inbox/conversations/98765/assignee \
-H "X-Api-Key: YOUR_API_KEY"
Response
204 No Content — the conversation is back to unassigned. The operation is idempotent: calling it on an already-unassigned conversation still returns 204.
:::tip One assignee at a time
Each conversation can have at most one assignee. A new POST .../assignee replaces the previous assignment without requiring an explicit DELETE.
:::
Behind the scenes — Assignment lifecycle
- Exclusive ownership: Only one team member can own a conversation at a time. Re-assigning silently replaces the previous owner.
- Notifications: The new assignee receives a real-time notification about the assignment and any subsequent inbound messages on that conversation.
- Idempotent release:
DELETE .../assigneereturns 204 whether or not there was a previous assignee, so retry logic is safe. - Cross-company guard: The
userIdin the assign request must belong to your company. Attempts to assign to a user from another account return 404, not 403, to avoid leaking user existence across tenants.
Expected result
| Step | Action | Result |
|---|---|---|
| 1 | GET /inbox/conversations | Conversation list with preview and unread count |
| 2 | GET /inbox/conversations/{chatId}/messages | Complete message history of the thread |
| 3 | PATCH /{chatId}/read + PATCH /{chatId}/archive | Conversation read and archived |
| 4 | POST /{chatId}/assignee + DELETE /{chatId}/assignee | Conversation assigned to a teammate and later released |
Complete end-to-end example
Scenario ShopOnline: automatic triage of unread conversations.
# 1. Retrieve unread conversations
echo "=== Unread Conversations ==="
CHATS=$(curl -s -X GET "https://lora-api.agiletelecom.com/api/partner-gateway/v1/inbox/conversations?status=active&unreadOnly=true" \
-H "X-Api-Key: YOUR_API_KEY")
echo "$CHATS" | jq '.conversations[] | {chatId, channel: .channel, contact: .contact.name, unread: .unreadCount}'
# 2. Read messages of the first conversation
FIRST_CHAT=$(echo "$CHATS" | jq -r '.conversations[0].chatId')
echo "=== Messages for $FIRST_CHAT ==="
curl -s -X GET "https://lora-api.agiletelecom.com/api/partner-gateway/v1/inbox/conversations/${FIRST_CHAT}/messages" \
-H "X-Api-Key: YOUR_API_KEY" | jq '.messages[] | {direction, body, timestamp}'
# 3. Mark as read
curl -s -X PATCH "https://lora-api.agiletelecom.com/api/partner-gateway/v1/inbox/conversations/${FIRST_CHAT}/read" \
-H "X-Api-Key: YOUR_API_KEY" | jq .
Variants
Restore an archived conversation
If a conversation was archived by mistake, restore it:
curl -X PATCH https://lora-api.agiletelecom.com/api/partner-gateway/v1/inbox/conversations/chat_abc123/unarchive \
-H "X-Api-Key: YOUR_API_KEY"
Common errors
404 Not Found — Conversation not found
{
"status": "fail",
"data": {
"conversation": "Conversation not found: chat_invalid_id"
}
}
Solution: Verify that the chatId is correct. Use GET /inbox/conversations to get the list of valid IDs.
404 Not Found — User not in your company
{
"status": "fail",
"data": {
"user": "User 9999 does not belong to your company"
}
}
Solution: The userId you tried to assign does not exist in your team. Call GET /inbox/conversations/assignable-users to list the valid IDs before retrying.
409 Conflict — Conversation already archived
{
"status": "fail",
"data": {
"conversation": "Conversation is already archived"
}
}
Solution: The conversation is already in the archive. If you want to restore it, use the unarchive endpoint.
Next steps
- UC-009 — Two-Way Conversation: Reply to messages received in the inbox
- UC-019 — Analyze Message History: Analyze history for reports and audits
- UC-008 — Delivery Tracking with Webhooks: Configure webhooks for real-time notifications