Inbox
Read calls, voicemails, and messages grouped by external phone number, then open a timeline and mark observed activity seen.
The inbox model
An inbox thread is a read view, not a persisted conversation. There is no conversation ID or create-conversation endpoint. Threads aggregate activity across the company's business numbers unless a business-number filter is supplied. Contacts with no activity do not produce threads. An empty timeline read does not create a contact.
Calls linked to a voicemail are represented by the voicemail instead of appearing twice. Threads and timelines are ordered newest first, with deterministic type and record-ID tie-breakers. Calls, voicemails, and messages are included. See Texting and inbox for SMS-specific fields, sending, delivery state, and automatic replies.
Thread properties
- Name
phone_number- Type
- string
- Description
- Normalized E.164 external phone number. This is the thread address.
- Name
contact- Type
- object | null
- Description
- Existing contact reference, including ID, display name, phone, and saved contact fields; null when no contact exists.
- Name
last_activity_at- Type
- string
- Description
- ISO 8601 creation timestamp of the latest activity.
- Name
unseen_count- Type
- integer
- Description
- Number of unseen inbound activity items, including received messages, after call/voicemail folding. Outbound calls do not count as unseen.
- Name
business_number_ids- Type
- array
- Description
- Public IDs of business numbers represented in this thread at the observation boundary.
- Name
preview- Type
- string
- Description
- Call summary, voicemail transcription, or SMS message text, with a fallback label; truncated to 160 characters.
- Name
latest_item- Type
- object
- Description
- Latest activity metadata. Full summary, transcription, message text, and recording URL are omitted.
Activity properties
- Name
id- Type
- string
- Description
- Stable call or voicemail public ID.
- Name
type- Type
- string
- Description
- call, voicemail, or sms. MMS is not implemented.
- Name
created_at- Type
- string
- Description
- ISO 8601 storage timestamp, used for ordering and seen boundaries.
- Name
business_number_id- Type
- string
- Description
- Owning business number public ID.
- Name
business_number_name- Type
- string
- Description
- Owning business number name.
- Name
seen_at- Type
- string | null
- Description
- ISO 8601 timestamp when the team marked this activity seen.
- Name
direction- Type
- string
- Description
- inbound or outbound; voicemails are inbound.
- Name
from- Type
- string
- Description
- Caller phone number.
- Name
to- Type
- string
- Description
- Destination phone number; present on calls.
- Name
duration- Type
- integer | null
- Description
- Call duration or analyzed voicemail recording length in seconds.
Call items also include state, missed, summary, nullable employee with id and name, and has_transcription. Voicemail items include transcription, recording_url, listened, and nullable linked call_id.
Extensible activity types
Treat activity type as extensible. Clients should skip types they do not understand without discarding the thread, and still follow next_cursor when a page contains no renderable items. An unfamiliar latest_item.type must not hide the thread.
The seen endpoint acknowledges the entire thread through observed_at, not just the items a client rendered. Clients that ignore activity types must not assume those items remain unseen after acknowledging that boundary.
Pagination and seen state
List responses include nullable next_cursor. Supply it unchanged as cursor to fetch the next page. Cursors are signed and bound to the company, selected business number, endpoint, and filters. Pages share the first request's observation boundary, so later arrivals do not reshuffle that result set.
Timeline responses also include observed_at. Pass that timestamp to the seen endpoint, rather than generating a timestamp on the client. Seen state is shared by the team, not per employee. The update covers unseen inbound calls and voicemails stored through that boundary, including received messages and folded calls, and preserves later arrivals. Seeing a voicemail does not mark it listened.
Invalid filters, phone numbers, timestamps, or cursors return 422. Future seen timestamps are rejected. Foreign or unknown business numbers return 404; missing authentication returns 401. Company API keys and OAuth tokens are supported. Existing calls, voicemails, and legacy seen/unseen endpoints remain unchanged.
List the inbox
List grouped activity previews. Filter by optional business_number_id, query, or unseen=true. Text queries use the existing company-isolated keyword and semantic contact search index, including contact name, company name, email, and note, but not call or voicemail bodies. At most 100 indexed contact candidates are resolved to this company's threads; new or edited contacts become searchable after indexing. Phone-only queries accept spaces, parentheses, dots, and dashes and match the normalized phone substring directly, without requiring the search index. Mixed text-and-digit queries are searched intact rather than reduced to digits. The maximum query length is 128 characters. limit defaults to 50 and is clamped to 1–100. Supply cursor for another page.
Request
curl 'https://app.phone.inc/api/v1/inbox?limit=50' \
-H "X-Api-Key: $PHONE_INC_API_KEY"
Response
{
"threads": [
{
"phone_number": "+4523909778",
"contact": null,
"last_activity_at": "2026-10-07T09:40:59Z",
"unseen_count": 1,
"business_number_ids": [
"019daef1-085e-762f-98a5-ed28d44138b8"
],
"preview": "Missed call",
"latest_item": {
"id": "019daef1-085e-7700-a1b2-c3d4e5f67890",
"type": "call",
"direction": "inbound",
"missed": true
}
}
],
"next_cursor": null
}
List activity
Read one external phone number’s calls, voicemails, and messages. E.164 is recommended; national numbers are normalized using the company country. The path phone number takes precedence over query/body values. Optional business_number_id selects one business number. limit defaults to 50 and is clamped to 1–100. Supply cursor for another page.
Request
curl 'https://app.phone.inc/api/v1/inbox/+4523909778/activity?limit=50' \
-H "X-Api-Key: $PHONE_INC_API_KEY"
Response
{
"phone_number": "+4523909778",
"contact": null,
"items": [
{
"id": "019daef1-085e-7700-a1b2-c3d4e5f67890",
"type": "call",
"created_at": "2026-10-07T09:40:59Z",
"business_number_id": "019daef1-085e-762f-98a5-ed28d44138b8",
"business_number_name": "Office",
"seen_at": null,
"direction": "inbound",
"from": "+4523909778",
"to": "+4592457318",
"state": "ended",
"missed": true,
"summary": null,
"duration": 0,
"employee": null,
"has_transcription": false
}
],
"next_cursor": null,
"observed_at": "2026-10-07T09:41:00Z"
}
Mark activity seen
Mark this thread seen through the required through timestamp returned as observed_at by the activity endpoint. Optional business_number_id limits the update to that business number. Returns 204 No Content. The operation is idempotent and broadcasts a metadata-only unseen-count invalidation.
Request
curl -X POST 'https://app.phone.inc/api/v1/inbox/+4523909778/seen' \
-H "X-Api-Key: $PHONE_INC_API_KEY" \
-H 'Content-Type: application/json' \
-d '{"through":"2026-10-07T09:41:00Z"}'