API Documentation

Comprehensive guide to using the PhishStats API for accessing phishing data

API use is subject to tier quotas and our Terms of Service (including acceptable use limits).

Base URL

https://api.phishstats.info/api/phishing

Authentication & API keys

Read-only endpoints on api.phishstats.info are public, but daily quotas depend on how you authenticate. Anonymous traffic (no key) is limited to 50 requests/day per IP. Registered and paid tiers require a psk_* API key sent on every request.

  1. Sign in and create an API key (free accounts get 1 key; Premium 2; Enterprise 3).
  2. Copy the full key when shown. It is displayed only once.
  3. Send the key as a header on every programmatic call (see example below).
curl -H 'X-API-Key: psk_YOUR_KEY' \
  'https://api.phishstats.info/api/phishing?_sort=-id&_p=0&_size=100'

Alternative: Authorization: Bearer psk_… or query ?apikey=psk_… (header preferred). Subscribing to Premium or Enterprise does not upgrade anonymous IP traffic. You must send your key. Do not use _apikey=; that prefix is xmysql filter syntax.

Parameters

Filtering

_where=(field,operator,value)

Filter results based on field conditions

Operators

eq

equals

ne

not equals

gt

greater than

lt

less than

like

contains

and

logical AND

or

logical OR

Sorting

_sort=field

Sort by field (use -field for descending order)

Pagination

_p=page_number
(default: 1)
_size=records_per_page
(default: 20, max: 100)

Examples

Basic Queries

By ID

/api/phishing?_where=(id,eq,3296584)

Get specific record by ID

By ASN

/api/phishing?_where=(asn,eq,AS14061)

Get records from specific ASN

By IP Address

/api/phishing?_where=(ip,eq,148.228.16.3)

Get records from specific IP

By Country

/api/phishing?_where=(countrycode,eq,US)

Get records from specific country

By TLD

/api/phishing?_where=(tld,eq,BR)

Get records with specific top-level domain

Advanced Queries

Latest by Date

/api/phishing?_sort=-date

Get most recent records

Title Contains "apple"

/api/phishing?_where=(title,like,apple)&_sort=-id

Search for records with "apple" in title

URL Contains "login"

/api/phishing?_where=(url,like,login)&_sort=-id

Search for records with "login" in URL

Title OR URL Contains "bank"

/api/phishing?_where=(title,like,bank)~or(url,like,bank)&_sort=-id

Search for "bank" in either title or URL

Score > 5 and Country ≠ BR

/api/phishing?_where=(score,gt,5)~and(countrycode,ne,BR)&_sort=-id

High score records not from Brazil

High Score with .com TLD

/api/phishing?_where=(score,gt,8)~and(tld,eq,com)&_sort=-date

High confidence .com domains

Complex Query

/api/phishing?_where=(countrycode,eq,BR)~and(url,like,login)~and(score,gt,4)&_sort=-date

Brazilian login pages with score > 4

Pagination Examples

Page 1, 50 Results

/api/phishing?_p=1&_size=50

Get first 50 records

Page 2, 100 Results

/api/phishing?_p=2&_size=100

Get next 100 records

Recent .xyz Domains

/api/phishing?_where=(tld,eq,xyz)&_sort=-date&_p=1&_size=100

Latest 100 .xyz domain records

Rate Limits

Limits depend on your plan. Anonymous API access is capped at 50 requests per day per IP. Registered free users get 150 API requests per day with an API key, plus per-minute burst limits. Premium and Enterprise plans offer higher daily quotas. See our Pricing page for details. All daily quotas reset at UTC midnight.

PhishStats has offered free API access since 2018. Tiered limits fund infrastructure while keeping research access free. Register for a key before upgrading if you need more than 50 requests/day.

Tier API requests / day Burst (approx.)
Anonymous (no API key)50 / IP20 / min
Free (registered + API key)150120 / min
Premium1,000Higher burst
Enterprise10,000Higher burst

Authenticate with X-API-Key: psk_… or Authorization: Bearer psk_…. Create keys at Settings → API keys after signing in. Prefer webhook monitoring over polling. See Monitoring alerts.

Query-string auth is supported as ?apikey=psk_… (no underscore). Do not use _apikey=. That prefix is xmysql filter syntax, not API authentication. Premium and paid tiers only apply when a valid psk_* key is sent; unauthenticated requests stay on the anonymous 50/day IP limit.

Handling HTTP 429

When you exceed burst or daily limits, the API returns HTTP 429 Too Many Requests. Responses include a human-readable error field and structured metadata to help clients back off or upgrade.

Limit types

  • burst: too many requests per minute; spread traffic or retry after Retry-After.
  • anonymous_daily: 50/day without an API key; register for 150/day free.
  • daily: API-key daily quota exhausted; upgrade or wait until UTC midnight.

Example: anonymous daily limit

HTTP/1.1 429 Too Many Requests
Content-Type: application/json

{
  "error": "Anonymous daily limit reached (50/day). Register free at phishstats.info for 150 API requests/day with an API key. Quota resets at UTC midnight.",
  "limit_type": "anonymous_daily",
  "limit": 50,
  "register_url": "https://phishstats.info/settings/api-keys",
  "upgrade_url": "https://phishstats.info/pricing",
  "monitoring_url": "https://phishstats.info/settings/monitoring",
  "docs_url": "https://phishstats.info/api-docs",
  "quota_resets_at": "2026-06-19T00:00:00.000Z"
}

Example: burst rate limit

HTTP/1.1 429 Too Many Requests
Content-Type: application/json

{
  "message": "API rate limit exceeded (20/min). Spread requests across time, or upgrade at https://phishstats.info/pricing."
}

Kong burst responses use the message field; daily quota responses use error plus the fields above.

Example: daily quota (API key)

HTTP/1.1 429 Too Many Requests
Content-Type: application/json

{
  "error": "Daily API quota reached (150/day). Quota resets at UTC midnight. Upgrade at https://phishstats.info/pricing for higher limits, or use webhook monitoring at https://phishstats.info/settings/monitoring instead of polling.",
  "limit_type": "daily",
  "limit": 150,
  "register_url": "https://phishstats.info/settings/api-keys",
  "upgrade_url": "https://phishstats.info/pricing",
  "monitoring_url": "https://phishstats.info/settings/monitoring",
  "docs_url": "https://phishstats.info/api-docs",
  "quota_resets_at": "2026-06-19T00:00:00.000Z"
}

Client recommendation: honor Retry-After, cache results, avoid polling more often than our 90-minute data refresh cycle, and use monitoring webhooks for term-based alerts instead of repeated API queries.

Support

For any questions or support regarding the API, please send an email to [email protected]