Telnyx Email Threads API
Account-wide conversation threads across every inbox, for agents operating many inboxes at once.
Account-wide conversation threads across every inbox, for agents operating many inboxes at once.
Every API here is available over the APIs.io API and to AI agents over MCP.
One button, every client — Claude, Cursor, VS Code and the rest.
https://apis.io/mcp
find_apisBrowse and filter every API in the catalog.get_api_artifactsOne API's artifacts, grouped by type.get_openapiThe primary OpenAPI for this API.find_similar_apisAPIs that look like this one.apis_io_searchSTART HERE — APIs, providers and tags for one query, each with its total.resolveTurn a domain, URL or GitHub org into the provider it belongs to.find_cohortsEvery scored population of providers in the catalog.curl "https://apis.io/api/v1/apis/telnyx:telnyx-email-threads-api"
curl "https://apis.io/api/v1/apis?limit=25"
Discovery needs no key. Ratings and market analysis are Pro.
Free tier, no form to fill in. Signing in shares your email address with us — we store it to create your key and to recognise you if you sign in with another provider. See our Privacy Policy and Terms.
A second provider on the same verified email joins the account you already have.
openapi: 3.2.0
info:
version: 2.0.0
x-latency-category: responsive
x-endpoint-cost: light
title: Telnyx Email Threads API
description: SIP trunking, SMS, MMS, Call Control and Telephony Data Services.
contact:
email: support@telnyx.com
servers:
- url: https://api.telnyx.com/v2
description: Version 2.0.0 of the Telnyx API
security:
- bearerAuth: []
tags:
- name: Email Threads
description: Account-wide conversation threads across every inbox, for agents operating many inboxes at once.
paths:
/email_threads:
get:
tags:
- Email Threads
operationId: ListEmailThreads
summary: List threads across every inbox in the account
description: 'Lists thread summaries for the whole account, newest first, using stable
cursor pagination. An agent operating many inboxes gets every
conversation in one call instead of one call per inbox. Each thread
carries its own `inbox_id` so a reply can be routed back to the right
inbox. Use `filter[inbox_id]` (repeatable) to narrow the result to
specific inboxes. Because a thread ID can be delivered to multiple
inboxes, each result is identified by its `(inbox_id, id)` pair.'
parameters:
- name: filter[inbox_id]
in: query
required: false
description: 'Restrict results to one or more inboxes. Repeat the parameter
(`filter[inbox_id][]=...&filter[inbox_id][]=...`) or pass a
comma-separated list. Omit to list every inbox in the account.
Inboxes outside the account are silently excluded. If the filter
is present, it must contain at least one non-empty UUID.
'
explode: true
schema:
type: array
minItems: 1
items:
type: string
format: uuid
- name: page[size]
in: query
required: false
description: Number of results to return. Defaults to 25; maximum is 100.
schema:
type: integer
minimum: 1
maximum: 100
default: 25
- name: page[after]
in: query
required: false
description: Opaque cursor returned by the previous page.
schema:
type: string
- name: filter[label]
in: query
required: false
description: Returns only threads carrying this label. Matching is exact and case-sensitive. Thread labels are independent of the labels on the thread's messages.
schema:
type: string
maxLength: 255
responses:
'200':
description: Paginated account-wide threads.
content:
application/json:
schema:
$ref: '#/components/schemas/InboundThreadListResponse'
example:
data:
- id: 33333333-3333-3333-3333-333333333333
record_type: email_thread
inbox_id: 11111111-1111-1111-1111-111111111111
subject: Project update
preview: null
message_count: 2
unread_count: 1
last_message_id: 55555555-5555-5555-5555-555555555555
last_message_at: '2026-07-15T12:30:00Z'
created_at: '2026-07-14T10:00:00Z'
updated_at: '2026-07-15T12:30:00Z'
labels:
- needs_review
- id: 44444444-4444-4444-4444-444444444444
record_type: email_thread
inbox_id: 22222222-2222-2222-2222-222222222222
subject: Support request
preview: null
message_count: 1
unread_count: 0
last_message_id: 66666666-6666-6666-6666-666666666666
last_message_at: '2026-07-15T09:00:00Z'
created_at: '2026-07-15T09:00:00Z'
updated_at: '2026-07-15T09:00:00Z'
labels: []
meta:
page_size: 25
page_cursor: MjAyNi0wNy0xNVQxMjozMDowMFp8MzMzMzMzMzMtMzMzMy0zMzMzLTMzMzMtMzMzMzMzMzMzMzMz
'401':
$ref: '#/components/responses/email_UnauthorizedResponse'
'404':
$ref: '#/components/responses/email_NotFoundResponse'
'422':
$ref: '#/components/responses/ValidationErrorResponse'
'503':
description: Inbound thread storage is temporarily unavailable.
content:
application/json:
schema:
$ref: '#/components/schemas/email_ErrorResponse'
example:
errors:
- code: '10016'
title: Service Unavailable
detail: Email threads are temporarily unavailable. Please try again later.
/email_threads/{thread_id}:
get:
tags:
- Email Threads
operationId: GetEmailThread
summary: Get an account-wide thread and a page of its messages
description: 'Returns a thread and a bounded page of its inbound and outbound messages,
interleaved in chronological order. The `inbox_id` returned by the list
endpoint is required because a thread ID can occur in multiple inboxes.
Only messages matching that `(inbox_id, thread_id)` pair are returned. Threads outside the account
return an opaque 404.'
parameters:
- name: thread_id
in: path
required: true
description: Email thread UUID.
schema:
type: string
format: uuid
- name: inbox_id
in: query
required: true
description: Inbox UUID that, together with `thread_id`, identifies the thread.
schema:
type: string
format: uuid
- name: page[size]
in: query
required: false
description: Number of thread messages to return. Defaults to 25; maximum is 100.
schema:
type: integer
minimum: 1
maximum: 100
default: 25
- name: page[after]
in: query
required: false
description: Opaque message cursor returned by the previous thread-detail page.
schema:
type: string
responses:
'200':
description: Thread summary and chronological messages.
content:
application/json:
schema:
type: object
properties:
data:
$ref: '#/components/schemas/InboundThreadDetail'
meta:
$ref: '#/components/schemas/email_PaginationMeta'
required:
- data
- meta
example:
data:
id: 33333333-3333-3333-3333-333333333333
record_type: email_thread
inbox_id: 11111111-1111-1111-1111-111111111111
subject: Project update
preview: null
message_count: 1
unread_count: 0
last_message_id: 55555555-5555-5555-5555-555555555555
last_message_at: '2026-07-15T12:30:00Z'
created_at: '2026-07-15T12:30:00Z'
updated_at: '2026-07-15T12:30:00Z'
labels:
- needs_review
messages:
- id: 55555555-5555-5555-5555-555555555555
record_type: email_message
direction: inbound
status: received
inbox_id: 11111111-1111-1111-1111-111111111111
thread_id: 33333333-3333-3333-3333-333333333333
message_id: <message@example.com>
in_reply_to: null
references: []
from:
email: alice@example.com
name: Alice
to:
- email: agent@inbox.example.test
cc: []
bcc: []
reply_to: []
subject: Project update
text_body_url: null
html_body_url: null
reply_text: Thanks, I will send it today.
has_quoted_text: true
headers: {}
inline_files: []
attachments: []
labels: []
read_at: null
received_at: '2026-07-15T12:30:00Z'
sent_at: null
created_at: '2026-07-15T12:30:00Z'
updated_at: '2026-07-15T12:30:00Z'
meta:
page_size: 25
'401':
$ref: '#/components/responses/email_UnauthorizedResponse'
'404':
$ref: '#/components/responses/email_NotFoundResponse'
'422':
$ref: '#/components/responses/ValidationErrorResponse'
'503':
description: Inbound thread storage is temporarily unavailable.
content:
application/json:
schema:
$ref: '#/components/schemas/email_ErrorResponse'
example:
errors:
- code: '10016'
title: Service Unavailable
detail: Email threads are temporarily unavailable. Please try again later.
components:
schemas:
email_PaginationMeta:
type: object
properties:
page_size:
type: integer
minimum: 1
maximum: 100
page_cursor:
type: string
description: Cursor for the next page, when more results are available.
required:
- page_size
InboundThreadDetail:
allOf:
- $ref: '#/components/schemas/InboundThread'
- type: object
properties:
messages:
type: array
items:
$ref: '#/components/schemas/ThreadMessage'
required:
- messages
ThreadMessage:
type: object
properties:
id:
type: string
format: uuid
record_type:
type: string
enum:
- email_message
direction:
type: string
enum:
- inbound
- outbound
status:
type: string
description: Received for inbound messages; the current send status for outbound messages.
inbox_id:
type: string
format: uuid
thread_id:
type: string
format: uuid
message_id:
type: string
nullable: true
description: RFC Message-ID header. Null is possible for legacy outbound messages.
in_reply_to:
type: string
nullable: true
references:
type: array
description: Ordered RFC Message-ID values from the References header.
items:
type: string
from:
$ref: '#/components/schemas/InboundEmailAddress'
to:
type: array
items:
$ref: '#/components/schemas/InboundEmailAddress'
cc:
type: array
items:
$ref: '#/components/schemas/InboundEmailAddress'
bcc:
type: array
items:
$ref: '#/components/schemas/InboundEmailAddress'
reply_to:
type: array
items:
$ref: '#/components/schemas/InboundEmailAddress'
subject:
type: string
nullable: true
text_body_url:
type: string
format: uri
nullable: true
description: URL for an offloaded plain-text body. Null means the body is not offloaded to a URL; an inline plain-text body may still exist but is not returned on list reads. `reply_text` and `has_quoted_text` are persisted during ingest before any body offload.
html_body_url:
type: string
format: uri
nullable: true
description: URL for an offloaded HTML body. Null means the body is not offloaded to a URL; an inline HTML body may still exist but is not returned on list reads. Reply extraction uses only the plain-text body during ingest.
reply_text:
type: string
nullable: true
description: Conservatively extracted new-reply content persisted from the plain-text body during ingest. Null means no plain-text extraction input was available or extraction was skipped or failed; HTML bodies are not parsed.
has_quoted_text:
type: boolean
description: Whether conservative plain-text extraction detected a quoted tail. False does not prove that the source contains no quoted content.
headers:
type: object
additionalProperties: true
inline_files:
type: array
items:
type: object
additionalProperties: true
attachments:
type: array
items:
type: object
additionalProperties: true
labels:
type: array
description: 'Mutable message labels used for agent workflow state (for example `spam`, `needs_review`, `processed`). Distinct from the immutable send-time `tags` on outbound messages: labels are never propagated to Email Detail Records or Mission Control reporting. Always empty for outbound messages. Labels on a message are independent of the labels on its thread.'
items:
type: string
maxLength: 255
maxItems: 50
read_at:
type: string
format: date-time
nullable: true
description: Time the inbound message was marked read. Null means unread.
received_at:
type: string
format: date-time
nullable: true
description: Receipt time for inbound messages; null for outbound messages.
sent_at:
type: string
format: date-time
nullable: true
description: Creation/send-acceptance time for outbound messages; null for inbound messages.
created_at:
type: string
format: date-time
updated_at:
type: string
format: date-time
required:
- id
- record_type
- direction
- status
- inbox_id
- thread_id
- message_id
- in_reply_to
- references
- from
- to
- cc
- bcc
- reply_to
- subject
- text_body_url
- html_body_url
- reply_text
- has_quoted_text
- headers
- inline_files
- attachments
- labels
- read_at
- received_at
- sent_at
- created_at
- updated_at
email_ErrorResponse:
type: object
properties:
errors:
type: array
items:
$ref: '#/components/schemas/ErrorObject'
suppressed:
type: array
description: Present when every recipient is suppressed, so the request is rejected and no message is created.
items:
$ref: '#/components/schemas/SuppressedRecipient'
required:
- errors
InboundThread:
type: object
properties:
id:
type: string
format: uuid
record_type:
type: string
enum:
- email_thread
inbox_id:
type: string
format: uuid
subject:
type: string
nullable: true
preview:
type: string
nullable: true
maxLength: 200
message_count:
type: integer
minimum: 1
description: Total inbound and outbound messages in the thread.
unread_count:
type: integer
minimum: 0
description: Unread inbound messages; outbound messages never increment this count.
last_message_id:
type: string
format: uuid
last_message_at:
type: string
format: date-time
created_at:
type: string
format: date-time
updated_at:
type: string
format: date-time
labels:
type: array
description: Mutable thread labels used for agent workflow state. Independent of the labels on the thread's messages, and distinct from the send-time `tags` on outbound messages.
items:
type: string
maxLength: 255
maxItems: 50
required:
- id
- record_type
- inbox_id
- subject
- preview
- message_count
- unread_count
- last_message_id
- last_message_at
- created_at
- updated_at
- labels
ErrorObject:
type: object
properties:
code:
type: string
description: Telnyx error code. Send admission errors include account daily quota 10011 and sender-domain ramp code domain_graduation_limit_exceeded. Edge idempotency errors use 10027 or 10036. Fallback 404/500 responses from the framework may use string status codes ('404', '500') instead.
enum:
- '10001'
- '10006'
- '10007'
- '10011'
- '10015'
- '10016'
- '10019'
- domain_graduation_limit_exceeded
- recipient_suppressed
- reputation_suspended
- '404'
- '500'
- '10027'
- '10036'
title:
type: string
detail:
description: Human-readable error detail. Changeset responses may return a structured object.
oneOf:
- type: string
- type: object
additionalProperties: true
source:
type: object
additionalProperties: true
nullable: true
meta:
type: object
additionalProperties: true
nullable: true
description: Additional metadata. Present on 401 errors with a documentation URL.
required:
- code
- title
- detail
InboundThreadListResponse:
type: object
properties:
data:
type: array
items:
$ref: '#/components/schemas/InboundThread'
meta:
$ref: '#/components/schemas/email_PaginationMeta'
required:
- data
- meta
InboundEmailAddress:
type: object
properties:
email:
type: string
format: email
name:
type: string
required:
- email
SuppressedRecipient:
type: object
properties:
to:
type: string
format: email
description: Suppressed recipient email address.
reason:
type: string
description: Suppression reason returned by the recipient suppression service.
scope:
type: string
description: Scope at which the suppression applies.
override_allowed:
type: boolean
description: Whether an authorized send may override this suppression.
required:
- to
- reason
- scope
- override_allowed
responses:
email_UnauthorizedResponse:
description: Not authorized (10006).
content:
application/json:
schema:
$ref: '#/components/schemas/email_ErrorResponse'
example:
errors:
- code: '10006'
title: Not authorized
detail: Invalid API key
meta:
url: https://developers.telnyx.com/docs/overview/errors/10006
email_NotFoundResponse:
description: Resource not found (10001).
content:
application/json:
schema:
$ref: '#/components/schemas/email_ErrorResponse'
example:
errors:
- code: '10001'
title: Not Found
detail: The requested resource was not found
ValidationErrorResponse:
description: Validation Failed (10015) or changeset validation error.
content:
application/json:
schema:
$ref: '#/components/schemas/email_ErrorResponse'
example:
errors:
- code: '10015'
title: Validation Failed
detail: subject can't be blank
source:
pointer: /data/attributes/subject
securitySchemes:
BearerAuth:
type: http
scheme: bearer
bearerFormat: API key
description: 'Telnyx API key supplied as `Authorization: Bearer <token>`. In production, auth may be validated by the API gateway and forwarded via Telnyx auth headers.'
Payment:
type: apiKey
in: header
name: Authorization
description: 'Machine Payment Protocol credential used on paid retries, sent as `Authorization: Payment ...`. Obtained by paying a challenge returned in the `WWW-Authenticate` header of a 402 response. This is not a Telnyx API key; initial challenge requests use standard bearer authentication instead.'
agent-memory_bearerAuth:
type: http
scheme: bearer
description: Telnyx API key
bearerAuth:
type: http
scheme: bearer
branded-calling_bearerAuth:
type: http
scheme: bearer
description: Telnyx API key. Generate one at https://portal.telnyx.com/#/app/api-keys.
collections_bearerAuth:
type: http
scheme: bearer
description: Telnyx API key. Collections and results are automatically scoped to the authenticated user's organization.
number-reputation_bearerAuth:
type: http
scheme: bearer
description: Telnyx API key. Generate one at https://portal.telnyx.com/#/app/api-keys.
oauthClientAuth:
type: oauth2
flows:
clientCredentials:
tokenUrl: https://api.telnyx.com/v2/oauth/token
scopes:
admin: Administrative access to Telnyx resources
authorizationCode:
authorizationUrl: https://api.telnyx.com/v2/oauth/authorize
tokenUrl: https://api.telnyx.com/v2/oauth/token
refreshUrl: https://api.telnyx.com/v2/oauth/token
scopes:
admin: Administrative access to Telnyx resources
description: OAuth 2.0 authentication for Telnyx API and MCP integrations
outbound-voice-profiles_bearerAuth:
type: http
scheme: bearer
bearerFormat: JWT
pronunciation-dicts_bearerAuth:
type: http
scheme: bearer
description: Telnyx API v2 key. Obtain from https://portal.telnyx.com
rcs-registration_bearerAuth:
type: http
scheme: bearer
bearerFormat: API key
stored-payment-transactions_bearerAuth:
type: http
scheme: bearer
bearerFormat: JWT
transcriptions-search_bearerAuth:
type: http
scheme: bearer
description: Telnyx API key. Results are automatically scoped to the authenticated user's organization.
web-search_bearerAuth:
type: http
scheme: bearer
description: Telnyx API key
x-service-info:
categories:
- communication
- developer-tools
docs:
apiReference: https://developers.telnyx.com
homepage: https://telnyx.com
llms: https://telnyx.com/llms.txt