LinkedIn, WhatsApp and email outreach, lead sourcing, messaging, posting and email enrichment through LinkupAPI's V2 API.
LinkupAPI ships in the w6w first-party pack. It declares 54 actions, 3 health checks, and the host runs its code in a sandbox that never sees the credential.
io.w6w.linkupapiLinkupAPI puts one API in front of LinkedIn, WhatsApp and email for sales and recruiting automation. You connect a channel account once in LinkupAPI’s own dashboard, and every call from a workflow names that account by its account_id, so w6w holds only the API key and never a LinkedIn password or session.
This app covers the V2 surface: reading and searching profiles, companies and posts; sending connection requests and managing received, sent and withdrawn invitations; sending, reading and replying to LinkedIn, WhatsApp and email messages; publishing, reacting to, commenting on and reposting content; recruiter job postings, candidates and CVs; email finding, validation and reverse lookup; and webhooks with a pollable event stream for reacting to replies and accepted invitations.
LinkupAPI drives real LinkedIn accounts on the account holder’s behalf, which LinkedIn’s terms restrict, and the vendor’s own guidance is to stay well under LinkedIn’s limits (about 100 invitations a day on a paid account). Credits are metered per call, and a credit-balance health check shows how many remain.
Three routes to the same 54 actions. The Workflow tab is generated from LinkupAPI's own manifest and carries its real ids, so it is copy-pasteable; the Code and CLI examples are the same call for any action on any app, so every app-specific value in them is a blank you fill in.
account-get Read one connected account: status, checkpoint state, country and Sales Navigator seat.
account-list List the channel accounts (LinkedIn, WhatsApp, email) connected to the API key, with their status and the account_id every other action needs.
comment-reply Reply to a comment on a post. trackingId, profileUrn and commentUrn come from Get Post Comments.
company-search Search LinkedIn company pages by keyword, location, sector and size.
conversation-get Read the messages of one conversation, found by conversation id, profile URL or phone number.
credits-get Read the credits remaining on the LinkupAPI account. Consumes no credits.
email-find Find a professional email address from a name and company, or from a LinkedIn profile URL.
invitation-status-get Check the connection or invitation state between the connected account and a member.
invitation-withdraw Withdraw a pending sent invitation. LinkedIn only lets you invite the same member again about three weeks later.
job-create Create a job posting in draft state; publish it with Publish Job Posting.
log-list Browse the API call history, one entry per request, with the credits each consumed.
message-send Send a LinkedIn message or InMail, a WhatsApp message, or an email from a connected account. Pass the recipient field that matches the account's platform.
people-search Search LinkedIn members by keyword, title, company, location, school, industry or network degree.
post-create Publish a post with text and optionally an image, video, document or carousel.
profile-contact-get Read the contact details a member shares with the connected account (email, phone, websites).
profile-viewers-list List the people who recently viewed the connected account's profile.
webhook-create Register a webhook for an account. Omit the URL for a hosted webhook read by polling. With enableSignature the response carries the signing secret once.
webhook-events-list Read the events stored for a webhook, the catch-up path for hosted and custom webhooks.
A workflow step names the app and the action, and the editor fills in the
connection when you pick one. This is the Step shape from the
workflow spec, carrying LinkupAPI's real ids.
{
"manifestVersion": "2",
"name": "linkupapi-example",
"steps": [
{
"id": "account-get",
"uses": {
"app": "io.w6w.linkupapi",
"action": "account-get",
"connection": "conn_YOUR_CONNECTION_ID"
},
"with": {
"accountId": "<accountId>"
}
}
]
}account-get account-list candidate-cv-get comment-reply company-get +49 more actions available
Every app-specific value here is a blank you have to fill in. An
app action is reached through the connection that authenticates it, so the
address is a connection id, not the app id — and connections belong to your account,
so a public page cannot know yours. Create one for LinkupAPI, then fill in
the three blanks: conn_YOUR_CONNECTION_ID, the action key, and the
parameters that action declares. The call itself is real — the shape is transcribed
from the studio's own snippet builder, which prints the same kind of blanks — but
nothing in it is specific to LinkupAPI. The Workflow tab is where this app's
real ids are.
npm install @w6w/sdkyarn add @w6w/sdkpnpm add @w6w/sdkdeno add npm:@w6w/sdkimport { W6wClient, isActionRun } from "@w6w/sdk";
// Reads W6W_BASE_URL and W6W_TOKEN from the environment when omitted.
const client = new W6wClient();
const envelope = await client.run({
urn: "conn_YOUR_CONNECTION_ID",
action: "account-get",
payload: {
accountId: "<value>",
},
});
if (isActionRun(envelope)) console.log(envelope.value); npm install -g @w6w/cli w6w run conn_YOUR_CONNECTION_ID --action account-get --payload '{"accountId":"<value>"}' Give an AI agent LinkupAPI — without giving it LinkupAPI's credentials. One MCP endpoint exposes every app, function and workflow the caller is entitled to, as tools it can discover and run. Access is granted per team while we onboard.
One tool call{
"name": "w6w_invoke",
"arguments": {
"ref": "app:io.w6w.linkupapi#account-get",
"input": {
"accountId": "<accountId>"
}
}
}
Every tool names its target with a single ref. The
app: form above doesn't name a connection at all — the
host resolves which of the caller's LinkupAPI connections to sign
with, and refuses rather than guesses when the answer is ambiguous.
The token is attached host-side, at the moment of the call. It is never a tool argument, never in the model's context, and never in a transcript — so a prompt injection has nothing to exfiltrate.
Tools are derived per end user from what that person has actually connected and is entitled to — not one shared bot identity carrying the union of everyone's access.
Multi-step work runs on the workflow engine and returns a run handle the agent can poll — retries, branching and state survive the conversation that started them.
LinkupAPI's declared health checks are on the surface too, so an agent can tell "the vendor is down" from "your credential expired" before it burns a retry on either.
The MCP surface is part of the hosted platform. LinkupAPI itself is MIT, and the runtime that executes it is source-available (FSL).
LinkupAPI declares its own checks, so its health is a property of the app rather than something the host guesses at.
Unauthenticated GET /v2/credits. LinkupAPI's JSON INVALID_API_KEY refusal passes: it proves the application is answering.
Credits remaining, from GET /v2/credits. Free to call. Per-seat plans are unmetered; the balance still reads but is not a limit there.