Search by task, endpoint, field, or error.
Make your first request.
Parse your User-Agent as JSON. No API key needed.
curl https://api.parseapi.com/useragentRequest
Send a GET request to https://api.parseapi.com. The path names the lookup, query parameters adjust it, and the response is JSON.
A path such as /email/{email} is a template. Replace the braces and their contents with your value. URL-encode values containing spaces or reserved characters.
Add ?pretty=true for formatted JSON.
Response
A successful request can answer that an input is invalid. For example, Phone and IBAN can return 200 with valid: false when parsing or a checksum fails. Email rejects malformed addresses with 400. Check the fields as well as the HTTP status.
- false
- A negative answer to that field's question.
valid: falsedoes not mean the request failed. - null
- No answer is available for that field. Keep it distinct from
false, zero, or an empty string. - Omitted
- The field is not part of this response. For example,
deepis absent unless requested.
Each endpoint explains its fields, supported inputs, and coverage. Handle missing answers explicitly and allow new fields to be added to the response.
Authentication
Send your API key with the X-API-Key header, the same key you create in the dashboard. No token exchange or refresh step is needed.
X-API-Key: YOUR_API_KEYThe bare /ip and /useragent self-lookups also work without a key. Use a key for other lookups.
Authorization: Bearer works too. Same key, either header. Use whichever your client or SDK defaults to.
Authorization: Bearer YOUR_API_KEYcurl "https://api.parseapi.com/ip/8.8.8.8" \
-H "X-API-Key: YOUR_API_KEY" \
-H "Parse-Version: 2.0.0"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.
1. Install
npm install @parseapi/sdk2. Add your key
Create a secret key in Keys. Set it in the terminal that will run the example. Keep it on your server.
export PARSEAPI_KEY='YOUR_API_KEY'3. Make a request
Look up a country and print its name. This lookup uses your plan's request allowance.
import { parseAPI } from '@parseapi/sdk';
const parse = parseAPI(); // Reads PARSEAPI_KEY.
const country = await parse.country('US');
console.log(country.name);node example.mjsHandle errors by code, such as invalid_api_key or not_found. A response with valid: false is a successful lookup.
Handle API errors in your app
The same request, with a handler for API errors. Transport failures still propagate.
import { parseAPI, ParseAPIError } from '@parseapi/sdk';
const parse = parseAPI(); // Reads PARSEAPI_KEY.
try {
const country = await parse.country('US');
console.log(country.name);
} catch (error) {
if (error instanceof ParseAPIError) {
console.error(error.code, error.status, error.requestId);
}
throw error;
}MIT licensed, source on GitHub.
Headers
Authenticated requests send 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: 42X-Served-From is the edge that answered, where in plain language (Virginia, Tokyo, …), so you can see where your request was answered.
Error bodies include that same request_id, copy it from Activity in the dashboard if you contact support.
The Parse-Version response header identifies the API version that answered. Send an optional Parse-Version request header to pin your application to a supported contract. Requests that omit it use the team setting in Settings → API version. Your authentication and lookup URL stay the same.
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 check the calling page against the domains you list. They are designed to be included in browser code. 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.
1. Install
Add the ParseAPI product to your app target. In Xcode, you can also add the repository URL through Add Package Dependencies.
.package(url: "https://github.com/parseapi/swift", from: "1.4.0")2. Add your key
Create an app key in Keys and allow your bundle identifier. Replace parse_app_... below. The SDK sends your bundle identifier automatically. Use your server for metered checks.
3. Make a request
Look up a country and print its name. This lookup uses your plan's request allowance.
import ParseAPI
func loadCountry() async throws {
let parse = try ParseAPI("parse_app_...")
let country = try await parse.country("US")
print(country.name)
}
// Call from your app's async task.
// try await loadCountry()Handle errors by code, such as invalid_api_key or not_found. A response with valid: false is a successful lookup.
Handle API errors in your app
The same request, with a handler for API errors. Transport failures still propagate.
import ParseAPI
func loadCountry() async throws {
let parse = try ParseAPI("parse_app_...")
do {
let country = try await parse.country("US")
print(country.name)
} catch let error as ParseAPIError {
print(error.code, error.status, error.requestId ?? "")
throw error
}
}
// Call from your app's async task.
// try await loadCountry()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.
Email and VAT behave differently: on an app key, ?deep=true returns the core result plus deep: {}, with no verification charge. Run those deep checks from your server with a secret key.
Archive a key in the dashboard to stop further use. Allow a few seconds for the change to take effect.
Usage and metered lookups
Every plan pools a monthly request allowance across the APIs. New terms allow seven days of grace after the allowance is exceeded, ending sooner if the UTC calendar month resets. After grace, requests return quota_exceeded (429) until the month resets or an upgrade provides enough capacity. There are no automatic request overage charges. Existing teams keep their prior soft-limit policy until they switch plans. See your current terms in Dashboard → Plan.
Responses under the new monthly policy include X-Quota-Limit and X-Quota-Reset. X-Quota-Remaining reports the remaining requests when available; X-Quota-Grace-Until appears during grace. Reset and grace deadlines are UTC Unix timestamps in seconds. Monthly usage counts successful authenticated requests, including metered checks, and updates shortly after a response. These headers are separate from the per-minute rate limit.
Metered products have separate monthly allowances. Email and VAT meter deep checks. Carrier, Caller, and HLR meter the lookup itself. Free includes a limited allowance for these products, too.
When a metered allowance runs out, further checks require on-demand usage on an eligible plan. Enable it and set a shared monthly spending limit under Dashboard → Plan. Without available allowance or enabled on-demand usage, the check returns quota_exceeded. Basic Email and VAT checks work without ?deep=true while the monthly request allowance or grace period permits.
See Plans for included allowances and rates. Each endpoint explains what counts as a metered check.
Errors
Errors return a consistent JSON body: code, message, docs, and request_id.
rate_limited, server_error, and service_unavailable may be temporary. See Retries and timeouts before retrying. Other errors usually require a change to the request, key settings, or plan.
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": "lat and lon must be valid numbers",
"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. For an app key, check the exact app ID and whether the endpoint allows app keys. Call metered products from your server when using a mobile app. Read the response message before changing keys.
{
"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_…"
}api_version_retired 410
The version selected by your request header or team default is retired. Review the upgrade guide, test the matching response contract, then select a supported version in your application. For requests without a header, review the fallback in Settings → API version. Retrying the same version will not fix this error.
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_…"
}Retries and timeouts
Set a timeout and check the HTTP status before treating a response as data. For rate_limited, wait the number of seconds in Retry-After. Temporary connection failures and 500 or 503 responses can be retried with bounded backoff.
A timeout does not prove the original lookup was never processed. Repeating a metered check can consume another unit. Official SDKs default to no automatic retries for metered checks; choose an explicit retry policy if your application needs one.
Keep the error's request_id when debugging or contacting support. A 429 with quota_exceeded needs allowance or billing action; waiting a few seconds will not resolve it.
A server-side JavaScript example with a ten-second timeout and one attempt:
const response = await fetch('https://api.parseapi.com/ip/8.8.8.8', {
headers: { 'X-API-Key': 'YOUR_API_KEY', 'Parse-Version': '2.0.0' },
signal: AbortSignal.timeout(10_000),
});
const body = await response.json();
if (!response.ok) {
throw new Error(body.code + ': ' + body.message + ' (' + body.request_id + ')');
}
console.log(body);Run this JavaScript on your server. In a browser, use a public key restricted to your domain.
Deep responses
Add ?deep=true to request additional fields for the same lookup. Those fields live in a nested deep object. The route and its core fields stay the same.
- No ?deep=true
- The
deepkey is omitted. - deep: {}
- Requested, but no extra fields are included for this endpoint, plan, or key type.
- deep: { ... }
- Additional fields are included. Individual values may still be
null.
An empty object is truthy in JavaScript. Check the field you need explicitly, such as response.deep?.deliverable === true. The presence of deep alone does not mean a check succeeded.
Plan deep is included on paid plans for endpoints such as geography profiles, Name, NAICS, IP, Useragent, Domain, Weather, VIN, NPI and Tariff. Email and VAT deep use metered allowances, including the Free plan's included checks. These can return a quota error when no allowance is available.
Phone core returns validation and formats; ?deep=true adds numbering-plan location on every plan. Time, Date, Currency, Language, Emoji, IBAN and Point also offer optional detail on every plan. Carrier and HLR deep add detail within the same metered lookup, with no second unit. Use Carrier for the serving carrier, Caller for caller ID, or HLR for live status. Each is a separate metered lookup.
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?
Read
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.
- CountryCountry names, currency, languages, and timezones.
- StateA state or province by code or name, with timezones.
- DistrictA district by code or name, with its state and timezones.
- CityExact name, typeahead, nearest, or nearby cities.
- PostalA ZIP or postal code to its city, state, coordinates, and timezone.
- AddressA US address, checked against official records.
- PointCountry, state, district, and timezone at a coordinate.
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, and burner.
- CallerThe registered caller ID (CNAM) for a number.
- HLRAssignment and reachability at the last network check.
- VATChecksum a VAT number. Deep asks the live registry.
- IBANValidate an IBAN. Bank details in 100 countries and territories.
- DomainWhether a domain is available to register.
- DNSDNS record names, types, values, and remaining TTLs.
- MXMail exchange records for a domain.
- NPIA US provider, specialty, address, and registry status.
Decode
- ASNA network organization and recorded country from its ASN.
- MACA normalized MAC address, registered vendor, and address flags.
- UseragentDevice, OS, browser, and bot, from one header.
- CurrencyCurrency names and symbols, plus daily exchange rates.
- LanguageA language by ISO code, with name, script, and direction.
- BIN / IINCard issuer details with the matched prefix in every response.
- TimeLocal time, timezone lookup, and conversion.
- DateAn ISO date, validity, and Unix timestamp.
- 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 into year, make, model, and vehicle type.
- NAICSFind an industry by code or business activity.
Questions? Email