# Searchwire

Search and SEO data for agents: keyword search volume, Google results, domain
registration status and name checks. Answers come from several suppliers and public
registries behind one key, one shared cache and one daily budget per key.

Auth: `Authorization: Bearer <key>`. Without a key, domain and name checks and
answers already in the cache work for 20 calls a day per IP. API calls are `POST`
with a JSON body and return JSON.

## Calls

### POST /v1/keywords/volume
`{"keywords": ["ai wiki", "living docs"], "country": "us", "language": "en"}`
Up to 1,000 keywords. Optional `"origins": ["clickstream"]` restricts which kind of
data may answer (see Provenance). Each item: `keyword, volume, cpc, competition (0-1),
monthly[]`, plus provenance.

### POST /v1/serp
`{"keyword": "ai wiki", "country": "us", "language": "en", "depth": 10, "source": "any"}`
Organic Google results as `items[]: {rank, url, domain, title}` and `observed_at`.
`source`: `"index"` = results already collected earlier (no live query is made),
`"live"` = fetched now, `"any"` (default) = collected results first, live if none.

### POST /v1/domains/check
`{"domains": ["example.dev", "example.com"]}` (up to 50). Registry data over RDAP:
`registered`, and when registered `registrar, created, expires, status[]`. Not registered
does not guarantee it can be bought at the standard price (reserved or premium names).

### POST /v1/names/check
`{"name": "pagenta", "tlds": ["com", "dev", "ai"], "country": "us"}`
One call for a product or brand name: domain status per TLD (default com, dev, ai,
io, app, co), GitHub account, npm package, and the name's search volume.

### GET /v1/account
Your balance, daily budget, and today's (UTC) spend, savings, cache hits and misses.
`POST /v1/account` with `{"daily_budget_usd": 2}` sets your own daily spending cap.

### Getting a key and credit
`POST /v1/billing/checkout` with `{"amount_usd": 10}` (10, 25, 50, 100 or 250) returns
`checkout_url` and `claim_url`. A person pays at `checkout_url`; then `GET claim_url`
returns the key (it keeps returning the same key, so keep it private). Send the
request with your key to add credit to that key instead. Credit never expires.

Example:

    curl -s "https://searchwire.dev/v1/keywords/volume" \
      -H "Authorization: Bearer $KEY" -H "content-type: application/json" \
      -d '{"keywords":["ai wiki","living docs"],"country":"us"}'

## How to use it well

1. Collect your candidate keywords first, then ask for all of them in one
   `/v1/keywords/volume` call per country and language (up to 1,000). One call with
   200 keywords costs a fraction of 200 calls with one.
2. Narrow down by volume, then call `/v1/serp` only for the few keywords worth a look.
3. Read `observed_at` on SERP answers: collected results can be weeks old. Ask
   `"source": "live"` only when you need today's ranking.
4. Reuse answers you already have; volumes change monthly. Set a daily budget on your
   key (`POST /v1/account`) before running agents in a loop.

## Provenance

Every answer carries `source` (the provider), `origin` (what kind of data it is),
`fetched_at` and `cached`. Origins: `google_ads` (Google Ads keyword data),
`clickstream` (clickstream or Bing Ads based volume, no Google data), `serp_index`
(Google results collected earlier), `live_scrape` (Google results fetched for this
request), `registry` (public registries: RDAP, GitHub, npm).

Which providers can answer depends on your key's licence scope: external keys only
receive public data and data from suppliers that allow resale.

## Price

Fresh data costs what it costs upstream plus 30%. Answers from the shared cache cost
30% of that. Domain, GitHub and npm checks are free. Each response's `cost` is what
the call cost you, and `saved` is what cache hits saved you. Upstream charges per
request plus per keyword, so one call with many keywords is far cheaper than many
calls with one: fresh volume is about $0.016 for 1 keyword and $0.03 for 100.

## Cache

Answers are cached and shared by every key. Freshness: keyword volume 30 days, Google
results 7 days, registered domains and names 1 day, unregistered domains 1 hour.
Add `?fresh=1` to refetch. Keywords are compared trimmed and lowercased; volume for
many keywords is fetched in one upstream request, so batch your keywords.

## Limits and errors

Each key has a daily budget in USD (UTC day), $5 unless you set it. Past it, or with
no credit left, paid providers are skipped; cached and free answers still work. An
item that no provider could answer carries `error` with the reason from each provider
tried; do not invent a value for it. HTTP 400 = bad request, 401 = unknown key,
429 = free limit without a key reached.
