Sync Inbox
curl --request POST \
--url https://api.linkupapi.com/v2/accounts/{account_id}/sync \
--header 'Content-Type: application/json' \
--header 'x-api-key: <x-api-key>' \
--data '
{
"since": 123,
"inbox": "<string>",
"max_conversations": 123,
"messages_per_conversation": 123
}
'import requests
url = "https://api.linkupapi.com/v2/accounts/{account_id}/sync"
payload = {
"since": 123,
"inbox": "<string>",
"max_conversations": 123,
"messages_per_conversation": 123
}
headers = {
"x-api-key": "<x-api-key>",
"Content-Type": "application/json"
}
response = requests.post(url, json=payload, headers=headers)
print(response.text)const options = {
method: 'POST',
headers: {'x-api-key': '<x-api-key>', 'Content-Type': 'application/json'},
body: JSON.stringify({
since: 123,
inbox: '<string>',
max_conversations: 123,
messages_per_conversation: 123
})
};
fetch('https://api.linkupapi.com/v2/accounts/{account_id}/sync', options)
.then(res => res.json())
.then(res => console.log(res))
.catch(err => console.error(err));<?php
$curl = curl_init();
curl_setopt_array($curl, [
CURLOPT_URL => "https://api.linkupapi.com/v2/accounts/{account_id}/sync",
CURLOPT_RETURNTRANSFER => true,
CURLOPT_ENCODING => "",
CURLOPT_MAXREDIRS => 10,
CURLOPT_TIMEOUT => 30,
CURLOPT_HTTP_VERSION => CURL_HTTP_VERSION_1_1,
CURLOPT_CUSTOMREQUEST => "POST",
CURLOPT_POSTFIELDS => json_encode([
'since' => 123,
'inbox' => '<string>',
'max_conversations' => 123,
'messages_per_conversation' => 123
]),
CURLOPT_HTTPHEADER => [
"Content-Type: application/json",
"x-api-key: <x-api-key>"
],
]);
$response = curl_exec($curl);
$err = curl_error($curl);
curl_close($curl);
if ($err) {
echo "cURL Error #:" . $err;
} else {
echo $response;
}package main
import (
"fmt"
"strings"
"net/http"
"io"
)
func main() {
url := "https://api.linkupapi.com/v2/accounts/{account_id}/sync"
payload := strings.NewReader("{\n \"since\": 123,\n \"inbox\": \"<string>\",\n \"max_conversations\": 123,\n \"messages_per_conversation\": 123\n}")
req, _ := http.NewRequest("POST", url, payload)
req.Header.Add("x-api-key", "<x-api-key>")
req.Header.Add("Content-Type", "application/json")
res, _ := http.DefaultClient.Do(req)
defer res.Body.Close()
body, _ := io.ReadAll(res.Body)
fmt.Println(string(body))
}HttpResponse<String> response = Unirest.post("https://api.linkupapi.com/v2/accounts/{account_id}/sync")
.header("x-api-key", "<x-api-key>")
.header("Content-Type", "application/json")
.body("{\n \"since\": 123,\n \"inbox\": \"<string>\",\n \"max_conversations\": 123,\n \"messages_per_conversation\": 123\n}")
.asString();require 'uri'
require 'net/http'
url = URI("https://api.linkupapi.com/v2/accounts/{account_id}/sync")
http = Net::HTTP.new(url.host, url.port)
http.use_ssl = true
request = Net::HTTP::Post.new(url)
request["x-api-key"] = '<x-api-key>'
request["Content-Type"] = 'application/json'
request.body = "{\n \"since\": 123,\n \"inbox\": \"<string>\",\n \"max_conversations\": 123,\n \"messages_per_conversation\": 123\n}"
response = http.request(request)
puts response.read_body{
"success": true,
"data": {
"sync_id": "6ae89fc905a1e2341aadccda",
"account_id": "6a7705f479d5cb9de0687ae0",
"status": "queued",
"since": 0,
"inboxes": {
"classic": { "status": "queued", "conversations_total": null, "conversations_done": 0, "messages_delivered": 0 }
},
"max_conversations": 100,
"messages_per_conversation": 200,
"created_at": "2026-11-02T14:20:03.511000",
"started_at": null,
"finished_at": null,
"estimated_minutes": 20
},
"metadata": {
"action": "sync_account",
"credits_consumed": 0,
"timestamp": "2026-11-02T14:20:03.514201"
}
}
{
"success": false,
"error": {
"code": "RATE_LIMITED",
"message": "A sync is already running on this account (sync_id 6ae89fc905a1e2341aadccda)"
},
"metadata": {
"action": "sync_account",
"credits_consumed": 0,
"timestamp": "2026-11-02T14:21:40.002117"
}
}
{
"success": true,
"data": {
"sync_id": "6ae89fc905a1e2341aadccda",
"account_id": "6a7705f479d5cb9de0687ae0",
"status": "running",
"since": 0,
"inboxes": {
"classic": { "status": "running", "conversations_total": 100, "conversations_done": 37, "messages_delivered": 412 }
},
"max_conversations": 100,
"messages_per_conversation": 200,
"created_at": "2026-11-02T14:20:03.511000",
"started_at": "2026-11-02T14:20:05.108000",
"finished_at": null
},
"metadata": {
"action": "get_account_sync",
"credits_consumed": 0,
"timestamp": "2026-11-02T14:28:51.730415"
}
}
Accounts
Sync Inbox
Import the existing LinkedIn inbox of an account into your webhooks
POST
/
v2
/
accounts
/
{account_id}
/
sync
Sync Inbox
curl --request POST \
--url https://api.linkupapi.com/v2/accounts/{account_id}/sync \
--header 'Content-Type: application/json' \
--header 'x-api-key: <x-api-key>' \
--data '
{
"since": 123,
"inbox": "<string>",
"max_conversations": 123,
"messages_per_conversation": 123
}
'import requests
url = "https://api.linkupapi.com/v2/accounts/{account_id}/sync"
payload = {
"since": 123,
"inbox": "<string>",
"max_conversations": 123,
"messages_per_conversation": 123
}
headers = {
"x-api-key": "<x-api-key>",
"Content-Type": "application/json"
}
response = requests.post(url, json=payload, headers=headers)
print(response.text)const options = {
method: 'POST',
headers: {'x-api-key': '<x-api-key>', 'Content-Type': 'application/json'},
body: JSON.stringify({
since: 123,
inbox: '<string>',
max_conversations: 123,
messages_per_conversation: 123
})
};
fetch('https://api.linkupapi.com/v2/accounts/{account_id}/sync', options)
.then(res => res.json())
.then(res => console.log(res))
.catch(err => console.error(err));<?php
$curl = curl_init();
curl_setopt_array($curl, [
CURLOPT_URL => "https://api.linkupapi.com/v2/accounts/{account_id}/sync",
CURLOPT_RETURNTRANSFER => true,
CURLOPT_ENCODING => "",
CURLOPT_MAXREDIRS => 10,
CURLOPT_TIMEOUT => 30,
CURLOPT_HTTP_VERSION => CURL_HTTP_VERSION_1_1,
CURLOPT_CUSTOMREQUEST => "POST",
CURLOPT_POSTFIELDS => json_encode([
'since' => 123,
'inbox' => '<string>',
'max_conversations' => 123,
'messages_per_conversation' => 123
]),
CURLOPT_HTTPHEADER => [
"Content-Type: application/json",
"x-api-key: <x-api-key>"
],
]);
$response = curl_exec($curl);
$err = curl_error($curl);
curl_close($curl);
if ($err) {
echo "cURL Error #:" . $err;
} else {
echo $response;
}package main
import (
"fmt"
"strings"
"net/http"
"io"
)
func main() {
url := "https://api.linkupapi.com/v2/accounts/{account_id}/sync"
payload := strings.NewReader("{\n \"since\": 123,\n \"inbox\": \"<string>\",\n \"max_conversations\": 123,\n \"messages_per_conversation\": 123\n}")
req, _ := http.NewRequest("POST", url, payload)
req.Header.Add("x-api-key", "<x-api-key>")
req.Header.Add("Content-Type", "application/json")
res, _ := http.DefaultClient.Do(req)
defer res.Body.Close()
body, _ := io.ReadAll(res.Body)
fmt.Println(string(body))
}HttpResponse<String> response = Unirest.post("https://api.linkupapi.com/v2/accounts/{account_id}/sync")
.header("x-api-key", "<x-api-key>")
.header("Content-Type", "application/json")
.body("{\n \"since\": 123,\n \"inbox\": \"<string>\",\n \"max_conversations\": 123,\n \"messages_per_conversation\": 123\n}")
.asString();require 'uri'
require 'net/http'
url = URI("https://api.linkupapi.com/v2/accounts/{account_id}/sync")
http = Net::HTTP.new(url.host, url.port)
http.use_ssl = true
request = Net::HTTP::Post.new(url)
request["x-api-key"] = '<x-api-key>'
request["Content-Type"] = 'application/json'
request.body = "{\n \"since\": 123,\n \"inbox\": \"<string>\",\n \"max_conversations\": 123,\n \"messages_per_conversation\": 123\n}"
response = http.request(request)
puts response.read_body{
"success": true,
"data": {
"sync_id": "6ae89fc905a1e2341aadccda",
"account_id": "6a7705f479d5cb9de0687ae0",
"status": "queued",
"since": 0,
"inboxes": {
"classic": { "status": "queued", "conversations_total": null, "conversations_done": 0, "messages_delivered": 0 }
},
"max_conversations": 100,
"messages_per_conversation": 200,
"created_at": "2026-11-02T14:20:03.511000",
"started_at": null,
"finished_at": null,
"estimated_minutes": 20
},
"metadata": {
"action": "sync_account",
"credits_consumed": 0,
"timestamp": "2026-11-02T14:20:03.514201"
}
}
{
"success": false,
"error": {
"code": "RATE_LIMITED",
"message": "A sync is already running on this account (sync_id 6ae89fc905a1e2341aadccda)"
},
"metadata": {
"action": "sync_account",
"credits_consumed": 0,
"timestamp": "2026-11-02T14:21:40.002117"
}
}
{
"success": true,
"data": {
"sync_id": "6ae89fc905a1e2341aadccda",
"account_id": "6a7705f479d5cb9de0687ae0",
"status": "running",
"since": 0,
"inboxes": {
"classic": { "status": "running", "conversations_total": 100, "conversations_done": 37, "messages_delivered": 412 }
},
"max_conversations": 100,
"messages_per_conversation": 200,
"created_at": "2026-11-02T14:20:03.511000",
"started_at": "2026-11-02T14:20:05.108000",
"finished_at": null
},
"metadata": {
"action": "get_account_sync",
"credits_consumed": 0,
"timestamp": "2026-11-02T14:28:51.730415"
}
}
Imports the messages already in an account’s inbox into your webhooks — typically right after connecting it, to build the inbox in your product before real time takes over. Covers the classic inbox and the connected Sales Navigator / Recruiter seats.
The sync runs in the background (~20 minutes for 100 conversations). Every message is delivered exactly like a real-time
message webhook, grouped per conversation: each POST carries up to 25 messages under events, with sync_id and catch_up: true at the top level. Messages already delivered to your webhooks are skipped, and your webhook’s message_type filter applies.
This endpoint is free — it does not consume any credits. One sync at a time per account, 10 per 24 hours.
The account needs an active webhook subscribed to messages (
events: all or message_received). Set message_type: "all" on it to also import the messages the account sent.Path Parameters
string
required
A LinkedIn account of your API key
Header Parameters
string
required
Your API key
Body Parameters
integer
Only conversations and messages from this point on, in epoch milliseconds. Omit it to import the whole inbox (within the limits below)
string
default:"all"
all, classic, sales_nav or recruiter. all syncs every inbox connected on the accountinteger
default:100
Most recent conversations to import, 1 to 500
integer
default:200
Most recent messages per conversation, 1 to 200. Older ones:
get_conversation with cursorResponse
object
Show Properties
Show Properties
string
Identifier of the sync, also present on every webhook it delivers
string
queued, running, completed or failedobject
Progress per inbox (
classic, sales_nav, recruiter): status, conversations_total, conversations_done, messages_delivered, and error when that inbox failedinteger
Typical duration of the sync
array
Present when your webhooks only receive one direction of messages (
message_type){
"success": true,
"data": {
"sync_id": "6ae89fc905a1e2341aadccda",
"account_id": "6a7705f479d5cb9de0687ae0",
"status": "queued",
"since": 0,
"inboxes": {
"classic": { "status": "queued", "conversations_total": null, "conversations_done": 0, "messages_delivered": 0 }
},
"max_conversations": 100,
"messages_per_conversation": 200,
"created_at": "2026-11-02T14:20:03.511000",
"started_at": null,
"finished_at": null,
"estimated_minutes": 20
},
"metadata": {
"action": "sync_account",
"credits_consumed": 0,
"timestamp": "2026-11-02T14:20:03.514201"
}
}
{
"success": false,
"error": {
"code": "RATE_LIMITED",
"message": "A sync is already running on this account (sync_id 6ae89fc905a1e2341aadccda)"
},
"metadata": {
"action": "sync_account",
"credits_consumed": 0,
"timestamp": "2026-11-02T14:21:40.002117"
}
}
{
"success": true,
"data": {
"sync_id": "6ae89fc905a1e2341aadccda",
"account_id": "6a7705f479d5cb9de0687ae0",
"status": "running",
"since": 0,
"inboxes": {
"classic": { "status": "running", "conversations_total": 100, "conversations_done": 37, "messages_delivered": 412 }
},
"max_conversations": 100,
"messages_per_conversation": 200,
"created_at": "2026-11-02T14:20:03.511000",
"started_at": "2026-11-02T14:20:05.108000",
"finished_at": null
},
"metadata": {
"action": "get_account_sync",
"credits_consumed": 0,
"timestamp": "2026-11-02T14:28:51.730415"
}
}
Follow a sync
GET /v2/accounts/{account_id}/sync/{sync_id} returns the same object (without estimated_minutes), updated as the sync progresses. Free. 404 when the sync does not exist on this account.
Notes
- A sync is
completedwhen at least one of its inboxes succeeded; checkinboxes.<inbox>.statusfor each one - Synced messages can be months old: skip those carrying
sync_id/catch_up: truein automations that react to incoming messages - Each item of
eventsis theeventobject of a real-time message webhook — see Manage LinkedIn Messaging for a parser handling both 409when a sync is already running on the account,429after 10 syncs in 24 hours- LinkedIn accounts only
Was this page helpful?