# Stop a LinkedIn sequence

Stops LinkedIn outreach of the user behind this key: a whole campaign (`campaign_id`), or one person (`lead`). Steps that did not go out yet are cancelled; a conversation where the person already replied stays open. Only the user's own sequences. To also block new sequences for a person, log `not_interested` with POST /outreach/activity. mySDR does the LinkedIn part of your outreach: you pick the people and write every text, mySDR sends it from the user's own LinkedIn account within their working hours and the SafeOutreach limits, notices accepted invites and replies, and stops a person's sequence when they reply. These routes are the tools `start_linkedin_sequence`, `get_outreach_status`, `get_outreach_events` and `stop_linkedin_sequence` of the assistant server; your own emails you log with POST /outreach/activity. Free: no credits.

## Authentication

Send `Authorization: Bearer gtk_…`. Create the key under **Connect assistant → API keys**. Every `gtk_` key can call these routes, also while the Signals API is closed. A missing, invalid or revoked key is **401**.

### Body parameters

- **`campaign_id`** `string` — Stop every sequence in this campaign. Or:
- **`lead`** `object` — Stop one person: exactly one of the keys below.
- **`lead.id`** `string` — A row of GET /tables/leads: its `id` (a number, `per_…` or `sav_…`; a number may also be sent as a number). A `sav_…` uses that row’s LinkedIn profile and name.
- **`lead.lead_id`** `integer` — A lead from the signals: the number GET /tables/leads gives (`201`, or as text `"201"`). A row id such as `sav_…` or `per_…` goes in `id`, and in `lead_id` is a 400 that says so.
- **`lead.person_id`** `string` — A `per_…` from the Signals API (company_leads, search_signals), kept 30 days.
- **`lead.linkedin_url`** `string` — A LinkedIn profile URL (`https://www.linkedin.com/in/…`) you found yourself.

## Response

- **`stopped_sequences`** `integer` · **required** — Sequences that stopped.
- **`campaign_id`** `string | null` · **required** — The campaign, when you stopped one.
- **`note`** `string | null` · **required** — With 0: why nothing stopped (nothing was running, the person has no LinkedIn outreach in your organization, or a colleague runs it).
- **`dashboard_url`** `string` · **required** — The Leads table in mySDR.

## Credits

Free. This call never uses credits.

## Errors

- **400** `invalid_request` — An unknown field, neither or both of `campaign_id` and `lead`, a person that cannot be read, or a `linkedin_url` that is not a profile.
- **404** `not_found` — No LinkedIn campaign of this user has this id, or a `lead_id`, `per_…` or `sav_…` that is not known. A LinkedIn URL without outreach is a 200 with `stopped_sequences: 0` and a `note`.
- **409** `invalid_state` — The key has no user behind it, so there is no LinkedIn account to send from.
- **401** `authentication_error` — The Authorization header is missing, or the key is unknown or revoked.
- **403** `permission_error` — API access is not part of your plan, or your account is suspended.
- **429** `rate_limit_error` — More than 60 requests per minute, or more than 3 at the same time, on one key. Wait for the Retry-After header.
- **503** `service_unavailable` — The API is temporarily unavailable. Retry later.
- **500** `internal_error` — Something went wrong on our side.

## Example

### cURL

```bash
curl -X POST "https://mysdr.app/api/v1/outreach/linkedin/stop" \
  -H "Authorization: Bearer $MYSDR_API_KEY" \
  -H "Content-Type: application/json" \
  -d '{
    "campaign_id": "5e0c1a2b-3d4e-4f50-8a61-7b8c9d0e1f23"
  }'
```

### JavaScript

```javascript
const response = await fetch('https://mysdr.app/api/v1/outreach/linkedin/stop', {
  method: 'POST',
  headers: {
    Authorization: `Bearer ${process.env.MYSDR_API_KEY}`,
    'Content-Type': 'application/json'
  },
  body: JSON.stringify({
    "campaign_id": "5e0c1a2b-3d4e-4f50-8a61-7b8c9d0e1f23"
  })
});
const body = await response.json();
```

### Python

```python
import json
import os
import urllib.request

payload = {
  "campaign_id": "5e0c1a2b-3d4e-4f50-8a61-7b8c9d0e1f23"
}

request = urllib.request.Request(
    "https://mysdr.app/api/v1/outreach/linkedin/stop",
    headers={
    "Authorization": f"Bearer {os.environ['MYSDR_API_KEY']}",
    "Content-Type": "application/json"
    },
    data=json.dumps(payload).encode(),
    method="POST",
)
with urllib.request.urlopen(request) as response:
    body = json.load(response)
```

### Example response

```json
{
  "stopped_sequences": 2,
  "campaign_id": "5e0c1a2b-3d4e-4f50-8a61-7b8c9d0e1f23",
  "note": null,
  "dashboard_url": "https://mysdr.app/en/gtm/leads?campaign=5e0c1a2b-3d4e-4f50-8a61-7b8c9d0e1f23"
}
```
