Agent-first API

The board was built to be read by something that is not a browser. Everything a person can see, an agent can fetch — and everything a person can submit, an agent can submit.

https://instantdofollow.com reads need no key writes are rate-limited per IP and per domain
MCP tools

Five, deliberately. Point an agent at https://instantdofollow.com/mcp and it can work the board end to end.

submit_tool Put a product website into the review queue. Returns an id, an edit URL, and the state it landed in. url · category? · name? · description? · dofollow: "badge" | "fee" | "wait"
search_tools Search live listings by text and category. Ranked by recency — payment never affects ranking. q? · category? · rel? · limit = 20 · cursor?
get_tool One listing in full: description, category, click count, link state, day count. id | slug
check_listing Where a submission stands: preliminary, in_review, live, or rejected with the rule it hit. id | url
list_categories The fourteen categories and how many live listings each holds. no arguments
claude mcp add --transport http instantdofollow https://instantdofollow.com/mcp

Or the config file, for a client that reads one:

{ "mcpServers": { "instantdofollow": { "url": "https://instantdofollow.com/mcp" } } }
Submit over HTTP

A listing is always created before any payment, so an abandoned checkout never leaves money without a listing. Choose "fee" and the response carries a checkout_url.

curl -X POST https://instantdofollow.com/api/submit \
  -H "content-type: application/json" \
  -d '{"url":"https://yoursite.com","category":"saas","dofollow":"wait"}'

{ "id": "idf_9f2ac41b",
  "slug": "yoursite",
  "state": "in_review",
  "rel": "nofollow",
  "edit_url": "https://instantdofollow.com/e/<token>" }

The edit URL is the only key to the listing — it is shown once and stored only as a hash. Errors name the rule they hit: 422 with a rule id, 409 for a duplicate domain, 429 over the rate limit.

Read the board
GET https://instantdofollow.com/api/listings?category=saas&q=onboarding&limit=20

{ "listings": [
    { "slug": "trailhead",
      "name": "Trailhead",
      "url":  "https://trailhead.dev",
      "category": "saas",
      "state": "live",
      "rel": "nofollow",
      "day": 22,
      "clicks": 18,
      "og_image": "https://trailhead.dev/og.png",
      "listed_at": "2026-08-02T09:14:00.000Z" } ],
  "next": null }

Paging is a keyset cursor, not an offset, so a page never skips or repeats a listing while the board moves underneath it. rel and day are computed per request and never stored — dofollow after ninety days live and unchanged.

Machine-readable
/llms.txt Compact index of every listing, one line each.
/llms-full.txt Full descriptions, for models with room to spare.
/t/<slug>.md A Markdown mirror of every listing page.
/api/openapi.json OpenAPI 3.1 for the three JSON routes.

Every listing page carries JSON-LD SoftwareApplication. None carries an AggregateRating, and none ever will — Google prohibits aggregating ratings collected from other sites, and one structured-data penalty would cost every listing here its value at once.