> ## Documentation Index
> Fetch the complete documentation index at: https://docs.tempmaillab.com/llms.txt
> Use this file to discover all available pages before exploring further.

> ## Agent Instructions
> Treat docs/openapi.yaml as the normative public API contract.
> Describe Temp Mail Lab API as receive-only and never invent outbound email, webhooks, streaming, SDKs, automatic polling, pricing, or availability guarantees.
> Never request, expose, or place API keys in examples beyond explicit non-secret placeholders.

# List messages for an email

> Returns non-expired messages for an email owned by the authenticated
account. The service never calls this endpoint automatically. Messages
disappear from reads 15 minutes after arrival even if physical cleanup is
still running. A 304 response is still charged.




## OpenAPI

````yaml /docs/openapi.yaml get /v1/emails/{email_id}/messages
openapi: 3.1.0
info:
  title: Temp Mail Lab API
  version: 0.1.0-draft
  summary: Receive-only temporary email API for Temp Mail Lab Premium customers.
  description: |
    Create isolated temporary email addresses and retrieve messages, raw RFC 822
    source, and attachments. This contract is a pre-launch draft.

    The API never sends email and never performs automatic polling. A client
    decides when to make each request, and every processed request follows the
    documented usage policy.
  contact:
    name: Temp Mail Lab
    url: https://tempmaillab.com
  license:
    name: Temp Mail Lab Terms of Service
    url: https://tempmaillab.com/terms
servers:
  - url: https://api.tempmaillab.com
    description: Production (available only after the approved public launch)
security:
  - bearerAuth: []
tags:
  - name: Domains
    description: Discover domains that can create and receive API email.
  - name: Emails
    description: Create and inspect isolated temporary email reservations.
  - name: Messages
    description: List and retrieve received messages and their private content.
  - name: Usage
    description: Inspect the authenticated account's current request allowance.
paths:
  /v1/emails/{email_id}/messages:
    get:
      tags:
        - Messages
      summary: List messages for an email
      description: >
        Returns non-expired messages for an email owned by the authenticated

        account. The service never calls this endpoint automatically. Messages

        disappear from reads 15 minutes after arrival even if physical cleanup
        is

        still running. A 304 response is still charged.
      operationId: listEmailMessages
      parameters:
        - $ref: '#/components/parameters/EmailId'
        - $ref: '#/components/parameters/Limit'
        - $ref: '#/components/parameters/Cursor'
        - $ref: '#/components/parameters/IfNoneMatch'
      responses:
        '200':
          description: Current non-expired messages.
          headers:
            X-Request-Id:
              $ref: '#/components/headers/RequestId'
            RateLimit-Limit:
              $ref: '#/components/headers/RateLimitLimit'
            RateLimit-Remaining:
              $ref: '#/components/headers/RateLimitRemaining'
            RateLimit-Reset:
              $ref: '#/components/headers/RateLimitReset'
            ETag:
              $ref: '#/components/headers/ETag'
            Cache-Control:
              $ref: '#/components/headers/PrivateNoStore'
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/MessageList'
        '304':
          $ref: '#/components/responses/NotModifiedCharged'
        '400':
          $ref: '#/components/responses/BadRequestCharged'
        '401':
          $ref: '#/components/responses/Unauthorized'
        '403':
          $ref: '#/components/responses/Forbidden'
        '404':
          $ref: '#/components/responses/NotFoundCharged'
        '429':
          $ref: '#/components/responses/RateLimited'
        '500':
          $ref: '#/components/responses/ServerError'
        '503':
          $ref: '#/components/responses/ServiceUnavailable'
