Jobs and polling
Every command becomes a job. Reads usually finish in seconds. Writes are released by the Governor one at a time per account, inside working hours and budgets, and may wait for approval, so a write can take minutes, hours, or until the next working day.
Lifecycle
Section titled “Lifecycle”awaiting_approval ─approve─▶ queued / scheduled ─▶ running ─▶ completed │ └────▶ failed └─reject──▶ failed (any time before running) ─cancel─▶ cancelled| Status | Meaning |
|---|---|
awaiting_approval |
The account is in approve or assist mode. job.approval has the request id, summary and expiry. |
queued |
Ready; waiting for its turn on the account. |
scheduled |
Waiting for a time in eta: the next working session, budget tomorrow, or a cool-down. waitingOn says why when known. |
running |
Being sent to LinkedIn now. |
completed |
Done. result holds the outcome. |
failed |
error holds { type, message, next }. See Errors. |
cancelled |
Cancelled before it ran. |
Long-polling
Section titled “Long-polling”GET /v1/jobs/{id}?wait=N holds the request for up to N seconds (max 600) and returns as soon as the job is completed, failed or cancelled. If it’s still pending when the time is up, you get the current snapshot.
curl "https://api.linnia.ai/v1/jobs/$JOB?wait=60" -H "Authorization: Bearer $LINNIA_KEY"{ "ok": true, "job": { "id": "0c9b6d3e-12f4-4a8b-b5e1-7d2c9f0a6e13", "accountId": "6f1c2a9e-4b7d-4c1e-9a53-2f8e0d7b1c44", "kind": "connect", "status": "completed", "approval": null, "input": { "person": "jana-novak", "note": "Hi Jana, enjoyed your post on RevOps hiring." }, "result": { "person": { "providerId": "ACoAAA0001", "name": "Jana Novak" }, "invitationId": "7251234567890123456", "note": "Hi Jana, enjoyed your post on RevOps hiring.", "quality": { "score": 72, "reasons": ["2nd-degree connection", "4 shared connections"] } }, "error": null, "eta": "2026-10-18T09:14:03.000Z", "waitingOn": null, "createdAt": "2026-10-18T09:14:03.000Z", "finishedAt": "2026-10-18T10:41:27.000Z" }}For writes that may wait hours, prefer the job.completed and job.failed webhooks over polling.
Results
Section titled “Results”result depends on the command. Some examples:
| Command | result |
|---|---|
connect |
{ person, invitationId, note, quality } |
send_message |
{ chatId, messageId, inmail } |
search_people, search_companies |
{ items, cursor, rowsCharged }; pass cursor back for the next page |
list_chats |
{ items, cursor }; each conversation carries its latest reply triage |
get_conversation, get_posts |
{ items, cursor } |
comment |
{ post, commentId } |
create_post |
{ postId } |
| workflow | A tree: one entry per action with action, status, data or error, and then children |
Listing and cancelling
Section titled “Listing and cancelling”GET /v1/jobs?account={id}&limit=50lists recent jobs, newest first (max 200).DELETE /v1/jobs/{id}cancels a job that hasn’t finished and rejects its pending approvals. An action already sent to LinkedIn is not undone.