API reference
API: Marketing
| Method | Path | What it does | Scope |
|---|---|---|---|
| GET | /v1/marketing/accounts | Your social accounts: LinkedIn (through Unipile), and X, Reddit and Instagram where this server has their apps set up | connections:read |
| DELETE | /v1/marketing/accounts/:id | Disconnect one of your social accounts | connections:write |
| POST | /v1/marketing/accounts/:platform/connect | Connect your X, Reddit or Instagram (Business or Creator, through Facebook Login) account: returns the sign-in page | connections:write |
| POST | /v1/marketing/ads/reports | Run a read-only report (the same as the agent tools): Google Ads GAQL, GA4, Search Console, LinkedIn Ads or Reddit Ads | connections:write |
| GET | /v1/marketing/ads/status | Which marketing accounts are connected (Google Ads, Analytics and Search Console; LinkedIn Ads; Reddit Ads; WordPress) and what's missing | connections:read |
| GET | /v1/marketing/brand-kit | The brand kit: voice, audience, do's and don'ts, hashtags, banned words, the subreddits Reddit posts may go to, discover mode | knowledge:read |
| PUT | /v1/marketing/brand-kit | Change the brand kit (owners); turning discover mode on makes you its reviewer | settings:write |
| GET | /v1/marketing/commenters | Commenters on your organization's own LinkedIn posts who sound like buyers (scored; never messaged automatically) | signals:read |
| POST | /v1/marketing/commenters/:id/decision | Add a flagged commenter to the CRM as a lead (an existing contact is linked instead), or dismiss them | signals:write |
| GET | /v1/marketing/moments | Moments (clips) from meetings our recorder recorded, and whether their account may be referenced | transcripts:read |
| POST | /v1/marketing/moments/:id/post | Draft a post from a moment: paraphrased with names, numbers and contact details removed, or the quote word for word once the person quoted agrees (a request email, as your draft) | transcripts:write |
| GET | /v1/marketing/partners | Creator and partner candidates, best fit first | prospecting:read |
| POST | /v1/marketing/partners/:id/decision | Shortlist a candidate, mark it contacted, or dismiss it | prospecting:write |
| POST | /v1/marketing/partners/search | Find creators (podcasts, newsletters, channels, blogs) or partners (agencies, consultants, products) on a topic, scored for fit; nothing is sent | prospecting:write |
| GET | /v1/marketing/plan | The plan's open items, by week | signals:read |
| POST | /v1/marketing/plan/:id/decision | Accept, dismiss or mark a plan item done | signals:write |
| POST | /v1/marketing/plans | Plan the next 4 to 12 weeks (launches, promotions, partnerships, local events, content) from competitor changes and news, each item citing its evidence | signals:write |
| GET | /v1/marketing/posts | Posts: drafts (yours to approve), scheduled, published, failed | sequences:read |
| POST | /v1/marketing/posts | Draft a post (checked against the brand kit); nothing is published until you approve it | sequences:write |
| PATCH | /v1/marketing/posts/:id | Edit your draft | sequences:write |
| POST | /v1/marketing/posts/:id/decision | Approve your post (published now, or at scheduled_at, from your account, through policy), reject it, or cancel a scheduled one (back to draft) | messages:send |
| GET | /v1/marketing/seo/briefs | SEO, local and AI-answer briefs: research, drafts, approvals | sequences:read |
| POST | /v1/marketing/seo/briefs | Research a topic: what ranks, what people ask, the local pack (with a location), and your Search Console queries that are seen but not clicked | sequences:write |
| GET | /v1/marketing/seo/briefs/:id | A brief with its research and draft | sequences:read |
| PATCH | /v1/marketing/seo/briefs/:id | Edit the draft (the brand checks run again) | sequences:write |
| POST | /v1/marketing/seo/briefs/:id/decision | Approve the draft (optionally creating a WordPress draft, or publishing it) or reject it | messages:send |
| POST | /v1/marketing/seo/briefs/:id/draft | Draft the brief: an answer-first article, FAQ or local page in the brand voice, with a title, meta description, FAQ and JSON-LD | sequences:write |
| POST | /v1/marketing/site/audits | Audit your own website (home page and up to seven pages it links to): titles, descriptions, headings, structured data, alt text, FAQ | sequences:write |
| GET | /v1/marketing/site/changes | Proposed website changes (from audits), applied through WordPress or by hand | sequences:read |
| POST | /v1/marketing/site/changes/:id/decision | Apply a change on your WordPress site (a title, or a description as the page's excerpt), mark it done by hand, or reject it | messages:send |
| GET | /v1/promotions | Promotions | deals:read |
| POST | /v1/promotions | Create a promotion: a name, a code, an offer, its dates and landing page (a UTM campaign is made from the code) | deals:write |
| GET | /v1/promotions/:id | A promotion with its tracking links | deals:read |
| GET | /v1/promotions/:id/results | A promotion's sales: attributed pipeline and wins (its UTM campaign), touches, orders and quotes with its code; per currency | deals:read |
| POST | /v1/promotions/:id/status | Launch a promotion (optionally drafting announcement posts for you to approve) or end it | deals:write |
| PUT | /v1/quotes/:id/promo-code | Put a promotion's code on a quote (null clears it) | deals:write |
Examples
GET /v1/marketing/accounts
Your social accounts: LinkedIn (through Unipile), and X, Reddit and Instagram where this server has their apps set up
curl -s "https://api.closefinch.com/v1/marketing/accounts" \
-H "Authorization: Bearer $RA_API_KEY"const res = await fetch(`https://api.closefinch.com/v1/marketing/accounts`, {
method: "GET",
headers: { authorization: `Bearer ${process.env.RA_API_KEY}` },
});
const data = await res.json();DELETE /v1/marketing/accounts/$ID
Disconnect one of your social accounts
curl -s -X DELETE "https://api.closefinch.com/v1/marketing/accounts/$ID" \
-H "Authorization: Bearer $RA_API_KEY"const res = await fetch(`https://api.closefinch.com/v1/marketing/accounts/${id}`, {
method: "DELETE",
headers: { authorization: `Bearer ${process.env.RA_API_KEY}` },
});
const data = await res.json();POST /v1/marketing/accounts/$PLATFORM/connect
Connect your X, Reddit or Instagram (Business or Creator, through Facebook Login) account: returns the sign-in page
curl -s -X POST "https://api.closefinch.com/v1/marketing/accounts/$PLATFORM/connect" \
-H "Authorization: Bearer $RA_API_KEY" \
-H "content-type: application/json" \
-d '{}'const res = await fetch(`https://api.closefinch.com/v1/marketing/accounts/${platform}/connect`, {
method: "POST",
headers: { authorization: `Bearer ${process.env.RA_API_KEY}`, "content-type": "application/json" },
body: JSON.stringify({}), // fields: see the OpenAPI schema
});
const data = await res.json();POST /v1/marketing/ads/reports
Run a read-only report (the same as the agent tools): Google Ads GAQL, GA4, Search Console, LinkedIn Ads or Reddit Ads
curl -s -X POST "https://api.closefinch.com/v1/marketing/ads/reports" \
-H "Authorization: Bearer $RA_API_KEY" \
-H "content-type: application/json" \
-d '{}'const res = await fetch(`https://api.closefinch.com/v1/marketing/ads/reports`, {
method: "POST",
headers: { authorization: `Bearer ${process.env.RA_API_KEY}`, "content-type": "application/json" },
body: JSON.stringify({}), // fields: see the OpenAPI schema
});
const data = await res.json();GET /v1/marketing/ads/status
Which marketing accounts are connected (Google Ads, Analytics and Search Console; LinkedIn Ads; Reddit Ads; WordPress) and what's missing
curl -s "https://api.closefinch.com/v1/marketing/ads/status" \
-H "Authorization: Bearer $RA_API_KEY"const res = await fetch(`https://api.closefinch.com/v1/marketing/ads/status`, {
method: "GET",
headers: { authorization: `Bearer ${process.env.RA_API_KEY}` },
});
const data = await res.json();GET /v1/marketing/brand-kit
The brand kit: voice, audience, do's and don'ts, hashtags, banned words, the subreddits Reddit posts may go to, discover mode
curl -s "https://api.closefinch.com/v1/marketing/brand-kit" \
-H "Authorization: Bearer $RA_API_KEY"const res = await fetch(`https://api.closefinch.com/v1/marketing/brand-kit`, {
method: "GET",
headers: { authorization: `Bearer ${process.env.RA_API_KEY}` },
});
const data = await res.json();PUT /v1/marketing/brand-kit
Change the brand kit (owners); turning discover mode on makes you its reviewer
curl -s -X PUT "https://api.closefinch.com/v1/marketing/brand-kit" \
-H "Authorization: Bearer $RA_API_KEY" \
-H "content-type: application/json" \
-d '{}'const res = await fetch(`https://api.closefinch.com/v1/marketing/brand-kit`, {
method: "PUT",
headers: { authorization: `Bearer ${process.env.RA_API_KEY}`, "content-type": "application/json" },
body: JSON.stringify({}), // fields: see the OpenAPI schema
});
const data = await res.json();GET /v1/marketing/commenters
Commenters on your organization's own LinkedIn posts who sound like buyers (scored; never messaged automatically)
curl -s "https://api.closefinch.com/v1/marketing/commenters" \
-H "Authorization: Bearer $RA_API_KEY"const res = await fetch(`https://api.closefinch.com/v1/marketing/commenters`, {
method: "GET",
headers: { authorization: `Bearer ${process.env.RA_API_KEY}` },
});
const data = await res.json();POST /v1/marketing/commenters/$ID/decision
Add a flagged commenter to the CRM as a lead (an existing contact is linked instead), or dismiss them
curl -s -X POST "https://api.closefinch.com/v1/marketing/commenters/$ID/decision" \
-H "Authorization: Bearer $RA_API_KEY" \
-H "content-type: application/json" \
-d '{}'const res = await fetch(`https://api.closefinch.com/v1/marketing/commenters/${id}/decision`, {
method: "POST",
headers: { authorization: `Bearer ${process.env.RA_API_KEY}`, "content-type": "application/json" },
body: JSON.stringify({}), // fields: see the OpenAPI schema
});
const data = await res.json();GET /v1/marketing/moments
Moments (clips) from meetings our recorder recorded, and whether their account may be referenced
curl -s "https://api.closefinch.com/v1/marketing/moments" \
-H "Authorization: Bearer $RA_API_KEY"const res = await fetch(`https://api.closefinch.com/v1/marketing/moments`, {
method: "GET",
headers: { authorization: `Bearer ${process.env.RA_API_KEY}` },
});
const data = await res.json();POST /v1/marketing/moments/$ID/post
Draft a post from a moment: paraphrased with names, numbers and contact details removed, or the quote word for word once the person quoted agrees (a request email, as your draft)
curl -s -X POST "https://api.closefinch.com/v1/marketing/moments/$ID/post" \
-H "Authorization: Bearer $RA_API_KEY" \
-H "content-type: application/json" \
-d '{}'const res = await fetch(`https://api.closefinch.com/v1/marketing/moments/${id}/post`, {
method: "POST",
headers: { authorization: `Bearer ${process.env.RA_API_KEY}`, "content-type": "application/json" },
body: JSON.stringify({}), // fields: see the OpenAPI schema
});
const data = await res.json();GET /v1/marketing/partners
Creator and partner candidates, best fit first
curl -s "https://api.closefinch.com/v1/marketing/partners" \
-H "Authorization: Bearer $RA_API_KEY"const res = await fetch(`https://api.closefinch.com/v1/marketing/partners`, {
method: "GET",
headers: { authorization: `Bearer ${process.env.RA_API_KEY}` },
});
const data = await res.json();POST /v1/marketing/partners/$ID/decision
Shortlist a candidate, mark it contacted, or dismiss it
curl -s -X POST "https://api.closefinch.com/v1/marketing/partners/$ID/decision" \
-H "Authorization: Bearer $RA_API_KEY" \
-H "content-type: application/json" \
-d '{}'const res = await fetch(`https://api.closefinch.com/v1/marketing/partners/${id}/decision`, {
method: "POST",
headers: { authorization: `Bearer ${process.env.RA_API_KEY}`, "content-type": "application/json" },
body: JSON.stringify({}), // fields: see the OpenAPI schema
});
const data = await res.json();POST /v1/marketing/partners/search
Find creators (podcasts, newsletters, channels, blogs) or partners (agencies, consultants, products) on a topic, scored for fit; nothing is sent
curl -s -X POST "https://api.closefinch.com/v1/marketing/partners/search" \
-H "Authorization: Bearer $RA_API_KEY" \
-H "content-type: application/json" \
-d '{}'const res = await fetch(`https://api.closefinch.com/v1/marketing/partners/search`, {
method: "POST",
headers: { authorization: `Bearer ${process.env.RA_API_KEY}`, "content-type": "application/json" },
body: JSON.stringify({}), // fields: see the OpenAPI schema
});
const data = await res.json();GET /v1/marketing/plan
The plan's open items, by week
curl -s "https://api.closefinch.com/v1/marketing/plan" \
-H "Authorization: Bearer $RA_API_KEY"const res = await fetch(`https://api.closefinch.com/v1/marketing/plan`, {
method: "GET",
headers: { authorization: `Bearer ${process.env.RA_API_KEY}` },
});
const data = await res.json();POST /v1/marketing/plan/$ID/decision
Accept, dismiss or mark a plan item done
curl -s -X POST "https://api.closefinch.com/v1/marketing/plan/$ID/decision" \
-H "Authorization: Bearer $RA_API_KEY" \
-H "content-type: application/json" \
-d '{}'const res = await fetch(`https://api.closefinch.com/v1/marketing/plan/${id}/decision`, {
method: "POST",
headers: { authorization: `Bearer ${process.env.RA_API_KEY}`, "content-type": "application/json" },
body: JSON.stringify({}), // fields: see the OpenAPI schema
});
const data = await res.json();POST /v1/marketing/plans
Plan the next 4 to 12 weeks (launches, promotions, partnerships, local events, content) from competitor changes and news, each item citing its evidence
curl -s -X POST "https://api.closefinch.com/v1/marketing/plans" \
-H "Authorization: Bearer $RA_API_KEY" \
-H "content-type: application/json" \
-d '{}'const res = await fetch(`https://api.closefinch.com/v1/marketing/plans`, {
method: "POST",
headers: { authorization: `Bearer ${process.env.RA_API_KEY}`, "content-type": "application/json" },
body: JSON.stringify({}), // fields: see the OpenAPI schema
});
const data = await res.json();GET /v1/marketing/posts
Posts: drafts (yours to approve), scheduled, published, failed
curl -s "https://api.closefinch.com/v1/marketing/posts" \
-H "Authorization: Bearer $RA_API_KEY"const res = await fetch(`https://api.closefinch.com/v1/marketing/posts`, {
method: "GET",
headers: { authorization: `Bearer ${process.env.RA_API_KEY}` },
});
const data = await res.json();POST /v1/marketing/posts
Draft a post (checked against the brand kit); nothing is published until you approve it
curl -s -X POST "https://api.closefinch.com/v1/marketing/posts" \
-H "Authorization: Bearer $RA_API_KEY" \
-H "content-type: application/json" \
-d '{}'const res = await fetch(`https://api.closefinch.com/v1/marketing/posts`, {
method: "POST",
headers: { authorization: `Bearer ${process.env.RA_API_KEY}`, "content-type": "application/json" },
body: JSON.stringify({}), // fields: see the OpenAPI schema
});
const data = await res.json();PATCH /v1/marketing/posts/$ID
Edit your draft
curl -s -X PATCH "https://api.closefinch.com/v1/marketing/posts/$ID" \
-H "Authorization: Bearer $RA_API_KEY" \
-H "content-type: application/json" \
-d '{}'const res = await fetch(`https://api.closefinch.com/v1/marketing/posts/${id}`, {
method: "PATCH",
headers: { authorization: `Bearer ${process.env.RA_API_KEY}`, "content-type": "application/json" },
body: JSON.stringify({}), // fields: see the OpenAPI schema
});
const data = await res.json();POST /v1/marketing/posts/$ID/decision
Approve your post (published now, or at scheduled_at, from your account, through policy), reject it, or cancel a scheduled one (back to draft)
curl -s -X POST "https://api.closefinch.com/v1/marketing/posts/$ID/decision" \
-H "Authorization: Bearer $RA_API_KEY" \
-H "content-type: application/json" \
-d '{}'const res = await fetch(`https://api.closefinch.com/v1/marketing/posts/${id}/decision`, {
method: "POST",
headers: { authorization: `Bearer ${process.env.RA_API_KEY}`, "content-type": "application/json" },
body: JSON.stringify({}), // fields: see the OpenAPI schema
});
const data = await res.json();GET /v1/marketing/seo/briefs
SEO, local and AI-answer briefs: research, drafts, approvals
curl -s "https://api.closefinch.com/v1/marketing/seo/briefs" \
-H "Authorization: Bearer $RA_API_KEY"const res = await fetch(`https://api.closefinch.com/v1/marketing/seo/briefs`, {
method: "GET",
headers: { authorization: `Bearer ${process.env.RA_API_KEY}` },
});
const data = await res.json();POST /v1/marketing/seo/briefs
Research a topic: what ranks, what people ask, the local pack (with a location), and your Search Console queries that are seen but not clicked
curl -s -X POST "https://api.closefinch.com/v1/marketing/seo/briefs" \
-H "Authorization: Bearer $RA_API_KEY" \
-H "content-type: application/json" \
-d '{}'const res = await fetch(`https://api.closefinch.com/v1/marketing/seo/briefs`, {
method: "POST",
headers: { authorization: `Bearer ${process.env.RA_API_KEY}`, "content-type": "application/json" },
body: JSON.stringify({}), // fields: see the OpenAPI schema
});
const data = await res.json();GET /v1/marketing/seo/briefs/$ID
A brief with its research and draft
curl -s "https://api.closefinch.com/v1/marketing/seo/briefs/$ID" \
-H "Authorization: Bearer $RA_API_KEY"const res = await fetch(`https://api.closefinch.com/v1/marketing/seo/briefs/${id}`, {
method: "GET",
headers: { authorization: `Bearer ${process.env.RA_API_KEY}` },
});
const data = await res.json();PATCH /v1/marketing/seo/briefs/$ID
Edit the draft (the brand checks run again)
curl -s -X PATCH "https://api.closefinch.com/v1/marketing/seo/briefs/$ID" \
-H "Authorization: Bearer $RA_API_KEY" \
-H "content-type: application/json" \
-d '{}'const res = await fetch(`https://api.closefinch.com/v1/marketing/seo/briefs/${id}`, {
method: "PATCH",
headers: { authorization: `Bearer ${process.env.RA_API_KEY}`, "content-type": "application/json" },
body: JSON.stringify({}), // fields: see the OpenAPI schema
});
const data = await res.json();POST /v1/marketing/seo/briefs/$ID/decision
Approve the draft (optionally creating a WordPress draft, or publishing it) or reject it
curl -s -X POST "https://api.closefinch.com/v1/marketing/seo/briefs/$ID/decision" \
-H "Authorization: Bearer $RA_API_KEY" \
-H "content-type: application/json" \
-d '{}'const res = await fetch(`https://api.closefinch.com/v1/marketing/seo/briefs/${id}/decision`, {
method: "POST",
headers: { authorization: `Bearer ${process.env.RA_API_KEY}`, "content-type": "application/json" },
body: JSON.stringify({}), // fields: see the OpenAPI schema
});
const data = await res.json();POST /v1/marketing/seo/briefs/$ID/draft
Draft the brief: an answer-first article, FAQ or local page in the brand voice, with a title, meta description, FAQ and JSON-LD
curl -s -X POST "https://api.closefinch.com/v1/marketing/seo/briefs/$ID/draft" \
-H "Authorization: Bearer $RA_API_KEY" \
-H "content-type: application/json" \
-d '{}'const res = await fetch(`https://api.closefinch.com/v1/marketing/seo/briefs/${id}/draft`, {
method: "POST",
headers: { authorization: `Bearer ${process.env.RA_API_KEY}`, "content-type": "application/json" },
body: JSON.stringify({}), // fields: see the OpenAPI schema
});
const data = await res.json();POST /v1/marketing/site/audits
Audit your own website (home page and up to seven pages it links to): titles, descriptions, headings, structured data, alt text, FAQ
curl -s -X POST "https://api.closefinch.com/v1/marketing/site/audits" \
-H "Authorization: Bearer $RA_API_KEY" \
-H "content-type: application/json" \
-d '{}'const res = await fetch(`https://api.closefinch.com/v1/marketing/site/audits`, {
method: "POST",
headers: { authorization: `Bearer ${process.env.RA_API_KEY}`, "content-type": "application/json" },
body: JSON.stringify({}), // fields: see the OpenAPI schema
});
const data = await res.json();GET /v1/marketing/site/changes
Proposed website changes (from audits), applied through WordPress or by hand
curl -s "https://api.closefinch.com/v1/marketing/site/changes" \
-H "Authorization: Bearer $RA_API_KEY"const res = await fetch(`https://api.closefinch.com/v1/marketing/site/changes`, {
method: "GET",
headers: { authorization: `Bearer ${process.env.RA_API_KEY}` },
});
const data = await res.json();POST /v1/marketing/site/changes/$ID/decision
Apply a change on your WordPress site (a title, or a description as the page's excerpt), mark it done by hand, or reject it
curl -s -X POST "https://api.closefinch.com/v1/marketing/site/changes/$ID/decision" \
-H "Authorization: Bearer $RA_API_KEY" \
-H "content-type: application/json" \
-d '{}'const res = await fetch(`https://api.closefinch.com/v1/marketing/site/changes/${id}/decision`, {
method: "POST",
headers: { authorization: `Bearer ${process.env.RA_API_KEY}`, "content-type": "application/json" },
body: JSON.stringify({}), // fields: see the OpenAPI schema
});
const data = await res.json();GET /v1/promotions
Promotions
curl -s "https://api.closefinch.com/v1/promotions" \
-H "Authorization: Bearer $RA_API_KEY"const res = await fetch(`https://api.closefinch.com/v1/promotions`, {
method: "GET",
headers: { authorization: `Bearer ${process.env.RA_API_KEY}` },
});
const data = await res.json();POST /v1/promotions
Create a promotion: a name, a code, an offer, its dates and landing page (a UTM campaign is made from the code)
curl -s -X POST "https://api.closefinch.com/v1/promotions" \
-H "Authorization: Bearer $RA_API_KEY" \
-H "content-type: application/json" \
-d '{}'const res = await fetch(`https://api.closefinch.com/v1/promotions`, {
method: "POST",
headers: { authorization: `Bearer ${process.env.RA_API_KEY}`, "content-type": "application/json" },
body: JSON.stringify({}), // fields: see the OpenAPI schema
});
const data = await res.json();GET /v1/promotions/$ID
A promotion with its tracking links
curl -s "https://api.closefinch.com/v1/promotions/$ID" \
-H "Authorization: Bearer $RA_API_KEY"const res = await fetch(`https://api.closefinch.com/v1/promotions/${id}`, {
method: "GET",
headers: { authorization: `Bearer ${process.env.RA_API_KEY}` },
});
const data = await res.json();GET /v1/promotions/$ID/results
A promotion's sales: attributed pipeline and wins (its UTM campaign), touches, orders and quotes with its code; per currency
curl -s "https://api.closefinch.com/v1/promotions/$ID/results" \
-H "Authorization: Bearer $RA_API_KEY"const res = await fetch(`https://api.closefinch.com/v1/promotions/${id}/results`, {
method: "GET",
headers: { authorization: `Bearer ${process.env.RA_API_KEY}` },
});
const data = await res.json();POST /v1/promotions/$ID/status
Launch a promotion (optionally drafting announcement posts for you to approve) or end it
curl -s -X POST "https://api.closefinch.com/v1/promotions/$ID/status" \
-H "Authorization: Bearer $RA_API_KEY" \
-H "content-type: application/json" \
-d '{}'const res = await fetch(`https://api.closefinch.com/v1/promotions/${id}/status`, {
method: "POST",
headers: { authorization: `Bearer ${process.env.RA_API_KEY}`, "content-type": "application/json" },
body: JSON.stringify({}), // fields: see the OpenAPI schema
});
const data = await res.json();PUT /v1/quotes/$ID/promo-code
Put a promotion's code on a quote (null clears it)
curl -s -X PUT "https://api.closefinch.com/v1/quotes/$ID/promo-code" \
-H "Authorization: Bearer $RA_API_KEY" \
-H "content-type: application/json" \
-d '{}'const res = await fetch(`https://api.closefinch.com/v1/quotes/${id}/promo-code`, {
method: "PUT",
headers: { authorization: `Bearer ${process.env.RA_API_KEY}`, "content-type": "application/json" },
body: JSON.stringify({}), // fields: see the OpenAPI schema
});
const data = await res.json();Request and response schemas: https://www.closefinch.com/openapi.json. All resources: API reference.