API access instructions

Step-by-step guide to accessing the FatGrid database via API, including authentication, endpoints, and available data.

What you can access

The FatGrid API gives programmatic access to our full database of domains with link placement pricing. All data is updated continuously.

The API is available to all FatGrid users.

  • All plans — API requests draw on the same unit balance as the in-app tools. See Units and rate limits below for what each endpoint costs.
  • Advanced and Business plans — additionally unlock the Orders endpoints for programmatic ordering.

Where to find your API key

Open Profile settings → General and press Generate API key. Keys are not created automatically, so every account starts without one.

Your key starts with glp_. It is shown once, at the moment you generate it — copy it straight into your integration or password manager. Afterwards the profile page shows only a masked version and the key cannot be recovered.

If a key is lost or leaked, press Rotate to replace it — the old key stops working immediately — or Revoke to switch API access off. Keys are stored hashed, so support cannot read yours back to you either.

Authentication

Every GET request requires a key query parameter. POST requests use an x-api-key header.

Base URL for all endpoints: https://api.fatgrid.com/api/public

# GET request (add key= to every request)
GET https://api.fatgrid.com/api/public?key=YOUR_KEY&type=...

# POST request (x-api-key header)
POST https://api.fatgrid.com/api/public/search-domains
x-api-key: YOUR_KEY

Units and rate limits

API calls consume units from your account balance:

  • domains_list — 1 unit per domain returned
  • domain_prices — 1 unit per lookup, whether or not the domain is found
  • search-domains — 1 unit per domain submitted
  • marketplaces_list — free
  • orders/availability — 1 unit per check
  • orders — 1 unit per order attempt

When your balance runs low, requests are trimmed rather than rejected: ask for 500 domains with 30 units left and you get 30 domains back. Only a fully exhausted balance returns an error.

Requests are also rate limited. Exceeding a limit returns 429 Too Many Requests, so space out bulk jobs rather than retrying immediately.

  • All endpoints above except orders — 3 requests per second
  • orders/availability — 10 requests per minute
  • orders — 5 requests per minute

Filter values

Filters that accept several values take them separated by commas, and a domain matches if it has any of them. Spaces around the commas are ignored. Spaces inside a value are fine but need URL encoding, for example categories=News%20and%20Media.

Case matters for three filters. categories and languages are matched case-insensitively. databases, niches and resources are matched exactly — use the values from the reference section verbatim. databases=US, niches=Casino and resources=collaborator all return nothing, while us, casino and collaborator.pro are correct.

1. Domains List

Returns a paginated list of domains available for guest posts or link insertions, with full pricing and metrics. This is the most used endpoint — ideal for bulk inventory pulls and filtered searches.

Required parameters

  • key — your API key
  • type — must be domains_list
  • page — page number, starting at 1
  • limit — domains per page, maximum 500

Optional filter parameters

  • minPrice / maxPrice — price range in USD
  • minDr / maxDr — Domain Rating range (0–100)
  • minAs / maxAs — Authority Score range (0–100)
  • minRefDomains / maxRefDomains — referring domain count
  • minTraffic / maxTraffic — traffic from the top country
  • minOrganicTraffic / maxOrganicTraffic — organic traffic from the top country
  • minTotalTraffic / maxTotalTraffic — combined traffic across countries
  • minTotalOrganicTraffic / maxTotalOrganicTraffic — total organic traffic
  • minMonthlyOrganicTraffic / maxMonthlyOrganicTraffic — lowest monthly organic traffic
  • createdAtFrom / createdAtTo — date the domain appeared on the platform, e.g. 2022-01-01
  • linkFollowdofollow or nofollow
  • offerTypeguest_post or link_insertion
  • sponsored1 for sponsored listings only, 0 for unsponsored only
  • isReachable1 for domains that currently resolve, 0 for unreachable ones
  • title — case-insensitive substring search on the site title
  • categories — comma-separated category names, not ids
  • niches — restrict to niche-accepting domains: casino, crypto, cbd, finance_and_trading, dating, adult, medicine
  • resources — filter by marketplace, e.g. collaborator.pro. Full names including the suffix; use private_seller for offers listed directly by site owners
  • languages — comma-separated language codes, e.g. en,es,fr
  • databases — country/region database code, e.g. us, uk, ca (see reference section for the full list)
# Basic request — first page, 100 domains
GET https://api.fatgrid.com/api/public?key=YOUR_KEY&type=domains_list&page=1&limit=100

