Skip to content

LinkedIn Ads

Your agents build LinkedIn campaigns on your ad account for the job titles and companies you approved, and qualify each lead form as it arrives.

Connect
Sign in once, 5 grants
Runs through
Your account
First run
Read the ads a rival runs on LinkedIn, about 0.16¢
Campaign.create
You, to your agent

Build a $100 LinkedIn test with my 3 ads, aimed at owners and property managers at the companies on my approved list.

curl -X POST "https://api.sb/leaseline.app/campaigns/create?mode=try" \
  -H "Authorization: Bearer $SB_TOKEN" \
  -H "Content-Type: application/json" \
  -d '{"venue":"linkedin","objective":"leads","audience":"audiences/approved-property-managers","titles":["Owner","Property Manager"],"budget":{"amount":100,"currency":"USD","per":"lifetime"},"ads":["ads/linkedin-ledger","ads/linkedin-renewals","ads/linkedin-owner-statements"]}'
npx startup-builder do Campaign.create --try --data '{"venue":"linkedin","objective":"leads","audience":"audiences/approved-property-managers","titles":["Owner","Property Manager"],"budget":{"amount":100,"currency":"USD","per":"lifetime"},"ads":["ads/linkedin-ledger","ads/linkedin-renewals","ads/linkedin-owner-statements"]}'
{
  "name": "do",
  "arguments": {
    "mode": "try",
    "code": "return await $.Campaign.create({ venue: 'linkedin', objective: 'leads', audience: 'audiences/approved-property-managers', titles: ['Owner', 'Property Manager'], budget: { amount: 100, currency: 'USD', per: 'lifetime' }, ads: ['ads/linkedin-ledger', 'ads/linkedin-renewals', 'ads/linkedin-owner-statements'] })"
  }
}
import { $ } from 'startup-builder'

const result = await $.try.Campaign.create({ venue: 'linkedin', objective: 'leads', audience: 'audiences/approved-property-managers', titles: ['Owner', 'Property Manager'], budget: { amount: 100, currency: 'USD', per: 'lifetime' }, ads: ['ads/linkedin-ledger', 'ads/linkedin-renewals', 'ads/linkedin-owner-statements'] })
Response
{
  "$type": "Campaign",
  "mode": "try",
  "stored": false,
  "venue": "linkedin",
  "objective": "lead generation",
  "audience": {
    "matchedMembers": 2140,
    "minimum": 300
  },
  "budget": {
    "amount": 100,
    "currency": "USD",
    "per": "lifetime",
    "pacedAt": "about $14 a day for 7 days"
  },
  "checks": {
    "dailyMinimum": "passes $10",
    "lifetimeMinimum": "meets $100"
  },
  "ads": 3,
  "expect": {
    "clicks": "7 to 9",
    "readsAt": "$100"
  },
  "runsBy": "account"
}
Try mode reads, stores nothing and spends nothingAPI referenceIts Nouns

Connect once

  1. Call Integration.connect with system: 'ads' and venue: 'linkedin', then open the connectUrl it returns and sign in as yourself with LinkedIn.
  2. Pick the ad account and the company page the ads run as; your role on the ad account must allow creating campaigns.
  3. Set the spend on your standing approval with Mandate.authorize: the most your agents may spend a day and in all; LinkedIn bills your ad account, never the platform.
GrantWhat it unlocksScope
Build and change adsCampaign groups, campaigns, creatives, budgets and statusrw_ads
Read resultsSpend, impressions, clicks and leads by campaign, creative and dayr_ads_reporting
Matched audiencesUploading a company or contact list as a matched audiencerw_dmp_segments
Lead form responsesEach lead form response the moment it is submittedr_marketing_leadgen_automation
Post as the pageThe post a creative references, published as your company pagew_organization_social
ToDo this
PauseIntegration.pause stops every call through LinkedIn at once and keeps the token; Integration.resume picks up from the same cursor.
ReconnectIntegration.reconnect returns a fresh connectUrl that lasts one hour, and keeps the Integration's id and cursor, so nothing imports twice.
DisconnectIntegration.revoke revokes the token with LinkedIn; every record it brought in stays in your records.

What your agents do

AskVerbRuns throughPrice
Upload my approved company list as a matched audience.Audience.createYour accountFree
Build a $100 test with 3 ads to owners and property managers at those companies.Campaign.createYour accountFree
Add a document ad with the rent-ledger template.Ad.createYour accountFree
Pause the two weaker ads and keep the best one running.Campaign.updateYour accountFree
Show me spend, impressions, clicks and form fills by ad.Metric.queryYour accountFree
Qualify each lead form response the morning it arrives.Lead.qualifyYour accountFree

Calls on your own account are free; LinkedIn bills your spend directly.

Reading this site’s public data needs no account: Ad.find is a Data call (the three ways a call runs).

What it holds

NounThe account’s objectWhenWhich side leads
CampaignadCampaignGroup and adCampaignYour agent builds itYour records
AdcreativeYour agent builds it; LinkedIn’s review sets its statusYour records
AudiencedmpSegmentYour agent uploads your listYour records
LeadleadFormResponseSomeone submits the formThe account
EntryadAnalytics: costInLocalCurrencyEach day’s spend settlesThe account

Events and webhooks

DirectionEvent
EmitsCampaign.created, Campaign.updated, Ad.created, Audience.created, Lead.created, Lead.qualified, Entry.posted

