# Migrating Integrations

Use the Vault API's [import endpoint](/apis/vault/reference#operation/connectionsImport) to bring an
existing, already-authorized integration (a connection your users authorized outside Apideck) into Vault
without forcing them to reauthorize. Send the existing OAuth tokens or API key credentials in the request
body and Apideck creates or updates the matching Vault connection.

## Import Connection

The [import endpoint](/apis/vault/reference#operation/connectionsImport) creates a Vault connection from
credentials a user already authorized outside Apideck, so that user keeps their existing authorization
instead of reconnecting from scratch.

### Authorization

Like other Vault API calls, the import endpoint requires the following headers:

```
x-apideck-app-id: [Your Unify Application ID]
x-apideck-consumer-id: [Your Consumer Identifie]
Authorization: 'Bearer [Your Unify Api Key]
```

#### Example:

`POST: {{baseUrl}}/vault/connections/:unified_api/:service_id/import`

```
{
  "credentials": {
    "access_token": "eyJlbmMiOiJBMTI4Q0JDLUhTMjU2IiwiYWxnIjoiZGlyIn0..e6E6fFVEJTLKqeXjgiloMg.Cfxk4gm3Iab4DHw1PMLJZOhQdrbXiYwtCf2odk5vV4dNpqatHvq9MqtdSkjzM6Z1J3f0DYII3EpM3-dAPb1Vb0XfA9SKWkq329kxIHevMICzxDgUuXWMCYddatvZYyVJ62fBDVdjZBUxNxGDjLg9os0eCISRUFg4StFLmFfvuZE_1snjr1fu_gVvZA4sp4CiSvFi74LOAqadItrHkAfIYcs0Gca3IZQEZorerNB2AcJ73jDgT7pHxEhmun0GIOpienZ_j7C54uxUVOyJiWuJEvk5TWtzNmyTVoRj41ntBBZANo40fQcqvaDC9pFDXH1zJrNgRIIdZ_AdEJjvVKYAogOt7wUv_v1jI5vUpEOBczwJvzoSBT23vWnuzBcD1f4PsWaG2SpMkl4qS2nHZB0AsISuNVvf45O-cOLk2TK7E-M2fzxZTsTvqB_im9qQjJdonqQUols0_NmPaMJSLZdVHjHLz-m1Xaq1ebOQIlKb1qA654j--L3ov4dRa1SYhDHVO4kBy1hEqgnPcvW4Og2tIgWpFFS9b-Jx1OXzo4S4NQTdclzuY7RdYoEVlE5FX9MJU_DoGRpoz70cUKeW5mt2xaAD4EjTT0oFBuVb7TMRFSDPgcGAt2XllFTmQ12UhSJhIuS5fH9LjUartV4Ul5DzTjGp87r78YmCpd2VjjEal3aNvezvkWEdRfMt1fYzCc-EE0PI1o8Gx-B0D2sbgiaYuVmPgBByMQ_OufwyFUiQPepGV73WUGAMS6q5wJ2x4abV8kBTI-v1L1KjQt2Wf_9KIdFz3EF1SLdd6KVhb7Y6vClixHmDiQjKcneun08VReachmTpw_fbDSAByR80pq6Ik1LFIUWw08jJtrp2S27sdQSnqR8bVDG7L1vvQsN55dTD.E4FRbSEGpm7D_4c123456",
    "refresh_token": "AB11657526083yYu5cvT2ojgtzqWhwNQ1gu6VcfEACe123456",
    "issued_at": "2022-04-01T12:05:06.019Z",
    "expires_in": 3600000
  },
  "consumer_id": "test-consumer",
  "settings": {
    "realm_id": "4620816365164357123"
  },
  "metadata": {
    "account": "sandbox"
  }
}
```

### Required:

Which fields you send depends on the connector's `AuthType`: `AuthType.apiKey` and `AuthType.basic`
connectors take their credentials in `settings` (`api_key`, or a username/password pair), while
`AuthType.oauth2` connectors take an `access_token` and `refresh_token` in `credentials`.

### Refreshing Tokens

For an `AuthType.oauth2` connection, Apideck uses the `issued_at` and `expires_in` properties you send to
know when the token needs refreshing. If the token is already expired, or if you omit `issued_at`/`expires_in`
entirely, Apideck triggers a background job immediately that uses your `refresh_token` to get a new
`access_token`.

### Webhooks

If that background refresh job fails for an `AuthType.oauth2` connection, Apideck publishes a
`vault.connection.token_refresh.failed` webhook event containing non-sensitive connection details.
Configure this webhook in the Apideck Admin under Unify -> Webhooks -> Vault API.

### Retry

Importing a connection is an upsert keyed on `application_id+consumer_id`: if a connection with that ID
already exists, the import updates it; otherwise it creates a new one.

⚠️ If you map an object that only contains a type, it will be removed.
