ReplySparrow Docs

Sync my LinkedIn Inbox

Read Unibox threads and their messages, then reply, through the API.

Why manage your LinkedIn inbox outside the app

The Unibox gathers the LinkedIn conversations of every seat in your workspace, and ReplySparrow flags which replies are interested. Reaching it through the API puts those replies where you already work:

  • Never miss a hot reply. Pull interested, unread threads into your CRM, Slack, or a daily digest, so a "let's talk" doesn't wait in a tab nobody opened.
  • Keep your CRM complete. Copy every LinkedIn conversation onto the matching contact or deal, next to emails and calls, so the whole team sees the history.
  • Reply faster. Start from the AI draft ReplySparrow already wrote for the thread, review it, and send it from the right LinkedIn seat without switching tools.
  • Cover several seats at once. Managers follow every seat's replies in one place: leave out seat_id and the sync covers all the LinkedIn seats of the workspace. A key reaches one workspace, so agencies use one key per workspace.

The MCP server has no Unibox tools yet, so this sync runs on the API. In an assistant, inbox_list with channel: "linkedin" lists the contacts who replied on LinkedIn, with how each reply was classified. Reading a thread's messages and sending a LinkedIn message are API-only.

Sync the inbox

A sync is two calls. List the conversations, then read the messages in each one. Both responses are a page: data is the rows, and total, page, limit, and totalPages describe that page.

Send Authorization: Bearer YOUR_API_KEY. The base URL is https://app.replysparrow.com/api/v1. The key needs the inbox:read scope, plus inbox:send to reply.

1. List threads

GET /unibox/threads returns LinkedIn conversations, newest activity first. Omit seat_id to include every LinkedIn seat in the workspace, or pass one seat id to sync that seat only. Pass date_from as an ISO 8601 date to keep threads whose latest message is at or after that time (date_to sets the other end). interested, seen, and attendee_full_name narrow the list further.

curl --header "Authorization: Bearer YOUR_API_KEY" \
  "https://app.replysparrow.com/api/v1/unibox/threads?limit=20&order=DESC"
{
  "data": [
    {
      "id": "c1d2e3f4-0000-4a51-9d0e-2b6f8f6d9c11",
      "seen": false,
      "interested": true,
      "attendee_full_name": "Grace Hopper",
      "attendee_headline": "VP Engineering at Navy Labs",
      "attendee_profile_url": "https://www.linkedin.com/in/gracehopper",
      "attendee_profile_picture": "https://media.licdn.com/dms/image/abc",
      "contact_id": "8f1c2c3e-5b7a-4a51-9d0e-2b6f8f6d9c11",
      "seat_id": "acc_42",
      "last_message": "Sounds good, let's talk Tuesday",
      "last_message_date": "2026-10-23T15:04:05.000Z",
      "last_message_full_name": "Grace Hopper",
      "ai_generated_reply": "Tuesday works for me. Does 10am suit you?",
      "created_at": "2026-10-01T09:00:00.000Z"
    }
  ],
  "total": 128,
  "page": 1,
  "limit": 20,
  "totalPages": 7
}

Store id. That is the thread id the next calls expect, and the chat_id you reply with. It is not the LinkedIn conversation id.

contact_id is set when the other person matches a ReplySparrow contact, and is null otherwise. seen is whether the thread has been read. interested is whether the thread is marked as interested. ai_generated_reply is a draft reply for you to review, when the seat drafts replies; it is cleared once a reply is sent. Walk page from 1 through totalPages; limit goes up to 100.

To read the conversations with one CRM contact instead, GET /unibox/contacts/{contact_id} returns every thread with that contact, across all seats, as a plain array.

2. Read the messages in a thread

GET /unibox/threads/{thread_id}/messages returns that thread's messages, oldest first. thread_id is the id from the previous call. Pass order=DESC for newest first; limit goes up to 200.

curl --header "Authorization: Bearer YOUR_API_KEY" \
  "https://app.replysparrow.com/api/v1/unibox/threads/c1d2e3f4-0000-4a51-9d0e-2b6f8f6d9c11/messages?limit=50"
{
  "data": [
    {
      "id": "m_9a8b7c",
      "thread_id": "c1d2e3f4-0000-4a51-9d0e-2b6f8f6d9c11",
      "seat_id": "acc_42",
      "sender_full_name": "Grace Hopper",
      "sender_is_self": false,
      "content": "Sounds good, let's talk Tuesday",
      "attachments": [
        {
          "id": "att_1",
          "name": "agenda.pdf",
          "type": "file",
          "mime_type": "application/pdf",
          "size": 20480
        }
      ],
      "delivered_at": "2026-10-23T15:04:05.000Z",
      "created_at": "2026-10-23T15:04:05.000Z"
    }
  ],
  "total": 6,
  "page": 1,
  "limit": 50,
  "totalPages": 1
}

sender_is_self is true when the message was sent from your LinkedIn seat, and false when the other person sent it. delivered_at is the time LinkedIn gave the message when it was delivered, and created_at is the same time. content is empty for an attachment-only message.

To fetch an attachment's file, pass the message id and the attachment id to Download an attachment. The file comes back as base64 with its mime_type, fetched live from LinkedIn, so download each attachment once and keep it on your side: the call is limited to 10 downloads per minute per workspace. Only seats connected through Unipile have downloadable attachments.

On the next sync, pass the newest last_message_date you stored as date_from so you only pull threads that changed.

3. Reply (optional)

POST /unibox/messages/send-message sends a LinkedIn message in the thread, from the thread's seat. chat_id is the thread id. Send JSON for text only, or multipart/form-data to attach a file or a voice_message (one of them, up to 15 MB, on a seat connected through Unipile). message holds up to 8,000 characters.

curl --request POST \
  --header "Authorization: Bearer YOUR_API_KEY" \
  --header "Content-Type: application/json" \
  --data '{
    "chat_id": "c1d2e3f4-0000-4a51-9d0e-2b6f8f6d9c11",
    "message": "Great, Tuesday 10am works. Here is the invite link."
  }' \
  "https://app.replysparrow.com/api/v1/unibox/messages/send-message"

The message is sent right away, not queued. The response (201) is the stored message, in the same format as in the previous step, and the thread's AI draft is discarded. A 429 rate_limited means LinkedIn asked to slow down; try again later.

This sends a real message to a real person and cannot be undone. When an assistant or a script drafts replies for you, review them before you send.

Every field is listed on Get threads, Get messages, Get contact chats, and Send a message.

On this page