
# LinkedIn API and AI Assistants (MCP)

Everything you do on the LinkedIn pages can also be done from a script or an AI
assistant: your leads, the connection request queue, your ICP rules (including
which countries you accept and how big a lead's network has to be), your inbox,
your AI agents and your settings.

There is nothing new to set up. It uses the **same API key as the rest of
<span data-t="appName">DM Champ</span>**, so if you already call our API or have an AI assistant connected,
you are ready.

## Where to find your key

Settings → Integrations → API Key. If you do not have one yet, click **Generate
API key**. The full steps are in [API Access](api-access.md).

There is no separate LinkedIn key to create, rotate or revoke. The key acts as
you, with the same permissions you have in the app, so treat it like a password.
Revoking it in Settings cuts off every connected script and assistant instantly.

## Calling the API directly

- **Base URL:** `https://app.sdrpilot.ai/api/v1`
- **Header:** `X-API-Key: YOUR_API_KEY`
- **Machine-readable description:** `https://app.sdrpilot.ai/api/v1/docs/openapi.yaml`
  (also available as `.json`)

The OpenAPI document is public and describes every route, so most API tools and
code generators can import it directly without a key.

`Authorization: Bearer YOUR_API_KEY` works as well. What you cannot do is send a
wrong key and hope it falls through to something else: once a key is presented,
the answer is based on that key.

What comes back when something is wrong:

| Response | What it means |
|---|---|
| `401` | The key is missing, malformed or not accepted. |
| `403` | The key is valid, but that account has no LinkedIn workspace, or is not allowed in yet. |
| `429` | Too many rejected attempts in a minute for that key. Slow down. |
| `502` `dmchamp_unreachable` | We could not check your key just then. It is never treated as a pass. Retry. |

## Connecting an AI assistant

The LinkedIn tools live on the same MCP endpoint as <span data-t="appName">DM Champ</span>'s, with the same
API key, so an assistant you already connected picks them up automatically. If
you have not connected one yet, follow
[Connect AI Assistants (MCP)](connect-ai-clients.md) and use the endpoint listed
there.

::: master-only
The endpoint is `https://mcp.youraiconnector.com/mcp`, authenticated with the
`X-API-Key` header, exactly as described in Connect AI Assistants (MCP).
:::

The LinkedIn tools are all prefixed **`linkedin_`**, so they are easy to spot in
your assistant's tool list and easy to ask for by name ("use the LinkedIn tools
to show me what is queued"). There are no per-tool permissions: a tool can do
whatever you can do in the app.

## Example 1 — only accept leads from certain countries

Your ICP profile holds the rules that leads have to pass. This sets an
allow-list of the Netherlands and Belgium. Country codes are two letters,
uppercase.

```bash
curl -X PUT https://app.sdrpilot.ai/api/v1/icp/YOUR_ICP_ID/filters \
  -H "X-API-Key: YOUR_API_KEY" \
  -H "Content-Type: application/json" \
  -d '{"countries":{"mode":"allow","codes":["NL","BE"]}}'
```

Two things to know. The body is the **complete** set of rules, not a patch: a
rule you leave out is switched off. And the answer includes an
`impact_on_queue` block telling you how many already-queued connection requests
would fail the new rules, for example `{"examined": 389, "would_withdraw": 155}`.
Saving rules does not withdraw anything by itself.

In an assistant you would simply say: "Set my ICP to accept only the
Netherlands and Belgium, and tell me what that would do to my queue."

## Example 2 — see what is queued

Connection requests that have been approved but not sent yet:

```bash
curl -s "https://app.sdrpilot.ai/api/v1/connections/queue?status=queued&limit=100" \
  -H "X-API-Key: YOUR_API_KEY"
```

Each row carries the person's name, headline, company, location, country, their
connection and follower counts, and the score. You can narrow the list with
`country`, `min_score`, `max_score` and `source`, and page through it with
`limit` and `cursor`. Only queued and awaiting-approval requests appear here.
Requests already sent are history and cannot be changed.

## Example 3 — withdraw everyone outside your countries

After changing your rules, re-check the queue against them. Without
`apply=true` this is a preview and changes nothing:

```bash
curl -X POST "https://app.sdrpilot.ai/api/v1/connections/queue/rescreen" \
  -H "X-API-Key: YOUR_API_KEY"
```

You get back how many were examined, how many would be withdrawn, and a
breakdown per rule, such as `country` and `network_too_small` (the lead's
network was smaller than your minimum). Happy with it? Run it again with
`?apply=true` and those requests are withdrawn.

```bash
curl -X POST "https://app.sdrpilot.ai/api/v1/connections/queue/rescreen?apply=true" \
  -H "X-API-Key: YOUR_API_KEY"
```

If you would rather withdraw a specific set, post the ids instead, or a filter
such as `{"filter":{"status":"queued","country":"NG"}}` to drain everything that
matches. Send ids or a filter, not both.

## Troubleshooting

- **`401` on every call** — the key is missing or wrong. Copy it again from
  Settings → Integrations → API Key.
- **`403` although the key works elsewhere** — that account is not linked to a
  LinkedIn workspace, or LinkedIn is not enabled for it yet.
- **`502 dmchamp_unreachable`** — a temporary hiccup checking your key. Nothing
  was let through; retry.
- **A rule matches nothing** — country codes must be the two-letter uppercase
  form (`NL`, not `Netherlands` or `nl`), and language codes must be lowercase.
- **The assistant shows no LinkedIn tools** — reconnect it so it reloads the
  tool list, and check you are using the same API key.

---

## Next Steps

- [Connect AI Assistants (MCP)](connect-ai-clients.md) — set up Claude, ChatGPT
  or Cursor with your key.
- [API Access](api-access.md) — generate or rotate the key this uses.
