in
LinkedIn leads
API

Four on-ramps. Same data.

Ounie accounts hit REST endpoints with a bearer token. AI assistants connect via MCP and get a native tool surface. One-off scripts can skip the account and pay per call via x402 in USDC. All four return the same normalized profile rows.

POST/api/scrape
auth: Bearer
Start an enrichment job
Returns a job_id immediately. The actual run completes async (≈3s per profile); poll /api/jobs/{id} or wait on the webhook.
Body
{
  "profile_urls": [
    "https://www.linkedin.com/in/abrar-kim",
    "https://www.linkedin.com/in/rita-jensen"
  ],
  "label": "Q3 outbound · founders",
  "webhook_url": "https://your-host.com/hook"   // optional
}
Response
{ "ok": true, "job_id": "job_01HX...", "profile_count": 2, "credits_reserved": 2 }
GET/api/jobs/{id}
auth: Bearer
Check job status
Returns the job row plus a 10-minute signed download URL once succeeded.
Response
{
  "job": { "status": "succeeded", "results_count": 2, ... },
  "preview_url": "https://...presigned..."
}
GET/api/jobs/{id}/export?format=csv|json
auth: Bearer
Download the dataset
Streams the file directly. CSV is the default; JSON returns the full normalized profile shape.
POST/api/x402/scrape
auth: none · x402
Pay-per-call (agents)
No account, no API key. Returns 402 with payment terms; sign and retry with X-Payment header. Synchronous; capped at 50 profiles per call.
Body
{
  "profile_urls": [
    "https://www.linkedin.com/in/marcos-silva"
  ]
}
Response
// 402 Payment Required (initial)
{ "x402Version": 1, "accepts": [{ "scheme":"exact", "network":"eip155:8453", "maxAmountRequired": "60000", ... }] }

// 200 OK (after settled X-Payment header)
{ "ok": true, "count": 1, "profiles": [...], "payment": { "tx_hash": "0x..." } }
HTTP/api/mcp
MCP · Streamable HTTP + SSE
Model Context Protocol server
Drop our tool surface into any MCP host (Cursor, Claude desktop, ChatGPT GPTs, the AI SDK, the Ounie AI Team). Seven tools: scrape_linkedin_profiles, get_job_status, export_job_results, list_jobs, get_credit_balance, get_pricing, whoami. Auth: Bearer API key minted in the dashboard — or append ?api_key=lik_live_… to the URL for MCP clients that can't set headers. Calls draw your Ounie credits; jobs that would exceed your balance are refused with a top-up link.
Body
// .cursor/mcp.json (Cursor / any Streamable HTTP host)
{
  "mcpServers": {
    "linkedin-leads": {
      "url": "https://linkedin.ounie.com/api/mcp",
      "headers": { "Authorization": "Bearer lik_live_..." }
    }
  }
}
Response
// Tool call: scrape_linkedin_profiles
{
  "profile_urls": [
    "https://www.linkedin.com/in/abrar-kim",
    "https://www.linkedin.com/in/rita-jensen"
  ],
  "label": "Sales prospects · May"
}
→ { "ok": true, "job_id": "...", "profile_count": 2, "credits_reserved": 2, "poll_with": { ... } }
// One request. Async job. Webhook or poll for results.
const res = await fetch("https://linkedin.ounie.com/api/scrape", {
  method: "POST",
  headers: {
    "Authorization": "Bearer ${API_KEY}",
    "Content-Type": "application/json",
  },
  body: JSON.stringify({
    profile_urls: [
      "https://www.linkedin.com/in/abrar-kim",
      "https://www.linkedin.com/in/rita-jensen",
    ],
    label: "Q3 outbound · founders",
  }),
});

const { job_id } = await res.json();
// → poll /api/jobs/${job_id} or wait on the webhook
Schema
Every profile row.
{
  "linkedinUrl": "https://www.linkedin.com/in/...",
  "publicIdentifier": "...",
  "firstName": "...", "lastName": "...", "fullName": "...",
  "headline": "...", "about": "...",
  "jobTitle": "...", "currentCompany": "...", "industry": "...",
  "location": "...", "city": "...", "country": "...",
  "email": "...", "emails": ["..."],
  "phone": "+1 ...", "phones": ["..."],
  "twitter": "...", "websites": ["..."],
  "profileImageUrl": "https://...",
  "connections": 500, "followers": 1240,
  "experience": [
    {"company":"...","title":"...","dates":"2021–Present","location":"...","description":"..."}
  ],
  "education": [
    {"school":"...","degree":"BSc Computer Science","dates":"2015–2019","description":"..."}
  ],
  "skills": ["..."],
  "certifications": ["..."],
  "languages": ["..."],
  "honorsAndAwards": ["..."],
  "volunteerExperience": ["..."],
  "projects": ["..."],
  "publications": ["..."]
}
Availability

A scheduled probe checks the enrichment engine. While it is down we refuse up front with 503 upstream_unavailable — no price is quoted, no credits are reserved, and nothing is charged on either rail. Service resumes automatically; retry after the Retry-After window.

Rate limits
  • · REST: 60 jobs / min / key
  • · x402: 5 req / sec / payer address
  • · Max profiles per job: 5,000 (REST) · 50 (x402)