APILinkbuilding
Link building API. Your links, prospects and outreach in your own tools.
MarketingTracer keeps your link building pipeline: the sites you found, the ones you mailed, the links that went live, and a check on every live link to see that it stays. The API gives you that pipeline, so the numbers can sit in your report, your CRM or your own alerts.
Live and lost
Links won and lost, per month.
The pipeline
Found, contacted, agreed, live.
Outreach
Your sequences and the mails still to go.
Checked links
Is the link still there, follow or nofollow.
Four endpoints, four MCP tools
Each endpoint is a POST to /rest/v1/<endpoint> on app.marketingtracer.com. In your AI assistant the same data is the MCP tool under each endpoint.
| Endpoint and MCP tool | What you get |
|---|---|
linkbuilding.overviewget_linkbuilding_overview | Live and lost links, links won and lost per month, how far your prospects of the last 90 days got, what needs attention, and the anchor texts of your live links. |
linkbuilding.linksget_linkbuilding_links | Your links and prospects with their stage, the contact we found, and what our last check saw: is the link there, its anchor text, follow or nofollow. |
linkbuilding.sequencesget_linkbuilding_sequences | Your outreach sequences, with how many sites each one contacted and how many said yes. |
linkbuilding.queueget_linkbuilding_queue | The outreach mails planned to go out through your own mail server. |
Every endpoint takes site_id. linkbuilding.links takes stage, limit (1 to 5,000, default 100) and cursor; linkbuilding.overview takes month (YYYY-MM) for a report of an earlier month.
A live link that went missing, as the API returns it
curl -X POST https://app.marketingtracer.com/rest/v1/linkbuilding.links \
-H "Authorization: Bearer YOUR_API_KEY" \
-H "Content-Type: application/json" \
-d '{"site_id": "YOUR_SITE_ID", "stage": "live", "limit": 1}'
From a real account, with the sites and ids changed and shortened where you see …:
{
"data": [{
"id": "6ae03f867a2162526408e976",
"url": "https://news.example.org/article/css-tricks-is-back",
"domain": "news.example.org",
"stage": "live",
"email": "hello@example.org",
"contact_form": "https://example.org/contact",
"added_at": "2026-10-27T06:07:02Z",
"live_at": "2026-10-30T12:49:47Z",
"check": {
"state": "missing",
"last_at": "2026-10-30T13:50:01Z",
"next_at": "2026-11-01T02:50:01Z",
"found": null,
"history": [{"at": "2026-10-30T13:50:01Z", "result": "missing"}]
},
…
}],
"meta": {"site_id": "YOUR_SITE_ID", "next_cursor": "6ae03f867a2162526408e976", "total": 8}
}
This one is worth a look: it was marked live, but our first check did not find the link on the page. It counts as lost only after two checks in a row that don't find it. A page that doesn't load doesn't count as a miss, so a site that is down for a day doesn't set off an alarm.
New links in the monthly report
If you pay for links, or sell them, you want to see them. linkbuilding.overview with last month's month gives the links won and lost and the anchor texts. Your report shows them in your own layout. Every live link is checked, so the list is current.
A lost link on your ticket board
Ask linkbuilding.links with stage: "lost" once a day and compare with yesterday. A link that went missing lands on your ticket board with the page and the contact, while the site owner still remembers you. One call a day per site, far inside the limit.
Every endpoint, argument and field
Generated from the same definitions the API itself runs on, and the example answers are tested against them, so this reference is never behind. Every endpoint is a POST with a JSON body; reading endpoints also take a GET with the same arguments in the query string. Send your API key as Authorization: Bearer YOUR_API_KEY. Every answer is {"data": …, "meta": {…}}: meta.site_id always, meta.next_cursor and meta.total for a list, meta.period where the endpoint covers a period. An error is {"error": {"code", "message"}} with the HTTP status: 400 invalid_argument, unknown_argument or missing_argument; 401 not_authenticated; 403 no_access or tool_off; 404 not_found; 429 rate_limited. The machine-readable version is openapi.json.
linkbuilding.overview
POST /rest/v1/linkbuilding.overview · MCP tool get_linkbuilding_overview
Returns the link building results of one site: live and lost links, links won and lost per month (12 months up to month), how far the prospects added in the last 90 days got (found, contacted, agreed, live), what needs attention, and the anchor texts of the live links.
Arguments
| Argument | Type | What it does |
|---|---|---|
site_id (required) | string | The site: its id from list_sites, or the id in the app’s address. |
month | string, YYYY-MM | Last month of the 12-month series, YYYY-MM. Defaults to this month. |
Example request
curl -X POST https://app.marketingtracer.com/rest/v1/linkbuilding.overview \
-H "Authorization: Bearer YOUR_API_KEY" \
-H "Content-Type: application/json" \
-d '{"site_id":"YOUR_SITE_ID"}'
Example response · A real answer, anonymised and shortened to two items per list.
{
"data": {
"month": "2026-10",
"kpis": {
"live": 8,
"lost": 1,
"waiting": 4,
"follow": 0,
"checked": 0,
"nofollow": 0,
"new_this_month": 1,
"lost_this_month": 0,
"follow_pct": null
},
"months": [{"month": "2026-09", "new": 0, "lost": 0}, {"month": "2026-10", "new": 1, "lost": 0}],
"funnel_90_days": {"found": 45, "sent": 2, "agreed": 2, "live": 1},
"attention": {"lost": [], "agreed_old": [], "changed": [], "mails_next_24h": 0},
"anchors": [
{"anchor": "example text", "count": 2, "share_pct": 40},
{"anchor": "more text", "count": 1, "share_pct": 20}
],
"smtp_ready": false
},
"meta": {"site_id": "YOUR_SITE_ID"}
}
Response fields · in data:
| Field | Type | What it is |
|---|---|---|
month | string | The last month of the series, YYYY-MM. |
kpis | object | The state now. |
kpis.live | integer | Live links. |
kpis.lost | integer | Links that were live and are gone. |
kpis.waiting | integer | Contacted links waiting for an answer. |
kpis.follow | integer | Checked live links that are follow (as last found). |
kpis.checked | integer | Live links our check has found on their page at least once. |
kpis.nofollow | integer | Checked live links that are nofollow (as last found). |
kpis.new_this_month | integer | Links that went live in month. |
kpis.lost_this_month | integer | Links lost in month. |
kpis.follow_pct | number or null | follow as a share of checked, 0-100, a whole number; null when no live link has been found yet. |
months | array | 12 months up to month, oldest first. |
months[].month | string | YYYY-MM. |
months[].new | integer | Links that went live that month (for older links without a live date: the month they were added). |
months[].lost | integer | Links lost that month. |
funnel_90_days | object | Prospects added in the last 90 days, by how far they got. |
funnel_90_days.found | integer | All of them. |
funnel_90_days.sent | integer | Contacted, or rejected later. |
funnel_90_days.agreed | integer | Agreed (or further). |
funnel_90_days.live | integer | Live (or lost later). |
attention | object | What needs a look; the lists hold at most 5 each. |
attention.lost | array | Links lost in the last 30 days. |
attention.lost[].link_id | string | The link. |
attention.lost[].url | string | The page. |
attention.lost[].lost_at | string or null | When it was lost, ISO 8601 UTC. |
attention.agreed_old | array | Links agreed more than 14 days ago and not live yet. |
attention.agreed_old[].link_id | string | The link. |
attention.agreed_old[].url | string | The page. |
attention.changed | array | Live links that changed. |
attention.changed[].link_id | string | The link. |
attention.changed[].url | string | The page. |
attention.changed[].changes | array<string> | nofollow, anchor and/or target. |
attention.mails_next_24h | integer | Outreach mails due within the next 24 hours, including overdue ones. |
anchors | array | The 4 most used anchor texts of the live links, then one row with anchor null for all the others. |
anchors[].anchor | string or null | The anchor text, lowercase (the one our check found, else the one you want); null for the row with all other anchors. |
anchors[].count | integer | Live links with it. |
anchors[].share_pct | number | Share of the live links that have an anchor text, 0-100, a whole number. |
smtp_ready | boolean | Whether the site's own mail server is set up and approved for outreach. |
linkbuilding.links
POST /rest/v1/linkbuilding.links · MCP tool get_linkbuilding_links
Returns the links and prospects of one site, newest first: the page, its domain, the stage (found, sent = contacted, agreed, live, lost, rejected), the contact found, what our own check last saw on the page (is the link there, the anchor, follow or nofollow) and the state of the outreach mails.
Arguments
| Argument | Type | What it does |
|---|---|---|
site_id (required) | string | The site: its id from list_sites, or the id in the app’s address. |
stage | one of found, sent, agreed, live, lost, rejected | Only links in this stage. |
limit | integer, 1 to 5,000, default 100 | Links per call. |
cursor | string | meta.next_cursor of the previous call, for the next page. |
Example request
curl -X POST https://app.marketingtracer.com/rest/v1/linkbuilding.links \
-H "Authorization: Bearer YOUR_API_KEY" \
-H "Content-Type: application/json" \
-d '{"site_id":"YOUR_SITE_ID","limit":2}'
Example response · A real answer, anonymised and shortened to two items per list.
{
"data": [
{
"id": "6ae43406b841f35e0f0d9c95",
"url": "https://news.example.org/articles/rail-grant",
"domain": "news.example.org",
"status": "agreed",
"stage": "agreed",
"my_url": null,
"anchor": null,
"tag": "critical css",
"note": null,
"email": null,
"contact_form": "https://news.example.org/contact",
"contact_queued": false,
"contact_checked_at": "2026-10-30T12:48:34Z",
"added_at": "2026-10-30T06:07:02Z",
"status_at": "2026-10-30T12:49:44Z",
"live_at": null,
"check": {
"state": null,
"last_at": null,
"next_at": "2026-10-31T12:49:44Z",
"found": null,
"history": [],
"changes": []
},
"mail": {
"sequence_id": null,
"step": 0,
"next_at": null,
"last_at": null,
"stopped": null,
"error": null
}
},
{
"id": "6ae2e285b195fcf9b00f6244",
"url": "https://m.example.net/news/report/css-officers",
"domain": "m.example.net",
"status": "open",
"stage": "found",
"my_url": null,
"anchor": null,
"tag": "critical css",
"note": null,
"email": null,
"contact_form": "https://example.net/contact",
"contact_queued": false,
"contact_checked_at": "2026-10-30T12:48:30Z",
"added_at": "2026-10-29T06:07:01Z",
"status_at": null,
"live_at": null,
"check": {
"state": null,
"last_at": null,
"next_at": null,
"found": null,
"history": [],
"changes": []
},
"mail": {
"sequence_id": null,
"step": 0,
"next_at": null,
"last_at": null,
"stopped": null,
"error": null
}
}
],
"meta": {"site_id": "YOUR_SITE_ID", "next_cursor": "6ae2e285b195fcf9b00f6244", "total": 958}
}
Response fields · data is a list; each item has:
| Field | Type | What it is |
|---|---|---|
id | string | The link id. |
url | string | The page that links, or should link, to the site. |
domain | string | Its domain. |
status | string | The detailed status: open, pending, firstreminder, secondreminder, agreed, done, lost, rejected or stalled. |
stage | string | found, sent, agreed, live, lost or rejected. |
my_url | string or null | The page of the site the link should point to, as entered; null when not set (then the homepage). |
anchor | string or null | The anchor text you want. |
tag | string or null | Your own label. |
note | string or null | Your own note. |
email | string or null | The contact address found on this domain. |
contact_form | string or null | The contact form found on this domain. |
contact_queued | boolean | Whether a contact search is waiting. |
contact_checked_at | string or null | When a contact was last looked for on this domain, ISO 8601 UTC. |
added_at | string | When it was added, ISO 8601 UTC. |
status_at | string or null | When the status last changed, ISO 8601 UTC. |
live_at | string or null | When it went live, ISO 8601 UTC. |
check | object | Our check of the page. |
check.state | string or null | found, changed or missing at the last check that got an answer; null before that. |
check.last_at | string or null | When it was last checked, ISO 8601 UTC. |
check.next_at | string or null | When it is checked next, ISO 8601 UTC; null when it is not checked (stage found or rejected). |
check.found | object or null | The link as our check last found it on the page; null if never found. |
check.found.href | string or null | Where it points. |
check.found.anchor | string or null | Its anchor text. |
check.found.rel | string or null | Its rel attribute. |
check.found.follow | boolean | Whether it is follow. |
check.history | array | The last checks, oldest first, at most 12. |
check.history[].at | string or null | When, ISO 8601 UTC. |
check.history[].result | string or null | found, changed, missing, or error (the page did not answer; never counts as missing). |
check.changes | array<string> | What changed at the last check that found the link: nofollow, anchor and/or target. |
mail | object | The outreach for this link. |
mail.sequence_id | string or null | The sequence it is in. |
mail.step | integer | Mails sent so far. |
mail.next_at | string or null | When the next mail goes out, ISO 8601 UTC. |
mail.last_at | string or null | When the last mail went out, ISO 8601 UTC. |
mail.stopped | string or null | Why the sequence stopped: manual, deleted (sequence removed), status (status changed), no_email, blocked (do-not-contact list), recent (domain contacted in the last 180 days) or no_step; null when it did not stop. |
mail.error | string or null | The last sending error. |
linkbuilding.sequences
POST /rest/v1/linkbuilding.sequences · MCP tool get_linkbuilding_sequences
Returns the outreach sequences of one site: a first mail and up to two follow-ups after a number of working days, with how many sites were contacted with it and how many agreed.
Arguments
| Argument | Type | What it does |
|---|---|---|
site_id (required) | string | The site: its id from list_sites, or the id in the app’s address. |
Example request
curl -X POST https://app.marketingtracer.com/rest/v1/linkbuilding.sequences \
-H "Authorization: Bearer YOUR_API_KEY" \
-H "Content-Type: application/json" \
-d '{"site_id":"YOUR_SITE_ID"}'
Example response · Illustrative: the account we sampled had no sequences or scheduled mails; the fields are as the code returns them.
{
"data": [
{
"id": "seq1",
"name": "Resource pages",
"steps": [
{
"subject": "A resource for your readers",
"body": "Hi [voornaam], I read [partner_link] …",
"after_workdays": 0
},
{
"subject": "",
"body": "Hi [voornaam], a quick follow-up …",
"after_workdays": 4
}
],
"contacted": 12,
"agreed": 3
}
],
"meta": {"site_id": "YOUR_SITE_ID", "next_cursor": null, "total": 1}
}
Response fields · data is a list; each item has:
| Field | Type | What it is |
|---|---|---|
id | string | The sequence id. |
name | string | Its name. |
steps | array | The mails, in order. |
steps[].subject | string | The subject; empty for a follow-up means "Re:" plus the first subject. |
steps[].body | string | The text, with the fields [partner_domain], [partner_link], [voornaam], [mijn_pagina] and [ankertekst]. |
steps[].after_workdays | integer | Working days after the mail before; always 0 for the first. |
contacted | integer | Links that got at least one mail of it. |
agreed | integer | Links in it that are now agreed or live. |
linkbuilding.queue
POST /rest/v1/linkbuilding.queue · MCP tool get_linkbuilding_queue
Returns the outreach mails scheduled for one site, sent through the site's own mail server on working days, and how many went out today against the daily limit.
Arguments
| Argument | Type | What it does |
|---|---|---|
site_id (required) | string | The site: its id from list_sites, or the id in the app’s address. |
Example request
curl -X POST https://app.marketingtracer.com/rest/v1/linkbuilding.queue \
-H "Authorization: Bearer YOUR_API_KEY" \
-H "Content-Type: application/json" \
-d '{"site_id":"YOUR_SITE_ID"}'
Example response · Illustrative: the account we sampled had no sequences or scheduled mails; the fields are as the code returns them.
{
"data": {
"sent_today": 3,
"day_limit": 25,
"scheduled": [
{
"link_id": "6ae43406b841f35e0f0d9c95",
"domain": "news.example.org",
"email": "editor@example.org",
"sequence_id": "seq1",
"sequence": "Resource pages",
"step": 1,
"send_at": "2026-11-02T09:10:00Z",
"error": null
}
]
},
"meta": {"site_id": "YOUR_SITE_ID"}
}
Response fields · in data:
| Field | Type | What it is |
|---|---|---|
sent_today | integer | Mails sent today (Amsterdam time). |
day_limit | integer | Mails the site sends at most per day. |
scheduled | array | The next mails, soonest first, at most 100, including overdue ones. |
scheduled[].link_id | string | The link. |
scheduled[].domain | string | The site it goes to. |
scheduled[].email | string or null | The address. |
scheduled[].sequence_id | string or null | The sequence. |
scheduled[].sequence | string or null | Its name. |
scheduled[].step | integer | Mails sent so far; this is the next one. |
scheduled[].send_at | string or null | When it goes out, ISO 8601 UTC; the time may already have passed. |
scheduled[].error | string or null | The last sending error. |
Link building for every client. Under your name.
One key reads the link pipeline of every client site you can open, and outreach goes out from your own mail server under your own name. On a white-label dashboard the API answers on your own domain. The whole dashboard is white label: your domain, logo and colours, and team roles that set which modules each role sees.
Free 14-day trial
MarketingTracer smart A.I. tool shows you what you need to rank. Then we'll help you get it done.
- No credit card required
- No installation needed
- No strings attached
FAQ
Something else? Ask us.
What is a link building API?
A link building API gives your own software the state of your link work: the sites you approached, the links that went live and whether they are still there. This one reads the pipeline you keep in MarketingTracer.
Does it find backlinks I did not build?
No. MarketingTracer has no backlink index. It checks the links in your own pipeline.
What do the stages mean?
found: a prospect. sent: contacted. agreed: said yes. live: the link is on the page. lost: it was live and is gone. rejected: said no.
How often are live links checked?
Most often in the first weeks after a link goes live, then less often as it settles. check.next_at tells you when each link is checked next.
Do the mails go out from MarketingTracer?
No. Outreach goes through your own mail server, on working days, up to a daily limit you set. linkbuilding.queue shows what is planned.
Can I add prospects or change a stage through the API?
Not yet. The public API reads; you add prospects and move links between stages in the app.
What does it cost?
The API costs nothing extra; it is part of every plan. Prices are on the pricing page.