# Create a connect link

`POST https://api.versionseven.ai/v1/accounts/connect-link`

Mints a hosted sign-in link for a sender account. Send the `url` to the person whose LinkedIn or mailbox it is; they sign in on the hosted page, and the account appears in [List sender accounts](https://docs.versionseven.ai/api-reference/accounts/list-accounts) once connected. The link expires at `expires_at`, about a week after it's minted.

Without `reconnect_account_id`, the link adds a new account (`type: "create"`), which needs a free seat for its `platform`; with none free, the request answers `409 ACCOUNT_LIMIT_REACHED`. With `reconnect_account_id`, the `id` or `account_id` of an account that has disconnected, the link re-authenticates that account (`type: "reconnect"`) and uses no seat. The account must be on the same `platform`.

`email` is required when `platform` is `email`. The redirect URLs must be `https` on an origin Victoria AI allows, which always includes the Victoria AI app; leave them out to land in the app. The failure URL defaults to the success URL.

- Required scope: `accounts:write`

## Request

**cURL**

```bash
curl -X POST "https://api.versionseven.ai/v1/accounts/connect-link" \
  -H "Authorization: Bearer $VICTORIA_API_KEY" \
  -H "Content-Type: application/json" \
  -d '{
  "platform": "email",
  "display_name": "Sarah Johnson",
  "email": "sarah.johnson@acmecorp.com"
}'
```

**Node.js**

```javascript
const response = await fetch("https://api.versionseven.ai/v1/accounts/connect-link", {
  method: "POST",
  headers: {
    Authorization: `Bearer ${process.env.VICTORIA_API_KEY}`,
    "Content-Type": "application/json",
  },
  body: JSON.stringify({
    "platform": "email",
    "display_name": "Sarah Johnson",
    "email": "sarah.johnson@acmecorp.com"
  }),
});

const data = await response.json();
```

**Python**

```python
import os

import requests

response = requests.post(
    "https://api.versionseven.ai/v1/accounts/connect-link",
    headers={
        "Authorization": f"Bearer {os.environ['VICTORIA_API_KEY']}",
    },
    json={
        "platform": "email",
        "display_name": "Sarah Johnson",
        "email": "sarah.johnson@acmecorp.com",
    },
)
data = response.json()
```

## Headers

- `Authorization` (string, required): `Bearer` followed by a space and your API key, for example `Bearer vk_…`.

## Request body

- `platform` (string, required, one of `"linkedin"`, `"email"`): Which kind of sender account to connect
- `display_name` (string, required, at most 120 characters): The name the account is labelled with, usually its owner's
- `email` (string or null, optional, at most 254 characters): The mailbox address; required for email
- `failure_redirect_url` (string or null, optional, at most 2,000 characters): Where to send the user if connecting fails; defaults to the success URL
- `reconnect_account_id` (string or null, optional, at most 120 characters): Reconnect this existing account (its id or its provider account id) instead of adding a new one
- `success_redirect_url` (string or null, optional, at most 2,000 characters): Where to send the user after connecting; must be an allowed https origin

## Response

### `200`

```json
{
  "platform": "linkedin",
  "url": "https://example.com",
  "type": "create",
  "expires_at": "2026-01-14T19:30:00+00:00",
  "success": true
}
```

- `platform` (string, required, one of `"linkedin"`, `"email"`)
- `url` (string, required): Open this to connect; it signs the account into this organization
- `type` (string, required, one of `"create"`, `"reconnect"`)
- `expires_at` (string, required): ISO timestamp after which the link stops working (about a week)
- `success` (boolean, optional, default `true`)

## Errors

Errors share one JSON body: `success`, `error`, `message`, optional `details`, and `request_id`. For example:

```json
{
  "success": false,
  "error": "UNAUTHORIZED",
  "message": "Invalid or inactive API key",
  "request_id": "734d11a1-54d4-414c-9e8d-4e1ada977db4"
}
```

| Status | Code | Meaning |
| --- | --- | --- |
| 400 | `VALIDATION_ERROR` | The request didn't match the endpoint's schema: a missing or malformed field, a bad query parameter, or a value out of range. `details.errors` lists each failing field with its `field`, `message` and `type`. |
| 400 | `INVALID_ACCOUNT` | A sender account ID in the request isn't a connected account in your organization. Answered when a connected assistant assigns sender accounts to a campaign. This is a `400` rather than a `404` for the same reason as `INVALID_LEAD`. |
| 401 | `UNAUTHORIZED` | The `Authorization` header is missing or malformed, or the API key is unknown or has been deactivated. |
| 401 | `API_KEY_EXPIRED` | The API key is past its expiry date. Create a new key in the Victoria AI app. |
| 403 | `INSUFFICIENT_SCOPE` | The API key doesn't have the scope this endpoint requires, such as `leads:write`. |
| 403 | `ORGANIZATION_DEACTIVATED` | The organization that owns this API key has been deactivated. |
| 409 | `ACCOUNT_LIMIT_REACHED` | Connecting a new sender account would exceed the organization's seats for that platform. `details` carries the `max` and the number `used`. Free a seat, add one in the Victoria AI app, or reconnect an existing account instead. |
| 413 | `PAYLOAD_TOO_LARGE` | The request body is larger than 1 MB. |
| 429 | `RATE_LIMITED` | Too many requests for this API key: more than 100 a minute to one endpoint, or 600 a minute in total. Retry after the number of seconds in the `Retry-After` header. See [Rate limits](https://docs.versionseven.ai/guides/rate-limits). |
| 500 | `ORG_HAS_NO_MEMBERS` | The organization has no members, so the campaign can't be created. Contact support. |
| 500 | `INTERNAL_ERROR` | Something failed on our side. The response never includes internal details; quote its `request_id` when you contact support. |
| 503 | `UPSTREAM_TIMEOUT` | A service the API depends on timed out. The request is safe to retry. |
| 503 | `AUTH_UNAVAILABLE` | The API key couldn't be checked because the authentication service was unavailable. The request is safe to retry. |

## Response headers

| Header | Description |
| --- | --- |
| `X-Request-ID` | Correlation ID for the request, also returned as `request_id` in error bodies. Send your own `X-Request-ID`, up to 128 letters, digits, `.`, `_`, `:` or `-`, and it's used instead. |
| `RateLimit-Limit` | Requests allowed to this endpoint per minute. |
| `RateLimit-Remaining` | Requests you can still send to this endpoint right now. |
| `RateLimit-Reset` | Seconds until the endpoint's full limit is available again. |
| `Retry-After` | On a `429`: seconds to wait before retrying. |