Any Event can wake a Workflow, and a Watch delivers it to your endpoint, signed (Events and webhooks).

Limits

WhatLimitCall
Budget minimums$10 a day for any ad format, and a new campaign’s lifetime budget is at least $100Campaign.create
Matched audiencesRun from 300 matched members; under that the campaign refuses with venue-rejectedAudience.create
Ad reviewLinkedIn reviews every ad; a rejection comes back as venue-rejected with the reasonAd.create
ResultsRead through the reporting API each morning; a day’s numbers settle overnight, so a stop rule fires on yesterday’sMetric.query
SpendYour standing approval holds the daily and total cap; a change past it waits with over-mandateCampaign.update

Start here

MoveThe rule
StructureOne campaign group, one campaign on the lead generation objective with LinkedIn’s own lead form, aimed at the companies on your approved list (at least 300 matched members), with 3 single-image ads in rotation.
Budget$100 lifetime, LinkedIn’s minimum for a new campaign, paced at $10 to $15 a day over about a week. This first test prices your audience and finds the ad that gets clicked; it does not prove the channel.
Creative3 single-image ads at 1200 × 628, each with one claim from your evidence; intro text under 150 characters and a headline under 70. Make one a document ad if you have a real asset.
Kill ruleAt $100, keep the ad with the best CTR only if it is above 0.4%; under 0.4% on all three, change the audience before the words. Run the next test at $50 a day for 2 weeks only with an ad above 0.6% (our planning number).
BenchmarkSource
$10 a day minimum; a new campaign needs at least $100 lifetimeLinkedIn Marketing Solutions
$11 to $14 a click for B2B SaaS prospecting; CTR 0.4% to 0.8%Agency ad datasets, 2025
LinkedIn’s lead forms convert 6% to 13% of clicks, against 2% to 5% for landing pagesAgency ad datasets, 2025
$100 at $11 to $14 a click buys 7 to 9 clicks: enough to price the next test, too few to crown a winnerOur calculation
Matched audiences run from 300 members; 50,000 or more is recommendedLinkedIn help

Field map

Our fieldLinkedIn Ads’s fieldNotesCalls
Campaign.objectiveadCampaign.objectiveTypeleads is LEAD_GENERATION with LinkedIn’s lead form, traffic WEBSITE_VISIT, conversions WEBSITE_CONVERSIONCampaign.create, Campaign.update, Ad.create
Campaign.budgetadCampaign.dailyBudget or adCampaign.totalBudget{ amount, currencyCode }, the amount as a decimal string; a lifetime budget runs on lifetime pacing, which LinkedIn recommendsCampaign.create, Campaign.update, Ad.create
Campaign.startsAtadCampaign.runSchedule.startEpoch millisecondsCampaign.create
Campaign.endsAtadCampaign.runSchedule.endNone.Campaign.create, Campaign.update
Campaign.stateadCampaign.statusdraft is DRAFT, live ACTIVE, paused PAUSEDCampaign.update
Campaign.targetingadCampaign.targetingCriteriaJob titles, industries, staff count ranges and locations, each a LinkedIn targeting facetCampaign.create, Campaign.update
Campaign.audiencestargetingCriteria: audienceMatchingSegmentsNone.Campaign.create
Campaign.bidadCampaign.costType and adCampaign.unitCostlowest-cost lets LinkedIn bid to spend the budget; a costPer cap sets unitCostCampaign.create
Ad.bodypost commentaryThe creative references a post; 3,000 characters, 150 show before it truncatesAd.create
Ad.headlinepost content.article.title200 characters; 70 show before it truncatesAd.create
Ad.landingUrlpost content.article.source, or the lead formNone.Ad.create
Audience.querydmpSegment list uploadA company list by name and domain, or contacts with each email hashed before it leaves your recordsAudience.create
Lead.interestleadFormResponse answersNone.Lead.qualify

What try does here

Reads your ad account, the matched count of each audience and the targeting facets, and checks the campaign against LinkedIn’s budget minimums; LinkedIn has no validate-only call, so nothing is sent to it and nothing is created.

How long a connection lasts

A connection lasts 60 days per access token, renewed from a refresh token that LinkedIn ends 365 days after your first sign-in, however often it is used.

The platform asks you to reconnect 7 days before it runs out; until you do, a call that needs it refuses with needs-reauth.

Formats

SiteFormatLimits
LinkedInFeed post3,000 characters, with one image, a document, a video or several images
LinkedInSingle image ad Size 1200 × 628, 1200 × 1200 or 720 × 900Intro text 3,000 characters, 150 before it truncates; headline 200, 70 before it truncates; JPG, PNG or GIF up to 5 megabytes
LinkedInDocument adPDF, DOC, DOCX, PPT or PPTX up to 100 megabytes and 300 pages; LinkedIn advises under 10 pages

Plays and strategies

KindWhere
PlaysPaid social, Buying committee, Account ads
StrategiesPaid

Used by

Reference

6 calls, each with its path and price
CallPathPrice
Audience.createPOST /audiences/createFree
Campaign.createPOST /campaigns/createFree
Ad.createPOST /ads/createFree
Campaign.updatePOST /campaigns/updateFree
Metric.queryPOST /metrics/queryFree
Lead.qualifyPOST /leads/qualifyFree

Contents