Telnyx Email Events API

Retrieve account-level email events and event statistics.

Operations 2

GET /email_events List account email events #
GET /email_events/stats Get email event statistics #

Work with this as data

Every API here is available over the APIs.io API and to AI agents over MCP.

MCP server

One button, every client — Claude, Cursor, VS Code and the rest.

https://apis.io/mcp

Tools for apis

7 MCP tools reach this
  • 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.
All 92 tools →

Call it yourself

curl for this page
This API
curl "https://apis.io/api/v1/apis/telnyx:telnyx-email-events-api"
All apis
curl "https://apis.io/api/v1/apis?limit=25"

Discovery needs no key. Ratings and market analysis are Pro.

Get an API key

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 Specification

telnyx-email-events-api-openapi.yml Raw ↑
openapi: 3.2.0
info:
  version: 2.0.0
  x-latency-category: responsive
  x-endpoint-cost: light
  title: Telnyx Email Events 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 Events
  description: Retrieve account-level email events and event statistics.
paths:
  /email_events:
    get:
      tags:
      - Email Events
      operationId: ListEmailEvents
      summary: List account email events
      description: 'Lists account-level email events sorted oldest first by `occurred_at asc, id asc`. Each row contains a legacy email.-prefixed event_type and an additive canonical_event_type. Gateway rejection renders email.failed with canonical email.gw_reject; ambiguous injection timeout renders email.injection_timeout in both; MTA expiration renders email.bounced with canonical email.expired. Message-scoped queued, sending, sandbox, cancelled, and daily_limit_exceeded rows fan out per durable recipient with stable derived IDs matching webhook delivery. Scheduled is the cardinality exception: account polling retains one message-scoped scheduled row with its stored event ID, while scheduled webhook publication fans out per recipient with derived IDs; reconcile scheduled events by message ID, event type, and occurrence time rather than event UUID. Recipient-scoped stored rows retain their stored UUIDs across polling and webhook delivery. Legacy names are derived from stored rows; an AdminBounce row stored as failed renders email.failed in polling while its webhook retains email.bounced, both with canonical email.failed.'
      parameters:
      - $ref: '#/components/parameters/email_PageSize'
      - name: page[cursor]
        in: query
        description: Opaque URL-safe Base64 cursor returned by a previous event list response. The legacy `page[after]` and flat `page_cursor` forms are also accepted.
        required: false
        schema:
          type: string
        example: eyJpbn...EifQ
      - name: event_type
        in: query
        description: 'Comma-separated list of event types to include. Also accepts repeated

          query parameters (e.g. event_type=delivered&event_type=bounced).

          Unknown values return no matches.


          Dual-name compatibility: values are accepted

          bare or `email.`-prefixed. A legacy value keeps matching the

          rows it matched pre-rename — no widening: `failed` also

          matches the rows that now store the canonical names of the

          outcomes it covered (`gw_reject`, `injection_timeout`,

          `expired`); `bounced` matches stored `bounced` rows only

          (recipient-scoped Expirations stored `failed` pre-rename and

          never matched `bounced`, so `expired` is deliberately not a

          `bounced` expansion). A canonical value matches its own rows

          plus legacy rows whose recorded payload evidence proves that

          outcome (`expired` also surfaces legacy `bounced` rows with

          `bounce_category: transient`). The additive

          `canonical_event_type` field in each response row names the

          canonical outcome.

          '
        required: false
        schema:
          oneOf:
          - type: string
          - type: array
            items:
              type: string
        example: delivered,bounced,opened
      - name: email_id
        in: query
        description: Filter events for a specific email message UUID. Invalid UUID values are silently ignored (no filter applied).
        required: false
        schema:
          type: string
          format: uuid
      - $ref: '#/components/parameters/FromTimestamp'
      - $ref: '#/components/parameters/ToTimestamp'
      responses:
        '200':
          description: Paginated list of account email events.
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/AccountEmailEventListResponse'
              example:
                data:
                - id: f3a2c1d0-1234-4abc-9def-67890abcdef0
                  event_type: email.delivered
                  canonical_event_type: email.delivered
                  occurred_at: '2026-07-06T18:24:00.000Z'
                  recipient_id: 7c1e9a44-2f60-4d1b-9a0e-3c7b5e8d1f22
                  payload:
                    id: b0c7e8cb-6227-4c74-9f32-c7f80c30934b
                    recipient_id: 7c1e9a44-2f60-4d1b-9a0e-3c7b5e8d1f22
                    status: delivered
                    occurred_at: '2026-07-06T18:24:00.000Z'
                    from:
                      email: sender@example.com
                      name: Telnyx
                    to:
                      email: recipient@example.com
                      name: null
                      kind: to
                    subject: Welcome
                meta:
                  page_size: 50
                  time_range:
                    from: '2026-07-01T00:00:00Z'
                    to: '2026-07-31T00:00:00Z'
        '401':
          $ref: '#/components/responses/email_UnauthorizedResponse'
  /email_events/stats:
    get:
      tags:
      - Email Events
      operationId: GetEmailEventStats
      summary: Get email event statistics
      description: Returns counts and rates for email events over a time range. The default start time is 30 days ago.
      parameters:
      - $ref: '#/components/parameters/FromTimestamp'
      - $ref: '#/components/parameters/ToTimestamp'
      responses:
        '200':
          description: Email event statistics.
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/EmailEventStatsResponse'
              example:
                data:
                  record_type: email_event_stats
                  counts:
                    queued: 0
                    sent: 0
                    delivered: 0
                    deferred: 0
                    bounced: 0
                    opened: 0
                    clicked: 0
                    complained: 0
                    unsubscribed: 0
                    failed: 0
                  rates:
                    delivery_rate: 0
                    bounce_rate: 0
                    deferred_rate: 0
                    open_rate: 0
                    click_rate: 0
                    complaint_rate: 0
                  time_range:
                    from: '2024-01-23T18:10:02.574Z'
                    to: '2024-01-23T18:10:02.574Z'
        '401':
          $ref: '#/components/responses/email_UnauthorizedResponse'
