Pro plan. API keys are part of Pro and Agency (and the free trial). On Starter, Create key shows Part of Pro with an Upgrade to Pro button, and the API answers
403 PRO_FEATURE when a key creates something that is Pro. Anything you already have keeps working on every plan. See Plans and billing.Create an API key
1
Open Developers
Click Integrations > Developers (owners and admins only).
2
Create a key
Give it a name and pick its Scopes. A new key starts with only the read scopes ticked: tick the write scopes or admin yourself, only if it needs them. Click Create key and copy the key: it’s shown once.
3
Call the API
Good to know
- A key acts as the person who created it, never beyond their role, and only within its permissions. It stops working if that person leaves the workspace.
- Rate limit: 600 requests per minute per key (see the
RateLimit-*headers). - Safe retries: send an
Idempotency-Keyheader on writes; the same key within 24 hours returns the first answer instead of doing it twice. - Errors look like
{ "error": { "code": "...", "message": "..." } }. - Lists use cursor pagination.
- LinkedIn limits apply to everything the API does, exactly as in the app.
Some endpoints
- Pipeline:
GET /v1/pipelinereturns the board (every stage with its contacts, count and value),PUT /v1/leads/{id}/stagemoves a contact to a stage or off the board (null) and setsdeal_value_cents, andPUT /v1/pipeline/stagesrenames, adds, removes or reorders the stages (2 to 20, admin scope). Contacts havestageanddeal_value_cents. See Pipeline. - Smart segments:
GETandPOST /v1/segments,GET,PATCHandDELETE /v1/segments/{id},GET /v1/segments/{id}/leads(the contacts in it now) andPOST /v1/segments/count(how many contacts some filters match) (leads:read / leads:write). See Smart segments. - Broadcasts:
GETandPOST /v1/broadcasts,GETandPUT /v1/broadcasts/{id}(a draft; once sent,422BROADCAST_ALREADY_SENT),GET /v1/broadcasts/{id}/check(the preflight and the forecast) andPOST /v1/broadcasts/{id}/send(once) (workflows:read / workflows:write; sending starts the audience, so it needs enrollments:write too). See Broadcasts. - Lead routing and engagement:
GETandPUT /v1/workspace/lead-assignment(modeoff,round_robinorleast_open, anduser_ids) andGETandPUT /v1/workspace/engagement(points,hot_threshold,decay_days,hot_alert,enabled) (reads need leads:read, changes admin).GET /v1/leads/{id}/engagementreturns a contact’s score,hot_atand latest signals;GET /v1/leadstakessort=engagement,hotandmin_engagement, and every contact hasengagement_scoreandengagement_hot_at. See Who gets new contacts, and hot contacts. - Booking pages:
GETandPOST /v1/booking-links,GET,PATCHandDELETE /v1/booking-links/{id}(title,duration_minutes,assignmentsingleorround_robin,hostswithuser_idandmailbox_id,timezone,hours, buffers,min_notice_minutes,max_days_ahead,daily_cap,questions,conference,is_default),GET /v1/booking-links/{id}/availability?from=&to=(free times, at most 31 days),GET /v1/bookings(from,to,status,link_id,lead_id),POST /v1/bookings/{id}/cancelandPOST /v1/bookings/{id}/review(checkorreleasea booking that needs a check). Reads need leads:read, changes leads:write. See Your booking page. - Hosted forms, surveys and quizzes:
GET,PUTandDELETE /v1/triggers/{id}/formread, change or remove the form on a trigger URL (workflows:write scope). Fields can have atype(single_choice,multiple_choice,dropdown,rating,yes_no; absent means free text) withoptions(each alabeland optional quizpoints) or a ratingscale(5 or 10),layoutone_per_pageshows one question per page, andquiz(field, e.g.custom.quiz_score, andshow) saves the total score. The answer gives the form and its publicform_url. See Surveys and quizzes. - Business cards:
POST /v1/business-cards/scanreads a photo of one or more business cards (image.media_typeandimage.datain base64, JPG, PNG, WebP or GIF, up to 2.5 MB) intodraftsand saves nothing. Each draft has itsfields, the key fields the card didn’t show (missing) and anyduplicatealready in your contacts (bylinkedinoremailfor sure,phoneornameprobably).statusisreadorpartial, or says why the drafts are empty (unreadable,ai_off,ai_failed,ai_declined,quota,rate_limited).POST /v1/business-cardssaves one reviewed card (fields, optionalmerge_into,list_idornew_list_name,campaign_id,tags) and returns thelead_idand whether it wascreatedorupdated. Both need leads:write; a scan uses AI credits. See Scan business cards. - Business profile:
GET /v1/workspace/business-profilereads the text, the selling style and what your website says (workflows:read scope), andPUT /v1/workspace/business-profilechanges thetext(3,000 characters at most) and / or thestyle(gentle,balancedordirect), or forgets the website withclear_website(admin scope, owners and admins). See Business profile. - Campaign review:
GET /v1/workflows/{id}/reviewreturns what the builder’s Review shows (workflows:read scope): the checks (rules, each finding with itscode, itslevelproblemorimproveand the step’snode_id, plus theproblemsandimprovementscounts, andempty:truewhile the campaign has no steps yet, so nothing is judged) and the last AI opinion (ai:goal,ratingstrong,needs_workorweak,verdictand its findings with any rewritten text, ornull).staleistruewhen the campaign changed after that opinion. Asking the AI for a new opinion is in the app only. See Review your campaign. - Campaign step changes:
POST /v1/workflows/{id}/draft/changesapplies the same changes Ask AI proposes to the campaign’s draft (workflows:write scope):changesis a list of up to 6, each withop(add,editorremove),where(after,beforeorend) andstep(the step’s key or number), and foraddthe step’stype(message,email,inmail,waitwithdays,connect,tag,note,task,conditionwithcheck,integrationwithpreseticypeas.find_email_and_wait…) with itstextandsubject. It returns theadded,changedandremovedstep ids, what wasrefusedand why (http,link,secret,channel,step…) and whether the campaign islive. It never publishes: live contacts keep the published version until you publish. Webhook and HTTP steps, links,secrets.*, WhatsApp and SMS are refused here; usePUT /v1/workflows/{id}/draftfor the full definition. See Ask AI. - Why it’s stuck, in plain words:
GET /v1/leads/{id}/explainsays why a contact waits or is stuck in each campaign:reason_codeandreasonin plain words, since when, thestep(its number on the canvas), what ismissing, and thefixes, each with the API call that does it.GET /v1/workflows/{id}/explainsays why a campaign is stuck or slow:counts, where contacts wait by step and reason, each LinkedIn account’s usage against today’s limits, andnext_steps(workflows:read scope).GET /v1/workflows/{id}also returnssteps(andlive_steps) in plain words. Without leads:read the contact’s own fields come backnull; without senders:read the accounts’ usage is left out. - Build and launch a campaign:
POST /v1/workflows/from-descriptionbuilds a campaign draft from adescriptionlike Create with AI (workflows:write scope; one AI use; needs the business profile,422 BUSINESS_PROFILE_NEEDED); it returns thestepsand thenotes(what is left to do) and never launches.POST /v1/workflows/{id}/draft/changes/previewshows whatPOST /v1/workflows/{id}/draft/changeswould do, saving nothing.POST /v1/workflows/{id}/launchlaunches after the preflight, checking the contacts given and everyone waiting in the Contacts box (422 PREFLIGHT_BLOCKEDwithdetails.checks; it starts contacts, so it needs enrollments:write too).POST /v1/workflows/from-descriptionreturnsdestinations, and the preflight’sSENDS_DATA_OUTcheck lists the hosts a campaign sends contact data to (its webhook and HTTP steps and Always-on boxes).POST /v1/workflows/{id}/enrollmentswithwait_for_launch: truekeeps contacts added to a campaign not launched yet in its Contacts box until the launch. - Email templates:
GETandPOST /v1/email-templates,GET,PATCHandDELETE /v1/email-templates/{id},POST /v1/email-templates/{id}/duplicate,GET /v1/email-templates/{id}/versionsandPOST /v1/email-templates/{id}/versions/{version}/restore(reads need workflows:read, changes workflows:write).kindisblocks,htmlortext. Sendbase_version(the version you read) with a change: if someone saved meanwhile, the answer is422EDITED_ELSEWHERE.POST /v1/email-imagesuploads a picture asdata_base64(PNG, JPG, GIF or WebP, up to 1 MB; 25 MB per workspace) and returns its publicurl,GET /v1/email-imageslists the workspace’s pictures withused_bytesandmax_bytes, andDELETE /v1/email-images/{id}deletes one (emails already sent with it show it broken). See Email templates. - An automatic answer waiting to go out:
POST /v1/messages/{id}/send-nowsends it now (still checked again and within the account’s limits, at most once) andPOST /v1/messages/{id}/cancelstops it (it stays as the suggested reply). See Use the inbox. - Text messages (SMS) (coming soon: connecting Twilio answers
403 SMS_COMING_SOONuntil texting opens):/v1/sms,/v1/sms/twilio,/v1/sms-numbers/{id}and/v1/sms-opt-outsconnect and read your Twilio account, its numbers and the phones that texted STOP (senders:read and senders:write scopes; connecting, replacing or disconnecting the keys, and sending replies to Kerux need admin; the STOP list needs leads:read). See Twilio (text messages). - Sending rules and consent:
GET /v1/workspace/sending-identity(workflows:read) andPUT /v1/workspace/sending-identity(admin) read and setcompany_name,postal_address(required before campaign emails go out) andfooter_language.GET /v1/workspace/consent-default(workflows:read) reads the workspace’s Contacts’ consent switch, andPUT /v1/workspace/consent-default(admin) with emptychannelsturns it off; turning it on is refused to API keys (INSUFFICIENT_ROLE): an owner or admin does it in Settings > Sending rules.GET,POST /v1/leads/{id}/consentandDELETE /v1/leads/{id}/consent/{channel}read, record (channelswithsmsand / orwhatsapp,attest: true, optionalconsent_text) and withdraw a contact’s consent (leads:read / leads:write; errorsCONSENT_NOT_CONFIRMED,CONSENT_NEEDS_PHONE,CONSENT_DO_NOT_CONTACT).POST /v1/leads/{id}/do-not-contact(leads:write) stops every channel for a contact, andPOST /v1/leads/{id}/erase(admin) is a deletion request.GET,POST /v1/suppressionsandDELETE /v1/suppressions/{id}read, add to and remove from the do-not-contact list (leads:read / leads:write; only entries a teammate added in the app can be removed, elseSUPPRESSION_NOT_REMOVABLE). See Sending rules and consent.