Email and phone
Last updated:
Get a person's business email addresses or phone numbers by profile id — Verified email and Verified phone number. You pay only when we hold one.
/v1/profiles/{id}/email/v1/profiles/{id}/phoneAuthenticated with your x-api-key. See Authentication.
How it works
Pass a profile id — the same id a search result carries — to get that person's Verified email (/email: every business email address we hold) or Verified phone number (/phone: up to 3 numbers, best first).
You pay only when we hold one. A person we hold nothing for returns a 200 with has_email: false / has_phone: false and is charged `0`. Read has_email / has_phone first: false is a complete answer, not a failure, and retrying it will not change the result. A 404 profile_not_found means no such profile — a different thing from a profile with no email or phone.
Only business addresses are returned — personal mailboxes (Gmail, Outlook and the like) are not. A phone number is returned only when its country is known from the number itself or from the person's location.
Request
GET /v1/profiles/{id}/email
Host: search-api.xverum.com
x-api-key: XVERUM-API-KEYPath parameter
| Parameter | Description |
|---|---|
id | Opaque profile id, e.g. from a search result's id |
Example
curl "https://search-api.xverum.com/v1/profiles/a1b2c3d4/email" \
-H "x-api-key: XVERUM-API-KEY"curl "https://search-api.xverum.com/v1/profiles/a1b2c3d4/phone" \
-H "x-api-key: XVERUM-API-KEY"Response — email
| Field | Type | Description |
|---|---|---|
has_email | boolean | Whether we hold a business email for this person. Check this first. |
emails | object[] | Every address we hold; [] when has_email is false |
emails[].email | string | The address, lowercased |
emails[].confidence | string | null | The source's confidence in the address, e.g. High; null if none |
emails[].last_checked | string | null | When the address was last checked (YYYY-MM-DD); null if unknown |
credits_used | integer | Credits deducted — 2 when an email is held, 0 when it is not |
credits_remaining | integer | Balance left after this call |
request_id | string | Correlation id — also returned in the X-Request-Id header |
{
"has_email": true,
"emails": [
{ "email": "[email protected]", "confidence": "High", "last_checked": "2026-09-01" }
],
"credits_used": 2,
"credits_remaining": 4998,
"request_id": "1a2b3c4d5e6f7081"
}Response — phone
| Field | Type | Description |
|---|---|---|
has_phone | boolean | Whether we hold a phone for this person. Check this first. |
phones | object[] | Up to 3 numbers, best first; [] when has_phone is false |
phones[].phone | string | The number in international (E.164) form |
phones[].extension | string | The extension; "" when there is none |
phones[].line_type | string | null | mobile, fixed_line and so on; null if unknown |
phones[].country | string | null | The number's country (ISO 3166-1 alpha-2); null if non-geographic |
phones[].country_source | string | How country was decided: number (from the number's own country code) or person_country (from the person's location) |
credits_used | integer | Credits deducted — 6 when a phone is held, 0 when it is not |
credits_remaining | integer | Balance left after this call |
request_id | string | Correlation id — also returned in the X-Request-Id header |
{
"has_phone": true,
"phones": [
{
"phone": "+12025550123",
"extension": "",
"line_type": "mobile",
"country": "US",
"country_source": "number"
}
],
"credits_used": 6,
"credits_remaining": 4994,
"request_id": "1a2b3c4d5e6f7081"
}Example responses — nothing held
{
"has_email": false,
"emails": [],
"credits_used": 0,
"credits_remaining": 5000,
"request_id": "1a2b3c4d5e6f7081"
}{
"has_phone": false,
"phones": [],
"credits_used": 0,
"credits_remaining": 5000,
"request_id": "1a2b3c4d5e6f7081"
}Billing
A delivered email costs 2 credits and a delivered phone 6 credits — per person, however many addresses or numbers they have — echoed as credits_used. When nothing is held the call is free. Each charge is deduped per (api-key, id) within a short window, separately for email and phone: buying a person's email never makes their phone free.
Two identical calls sent at the same moment are billed once: the second is answered 409 request_in_progress with a Retry-After header — wait and retry, and the repeat is free.
Errors
All /v1 errors use the structured envelope (see Authentication):
| Status | error.code | Condition |
|---|---|---|
401 | invalid_api_key | Missing or invalid API key |
402 | out_of_credits | Out of credits — the envelope carries an upgrade_url to top up |
403 | account_not_authorized | Account not authorized |
404 | profile_not_found | No profile exists for the given id |
409 | request_in_progress | An identical call is still in flight — retry after Retry-After |
422 | validation_error | The id is empty or longer than 128 characters |
429 | rate_limited | Rate limit exceeded — see Rate limits |
502 | upstream_unavailable | The contact store failed — nothing charged, retry shortly |
503 | search_unavailable | Temporarily unavailable — retry shortly |