components:
  parameters:
    FromTimestamp:
      name: from
      in: query
      description: Inclusive ISO 8601 start timestamp. Defaults to 30 days ago when omitted.
      required: false
      schema:
        type: string
        format: date-time
    ToTimestamp:
      name: to
      in: query
      description: Inclusive ISO 8601 end timestamp. When `from` is provided without `to`, defaults to `from + 30 days`.
      required: false
      schema:
        type: string
        format: date-time
    email_PageSize:
      name: page_size
      in: query
      description: Number of results to return. Defaults to 25; maximum is 100. Invalid values are clamped to the valid range.
      required: false
      schema:
        type: integer
        minimum: 1
        maximum: 100
        default: 25
  schemas:
    EmailEventStatsResponse:
      type: object
      properties:
        data:
          $ref: '#/components/schemas/EmailEventStats'
      required:
      - data
    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
    AccountEmailEvent:
      type: object
      description: 'An account-polling event. The envelope is webhook-shaped, but polling preserves stored-event cardinality: queued, sending, sandbox, cancelled, and daily_limit_exceeded message events fan out per recipient; scheduled remains one message-scoped row. Payload fields vary among recipient-scoped, message-scoped, and minimal fallback rows.'
      properties:
        id:
          type: string
          format: uuid
          description: Event UUID.
        event_type:
          type: string
          pattern: ^email\.
          example: email.delivered
          description: Legacy customer-visible event name, prefixed with `email.`. Gateway rejections render `email.failed`; MTA expirations render `email.bounced`. Webhook subscription allowlists match the legacy name.
        canonical_event_type:
          type: string
          pattern: ^email\.
          example: email.delivered
          description: Additive canonical outcome name, prefixed with `email.`. Gateway rejection is `email.gw_reject`, ambiguous injection timeout is `email.injection_timeout`, and MTA expiration is `email.expired`. Unchanged outcomes retain their names. Existing stored rows are translated only when recorded payload evidence proves the outcome; a legacy failed row is not guessed or sharpened.
        occurred_at:
          type: string
          format: date-time
        recipient_id:
          type: string
          format: uuid
          description: Durable email recipient UUID. Present for recipient-scoped events, including each queued, sending, sandbox, cancelled, and daily_limit_exceeded fan-out event.
        payload:
          $ref: '#/components/schemas/AccountEmailEventPayload'
      required:
      - id
      - event_type
      - canonical_event_type
      - occurred_at
      - payload
    EmailWebhookRecipient:
      type: object
      properties:
        email:
          type: string
          format: email
        name:
          type: string
          nullable: true
        kind:
          type: string
          enum:
          - to
          - cc
          - bcc
      required:
      - email
    EmailEventRates:
      type: object
      description: Recipient-level event rates as percentages, rounded to 2 decimal places.
      properties:
        delivery_rate:
          type: number
          format: float
          minimum: 0
          description: Delivered recipients / queued recipients as a percentage.
        bounce_rate:
          type: number
          format: float
          minimum: 0
          description: Bounced recipients / queued recipients as a percentage.
        deferred_rate:
          type: number
          format: float
          minimum: 0
          description: Deferred recipients / queued recipients as a percentage.
        open_rate:
          type: number
          format: float
          minimum: 0
          description: Recipients opened / recipients delivered as a percentage.
        click_rate:
          type: number
          format: float
          minimum: 0
          description: Recipients clicked / recipients opened as a percentage.
        complaint_rate:
          type: number
          format: float
          minimum: 0
          description: Recipients with a complaint feedback report / delivered recipients as a percentage.
      required:
      - delivery_rate
      - bounce_rate
      - deferred_rate
      - open_rate
      - click_rate
      - complaint_rate
    EmailEventCounts:
      type: object
      description: Recipient-level outcome counts for the queried time range. Each to, cc, and bcc recipient counts separately; repeated events of the same type for the same message and recipient count once. Partial MTA injection results count successful recipients as sent and unsuccessful recipients as failed. Only the ten listed event types are counted; other valid event types (scheduled, cancelled, sandbox, sending, rejected) are not included in stats.
      properties:
        queued:
          type: integer
          minimum: 0
        sent:
          type: integer
          minimum: 0
        delivered:
          type: integer
          minimum: 0
        deferred:
          type: integer
          minimum: 0
        bounced:
          type: integer
          minimum: 0
        opened:
          type: integer
          minimum: 0
        clicked:
          type: integer
          minimum: 0
        complained:
          type: integer
          minimum: 0
        unsubscribed:
          type: integer
          minimum: 0
        failed:
          type: integer
          minimum: 0
      required:
      - queued
      - sent
      - delivered
      - deferred
      - bounced
      - opened
      - clicked
      - complained
      - unsubscribed
      - failed
    AccountEmailEventListResponse:
      type: object
      properties:
        data:
          type: array
          items:
            $ref: '#/components/schemas/AccountEmailEvent'
        meta:
          $ref: '#/components/schemas/EventPaginationMeta'
      required:
      - data
      - meta
    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
    TimeRange:
      type: object
      properties:
        from:
          type: string
          format: date-time
          nullable: true
        to:
          type: string
          format: date-time
          nullable: true
      required:
      - from
      - to
    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
    EmailEventStats:
      type: object
      properties:
        record_type:
          type: string
          enum:
          - email_event_stats
        counts:
          $ref: '#/components/schemas/EmailEventCounts'
        rates:
          $ref: '#/components/schemas/EmailEventRates'
        time_range:
          $ref: '#/components/schemas/TimeRange'
      required:
      - record_type
      - counts
      - rates
      - time_range
    AccountEmailEventPayload:
      type: object
      additionalProperties: true
      description: Payload returned by GET /email_events. Every row includes id, status, and occurred_at. Recipient-scoped rows also include recipient_id, from, subject, and exactly one object-valued to, cc, or bcc field. Legacy or message-scoped rows can omit recipient_id and use object-valued or string-valued to/cc fields, including an empty string when no address exists; bcc is redacted. If the related message or recipient cannot be loaded, the minimal fallback can omit from, subject, and recipient fields. Additional persisted public evidence can be present.
      properties:
        id:
          type: string
          format: uuid
          description: Email message UUID.
        recipient_id:
          type: string
          format: uuid
          description: Durable email recipient UUID. Present for recipient-scoped events.
        status:
          type: string
          description: 'Stored event outcome slug, not the authoritative recipient status. Account polling returns the stored name, including suppression, scan, and quarantine lifecycle names. Webhooks retain legacy payload names: gateway rejections use failed and MTA expirations use bounced. New sharp stored rows can expose gw_reject, injection_timeout, or expired. Use the envelope canonical_event_type to identify the outcome across surfaces.'
          enum:
          - queued
          - deferred
          - scheduled
          - cancelled
          - sandbox
          - sending
          - sent
          - failed
          - delivered
          - bounced
          - complained
          - suppressed
          - rejected
          - opened
          - clicked
          - unsubscribed
          - daily_limit_exceeded
          - scan_deferred
          - quarantined
          - quarantine_released
          - quarantine_release_dispatched
          - quarantine_rejected
          - quarantine_expired
          - gw_reject
          - injection_timeout
          - expired
        occurred_at:
          type: string
          format: date-time
        from:
          $ref: '#/components/schemas/AccountEmailEventSender'
        to:
          oneOf:
          - $ref: '#/components/schemas/EmailWebhookRecipient'
          - type: string
            description: Legacy message-scoped address, or an empty string when absent.
        cc:
          oneOf:
          - $ref: '#/components/schemas/EmailWebhookRecipient'
          - type: string
            description: Legacy message-scoped address, or an empty string when absent.
        bcc:
          oneOf:
          - $ref: '#/components/schemas/EmailWebhookRecipient'
          - type: string
            enum:
            - redacted
        subject:
          type: string
      required:
      - id
      - status
      - occurred_at
    EventPaginationMeta:
      type: object
      properties:
        page_size:
          type: integer
          minimum: 1
          maximum: 100
        time_range:
          $ref: '#/components/schemas/TimeRange'
        page_cursor:
          type: string
          description: Cursor for the next page, when more results are available.
      required:
      - page_size
      - time_range
    AccountEmailEventSender:
      type: object
      additionalProperties: false
      description: Sender projection in account event polling. The display name is explicitly null when the message has no sender name.
      properties:
        email:
          type: string
          format: email
        name:
          type: string
          nullable: true
      required:
      - email
      - name
  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
  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