# Filtered — dofollow guest posts with DR 40–70
GET https://api.fatgrid.com/api/public?key=YOUR_KEY&type=domains_list&page=1&limit=500
  &offerType=guest_post&linkFollow=dofollow&minDr=40&maxDr=70

Response fields

Each item in items contains:

  • id — internal domain ID
  • url — domain name
  • dr — Domain Rating (Ahrefs)
  • authorityScore — Authority Score (Semrush)
  • backlinks — total backlink count
  • refDomains — referring domain count
  • bestPrice — lowest available price across all marketplaces
  • currency — price currency (always USD)
  • traffic — session count
  • organicTraffic — organic search traffic
  • totalOrganicTraffic — total organic traffic
  • minMonthlyOrganicTraffic — minimum monthly organic traffic
  • totalTraffic — combined traffic figure
  • database — country/region database code
  • linkFollow — dofollow or nofollow
  • type — offer type: guest_post or link_insertion
  • title — site title (may be null)
  • language — primary language of the site
  • sponsored — whether the listing is sponsored
  • isProblematic — whether the domain is flagged as problematic
  • isReachable — whether the domain passed a reachability check
  • isVerifiedByPlatform — whether FatGrid has verified the site
  • categories — array of category strings
  • resourcesCount — number of offers in the resources array
  • createdAt — date the domain first appeared in the database
  • bestNichePrices — cheapest price per restricted niche, each with id, niche, price, currency

Each domain also includes a resources array with per-marketplace pricing. Each resource has:

  • id — resource listing ID
  • resource — marketplace name, or Private Seller for offers from individual site owners
  • type — offer type on this marketplace
  • price — the marketplace's own price
  • sellPrice — what you pay buying through FatGrid
  • currency — price currency
  • directBuy — whether direct purchase is available
  • publisherTypemarketplace or user
  • rating — marketplace rating score
  • priceUpdatedAt — when this price was last refreshed
  • source — direct URL to the listing on the marketplace (present for some marketplaces)
  • nichePrices — array of niche-specific prices, each with id, niche, price, sellPrice, currency

Pagination fields, inside the response's meta object:

  • currentPage — current page number
  • itemsPerPage — items returned per page
  • hasMore — true if more pages remain
  • totalItems — total number of domains matching your filters
# Paginate through the entire guest post inventory (all domains)
page = 1
all_domains = []

while True:
    url = (f"https://api.fatgrid.com/api/public?key=YOUR_KEY"
           f"&type=domains_list&page={page}&limit=500&offerType=guest_post")
    data = requests.get(url).json()
    all_domains.extend(data["items"])
    if not data["meta"]["hasMore"]:
        break
    page += 1

print(f"Total: {len(all_domains)} domains")

2. Domain Prices

Returns all marketplace listings for a single domain. Returns an empty array if the domain has no listings.

Required parameters

  • key — your API key
  • type — must be domain_prices
  • target — the domain name to look up

The response is an array with one entry per offer type. Each item has the same fields as the domains_list endpoint (url, dr, bestPrice, resources, etc.). Returns [] if the domain is not in the database.

GET https://api.fatgrid.com/api/public?key=YOUR_KEY&type=domain_prices&target=example.com

3. Search Domains (Batch Lookup)

Check a list of specific domains in a single request. Returns found domains with full pricing, marks missing and spam domains separately. Accepts up to 500 domains per request.

Method: POST
URL: https://api.fatgrid.com/api/public/search-domains
Header: x-api-key: YOUR_KEY
Content-Type: application/json

Request body

  • search — comma-separated string of domain names. Protocols, www. and paths are stripped for you
POST https://api.fatgrid.com/api/public/search-domains
x-api-key: YOUR_KEY
Content-Type: application/json

{
  "search": "domain1.com,domain2.com,domain3.com"
}

Response fields

  • entered — number of domains accepted from the request, and the number of units charged
  • found — number of domains found in the database
  • notFound — number of domains not found
  • notFoundItems — array of domain names not in the database
  • spam — number of blacklisted/spam domains
  • spamItems — array of spam domain names
  • items — array of found domain objects (same fields as domains_list)
  • meta — pagination metadata: totalItems, itemsCount, itemsPerPage, totalPages, currentPage

4. Marketplaces List

Returns the list of all integrated marketplaces and their last data refresh timestamp. Use this to verify data freshness. This request does not consume any units.

