CitationBenchTalk to Sales
API referenceLink Building

Link building campaign management API — unified view across all outreach types

Unified campaign endpoints across SERP, competitor, and custom outreach. List campaigns, read metrics, pause and resume, send one-off emails, and respond to inbound replies from one endpoint family.

The unified campaign view across SERP outreach, competitor outreach, and any custom outreach. Read metrics, pause/resume campaigns, send one-off emails, and respond to inbound replies — all from one endpoint family.

For the actual campaign-starting endpoints, see SERP outreach, competitor link outreach, and inbound.

Endpoints

MethodPathPurpose
GET/v1/link-building/campaignList all campaigns (across all types)
GET/v1/link-building/campaign/{id}Get one campaign
GET/v1/link-building/campaign/{id}/metricsCampaign-level metrics
POST/v1/link-building/campaign/{id}/pausePause a campaign
POST/v1/link-building/campaign/{id}/resumeResume
POST/v1/link-building/campaign/{id}/send-emailSend a manual one-off email within the campaign
POST/v1/link-building/campaign/respondRespond to a specific inbound reply (manual override)

curl -G .../v1/link-building/campaign \
  --data-urlencode "type=serp,competitor" \
  --data-urlencode "status=active" \
  --data-urlencode "since=2026-05-01T00:00:00Z"
{
  "data": [
    {
      "id": "scmp_***",
      "type": "serp",
      "name": "best PM software for engineering teams",
      "createdAt": "2026-05-08T...",
      "status": "active",
      "draftsCount": 14,
      "sentCount": 11,
      "repliedCount": 4,
      "placedCount": 2
    },
    {
      "id": "ccmp_***",
      "type": "competitor",
      "name": "vs monday.com",
      "createdAt": "2026-05-15T...",
      "status": "active",
      "draftsCount": 25,
      "sentCount": 18,
      "repliedCount": 7,
      "placedCount": 3
    }
  ],
  "total": 12
}

curl .../v1/link-building/campaign/scmp_***/metrics
{
  "campaignId": "scmp_***",
  "summary": {
    "drafted": 14,
    "sent": 11,
    "delivered": 11,
    "opened": 9,
    "replied": 4,
    "placed": 2,
    "openRate": 0.82,
    "replyRate": 0.36,
    "placementRate": 0.18
  },
  "timeline": [
    { "date": "2026-05-09", "event": "campaign_created" },
    { "date": "2026-05-09", "event": "drafts_ready", "count": 14 },
    { "date": "2026-05-09", "event": "approvals_completed", "count": 14 },
    { "date": "2026-05-10", "event": "emails_sent", "count": 11 },
    { "date": "2026-05-13", "event": "first_reply" },
    { "date": "2026-05-18", "event": "first_link_placed" }
  ],
  "byDomain": [
    {
      "domain": "engineering-blog.com",
      "status": "link_placed",
      "linkUrl": "https://engineering-blog.com/best-pm-tools"
    },
    { "domain": "devleadweekly.com", "status": "replied" },
    { "domain": "...", "status": "no_response" }
  ]
}

POST /v1/link-building/campaign/{id}/pause

Pauses any pending sends in the campaign (already-sent emails are untouched).

curl -X POST .../v1/link-building/campaign/scmp_***/pause -d '{
  "reason": "Need to revisit messaging"
}'

POST /v1/link-building/campaign/{id}/resume

curl -X POST .../v1/link-building/campaign/scmp_***/resume

POST /v1/link-building/campaign/{id}/send-email

Send a one-off email within the campaign context (e.g., a follow-up the agent didn't draft).

curl -X POST .../v1/link-building/campaign/scmp_***/send-email -d '{
  "relationshipId": "rel_***",
  "subject":        "Quick follow-up on my earlier note",
  "body":           "Hi Marina, just checking in ...",
  "scheduleAt":     "2026-05-26T10:00:00-04:00"
}'

Approval-gated by workspace policy. Returns an invocation + LinkBuildingEvent once sent.


POST /v1/link-building/campaign/respond

Manually respond to a specific inbound reply (override the inbound auto-response logic).

curl -X POST .../v1/link-building/campaign/respond -d '{
  "inboundMessageId": "msg_***",
  "body":             "Thanks Marina — yes happy to share the methodology. Want a 20-min call?",
  "scheduleAt":       "now"
}'

MCP

> List my active link-building campaigns and their reply rates.

Claude calls link_building.campaign.list and renders metrics inline.

> Pause campaign scmp_***.

Claude calls link_building.campaign.toggle with action: pause.

> Send a follow-up to Marina at engineering-blog.com.

Claude calls link_building.crm.relationship.list to find the relationship, then link_building.campaign.send_email.


Errors

StatusCodeCause
404campaign_not_found
409already_paused / already_active
422invalid_state_for_sendCampaign cancelled or completed

Cost

ActionCredits
List, get, metricsfree
Pause / resumefree
send-email2 (per email actually sent)
respond2

Use cases (string things together)

A. Agency portfolio campaign dashboard

curl -X POST .../v1/workspaces/bulk-action \
  -d '{
    "action":     "link_building.campaign.list",
    "workspaces": "all",
    "config":     { "status": "active" }
  }'

Per-client active-campaign view in one call.

B. Weekly reply rate report

curl -G .../v1/link-building/campaign \
  --data-urlencode "since=$(date -u -d '7 days ago' -Iseconds)" \
  | jq '.data[] | { id, sentCount, repliedCount, replyRate: (.repliedCount / .sentCount) }'

C. Webhooks on placements

curl -X POST .../v1/webhooks -d '{
  "url":    "https://hooks.our-portal.com/lb-placements",
  "events": ["link_building.link.placed"]
}'

D. Stop a campaign that's underperforming

METRICS=$(curl -sf .../v1/link-building/campaign/scmp_***/metrics)
REPLY_RATE=$(echo "$METRICS" | jq '.summary.replyRate')
if (( $(echo "$REPLY_RATE < 0.05" | bc -l) )); then
  curl -X POST .../v1/link-building/campaign/scmp_***/pause -d '{"reason":"Low reply rate"}'
fi

On this page