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

# Get a conversation

> Full timeline for one conversation: messages, no-reply expirations, label changes.

`events[]` is a discriminated-union timeline. The discriminator is
always `type`. Today the union includes:

| Type                      | What it is                                                        |
| ------------------------- | ----------------------------------------------------------------- |
| `message`                 | A message sent or received. Body, direction, snippet, timestamps. |
| `no_reply_expired`        | The no-reply timer fired without a reply. Carries `waitedMs`.     |
| `label_added`             | A label was added (today, dashboard-only).                        |
| `label_removed`           | A label was removed.                                              |
| `archived` / `unarchived` | The conv was archived or unarchived.                              |

To pull just the messages from the timeline:

```js theme={null}
const messages = conv.events
  .filter((e) => e.type === "message")
  .map((e) => e.message);
```

Same idea for filtering to no-reply expirations, label changes, etc.

## Snapshot, not subscription

This endpoint serves a fresh snapshot every call, off the materialized
state inside the durable object that owns the conversation. There is
no "give me the diff since last read" — and you don't need one. The
pattern we want you to use is:

* **Events stream** tells you something changed on `convId X`.
* **GET /conversations/:convId** gives you the current state.

You never reduce events into your own copy of the thread. We're the
reducer. See [Live thread list](/guides/live-thread-list).


## OpenAPI

````yaml GET /v1/identities/{handle}/conversations/{convId}
openapi: 3.1.0
info:
  title: inboxbase.ai API
  version: 1.0.0
  description: >-
    Managed email infrastructure for outbound. Send, reply, and read threads
    through one API; we run the mailbox pool, rotation, warmup, and
    deliverability under the hood.
  contact:
    name: inboxbase.ai support
    email: support@inboxbase.ai
    url: https://inboxbase.ai
servers:
  - url: https://api.inboxbase.ai
    description: Production
security:
  - bearerAuth: []
tags:
  - name: Send
    description: Sending email.
  - name: Conversations
    description: Reading threads.
  - name: Events
    description: Pull-mode event stream.
paths:
  /v1/identities/{handle}/conversations/{convId}:
    get:
      tags:
        - Conversations
      summary: Get one conversation
      description: >-
        Full timeline for one conversation. Discriminated-union `events[]` is
        the source of truth; everything else on the response is a projection of
        it.
      operationId: getConversation
      parameters:
        - $ref: '#/components/parameters/Handle'
        - name: convId
          in: path
          required: true
          description: Conversation id.
          schema:
            type: string
            pattern: ^conv_[0-9a-f]+$
      responses:
        '200':
          description: Conversation snapshot.
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/GetConversationResponse'
        '401':
          $ref: '#/components/responses/Unauthorized'
        '404':
          $ref: '#/components/responses/NotFound'
components:
  parameters:
    Handle:
      name: handle
      in: path
      required: true
      description: Identity handle, URL-encoded.
      schema:
        type: string
        example: alice.acme@inboxbase.ai
  schemas:
    GetConversationResponse:
      type: object
      properties:
        identity:
          type: string
        conversation:
          type: object
          properties:
            id:
              type: string
            with:
              type: string
            subject:
              type: string
            messageCount:
              type: integer
            archived:
              type: boolean
            labels:
              type: array
              items:
                type: string
            lastEventAt:
              type: integer
              format: int64
            lastEventAtIso:
              type: string
              format: date-time
            noReplyAt:
              type:
                - integer
                - 'null'
              format: int64
              description: >-
                Future timestamp the next no-reply alarm will fire at, or `null`
                if no timer is currently armed.
            noReplyAtIso:
              type:
                - string
                - 'null'
              format: date-time
            lastNoReplyAt:
              type:
                - integer
                - 'null'
              format: int64
            lastNoReplyAtIso:
              type:
                - string
                - 'null'
              format: date-time
            events:
              type: array
              items:
                $ref: '#/components/schemas/TimelineEvent'
    TimelineEvent:
      description: Discriminated union; the discriminator is `type`.
      oneOf:
        - $ref: '#/components/schemas/MessageTimelineEvent'
        - $ref: '#/components/schemas/NoReplyExpiredTimelineEvent'
        - $ref: '#/components/schemas/LabelTimelineEvent'
        - $ref: '#/components/schemas/ArchiveTimelineEvent'
      discriminator:
        propertyName: type
    Error:
      type: object
      required:
        - error
      properties:
        error:
          type: string
          description: Short machine-friendly error code.
        details:
          type: object
          additionalProperties: true
          description: Optional structured context.
    MessageTimelineEvent:
      type: object
      required:
        - type
        - ts
        - message
      properties:
        type:
          type: string
          enum:
            - message
        ts:
          type: integer
          format: int64
        tsIso:
          type: string
          format: date-time
        message:
          type: object
          properties:
            id:
              type: string
            direction:
              type: string
              enum:
                - out
                - in
            from:
              type: string
            to:
              type: string
            cc:
              type: string
            subject:
              type: string
            text:
              type: string
            html:
              type: string
            snippet:
              type: string
            ts:
              type: integer
              format: int64
    NoReplyExpiredTimelineEvent:
      type: object
      required:
        - type
        - ts
        - afterMessageId
        - waitedMs
      properties:
        type:
          type: string
          enum:
            - no_reply_expired
        ts:
          type: integer
          format: int64
        tsIso:
          type: string
          format: date-time
        afterMessageId:
          type: string
          description: The message id whose timer fired.
        waitedMs:
          type: integer
          format: int64
          description: Actual elapsed time.
    LabelTimelineEvent:
      type: object
      required:
        - type
        - ts
        - label
      properties:
        type:
          type: string
          enum:
            - label_added
            - label_removed
        ts:
          type: integer
          format: int64
        tsIso:
          type: string
          format: date-time
        label:
          type: string
    ArchiveTimelineEvent:
      type: object
      required:
        - type
        - ts
      properties:
        type:
          type: string
          enum:
            - archived
            - unarchived
        ts:
          type: integer
          format: int64
        tsIso:
          type: string
          format: date-time
  responses:
    Unauthorized:
      description: Missing or invalid API key.
      content:
        application/json:
          schema:
            $ref: '#/components/schemas/Error'
    NotFound:
      description: Identity or conversation not in this org.
      content:
        application/json:
          schema:
            $ref: '#/components/schemas/Error'
  securitySchemes:
    bearerAuth:
      type: http
      scheme: bearer
      bearerFormat: sk_live_...

````