DoFollow.pro

Partner API v1

For approved resellers and agencies. Order guest posts on our publications, send articles and follow each link from your own system, at your partner prices.

Getting started

  1. Become a partner: apply here.
  2. Sign in at my.dofollow.pro/api and create a key. It is shown once.
  3. Send it on every request: Authorization: Bearer dfk_live_…

Base URL: https://api.dofollow.pro/v1 · JSON in and out · prices in USD.

curl https://api.dofollow.pro/v1/catalog?niche=tech&min_dr=30 \
  -H "Authorization: Bearer $DOFOLLOW_KEY"

Endpoints

GET/v1/meYour account, partner discount and rate limit.
GET/v1/catalogSites you can order, with your prices. Filters: niche, min_dr, limit (max 1000).
POST/v1/ordersCreate an order. Returns it with a pay_url.
GET/v1/ordersYour orders, newest first. Paging: limit (max 100), before_id.
GET/v1/orders/{id}One order with every post: status, live URL, link check.
POST/v1/orders/{id}/items/{item_id}/articleSend the article for one post: {"title", "html"} or {"gdoc_url"}.

Create an order

curl -X POST https://api.dofollow.pro/v1/orders \
  -H "Authorization: Bearer $DOFOLLOW_KEY" \
  -H "Content-Type: application/json" \
  -H "Idempotency-Key: client-42-batch-7" \
  -d '{
    "client": "Acme Corp",
    "reference": "PO-1182",
    "items": [
      {"site": "example-site.com", "tier": "general",
       "target_url": "https://acme.com/pricing", "anchor": "acme pricing"}
    ]
  }'

Post statuses

pending (waiting for article or payment) → writing (with the editor) → published (live_url set; link checked daily, link_ok) · or removed.

Webhooks

Set an https address at my.dofollow.pro/api. Events:

order.paidPayment received; work starts.
order.cancelledThe order was cancelled.
item.liveA post is published. Includes live_url.
item.link_failedThe daily check could not find your link. Repeats weekly while it stays missing; we fix these.
{"id": "evt_…", "type": "item.live", "created": "2026-10-21T10:00:00+00:00",
 "data": {"order_id": 51, "item_id": 133, "reference": "PO-1182", "site": "example-site.com",
          "live_url": "https://example-site.com/…", "published_at": "…"}}

Verify the signature

Header X-DoFollow-Signature: t=<unix time>,v1=<hex>, where v1 is HMAC-SHA256 of "<t>." + raw body with your signing secret. Reject old timestamps (e.g. over 5 minutes) and use a constant-time compare.

import hmac, hashlib, time
def valid(secret, header, body: bytes):
    parts = dict(p.split("=", 1) for p in header.split(","))
    if abs(time.time() - int(parts["t"])) > 300: return False
    mac = hmac.new(secret.encode(), f"{parts['t']}.".encode() + body, hashlib.sha256).hexdigest()
    return hmac.compare_digest(mac, parts["v1"])

Reply with any 2xx within 10 seconds. Otherwise we retry after 1 min, 5 min, 30 min, 2 h, 6 h and 12 h (8 attempts in all). Redirects are not followed. Events may arrive more than once or out of order: use id to de-duplicate.

Limits and errors

120 requests a minute per key · 30 new orders an hour · 200 posts per order · 200 KB per article.

Errors look like {"error": {"code": "…", "message": "…"}} with status 400, 401 (bad key), 403 (not a partner), 404, 409 (post already published), 413, 422 or 429.

DoFollow.pro is a brand of iPressly LLC.