---
title: "Import a historical ticket"
method: POST
path: "/tickets/import"
tags: ["Tickets"]
---

# Import a historical ticket

`POST /tickets/import`

## Request

- Base URL: `https://there-there.app/api`
- URL: `https://there-there.app/api/tickets/import`
- Auth: HTTP bearer

Backfills a past conversation with its original timestamps, status, and full message thread. Nothing is sent or triggered: no email, workflows, notifications, or automations run. Requires an admin token. Has its own rate limit of 300 requests per minute, separate from the standard API limit.

## Headers

- `X-Workspace-Id` integer

## Request body

- object
  - `channel` string, required: Channel ULID.
  - `subject` string, required
  - `status` 'open' | 'waiting' | 'closed' | 'spam', required
  - `created_at` string, date-time, nullable: When the ticket was originally created. Must be in the past. Defaults to the earliest message.
  - `closed_at` string, date-time, nullable: When the ticket was resolved. Must be in the past. Used only when status is closed.
  - `external_id` string, nullable: Your own identifier for the ticket. Re-importing the same external_id returns the existing ticket.
  - `assignee_email` string, email, nullable: Email of a workspace member to assign. Ignored unless it is an active member with access to the channel.
  - `tags` string[]: Tag names to attach. A tag is created if it does not exist yet. Two names that only differ in punctuation cannot both exist, so a name the workspace already occupies answers 422 and the ticket is not imported.
  - `from_contact` object, required
    - `email` string, email, required
    - `name` string, nullable
  - `messages` object[], required: The conversation, in chronological order.
    - `type` 'inbound' | 'outbound' | 'note', required
    - `body` string, required: HTML body of the message.
    - `created_at` string, date-time, nullable: When the message was sent. Must be in the past. Defaults to the ticket created_at.
    - `author_email` string, email, nullable: Email of the agent who wrote an outbound message or note.
    - `author_name` string, nullable: Display name of that agent, used when author_email is not a workspace member.
    - `external_id` string, nullable: Your own identifier for the message, stored for correlation.
    - `attachment_ids` string[]: Upload tokens from POST /attachments. Embed a token as <img src="cid:TOKEN"> in the body to render it inline.

## Response `201`

Ticket imported

- object
  - `data` Ticket
    - `id` integer
    - `ulid` string
    - `number` integer
    - `subject` string
    - `status` 'open' | 'waiting' | 'closed' | 'spam'
    - `channel` Channel
      - `id` integer
      - `ulid` string
      - `name` string
      - `type` 'email' | 'widget'
      - `color` string
      - `email_address` string, nullable
    - `assignee` User
      - `id` integer
      - `name` string
      - `email` string, email
      - `avatar_url` string, nullable
      - `timezone` string, nullable
    - `assigned_team` Team
      - `id` integer
      - `ulid` string
      - `name` string
      - `description` string, nullable
      - `logo_url` string, nullable
      - `member_count` integer
    - `contact` Contact
      - `id` integer
      - `ulid` string
      - `name` string, nullable
      - `email` string, email
      - `avatar_url` string, nullable
      - `company` ContactCompany
        - `ulid` string
        - `name` string
        - `domain` string, nullable
      - `ticket_count` integer, nullable
      - `last_activity_at` string, date-time, nullable
      - `notes` string, nullable
    - `tags` Tag[]
      - `id` integer
      - `ulid` string
      - `name` string
      - `color` string
    - `custom_fields` TicketCustomField[]: Every custom field that applies to this ticket's channel, whether or not it holds a value. Returned on GET /tickets/{ticket} and on every ticket write response; omitted from the paginated list.
      - `ulid` string
      - `name` string
      - `type` 'text' | 'single_select' | 'multi_select'
      - `value` string, nullable: Set for text fields only; null for the two select types.
      - `selected_option_ulids` string[]: Empty for text fields and for select fields with no value.
      - `options` TicketCustomFieldOption[]: The options an admin defined, in the order they arranged them. Empty for text fields.
        - `ulid` string
        - `name` string
        - `color` string, nullable
        - `icon` string, nullable
    - `latest_message_preview` string, nullable
    - `summary` string, nullable
    - `title` string, nullable
    - `from_address` string, nullable
    - `created_at` string, date-time
    - `updated_at` string, date-time
    - `last_activity_at` string, date-time

## Other responses

- `403`: Not allowed
- `422`: Validation failed

---

[API](https://skmtc.dev/there-there/apis/there-there-api.md) · [All operations](https://skmtc.dev/there-there/apis/there-there-api/llms.txt) · [OpenAPI document](https://skmtc.dev/there-there/apis/there-there-api/revisions/1811fb0febc1?raw)
