API reference

Errors

Every error is { "error": { "code", "message" } } with a matching HTTP status. Switch on code, never on the message. No error uses credits.

curl "https://api.publicadsapi.com/v1/google/ads?keywords=travel" \
  -H "authorization: Bearer $PADS_API_KEY"
400 Bad Request
{
  "error": {
    "code": "INVALID_INPUT",
    "message": "keywords is not a parameter of GET /v1/google/ads. It takes: advertiser_id, domain, country, format, surface, political, date_from, date_to, cursor, include.",
    "field": "keywords"
  },
  "credits_used": 0,
  "credits_remaining": null
}

Codes

codeHTTPWhenWhat to do
INVALID_INPUT400A parameter missing, malformed or not taken by that platform.Fix the parameter field names. Don't retry as it is.
INVALID_URL400A library URL we can't read.Check the library address. Don't retry as it is.
UNAUTHENTICATED401No Authorization: Bearer <key> header.Send Authorization: Bearer <key>.
INVALID_KEY401A key that is not ours, or was revoked.Use a current key from Keys.
QUOTA_EXCEEDED402No credits left this month for this call.Upgrade at upgrade_url, add a card at add_card_url, or wait for the 1st. Agents: give your user claim_url.
PAYMENT_REQUIRED402A paid plan whose latest invoice is unpaid.Pay the latest invoice at upgrade_url.
AD_NOT_FOUND404No ad with that id.Check the id. The ad may have been taken down: don't retry.
ENDPOINT_NOT_FOUND404No endpoint at that path.Check the path, e.g. /v1/meta/ads.
RATE_LIMITED429Over the key's requests a second.Wait Retry-After seconds, then retry.
UPSTREAM_BLOCKED503The platform blocked every attempt, on several connections.Wait Retry-After seconds (about a minute), then retry.
UPSTREAM_CHANGED502The platform's page changed and we couldn't read it.Retry later. We're alerted and fix it; meanwhile other platforms work.
TIMEOUT504The platform didn't answer within 60 seconds.Retry once; if it times out again, narrow the search.
BUSY503Every one of our browsers is busy.Wait Retry-After seconds (a few), then retry.
INTERNAL500Our fault.Retry once, then write to us with the X-Request-Id.

Retrying

  • Retry: RATE_LIMITED, BUSY and UPSTREAM_BLOCKED after the Retry-After header's seconds; TIMEOUT, UPSTREAM_CHANGED and INTERNAL once, after a pause. Back off if they repeat.
  • Don't retry: every other 4xx. The same request gets the same answer.
  • Nothing is charged for any error, a block or a timeout included, so a retry costs only the call that succeeds.
  • Set a 60 second timeout on your client. A live call can take 30 seconds or more when a platform blocks and we retry on new IPs; we answer 504 TIMEOUT at 60.

Other fields

FieldOnWhat it is
error.fieldINVALID_INPUTThe parameter at fault, as you named it.
error.upgrade_urlQUOTA_EXCEEDED, PAYMENT_REQUIREDWhere a person changes plan or pays.
error.add_card_urlQUOTA_EXCEEDED on FreeWhere to add a card and pay for each extra credit.
error.claim_urlQUOTA_EXCEEDED for an agentThe link an AI agent gives its user to claim the account.
credits_used, credits_remainingSearch and one ad0 used, and what is left this month.

Request ids

Every response to /v1 carries an X-Request-Id header. Put it in a message to support and we can find the call.