Skip to main content

Error shape

Every failure returns a JSON body with a single error field:

Status codes

A brand outside your organization returns 404 rather than 403. Whether an id exists somewhere else in 3RD is not something a key is entitled to learn, so the two cases are deliberately indistinguishable.

Rate limit

100 requests per minute. At 1,000 rows per page that is up to 100,000 rows a minute, which is far more than a daily sync needs. The budget is counted per calling host, not per API key, so several integrations running from the same server share it. On 429, back off and retry. Exponential backoff starting around a second, with jitter, is enough — the window is one minute, so a retry after the window resets always succeeds.

Writing a resilient sync

  • Retry 429 and 5xx; do not retry 400, 401, or 404. Those mean the request itself is wrong and will fail identically forever.
  • Do not treat a short result as an error. A brand with no data for a period returns 200 with an empty data array.
  • Watch for null. brand_mentioned on /citations is null when the page was never scraped, or blocks our crawler. That is not the same as false, and charting it as false overstates the negative case.
  • Log meta.plan and meta.fromDate. When a sync suddenly returns fewer days than yesterday, a plan change is the usual cause.