How do I import issues using the API?

Last updated: October 29, 2026

To import conversation data with threaded messages, you need to use the /import/issues endpoint rather than the standard API endpoints. This endpoint allows you to preserve conversation threading by importing multiple messages within a single issue.

Using the Import Issues Endpoint

The /import/issues endpoint accepts the following structure:

Migration Options: For importing historical email data into Pylon, you have two options: (1) Purchase Pylon's Data Migration service, which works with a migration vendor that can import emails from any true inbox (not group inboxes), or (2) use this self-service API endpoint to backfill tickets yourself.

{
  "account_id": "string",
  "assignee_id": "string",
  "attachment_urls": [
    "string"
  ],
  "created_at": "string",
  "custom_fields": [
    {
      "slug": "string",
      "value": "string",
      "values": [
        "string"
      ]
    }
  ],
  "external_issues": [
    {
      "external_issue_id": "string",
      "source": "string"
    }
  ],
  "external_refs": {
    "intercom_conversation_id": "string",
    "zendesk_ticket_id": "string"
  },
  "first_response_time": "string",
  "issue_number": 0,
  "messages": [
    {
      "attachment_urls": [
        "string"
      ],
      "body_html": "string",
      "contact_id": "string",
      "created_at": "string",
      "is_private": true,
      "user_id": "string"
    }
  ],
  "partner_account_id": "string",
  "requester_id": "string",
  "resolution_time": "string",
  "state": "string",
  "tags": [
    "string"
  ],
  "team_id": "string",
  "title": "string",
  "updated_at": "string"
}

Required Fields

For the issue:

  1. title (string) - The title of the issue

  2. state (string) - Issue state (e.g., "new", "waiting_on_you", "waiting_on_customer", "on_hold", "closed", or a custom status slug)

  3. messages (array) - At least one message is required

For each message in the messages array:

  • body_html (string) - The HTML content of the message

  • is_private (boolean) - Whether the message is private (internal) or public

  • Either user_id OR contact_id (exactly one required, not both)

Understanding Message Authors

  • user_id - Use this for messages from your team members

  • contact_id - Use this for messages from customers/requestors

  • is_private - Set to true for internal notes (appears as yellow internal notes in Pylon), false for public messages

You would have to create these contacts as well as users before using the import endpoint.

It's also recommended to include account_id and created_at timestamp for better data organization.

Optional fields:

  • issue_number (integer) - Keeps the ticket number from the platform you're migrating from. Leave it unset unless you need historical ticket numbers, so Pylon assigns its own. When set, it must be greater than 0, lower than your organization's current ticket number counter, and not already in use.

  • partner_account_id (string) - A partner account that serves the issue's account. Requires account_id.

Note: This import endpoint is different from the standard API endpoints and is specifically designed for data migration scenarios where you need to preserve conversation threading.

Importing more messages into an existing issue

To add messages to an issue that already exists, use POST /import/issues/{id}/messages with a messages array in the same format as above. Imported messages keep the timestamps you send and don't start triggers, notifications, or AI side effects.

Updating AI data

Issues uploaded using the /import endpoint do not trigger any topic generation for our Knowledge Gaps or Feature Request features. If you do bulk import issues, please reach out to us through our shared slack channel or via email to migrations@usepylon.com.