Start a LinkedIn import through the API
POST /v1/imports does what the sourcing screens do: it creates a list and fills it from LinkedIn. It is the way contacts enter a workspace through the API — every other endpoint works on people already there.
One call
curl -X POST https://api.getswimlane.com/v1/imports \
-H "Authorization: Bearer wpa_…" \
-H "Content-Type: application/json" \
-d '{
"source": "post_engagement",
"listName": "Webinar commenters",
"postUrl": "https://www.linkedin.com/posts/…"
}'
You name the list yourself — nothing is derived from LinkedIn, unlike the app, which builds a name from the post's author.
The seven sources
source |
Who it collects | Fields it needs |
|---|---|---|
post_engagement |
everyone who reacted to or commented on one post | postUrl |
competitor_engagement |
the people engaging with someone else's recent posts | profileUrl |
profile_engagement |
the people engaging with your own posts | — |
profile_visitors |
who viewed your profile between two dates | from, to |
people_search |
a LinkedIn people search, written as a persona in plain words | persona |
topic_search |
a topic turned into a boolean search | topic, strategy |
suggested_contacts |
the people LinkedIn suggests to you | — |
For topic_search, strategy is thematic_search (people talking about the topic) or lead_magnet_hunter (people asking for a resource about it).
A source missing what it reads answers 422 import.missing_parameters, naming the fields.
What happens next
The call answers 202 with the list, and the list is empty. The scraping runs in the background on your own LinkedIn session, at a human pace. Two ways to follow it:
GET /v1/queue?method=Import.PostEngagement— the task, its status and its result.GET /v1/lists/<uuid>—statusgoesscheduled → importing → done(orerror).
Your daily import limit is claimed when the task runs, not when you call. An import started past the limit waits for the next day instead of failing, so queueing a day's sourcing up front is safe. The same goes for your virtual office hours: a run outside them is deferred to the next open window rather than dropped.
Keeping a list filling
Add recurring: true and the same source keeps topping the list up:
{
"source": "competitor_engagement",
"listName": "Engaged with Acme",
"profileUrl": "https://www.linkedin.com/in/acme-founder/",
"recurring": true
}
The response carries a recurringImport with its own uuid. Manage them with:
GET /v1/imports/recurring— every schedule, withnextRunAtandlastRunAt.PATCH /v1/imports/recurring/<uuid>with{"isActive": false}to pause,trueto resume.DELETE /v1/imports/recurring/<uuid>to stop it for good. The list and the contacts already imported are kept.
Two things to expect:
- The interval is not settable. It is drawn at random within a range on every run — roughly 2 to 4 hours, 12 to 24 for LinkedIn's suggestions. A clockwork cadence is one of the easiest automation signals to spot, so
frequencyHoursreports the last interval used rather than one you choose. - For
profile_visitors, each repeat reads the last seven days, whateverfromandtothe first run used.
The pattern worth knowing
A recurring import plus a continuous campaign is a pipeline that feeds itself: the import adds people to the list, and a campaign created with continuous: true on that list enrolls the newcomers on its next scan. Set both up once and new prospects are contacted without anyone opening the app.
That is also the reason to be deliberate about it. Every contact the import finds will be messaged, so point it at a source you would be happy to have a conversation with.
See Swimlane public API reference for the rest of the endpoints.
