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

# Get a chat

> Returns one chat: the exchange between one of your lines and one contact.

* **Credential:** an API key. A trial key returns `401 unauthorized`.
* **Line-scoped keys:** a [line-scoped key](/authentication#line-scoped-keys) gets `404 not_found` for a chat on a line outside its list.
* **Events:** none.
* **Personal data:** `contact_handle` is a phone number or an email address. Request it only when needed, do not copy it into logs, tickets or other tools, and refer to a contact by an id of your own.
* **Line owner:** a chat belongs to its line: after a line changes owner, the account that owns the line lists its chats, those of earlier owners included. See [A chat is never deleted](/guides/receiving-messages#a-chat-is-never-deleted).
* **What is returned:** the chat, with its counters and, on a shared line, the `outbound_number` that serves the contact. See [Chats](/guides/receiving-messages#chats).

## Errors

| Status | `error.code` | When |
| - | - | - |
| 404 | `not_found` | The chat is unknown, its line is not yours, or it is on a line outside the list of a line-scoped key. |

The errors that every operation shares are in [Errors](/errors-and-rate-limits#errors).


## OpenAPI

````yaml GET /v1/chats/{chat_id}
openapi: 3.0.0
info:
  title: iSnap API
  version: 2.45.0
  description: >-
    The iSnap API sends and receives iMessage, RCS and SMS on real phone lines,
    manages those lines, and reports events through webhooks. Every message is
    sent to a real recipient, with an `isnap_live_` key and with an
    `isnap_test_` key alike. Retry a `429` after `Retry-After` seconds. Retry a
    `500` or a `503` up to 2 times, with exponential backoff. Do not retry any
    other `4xx`: fix the request. Retry a write only on an operation that honors
    `Idempotency-Key`, with the key of the first attempt. Responses carry
    personal data: handles, names and message text.
servers:
  - url: https://api.isnap.ai
security:
  - bearerAuth: []
paths:
  /v1/chats/{chat_id}:
    get:
      summary: Get a chat
      description: >-
        Returns one chat. A chat belongs to its line, not to an account: after a
        line changes owner, the account that owns the line reads its chats,
        those of earlier owners included. Accepts an API key. A chat that does
        not exist, whose line is not yours, or that is on a line outside a
        line-scoped key's `line_ids` returns `404 not_found`. `contact_handle`
        is personal data: a phone number or an email address.
      parameters:
        - schema:
            type: string
            pattern: ^chat_[0-9A-Za-z]{25}$
            description: 'Chat id: `chat_` followed by 25 letters or digits.'
          required: true
          description: 'Chat id: `chat_` followed by 25 letters or digits.'
          name: chat_id
          in: path
      responses:
        '200':
          description: The chat.
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/ChatEnvelope'
        '400':
          description: >-
            Invalid request. `error.code` is `validation_failed` when a
            parameter, a header or the body does not match its schema:
            `error.issues` then lists each problem.
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/ErrorEnvelope'
        '401':
          description: No valid credential. `error.code` is `unauthorized`.
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/ErrorEnvelope'
        '404':
          description: >-
            Not found. `error.code` is `not_found`: the chat does not exist, its
            line is not yours, or it is on a line outside the key's `line_ids`.
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/ErrorEnvelope'
        '429':
          description: >-
            Too many requests. `error.code` is `rate_limit_exceeded` when more
            than 100 requests came from the same network address in 60 seconds,
            whatever their API key or account: wait `error.retry_after` seconds.
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/ErrorEnvelope'
        '500':
          description: >-
            Unexpected failure. `error.code` is `internal_error`. An operation
            that takes a JSON body also returns it when the body, sent as
            `application/json`, is not valid JSON. Quote `trace_id` when you
            report it to iSnap.
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/ErrorEnvelope'
      security:
        - bearerAuth: []
components:
  schemas:
    ChatEnvelope:
      type: object
      properties:
        success:
          type: boolean
          enum:
            - true
          description: Always `true` on a success response.
        data:
          $ref: '#/components/schemas/Chat'
        trace_id:
          type: string
          description: >-
            Trace id of the request that produced this response: 32 lowercase
            hexadecimal characters. Quote it when you report a problem to iSnap.
        request_id:
          type: string
          description: >-
            Id of the request that produced this response: `req_` followed by 25
            letters or digits.
      required:
        - success
        - data
        - trace_id
        - request_id
    ErrorEnvelope:
      type: object
      properties:
        success:
          type: boolean
          enum:
            - false
          description: Always `false` on an error response.
        data:
          nullable: true
          description: Always `null` on an error response.
        error:
          type: object
          properties:
            status:
              type: integer
              description: The HTTP status of the response.
            code:
              type: string
              description: >-
                Stable machine-readable code that names the refusal. Branch on
                this value.
            message:
              type: string
              description: >-
                Text for a person. It can change between versions: do not branch
                on it.
            retry_after:
              type: integer
              nullable: true
              description: >-
                Seconds to wait before the next attempt. Set on the `429`
                responses that know a delay, where the `Retry-After` header
                carries the same value. When it is above 60 seconds, do not wait
                in a request: schedule the call, or report the time. `null` on
                every other error.
            retry_at:
              type: string
              nullable: true
              description: >-
                ISO 8601 timestamp at which the refusal ends. Set only on `429
                rebind_cap_reached`. `null` on every other error.
            issues:
              type: array
              nullable: true
              items:
                type: object
                properties:
                  path:
                    type: array
                    items:
                      anyOf:
                        - type: string
                        - type: number
                    description: >-
                      Where the problem is: the field names and array indexes
                      that lead to it.
                  message:
                    type: string
                    description: Text for a person.
                  code:
                    type: string
                    description: >-
                      Kind of problem. On `validation_failed`, for example
                      `invalid_type`, `invalid_value`, `invalid_format`,
                      `invalid_union`, `invalid_key`, `invalid_element`,
                      `too_small`, `too_big`, `not_multiple_of`,
                      `unrecognized_keys` or `custom`. The list is open: read
                      `path` and `message`.
                  min:
                    type: integer
                    description: >-
                      Smallest accepted value. Present only on
                      `limit_out_of_bounds`, `mac_quantity_not_a_pack`,
                      `byop_reduction_strands_mac_sessions` and
                      `byop_reduction_strands_byod_lines`.
                  max:
                    type: integer
                    description: >-
                      Largest accepted value. Present only on
                      `limit_out_of_bounds` and
                      `mac_sessions_exceed_byop_lines`, and on the `too_big`
                      issue of an `Idempotency-Key` header longer than 255
                      characters.
                required:
                  - path
                  - message
                  - code
              description: >-
                Problems found in the request, one entry each. Set on most `400
                validation_failed` responses and on the refusals that name a
                field: a refused `handle` of `POST /v1/lookup` has `issues:
                null`. `null` on every other error.
          required:
            - status
            - code
            - message
            - retry_after
            - retry_at
            - issues
          description: >-
            What went wrong. The six fields are always present; `retry_after`,
            `retry_at` and `issues` are `null` when they do not apply.
        trace_id:
          type: string
          description: >-
            Trace id of the request that produced this response: 32 lowercase
            hexadecimal characters. Quote it when you report a problem to iSnap.
        request_id:
          type: string
          description: >-
            Id of the request that produced this response: `req_` followed by 25
            letters or digits.
      required:
        - success
        - data
        - error
        - trace_id
        - request_id
      description: The body of an error response.
    Chat:
      type: object
      properties:
        id:
          type: string
          description: 'Chat id: `chat_` followed by 25 letters or digits.'
          example: chat_5h7FqK2mNpQ8rT3vW9xY1zA4b
        line_id:
          type: string
          pattern: ^line_[0-9A-Za-z]{25}$
          description: Id of the line of the chat.
        contact_handle:
          type: string
          description: >-
            The handle that opened the chat: the E.164 form of `to` when a
            message you sent opened it, or the sender's handle as the line's
            device stores it, a phone number or an email address, when a
            received message opened it. The typing and read operations take only
            a chat whose `contact_handle` is a phone number in E.164. It is
            personal data. When the line receives messages in a group, they are
            recorded in one chat that shows one handle only, the first sender
            seen: nothing marks that chat as a group.
        outbound_number:
          type: string
          nullable: true
          description: >-
            On a shared line, the phone number that serves this contact, or
            `null` when none is assigned: the next message to the contact is
            then given a number. Always `null` on a line that is not a shared
            line.
        last_message_at:
          type: string
          description: >-
            Time of the last message of the chat, sent or received. Equals
            `created_at` while the chat has no message.
        message_count:
          type: integer
          minimum: 0
          description: >-
            Number of messages recorded in the chat since it was created,
            whoever owned the line. It does not decrease when iSnap deletes
            messages at the end of their retention. It decreases by one when
            iSnap deletes the copy of a message sent through the API that the
            device of the line had also reported as typed on the device.
        unread_count:
          type: integer
          minimum: 0
          description: >-
            Number of inbound messages received in the chat since it was
            created. Marking the chat as read does not reset it.
        created_at:
          type: string
          description: >-
            When iSnap created the chat: at the first message in either
            direction.
        updated_at:
          type: string
          description: When the chat last changed.
      required:
        - id
        - line_id
        - contact_handle
        - outbound_number
        - last_message_at
        - message_count
        - unread_count
        - created_at
        - updated_at
      description: >-
        The messages between one line and one contact. iSnap creates a chat at
        the first message in either direction and never deletes it: a chat stays
        listed after its messages are deleted. It uses the same chat for both
        directions when the device of the line stores the handle of the contact
        in the form of the `to` you send to. A chat belongs to its line, not to
        an account: after a line changes owner, the account that owns the line
        lists its chats, those of earlier owners included, and their counters
        include the messages of earlier owners.
  securitySchemes:
    bearerAuth:
      type: http
      scheme: bearer
      description: >-
        An API key created in the iSnap dashboard, or a trial key, sent as
        `Authorization: Bearer <key>`. An API key starts with `isnap_live_` or
        `isnap_test_`; both act on the same account, lines and billing. A trial
        key acts on its trial only.

````

This documentation is built and hosted on [Mintlify](https://mintlify.com), a developer documentation platform.