Required parameters

  • key — your API key
  • type — must be marketplaces_list

The response contains an items array and a total count. Each item has a name (marketplace domain) and fetchedAt (last update timestamp). The names are exactly the values the resources filter accepts.

GET https://api.fatgrid.com/api/public?key=YOUR_KEY&type=marketplaces_list

5. Orders

Place Assisted Purchase orders programmatically: we buy the placement from the cheapest available source on your behalf and deliver the live link.

These endpoints require an Advanced or Business subscription — other plans receive 403. They authenticate with the x-api-key header only; the key query parameter is not accepted here.

All amounts on the order endpoints are integer cents — 13100 means $131.00 — unlike the endpoints above, which return decimal prices.

Check availability and price

Method: POST
URL: https://api.fatgrid.com/api/public/orders/availability

Send the domain and the offer type you want. apPriceCents is the exact amount an order would charge, and niches lists the price for each restricted niche the publisher accepts. A domain that is not in our database, has no assisted purchase offer, or is on our spam list comes back as {"status": false}.

POST https://api.fatgrid.com/api/public/orders/availability
x-api-key: YOUR_KEY
Content-Type: application/json

{
  "domain": "example.com",
  "type": "guest_post"
}

# Response
{
  "status": true,
  "apPriceCents": 13100,
  "currency": "USD",
  "niches": [
    { "niche": "casino", "apPriceCents": 26200 }
  ]
}

Create an order

Method: POST
URL: https://api.fatgrid.com/api/public/orders

  • domain — required, the domain to publish on
  • type — required, guest_post or link_insertion
  • docUrl — required, an absolute URL including https:// that the publisher can open to get your content
  • niche — optional, one of the restricted niches, and only if the domain offers it

The order record is created before payment is attempted, so you always get an orderId back. What differs is the status, and whether you also get a paymentUrl.

POST https://api.fatgrid.com/api/public/orders
x-api-key: YOUR_KEY
Content-Type: application/json
Idempotency-Key: your-unique-string

{
  "domain": "example.com",
  "type": "guest_post",
  "docUrl": "https://docs.google.com/document/d/abc",
  "niche": "casino"
}

# Response — paid with the card on file
{ "status": "completed", "orderId": 1234 }

# Response — needs the buyer to finish paying
{
  "status": "payment_required",
  "orderId": 1234,
  "paymentUrl": "https://checkout.stripe.com/c/pay/cs_live_..."
}

Paying for an order

There is no card form in the API. We try to charge the card already saved on your FatGrid account, and when that is not possible we hand you a Stripe-hosted page to finish on. Four cases, and your integration only ever has to tell two of them apart:

  • You have a saved card and it goes throughstatus: completed, no paymentUrl. Nothing more to do.
  • You have no card saved yet — auto-charge is impossible, so we return status: payment_required with a paymentUrl. This is the normal first order on a new account.
  • Your card asks for 3-D Secure — the bank wants the cardholder present, which an API call cannot provide. We cancel that attempt and return status: payment_required with a paymentUrl where the cardholder can complete the challenge.
  • Your card is declined — same shape: status: payment_required with a paymentUrl, so a different card can be used.

So the rule for your code is simply: if paymentUrl is present, someone has to open it. Send it to whoever holds the card — by email, in your own UI, or as a link in your dashboard.

r = requests.post(
    "https://api.fatgrid.com/api/public/orders",
    headers={"x-api-key": API_KEY, "Idempotency-Key": str(uuid.uuid4())},
    json={
        "domain": "example.com",
        "type": "guest_post",
        "docUrl": "https://docs.google.com/document/d/abc",
    },
)

if r.status_code == 422:
    # Domain is not orderable — reason is not_in_inventory or no_assisted_offer
    raise SystemExit(r.json()["reason"])

order = r.json()

if order["status"] == "completed":
    print(f"Order {order['orderId']} paid with the card on file")
else:
    # 3-D Secure, a declined card, or no card saved yet.
    # The order exists but will not start until this page is completed.
    print(f"Order {order['orderId']} needs payment: {order['paymentUrl']}")

What happens on that page

The page is Stripe Checkout, hosted by Stripe, and accepts card payments. It stays valid for 24 hours. On success the buyer lands back on go.fatgrid.com/my-orders?apiOrder=success, and on cancel ?apiOrder=canceled.

