---
title: "Migrate connection"
method: POST
path: "/vault/connections/{unified_api}/{service_id}/migrate"
tags: ["Connections"]
---

# Migrate connection

`POST /vault/connections/{unified_api}/{service_id}/migrate`

Migrate the connection to the target connector, keeping its credentials and connection state
(settings, metadata, configuration, subscriptions, consents). The source connection record is
removed WITHOUT revoking or disconnecting the downstream token.

Available migration targets are declared per connector — refer to the connector's
documentation page or the Connector API's `migration_targets` field.

Migrated tokens carry the source connector's OAuth scopes, so operations exclusive to the
target connector may require re-authorization.

Retries are idempotent: a partially-completed migration resumes where it left off.

## Path parameters

- `service_id` string, required
- `unified_api` string, required

## Headers

- `x-apideck-consumer-id` string, required
- `x-apideck-app-id` string, required

## Request body

- ConnectionMigrateData
  - `target_service_id` string, required — The service id of the connector to migrate this connection to. Must be one of the source connector's declared migration targets.

## Response `200`

Connection created

- CreateConnectionResponse
  - `status_code` integer, required — HTTP Response Status Code
  - `status` string, required — HTTP Response Status
  - `data` Connection, required
    - `id` string — The unique identifier of the connection.
    - `service_id` string — The ID of the service this connection belongs to.
    - `name` string — The name of the connection
    - `tag_line` string
    - `unified_api` string — The unified API category where the connection belongs to.
    - `state` 'available' | 'callable' | 'added' | 'authorized' | 'invalid' — [Connection state flow](#section/Connection-state)
    - `integration_state` 'disabled' | 'needs_configuration' | 'configured' — The current state of the Integration.
    - `auth_type` 'oauth2' | 'apiKey' | 'basic' | 'custom' | 'none' — Type of authorization used by the connector
    - `oauth_grant_type` 'authorization_code' | 'client_credentials' | 'password' — OAuth grant type used by the connector. More info: https://oauth.net/2/grant-types
    - `status` 'live' | 'upcoming' | 'requested' — Status of the connection.
    - `enabled` boolean — Whether the connection is enabled or not. You can enable or disable a connection using the Update Connection API.
    - `website` string — The website URL of the connection
    - `icon` string — A visual icon of the connection, that will be shown in the Vault
    - `logo` string — The logo of the connection, that will be shown in the Vault
    - `authorize_url` string, nullable — The OAuth redirect URI. Redirect your users to this URI to let them authorize your app in the connector's UI. Before you can use this URI, you must add `redirect_uri` as a query parameter to the `authorize_url`. Be sure to URL encode the `redirect_uri` part. Your users will be redirected to this `redirect_uri` after they granted access to your app in the connector's UI.
    - `revoke_url` string, nullable — The OAuth revoke URI. Redirect your users to this URI to revoke this connection. Before you can use this URI, you must add `redirect_uri` as a query parameter. Your users will be redirected to this `redirect_uri` after they granted access to your app in the connector's UI.
    - `settings` object, nullable — Connection settings. Values will persist to `form_fields` with corresponding id
    - `metadata` object, nullable — Attach your own consumer specific metadata
      - `company_id` string — Normalized identifier of the authorized organization, copied from the connector-specific setting (e.g. Xero tenant_id, QuickBooks realm_id, NetSuite account_id).
    - `form_fields` FormField[] — The settings that are wanted to create a connection.
      - `id` string — The unique identifier of the form field.
      - `label` string — The label of the field
      - `placeholder` string, nullable — The placeholder for the form field
      - `description` string, nullable — The description of the form field
      - `type` 'text' | 'checkbox' | 'tel' | 'email' | 'url' | 'textarea' | 'select' | 'filtered-select' | 'multi-select' | 'datetime' | 'date' | 'time' | 'number' | 'password'
      - `required` boolean — Indicates if the form field is required, which means it must be filled in before the form can be submitted
      - `custom_field` boolean
      - `allow_custom_values` boolean — Only applicable to select fields. Allow the user to add a custom value though the option select if the desired value is not in the option select list.
      - `disabled` boolean, nullable — Indicates if the form field is displayed in a “read-only” mode.
      - `hidden` boolean, nullable — Indicates if the form field is not displayed but the value that is being stored on the connection.
      - `deprecated` boolean, nullable — When the setting is deprecated, it should be hidden from the user interface. The value will still be stored on the connection for the sake of backwards compatibility.
      - `sensitive` boolean, nullable — Indicates if the form field contains sensitive data, which will display the value as a masked input.
      - `prefix` string, nullable — Prefix to display in front of the form field.
      - `suffix` string, nullable — Suffix to display next to the form field.
      - `options` FormFieldOption[]
        - union
          - SimpleFormFieldOption
            - `label` string, required
            - `value` union
              - …
            - `option_type` 'simple', required
          - FormFieldOptionGroup
            - `id` string
            - `label` string, required
            - `options` SimpleFormFieldOption[], required
              - …
            - `option_type` 'group', required
    - `configuration` object[]
      - `resource` string
      - `defaults` object[]
        - `target` 'custom_fields' | 'resource'
        - `id` string
        - `options` FormFieldOption[]
          - union
            - SimpleFormFieldOption
              - …
            - FormFieldOptionGroup
              - …
        - `value` union
          - string
          - integer
          - number
          - boolean
          - union[]
            - union
              - …
    - `configurable_resources` string[]
    - `resource_schema_support` string[]
    - `resource_settings_support` string[]
    - `validation_support` boolean
    - `schema_support` boolean
    - `settings_required_for_authorization` string[] — List of settings that are required to be configured on integration before authorization can occur
    - `subscriptions` WebhookSubscription[]
      - `downstream_id` string — The ID of the downstream service
      - `unify_event_types` string[] — The list of Unify Events this connection is subscribed to
      - `downstream_event_types` string[] — The list of downstream Events this connection is subscribed to
      - `execute_url` string — The URL the downstream is sending to when the event is triggered
      - `created_at` string — The date and time the webhook subscription was created downstream
    - `has_guide` boolean — Whether the connector has a guide available in the developer docs or not (https://docs.apideck.com/connectors/{service_id}/docs/consumer+connection).
    - `custom_mappings` CustomMapping[] — List of custom mappings configured for this connection
      - `id` string — Target Field ID
      - `label` string — Target Field name to use as a label
      - `description` string, nullable — Target Field description
      - `value` string — Target Field Mapping value
      - `key` string — Target Field Key
      - `required` boolean — Target Field Mapping is required
      - `custom_field` boolean — This mapping represents a finder for a custom field
      - `consumer_id` string, nullable — Consumer ID
      - `example` string, nullable — Target Field Mapping example value from downstream
    - `consent_state` 'implicit' | 'pending' | 'granted' | 'denied' | 'revoked' | 'requires_reconsent' — The current consent state of the connection
    - `consents` ConsentRecord[] — Immutable array of consent records for compliance and audit purposes
      - `id` string, required — Unique identifier for this consent record
      - `created_at` string, required — ISO timestamp when consent was recorded
      - `granted` boolean, required — Whether consent was granted (true) or denied/revoked (false)
      - `resources` union, required — Data scopes resource configuration that can be either detailed field permissions or a wildcard
        - object — Map of resources to field-level permissions
        - '*' — Wildcard indicating all resources and fields when Data Scopes is selected
    - `latest_consent` ConsentRecord
      - `id` string, required — Unique identifier for this consent record
      - `created_at` string, required — ISO timestamp when consent was recorded
      - `granted` boolean, required — Whether consent was granted (true) or denied/revoked (false)
      - `resources` union, required — Data scopes resource configuration that can be either detailed field permissions or a wildcard
        - object — Map of resources to field-level permissions
        - '*' — Wildcard indicating all resources and fields when Data Scopes is selected
    - `application_data_scopes` DataScopes
      - `enabled` boolean — Whether Data Scopes is enabled for this application
      - `updated_at` string — ISO timestamp of when the Data Scopes configuration was last modified
      - `resources` union — Data scopes resource configuration that can be either detailed field permissions or a wildcard
        - object — Map of resources to field-level permissions
        - '*' — Wildcard indicating all resources and fields when Data Scopes is selected
    - `health` 'revoked' | 'missing_settings' | 'needs_consent' | 'pending_confirmation' | 'needs_auth' | 'pending_refresh' | 'ok' | 'degraded' — Operational health status of the connection
    - `credentials_expire_at` number — Unix timestamp in milliseconds when credentials will be deleted if token refresh continues to fail. A value of 0 indicates no active retention window (connection is healthy or not using OAuth token refresh).
    - `last_refresh_failed_at` number — Unix timestamp in milliseconds of the last failed token refresh attempt. A value of 0 indicates no recent failures. This field is used internally to enforce cooldown periods between retry attempts.
    - `last_downstream_error_at` number — Unix timestamp in milliseconds of the last downstream unreachable error (502/504 network class). A value of 0 indicates no active error. Connection remains callable while this is set; health surfaces as 'degraded'.
    - `created_at` number
    - `updated_at` number, nullable
  - `_raw` Raw, nullable — Raw response from the integration when raw=true query param is provided

## Other responses

- `400` — Bad Request
- `401` — Unauthorized
- `402` — Payment Required
- `404` — The specified resource was not found
- `409` — Conflict — a connection already exists for the target connector
- `422` — Unprocessable
- `default` — Unexpected error

---

[API](https://skmtc.net/apideck-libraries/apis/vault-api.md) · [All operations](https://skmtc.net/apideck-libraries/apis/vault-api/llms.txt) · [OpenAPI document](https://skmtc-service-staging.skmtc.workers.dev/v1/apis/apideck-libraries/vault-api/versions/1b8e8b6feb36/schema)
