Skip to main content
POST
Send a Reply
Sends one message into an existing conversation from the human’s account, then returns processing with a request to poll. Paid: flat price per message (see Pricing). Requires the reply grant and an Idempotency-Key header.
The human’s account sends the message, and a message LinkedIn accepted cannot be recalled. Every call must carry an Idempotency-Key. The SDKs generate one if you omit it and reuse it on retries.

Request

string
required
1–255 chars of [A-Za-z0-9_.:-]. A retry with the same key and body replays the accepted response instead of paying and sending again. The same key with a different body returns 422 idempotency_key_reuse. The key is also stored on the action, so reuse is refused (409 duplicate_request, with the original request_id) even if the cache is unavailable.
string
required
Connected LinkedIn account id.
string
required
Conversation id from Conversations. To reach a connection you have no conversation with yet, use Message a connection.
string
required
1–4000 characters.

Before payment

Every rejection happens before payment. Each of these returns a non-2xx and is never settled:

Response

scheduled_for is non-null when a spacing delay was scheduled at acceptance (randomized, ~45 s ± 50 % between sends on the same account). null means no initial delay. The worker can still defer the send during its execution-time checks. The response is processing either way.

Outcome

Poll GET /v1/requests/{request_id} (the SDK waits for you):
  • completed: { "action_request_id", "status": "sent", "provider_message_id", "message_id", "sent_at" }. The message is also visible in Messages with source: "send".
  • failed: error_code ∈ grant_revoked (grant changed or revoked since enqueue), account_disconnected (LinkedIn refused the session, and the account is now reconnect_required), recipient_not_connected, content_rejected, rate_limited, account_send_limit, target_not_found. The failed-job sweep refunds jobs that failed before sending.
  • processing with send_status: "ambiguous": the upstream timed out after the request may have been delivered. OneShot does not retry blindly. It reconciles against the chat every few minutes and re-attempts once if there is still no evidence after 10 minutes. After 24 hours without confirmation it fails the job with send_unverified. An unconfirmed send is never auto-refunded.

Execution-time checks

A queued request has not been sent yet. Immediately before the upstream call, the worker re-checks under a row lock that the account is connected, not revoked, and still grants reply, and that grant_version has not changed since acceptance. It re-reserves a slot against the daily cap (Redis with a database fallback; the check fails closed). If sending now would break the spacing, it defers the send instead of sleeping. A request that fails these checks is cancelled, its job fails with the matching code, and nothing reaches LinkedIn.

Example