Migrating From Unipile
Moving a Unipile integration to Direct: base URL, key, account ids, chat ids, webhooks, hosted auth and fallback.
Direct answers Unipile's LinkedIn routes with Unipile's paths, fields, status codes and error types. Moving a Unipile integration is mostly configuration, plus a few points below.
1. Base URL And Key#
| Unipile | Direct | |
|---|---|---|
| Base URL | https://<your-dsn>/api/v1 |
https://direct.lempile.com/api/v1 |
| Key header | X-API-KEY: <unipile key> |
X-API-KEY: <Direct key> (one per workspace, made in Lempile's dashboard) |
Paths stay the same: GET /users/me, GET /chats, POST /chats/{chat_id}/messages…
If your code checks hostnames (for example that a hosted auth link starts with https://account.unipile.com/, or that the API host ends in unipile.com), accept direct.lempile.com too.
2. Account IDs#
Direct's account ids are Lempile account ids. A Unipile account id doesn't exist here.
- Connect each LinkedIn account through Direct's hosted auth link (or have Lempile connect it), then store the new id.
GET /accountslists them;connection_params.im.idis the member's provider id, the same as on Unipile, so you can match accounts by it. - Every account starts with writes off. Ask Lempile to turn writes on per account, and use
?dry_run=truemeanwhile.
3. Chat And Message IDs#
- A chat id is LinkedIn's own conversation id (
2-…) and a message id LinkedIn's own message id, answered URL-safe (-and_, no=). They are not Unipile's ids: chat and message ids stored from Unipile don't resolve. Read the chats from Direct to map them (match on the other attendee's provider id and the latest message's time). - Every inbox call names its account:
GET /chats/{chat_id}?account_id=,GET /chats/{chat_id}/messages?account_id=,GET /messages/{message_id}?account_id=, andaccount_idin the body ofPOST /chats/{chat_id}/messages. Unipile finds the account from the chat id; Direct can't. - Profile provider ids (
ACo…) and posts'social_id(urn:li:activity:…) are LinkedIn's own, as on Unipile, so stored ones keep working. Comment and invitation ids are LinkedIn's numbers; read them from Direct.
4. Webhooks#
- Register your webhooks again with
POST /webhookson Direct: webhooks set in Unipile's dashboard don't move. Same bodies, same payloads. - Messaging events come in real time from LinkedIn's own live connection, with polling as the backstop;
new_relationfrom polling, 30 to 60 minutes after the connection. See Webhooks. message_received,message_read,message_reaction,message_edited,message_deleted,new_relationand the account status events are sent.message_deliveredis accepted but never sent.- Deliveries carry the headers you registered and are not signed: authenticate them with a secret header, as with Unipile.
5. Hosted Auth#
POST /hosted/accounts/linktakes Unipile's body and answers Unipile'sHostedAuthUrl(200). Theurlis ondirect.lempile.com.providerstakes Unipile's forms ("LINKEDIN",["LINKEDIN"],"*","*:MESSAGING") and must take LinkedIn; areconnectlink needs none.- A new account joins your key's workspace; a reconnect link can only name your workspace's accounts.
notify_urlreceives exactly{status, account_id, name}(CREATION_SUCCESSorRECONNECTED), as on Unipile.- Unipile's options
disabled_features,disabled_options,proxy,sync_limit,google_scopes,microsoft_scopesandsingle_useare ignored. The link lasts 24 hours at most. - Native authentication (
POST /accountswith credentials or cookies), checkpoints (POST /accounts/checkpoint) andPATCH /accounts/{id}answer501: accounts connect only through Lempile's real-browser sign-in.
6. Errors And Fallback#
- Error bodies are Unipile's
{title, detail, type, status}; types and statuses follow Unipile's. - Anything Direct doesn't do answers
501 errors/feature_not_implemented. A client that keeps Unipile for some accounts or features can fall back to Unipile on501. For a write, fall back only on501(or403Writes off, or404Account not found): any other answer may mean the write went out. 429 errors/too_many_requestscomes withretry_afterand aRetry-Afterheader: Direct's limits are per account (1,500 LinkedIn calls and 150 writes a day). See Errors And Limits.- A missing
account_idanswers400 errors/missing_parameters, a parameter of the wrong type400 errors/invalid_parameters.
7. What You Gain#
?dry_run=trueon every write: the exact LinkedIn call, not sent.Idempotency-Keyon writes: the same key never writes twice, so retries are safe.DELETE /posts/{post_id}/comments/{comment_id}andDELETE /posts/reaction, which Unipile doesn't have.- Every call goes out from the account's own browser session and its own proxy.
8. Checklist#
- Get a Direct key for your workspace; set the base URL and the key.
- Connect the accounts through hosted auth; store the new account ids.
- Add
account_idto every inbox call that lacked it. - Re-read chats from Direct; don't reuse Unipile's chat and message ids.
- Register the webhooks on Direct; authenticate them with a header secret.
- Accept
direct.lempile.comwherever your code checks Unipile's hostnames. - Try every write with
?dry_run=true, then ask Lempile to turn writes on. - Handle
501(fall back or skip) and429(waitretry_after). - Check the routes you use against Unipile Compatibility.
Was this page helpful?