Skip to content
Docs

Errors And Limits

Every error type Direct answers, pacing and daily caps, retries, dry runs, Idempotency-Key and unknown outcomes.

Direct answers errors in Unipile's shape, with Unipile's status codes and error types, so code written for Unipile's errors keeps working.

JSON
{
  "title": "Too many requests",
  "detail": "LinkedIn asked this account to slow down.",
  "type": "errors/too_many_requests",
  "status": 429,
  "retry_after": 900
}

Branch on status and type. detail is for people: its words can change, and it never holds an account's data.

Every Error Type#

HTTP type Meaning
400 errors/invalid_parameters A parameter or body field is invalid: a value of the wrong type (limit=abc), a limit out of range, a cursor this API didn't give, an id that isn't LinkedIn's, a text too long, a body that isn't JSON or a form, an Idempotency-Key used for another write.
400 errors/invalid_url Hosted auth or webhooks: a URL that isn't https.
400 errors/content_too_large A file over LinkedIn's limit (a message's file over 20 MB, an image over 36 MB, a video under 75 KB or over 5 GB).
400 errors/missing_parameters A required parameter is missing: account_id on a read, api_url or reconnect_account on a hosted auth link. detail names it.
401 errors/missing_credentials The X-API-KEY header is missing, wrong or revoked.
401 errors/disconnected_account LinkedIn signed the account out, asks it for a security check, or its browser has no LinkedIn session. Reconnect it with a hosted auth link.
402 errors/subscription_required Your workspace has no active trial or subscription, so its API keys answer this on every route. Start the free trial or add a card at lempile.com/dashboard/subscription and they work again right away. Your accounts stay connected and your webhooks keep coming meanwhile.
403 errors/insufficient_permissions The account doesn't write through Direct (title Writes off), the post isn't the account's to delete, LinkedIn says the account may not do this, or a workspace key called one of Direct's internal admin routes.
403 errors/resource_access_restricted LinkedIn refused this read or write for this account.
403 errors/account_restricted LinkedIn says the account is restricted.
403 errors/action_required LinkedIn asks the account to confirm its email address first.
403 errors/feature_not_subscribed A Sales Navigator or Recruiter search, parameter or route: Direct serves LinkedIn's classic API.
404 errors/resource_not_found An account Direct doesn't serve or that isn't your workspace's (title Account not found, the same answer for both), or nothing on LinkedIn with this id (a profile, a post, a chat, a message, an invitation, a webhook).
409 errors/conflict A write with this Idempotency-Key is still running.
415 errors/unsupported_media_type A voice note that isn't audio Direct can turn into LinkedIn's format. Nothing was sent.
422 errors/invalid_parameters LinkedIn refused the write's content (title LinkedIn refused it).
422 errors/already_connected Invitation: already a connection.
422 errors/already_invited_recently Invitation: one is already waiting.
422 errors/cannot_invite_attendee Invitation: the account itself, or someone whose invitation to the account is waiting.
422 errors/invalid_recipient No profile with this id, or the account itself as a chat's recipient.
422 errors/cannot_resend_yet LinkedIn's weekly invitation limit, or a withdrawn invitation sent again within about 3 weeks. The account's other calls go on.
422 errors/limit_exceeded Too many invitations waiting for an answer: withdraw some.
422 errors/connection_limit_reached The account reached LinkedIn's connection limit.
422 errors/no_connection_with_recipient The account can't message this person for free: only an InMail would reach them.
422 errors/not_allowed_inmail LinkedIn offers no InMail to this person from this account.
422 errors/insufficient_credits No InMail credit for this person.
422 errors/invalid_post LinkedIn refused the post.
422 errors/unprocessable_entity LinkedIn refused another write (for example a post's deletion), or a message sent more than 60 minutes ago can't be deleted or edited.
422 errors/not_supported_by_provider PATCH /chats/{chat_id} with one of Unipile's WhatsApp or Telegram actions.
422 errors/invalid_message A voice note over 60 seconds. Nothing was sent.
422 errors/action_already_performed The message is already deleted.
429 errors/too_many_requests The account is resting, used up its day, or is busy. See Pacing. Always with retry_after.
500 errors/provider_error LinkedIn answered something Direct couldn't read, or an error of its own. Nothing was written.
500 errors/unexpected_error Direct failed.
501 errors/feature_not_implemented Direct doesn't do this (yet): fall back to Unipile, or do without.
503 errors/network_down The account's proxy or Lempile's browser server didn't answer. Nothing was sent.
504 errors/request_timeout A read: LinkedIn didn't answer in time. A write: unknown outcome (see below).

Parameter Errors#

A required query parameter that's missing, or one of the wrong type, answers Unipile's 400 too, naming the parameter (never the value you sent):

JSON
{ "title": "Missing parameters", "detail": "account_id is required.", "type": "errors/missing_parameters", "status": 400 }
JSON
{ "title": "Invalid parameters", "detail": "limit: Input should be a valid integer, unable to parse string as an integer.", "type": "errors/invalid_parameters", "status": 400 }

Cloudflare's Answers#

direct.lempile.com is behind Cloudflare. Two of its answers can reach you instead of Direct's:

  • 524: the request took more than 100 seconds (a write waiting its turn, a large upload). For a write, it's an unknown outcome.
  • 413: the request body is over Cloudflare's limit (100 MB on most plans): a large video.

Pacing#

Every LinkedIn call of an account goes through that account's own pace:

Limit Value When reached
One call at a time A call waits its turn up to 60 seconds, then 429 with retry_after: 60.
Gap between calls 1.5 to 3 seconds Calls wait; nothing is refused.
LinkedIn calls in any 24 hours 1,500 429 until the oldest of them is 24 hours old (retry_after says when).
Writes in any 24 hours 150 429 until the oldest write is 24 hours old.
Rest after LinkedIn's "too many" (429 or 999) 15 minutes Every call of the account answers 429 with the seconds left.
  • The limits are per account, never per key: two apps using one account share its budget.
  • One request can cost several LinkedIn calls: a profile with sections, a long page, a write's checks and uploads. Each route's page says what it reads.
  • The webhook reads use the same budget (about 300 calls a quiet day, 450 at most; see Webhooks).
  • A security check (errors/disconnected_account) is never retried.
  • The counters live in Direct's memory and start again when Direct restarts.

Retrying#

Answer Retry?
429 Yes, after retry_after seconds (also in the Retry-After header).
503 Yes: nothing was sent.
500 provider_error A read: yes, later. A write: nothing was written; retry once.
504 on a read Yes.
504 on a write, 524, a lost connection Only with the same Idempotency-Key (below), or after checking the write didn't happen.
401 disconnected_account No: reconnect the account.
Other 4xx, 501 No.

Writes#

Dry Runs#

Every write takes ?dry_run=true. Direct does everything up to the write itself (it reads what it checks: the profile before an invitation, the "Message" option before a new chat, the post before its deletion) and answers the plan instead of sending it:

JSON
{
  "object": "DryRun",
  "route": "posts.react",
  "method": "POST",
  "path": "/voyager/api/voyagerSocialDashReactions?threadUrn=urn%3Ali%3Aactivity%3A7388000000000000000",
  "body": { "reactionType": "LIKE" },
  "status": 201
}
  • Status 200. status is what the real write would answer. uploads, multiphoto and checked appear when the write has files or checks.
  • Nothing is sent to a LinkedIn write endpoint, and no file is uploaded. The checks' reads do happen and count in the account's calls.
  • Dry runs work for every served account, writes on or off, and don't use an Idempotency-Key.
  • A refusal found by the checks (already_connected, no_connection_with_recipient…) answers as the real write would.

Idempotency-Key#

Send an Idempotency-Key header (1 to 200 characters, unique per write) on every real write:

  • The key is claimed (per account) before anything is sent. The same key on the same account never writes twice.
  • A repeat after the write finished answers the first answer again (same status, same body; an empty 204 stays empty), for 7 days.
  • A repeat while the first is still running answers 409 errors/conflict.
  • A write that surely didn't happen (a refusal, 429, 503, 500 provider_error) frees the key: the same key may try again. A refusal found by the checks before sending never takes the key at all.
  • A write whose outcome is unknown answers the same 504 to every repeat: it never writes again under that key.
  • The same key on another route answers 400.

With a key, retrying after a timeout, a 524 or a lost connection is safe: you get the first answer, 409 while it runs, or the write if it never started.

Unknown Outcome#

A write is tried again by Direct only when nothing reached LinkedIn (the proxy refused the connection, or LinkedIn refused the session before reading it). When LinkedIn may have received it (a timeout after sending, or an answer that doesn't name what it made), Direct answers:

JSON
{
  "title": "Unknown outcome",
  "detail": "LinkedIn may have received this write; it isn't tried again. Check before sending it once more.",
  "type": "errors/request_timeout",
  "status": 504
}

Check before writing again: the chat's latest messages, the account's posts, the post's comments, the sent invitations.

Other Limits#

Page sizes Each list's limit range is on its page (relations up to 1,000; chats, messages and attendees up to 250; most others up to 100).
Cursors Opaque; only the list that gave one takes it back.
Texts Message 8,000 characters, post 3,000, comment 1,250, invitation note 300, InMail subject 200.
Files Message: 20 MB each. Post: up to 20 images of 36 MB, or one video of 75 KB to 5 GB. Comment: one image.
Webhooks 20 headers each; one request_url and one source each.

Was this page helpful?