Skip to main content
POST
Hand back a running step without settling it

Authorizations

X-API-Key
string
header
required

Path Parameters

action_id
string<uuid>
required

Body

application/json
claimed_at
string<date-time>
required

The step's claim, exactly as the claim handed it out.

reason
enum<string>
required

verified_absent (looked, not done, may not finish it now) or reopen_paused (the person closed the tab again). Neither counts against the step: a run cut off under it is reported to the attempts endpoint.

Available options:
verified_absent,
reopen_paused

Response

Successful Response

One LinkedIn step, in the shape the dashboard and every extension build read.

A step is queued only once it may run (its approval, when one was asked for, happened on Tasks before it was queued), so every step reads approved_at as the moment it was queued and requires_approval false: the extension's store builds draw "Approve tasks" from exactly these two fields, and no step in the line waits for a person. hold is kept for the same builds and is always null: whether a step is out of the line is held.

account_id
string<uuid>
required
claimed_at
string<date-time> | null
required
duration_ms
integer | null
required
error_code
enum<string> | null
required

Why one action did not succeed, as a closed vocabulary.

Two populations in one enum, on purpose. The first twelve are reported by the browser agent and were previously a free string that only the extension had written down, so nothing stopped a typo storing and rendering exactly like a real code. The last four the backend writes itself: three when an action settles without the browser ever running it, and CLAIM_EXPIRED when the browser took a step and then went silent, so nobody can say whether it ran.

The list is the whole contract: a code outside it is rejected at the API boundary rather than persisted, so the extension and the dashboard can only ever speak about failures both sides can name.

Available options:
selector_missing,
blocked_checkpoint,
not_authenticated,
account_mismatch,
navigation_failed,
timed_out,
linkedin_error,
agent_restarted,
tab_lost,
not_applicable,
not_connected,
invalid_params,
user_rejected,
cancelled,
missed_window,
sender_changed,
claim_expired,
interrupted_repeatedly
error_message
string | null
required
finished_at
string<date-time> | null
required
id
string<uuid>
required
kind
enum<string>
required

What the browser agent is being asked to do.

The four CHECK_*/READ_* kinds are housekeeping: they read our own outbound invitations, our own newest connections and our own conversations to detect what the contact did, so they are free and deliberately excluded from the priced kinds below.

CHECK_CONNECTIONS reads the first batch of the sender's connections list, newest first: a person found there has accepted, whenever the invitation went out. It is how an acceptance is noticed at all once an invitation has fallen out of the ten rows the sent list shows a background tab.

CHECK_INBOX scans the conversation list for threads with new inbound activity; READ_CONVERSATION opens one of them and reads it in full. The split keeps LinkedIn activity proportional to real replies: the cheap scan runs on every sweep, the expensive read only where the scan saw a change.

LIKE_LATEST_POST targets the contact's most recent post at the moment the browser runs it. A contact with no posts is not a failure: the driver reports the action SKIPPED, and the sequence advances either way.

Every profile-targeted outcome carries the facts the browser read off the profile, including the three-state Premium "Open Profile" reading; see the section comment above the outcome models.

Available options:
profile_view,
connection_request,
send_message,
inmail,
withdraw_connection_request,
follow_contact,
like_latest_post,
check_sent_invitations,
check_connections,
check_inbox,
read_conversation
outcome
ProfileViewOutcome · object
required

What a profile view saw: the common fields and the nine profile facts.

The view IS the action: LinkedIn records it server-side the moment the page renders, so page_loaded is the verification and a view whose facts all read None is still a completed view. How long the browser lingered and how far it scrolled are the driver's pacing, not facts about the member, and the row's own duration_ms already says how long the step took.

params
ProfileViewParams · object
required

Open a member's profile and read it like a person would. The navigation is the action.

profile_url is where the browser goes first. read_relationship asks the browser to settle whether the member is connected or has our invitation pending even where the action bar does not show it, by opening the member's own More menu and reading it: the look a connection request queues when its answer cannot be told any other way.

queued_at
string<date-time>
required
status
enum<string>
required

Where one queued action stands.

Governor-deferral is deliberately NOT a status: an action whose kind has hit its daily cap stays QUEUED and is simply not handed out, with the reason travelling on the hand-out response instead. A DEFERRED row would make the queue lie about what is still waiting to happen.

SKIPPED is "not applicable" (no LinkedIn URL, already connected); REJECTED is "a human refused it"; FAILED is "we tried and could not".

RESUMING is a step put back in line after an attempt that may have acted on LinkedIn (its browser was granted the press, or lost track of the step): it is never "queued", so no path that assumes nothing happened yet (moving it to another sender, a plain copy, "did not run") ever reads it as such, and it is handed only to a browser that checks LinkedIn before acting.

Available options:
queued,
resuming,
claimed,
succeeded,
failed,
rejected,
skipped
acted_at
string<date-time> | null

When the step said it acted on LinkedIn, for a result that arrived late. On a failed step it means the step happened after all: it stays failed for a person, and a Retry checks LinkedIn first and never sends it twice.

approved_at
string<date-time> | null

When the step was let run: the moment it was queued, since a step is queued only once it may run. Kept for older extension builds.

held
boolean
default:false

Whether the step is held out of every browser's line, because its paused sequence or paused contact holds it. It runs once they are resumed. Only the dashboard's queue lists a held step that is waiting; a browser is never sent one.

hold
enum<string> | null

Always null; read held. Kept for older extension builds.

Available options:
sequence_paused,
contact_paused
metered
boolean
default:true

Whether the step spends the sender's limits and credit. False for a step the Oneprofile team fired to test the sender: it goes first, waits for no gap and counts against no limit.

requires_approval
boolean
default:false

Always false: a step that asks for a person waits on Oneprofile's Tasks page, never in the line. Kept for older extension builds.