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¢
- Sites
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'] })
{
"$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"
}
Connect once
- Call
Integration.connectwithsystem:and'ads' venue:, then open the'linkedin' connectUrlit returns and sign in as yourself with LinkedIn. - Pick the ad account and the company page the ads run as; your role on the ad account must allow creating campaigns.
- 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.
| Grant | What it unlocks | Scope |
|---|---|---|
| Build and change ads | Campaign groups, campaigns, creatives, budgets and status | rw_ads |
| Read results | Spend, impressions, clicks and leads by campaign, creative and day | r_ads_reporting |
| Matched audiences | Uploading a company or contact list as a matched audience | rw_dmp_segments |
| Lead form responses | Each lead form response the moment it is submitted | r_marketing_leadgen_automation |
| Post as the page | The post a creative references, published as your company page | w_organization_social |
| To | Do this |
|---|---|
| Pause | Integration.pause stops every call through LinkedIn at once and keeps the token; Integration.resume picks up from the same cursor. |
| Reconnect | Integration.reconnect returns a fresh connectUrl that lasts one hour, and keeps the Integration's id and cursor, so nothing imports twice. |
| Disconnect | Integration.revoke revokes the token with LinkedIn; every record it brought in stays in your records. |
What your agents do
| Ask | Verb | Runs through | Price |
|---|---|---|---|
| Upload my approved company list as a matched audience. | Audience.create | Your account | Free |
| Build a $100 test with 3 ads to owners and property managers at those companies. | Campaign.create | Your account | Free |
| Add a document ad with the rent-ledger template. | Ad.create | Your account | Free |
| Pause the two weaker ads and keep the best one running. | Campaign.update | Your account | Free |
| Show me spend, impressions, clicks and form fills by ad. | Metric.query | Your account | Free |
| Qualify each lead form response the morning it arrives. | Lead.qualify | Your account | Free |
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
| Noun | The account’s object | When | Which side leads |
|---|---|---|---|
| Campaign | adCampaignGroup and adCampaign | Your agent builds it | Your records |
| Ad | creative | Your agent builds it; LinkedIn’s review sets its status | Your records |
| Audience | dmpSegment | Your agent uploads your list | Your records |
| Lead | leadFormResponse | Someone submits the form | The account |
| Entry | adAnalytics: | Each day’s spend settles | The account |
Events and webhooks
| Direction | Event |
|---|---|
| Emits | Campaign.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
| What | Limit | Call |
|---|---|---|
| Budget minimums | $10 a day for any ad format, and a new campaign’s lifetime budget is at least $100 | Campaign.create |
| Matched audiences | Run from 300 matched members; under that the campaign refuses with venue-rejected | Audience.create |
| Ad review | LinkedIn reviews every ad; a rejection comes back as venue-rejected with the reason | Ad.create |
| Results | Read through the reporting API each morning; a day’s numbers settle overnight, so a stop rule fires on yesterday’s | Metric.query |
| Spend | Your standing approval holds the daily and total cap; a change past it waits with over-mandate | Campaign.update |
Start here
| Move | The rule |
|---|---|
| Structure | One 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. |
| Creative | 3 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 rule | At $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). |
| Benchmark | Source |
|---|---|
| $10 a day minimum; a new campaign needs at least $100 lifetime | LinkedIn 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 pages | Agency 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 winner | Our calculation |
| Matched audiences run from 300 members; 50,000 or more is recommended | LinkedIn help |
Field map
| Our field | LinkedIn Ads’s field | Notes | Calls |
|---|---|---|---|
Campaign.objective | adCampaign.objectiveType | leads is LEAD_GENERATION with LinkedIn’s lead form, traffic WEBSITE_VISIT, conversions WEBSITE_CONVERSION | Campaign.create, Campaign.update, Ad.create |
Campaign.budget | adCampaign.dailyBudget or adCampaign.totalBudget | { amount,, the amount as a decimal string; a lifetime budget runs on lifetime pacing, which LinkedIn recommends | Campaign.create, Campaign.update, Ad.create |
Campaign.startsAt | adCampaign.runSchedule.start | Epoch milliseconds | Campaign.create |
Campaign.endsAt | adCampaign.runSchedule.end | None. | Campaign.create, Campaign.update |
Campaign.state | adCampaign.status | draft is DRAFT, live ACTIVE, paused PAUSED | Campaign.update |
Campaign.targeting | adCampaign.targetingCriteria | Job titles, industries, staff count ranges and locations, each a LinkedIn targeting facet | Campaign.create, Campaign.update |
Campaign.audiences | targetingCriteria: | None. | Campaign.create |
Campaign.bid | adCampaign.costType and adCampaign.unitCost | lowest-cost lets LinkedIn bid to spend the budget; a costPer cap sets unitCost | Campaign.create |
Ad.body | post commentary | The creative references a post; 3,000 characters, 150 show before it truncates | Ad.create |
Ad.headline | post content.article.title | 200 characters; 70 show before it truncates | Ad.create |
Ad.landingUrl | post content.article.source, | None. | Ad.create |
Audience.query | dmpSegment list upload | A company list by name and domain, or contacts with each email hashed before it leaves your records | Audience.create |
Lead.interest | leadFormResponse answers | None. | 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
| Site | Format | Limits |
|---|---|---|
| Feed post | 3,000 characters, with one image, a document, a video or several images | |
| Single image ad Size 1200 × 628, 1200 × 1200 or 720 × 900 | Intro text 3,000 characters, 150 before it truncates; headline 200, 70 before it truncates; JPG, PNG or GIF up to 5 megabytes | |
| Document ad | PDF, DOC, DOCX, PPT or PPTX up to 100 megabytes and 300 pages; LinkedIn advises under 10 pages |
Plays and strategies
| Kind | Where |
|---|---|
| Plays | Paid social, Buying committee, Account ads |
| Strategies | Paid |
Used by
- Workflows: Ad test setup · Post-engager harvest
- Agent tasks: Launch day · Message test
Reference
6 calls, each with its path and price
| Call | Path | Price |
|---|---|---|
Audience.create | POST / | Free |
Campaign.create | POST / | Free |
Ad.create | POST / | Free |
Campaign.update | POST / | Free |
Metric.query | POST / | Free |
Lead.qualify | POST / | Free |