{"openapi":"3.1.0","info":{"title":"OutPilot Public API","version":"1.0.0","description":"Programmatic access to OutPilot campaigns, lead lists, lead imports (every import method of the dashboard: Sales Navigator, LinkedIn search, event attendees, post reactors, CSV / Excel, company search, decision-makers and company CSV / Excel), leads, accounts (including connecting new LinkedIn sender accounts and resolving 2FA checkpoints), inbox, stats, and outbound webhooks. Authenticate every request with the `X-API-KEY` header. Rate limit: 300 requests / minute / key.","contact":{"name":"OutPilot Support","url":"https://getbanyan.co/api"}},"servers":[{"url":"https://api.getbanyan.co","description":"Production"}],"tags":[{"name":"Auth"},{"name":"Campaigns"},{"name":"Lead Lists"},{"name":"Lead Imports","description":"Fill a lead list from LinkedIn or a file, with the same gates, daily quotas and limits as the dashboard. Search imports run in the background: the start call answers 202 with a job, and GET /v1/lead-imports/{jobId} reports progress. One search import runs per workspace at a time (shared with the dashboard); a second answers 409 IMPORT_IN_PROGRESS with the running job's id. A Sales Navigator \"import all\" is a run that continues across days: poll GET /v1/lead-imports/runs/{runId}. CSV / Excel imports are synchronous. People methods fill a people list (list created from `listName`, or an existing `leadListId`); company methods fill a company list, whose rows you read at GET /v1/lead-lists/{id}/companies and can feed to decision-makers."},{"name":"Leads"},{"name":"Accounts"},{"name":"Inbox"},{"name":"Stats"},{"name":"Webhooks"}],"components":{"securitySchemes":{"apiKey":{"type":"apiKey","in":"header","name":"X-API-KEY","description":"Workspace-scoped API key prefixed with `op_live_`. Create one at Settings → Developers in the OutPilot dashboard."}},"schemas":{"ApiOk":{"type":"object","required":["success","data","error"],"properties":{"success":{"type":"boolean","const":true},"data":{},"error":{"type":"null"}}},"ApiErr":{"type":"object","required":["success","data","error"],"properties":{"success":{"type":"boolean","const":false},"data":{"type":"null"},"error":{"type":"object","required":["code","message"],"properties":{"code":{"type":"string","example":"INVALID_API_KEY"},"message":{"type":"string"},"details":{}}}}},"Paginated":{"type":"object","required":["data","total","limit","offset"],"properties":{"data":{"type":"array","items":{}},"total":{"type":"integer"},"limit":{"type":"integer"},"offset":{"type":"integer"}}},"LeadImportJob":{"type":"object","properties":{"jobId":{"type":"string"},"type":{"type":["string","null"],"description":"sales_navigator | linkedin_search | event_attendees | post_reactors | decision_makers | company_search. GET /v1/lead-imports also lists the steps of an \"import all\" run (sn_split_plan, then sales_navigator jobs), with their runId."},"status":{"type":"string","enum":["queued","running","completed","failed"]},"leadListId":{"type":["integer","null"],"description":"The list being filled, once known (a new list is created when the job starts)."},"leadListName":{"type":["string","null"]},"requested":{"type":["integer","null"],"description":"How many leads (or companies) the import was started with; null = everything available."},"imported":{"type":"integer","description":"New leads (or companies) added to the list so far."},"searchTotal":{"type":["integer","null"],"description":"Results LinkedIn reported for the search, once known."},"runId":{"type":["integer","null"],"description":"Set when the job is a step of a Sales Navigator \"import all\" run."},"pagesProcessed":{"type":"integer"},"stoppedReason":{"type":["string","null"],"description":"Why a finished import stopped, e.g. max_reached, end_of_results, daily_limit. Company search also: no_new_companies (a page added nothing new: the rest is likely in the list already), page_limit, account_changed / account_disconnected (the account was reconnected or disconnected mid-run), account_reconnect_required, search_failed."},"errorCode":{"type":["string","null"]},"error":{"type":["string","null"],"description":"Set when status is failed."},"createdAt":{"type":["string","null"],"format":"date-time"},"startedAt":{"type":["string","null"],"format":"date-time"},"finishedAt":{"type":["string","null"],"format":"date-time"}}},"LeadImportRun":{"type":"object","description":"A Sales Navigator \"import all\": planned into slices of at most 2,500, imported one after another at the account's daily Sales Navigator budget, across days if needed.","properties":{"runId":{"type":"integer"},"kind":{"type":"string","example":"sn_split"},"status":{"type":"string","description":"planning | queued | running | paused_quota (waits for tomorrow's budget, resumes on its own) | completed | exhausted | failed | cancelled"},"leadListId":{"type":["integer","null"]},"target":{"type":"integer","description":"People the run aims for: the planner's reachable estimate once planned."},"imported":{"type":"integer"},"remaining":{"type":"integer"},"planning":{"type":["object","null"],"properties":{"status":{"type":["string","null"],"description":"planning | planned | failed"},"sourceUrl":{"type":["string","null"]},"baseTotal":{"type":["integer","null"],"description":"Results the whole search reported."},"estimatedReachable":{"type":["integer","null"]},"unreachableEstimate":{"type":["integer","null"]},"slices":{"type":["integer","null"]},"warnings":{"type":"array","items":{"type":"string"}},"error":{"type":["string","null"]}}},"pausedUntil":{"type":["string","null"],"format":"date-time"},"pauseReason":{"type":["string","null"],"description":"daily_limit | retry"},"stopReason":{"type":["string","null"]},"error":{"type":["string","null"]},"currentJob":{"type":["object","null"],"properties":{"jobId":{"type":"string"},"state":{"type":"string"},"imported":{"type":"integer"},"pagesProcessed":{"type":"integer"}}},"createdAt":{"type":["string","null"],"format":"date-time"},"startedAt":{"type":["string","null"],"format":"date-time"},"finishedAt":{"type":["string","null"],"format":"date-time"}}},"FileImportResult":{"type":"object","properties":{"leadListId":{"type":"integer"},"leadListName":{"type":"string"},"listCreated":{"type":"boolean","description":"True when this call created the list (listName)."},"rowsRead":{"type":"integer"},"imported":{"type":"integer","description":"New rows added to the list."},"updated":{"type":"integer","description":"Rows that matched one already in the list and filled in its blank fields."},"duplicates":{"type":"integer"},"duplicatesInFile":{"type":"integer"},"duplicatesExisting":{"type":"integer"},"quarantineCount":{"type":"integer","description":"Rows not imported; each is listed in `quarantined` with its reason."},"quarantined":{"type":"array","items":{"type":"object","additionalProperties":{"type":"string"}}},"quarantineReasons":{"type":"object","additionalProperties":{"type":"integer"}},"linkedinColumnFound":{"type":"boolean"},"linkedinColumnSniffed":{"type":"boolean","description":"The LinkedIn column was recognised from its values rather than its header."},"detectedColumns":{"type":"object","additionalProperties":{"type":["string","null"]},"description":"Field → the header it was read from."},"hint":{"type":["string","null"],"description":"A likely problem with the file, e.g. a people file sent to the company importer."},"sheet":{"type":["string","null"],"description":"The workbook sheet read (Excel)."},"headerRow":{"type":["integer","null"]}}},"LeadListCompany":{"type":"object","properties":{"id":{"type":"integer"},"linkedinCompanyId":{"type":["string","null"]},"name":{"type":["string","null"]},"profileUrl":{"type":["string","null"]},"website":{"type":["string","null"]},"industry":{"type":["string","null"]},"location":{"type":["string","null"]},"description":{"type":["string","null"]},"employeeCount":{"type":["integer","null"]},"employeeRangeFrom":{"type":["integer","null"]},"employeeRangeTo":{"type":["integer","null"]},"followersCount":{"type":["integer","null"]},"primaryEmail":{"type":["string","null"]},"primaryPhone":{"type":["string","null"]},"source":{"type":["string","null"],"description":"company_search | csv"},"linkedinMatchStatus":{"type":["string","null"],"description":"How a CSV row's LinkedIn page was found; null for search rows."},"enrichedAt":{"type":["string","null"],"format":"date-time","description":"When company details were fetched from LinkedIn; null = not yet (it happens in the background after an import)."},"createdAt":{"type":["string","null"],"format":"date-time"}}},"Campaign":{"type":"object","properties":{"id":{"type":"integer"},"name":{"type":"string"},"description":{"type":["string","null"]},"status":{"type":["string","null"],"example":"active","description":"active | paused | draft | completed | finished | failed"},"leadListId":{"type":["integer","null"]},"workflowType":{"type":["string","null"]},"leadsInCampaign":{"type":"integer"},"leadsFinished":{"type":"integer"},"leadsFailed":{"type":"integer"},"connectionAcceptanceRate":{"type":["number","null"]},"messageReplyRate":{"type":["number","null"]},"pausedAt":{"type":["string","null"],"format":"date-time"},"completedAt":{"type":["string","null"],"format":"date-time"},"archivedAt":{"type":["string","null"],"format":"date-time","description":"Set when the campaign is archived. Archived campaigns are hidden from lists by default (include_archived=true to see them)."},"firstExecutionDate":{"type":["string","null"],"format":"date-time"},"lastExecutionDate":{"type":["string","null"],"format":"date-time"},"createdAt":{"type":["string","null"],"format":"date-time"},"updatedAt":{"type":["string","null"],"format":"date-time"}}},"LeadList":{"type":"object","properties":{"id":{"type":"integer"},"name":{"type":"string"},"description":{"type":["string","null"]},"listType":{"type":"string","enum":["people","company"],"description":"people: leads you can put into campaigns. company: companies from a company import (feed them to POST /v1/lead-imports/decision-makers)."},"leadCount":{"type":"integer","description":"People in the list (0 for a company list)."},"companyCount":{"type":"integer","description":"Companies in the list (0 for a people list)."},"createdAt":{"type":["string","null"],"format":"date-time"},"updatedAt":{"type":["string","null"],"format":"date-time"}}},"Lead":{"type":"object","properties":{"id":{"type":"integer"},"leadListId":{"type":"integer"},"fullName":{"type":["string","null"]},"firstName":{"type":["string","null"]},"lastName":{"type":["string","null"]},"linkedinUrl":{"type":["string","null"]},"company":{"type":["string","null"]},"jobTitle":{"type":["string","null"]},"headline":{"type":["string","null"]},"emailAddress":{"type":["string","null"]},"location":{"type":["string","null"]},"hasReplied":{"type":"boolean"},"repliedAt":{"type":["string","null"],"format":"date-time"},"customFields":{"type":["object","null"]},"createdAt":{"type":["string","null"],"format":"date-time"},"updatedAt":{"type":["string","null"],"format":"date-time"}}},"LeadInput":{"type":"object","description":"Either `linkedinUrl` or `publicIdentifier` is required. All other fields are optional. A profile URL in any spelling (country subdomain, trailing slash, tracking query) is stored as https://www.linkedin.com/in/<slug>. With only `fullName`, it is split into first and last name for {{first_name}}. `customFields` keys become {{tokens}} in messages.","properties":{"linkedinUrl":{"type":["string","null"]},"publicIdentifier":{"type":["string","null"]},"fullName":{"type":["string","null"]},"firstName":{"type":["string","null"]},"lastName":{"type":["string","null"]},"emailAddress":{"type":["string","null"]},"company":{"type":["string","null"]},"jobTitle":{"type":["string","null"]},"headline":{"type":["string","null"]},"location":{"type":["string","null"]},"about":{"type":["string","null"]},"profileImageUrl":{"type":["string","null"]},"customFields":{"type":["object","null"]}}},"Account":{"type":"object","properties":{"id":{"type":"integer"},"email":{"type":"string"},"status":{"type":["string","null"]},"profileSlug":{"type":["string","null"]},"profileName":{"type":["string","null"]},"profilePicture":{"type":["string","null"]},"country":{"type":["string","null"]},"timezone":{"type":["string","null"]},"unipileAccountId":{"type":["string","null"]},"isPrimary":{"type":"boolean"},"isPremium":{"type":"boolean"},"isSalesNavigator":{"type":"boolean"},"isRecruiter":{"type":"boolean"},"lastLoginAt":{"type":["string","null"],"format":"date-time"},"lastActivityAt":{"type":["string","null"],"format":"date-time"},"createdAt":{"type":["string","null"],"format":"date-time"},"updatedAt":{"type":["string","null"],"format":"date-time"}}},"Conversation":{"type":"object","properties":{"id":{"type":"integer"},"accountId":{"type":["integer","null"]},"participantName":{"type":["string","null"]},"participantHeadline":{"type":["string","null"]},"participantProfileUrl":{"type":["string","null"]},"participantImageUrl":{"type":["string","null"]},"participantLocation":{"type":["string","null"]},"participantJobTitle":{"type":["string","null"]},"participantEmail":{"type":["string","null"]},"unreadCount":{"type":"integer"},"isArchived":{"type":"boolean"},"isReplied":{"type":["boolean","null"]},"lastMessagePreview":{"type":["string","null"]},"lastMessageAt":{"type":["string","null"],"format":"date-time"},"lastReadAt":{"type":["string","null"],"format":"date-time"},"createdAt":{"type":["string","null"],"format":"date-time"},"updatedAt":{"type":["string","null"],"format":"date-time"}}},"Message":{"type":"object","properties":{"id":{"type":"integer"},"conversationId":{"type":"integer"},"senderName":{"type":["string","null"]},"senderProfileUrl":{"type":["string","null"]},"text":{"type":["string","null"]},"type":{"type":["string","null"]},"isFromMe":{"type":"boolean"},"sentAt":{"type":"string","format":"date-time"},"readAt":{"type":["string","null"],"format":"date-time"}}},"WebhookSubscription":{"type":"object","properties":{"id":{"type":"integer"},"workspaceId":{"type":"integer"},"url":{"type":"string"},"eventTypes":{"type":"array","items":{"type":"string","enum":["lead.replied","connection.accepted"]}},"isActive":{"type":"boolean"},"description":{"type":["string","null"]},"lastDeliveryAt":{"type":["string","null"],"format":"date-time"},"lastStatus":{"type":["string","null"]},"lastErrorCode":{"type":["string","null"]},"lastErrorAt":{"type":["string","null"],"format":"date-time"},"createdAt":{"type":"string","format":"date-time"},"updatedAt":{"type":"string","format":"date-time"}}},"WebhookDelivery":{"type":"object","properties":{"id":{"type":"integer"},"eventId":{"type":"string"},"eventType":{"type":"string"},"status":{"type":"string","enum":["pending","retry","delivered","failed"]},"attemptCount":{"type":"integer"},"lastStatusCode":{"type":["integer","null"]},"lastErrorCode":{"type":["string","null"]},"deliveredAt":{"type":["string","null"],"format":"date-time"},"createdAt":{"type":"string","format":"date-time"}}},"OverviewStats":{"type":"object","properties":{"campaigns":{"type":"object","properties":{"total":{"type":"integer"},"active":{"type":"integer"},"paused":{"type":"integer"},"completed":{"type":"integer"},"draft":{"type":"integer"},"archived":{"type":"integer"}}},"leadLists":{"type":"object","properties":{"total":{"type":"integer"}}},"leads":{"type":"object","properties":{"total":{"type":"integer"}}},"accounts":{"type":"object","properties":{"total":{"type":"integer"},"active":{"type":"integer"}}},"inbox":{"type":"object","properties":{"unreadConversations":{"type":"integer"}}}}}},"parameters":{"Limit":{"name":"limit","in":"query","schema":{"type":"integer","default":50,"maximum":200}},"Offset":{"name":"offset","in":"query","schema":{"type":"integer","default":0}},"IdPath":{"name":"id","in":"path","required":true,"schema":{"type":"integer"}},"IdempotencyKey":{"name":"Idempotency-Key","in":"header","required":false,"description":"Any unique string (≤255 printable characters). A retry with the same key within 24 h gets the first response back, with the header Idempotent-Replayed: true, instead of running again.","schema":{"type":"string","maxLength":255}},"LeadSource":{"name":"X-Outpilot-Source","in":"header","required":false,"description":"Who is pushing these leads, stored as the leads' source. Same as the body's `source`.","schema":{"type":"string","enum":["api","factors","zapier","make","n8n","clay","pipedream"]}}}},"security":[{"apiKey":[]}],"paths":{"/v1/auth/check":{"get":{"tags":["Auth"],"summary":"Verify the API key","responses":{"200":{"description":"Success","content":{"application/json":{"schema":{"allOf":[{"$ref":"#/components/schemas/ApiOk"},{"type":"object","properties":{"data":{"properties":{"valid":{"type":"boolean"},"workspaceId":{"type":"integer"},"workspaceName":{"type":["string","null"]},"keyName":{"type":["string","null"]},"scopes":{"type":"array","items":{"type":"string"}},"rateLimitPerMinute":{"type":"integer"}}}}}]}}}}}}},"/v1/stats/overview":{"get":{"tags":["Stats"],"summary":"Account-wide rollup","responses":{"200":{"description":"Success","content":{"application/json":{"schema":{"allOf":[{"$ref":"#/components/schemas/ApiOk"},{"type":"object","properties":{"data":{"$ref":"#/components/schemas/OverviewStats"}}}]}}}}}}},"/v1/campaigns":{"get":{"tags":["Campaigns"],"summary":"List campaigns","parameters":[{"$ref":"#/components/parameters/Limit"},{"$ref":"#/components/parameters/Offset"},{"name":"status","in":"query","schema":{"type":"string"}},{"name":"include_archived","in":"query","schema":{"type":"boolean","default":false},"description":"Archived campaigns are excluded unless true."}],"responses":{"200":{"description":"Paginated success","content":{"application/json":{"schema":{"allOf":[{"$ref":"#/components/schemas/ApiOk"},{"type":"object","properties":{"data":{"type":"object","required":["data","total","limit","offset"],"properties":{"data":{"type":"array","items":{"$ref":"#/components/schemas/Campaign"}},"total":{"type":"integer"},"limit":{"type":"integer"},"offset":{"type":"integer"}}}}}]}}}}}}},"/v1/campaigns/{id}":{"get":{"tags":["Campaigns"],"summary":"Get a campaign","parameters":[{"$ref":"#/components/parameters/IdPath"}],"responses":{"200":{"description":"Success","content":{"application/json":{"schema":{"allOf":[{"$ref":"#/components/schemas/ApiOk"},{"type":"object","properties":{"data":{"$ref":"#/components/schemas/Campaign"}}}]}}}},"404":{"description":"NOT_FOUND","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ApiErr"}}}}}}},"/v1/campaigns/{id}/leads":{"get":{"tags":["Campaigns"],"summary":"List leads in a campaign's lead list","parameters":[{"$ref":"#/components/parameters/IdPath"},{"$ref":"#/components/parameters/Limit"},{"$ref":"#/components/parameters/Offset"}],"responses":{"200":{"description":"Paginated success","content":{"application/json":{"schema":{"allOf":[{"$ref":"#/components/schemas/ApiOk"},{"type":"object","properties":{"data":{"type":"object","required":["data","total","limit","offset"],"properties":{"data":{"type":"array","items":{"$ref":"#/components/schemas/Lead"}},"total":{"type":"integer"},"limit":{"type":"integer"},"offset":{"type":"integer"}}}}}]}}}},"404":{"description":"NOT_FOUND","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ApiErr"}}}}}},"post":{"tags":["Campaigns"],"summary":"Add leads to a campaign (writes to its lead list)","description":"An active campaign picks new leads up on its next run. Leads already in the list (same LinkedIn profile, however the URL is spelled) are skipped.","parameters":[{"$ref":"#/components/parameters/IdPath"},{"$ref":"#/components/parameters/IdempotencyKey"},{"$ref":"#/components/parameters/LeadSource"}],"requestBody":{"required":true,"content":{"application/json":{"schema":{"type":"object","required":["leads"],"properties":{"leads":{"type":"array","maxItems":200,"items":{"$ref":"#/components/schemas/LeadInput"}},"source":{"type":"string","enum":["api","factors","zapier","make","n8n","clay","pipedream"],"description":"Who is pushing these leads, stored as their source (default api). Same as the X-Outpilot-Source header."}}}}}},"responses":{"200":{"description":"Success","content":{"application/json":{"schema":{"allOf":[{"$ref":"#/components/schemas/ApiOk"},{"type":"object","properties":{"data":{"properties":{"added":{"type":"integer"},"skipped":{"type":"integer"}}}}}]}}}},"400":{"description":"INVALID_BODY | INVALID_SOURCE | NO_LEAD_LIST","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ApiErr"}}}},"404":{"description":"NOT_FOUND","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ApiErr"}}}}}}},"/v1/campaigns/{id}/pause":{"post":{"tags":["Campaigns"],"summary":"Pause a campaign","parameters":[{"$ref":"#/components/parameters/IdPath"}],"responses":{"200":{"description":"Success","content":{"application/json":{"schema":{"allOf":[{"$ref":"#/components/schemas/ApiOk"},{"type":"object","properties":{"data":{"$ref":"#/components/schemas/Campaign"}}}]}}}},"404":{"description":"NOT_FOUND","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ApiErr"}}}}}}},"/v1/campaigns/{id}/resume":{"post":{"tags":["Campaigns"],"summary":"Resume a campaign","parameters":[{"$ref":"#/components/parameters/IdPath"}],"responses":{"200":{"description":"Success","content":{"application/json":{"schema":{"allOf":[{"$ref":"#/components/schemas/ApiOk"},{"type":"object","properties":{"data":{"$ref":"#/components/schemas/Campaign"}}}]}}}},"403":{"description":"SUBSCRIPTION_REQUIRED","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ApiErr"}}}},"404":{"description":"NOT_FOUND","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ApiErr"}}}},"409":{"description":"CAMPAIGN_ARCHIVED","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ApiErr"}}}}}}},"/v1/campaigns/{id}/archive":{"post":{"tags":["Campaigns"],"summary":"Archive a campaign (hidden from lists; an active campaign is paused first). Idempotent.","parameters":[{"$ref":"#/components/parameters/IdPath"}],"responses":{"200":{"description":"Success","content":{"application/json":{"schema":{"allOf":[{"$ref":"#/components/schemas/ApiOk"},{"type":"object","properties":{"data":{"$ref":"#/components/schemas/Campaign"}}}]}}}},"404":{"description":"NOT_FOUND","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ApiErr"}}}}}}},"/v1/campaigns/{id}/unarchive":{"post":{"tags":["Campaigns"],"summary":"Restore an archived campaign (status is unchanged — never auto-active). Idempotent.","parameters":[{"$ref":"#/components/parameters/IdPath"}],"responses":{"200":{"description":"Success","content":{"application/json":{"schema":{"allOf":[{"$ref":"#/components/schemas/ApiOk"},{"type":"object","properties":{"data":{"$ref":"#/components/schemas/Campaign"}}}]}}}},"404":{"description":"NOT_FOUND","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ApiErr"}}}}}}},"/v1/lead-lists":{"get":{"tags":["Lead Lists"],"summary":"List lead lists","parameters":[{"$ref":"#/components/parameters/Limit"},{"$ref":"#/components/parameters/Offset"}],"responses":{"200":{"description":"Paginated success","content":{"application/json":{"schema":{"allOf":[{"$ref":"#/components/schemas/ApiOk"},{"type":"object","properties":{"data":{"type":"object","required":["data","total","limit","offset"],"properties":{"data":{"type":"array","items":{"$ref":"#/components/schemas/LeadList"}},"total":{"type":"integer"},"limit":{"type":"integer"},"offset":{"type":"integer"}}}}}]}}}}}},"post":{"tags":["Lead Lists"],"summary":"Create an empty lead list","requestBody":{"required":true,"content":{"application/json":{"schema":{"type":"object","required":["name"],"properties":{"name":{"type":"string"},"description":{"type":["string","null"]},"listType":{"type":"string","enum":["people","company"],"default":"people"}}}}}},"responses":{"201":{"description":"Success","content":{"application/json":{"schema":{"allOf":[{"$ref":"#/components/schemas/ApiOk"},{"type":"object","properties":{"data":{"$ref":"#/components/schemas/LeadList"}}}]}}}},"409":{"description":"DUPLICATE_LIST_NAME","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ApiErr"}}}}}}},"/v1/lead-lists/{id}":{"get":{"tags":["Lead Lists"],"summary":"Get a lead list","parameters":[{"$ref":"#/components/parameters/IdPath"}],"responses":{"200":{"description":"Success","content":{"application/json":{"schema":{"allOf":[{"$ref":"#/components/schemas/ApiOk"},{"type":"object","properties":{"data":{"$ref":"#/components/schemas/LeadList"}}}]}}}},"404":{"description":"NOT_FOUND","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ApiErr"}}}}}}},"/v1/lead-lists/{id}/leads":{"get":{"tags":["Lead Lists"],"summary":"List leads in a list","parameters":[{"$ref":"#/components/parameters/IdPath"},{"$ref":"#/components/parameters/Limit"},{"$ref":"#/components/parameters/Offset"}],"responses":{"200":{"description":"Paginated success","content":{"application/json":{"schema":{"allOf":[{"$ref":"#/components/schemas/ApiOk"},{"type":"object","properties":{"data":{"type":"object","required":["data","total","limit","offset"],"properties":{"data":{"type":"array","items":{"$ref":"#/components/schemas/Lead"}},"total":{"type":"integer"},"limit":{"type":"integer"},"offset":{"type":"integer"}}}}}]}}}},"404":{"description":"NOT_FOUND","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ApiErr"}}}}}},"post":{"tags":["Lead Lists"],"summary":"Add leads to a list","description":"Leads already in the list (same LinkedIn profile, however the URL is spelled) are skipped.","parameters":[{"$ref":"#/components/parameters/IdPath"},{"$ref":"#/components/parameters/IdempotencyKey"},{"$ref":"#/components/parameters/LeadSource"}],"requestBody":{"required":true,"content":{"application/json":{"schema":{"type":"object","required":["leads"],"properties":{"leads":{"type":"array","maxItems":200,"items":{"$ref":"#/components/schemas/LeadInput"}},"source":{"type":"string","enum":["api","factors","zapier","make","n8n","clay","pipedream"],"description":"Who is pushing these leads, stored as their source (default api). Same as the X-Outpilot-Source header."}}}}}},"responses":{"200":{"description":"Success","content":{"application/json":{"schema":{"allOf":[{"$ref":"#/components/schemas/ApiOk"},{"type":"object","properties":{"data":{"properties":{"added":{"type":"integer"},"skipped":{"type":"integer"}}}}}]}}}},"400":{"description":"INVALID_BODY | INVALID_SOURCE","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ApiErr"}}}},"404":{"description":"NOT_FOUND","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ApiErr"}}}},"422":{"description":"UNSUPPORTED_LIST_TYPE (a company list)","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ApiErr"}}}}}}},"/v1/lead-lists/{id}/companies":{"get":{"tags":["Lead Lists"],"summary":"List companies in a company list","parameters":[{"$ref":"#/components/parameters/IdPath"},{"$ref":"#/components/parameters/Limit"},{"$ref":"#/components/parameters/Offset"}],"responses":{"200":{"description":"Paginated success","content":{"application/json":{"schema":{"allOf":[{"$ref":"#/components/schemas/ApiOk"},{"type":"object","properties":{"data":{"type":"object","required":["data","total","limit","offset"],"properties":{"data":{"type":"array","items":{"$ref":"#/components/schemas/LeadListCompany"}},"total":{"type":"integer"},"limit":{"type":"integer"},"offset":{"type":"integer"}}}}}]}}}},"404":{"description":"NOT_FOUND","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ApiErr"}}}},"422":{"description":"UNSUPPORTED_LIST_TYPE (a people list)","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ApiErr"}}}}}}},"/v1/lead-imports/sales-navigator":{"post":{"tags":["Lead Imports"],"summary":"Import a Sales Navigator people search","description":"Imports up to 2,500 people (LinkedIn's per-search ceiling) from one Sales Navigator people search. The account needs Sales Navigator. For more than 2,500, use POST /v1/lead-imports/sales-navigator-all. A SALES_NAVIGATOR_SESSION_EXPIRED refusal is remembered for 10 minutes per account, so retrying sooner (even right after renewing Sales Navigator) gets the same answer.","requestBody":{"required":true,"content":{"application/json":{"schema":{"type":"object","required":["accountId","searchUrl"],"properties":{"accountId":{"type":"integer","description":"The LinkedIn account that runs the search (GET /v1/accounts)."},"searchUrl":{"type":"string","description":"A linkedin.com/sales/search/people URL, copied after the results load."},"leadListId":{"type":"integer","description":"An existing people list to add to."},"listName":{"type":"string","maxLength":255,"description":"Or: the name of a new list (made unique if taken)."},"maxLeads":{"type":"integer","minimum":1,"maximum":2500,"description":"Defaults to everything, up to 2,500."}}}}}},"responses":{"202":{"description":"Success","content":{"application/json":{"schema":{"allOf":[{"$ref":"#/components/schemas/ApiOk"},{"type":"object","properties":{"data":{"$ref":"#/components/schemas/LeadImportJob"}}}]}}}},"400":{"description":"VALIDATION | INVALID_BODY | INVALID_ACCOUNT | NOT_CONNECTED | ACCOUNT_NOT_ACTIVE | SALES_NAVIGATOR_REQUIRED","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ApiErr"}}}},"403":{"description":"SUBSCRIPTION_REQUIRED","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ApiErr"}}}},"404":{"description":"NOT_FOUND","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ApiErr"}}}},"409":{"description":"IMPORT_IN_PROGRESS (one search import at a time; details.jobId names the running one) | IMPORT_STARTING (another start is in flight; retry in a few seconds) | SALES_NAVIGATOR_SESSION_EXPIRED","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ApiErr"}}}},"422":{"description":"UNSUPPORTED_LIST_TYPE","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ApiErr"}}}},"429":{"description":"IMPORT_DAILY_LIMIT | SEARCH_DAILY_LIMIT","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ApiErr"}}}},"503":{"description":"QUEUE_UNAVAILABLE | UNIPILE_UNAVAILABLE","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ApiErr"}}}}}}},"/v1/lead-imports/sales-navigator-all":{"post":{"tags":["Lead Imports"],"summary":"Import every person in a Sales Navigator search (beyond 2,500)","description":"Starts a run: a planner splits the search into slices of at most 2,500 (a few minutes), then imports them one after another at the account's daily Sales Navigator budget, pausing at the daily limit and resuming on its own. Poll GET /v1/lead-imports/runs/{runId}. One run per account at a time.","requestBody":{"required":true,"content":{"application/json":{"schema":{"type":"object","required":["accountId","searchUrl"],"properties":{"accountId":{"type":"integer","description":"The LinkedIn account that runs the search (GET /v1/accounts)."},"searchUrl":{"type":"string","description":"A linkedin.com/sales/search/people URL containing its filters (query=(…)); saved-search links can't be split."},"leadListId":{"type":"integer","description":"An existing people list to add to."},"listName":{"type":"string","maxLength":255,"description":"Or: the name of a new list (made unique if taken)."}}}}}},"responses":{"202":{"description":"Success","content":{"application/json":{"schema":{"allOf":[{"$ref":"#/components/schemas/ApiOk"},{"type":"object","properties":{"data":{"type":"object","properties":{"run":{"$ref":"#/components/schemas/LeadImportRun"},"note":{"type":"string"}}}}}]}}}},"400":{"description":"VALIDATION | INVALID_BODY | SALES_NAVIGATOR_REQUIRED | NOT_CONNECTED | ACCOUNT_NOT_ACTIVE","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ApiErr"}}}},"403":{"description":"SUBSCRIPTION_REQUIRED","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ApiErr"}}}},"404":{"description":"NOT_FOUND","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ApiErr"}}}},"409":{"description":"SOURCING_RUN_IN_PROGRESS (details.runId; cancel it with POST /v1/lead-imports/runs/{runId}/cancel) | SALES_NAVIGATOR_SESSION_EXPIRED","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ApiErr"}}}},"422":{"description":"UNSUPPORTED_LIST_TYPE","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ApiErr"}}}}}}},"/v1/lead-imports/linkedin-search":{"post":{"tags":["Lead Imports"],"summary":"Import a LinkedIn people search (keywords or search URL)","description":"Classic LinkedIn search, by keywords and filters or by a linkedin.com/search/results/people URL. Counts against the account's daily search limit (lower for free accounts).","requestBody":{"required":true,"content":{"application/json":{"schema":{"type":"object","required":["accountId"],"properties":{"accountId":{"type":"integer","description":"The LinkedIn account that runs the search (GET /v1/accounts)."},"keywords":{"type":"string","maxLength":500},"url":{"type":"string","maxLength":8000,"description":"A linkedin.com/search/results/people URL (instead of keywords)."},"location":{"description":"Location name(s) or LinkedIn geo id(s). Up to 20 values; each name costs a LinkedIn lookup to resolve.","oneOf":[{"type":"string","maxLength":200},{"type":"array","maxItems":20,"items":{"type":["string","integer"],"maxLength":200}}]},"industry":{"description":"Industry name(s) or LinkedIn id(s). Up to 20 values; each name costs a LinkedIn lookup to resolve.","oneOf":[{"type":"string","maxLength":200},{"type":"array","maxItems":20,"items":{"type":["string","integer"],"maxLength":200}}]},"currentCompany":{"description":"Company name(s) or LinkedIn company id(s). Up to 20 values; each name costs a LinkedIn lookup to resolve.","oneOf":[{"type":"string","maxLength":200},{"type":"array","maxItems":20,"items":{"type":["string","integer"],"maxLength":200}}]},"pastCompany":{"description":"Company name(s) or LinkedIn company id(s). Up to 20 values; each name costs a LinkedIn lookup to resolve.","oneOf":[{"type":"string","maxLength":200},{"type":"array","maxItems":20,"items":{"type":["string","integer"],"maxLength":200}}]},"connectionDegree":{"type":"array","maxItems":3,"items":{"type":"integer","enum":[1,2,3]}},"skipExistingInOtherLists":{"type":"boolean","default":true,"description":"Leave out people already in your other lists."},"leadListId":{"type":"integer","description":"An existing people list to add to."},"listName":{"type":"string","maxLength":255,"description":"Or: the name of a new list (made unique if taken)."},"maxLeads":{"type":"integer","minimum":1,"default":500}}}}}},"responses":{"202":{"description":"Success","content":{"application/json":{"schema":{"allOf":[{"$ref":"#/components/schemas/ApiOk"},{"type":"object","properties":{"data":{"$ref":"#/components/schemas/LeadImportJob"}}}]}}}},"400":{"description":"VALIDATION | INVALID_BODY | INVALID_ACCOUNT | NOT_CONNECTED | ACCOUNT_NOT_ACTIVE","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ApiErr"}}}},"403":{"description":"SUBSCRIPTION_REQUIRED","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ApiErr"}}}},"404":{"description":"NOT_FOUND","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ApiErr"}}}},"409":{"description":"IMPORT_IN_PROGRESS (one search import at a time; details.jobId names the running one) | IMPORT_STARTING (another start is in flight; retry in a few seconds) | SEARCH_SUPPRESSED","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ApiErr"}}}},"422":{"description":"UNSUPPORTED_LIST_TYPE","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ApiErr"}}}},"429":{"description":"IMPORT_DAILY_LIMIT | SEARCH_DAILY_LIMIT","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ApiErr"}}}},"503":{"description":"QUEUE_UNAVAILABLE | UNIPILE_UNAVAILABLE","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ApiErr"}}}}}}},"/v1/lead-imports/event-attendees":{"post":{"tags":["Lead Imports"],"summary":"Import the attendees of a LinkedIn event","description":"LinkedIn shows an event's attendee list only to accounts that are attending: RSVP (\"Attend\") with the sending account first, or the import completes with 0. Runs as a LinkedIn search and counts against the same daily limit.","requestBody":{"required":true,"content":{"application/json":{"schema":{"type":"object","required":["accountId"],"properties":{"accountId":{"type":"integer","description":"The LinkedIn account that runs the search (GET /v1/accounts)."},"eventUrl":{"type":"string","maxLength":8000,"description":"The event's address, e.g. https://www.linkedin.com/events/1234567890/."},"eventId":{"type":"string","description":"Or the numeric event id, as a string (JSON numbers can't hold 19-digit ids exactly)."},"skipExistingInOtherLists":{"type":"boolean","default":true},"leadListId":{"type":"integer","description":"An existing people list to add to."},"listName":{"type":"string","maxLength":255,"description":"Or: the name of a new list (made unique if taken)."},"maxLeads":{"type":"integer","minimum":1,"default":500}}}}}},"responses":{"202":{"description":"Success","content":{"application/json":{"schema":{"allOf":[{"$ref":"#/components/schemas/ApiOk"},{"type":"object","properties":{"data":{"$ref":"#/components/schemas/LeadImportJob"}}}]}}}},"400":{"description":"VALIDATION | INVALID_BODY | INVALID_ACCOUNT | NOT_CONNECTED | ACCOUNT_NOT_ACTIVE","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ApiErr"}}}},"403":{"description":"SUBSCRIPTION_REQUIRED","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ApiErr"}}}},"404":{"description":"NOT_FOUND","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ApiErr"}}}},"409":{"description":"IMPORT_IN_PROGRESS (one search import at a time; details.jobId names the running one) | IMPORT_STARTING (another start is in flight; retry in a few seconds) | SEARCH_SUPPRESSED","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ApiErr"}}}},"422":{"description":"UNSUPPORTED_LIST_TYPE","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ApiErr"}}}},"429":{"description":"IMPORT_DAILY_LIMIT | SEARCH_DAILY_LIMIT","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ApiErr"}}}},"503":{"description":"QUEUE_UNAVAILABLE | UNIPILE_UNAVAILABLE","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ApiErr"}}}}}}},"/v1/lead-imports/post-reactors":{"post":{"tags":["Lead Imports"],"summary":"Import the people who reacted to a LinkedIn post","requestBody":{"required":true,"content":{"application/json":{"schema":{"type":"object","required":["accountId","postUrl"],"properties":{"accountId":{"type":"integer","description":"The LinkedIn account that runs the search (GET /v1/accounts)."},"postUrl":{"type":"string","description":"The post's address (linkedin.com/posts/… or linkedin.com/feed/update/…)."},"leadListId":{"type":"integer","description":"An existing people list to add to."},"listName":{"type":"string","maxLength":255,"description":"Or: the name of a new list (made unique if taken)."}}}}}},"responses":{"202":{"description":"Success","content":{"application/json":{"schema":{"allOf":[{"$ref":"#/components/schemas/ApiOk"},{"type":"object","properties":{"data":{"$ref":"#/components/schemas/LeadImportJob"}}}]}}}},"400":{"description":"VALIDATION | INVALID_BODY | INVALID_ACCOUNT | NOT_CONNECTED | ACCOUNT_NOT_ACTIVE","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ApiErr"}}}},"403":{"description":"SUBSCRIPTION_REQUIRED","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ApiErr"}}}},"404":{"description":"NOT_FOUND","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ApiErr"}}}},"409":{"description":"IMPORT_IN_PROGRESS (one search import at a time; details.jobId names the running one) | IMPORT_STARTING (another start is in flight; retry in a few seconds)","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ApiErr"}}}},"422":{"description":"UNSUPPORTED_LIST_TYPE","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ApiErr"}}}},"429":{"description":"IMPORT_DAILY_LIMIT | SEARCH_DAILY_LIMIT","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ApiErr"}}}},"503":{"description":"QUEUE_UNAVAILABLE | UNIPILE_UNAVAILABLE","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ApiErr"}}}}}}},"/v1/lead-imports/csv":{"post":{"tags":["Lead Imports"],"summary":"Import people from a CSV or Excel file (synchronous)","description":"Every row needs a LinkedIn profile URL; other columns (name, company, title, email, phone, …) are recognised from their headers. Send CSV text in `csv`, or a .csv / .tsv / .xlsx file base64-encoded in `file.content`. Up to 20,000 rows; body limit 12 MiB.","requestBody":{"required":true,"content":{"application/json":{"schema":{"type":"object","properties":{"leadListId":{"type":"integer","description":"An existing people list to add to."},"listName":{"type":"string","maxLength":255,"description":"Or: the name of a new list (made unique if taken)."},"csv":{"type":"string","description":"CSV text."},"file":{"type":"object","required":["content"],"description":"A file instead of `csv`.","properties":{"name":{"type":"string","example":"leads.xlsx"},"content":{"type":"string","description":"The file's bytes, base64-encoded (a data: URL works too)."}}}}}}}},"responses":{"200":{"description":"Success","content":{"application/json":{"schema":{"allOf":[{"$ref":"#/components/schemas/ApiOk"},{"type":"object","properties":{"data":{"$ref":"#/components/schemas/FileImportResult"}}}]}}}},"400":{"description":"VALIDATION","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ApiErr"}}}},"403":{"description":"SUBSCRIPTION_REQUIRED","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ApiErr"}}}},"404":{"description":"NOT_FOUND","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ApiErr"}}}},"413":{"description":"FILE_TOO_LARGE","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ApiErr"}}}},"422":{"description":"UNSUPPORTED_LIST_TYPE (a company list)","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ApiErr"}}}}}}},"/v1/lead-imports/company-search":{"post":{"tags":["Lead Imports"],"summary":"Import a LinkedIn or Sales Navigator company search","description":"Fills a company list from a linkedin.com/search/results/companies URL, or a Sales Navigator linkedin.com/sales/search/company URL (the account then needs Sales Navigator). LinkedIn serves about 1,000 results per company search. Company details (size, description, HQ, website) are filled in in the background afterwards (`enrichedAt`). Counts against the account's daily search limit.","requestBody":{"required":true,"content":{"application/json":{"schema":{"type":"object","required":["accountId","searchUrl"],"properties":{"accountId":{"type":"integer","description":"The LinkedIn account that runs the search (GET /v1/accounts)."},"searchUrl":{"type":"string"},"leadListId":{"type":"integer","description":"An existing company list to add to."},"listName":{"type":"string","maxLength":255,"description":"Or: the name of a new company list."},"maxCompanies":{"type":"integer","minimum":1,"maximum":1000,"default":500,"description":"New companies to add. Pages hold 50, and the last page is kept whole, so the count can overshoot by up to 49. A page that adds no new company ends the run (the rest of the search is most likely in the list already)."}}}}}},"responses":{"202":{"description":"Success","content":{"application/json":{"schema":{"allOf":[{"$ref":"#/components/schemas/ApiOk"},{"type":"object","properties":{"data":{"$ref":"#/components/schemas/LeadImportJob"}}}]}}}},"400":{"description":"VALIDATION | INVALID_BODY | INVALID_ACCOUNT | NOT_CONNECTED | ACCOUNT_NOT_ACTIVE | SALES_NAVIGATOR_REQUIRED","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ApiErr"}}}},"403":{"description":"SUBSCRIPTION_REQUIRED","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ApiErr"}}}},"404":{"description":"NOT_FOUND","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ApiErr"}}}},"409":{"description":"IMPORT_IN_PROGRESS (one search import at a time; details.jobId names the running one) | IMPORT_STARTING (another start is in flight; retry in a few seconds) | SALES_NAVIGATOR_SESSION_EXPIRED","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ApiErr"}}}},"422":{"description":"UNSUPPORTED_LIST_TYPE","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ApiErr"}}}},"429":{"description":"IMPORT_DAILY_LIMIT | SEARCH_DAILY_LIMIT","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ApiErr"}}}},"503":{"description":"QUEUE_UNAVAILABLE | UNIPILE_UNAVAILABLE","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ApiErr"}}}}}}},"/v1/lead-imports/decision-makers":{"post":{"tags":["Lead Imports"],"summary":"Find decision-makers at a set of companies","description":"Searches Sales Navigator company by company for senior people (owners, C-level, VPs, directors and managers by default, senior-most first) and puts them in a NEW people list. Target a company list (sourceCompanyListId) or give LinkedIn company ids. The account needs Sales Navigator; the search spends its daily Sales Navigator budget.","requestBody":{"required":true,"content":{"application/json":{"schema":{"type":"object","required":["accountId"],"properties":{"accountId":{"type":"integer","description":"The LinkedIn account that runs the search (GET /v1/accounts)."},"listName":{"type":"string","maxLength":255,"default":"Decision-makers"},"sourceCompanyListId":{"type":"integer","description":"A company list; rows not yet matched to a LinkedIn company page are skipped."},"companies":{"type":"array","maxItems":500,"items":{"type":"object","required":["id"],"properties":{"id":{"type":"string","pattern":"^[0-9]+$","description":"LinkedIn company id, as a string."},"name":{"type":"string"}}}},"filters":{"type":"object","properties":{"seniority":{"type":"array","items":{"type":"string","enum":["owner/partner","cxo","vice_president","director","experienced_manager","entry_level_manager","strategic","senior","entry_level","in_training"]}},"functionIds":{"type":"array","items":{"type":"string"},"description":"LinkedIn function (department) ids."},"roleKeywords":{"type":"array","items":{"type":"string"},"description":"Words the current job title must contain."},"headcountMin":{"type":"integer","minimum":0},"headcountMax":{"type":"integer","minimum":0},"locationIds":{"type":"array","items":{"type":"string"},"description":"LinkedIn geo ids."}}},"perCompanyCap":{"type":"integer","minimum":1,"maximum":100,"default":25},"maxLeads":{"type":"integer","minimum":1,"maximum":1000,"default":1000}}}}}},"responses":{"202":{"description":"Success","content":{"application/json":{"schema":{"allOf":[{"$ref":"#/components/schemas/ApiOk"},{"type":"object","properties":{"data":{"allOf":[{"$ref":"#/components/schemas/LeadImportJob"},{"type":"object","properties":{"companiesMatched":{"type":["integer","null"],"description":"Company-list rows matched to a LinkedIn company page."},"companiesTotal":{"type":["integer","null"]}}}]}}}]}}}},"400":{"description":"VALIDATION | INVALID_BODY | INVALID_ACCOUNT | SALES_NAVIGATOR_REQUIRED | NOT_CONNECTED | ACCOUNT_NOT_ACTIVE","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ApiErr"}}}},"403":{"description":"SUBSCRIPTION_REQUIRED","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ApiErr"}}}},"404":{"description":"NOT_FOUND","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ApiErr"}}}},"409":{"description":"IMPORT_IN_PROGRESS | SALES_NAVIGATOR_SESSION_EXPIRED","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ApiErr"}}}},"429":{"description":"SEARCH_DAILY_LIMIT","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ApiErr"}}}},"503":{"description":"QUEUE_UNAVAILABLE","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ApiErr"}}}}}}},"/v1/lead-imports/companies-csv":{"post":{"tags":["Lead Imports"],"summary":"Import companies from a CSV or Excel file (synchronous)","description":"Each row needs a LinkedIn company URL or id, a website, or both (rows with only a name are imported when they name a person at the company). Rows without a LinkedIn id are matched to their LinkedIn page in the background, then enriched. Send CSV text in `csv`, or a base64 file in `file.content`. Up to 20,000 rows; 5,000 companies per list.","requestBody":{"required":true,"content":{"application/json":{"schema":{"type":"object","properties":{"leadListId":{"type":"integer","description":"An existing company list."},"listName":{"type":"string","maxLength":255,"description":"Or: the name of a new company list."},"csv":{"type":"string"},"file":{"type":"object","required":["content"],"description":"A file instead of `csv`.","properties":{"name":{"type":"string","example":"leads.xlsx"},"content":{"type":"string","description":"The file's bytes, base64-encoded (a data: URL works too)."}}}}}}}},"responses":{"200":{"description":"Success","content":{"application/json":{"schema":{"allOf":[{"$ref":"#/components/schemas/ApiOk"},{"type":"object","properties":{"data":{"allOf":[{"$ref":"#/components/schemas/FileImportResult"},{"type":"object","properties":{"websiteColumnFound":{"type":"boolean"},"websiteColumnSniffed":{"type":"boolean"},"identity":{"type":"object","description":"How the written rows are identified.","properties":{"withId":{"type":"integer"},"withSlug":{"type":"integer"},"websiteOnly":{"type":"integer"},"nameWithPerson":{"type":"integer"}}}}}]}}}]}}}},"400":{"description":"VALIDATION","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ApiErr"}}}},"403":{"description":"SUBSCRIPTION_REQUIRED","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ApiErr"}}}},"404":{"description":"NOT_FOUND","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ApiErr"}}}},"413":{"description":"FILE_TOO_LARGE","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ApiErr"}}}},"422":{"description":"UNSUPPORTED_LIST_TYPE (a people list)","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ApiErr"}}}}}}},"/v1/lead-imports":{"get":{"tags":["Lead Imports"],"summary":"Imports still queued or running in this workspace","responses":{"200":{"description":"Success","content":{"application/json":{"schema":{"allOf":[{"$ref":"#/components/schemas/ApiOk"},{"type":"object","properties":{"data":{"type":"array","items":{"$ref":"#/components/schemas/LeadImportJob"}}}}]}}}},"503":{"description":"QUEUE_UNAVAILABLE","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ApiErr"}}}}}}},"/v1/lead-imports/{jobId}":{"get":{"tags":["Lead Imports"],"summary":"Get an import job","parameters":[{"name":"jobId","in":"path","required":true,"schema":{"type":"string"}}],"responses":{"200":{"description":"Success","content":{"application/json":{"schema":{"allOf":[{"$ref":"#/components/schemas/ApiOk"},{"type":"object","properties":{"data":{"$ref":"#/components/schemas/LeadImportJob"}}}]}}}},"400":{"description":"INVALID_ID","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ApiErr"}}}},"404":{"description":"NOT_FOUND","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ApiErr"}}}},"503":{"description":"QUEUE_UNAVAILABLE","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ApiErr"}}}}}}},"/v1/lead-imports/runs/{runId}/cancel":{"post":{"tags":["Lead Imports"],"summary":"Cancel a Sales Navigator import-all run","description":"Stops the run. A step that hasn't started is dropped; one in progress stops after its current page. Leads already added stay in the list.","parameters":[{"name":"runId","in":"path","required":true,"schema":{"type":"integer"}}],"responses":{"200":{"description":"Success","content":{"application/json":{"schema":{"allOf":[{"$ref":"#/components/schemas/ApiOk"},{"type":"object","properties":{"data":{"type":"object","properties":{"run":{"$ref":"#/components/schemas/LeadImportRun"},"message":{"type":"string"}}}}}]}}}},"400":{"description":"INVALID_ID","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ApiErr"}}}},"404":{"description":"NOT_FOUND","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ApiErr"}}}},"409":{"description":"BUSY | CONFLICT (try again)","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ApiErr"}}}}}}},"/v1/lead-imports/runs/{runId}":{"get":{"tags":["Lead Imports"],"summary":"Get a Sales Navigator import-all run","parameters":[{"name":"runId","in":"path","required":true,"schema":{"type":"integer"}}],"responses":{"200":{"description":"Success","content":{"application/json":{"schema":{"allOf":[{"$ref":"#/components/schemas/ApiOk"},{"type":"object","properties":{"data":{"$ref":"#/components/schemas/LeadImportRun"}}}]}}}},"400":{"description":"INVALID_ID","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ApiErr"}}}},"404":{"description":"NOT_FOUND","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ApiErr"}}}}}}},"/v1/leads":{"get":{"tags":["Leads"],"summary":"List leads across all lists","parameters":[{"$ref":"#/components/parameters/Limit"},{"$ref":"#/components/parameters/Offset"},{"name":"leadListId","in":"query","schema":{"type":"integer"}}],"responses":{"200":{"description":"Paginated success","content":{"application/json":{"schema":{"allOf":[{"$ref":"#/components/schemas/ApiOk"},{"type":"object","properties":{"data":{"type":"object","required":["data","total","limit","offset"],"properties":{"data":{"type":"array","items":{"$ref":"#/components/schemas/Lead"}},"total":{"type":"integer"},"limit":{"type":"integer"},"offset":{"type":"integer"}}}}}]}}}}}}},"/v1/leads/{id}":{"get":{"tags":["Leads"],"summary":"Get a lead","parameters":[{"$ref":"#/components/parameters/IdPath"}],"responses":{"200":{"description":"Success","content":{"application/json":{"schema":{"allOf":[{"$ref":"#/components/schemas/ApiOk"},{"type":"object","properties":{"data":{"$ref":"#/components/schemas/Lead"}}}]}}}},"404":{"description":"NOT_FOUND","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ApiErr"}}}}}}},"/v1/leads/{id}/connect":{"post":{"tags":["Leads"],"summary":"Send a LinkedIn connection request to this lead","description":"Uses the lead's linkedinUrl and an already-connected sender account. Shares the account's daily connection cap with campaigns — an API key cannot exceed the account's normal send limits.","parameters":[{"$ref":"#/components/parameters/IdPath"}],"requestBody":{"required":true,"content":{"application/json":{"schema":{"type":"object","properties":{"accountId":{"type":"integer","description":"Which connected account to send from. Defaults to the workspace's first ready account."},"note":{"type":"string","maxLength":300}}}}}},"responses":{"200":{"description":"Success","content":{"application/json":{"schema":{"allOf":[{"$ref":"#/components/schemas/ApiOk"},{"type":"object","properties":{"data":{"type":"object","properties":{"sent":{"type":"boolean"},"alreadyConnected":{"type":"boolean"},"accountId":{"type":"integer"},"providerId":{"type":["string","null"]},"budgetAfter":{"type":"object","properties":{"used":{"type":"integer"},"cap":{"type":"integer"},"remaining":{"type":"integer"}}}}}}}]}}}},"400":{"description":"NO_LINKEDIN_URL | NO_ACCOUNT | INVITE_FAILED","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ApiErr"}}}},"404":{"description":"NOT_FOUND","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ApiErr"}}}},"429":{"description":"DAILY_LIMIT","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ApiErr"}}}}}}},"/v1/accounts":{"get":{"tags":["Accounts"],"summary":"List LinkedIn accounts","parameters":[{"$ref":"#/components/parameters/Limit"},{"$ref":"#/components/parameters/Offset"}],"responses":{"200":{"description":"Paginated success","content":{"application/json":{"schema":{"allOf":[{"$ref":"#/components/schemas/ApiOk"},{"type":"object","properties":{"data":{"type":"object","required":["data","total","limit","offset"],"properties":{"data":{"type":"array","items":{"$ref":"#/components/schemas/Account"}},"total":{"type":"integer"},"limit":{"type":"integer"},"offset":{"type":"integer"}}}}}]}}}}}},"post":{"tags":["Accounts"],"summary":"Connect a new LinkedIn sender account","description":"Submits LinkedIn credentials to Unipile. LinkedIn commonly challenges a new login — a `checkpointRequired: true` response means you must call POST /v1/accounts/{id}/solve-checkpoint with the code LinkedIn sent before the account can send anything. Counts against the workspace's seat limit exactly like the dashboard's Connect flow.","requestBody":{"required":true,"content":{"application/json":{"schema":{"type":"object","required":["email","password","country"],"properties":{"email":{"type":"string","format":"email"},"password":{"type":"string"},"country":{"type":"string","description":"ISO 3166-1 alpha-2, e.g. \"IN\", \"US\" — used to assign a same-region proxy."},"totpSecret":{"type":"string","description":"Authenticator TOTP secret, if this account uses one — lets 2FA auto-resolve instead of requiring a manual code."},"inboxScope":{"type":"string","enum":["campaign","full"],"default":"campaign"}}}}}},"responses":{"201":{"description":"Success","content":{"application/json":{"schema":{"allOf":[{"$ref":"#/components/schemas/ApiOk"},{"type":"object","properties":{"data":{"type":"object","properties":{"account":{"$ref":"#/components/schemas/Account"},"checkpointRequired":{"type":"boolean"},"checkpointType":{"type":["string","null"]},"message":{"type":"string"}}}}}]}}}},"202":{"description":"Success","content":{"application/json":{"schema":{"allOf":[{"$ref":"#/components/schemas/ApiOk"},{"type":"object","properties":{"data":{"type":"object","properties":{"pending":{"type":"boolean","const":true},"message":{"type":"string"}}}}}]}}}},"400":{"description":"VALIDATION | COUNTRY_REQUIRED | SEAT_LIMIT","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ApiErr"}}}},"429":{"description":"CONNECT_RATE_LIMITED","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ApiErr"}}}},"503":{"description":"UNIPILE_UNAVAILABLE","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ApiErr"}}}}}}},"/v1/accounts/{id}":{"get":{"tags":["Accounts"],"summary":"Get a LinkedIn account","parameters":[{"$ref":"#/components/parameters/IdPath"}],"responses":{"200":{"description":"Success","content":{"application/json":{"schema":{"allOf":[{"$ref":"#/components/schemas/ApiOk"},{"type":"object","properties":{"data":{"$ref":"#/components/schemas/Account"}}}]}}}},"404":{"description":"NOT_FOUND","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ApiErr"}}}}}}},"/v1/accounts/{id}/solve-checkpoint":{"post":{"tags":["Accounts"],"summary":"Submit a 2FA/OTP code for a pending checkpoint","parameters":[{"$ref":"#/components/parameters/IdPath"}],"requestBody":{"required":true,"content":{"application/json":{"schema":{"type":"object","properties":{"code":{"type":"string","description":"Leave empty for an app-approval checkpoint (LinkedIn's in-app \"Yes, it's me\" prompt) once the owner has tapped it."}}}}}},"responses":{"200":{"description":"Success","content":{"application/json":{"schema":{"allOf":[{"$ref":"#/components/schemas/ApiOk"},{"type":"object","properties":{"data":{"$ref":"#/components/schemas/Account"}}}]}}}},"400":{"description":"VALIDATION | NOT_CONNECTED","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ApiErr"}}}},"404":{"description":"NOT_FOUND","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ApiErr"}}}},"502":{"description":"CHECKPOINT_FAILED","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ApiErr"}}}},"503":{"description":"UNIPILE_UNAVAILABLE","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ApiErr"}}}}}}},"/v1/accounts/{id}/resend-checkpoint":{"post":{"tags":["Accounts"],"summary":"Resend the checkpoint verification code","parameters":[{"$ref":"#/components/parameters/IdPath"}],"responses":{"200":{"description":"Success","content":{"application/json":{"schema":{"allOf":[{"$ref":"#/components/schemas/ApiOk"},{"type":"object","properties":{"data":{"type":"object","properties":{"message":{"type":"string"},"cooldownSeconds":{"type":"integer"},"account":{"$ref":"#/components/schemas/Account"}}}}}]}}}},"400":{"description":"NOT_CONNECTED","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ApiErr"}}}},"404":{"description":"NOT_FOUND","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ApiErr"}}}},"409":{"description":"ALREADY_RESOLVED | CHECKPOINT_EXPIRED","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ApiErr"}}}},"429":{"description":"RESEND_COOLDOWN","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ApiErr"}}}},"503":{"description":"UNIPILE_UNAVAILABLE","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ApiErr"}}}}}}},"/v1/inbox/conversations":{"get":{"tags":["Inbox"],"summary":"List conversations","parameters":[{"$ref":"#/components/parameters/Limit"},{"$ref":"#/components/parameters/Offset"},{"name":"accountId","in":"query","schema":{"type":"integer"}},{"name":"archived","in":"query","schema":{"type":"boolean"}}],"responses":{"200":{"description":"Paginated success","content":{"application/json":{"schema":{"allOf":[{"$ref":"#/components/schemas/ApiOk"},{"type":"object","properties":{"data":{"type":"object","required":["data","total","limit","offset"],"properties":{"data":{"type":"array","items":{"$ref":"#/components/schemas/Conversation"}},"total":{"type":"integer"},"limit":{"type":"integer"},"offset":{"type":"integer"}}}}}]}}}}}}},"/v1/inbox/conversations/{id}/messages":{"get":{"tags":["Inbox"],"summary":"List messages in a conversation","parameters":[{"$ref":"#/components/parameters/IdPath"},{"$ref":"#/components/parameters/Limit"},{"$ref":"#/components/parameters/Offset"}],"responses":{"200":{"description":"Paginated success","content":{"application/json":{"schema":{"allOf":[{"$ref":"#/components/schemas/ApiOk"},{"type":"object","properties":{"data":{"type":"object","required":["data","total","limit","offset"],"properties":{"data":{"type":"array","items":{"$ref":"#/components/schemas/Message"}},"total":{"type":"integer"},"limit":{"type":"integer"},"offset":{"type":"integer"}}}}}]}}}},"404":{"description":"NOT_FOUND","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ApiErr"}}}}}},"post":{"tags":["Inbox"],"summary":"Send a message in a conversation","parameters":[{"$ref":"#/components/parameters/IdPath"}],"requestBody":{"required":true,"content":{"application/json":{"schema":{"type":"object","required":["accountId","text"],"properties":{"accountId":{"type":"integer","description":"ID of the LinkedIn account that should send the message; must be the account the conversation belongs to (400 ACCOUNT_MISMATCH otherwise)"},"text":{"type":"string"}}}}}},"responses":{"200":{"description":"Success","content":{"application/json":{"schema":{"allOf":[{"$ref":"#/components/schemas/ApiOk"},{"type":"object","properties":{"data":{"properties":{"messageId":{"type":["string","null"]}}}}}]}}}},"400":{"description":"INVALID_ACCOUNT | INVALID_TEXT | ACCOUNT_NOT_CONNECTED","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ApiErr"}}}},"403":{"description":"ACCOUNT_RECONNECT_REQUIRED","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ApiErr"}}}},"404":{"description":"NOT_FOUND | ACCOUNT_NOT_FOUND","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ApiErr"}}}},"422":{"description":"RECIPIENT_UNREACHABLE","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ApiErr"}}}},"502":{"description":"UPSTREAM_ERROR","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ApiErr"}}}}}}},"/v1/inbox/conversations/{id}/seen":{"post":{"tags":["Inbox"],"summary":"Mark a conversation as read","parameters":[{"$ref":"#/components/parameters/IdPath"}],"responses":{"200":{"description":"Success","content":{"application/json":{"schema":{"allOf":[{"$ref":"#/components/schemas/ApiOk"},{"type":"object","properties":{"data":{"$ref":"#/components/schemas/Conversation"}}}]}}}},"404":{"description":"NOT_FOUND","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ApiErr"}}}}}}},"/v1/webhooks":{"get":{"tags":["Webhooks"],"summary":"List webhook subscriptions","responses":{"200":{"description":"Success","content":{"application/json":{"schema":{"allOf":[{"$ref":"#/components/schemas/ApiOk"},{"type":"object","properties":{"data":{"type":"array","items":{"$ref":"#/components/schemas/WebhookSubscription"}}}}]}}}}}},"post":{"tags":["Webhooks"],"summary":"Create a webhook subscription","requestBody":{"required":true,"content":{"application/json":{"schema":{"type":"object","required":["url","eventTypes"],"properties":{"url":{"type":"string","format":"uri","description":"https URL receiving the deliveries. Must not point to localhost / private hosts."},"eventTypes":{"type":"array","items":{"type":"string","enum":["lead.replied","connection.accepted"]}},"secret":{"type":["string","null"],"description":"HMAC secret used to sign deliveries (Stripe-style x-outpilot-signature). Returned ONCE on create — store it."},"description":{"type":["string","null"]}}}}}},"responses":{"200":{"description":"Success","content":{"application/json":{"schema":{"allOf":[{"$ref":"#/components/schemas/ApiOk"},{"type":"object","properties":{"data":{"allOf":[{"$ref":"#/components/schemas/WebhookSubscription"},{"type":"object","properties":{"secret":{"type":["string","null"]}}}]}}}]}}}},"400":{"description":"INVALID_URL | INVALID_EVENT_TYPES","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ApiErr"}}}}}}},"/v1/webhooks/{id}":{"get":{"tags":["Webhooks"],"summary":"Get a webhook subscription","parameters":[{"$ref":"#/components/parameters/IdPath"}],"responses":{"200":{"description":"Success","content":{"application/json":{"schema":{"allOf":[{"$ref":"#/components/schemas/ApiOk"},{"type":"object","properties":{"data":{"$ref":"#/components/schemas/WebhookSubscription"}}}]}}}},"404":{"description":"NOT_FOUND","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ApiErr"}}}}}},"patch":{"tags":["Webhooks"],"summary":"Update a webhook subscription","parameters":[{"$ref":"#/components/parameters/IdPath"}],"requestBody":{"required":true,"content":{"application/json":{"schema":{"type":"object","properties":{"url":{"type":"string"},"eventTypes":{"type":"array","items":{"type":"string"}},"isActive":{"type":"boolean"},"secret":{"type":["string","null"]},"description":{"type":["string","null"]}}}}}},"responses":{"200":{"description":"Success","content":{"application/json":{"schema":{"allOf":[{"$ref":"#/components/schemas/ApiOk"},{"type":"object","properties":{"data":{"$ref":"#/components/schemas/WebhookSubscription"}}}]}}}},"400":{"description":"INVALID_URL | INVALID_EVENT_TYPES","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ApiErr"}}}},"404":{"description":"NOT_FOUND","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ApiErr"}}}}}},"delete":{"tags":["Webhooks"],"summary":"Delete a webhook subscription","parameters":[{"$ref":"#/components/parameters/IdPath"}],"responses":{"200":{"description":"Success","content":{"application/json":{"schema":{"allOf":[{"$ref":"#/components/schemas/ApiOk"},{"type":"object","properties":{"data":{"properties":{"deleted":{"type":"boolean"}}}}}]}}}},"404":{"description":"NOT_FOUND","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ApiErr"}}}}}}},"/v1/webhooks/{id}/test":{"post":{"tags":["Webhooks"],"summary":"Fire a synthetic delivery for testing","parameters":[{"$ref":"#/components/parameters/IdPath"}],"requestBody":{"required":true,"content":{"application/json":{"schema":{"type":"object","properties":{"eventType":{"type":"string","enum":["lead.replied","connection.accepted"],"default":"lead.replied"}}}}}},"responses":{"200":{"description":"Success","content":{"application/json":{"schema":{"allOf":[{"$ref":"#/components/schemas/ApiOk"},{"type":"object","properties":{"data":{"properties":{"deliveryId":{"type":"integer"},"queued":{"type":"boolean"}}}}}]}}}},"404":{"description":"NOT_FOUND","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ApiErr"}}}}}}},"/v1/webhooks/{id}/deliveries":{"get":{"tags":["Webhooks"],"summary":"Recent delivery attempts for a subscription","parameters":[{"$ref":"#/components/parameters/IdPath"},{"name":"limit","in":"query","schema":{"type":"integer","default":20,"maximum":100}}],"responses":{"200":{"description":"Success","content":{"application/json":{"schema":{"allOf":[{"$ref":"#/components/schemas/ApiOk"},{"type":"object","properties":{"data":{"type":"array","items":{"$ref":"#/components/schemas/WebhookDelivery"}}}}]}}}},"404":{"description":"NOT_FOUND","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ApiErr"}}}}}}}}}