# Rate limits (/docs/rate-limits)



LinkFetch enforces two limits in parallel:

1. **Per-key request rate** — protects the platform; tier-based.
2. **Per-action LinkedIn-side throttle** — for outbound writes only;
   protects the user's account.

Both surface in response headers so your client can self-throttle
without parsing error bodies.

## Per-key request rate [#per-key-request-rate]

| Tier    | Sustained  | Burst          |
| ------- | ---------- | -------------- |
| Free    | 1 req/sec  | 60 / minute    |
| Starter | 10 req/sec | 600 / minute   |
| Pro     | 50 req/sec | 3,000 / minute |
| Scale   | Custom     | Custom         |

Limits are per **API key**, not per workspace — if you need parallel
clients, mint a key per client and the limits scale with you.

## Response headers [#response-headers]

Every response includes the current state of your bucket:

```
X-RateLimit-Limit: 600
X-RateLimit-Remaining: 597
X-RateLimit-Reset: 2026-04-23T14:03:00Z
X-Credits-Remaining: 4995
X-Request-Id: req_2Yq7zR1tDkH
```

`X-RateLimit-Reset` is the exact UTC timestamp at which your remaining
budget refills — use it instead of guessing.

## Hitting the ceiling [#hitting-the-ceiling]

When you exceed your limit you get:

```json
{
  "error": "rate_limit",
  "message": "Per-key request rate exceeded. Retry after 2026-04-23T14:03:00Z.",
  "request_id": "req_2Yq7zR1tDkH",
  "retry_after_seconds": 12
}
```

HTTP status is `429`. The `retry_after_seconds` field and the standard
`Retry-After` header carry the same value — pick whichever your client
already speaks.

## Recommended client behaviour [#recommended-client-behaviour]

* **Read the headers.** Self-throttle when `X-RateLimit-Remaining` is
  below 5% of your tier — don't wait for a 429.
* **Honour `Retry-After`.** Add jitter on top so concurrent clients
  don't synchronise their retries.
* **Exponential backoff on 5xx, fixed backoff on 429.** A 429 is a
  policy decision, not a transient failure — exponential backoff just
  amplifies the pain.
* **Idempotency keys on POST.** Pass `Idempotency-Key: <uuid>` and the
  API will dedupe retries for 24 hours. See [Errors](/docs/errors).

## Outbound throttling [#outbound-throttling]

Outbound writes (`POST /v1/outbound/*`) are subject to a **second**,
LinkedIn-side throttle that LinkFetch enforces locally so the user's
account doesn't get challenged or banned. Defaults are:

| Action               | Daily cap (per user)     | Per-hour cap |
| -------------------- | ------------------------ | ------------ |
| Connection requests  | \~80 (LinkedIn-enforced) | 20           |
| Direct messages      | 100                      | 30           |
| Reactions / comments | 250                      | 80           |
| Follows / saves      | 500                      | 200          |

When you hit either cap, the API returns `429 outbound_throttled` with
a `next_available_at` timestamp. Account-protective; LinkedIn does not
publish exact thresholds, so we err on the safe side.

## Concurrency [#concurrency]

There is no per-key concurrent-connection limit beyond the request
rate. Pipelining is fine. If you're consistently bounded by latency
rather than rate, send us a note — most workloads are better served by
the [MCP server](/docs/mcp), which streams.