The card is saved for next time. Paying through the hosted page stores the card on your FatGrid account and makes it the default, so later orders come back as completed without a link.

You can also set the card up before you start. Go to Profile settings → Billing and press Manage Billing — that opens the Stripe billing portal, where you can add a card, replace an expired one, or change which card is used. Do that first and even your first API order comes back as completed. The same tab lists the cards currently on file under Saved payment methods.

In practice the card paying for your subscription is already there, so most accounts never see payment_required at all — it turns up only when the bank asks for 3-D Secure, or the card is declined or expired.

When is the order actually placed

An order stays in created and is not sent to the publisher until its payment is authorised. Once it is, the order moves to order_submitted and work begins — whether the payment came from the saved card or from the hosted page.

Note that completed means authorised, not captured: the amount is held on the card and taken later, when the placement is delivered. A cancelled order releases the hold instead of refunding it.

The API has no order-status endpoint yet, so to follow an order after creation use My Orders in your FatGrid account. Keep the orderId from the response — it is the same number shown there.

Idempotency

Send an Idempotency-Key header — any unique string up to 128 characters — so a network retry cannot create a second order. The first response for a key is replayed for 24 hours.

Retrying while the original request is still running returns 409. If our deduplication store is briefly unavailable we return 503 instead of risking a duplicate charge; retry with the same key.

Order errors

  • 401 — missing or invalid x-api-key
  • 402 — no units left on your balance
  • 403 — your plan does not include ordering, or the account is not active
  • 409 — a request with the same Idempotency-Key is still being processed
  • 422 — the domain cannot be ordered (reason: not_in_inventory or no_assisted_offer), or the niche is not offered (reason: niche_not_available)
  • 429 — rate limit exceeded
  • 503 — deduplication store unavailable, retry with the same key

Error responses

All errors return JSON with message, error and statusCode fields.

  • Missing or invalid key — 400, message: "key must be a string"
  • Unrecognised key — 400, message: "Key is incorrect"
  • Invalid type value — 400, message lists the three valid values: domain_prices, domains_list, marketplaces_list
  • Missing required parameter — 400, message names the missing field
  • Limit exceeds 500 — 400, message: "limit must not be greater than 500"
  • Account blocked or inactive — 403, message: "Account is not active. Contact support if you believe this is an error."
  • Rate limit exceeded — 429

No units on your balance —

{
  "statusCode": 402,
  "error": "INSUFFICIENT_UNITS",
  "message": "Operation requires 1 units, but you have 0. Upgrade your plan or top up your balance.",
  "currentBalance": 0,
  "requiredUnits": 1
}

Reference data

Integrated marketplaces (14)

adsy.com, backlinked.com, bazoom.com, collaborator.pro, ereferer.com, guestpostlinks.net, linkpublishers.com, linksasaservice.com, linksmanagement.com, meup.com, prnews.io, prposting.com, serpzilla.com, whitepress.com

Call marketplaces_list for the live list. Add private_seller to the resources filter to include offers listed directly by site owners.

Restricted niches (7)

casino, finance_and_trading, crypto, adult, dating, cbd, medicine

Use these exact values in the niches filter parameter to find domains that accept content in these categories, and in the niche field when creating an order.

Country/region database codes (121)

Americas: us, ca, br, mx, ar, cl, co, pe, ve, ec, bo, py, uy, cr, gt, hn, sv, ni, pa, do, jm, tt, ht, bs, bz, gy
Europe: uk, de, fr, es, it, pl, nl, ru, ua, ro, cz, hu, bg, hr, rs, sk, si, lt, lv, ee, fi, se, no, dk, pt, gr, tr, be, ch, at, ie, by, al, ba, cy, is, lu, md, me, mt
Asia-Pacific: au, nz, in, jp, kr, sg, my, ph, th, id, vn, hk, tw, pk, bd, lk, bn, kh, kz, mn, np
Africa and Middle East: za, ng, gh, eg, ae, il, sa, dz, ao, am, az, bh, bw, cd, cm, cv, et, ge, jo, kw, lb, ly, ma, mg, mu, mz, na, om, qa, sn, tn, zm, zw, af

Languages

Site language is reported by the publisher, so the same language can appear either as an ISO code or as its English name — en and english, fr and french, de and german. To catch every site in a language, pass both forms, for example languages=fr,french.

Max Roslyakov

Max Roslyakov

Founder, FatGrid