API Reference
List inbox messages across connected accounts or within one conversation
Account-level requests default to status=unanswered and windowDays=30, returning latest conversations whose newest provider message is inbound. Pass status=needs_reply to return only conversations that need a manual response after excluding active Sonarly reply automation and scheduled responses. Account-level items filtered by unanswered, new, answered, or needs_reply include replyHandling with the current automation state, active scheduled response, and needsManualReply decision. Existing status=unanswered behavior remains unchanged. Pass status=all to include message-level results from answered conversations, or pass conversationId to read full history for one conversation by default; status=all and conversation history items omit replyHandling because they may contain non-latest messages. The returned conversationId can be used to queue a direct reply even when no prospectId exists.
/v1/accounts/{accountGroupId}/messagesDefault inbox filter
Account-level requests default to status=unanswered and a 30-day window, returning conversations whose latest provider message is inbound. Use status=needs_reply to exclude conversations with active Sonarly reply automation or a scheduled response. Existing status=unanswered behavior is unchanged.
Reply handling
Account-level items filtered by unanswered, new, answered, or needs_reply include replyHandling. A conversation needs a manual response only when replyHandling.needsManualReply is true. Inspect automationState and scheduledResponse to understand why Sonarly is still handling a conversation. status=all and conversation-history items omit this conversation-level field because they may include older messages.
Resolving participants
Use GET /v1/accounts/{accountGroupId}/prospects/by-provider-id/{providerId} with items[].participantProviderId to resolve a conversation participant back to Sonarly prospect records in the same account group.
Integration notes
Required API permission
messages:read.
Prerequisites
integration_api_key, account_group_access.
Parameters
accountGroupIdPathType: string
Account group ID that scopes the request.
Required
cursorQueryType: string
Opaque pagination cursor returned by the previous page.
Optional
limitQueryType: number
Maximum number of items to return in this page.
Optional
conversationIdQueryType: string
Existing conversation ID used when responding in a direct message thread.
Optional
statusQueryType: string
Current lifecycle status of the resource.
Optional
windowDaysQueryType: integer
Query parameter used to filter or shape window days.
Optional
Request body
Responses
Paginated inbox messages across connected accounts or within one filtered conversation
Schema: MessageListSuccessResponse
Request validation failed
Schema: ValidationErrorResponse
Invalid or missing API key
Schema: ErrorResponse
Missing required permission
Schema: ErrorResponse
Rate limit exceeded
Schema: ErrorResponse
Internal server error
Schema: ErrorResponse
Upstream service error
Schema: ErrorResponse
Response examples
200 Example JSONMessageListSuccessResponse
{
"success": true,
"data": {
"items": [
{
"id": "507f1f77bcf86cd799439011",
"text": "string",
"sentAt": "string",
"accountId": "507f1f77bcf86cd799439011",
"accountType": "string",
"conversationId": "507f1f77bcf86cd799439011",
"conversationProviderId": "507f1f77bcf86cd799439011",
"conversationName": "Avery Stone",
"participantProviderId": "507f1f77bcf86cd799439011",
"senderId": "507f1f77bcf86cd799439011",
"isSender": true,
"unreadCount": 25,
"parentMessageId": "507f1f77bcf86cd799439011",
"attachments": [
{
"type": "string",
"id": "507f1f77bcf86cd799439011",
"url": "https://example.com/resource",
"fileName": "Avery Stone",
"mimeType": "string"
}
],
"replyHandling": {
"needsManualReply": true,
"managedBySystem": true,
"automationState": "string",
"workflowInstanceId": "507f1f77bcf86cd799439011",
"updatedAt": "2026-04-28T15:30:00.000Z",
"scheduledResponse": {
"id": "507f1f77bcf86cd799439011",
"activityId": "507f1f77bcf86cd799439011",
"status": "active",
"scheduledAt": "string"
}
}
}
],
"nextCursor": "eyJjcmVhdGVkQXQiOiIyMDI2LTA0LTI4VDE1OjMwOjAwLjAwMFoifQ",
"hasMore": true
},
"error": null,
"traceId": "507f1f77bcf86cd799439011"
}400 Example JSONValidationErrorResponse
{
"success": false,
"data": null,
"error": {
"code": "VALIDATION_ERROR",
"message": "Thanks for the context. I can send over details this afternoon.",
"details": "string"
},
"traceId": "507f1f77bcf86cd799439011"
}401 Example JSONErrorResponse
{
"success": false,
"data": null,
"error": {
"code": "string",
"message": "Thanks for the context. I can send over details this afternoon.",
"details": "string"
},
"traceId": "507f1f77bcf86cd799439011"
}403 Example JSONErrorResponse
{
"success": false,
"data": null,
"error": {
"code": "string",
"message": "Thanks for the context. I can send over details this afternoon.",
"details": "string"
},
"traceId": "507f1f77bcf86cd799439011"
}429 Example JSONErrorResponse
{
"success": false,
"data": null,
"error": {
"code": "string",
"message": "Thanks for the context. I can send over details this afternoon.",
"details": "string"
},
"traceId": "507f1f77bcf86cd799439011"
}500 Example JSONErrorResponse
{
"success": false,
"data": null,
"error": {
"code": "string",
"message": "Thanks for the context. I can send over details this afternoon.",
"details": "string"
},
"traceId": "507f1f77bcf86cd799439011"
}502 Example JSONErrorResponse
{
"success": false,
"data": null,
"error": {
"code": "string",
"message": "Thanks for the context. I can send over details this afternoon.",
"details": "string"
},
"traceId": "507f1f77bcf86cd799439011"
}