Skip to content
Docs

Quick Start

From an API key to a connected LinkedIn account, a first read, a first webhook and a first write tried without sending it.

This page takes you from an API key to a connected LinkedIn account, a first read, a first webhook and a first write tried without sending it. Every example uses shell variables: replace them with your own values.

1. Set Your Key#

Direct authenticates every API call with the X-API-KEY header. See Authentication And Accounts for how to get a key.

Shell
export DIRECT_API_KEY="your-api-key"
export DIRECT="https://direct.lempile.com/api/v1"

Check it:

Shell
curl -sS "$DIRECT/accounts" -H "X-API-KEY: $DIRECT_API_KEY"
JSON
{
  "object": "AccountList",
  "items": [],
  "cursor": null,
  "total_count": 0,
  "status_counts": { "OK": 0, "CONNECTING": 0, "CREDENTIALS": 0, "STOPPED": 0, "ERROR": 0 }
}

The list holds your workspace's accounts only. A missing, wrong or revoked key answers 401 with "type": "errors/missing_credentials".

2. Connect A LinkedIn Account#

Ask for a hosted auth link, then send the person who owns the LinkedIn account to its url. They sign in to LinkedIn on Lempile's page, in a real browser (security checks and codes included), and come back to your success_redirect_url.

Shell
curl -sS -X POST "$DIRECT/hosted/accounts/link" \
  -H "X-API-KEY: $DIRECT_API_KEY" \
  -H "Content-Type: application/json" \
  -d '{
    "type": "create",
    "api_url": "https://direct.lempile.com",
    "providers": ["LINKEDIN"],
    "expiresOn": "2026-11-01T12:00:00.000Z",
    "name": "user_42",
    "success_redirect_url": "https://app.example.com/linkedin/connected",
    "failure_redirect_url": "https://app.example.com/linkedin/failed",
    "notify_url": "https://app.example.com/hooks/direct-connected?secret=your-own-secret"
  }'
JSON
{
  "object": "HostedAuthUrl",
  "url": "https://direct.lempile.com/connect/<token>"
}

When the account works, Direct POSTs your notify_url:

JSON
{ "status": "CREATION_SUCCESS", "account_id": "<account_id>", "name": "user_42" }

Keep account_id: every other call names it.

Shell
export ACCOUNT_ID="<account_id>"
curl -sS "$DIRECT/accounts/$ACCOUNT_ID" -H "X-API-KEY: $DIRECT_API_KEY"

The account is ready when sources[0].status is OK.

3. First Read#

Shell
curl -sS "$DIRECT/users/me?account_id=$ACCOUNT_ID" \
  -H "X-API-KEY: $DIRECT_API_KEY"
JSON
{
  "object": "AccountOwnerProfile",
  "provider": "LINKEDIN",
  "provider_id": "ACoAAAbcdefghijklmnop",
  "first_name": "Ada",
  "last_name": "Sender",
  "public_identifier": "ada-sender",
  "public_profile_url": "https://www.linkedin.com/in/ada-sender/",
  "premium": true
}

(Shortened.) Then the inbox:

Shell
curl -sS "$DIRECT/chats?account_id=$ACCOUNT_ID&limit=20" \
  -H "X-API-KEY: $DIRECT_API_KEY"

4. First Webhook#

Register a URL for new messages. Put your own secret in a header: Direct sends it with every delivery, and you check it.

Shell
curl -sS -X POST "$DIRECT/webhooks" \
  -H "X-API-KEY: $DIRECT_API_KEY" \
  -H "Content-Type: application/json" \
  -d '{
    "request_url": "https://app.example.com/hooks/linkedin-messages",
    "source": "messaging",
    "name": "messages",
    "headers": [{ "key": "x-webhook-secret", "value": "your-own-secret" }]
  }'
JSON
{ "object": "WebhookCreated", "webhook_id": "<webhook_id>" }

Send the account a LinkedIn message from another account. Within seconds, your URL receives a message_received event. Answer any 2xx. See Webhooks for the payload and the timing.

5. First Write, Not Sent#

Every write takes ?dry_run=true: Direct answers the exact LinkedIn call it would make, and sends nothing.

Shell
export CHAT_ID="<a chat id from GET /chats>"
curl -sS -X POST "$DIRECT/chats/$CHAT_ID/messages?dry_run=true" \
  -H "X-API-KEY: $DIRECT_API_KEY" \
  -H "Content-Type: application/json" \
  -d '{ "account_id": "'"$ACCOUNT_ID"'", "text": "Thanks, Tuesday works for me." }'
JSON
{
  "object": "DryRun",
  "route": "chats.message",
  "method": "POST",
  "path": "/voyager/api/voyagerMessagingDashMessengerMessages?action=createMessage",
  "body": { "message": { "body": { "attributes": [], "text": "Thanks, Tuesday works for me." } } },
  "status": 201
}

(Shortened.) To send it for real, drop dry_run and add an Idempotency-Key header, so a retry never sends it twice:

Shell
curl -sS -X POST "$DIRECT/chats/$CHAT_ID/messages" \
  -H "X-API-KEY: $DIRECT_API_KEY" \
  -H "Idempotency-Key: reply-42" \
  -H "Content-Type: application/json" \
  -d '{ "account_id": "'"$ACCOUNT_ID"'", "text": "Thanks, Tuesday works for me." }'
JSON
{ "object": "MessageSent", "message_id": "<message_id>", "id": "<message_id>" }

An account whose writes aren't on yet answers 403 with title Writes off (errors/insufficient_permissions). Dry runs work either way.

Next#

Was this page helpful?