API documentation
Everything the web app does, the API does. Discover publisher inventory with verified Ahrefs and Moz metrics, check exactly what an order must contain, place it, and poll its status until the link is live. Base URL:
https://linkbuildingapi.com/api/v1 Authentication
Create a key at Settings, API keys (free account required) and send it as a bearer token on every request:
curl https://linkbuildingapi.com/api/v1/sites \
-H "Authorization: Bearer lbk_live_YOUR_KEY" Keys carry scopes; pick the smallest set that works:
- read browse sites, publishers, categories, and read your orders
- order place, cancel, and confirm orders (buying)
- fulfill accept, reject, and publish orders (selling)
Errors and rate limits
Errors are JSON with a stable machine code: { "error": { "code": "too_many_links", "message": "..." } }. Statuses:
401 (bad key), 403 (missing scope), 404 (not yours or does not exist), 422 (validation),
429 (rate limited, see Retry-After). The limit is 120 requests per minute per
key.
Discovering inventory
GET /sites lists live, orderable sites. Every site carries its offers[], and each offer IS the order shape: price, who writes the content,
how many links you may place, turnaround, and restrictions. Filters are query params:
« category, type, link_type, content_by, language, publisher,
q, min_dr, min_traffic, max_price (cents), limit, cursor »
curl "https://linkbuildingapi.com/api/v1/sites?category=Technology%20%26%20SaaS&min_dr=40&max_price=25000" \
-H "Authorization: Bearer lbk_live_YOUR_KEY" Response (abridged):
{
"sites": [{
"id": "9be4...",
"domain": "example-tech-blog.com",
"categories": ["Technology & SaaS"],
"metrics": { "domain_rating": 52, "domain_authority": 44,
"organic_traffic": 18400, "referring_domains": 890,
"spam_score": 2, "checked_at": "2026-07-01T00:00:00Z" },
"publisher": "acme-media",
"offers": [{
"id": "1f77...",
"type": "guest_post",
"price_cents": 15000,
"link_type": "dofollow",
"max_links": 2,
"content_by": "buyer",
"min_word_count": 800,
"turnaround_days": 7
}]
}],
"next_cursor": "25"
} Also useful: GET /sites/:id, GET /categories (the exact category
values with live counts), GET /publishers and GET /publishers/:slug.
Placing an order
POST /orders with the site, the offer, your target/anchor pairs, and, when the
offer says content_by: "buyer", the full article inline (markdown or HTML, up
to 256 KB). We store it and hand it to the publisher.
curl -X POST https://linkbuildingapi.com/api/v1/orders \
-H "Authorization: Bearer lbk_live_YOUR_KEY" \
-H "Content-Type: application/json" \
-d '{
"site_id": "9be4...",
"offer_id": "1f77...",
"items": [
{ "target_url": "https://yoursite.com/pricing", "anchor_text": "pricing software" }
],
"content": { "format": "markdown", "body": "# The full article..." },
"instructions": "Please keep the intro vendor-neutral."
}' A 201 returns the order with a ref_code and status: "pending". Validation failures return 422 with codes like too_many_links, content_required, or content_not_accepted, so agents can self-correct.
Order lifecycle
pending ──accept──▶ accepted ──publish──▶ published ──confirm──▶ completed
│ │
├── reject / cancel (buyer) └── auto-completes after 7 days
└── expires after 7 days (no response) - Publishers have 7 days to accept or reject, or the order expires.
- Accepting starts the turnaround clock (
due_at). Late publishing is recorded on the order aslate_days. - Once published, you have 7 days to review; then it auto-completes.
- Poll
GET /orders/:idfor status plus the full event timeline, or register a webhook (below) for pushes. Polling every few minutes sits comfortably within the rate limit.
Buyer actions: POST /orders/:id/cancel (while pending), POST /orders/:id/complete (confirm the live link).
Webhooks
Instead of polling, set a webhook URL in Settings. Every order event you are a party to (as buyer or publisher) is POSTed to it the moment it happens:
POST https://yourapp.com/webhooks/linkbuildingapi
X-LBA-Event: order.published
X-LBA-Signature: sha256=8f3a... // HMAC-SHA256 of the raw body,
// keyed with your signing secret
{
"event": "order.published",
"sent_at": "2026-07-16T03:00:00.000Z",
"your_role": "buyer",
"order": { ...same shape as GET /orders/:id, items included... }
} Events: order.created, order.accepted, order.rejected, order.published, order.completed, order.auto_completed, order.cancelled, order.expired, plus ping from the test button.
- Verify the signature by recomputing the HMAC over the exact raw request body with your signing secret before trusting a payload.
- Delivery is one attempt with a 10 second timeout and no retries. Treat webhooks as a nudge;
GET /orders/:idstays the source of truth. - Respond with any 2xx quickly; do your processing after you have acknowledged.
MCP server
The marketplace is also a native MCP server, so agent frameworks get every capability as tools without touching HTTP themselves. Two ways to connect:
- OAuth (easiest): add
https://linkbuildingapi.com/mcpas a remote server in clients that support OAuth (claude.ai connectors, Claude Code, and friends) and approve the browser prompt. Dynamic registration, PKCE, refresh tokens: all handled. - API key header: for clients configured by hand or headless environments.
# Claude Code
claude mcp add --transport http linkbuildingapi https://linkbuildingapi.com/mcp --header "Authorization: Bearer lbk_live_YOUR_KEY"
# Generic client config (Cursor, Windsurf, etc.)
{
"mcpServers": {
"linkbuildingapi": {
"url": "https://linkbuildingapi.com/mcp",
"headers": { "Authorization": "Bearer lbk_live_YOUR_KEY" }
}
}
} Tools mirror the REST API and respect your key's scopes: search_sites, get_site, list_categories, list_publishers, get_publisher, create_order, get_order, list_orders, cancel_order, complete_order, plus the
publisher side: accept_order, reject_order, publish_order. Validation errors come back with the same machine codes as the
API, so an agent can correct itself and retry.
Fulfilling (publishers)
Publishers can run their side by API too, with a fulfill-scoped key:
# accept
curl -X POST https://linkbuildingapi.com/api/v1/orders/ORDER_ID/accept \
-H "Authorization: Bearer lbk_live_YOUR_KEY"
# reject with a reason
curl -X POST https://linkbuildingapi.com/api/v1/orders/ORDER_ID/reject \
-H "Authorization: Bearer lbk_live_YOUR_KEY" \
-H "Content-Type: application/json" \
-d '{ "reason": "We do not link to this niche." }'
# submit the live URL
curl -X POST https://linkbuildingapi.com/api/v1/orders/ORDER_ID/publish \
-H "Authorization: Bearer lbk_live_YOUR_KEY" \
-H "Content-Type: application/json" \
-d '{ "published_url": "https://example-tech-blog.com/your-post" }' List incoming work with GET /orders?role=publisher&status=pending. Email
notifications fire on every transition regardless.
OpenAPI spec
A machine-readable OpenAPI 3.1 document lives at /api/v1/openapi.json (no auth required). Point your agent or codegen at it.
Built by Tideworthy, the agentic SEO platform. Questions: adam@seobrothers.co