---
title: "Connect to External Ticket"
method: POST
path: "/v2/tickets/{ticket_id}/connect"
tags: ["Ticket API"]
---

# Connect to External Ticket

`POST /v2/tickets/{ticket_id}/connect`

Connect an existing Serval ticket to an existing external ticket in a sync channel. This establishes ongoing bidirectional sync between the tickets without creating a new external ticket. The external ticket must already exist in the target system.

## Path parameters

- `ticket_id` string, required — The Serval ticket ID to connect

## Request body

- object
  - `channelTarget` union — Unified channel target that works across all syncing scenarios. This is used by SyncTicketToChannel and ConnectTicketToExternalTicket endpoints.
    - object
      - `email` SvhelpPubapimodelsEmailChannelTarget, required — For Email channels - uses team email config (no integration needed)
        - `targetUserType` 'CHANNEL_SYNC_USER_TYPE_UNSPECIFIED' | 'CHANNEL_SYNC_TARGET_USER_TICKET_ASSIGNEE' | 'CHANNEL_SYNC_TARGET_USER_TICKET_REQUESTOR'
    - object
      - `slackChannel` SvhelpPubapimodelsSlackChannelTarget, required — For Slack channels (public or private) - link a ticket to a thread in a Slack channel. The channel must already be connected to Serval (i.e., Serval bot is in the channel and the channel is configured with a non-disabled mode).
        - `integrationId` string — Integration ID that identifies the Slack app instance
        - `channelId` string — The Slack channel ID (e.g., "C1234567890" for public, "G1234567890" for private)
    - object
      - `slackDm` SvhelpPubapimodelsSlackDMChannelTarget, required — For Slack DM channels - need to specify which user to sync to
        - `integrationId` string — Integration ID that identifies the Slack app instance
        - `targetUserType` 'CHANNEL_SYNC_USER_TYPE_UNSPECIFIED' | 'CHANNEL_SYNC_TARGET_USER_TICKET_ASSIGNEE' | 'CHANNEL_SYNC_TARGET_USER_TICKET_REQUESTOR'
    - object
      - `ticketSource` SvhelpPubapimodelsTicketSourceChannelTarget, required — For ticket source channels (Jira, ServiceNow, Linear, Zendesk, Freshservice, etc.)
        - `ticketSourceId` string — The ticket source ID from svflow - identifies which external system Deprecated: Use integration_id instead
        - `integrationId` string — The integration ID - identifies which external system/integration to sync to
  - `externalTicketId` string — The external ticket ID (format depends on the channel type): - For Slack (slack_channel or slack_dm): MUST be in the format "channelId:threadTs" Example: "C9DDYQ1B4:1779146751.061339" where channelId is the Slack channel ID (e.g., "C9DDYQ1B4") and threadTs is the Slack message timestamp (e.g., "1779146751.061339") - For ServiceNow and other integrations: the sys_id or unique identifier from the external system This should be a globally unique identifier for the external ticket.
  - `externalTicketData` GoogleProtobufStruct — `Struct` represents a structured data value, consisting of fields which map to dynamically typed values. In some languages, `Struct` might be supported by a native representation. For example, in scripting languages like JS a struct is represented as an object. The details of that representation are described together with the proto support for the language. The JSON representation for `Struct` is JSON object.
  - `externalTicketSubtype` string, nullable — Optional: Subtype of the external ticket within the integration. For ServiceNow, use "incident" or "requested_item" to specify the type. This determines which sync handler is used for ongoing synchronization.
  - `accountedForMessageIds` string[] — Optional: Serval message IDs on this ticket to register as already present in the external ticket's channel. Registered messages are skipped by the egresser, so they will not be re-sent to the external system after the connection is established. Use this when you have already posted a summary of the prior conversation to the external system and do not want the individual historical messages replayed on top of it. Each message must belong to this ticket.

## Response `200`

Success

- SvhelpPublicapiConnectTicketToExternalTicketResponse

## Other responses

- `default` — Error

---

[API](https://skmtc.net/serval/apis/serval-public-api.md) · [All operations](https://skmtc.net/serval/apis/serval-public-api/llms.txt) · [OpenAPI document](https://skmtc-service-staging.skmtc.workers.dev/v1/apis/serval/serval-public-api/versions/0549515e9384/schema)