components:
  parameters:
    EmailId:
      name: email_id
      in: path
      required: true
      description: Opaque email identifier. The address itself is never used as a path ID.
      schema:
        $ref: '#/components/schemas/EmailId'
    Limit:
      name: limit
      in: query
      required: false
      description: Maximum number of resources to return.
      schema:
        type: integer
        minimum: 1
        maximum: 100
        default: 50
    Cursor:
      name: cursor
      in: query
      required: false
      description: >-
        Opaque cursor returned by the previous page. Do not construct or modify
        it.
      schema:
        type: string
        minLength: 1
        maxLength: 512
    IfNoneMatch:
      name: If-None-Match
      in: header
      required: false
      description: Return 304 when the current representation matches this entity tag.
      schema:
        type: string
  headers:
    RequestId:
      description: Opaque request identifier for support and audit correlation.
      required: true
      schema:
        type: string
        pattern: ^req_[A-Za-z0-9_-]{16,80}$
    RateLimitLimit:
      description: >-
        Current authoritative request allowance visible to this key. Separate
        short-window safety limits may reject bursts with 429.
      required: true
      schema:
        type: integer
        minimum: 0
    RateLimitRemaining:
      description: Requests remaining in the current authoritative allowance window.
      required: true
      schema:
        type: integer
        minimum: 0
    RateLimitReset:
      description: >-
        UTC Unix timestamp when the current authoritative allowance window
        resets.
      required: true
      schema:
        type: integer
        minimum: 0
    ETag:
      description: Entity tag for a conditional one-shot read.
      required: true
      schema:
        type: string
    PrivateNoStore:
      description: Sensitive API responses must not be stored by shared or browser caches.
      required: true
      schema:
        type: string
        const: private, no-store
    RetryAfter:
      description: Seconds until the client may retry.
      required: true
      schema:
        type: integer
        minimum: 1
  schemas:
    MessageList:
      type: object
      additionalProperties: false
      required:
        - data
        - pagination
      properties:
        data:
          type: array
          items:
            $ref: '#/components/schemas/MessageSummary'
        pagination:
          $ref: '#/components/schemas/Pagination'
    EmailId:
      type: string
      pattern: ^eml_[A-Za-z0-9_-]{10,64}$
      examples:
        - eml_4p9g2t7n8w
    MessageSummary:
      type: object
      additionalProperties: false
      required:
        - id
        - email_id
        - from
        - to
        - subject
        - received_at
        - expires_at
        - size_bytes
        - attachment_count
      properties:
        id:
          $ref: '#/components/schemas/MessageId'
        email_id:
          $ref: '#/components/schemas/EmailId'
        from:
          type: string
          description: Sanitized sender header value.
        to:
          type: array
          items:
            type: string
        subject:
          type: string
          description: Sanitized subject header value.
        received_at:
          type: string
          format: date-time
        expires_at:
          type: string
          format: date-time
          description: >-
            Message, raw source, and attachments expire 15 minutes after
            arrival.
        size_bytes:
          type: integer
          minimum: 0
        attachment_count:
          type: integer
          minimum: 0
    Pagination:
      type: object
      additionalProperties: false
      required:
        - has_more
        - next_cursor
      properties:
        has_more:
          type: boolean
        next_cursor:
          type:
            - string
            - 'null'
    ErrorResponse:
      type: object
      additionalProperties: false
      required:
        - error
      properties:
        error:
          $ref: '#/components/schemas/ErrorObject'
    MessageId:
      type: string
      pattern: ^msg_[A-Za-z0-9_-]{10,64}$
      examples:
        - msg_7c2m9v4k8q
    ErrorObject:
      type: object
      additionalProperties: false
      required:
        - code
        - message
        - request_id
      properties:
        code:
          type: string
          pattern: ^[a-z][a-z0-9_]{2,63}$
        message:
          type: string
        request_id:
          type: string
        details:
          type: array
          items:
            $ref: '#/components/schemas/ErrorDetail'
    ErrorDetail:
      type: object
      additionalProperties: false
      required:
        - reason
      properties:
        field:
          type: string
        reason:
          type: string
  responses:
    NotModifiedCharged:
      description: Representation has not changed. This authenticated request is charged.
      headers:
        X-Request-Id:
          $ref: '#/components/headers/RequestId'
        RateLimit-Limit:
          $ref: '#/components/headers/RateLimitLimit'
        RateLimit-Remaining:
          $ref: '#/components/headers/RateLimitRemaining'
        RateLimit-Reset:
          $ref: '#/components/headers/RateLimitReset'
        ETag:
          $ref: '#/components/headers/ETag'
        Cache-Control:
          $ref: '#/components/headers/PrivateNoStore'
    BadRequestCharged:
      description: >-
        Authenticated request could not be processed because its syntax or
        parameters are invalid. Charged.
      headers:
        X-Request-Id:
          $ref: '#/components/headers/RequestId'
        RateLimit-Limit:
          $ref: '#/components/headers/RateLimitLimit'
        RateLimit-Remaining:
          $ref: '#/components/headers/RateLimitRemaining'
        RateLimit-Reset:
          $ref: '#/components/headers/RateLimitReset'
        Cache-Control:
          $ref: '#/components/headers/PrivateNoStore'
      content:
        application/json:
          schema:
            $ref: '#/components/schemas/ErrorResponse'
          examples:
            invalidCursor:
              value:
                error:
                  code: invalid_request
                  message: The request parameters are invalid.
                  request_id: req_a1b2c3d4e5f6g7h8
                  details:
                    - field: cursor
                      reason: invalid
    Unauthorized:
      description: >-
        Missing, malformed, revoked, or environment-invalid API key. Not
        charged.
      headers:
        X-Request-Id:
          $ref: '#/components/headers/RequestId'
        Cache-Control:
          $ref: '#/components/headers/PrivateNoStore'
      content:
        application/json:
          schema:
            $ref: '#/components/schemas/ErrorResponse'
          examples:
            invalidKey:
              value:
                error:
                  code: invalid_api_key
                  message: A valid API key is required.
                  request_id: req_a1b2c3d4e5f6g7h8
    Forbidden:
      description: >-
        Authenticated account is not entitled to the requested operation. Not
        charged.
      headers:
        X-Request-Id:
          $ref: '#/components/headers/RequestId'
        Cache-Control:
          $ref: '#/components/headers/PrivateNoStore'
      content:
        application/json:
          schema:
            $ref: '#/components/schemas/ErrorResponse'
    NotFoundCharged:
      description: >-
        Resource is absent, expired, or not owned by the authenticated account.
        Charged.
      headers:
        X-Request-Id:
          $ref: '#/components/headers/RequestId'
        RateLimit-Limit:
          $ref: '#/components/headers/RateLimitLimit'
        RateLimit-Remaining:
          $ref: '#/components/headers/RateLimitRemaining'
        RateLimit-Reset:
          $ref: '#/components/headers/RateLimitReset'
        Cache-Control:
          $ref: '#/components/headers/PrivateNoStore'
      content:
        application/json:
          schema:
            $ref: '#/components/schemas/ErrorResponse'
          examples:
            notFound:
              value:
                error:
                  code: resource_not_found
                  message: The requested resource was not found.
                  request_id: req_a1b2c3d4e5f6g7h8
    RateLimited:
      description: >-
        A short-window safety or authoritative quota limit was reached. Not
        charged.
      headers:
        X-Request-Id:
          $ref: '#/components/headers/RequestId'
        RateLimit-Limit:
          $ref: '#/components/headers/RateLimitLimit'
        RateLimit-Remaining:
          $ref: '#/components/headers/RateLimitRemaining'
        RateLimit-Reset:
          $ref: '#/components/headers/RateLimitReset'
        Retry-After:
          $ref: '#/components/headers/RetryAfter'
        Cache-Control:
          $ref: '#/components/headers/PrivateNoStore'
      content:
        application/json:
          schema:
            $ref: '#/components/schemas/ErrorResponse'
          examples:
            rateLimited:
              value:
                error:
                  code: rate_limit_exceeded
                  message: Too many requests. Retry after the indicated delay.
                  request_id: req_a1b2c3d4e5f6g7h8
    ServerError:
      description: >-
        The service failed before completing the operation. Not charged; never
        represented as an empty success.
      headers:
        X-Request-Id:
          $ref: '#/components/headers/RequestId'
        Cache-Control:
          $ref: '#/components/headers/PrivateNoStore'
      content:
        application/json:
          schema:
            $ref: '#/components/schemas/ErrorResponse'
    ServiceUnavailable:
      description: >-
        A required isolated API dependency is temporarily unavailable. Not
        charged.
      headers:
        X-Request-Id:
          $ref: '#/components/headers/RequestId'
        Retry-After:
          $ref: '#/components/headers/RetryAfter'
        Cache-Control:
          $ref: '#/components/headers/PrivateNoStore'
      content:
        application/json:
          schema:
            $ref: '#/components/schemas/ErrorResponse'
  securitySchemes:
    bearerAuth:
      type: http
      scheme: bearer
      bearerFormat: tml_live_...
      description: >
        Send a live API key in the Authorization header. Keys in query strings
        are

        rejected. A staging key never authenticates against production.

````