Docs
Introduction
All responses are minimal JSON. Add ?deep=true on a paid plan for richer fields, see Deep below for specifics.
Base: https://api.parseapi.com
Machine-readable: openapi.json (OpenAPI 3.1), or copy for agents.
State and postal require ?country=, codes are not globally unique.
Add ?pretty=true to any request for formatted JSON, handy in a browser or terminal.
Authentication
Send your API key on every request with the X-API-Key header, a static secret, not a token. Set the header and call the endpoint. That is the whole flow.
X-API-Key: YOUR_API_KEY
Authorization: Bearer works too. Same key, either header. Use whichever your client or SDK defaults to.
Authorization: Bearer YOUR_API_KEY
curl "https://api.parseapi.com/ip/8.8.8.8" \
-H "X-API-Key: YOUR_API_KEY"SDKs
Official clients. One method per endpoint, named after the route, same fields as the raw API. Swift and Kotlin take an app key and send the bundle ID. A language we don't have? Plain HTTP works everywhere, see Authentication above. AI agents get the same lookups as tools, see MCP.
npm install @parseapi/sdk
import { parseAPI } from '@parseapi/sdk';
const parse = parseAPI('YOUR_API_KEY');
const country = await parse.country('US');MIT licensed, source on GitHub.
Headers
Every request sends X-API-Key or Authorization: Bearer (see Authentication above). Optionally send your own X-Request-Id for tracing. We echo it back, or generate one (e.g. req_...) if you don't.
X-API-Key: YOUR_API_KEY X-Request-Id: req_01hxyz…
Authenticated responses include X-RateLimit-Limit, X-RateLimit-Remaining, and X-RateLimit-Reset, your per-minute limit, calls left in the current window, and seconds until it rolls over. Separate from your monthly quota. On rate_limited (429), Remaining is 0 and a Retry-After header (seconds) tells you exactly how long to back off.
X-Request-Id: req_01hxyz… X-Served-From: Virginia X-RateLimit-Limit: 60 X-RateLimit-Remaining: 59 X-RateLimit-Reset: 42
X-Served-From is the edge that answered, where in plain language (Virginia, Tokyo, …), so you can feel where the request landed.
Error bodies include that same request_id, copy it from Activity in the dashboard if you contact support.
API keys
Create and archive keys in the dashboard. Keys start with parse_. Use a separate one per environment, dev, staging, prod.
Keep secret keys server-side. Call parseAPI from your backend, not from browser code or a public repo.
Need to call from a browser? Create a public key instead. Public keys start with parse_public_ and only work from domains you list, so shipping one in your page source is the point, not a leak. Same header, same responses, same limits.
fetch('https://api.parseapi.com/email/hi@example.com', {
headers: { 'X-API-Key': 'parse_public_...' }
})Add example.com and it covers every subdomain too. Add localhost to the list for local development. Metered calls like deep email verification work on public keys and count against your plan, so keep those server-side unless you mean it.
Shipping a native app? Create an app key and use the Swift or Kotlin SDK. App keys start with parse_app_. List your iOS bundle ID or Android package name on the key. The SDK sends it as X-App-Id on every request.
.package(url: "https://github.com/parseapi/swift", from: "0.1.0")
import ParseAPI
let parse = try ParseAPI("parse_app_...")
let country = try await parse.country("US")App IDs match exactly, com.example.weather does not cover com.example.weather.widget. App keys cover lookups and plan deep. Metered endpoints like /carrier and /hlr answer 403 on an app key, call those from your server with a secret key.
Archiving a key stops it within a few seconds.
Usage
Every plan pools a monthly request quota across all APIs. Cross it and nothing breaks, it's a soft limit, not a cutoff. We email you at 80%, 100%, and 120%, so you see it coming instead of finding out in production.
Deep email verification and phone lookups have their own included monthly quota. Deep stops for that API once it is used, everything else keeps running, and you are never billed unless you turn it on yourself. Enable on-demand billing under Dashboard → Plan to keep deep calls going past your quota, capped at whatever you set.
Track usage in the dashboard.
Errors
Errors return a consistent JSON body: code, message, docs, and request_id.
rate_limited, server_error, and service_unavailable are worth retrying with backoff. Everything else means the request needs a fix, not a retry.
invalid_api_key 401
Missing or bad key. Check X-API-Key or Authorization, or grab a key from Dashboard → Keys.
{
"code": "invalid_api_key",
"message": "Invalid or missing API key",
"docs": "https://parseapi.com/docs#invalid_api_key",
"request_id": "req_…"
}invalid_request 400
Missing or invalid input. message names the exact field, fix it and resend.
{
"code": "invalid_request",
"message": "Invalid email address",
"docs": "https://parseapi.com/docs#invalid_request",
"request_id": "req_…"
}permission_denied 403
Your key can't perform this action. On a public key with Domain not allowed for this key, the page calling isn't on the key's domain list, add it in Dashboard → Keys. Otherwise, generate a fresh key there.
{
"code": "permission_denied",
"message": "Permission denied",
"docs": "https://parseapi.com/docs#permission_denied",
"request_id": "req_…"
}plan_required 403
This team needs its own paid plan. Subscribe it under Dashboard → Plan.
{
"code": "plan_required",
"message": "This team needs a paid plan to use the API",
"docs": "https://parseapi.com/docs#plan_required",
"request_id": "req_…"
}not_found 404
No match, or an unknown route. message names exactly what wasn't found, check the path and value.
{
"code": "not_found",
"message": "Postal code not found: 00000 (US)",
"docs": "https://parseapi.com/docs#not_found",
"request_id": "req_…"
}rate_limited 429
Too many requests in a short window. Back off and retry after Retry-After seconds, see Headers for your live limit and reset countdown.
{
"code": "rate_limited",
"message": "Rate limited",
"docs": "https://parseapi.com/docs#rate_limited",
"request_id": "req_…"
}quota_exceeded 429
A monthly allowance is exhausted. Wait for reset, or turn on on-demand billing under Dashboard → Plan.
{
"code": "quota_exceeded",
"message": "Monthly email verification limit reached. Basic validation still works without ?deep=true.",
"docs": "https://parseapi.com/docs#quota_exceeded",
"request_id": "req_…"
}server_error 500
Something broke on our side. Retry, if it keeps happening, email Email with your request_id.
{
"code": "server_error",
"message": "Server error",
"docs": "https://parseapi.com/docs#server_error",
"request_id": "req_…"
}Deep
Every endpoint returns a full, useful core response on every plan. Free included. Add ?deep=true and paid plans get that same response back, plus one more field: a nested deep object with richer data for the same lookup. There's no separate paid endpoint to learn, same route, same core fields, one param away from more.
Deep fields only ever live inside deep, never mixed into the fields above it. That's deliberate: your code can check if (response.deep) and always know what it got, and we can ship new deep fields later without ever changing what the core response looks like. Nothing built against core breaks when deep grows.
GET /ip/52.94.76.10?deep=true
{
"ip": "52.94.76.10",
"country": "US",
"country_name": "United States",
"continent": "NA",
"asn": "AS16509",
"asn_name": "Amazon.com, Inc.",
"deep": {
"state": "OR",
"city": "Boardman",
"datacenter": true,
"provider": "aws"
}
}It's opt-in on every call, not a plan-wide switch. Leave off ?deep=true and a paid key gets the exact same lean response as a free one, same fields, same latency, every time.
Supported on IP, email, VAT, useragent, phone, and domain. Continent, country, state, city, postal, currency, timezone, elevation, emoji, and MX already return their full payload, there's nothing extra for deep to add there.
For most of those, deep just returns data we already hold, gated by plan. Email and VAT are the exceptions, each runs a live check (mailbox deliverability, EU registry), so each draws from its own monthly allowance on your plan (100 on Free).
APIs
Grouped by what they answer. Locate: where is this? Measure: how high, how many, how hot? Validate: is this real? Decode: what does this mean?
Locate
- IPWhere an IP is from, country, ASN, network.
- ContinentA continent by code, or every country in it.
- BlocA country group by code, or every member in it.
- CountryA country by code or name. Currency, timezones, plugs, tax, states.
- StateA state or province by code or name. Capital, tax, area codes, timezones.
- DistrictOne district by code or name. Seat, timezones, area. US, FR, GB.
- CityExact name, typeahead, nearest, or nearby. Type, capital, district, elevation, id.
- PostalA postal or ZIP. City, state, area, coordinates. Country when the code collides.
- AddressA US address, checked against official government records.
- PointEverything at a latitude/longitude: elevation, country, state, district.
Measure
Validate
- NameA person's name, split, cased, and checked.
- EmailFormat, domain, role, and a typo suggestion, on every call.
- PhoneValidate and format a number. 245 countries and regions.
- CarrierWho serves a number: carrier, line type, burner.
- CallerThe registered caller ID (CNAM) for a number.
- HLRLive phone number status from the mobile network.
- VATChecksum a VAT number. Deep asks the live registry.
- IBANChecksum an IBAN. Country, bank name, BIC, and account codes out.
- DomainWhether a domain is available to register.
- MXMail exchange records for a domain.
- NPIAny NPI in the registry. Provider, specialty, Medicare enrollment.
Decode
- UseragentDevice, OS, browser, and bot, from one header.
- CurrencyA currency by ISO code, plus daily exchange rates.
- LanguageA language by ISO 639 code, name, script, direction.
- TimezoneThe zone at a point, or look up an IANA id.
- DateAny date format in. ISO, weekday, and week number out.
- HolidayPublic holidays by country and year, or check one date.
- EmojiBy character, shortcode, name, or search.
- TariffUS import duty. An HTS code in. The rate and the measures that hit it.
- VINDecode a VIN. Year, make, model, engine, and plant out.
Questions? Email