API
The finder over REST: send one keyword, get a search id, then read the sites that keyword turns up for Amazon products, with the addresses each site publishes. The API is on the Agency plan at $79 a month. A key is created in the dashboard and shown once.
Use found contacts for individual, relevant outreach only. No bulk unsolicited email. You are responsible for CAN-SPAM, GDPR and CASL compliance.
Authentication
Send the key on every request as a Bearer token. x-api-key works too. A missing, unknown or revoked key is a 401 and nothing else runs.
Only the Agency plan may call the API. A key on any other plan is a 403 with this one sentence, whatever the plan: API needs the Agency plan.
A request refused with a 401, a 403 or a 429 writes no row, queues no job, and counts against nothing.
export AAF_API_KEY=the_key_from_your_dashboard
Start a search: POST /api/v1/searches
The body is one JSON object with one string, keyword. A 200 means the search is queued, not that it has finished. The answer carries the new id:
curl -X POST https://amazonaffiliatefinder.com/api/v1/searches \
-H "Authorization: Bearer $AAF_API_KEY" \
-H "Content-Type: application/json" \
-d '{"keyword": "camping cot"}'{
"searchId": "cm2q7v0e80000x9k4bq1hn3zt"
}A keyword is accepted when 2 to 60 characters are left after normalising: surrounding spaces trimmed, runs of spaces collapsed to one, letters folded to lower case. Only letters, numbers, spaces and hyphens may remain. Every other value, including a body that is not JSON or carries no keyword, is a 400 with the same sentence:
{
"error": "Enter 2-60 letters, numbers, spaces or hyphens"
}A 403 is the plan refusal above, word for word:
{
"error": "API needs the Agency plan"
}A 429 means an allowance is used up, and nothing was written or queued. The account has used the month:
{
"error": "You have used this month's searches."
}Or the service has used its search budget for the month:
{
"error": "Search capacity is used up for this month"
}Read a search: GET /api/v1/searches/{id}
The same Authorization header reads the search back. Poll it until status is done or failed.
export SEARCH_ID=the_searchId_from_the_POST_answer curl https://amazonaffiliatefinder.com/api/v1/searches/$SEARCH_ID \ -H "Authorization: Bearer $AAF_API_KEY"
The answer holds six fields: id, the id the POST answered; status, queued while the job waits, done when the rows are saved, and failed when the run ended with an error; keyword, the normalised keyword; siteCount, the number of sites kept; error, null unless the run failed; and rows, the sites themselves.
Each row is domain, the site; page, the ranking page that was fetched; rank, its best organic position across the queries; query, the query that found it; amazonLinks, how many Amazon product and short links the page carried; tags, the distinct Amazon associate tag values seen on the page, at most 5; and contacts, the addresses the page publishes, each with address, label and sourceUrl.
Only the key's own account reads a search. Another account's id, and an id that does not exist, get the same 404:
{
"error": "Search not found."
}The values below are illustrative; the field names are the ones the route sends:
{
"id": "cm2q7v0e80000x9k4bq1hn3zt",
"status": "done",
"keyword": "camping cot",
"siteCount": 1,
"error": null,
"rows": [
{
"domain": "example.com",
"page": "https://example.com/best-camping-cots",
"rank": 3,
"query": "best camping cot",
"amazonLinks": 4,
"tags": ["tag=example-20"],
"contacts": [
{
"address": "[email protected]",
"label": "Role address",
"sourceUrl": "https://example.com/contact"
}
]
}
]
}Download the CSV
GET /api/search/{id}/csv returns the same rows as a file, and a key may call it with the same header. The Agency plan includes the export. The header is exactly these columns, in this order: domain,page,rank,query,amazon_links,tags,contacts. Several tags or contacts values are joined with ; , and contacts holds the addresses only.
curl -OJ https://amazonaffiliatefinder.com/api/search/$SEARCH_ID/csv \ -H "Authorization: Bearer $AAF_API_KEY"
domain,page,rank,query,amazon_links,tags,contacts
Limits
- Agency covers 500 searches a month, shared with the searches the same account starts in the web app. A search counts when it finishes with at least one site: a failed search, and one that found nothing, are not counted. Neither is a request refused with a 429.
- A key may make 60 requests every 60 seconds, reads and new searches together, and the request over that ceiling is a 429 with a
Retry-Afterheader naming the wait in seconds. - A rate-limited request is never counted: it writes no row, queues no job and uses none of the month, so a retry after the wait costs the same as the request it repeats.
- The paid search calls behind a search come out of the service's monthly search budget. When the month's budget is used up, the POST is the 429 above, before any row is written.
- Every search a key starts belongs to its account, so it uses the same month and the same results the dashboard shows.
- Results are kept 30 days for an account.
What the API never does
It reads the search results for the keyword you send and the public pages of the sites it finds. The rows carry the Amazon links those pages show, never sales, traffic or earnings figures. It does not send anything to the addresses it returns, does not guess an address that no page publishes, and does not work around a page that refuses to be read. What it fetches, how often, and how to block it: the crawler page. The duties that stay with you are in the terms.