Find and verify business emails, look up phone numbers, search and enrich company data, and manage your lead lists from your own code. One REST API, one API key, JSON everywhere.
Every endpoint is served from https://api.skrapp.io, followed by the path prefix of its version.
| Endpoints | Version | Path prefix |
|---|---|---|
| v2 | /api/v2 | |
| v3 | /api/v3/companies | |
| v3 | /api/v3/people | |
| v3 | /v3 |
Every endpoint below shows its full path and the version it lives on. Requests and responses are JSON. Credits are explained once in Credits; each endpoint links there.
# Find an address from a name + domain
curl "https://api.skrapp.io/api/v2/find?firstName=Jane&lastName=Doe&domain=acme.com" \
-H "X-Access-Key: YOUR_API_KEY"Send your API key in the X-Access-Key header on every request. The same key works for every endpoint on this page. Header names are case-insensitive, so x-access-key works too. There are no OAuth flows and no tokens to refresh.
Get or copy your key from your Skrapp account.
Keep the key server-side
The key spends your account credits. Never ship it in browser or mobile code.
A missing or invalid key is rejected before anything else runs, and nothing is charged. The status code differs by endpoint family; see Errors.
curl "https://api.skrapp.io/api/v2/account" \
-H "X-Access-Key: YOUR_API_KEY"Errors use standard HTTP status codes and a JSON body. The body shape depends on the service behind the endpoint, so each family is listed separately below. Some legacy bodies carry status as a string ("404") and others as a number (404); compare on the HTTP status code, not the body.
Applies to /api/v2/find and /api/v2/find_bulk.
| Status | When | Response body |
|---|---|---|
| 400 | A required parameter is missing (Email Finder). | {"status":400,"message":"Bad Request."} |
| 400 | The body is empty or not a JSON array (Bulk Email Finder). | {"code":400,"message":"Bad Request."} |
| 400 | More than 500 rows (Bulk Email Finder). | {"status":400,"limit":500,"message":"Payload too big. Limit is 500"} |
| 400 | The body is not valid JSON. | {"status":400,"response":"Bad JSON Format","error":"JSON"} |
| 403 | Missing or invalid API key. | {"status":403,"message":"Not authorized"} |
| 403 | No credits left, or the credit period has ended. The field name is spelled email_limit_exeeded exactly like this. | {"status":403,"email_limit_exeeded":true,"message":"Not authorized"} |
| 403 | Bulk Email Finder: fewer credits left than rows sent. | {"status":403,"message":"Insufficient credits."} |
| 403 | Free plans: the daily per-IP limit is reached, or the request was blocked by abuse protection. See Rate limits. | {"status":403,"message":"Forbidden."} |
| 404 | No email found, or the company could not be resolved to a domain. Not charged. Note status is a string here. | {"status":"404","message":"Not found"} |
| 408 | The search did not finish in time (10 s for Email Finder, 60 s for Bulk Email Finder). Not charged; retry. | {"status":408,"code":"RTO","message":"Request timed out before the search completed. No credit was charged — please retry."} |
| 429 | Too many requests for the credits you have left. See Rate limits. | {"status":429,"message":"Too Many Requests"} |
| 500 | Unexpected server error. Retry with backoff. | {"status":500,"response":"Internal Server Error.","error":"<message>"} |
The company endpoints (/api/v3/companies/…) use one JSON envelope. message is always a full sentence. Validation errors add a details array; rate-limit errors add limit, retry_after (seconds) and reset_at, plus a Retry-After header.
{
"status": 400,
"error": "BAD_REQUEST",
"message": "The request has 2 validation errors. See details.",
"details": [
"Field size must not be greater than 100.",
"Field revenueCurrency must be one of the following values: USD, EUR, …"
]
}{
"status": 429,
"error": "TOO_MANY_REQUESTS",
"message": "Too many search requests: 100 per minute. Retry in 8 seconds.",
"limit": 100,
"retry_after": 8,
"reset_at": "2026-10-09T14:03:00.000Z"
}| Status | When | Response body |
|---|---|---|
| 400 | Invalid parameters or body, invalid JSON, identifier in the wrong format. | — |
| 401 | No key: "Missing API key. Send your key in the x-access-key header." Unknown, revoked, expired or deleted key: "Invalid API key. Check the value sent in the x-access-key header, or contact Skrapp support for a new key." The key is checked before input validation, so a bad key returns 401 even when the request is also invalid. | — |
| 402 | Company enrichment needs more credits than are available. Nothing is charged (see the entitlement rule). Only the company enrichment endpoints return 402. | — |
| 403 | Free plan after its 14-day trial: enrichment (TRIAL_EXPIRED) or a premium search filter (FILTER_LOCKED). | — |
| 404 | No company matches the identifier. | — |
| 413 | Body larger than 100 kB. | — |
| 429 | Rate limit reached. | — |
| 502 | Company data temporarily unavailable. Retry. | — |
| 503 | Authentication is temporarily unavailable: "Authentication is temporarily unavailable. Please retry shortly." | — |
Behaviour to know
Phone lookup and Phone bulk lookup (/api/v3/people/phone…) use the same JSON envelope as the company endpoints. Each lists its own cases: Phone lookup, Phone bulk lookup.
Applies to /v3/verify, /v3/verify_bulk and POST /api/v2/list/:listId/load.
| Status | When | Response body |
|---|---|---|
| 400 | Invalid or missing parameters. Detailed validation messages are not returned. | {"statusCode":400,"message":"Bad Request"} |
| 401 | Missing or invalid API key. The HTTP status is 401, but the body says 403. | {"status":403,"message":"Not authorized"} |
| 403 | Not enough credits for the request. | {"message":"Not enough credits","status":403} |
| 429 | Email Verifier, free plans: the daily per-IP limit is reached. See Rate limits. | — |
| 503 | Authentication is temporarily unavailable. Retry shortly. | {"status":503,"message":"Authentication temporarily unavailable","reason":"auth_unavailable"} |
Applies to /api/v2/account, /api/v2/account-lists and every /api/v2/list endpoint except Add leads to a list. Each endpoint lists its own cases.
| Status | When | Response body |
|---|---|---|
| 400 | Invalid path ID or body. | {"status":"400","message":"Bad request"} |
| 403 | Missing or invalid API key. | {"status":403,"message":"Not authorized"} |
| 404 | The account, list or lead was not found, or the result is empty. | {"status":404,"message":"Not found"} |
| 500 | Unexpected server error. Retry with backoff. | {"status":"500","message":"Internal server error"} |
Finding and verifying emails, enriching companies and looking up phone numbers use your account credits. Everything else on this page is free. Your balance is credit.email in Account: remaining credits are quota - used. Responses from the Email Finder do not report what was charged; the Email Verifier reports it in consumedCredit, company enrichment in total_cost, and phone lookup in cost (total_cost for a batch).
| Action | Cost |
|---|---|
| Email Finder, Bulk Email Finder | 1 credit per email found for the first time. Not found is free. |
| Email Verifier, Bulk Email Verifier | 1 credit per email, unless already verified or found by your account. |
| Company enrich, Company bulk enrich | 1–5 credits per category, once per company and category (entitlement rule). |
| Phone lookup, Phone bulk lookup | 5 per person number found · 1 when only company numbers are found. Not found is free. |
Company data in Email Finder and Email Verifier (includeCompanyData, enrich) | Free |
| Account, Lists, Companies search, Company snapshot | Free |
email_limit_exeeded). A Bulk Email Finder request needs at least as many credits left as rows sent, even though only new found emails are charged.The Email Finder verifies each email before answering. When the email it charged for turns out invalid or unknown, the credit is returned automatically:
quality.status is invalid or unknown.catch-all and valid results stay charged.credit.email.used in Account if you need to reconcile.Company enrich charges per data category, once per company and category for your account: the first enrichment of a category is charged, every later request for it is free. Categories with no data cost nothing, and a request that needs more credits than you have returns 402 and charges nothing. Full rules and prices: Entitlement rule and Categories & Credits.
invalid and malformed addresses (format: "invalid").unknown, or already found it with the Email Finder. consumedCredit is then 0.unknown results are charged and not refunded. Verifying the same email again after an unknown is charged again.Limits depend on the endpoint and on your plan. Daily windows are UTC days and reset at 00:00 UTC.
| Endpoint | Free plan | Paid plan | When exceeded |
|---|---|---|---|
| GET /api/v2/find | 150 requests per IP per UTC day. Burst capped at the credits you have left. | No limit while more than 10% of your credits remain; below 10%, burst capped at the credits you have left. | 403 Forbidden. (daily IP cap) · 429 (burst) |
| POST /api/v2/find_bulk | Each row counts toward the 150 per IP per UTC day. | No limit. | 403 Forbidden. |
| GET /v3/verify | 100 requests per IP per 24 h. | No limit. | 429 |
| GET /v3/verify_bulk | No limit. | No limit. | — |
| Account and Lists | No limit. | No limit. | — |
| POST /api/v3/companies/search | 20 / min · 50 / day · page ≤ 20 · first 100 rows | 100 / min · 2,000 / day · page ≤ 100 · first 1,000 rows | 429 (rate) · 400 (page size, rows) |
| GET /api/v3/companies/snapshot | 200 / min · 500 distinct companies / day | 500 / min · 5,000 distinct companies / day | 429 |
| Company enrich, Company bulk enrich | No limit (14-day trial on free plans). | No limit. | — |
Request size limits are separate: Bulk Email Finder takes up to 500 rows, Bulk Email Verifier up to 50 emails, Company bulk enrich up to 20 companies, and Add leads to a list up to 10,000 leads per request. Email Finder requests time out after 10 s and Bulk Email Finder after 60 s (408, not charged).
Companies search responses carry these headers (readable from browsers through CORS). A rejected search request does not count toward the search limit. Company snapshot counts every request toward the minute limit, but only distinct companies toward the daily limit: viewing a company you already viewed today is free. Snapshot responses do not carry X-RateLimit-* headers.
| Header | Meaning |
|---|---|
| X-RateLimit-Limit-Minute | Requests allowed this minute |
| X-RateLimit-Remaining-Minute | Requests left this minute |
| X-RateLimit-Limit-Day | Requests allowed today (UTC) |
| X-RateLimit-Remaining-Day | Requests left today |
| Retry-After | Seconds to wait, on 429 only |
/api/v2/accountv2Credits: Free.
Read your plan, your credit balance and your most recent lists. Check it before a large bulk request to confirm you have the credits to finish it.
| Field | Type | Description |
|---|---|---|
name | string | Account name. |
email | string | Account email. |
package | string | Plan name, e.g. Professional 5K. |
packageRDate | number | End of the current credit period, as a Unix timestamp in milliseconds (not an ISO date). It is reported about one day before the actual reset. |
credit | object | Credit balance. |
email | object | Credits for finding, verifying and enriching. Remaining = quota - used. |
quota | integer | Credits in the current period. |
used | integer | Credits used so far, at most quota. Equal to quota once the period has ended. |
lists_count | integer | Number of lists on the account. |
lists | object[] | The 50 most recent lists. For all lists, use List your lists. |
id | integer | List ID. |
name | string | List name. |
path | string | App path of the list, /app/list/<id>. |
frozen | boolean | true when the list is locked and cannot be changed. |
size | integer | Number of leads in the list. |
| Status | When | Response body |
|---|---|---|
| 403 | Missing or invalid key. | {"status":403,"message":"Not authorized"} |
| 404 | Account not found. | {"status":404,"message":"Not found"} |
curl "https://api.skrapp.io/api/v2/account" \
-H "X-Access-Key: YOUR_API_KEY"{
"name": "Jane Doe",
"email": "jane@example.com",
"package": "Professional 5K",
"packageRDate": 1792195206224,
"credit": {
"email": { "quota": 5000, "used": 2779 }
},
"lists_count": 3,
"lists": [
{ "id": 17430846, "name": "Q4 outbound", "path": "/app/list/17430846", "frozen": false, "size": 150 },
{ "id": 17429843, "name": "Acme accounts", "path": "/app/list/17429843", "frozen": false, "size": 10 },
{ "id": 17266481, "name": "Enrichment test", "path": "/app/list/17266481", "frozen": false, "size": 281 }
]
}/api/v2/findv2Credits: 1 credit per email found for the first time; not found is free; invalid results refunded on paid plans. See Credits.
Find a person's business email from their name and their company. Give a domain when you have one; a company name is resolved to its domain for you.
Required inputs
fullName, or firstName and lastName together.domain or company. When both are sent, domain wins.{"status":400,"message":"Bad Request."}.| Parameter | Type | Description |
|---|---|---|
firstNamewith lastName | string | The person's first name. Send with lastName, or send fullName instead. |
lastNamewith firstName | string | The person's last name. |
fullNameor first + last | string | The full name, parsed into first and last name. Takes priority over firstName and lastName when sent. |
domainor company | string | The company domain, e.g. acme.com. http(s)://, www. and any path are stripped. A value that does not look like a domain is treated as a company name. |
companyor domain | string | The company name, resolved to its domain from Skrapp company data. If it cannot be resolved, the response is 404. |
countryoptional | string | Country name or ISO 2-letter code. Used only for companies with 1,000+ employees, to pick a country-specific email domain. |
includeCompanyDataoptional | string | Send exactly true to add a companyData block to the response. No extra credit.Default: false |
The finder waits for verification
Every email found is verified (SMTP check) before the response is sent, so quality.status is the verification result. This is the default behaviour (wait_verifier=true); keep it. The whole request has a 10-second budget: past it you get 408 and no credit is charged. An email is returned even when it verifies as invalid, catch-all or unknown, so always check quality.status.
An email was found. Fields that do not apply are absent rather than null.
| Field | Type | Description |
|---|---|---|
email | string | The email address found. |
pattern | string | The address pattern used at this domain, e.g. {first}.{last} or {f}{last}. Placeholders: {first}, {last}, {f} (first initial), {l} (last initial). Informational. |
quality | object | The verification result for email. |
status | string | valid, invalid, catch-all or unknown. See Verification statuses. |
status_message | string | A sentence explaining the status, e.g. "jane.doe@acme.com is a valid email address." Absent when verification could not complete (status unknown). |
companyData | object | Only with includeCompanyData=true. Absent (not null) when the company is not in Skrapp company data, or when the company lookup fails or takes longer than 2.5 s. Each field is absent when unknown. |
id | string | Encoded company ID (the same form as id in Companies search results). |
name | string | Company name. |
domain | string | Main company domain. |
website | string | Website URL. |
industry | string | Industry label. |
type | string | Company type, e.g. Privately Held. |
founded | integer | Founding year. |
linkedin_url | string | LinkedIn company page. |
revenue | string | Revenue range as a label, e.g. 10M-50M USD. |
employee_count_range | string | Employee range without thousands separators: 2-10, 11-50, 51-200, 201-500, 501-1000, 1001-5000, 5001-10000, 10001+. |
address | string | Headquarters address on one line. |
city | string | Headquarters city. |
country | string | Headquarters country. |
geo_area | string | Headquarters state or region. |
logo_url | string | Logo image URL. |
| Status | When | Response body |
|---|---|---|
| 400 | No name, or no domain or company. | {"status":400,"message":"Bad Request."} |
| 403 | Missing or invalid key; no credits left (email_limit_exeeded); free-plan daily IP limit. See Errors. | — |
| 404 | No email found, or the company could not be resolved. Free. | {"status":"404","message":"Not found"} |
| 408 | Timed out after 10 s. Not charged; retry. | — |
| 429 | Burst above the credits you have left. See Rate limits. | — |
curl "https://api.skrapp.io/api/v2/find?firstName=Jane&lastName=Doe&domain=acme.com" \
-H "X-Access-Key: YOUR_API_KEY"{
"email": "jane.doe@acme.com",
"pattern": "{first}.{last}",
"quality": {
"status": "valid",
"status_message": "jane.doe@acme.com is a valid email address."
}
}curl "https://api.skrapp.io/api/v2/find?fullName=Jane%20Doe&company=Acme%20Corp&includeCompanyData=true" \
-H "X-Access-Key: YOUR_API_KEY"{
"email": "jane.doe@acme.com",
"pattern": "{first}.{last}",
"quality": {
"status": "catch-all",
"status_message": "jane.doe@acme.com is a catch-all address, recipient's existence is uncertain."
},
"companyData": {
"id": "eMjwWd8bgOC5yKmKEo_G_cfAe7lFFIP5_uJkheLKRuF0CQc",
"name": "Acme Corp",
"domain": "acme.com",
"website": "https://www.acme.com",
"industry": "Software Development",
"type": "Privately Held",
"founded": 2012,
"linkedin_url": "https://www.linkedin.com/company/acme-corp",
"revenue": "10M-50M USD",
"employee_count_range": "51-200",
"address": "100 Market Street, San Francisco, California, United States",
"city": "San Francisco",
"country": "United States",
"geo_area": "California",
"logo_url": "https://logos-cdn.skrapp.io/logos/acme.com"
}
}{
"status": "404",
"message": "Not found"
}/api/v2/find_bulkv2Credits: Same as Email Finder, per row. Needs at least as many credits left as rows sent. See Credits.
Find emails for up to 500 people in one request. The request is synchronous: the results come back in the same 200 response, in the order you sent them. There is no job to poll and no webhook.
Request body
{"people": [...]}).{"status":400,"limit":500,"message":"Payload too big. Limit is 500"}.firstName + lastName, or name) and a company (domain or company).| Parameter | Type | Description |
|---|---|---|
tIdoptional | string | Your own ID for the row, echoed back so you can match results to your records. |
firstNamewith lastName | string | First name. Send with lastName, or send name. |
lastNamewith firstName | string | Last name. |
nameor first + last | string | Full name, parsed into first and last name. |
domainone company field | string | Company domain. A value that does not look like a domain is treated as a company name. |
companyone company field | string | Company name, resolved to its domain. |
countryoptional | string | Country name or ISO 2-letter code, used for country-specific domains of large companies. Not echoed back. |
An array with one item per row, in input order. Each item echoes your row, with names normalised; email and quality are added when an email was found. Rows that have no name and no company field at all are dropped from the response.
| Field | Type | Description |
|---|---|---|
[].tId | string | Your row ID, echoed. |
[].firstName | string | First name, parsed and capitalised. |
[].lastName | string | Last name, parsed and capitalised. |
[].name | string | null | Full name, capitalised, as sent. |
[].domain | string | On a hit, the domain of the company that was searched. |
[].company | string | On a hit, the company name from Skrapp company data. |
[].email | string | The email found. Absent on a miss. |
[].quality | object | Verification result, same shape as the Email Finder quality. Absent on a miss. |
status | string | valid, invalid, catch-all or unknown. |
status_message | string | A sentence explaining the status. |
There is no companyData block in bulk results; for full company data, use the Email Finder with includeCompanyData=true or Company snapshot.
| Status | When | Response body |
|---|---|---|
| 400 | Empty body, or not a JSON array. | {"code":400,"message":"Bad Request."} |
| 400 | More than 500 rows. | {"status":400,"limit":500,"message":"Payload too big. Limit is 500"} |
| 403 | Fewer credits left than rows sent. | {"status":403,"message":"Insufficient credits."} |
| 403 | Missing or invalid key, no credits left, or free-plan daily IP limit. See Errors. | — |
| 408 | Timed out after 60 s. Not charged; retry. | — |
curl -X POST "https://api.skrapp.io/api/v2/find_bulk" \
-H "X-Access-Key: YOUR_API_KEY" \
-H "Content-Type: application/json" \
-d '[
{ "tId": "row-1", "firstName": "jane", "lastName": "doe", "domain": "acme.com" },
{ "tId": "row-2", "name": "John Smith", "company": "Globex" },
{ "tId": "row-3", "firstName": "Alex", "lastName": "Martin", "domain": "initech.example" }
]'[
{
"tId": "row-1",
"firstName": "Jane",
"lastName": "Doe",
"name": null,
"domain": "acme.com",
"company": "Acme Corp",
"email": "jane.doe@acme.com",
"quality": {
"status": "valid",
"status_message": "jane.doe@acme.com is a valid email address."
}
},
{
"tId": "row-2",
"firstName": "John",
"lastName": "Smith",
"name": "John Smith",
"domain": "globex.com",
"company": "Globex",
"email": "jsmith@globex.com",
"quality": {
"status": "catch-all",
"status_message": "jsmith@globex.com is a catch-all address, recipient's existence is uncertain."
}
},
{
"tId": "row-3",
"firstName": "Alex",
"lastName": "Martin",
"name": null,
"domain": "initech.example"
}
]/api/v3/people/phonev3Credits: 5 per person number found · 1 when only company numbers are found. Not found is free.
Find a person's mobile, direct or company phone numbers from a LinkedIn profile, or from a name and their company. For many people at once, see Phone bulk lookup below.
| Parameter | Type | Description |
|---|---|---|
linkedinUrlone identifier | string | LinkedIn profile URL, profile slug, or Sales Navigator ID or URL, e.g. https://www.linkedin.com/in/jane-doe-example or jane-doe-example. Enough on its own: no other parameter is needed. Max 512 characters. |
firstNameone identifier | string | First name, e.g. Jane. Send with lastName. Max 100 characters. |
lastNameone identifier | string | Last name, e.g. Doe. Send with firstName. Max 100 characters. |
fullNameone identifier | string | Full name, e.g. Jane Doe, instead of firstName and lastName. If you send both, firstName + lastName are tried first. Max 200 characters. |
companyDomainoptional | string | The person's company domain, e.g. example.com. Tried before companyName. |
companyNameoptional | string | The person's company name, e.g. Example Ltd. Prefer companyDomain for an exact company. |
countryoptional | ISO 3166-1 alpha-2 | e.g. GB. With a name and no company, finds the person in that country and returns only numbers from that country. With a company, puts numbers from that country first. |
Which inputs to send
linkedinUrl alone. Nothing else is needed; if you also send a name, the LinkedIn profile is tried first.companyDomain, companyName or country. The name is firstName + lastName, or fullName; with both, firstName + lastName are tried first, then fullName if they find no one.country is the least precise input: it searches everyone with that name in the country. When several people match equally well, confidence is lower, so check it before using a number.| Field | Type | Description |
|---|---|---|
id | string | null | The person's ID. null when no person matched and only company numbers are returned. |
company_id | string | null | The company's ID, the same as in Company enrich. Set only when the numbers are company numbers. |
phones | object[] | The numbers found. Empty when the person has no usable number, at no cost. |
type | enum | mobile, direct or company. |
phone | string | The number as listed. |
phone_e164 | string | The number in E.164 format. |
country_code | string | Dialling code, e.g. 44. |
country_iso | string | null | ISO 3166-1 alpha-2 country of the number. |
extension | string | null | Extension, when the number has one. |
confidence | enum | null | The level of confidence_score: high from 0.9, medium from 0.5, low below 0.5. null when only company numbers are returned. |
confidence_score | number | null | How likely the returned person is the one you asked for, from 0 to 1. A LinkedIn input scores 1. A match through a middle name, an initial, a nickname or a close misspelling scores at most 0.89, so it is never high. null when only company numbers are returned. |
cost | integer | Credits this request charged. |
No error is charged.
| Status | When | Response body |
|---|---|---|
| 400 | Missing or invalid identifiers, e.g. a name with no company or country. The message names the field. | — |
| 401 | Missing or invalid API key. | — |
| 402 | Not enough credits: this request needs 5 and 2 are available. Nothing is charged. | required, available, categories |
| 404 | No person matches the given identifiers. | — |
| 502 | Phone lookup is temporarily unavailable. Please retry shortly. | — |
Caching: private, no-store.
curl "https://api.skrapp.io/api/v3/people/phone?linkedinUrl=https://www.linkedin.com/in/jane-doe-example" \
-H "X-Access-Key: YOUR_API_KEY"{
"id": "1234567890123456789",
"company_id": null,
"phones": [
{
"type": "mobile",
"phone": "+44 7700 900123",
"phone_e164": "+447700900123",
"country_code": "44",
"country_iso": "GB",
"extension": null
}
],
"confidence": "high",
"confidence_score": 1,
"cost": 5
}{
"status": 402,
"error": "PAYMENT_REQUIRED",
"message": "Not enough credits: this request needs 5 and 2 are available.",
"required": 5,
"available": 2,
"categories": { "phone": 5 }
}/api/v3/people/phone/bulkv3Credits: Same as Phone lookup, per person; all or nothing for the batch.
Look up to 50 people in one request. It is Phone lookup run on a list: the same identifiers, prices and free plan. This section only covers what differs.
| Phone lookup | Phone bulk lookup | |
|---|---|---|
| Method and input | GET, query parameters | POST, JSON body |
| People | 1 | 1–50, results in input order |
| Person not found | 404 | That item gets status: "not_found"; the others still succeed |
| Upstream failure | 502 | That item gets status: "error", is not charged and can be retried alone |
| Not enough credits | 402, nothing charged | 402 for the whole batch, nothing charged |
| Same person twice | — | Charged once; the cost shows on the first, 0 on the others |
| Parameter | Type | Description |
|---|---|---|
peoplerequired | object[] 1–50 | Each item takes the Phone lookup query parameters. One invalid item rejects the whole request with 400, naming its position. |
{ total_cost, results }, with one result per input, in the same order.
| Field | Type | Description |
|---|---|---|
total_cost | integer | Credits this request charged, for all people. |
results | object[] | One result per input, in the same order. |
input | object | The item exactly as you sent it, to match results to inputs. |
status | enum | found, not_found or error. |
(when found) | — | The Phone lookup response fields: id, company_id, phones, confidence, confidence_score, cost. |
message | string | Only for error: "Phone lookup failed for this entry. Retry it." |
Request-level errors stop the whole batch and charge nothing. Per-person problems are reported in results[].status instead.
| Status | When | Response body |
|---|---|---|
| 400 | Empty or more than 50 people, or an invalid item. The message names the item's position. | — |
| 401 | Missing or invalid API key. | — |
| 402 | Not enough credits for the batch. Nothing is charged. | required, available, categories |
| 502 | Phone lookup is temporarily unavailable. Please retry shortly. | — |
curl -X POST "https://api.skrapp.io/api/v3/people/phone/bulk" \
-H "X-Access-Key: YOUR_API_KEY" \
-H "Content-Type: application/json" \
-d '{"people":[{"linkedinUrl":"https://www.linkedin.com/in/jane-doe-example"},{"firstName":"John","lastName":"Smith","companyDomain":"example.com"},{"fullName":"Alex Taylor","country":"US"}]}'{
"total_cost": 6,
"results": [
{ "input": { "linkedinUrl": "https://www.linkedin.com/in/jane-doe-example" }, "status": "found", "id": "1234567890123456789", "company_id": null, "phones": [ "…" ], "cost": 5 },
{ "input": { "firstName": "John", "lastName": "Smith", "companyDomain": "example.com" }, "status": "found", "id": null, "company_id": "9876543210987654321", "phones": [ "…" ], "cost": 1 },
{ "input": { "fullName": "Alex Taylor", "country": "US" }, "status": "not_found" }
]
}Search companies by keywords, industry, size, location, financials, funding, technologies and growth signals, then get a free company card for any company by domain, name or internal ID. When you need more, enrich a company, or up to 20 at once, with detailed data such as firmographics, financials, funding, technologies and signals. Enrichment uses your account credits per data category, and a category is charged only the first time you enrich it for a company, so repeat requests are free; search and the company card cost no credits.
Base URL https://api.skrapp.io/api/v3. Authenticate with the same API key, in the X-Access-Key header (see Authentication). Errors and rate limits are in Errors and Rate limits.
| Endpoint | What it does | Credits | Rate limit |
|---|---|---|---|
| POST /companies/search | Filter companies with 60+ filters: keywords, firmographics, location, headcount, hiring, financials, funding, technologies, lookalikes and signals | Free | Per plan, minute + day |
| GET /companies/snapshot | The free company card, by internal ID, domain or name | Free | Per plan, minute + distinct companies per day |
| GET /companies/enrich | Return enrichment data for one company, using credits | Per category | None |
| POST /companies/bulk-enrich | Enrich up to 20 companies in one request | Per category | None |
Plans. Limits depend on the account's own plan. Free plans have lower limits and, for 14 days after sign-up, a free trial of enrichment and premium search filters.
Two company identifiers appear in responses, and they are not interchangeable.
| Identifier | Returned as | Use it in | Example (Stripe) |
|---|---|---|---|
| Internal ID: numeric string, larger than 2^53: keep it a string | internal_id in search results; id in snapshot and enrich responses | The id input of Company snapshot, Company enrich and Company bulk enrich | 8342903258370330161 |
| Encoded company ID: opaque string | id in search results | Companies search filters only: companyIds, exclude.companyIds | BkAautTuXYiAK_2wJBe0I5ObIQIOvAXnd-2yk8Dsw6SH7oE |
Which ID to use
For Company snapshot, Company enrich and Company bulk enrich, pass the search result's internal_id as id (or internalId), or identify the company by domain or name. Don't pass the search result's id: it is the encoded company ID and returns 400 "The Data gateway could not process this company identifier."
/api/v3/companies/searchv3Credits: No credits.
Find companies with more than 60 filters across 12 groups: keywords, firmographics, location, headcount, hiring, financials, public markets, funding, technologies, lookalikes, signals and exclusions. Results are paginated and can be sorted. Search never uses credits; your plan sets how much you can search and which filters you can use.
| Limit | Free plan | Paid plan | When exceeded |
|---|---|---|---|
| Requests per minute | 20 | 100 | 429 |
| Requests per UTC day | 50 | 2,000 | 429, resets 00:00 UTC |
Page size (size) | ≤ 20 | ≤ 100 | 400 |
Rows reachable per query (start) | first 100 | first 1,000 | 400 |
| Premium filters and sorts | 14-day trial from sign-up | Always | 403 FILTER_LOCKED |
Each page is one request. Requests rejected with 400, 401 or 403 do not count toward your limits. Remaining quota is returned in the X-RateLimit-* headers (see Rate limits).
Filters are either Free, available on every plan, or Premium, available on paid plans. Free plans can use premium filters during a 14-day trial from sign-up, the same trial as Company enrich. After the trial, a request that uses any premium filter or premium sort returns 403 and lists the filters to remove; the same request without them works.
| Free on every plan | Premium (paid plans, or the free trial) |
|---|---|
| Keywords, company name, domains, company IDs | Headcount growth |
| Firmographics: industry, specialities, company type, size range, SIC and NAICS codes, founding year | Hiring: job postings, counts and growth |
| Location: country, region, state, city, location text, presence | Profitability: is profitable, net income, EBITDA, margins |
| Employee count ranges, revenue range, publicly traded | Public markets: ticker, stock exchange, market cap |
| Exclusions, pagination, sort by relevance or popularity | Funding: amount, date, stage, total raised, rounds |
Technologies, lookalikes (similarTo), signals | |
| Sort by employee count, founding year, total raised or revenue |
{
"status": 403,
"error": "FORBIDDEN",
"message": "These search filters are available on paid plans: fundingMin, technologies. Your free trial ended on 2026-10-01 at 09:12 UTC. Upgrade your account at https://skrapp.io/pricing to use them.",
"reason": "FILTER_LOCKED",
"locked_filters": ["fundingMin", "technologies"],
"trial_ended_at": "2026-10-01T09:12:44.000Z",
"upgrade_url": "https://skrapp.io/pricing"
}| Parameter | Type | Description |
|---|---|---|
startoptional | integer ≥ 0 | Offset. Must be below your plan's row cap (100 free, 1,000 paid). Use a multiple of size: other values start at the beginning of their page.Default: 0 |
sizeoptional | integer 1–100 | Page size. Free plans: at most 20.Default: 20 |
lead_countsoptional | boolean | Adds lead_count (people we have at the company). Set false for faster responses.Default: true |
All body filters combine with AND; values inside one array combine with OR. Arrays must contain at least one element. Label filters (industry, type, country…) are case-insensitive. A …Min / …Max pair may be sent alone or together, and min must not exceed max. An empty body returns all companies by popularity.
| Parameter | Type | Description | Plan |
|---|---|---|---|
| Keywords & identifiers | |||
keywordsoptional | string[] 1–10 | Terms to find in the company description and tags, each 2–100 characters, e.g. ["cybersecurity", "managed services"]. A term matches when all its words appear in the description, or when it equals one of the company's tags. Duplicates are ignored, case-insensitively. Results are ranked by how many terms match, then popularity. | Free |
keywordsMatchoptional | any | all | any (default): at least one term matches. all: every term matches. Requires keywords. | Free |
companyNameoptional | string | Company name, ranked by name relevance (exact names first). | Free |
companyDomainsoptional | string[] | Website domains, e.g. stripe.com. URLs and www. are normalised. | Free |
companyIdsoptional | string[] | number[] | Restrict to these companies: encoded IDs from search results, or LinkedIn company IDs. | Free |
| Firmographics | |||
companyIndustriesoptional | string[] | Industry labels, e.g. Software Development (481 values; software is accepted as an alias). | Free |
companySpecialitiesoptional | string[] | Speciality labels. | Free |
companyTypesoptional | enum[] | Public Company, Privately Held, Subsidiary, Non-Profit, Government Agency, Educational, Partnership, Self-Employed, Self-Owned, Sole Proprietorship. | Free |
companySizeRangesoptional | enum[] | Employee size ranges: 1-10, 11-50, 51-200, 201-500, 501-1,000, 1,001-5,000, 5,001-10,000, 10,001+. | Free |
sicCodesoptional | string[] | SIC codes, 2–4 digits; a shorter code matches its whole branch, e.g. 73. | Free |
naicsCodesoptional | string[] | NAICS codes, 2–6 digits, e.g. 5112. | Free |
companyYearoptional | integer | Exact founding year. Cannot be combined with companyYearMin / companyYearMax. | Free |
companyYearMin · companyYearMaxoptional | integer | Founding year range, inclusive. | Free |
| Location (headquarters) | |||
geoCountriesoptional | string[] | Country names, e.g. France (248 values). | Free |
geoRegionsoptional | string[] | World regions, e.g. EMEA, APAC, AMER, Western Europe (34 values). | Free |
geoStatesoptional | string[] | States or regions, e.g. California, Île-de-France. | Free |
geoCitiesoptional | string[] | Cities, matched as written. | Free |
geoLocationoptional | string | Free-text match on the headquarters address, e.g. Bay Area. | Free |
geoPresenceInoptional | string | Companies with an office in this place, headquarters or not, e.g. Germany. | Free |
| Headcount | |||
companyHeadCountoptional | {start, end?}[] | Exact employee-count ranges. Several ranges are merged into one span from the lowest start to the highest end (open-ended if any range has no end). | Free |
headcountGrowthoptional | object[] | Employee count change over a period: {period, percentage?, min?, max?}. period: monthly, quarterly or yearly. percentage: true reads min/max as percent change, otherwise as a number of employees. Negative values mean shrinking. Example: {"period":"yearly","percentage":true,"min":20}. | Premium |
| Hiring | |||
hasJobPostingsoptional | boolean | Has (or has no) active job postings. | Premium |
jobPostingsMin · jobPostingsMaxoptional | integer ≥ 0 | Number of active job postings. | Premium |
jobPostingsGrowthoptional | object[] | Job postings change in percent: {period, min?, max?}, e.g. {"period":"quarterly","min":50}. | Premium |
| Revenue & profitability | |||
revenueMin · revenueMaxoptional | number ≥ 0 | Annual revenue bounds, matched to revenue ranges. | Free |
revenueCurrencyoptional | enum | Currency of the revenue bounds. Default USD. One of USD, AED, AUD, BRL, CAD, CNY, DKK, EUR, GBP, HKD, IDR, ILS, INR, JPY, NOK, NZD, RUB, SEK, SGD, THB, TRY, TWD. | Free |
isProfitableoptional | boolean | Positive net income in the latest fiscal year. | Premium |
netIncomeRangesoptional | enum[] | Latest net income, USD: lt_0, 0_1m, 1m_10m, 10m_100m, 100m_1b, gte_1b. | Premium |
ebitdaRangesoptional | enum[] | Latest EBITDA, same values as netIncomeRanges. | Premium |
grossMarginMin · grossMarginMaxoptional | number | Latest gross profit margin as a fraction: 0.4 = 40%. | Premium |
ebitMarginMin · ebitMarginMaxoptional | number | Latest EBIT margin as a fraction. | Premium |
ebitdaMarginMin · ebitdaMarginMaxoptional | number | Latest EBITDA margin as a fraction. | Premium |
| Public markets | |||
isPublicoptional | boolean | Publicly traded (or not). | Free |
tickersoptional | string[] | Stock tickers, e.g. AAPL. | Premium |
stockExchangesoptional | enum[] | NASDAQ, NYSE, AMEX, OTC, LSE, AIM, Euronext, XETRA, FWB, SIX, OMX, BIT, BME, TSE, HKEX, SSE, SZSE, KRX, TWSE, SGX, ASX, NZX, BSE, NSE, TSX, TSXV, B3, BMV, JSE, TASE, SET, IDX, KLSE, PSE. | Premium |
marketCapRangesoptional | enum[] | USD: lt_100m, 100m_1b, 1b_10b, 10b_100b, 100b_1t, gte_1t. | Premium |
| Funding | |||
fundingMin · fundingMaxoptional | number ≥ 0 | Amount of the last funding round. | Premium |
fundingCurrencyoptional | enum | Currency of the funding amounts (fundingMin/Max, totalRaisedMin/Max). Default USD; same values as revenueCurrency. | Premium |
fundingYearoptional | integer ≥ 1900 | Year of the last funding round. Cannot be combined with fundingDateFrom / fundingDateTo. | Premium |
fundingDateFrom · fundingDateTooptional | YYYY-MM-DD | Date range of the last funding round, inclusive. | Premium |
fundingStageoptional | string | Last round type, e.g. Seed, Series A. Close spellings match. | Premium |
totalRaisedMin · totalRaisedMaxoptional | number ≥ 0 | Total amount raised across all rounds. | Premium |
fundingRoundsMin · fundingRoundsMaxoptional | integer ≥ 0 | Number of funding rounds. | Premium |
| Technologies | |||
technologiesoptional | string[] | Technologies the company uses, lowercase, e.g. hubspot, salesforce, aws (3,430 values). Unknown values return 400. | Premium |
technologiesCountMin · technologiesCountMaxoptional | integer ≥ 0 | Number of technologies detected. | Premium |
| Lookalikes | |||
similarTooptional | string[] 1–10 | Companies similar to these, given as domains (stripe.com) or names (Adyen). A value containing a dot is read as a domain. | Premium |
| Signals | |||
signalTrendsoptional | object[] | Trend conditions, all of which must hold: {label, period, trend?, valuePctMin?, valuePctMax?}. label: revenue_growth, employee_count_change, job_postings_change, website_traffic_change, market_cap_trajectory, linkedin_follower_change. period: monthly, quarterly, yearly. trend: growth or decline. valuePct…: size of the change in percent, ≥ 0. | Premium |
revenuePerEmployeeMin · revenuePerEmployeeMaxoptional | number ≥ 0 | Annual revenue per employee. | Premium |
revenuePerEmployeeCurrencyoptional | enum | Required with the bounds above, and only valid with them: USD, EUR, GBP, CAD, AUD, AED, JPY, CHF or NZD. Matches companies reporting revenue in that currency (no conversion). | Premium |
ebitdaMarginLatestMin · ebitdaMarginLatestMaxoptional | number | Latest EBITDA margin from the profitability signal, as a fraction. | Premium |
ebitdaMarginTrendoptional | enum[] | improving, stable, declining. | Premium |
monthlyBurnMin · monthlyBurnMaxoptional | number ≥ 0 | Estimated monthly burn, USD. | Premium |
estimatedBurnMin · estimatedBurnMaxoptional | number ≥ 0 | Estimated total burn, USD (funds raised minus cumulative revenue). | Premium |
fundingMomentumoptional | enum[] | accelerating, stable, decelerating. | Premium |
| Exclusions | |||
excludeoptional | object | Remove matches: companyIds, companyTypes, companyIndustries, companySpecialities, geoCountries, geoCities. | Free |
| Sorting | |||
sortoptional | enum | Default: relevance when keywords or companyName is set, otherwise popularity. relevance and popularity are free; relevance needs keywords or companyName. employeeCount, foundedYear, totalRaised and revenue are premium; companies without a value come last. | See description |
sortDirectionoptional | asc | desc | Default desc. Only with employeeCount, foundedYear, totalRaised or revenue; relevance and popularity are always descending (400 if a direction is sent). | Free |
{ results, meta }. Fields without a value are omitted. When nothing matches, the response is {"results": []} with no meta. Responses carry the X-RateLimit-* headers.
| Field | Type | Description |
|---|---|---|
results | object[] | Matching companies. For funding, financials, technologies, signals and the rest, call Company enrich with the result's internal_id. |
id | string | Encoded company ID (for search filters) |
internal_id | string | Internal ID (for snapshot and enrich) |
name | string | Company name |
domain | string | Email domain |
website | string | Website URL |
industry | string | Industry label |
type | string | Company type |
founded | integer | Founding year |
linkedin_url | string | LinkedIn company page |
employee_count_range | string | e.g. 51-200, 10,001+ |
revenue_range | enum | lt_1m, 1m_10m, 10m_50m, 50m_100m, 100m_250m, 250m_500m, 500m_1b, 1b_10b, gte_10b |
revenue_range_formatted | string | e.g. 10M-50M USD |
hq_location | string | Headquarters address |
city · country · geo_area | string | Headquarters city, country, and state or region |
activity_status | string | e.g. Active |
logo_url | string | Logo image URL |
lead_count | integer | People at the company in our database. Omitted when lead_counts=false |
meta | object | Pagination and totals. |
total_all | integer | Total matching companies |
total_all_display | string | Abbreviated total, e.g. 40M+ |
total_results | integer | Rows on this page |
list_size | integer | Requested page size |
max_results_size | integer | Rows reachable for this query on your plan (100 free, 1,000 paid, or fewer if fewer match) |
previous · next | integer | start of the previous and next pages, when they exist |
| Status | When | Response body |
|---|---|---|
| 400 | "Field size must be at most 20 on your plan." · "Search results are limited to the first 100 rows per query on your plan, so start must be below 100." · "Field keywordsMatch requires keywords." · "Field revenuePerEmployeeCurrency is required with revenuePerEmployeeMin or revenuePerEmployeeMax." · "Sort relevance requires keywords or companyName." · "Field sortDirection applies to employeeCount, foundedYear, totalRaised and revenue." · Unknown enum values (industry, technology, range…). | — |
| 401 | Missing or invalid API key. | — |
| 403 | FILTER_LOCKED: a premium filter or sort was used on a free plan after the 14-day trial. Remove the listed filters or upgrade. | — |
| 429 | "Too many search requests: 20 per minute. Retry in N seconds." · "Daily search limit reached: 50 requests per day. It resets at 00:00 UTC." | — |
| 502 | "Data gateway search is temporarily unavailable. Please retry shortly." | — |
Order of checks: API key (401) → request validation (400) → premium filters (403) → quotas (429) → search.
curl -X POST "https://api.skrapp.io/api/v3/companies/search?size=20&lead_counts=false" \
-H "X-Access-Key: YOUR_API_KEY" \
-H "Content-Type: application/json" \
-d '{
"keywords": ["cybersecurity", "managed services"],
"keywordsMatch": "any",
"geoRegions": ["Western Europe"],
"companySizeRanges": ["51-200", "201-500"],
"fundingDateFrom": "2025-01-01",
"headcountGrowth": [{ "period": "yearly", "percentage": true, "min": 15 }],
"exclude": { "companyTypes": ["Subsidiary"] },
"sort": "relevance"
}'{
"results": [
{
"id": "eMjwWd8bgOC5yKmKEo_G_cfAe7lFFIP5_uJkheLKRuF0CQc",
"internal_id": "5462236887991785263",
"name": "Swapcard",
"domain": "swapcard.com",
"website": "https://www.swapcard.com",
"industry": "Software Development",
"type": "Privately Held",
"founded": 2014,
"linkedin_url": "https://www.linkedin.com/company/swapcard",
"revenue_range": "10m_50m",
"revenue_range_formatted": "10M-50M USD",
"hq_location": "Paris, Île-de-France",
"activity_status": "Active",
"employee_count_range": "51-200",
"city": "Paris",
"country": "France",
"geo_area": "Île-de-France",
"logo_url": "https://logos-cdn.skrapp.io/logos/swapcard.com",
"lead_count": 145
}
],
"meta": { "total_all": 614, "total_all_display": "614", "total_results": 20,
"list_size": 20, "max_results_size": 614, "next": 20 }
}/api/v3/companies/snapshotv3Credits: No credits.
The free company card for one company: its name, website, industry, size, revenue range, headquarters and founding year. Use it to identify a company or show a profile; use Company enrich for financials, funding, technologies and signals.
| Limit | Free plan | Paid plan | How it counts |
|---|---|---|---|
| Requests per minute | 200 | 500 | Every request |
| Companies per UTC day | 500 | 5,000 | Distinct companies. Viewing a company you already viewed today is free. Resets at 00:00 UTC |
Over a limit, the API returns 429 with retry_after and a Retry-After header. Snapshot responses don't carry X-RateLimit-* headers. Snapshot never uses credits and has no trial: it works on every plan.
| Parameter | Type | Description |
|---|---|---|
id · internalIdone of | digits | The company's internal ID, e.g. the internal_id of a search result (both names work). Not the encoded id of a search result. |
domainone of | string | Company website or email domain, e.g. stripe.com. Case, http(s)://, www. and a trailing slash are ignored. Regional and alias domains (e.g. ebay.ca) resolve to the company that owns them. |
nameone of | string | Company name. When several companies share it, the most popular one is returned; use domain or id for an exact match. |
Send exactly one identifier. None, or more than one, returns 400 "Exactly one company identifier is required: id, internalId, domain, or name."
A single company object. Every field below is always present; it is null when we don't have the value.
| Field | Type | Description |
|---|---|---|
id | string | The company's internal ID: a numeric string larger than 2^53, so keep it a string. Pass it as id to Company snapshot, Company enrich and Company bulk enrich. Same value as internal_id in search results. |
company_name | string | The company's usual name, e.g. Stripe. |
domain | string | null | The company's main domain, used for its websites and work emails, without protocol or www., e.g. stripe.com. |
domain_region | object | null | Country-specific domains the company also uses, keyed by two-letter country code, e.g. {"CA": "ebay.ca", "DE": "ebay.de"}. null when the company has only its main domain. |
website | string | null | Full homepage URL, e.g. https://www.stripe.com. |
linkedin_url | string | null | URL of the company's LinkedIn page. |
company_logo | string | null | URL of the company logo image, served by Skrapp's CDN; safe to display directly. |
industry | string | null | Industry label, e.g. Software Development. Same values as the companyIndustries search filter. |
type | string | null | Company type: Public Company, Privately Held, Subsidiary, Non-Profit, Government Agency, Educational, Partnership, Self-Employed, Self-Owned or Sole Proprietorship. |
employees_range | string | null | Employee size range: 1-10, 11-50, 51-200, 201-500, 501-1,000, 1,001-5,000, 5,001-10,000 or 10,001+. The exact count is in Company enrich (headcount). |
revenue_range | string | null | Annual revenue range as a key: lt_1m, 1m_10m, 10m_50m, 50m_100m, 100m_250m, 250m_500m, 500m_1b, 1b_10b or gte_10b (USD). Exact figures are in Company enrich (financials). |
revenue_range_formatted | string | null | The same range as a label for display, e.g. 10M-50M USD, 10B+ USD. |
hq_location | string | null | Headquarters as one display string, e.g. South San Francisco, California, United States. |
hq_country | string | null | Headquarters country name, e.g. United States. Same values as the geoCountries search filter. |
hq_state | string | null | Headquarters state or region, e.g. California, Île-de-France. |
hq_city | string | null | Headquarters city, e.g. South San Francisco. |
founded_year | integer | null | Year the company was founded, e.g. 2010. |
activity_status | string | null | Whether the company is still operating, e.g. Active. |
| Status | When | Response body |
|---|---|---|
| 400 | No identifier or more than one: "Exactly one company identifier is required: id, internalId, domain, or name." · Wrong format: "The Data gateway could not process this company identifier. Check its format." | — |
| 401 | Missing or invalid API key. | — |
| 404 | "No company matches the given identifier." | — |
| 429 | "Too many snapshot requests: 500 per minute. Retry in N seconds." · "Daily snapshot limit reached: 5000 companies per day. It resets at 00:00 UTC." | — |
| 502 | "Data gateway enrichment is temporarily unavailable. Please retry shortly." | — |
Caching: responses are private, no-store; company data may be up to 24 hours old (1 hour for "not found").
curl "https://api.skrapp.io/api/v3/companies/snapshot?domain=stripe.com" \
-H "X-Access-Key: YOUR_API_KEY"{
"id": "8342903258370330161",
"domain": "stripe.com",
"domain_region": null,
"company_name": "Stripe",
"website": "https://www.stripe.com",
"linkedin_url": "https://www.linkedin.com/company/stripe",
"company_logo": "https://logos-cdn.skrapp.io/logos/stripe.com",
"industry": "Technology, Information and Internet",
"employees_range": "10,001+",
"revenue_range": "gte_10b",
"revenue_range_formatted": "10B+ USD",
"hq_location": "South San Francisco, California, United States",
"hq_country": "United States",
"hq_state": "California",
"hq_city": "South San Francisco",
"type": "Privately Held",
"founded_year": 2010,
"activity_status": "Active"
}/api/v3/companies/enrichv3Credits: 1–5 credits per category, once per company and category; repeat requests are free. See the entitlement rule.
Get detailed data about one company, organised in 12 categories. You choose the categories; each one costs credits the first time your account enriches it for that company, and is free after that. To enrich up to 20 companies at once, use Company bulk enrich, which follows the same rules.
How charging works
data: null and costs 0.| Request | Categories requested | Charged | total_cost |
|---|---|---|---|
| 1st | firmographics | firmographics 1 | 1 |
| 2nd | firmographics,headcount,funding | headcount 3 + funding 2 (firmographics already entitled) | 5 |
| 3rd, a month later | firmographics,headcount,funding | nothing: all entitled, data refreshed | 0 |
| 4th | all | the 9 remaining categories (19 credits) | 19 |
Pass category keys in categories. Costs below are charged once per company (see the entitlement rule). All 12 categories together cost 25 credits. Each key links to its field reference.
| Category key | Credits | What it contains |
|---|---|---|
| signals | 5 | Ready-made indicators computed from the company's data: growth trends, revenue per employee, profitability, burn rate and funding momentum. |
| headcount | 3 | Workforce size and its evolution, plus key executives and their arrivals and departures. |
| financials | 3 | Revenue (annual and quarterly), profitability, latest fiscal year results, market data and historical income statements. |
| hiring | 3 | Recruiting activity: open job postings now and over time. |
| funding | 2 | Fundraising history: totals, the last round and every funding event. |
| technographics | 2 | The technologies and tools the company uses. |
| acquisitions | 2 | Mergers and acquisitions made by, or of, the company. |
| firmographics | 1 | The full company profile: names, descriptions, classification, size, headquarters and all offices, logo and social links. |
| competitors | 1 | Companies similar to this one, with a similarity score and the reason. |
| social | 1 | Audience size on social networks and how it changes. |
| traffic | 1 | Website audience: visits, their change, global rank and main topics. |
| contacts | 1 | Generic company contact points (not individual people). |
| Parameter | Type | Description |
|---|---|---|
id · internalIdone identifier | digits | The company's internal ID, e.g. a search result's internal_id. |
domainone identifier | string | Company website or email domain, e.g. stripe.com. |
nameone identifier | string | Company name; the most popular match is used. Prefer domain or id for an exact company, since you are charged for the company returned. |
categoriesoptional | string | Category keys from Categories & Credits, comma-separated (headcount,funding) or repeated. Omit, or pass all, for all 12. Unknown keys return 400.Default: all 12 |
Send exactly one of id, internalId, domain or name.
| Field | Type | Description |
|---|---|---|
id | string | The company's internal ID (keep it a string). |
company_name · domain | string | Company name and main domain, to confirm which company was enriched. |
last_updated_at | ISO datetime | When this company's data was last refreshed on our side. |
total_cost | integer | Credits charged by this request: the sum of the category costs below. 0 when everything was already entitled or empty. |
categories | object | One entry per requested category, keyed by category key. |
<key>.cost | integer | Credits charged for this category by this request: its price on first enrichment, 0 if already entitled or empty. |
<key>.data | object | null | The category's fields (see Category fields), or null when we have no data for it. |
Every field of each category's data object. Click a category to expand it. Any field can be null when unknown. Conventions: amounts come with a _currency field and a _formatted label; _usd fields are converted to USD; …_percentage and value_pct are percents (2.79 = 2.79%); margins are fractions (0.47 = 47%); dates are YYYY-MM-DD.
signals5 creditsReady-made indicators computed from the company's data: growth trends, revenue per employee, profitability, burn rate and funding momentum.| Field | Type | Meaning |
|---|---|---|
| signals_trend | object[] | Trends, one item per measure and period. label is one of:Revenue growthrevenue_growthyearlyEmployee count changeemployee_count_changeJob postings changejob_postings_changeWebsite traffic changewebsite_traffic_changeMarket cap trajectorymarket_cap_trajectorypublic companiesLinkedIn follower changelinkedin_follower_change
|
| signal_revenue_per_employee | number | Annual revenue divided by employee count, in the company's revenue currency. |
| signal_profitability | object | is_profitable, net_income_latest, period_end_date of the latest fiscal year, ebitda_margin_latest (fraction: 0.2 = 20%) and ebitda_margin_trend (improving, stable, declining). |
| signal_burn_rate_proxy | object | Estimated cash burn: estimated_burn_usd (funds raised minus cumulative revenue), monthly_burn_rate_usd, months_since_founding, and data_quality (sufficient or insufficient: treat the estimate as indicative when insufficient). |
| signal_funding_momentum | object | momentum (accelerating, stable, decelerating), num_events (funding events), last_event_date, gap_latest_days (days between the last two rounds) and gap_previous_days (the gap before that). |
| signal_funding_stage | object | stage: the latest funding stage as reported, e.g. Series B, Post-IPO Debt; stage_normalized: a standardised stage when available. |
headcount3 creditsWorkforce size and its evolution, plus key executives and their arrivals and departures.| Field | Type | Meaning |
|---|---|---|
| employees_count | integer | Current number of employees. |
| employees_range | string | Size range: 1-10 … 10,001+ (same values as search). |
| employees_count_change | object | Change in employee count: current, absolute change_monthly, change_quarterly, change_yearly, and the same in percent (change_monthly_percentage…, 2.79 = 2.79%). |
| employees_count_by_month | object[] | Monthly history, most recent first: date (YYYY-MM-DD) and employees_count. |
| key_executives | object[] | Senior people at the company: member_full_name, member_position_title. |
| key_executive_arrivals | object[] | Recent executive hires: member_full_name, member_position_title, arrival_date. |
| key_executive_departures | object[] | Recent executive departures: member_full_name, member_position_title, departure_date. |
| key_employee_change_events | object[] | News about notable people joining or leaving: employee_change_event_name (headline), employee_change_event_date, employee_change_event_url (source article). |
financials3 creditsRevenue (annual and quarterly), profitability, latest fiscal year results, market data and historical income statements.| Field | Type | Meaning |
|---|---|---|
| revenue_annual · _currency · _formatted · _date | number · string | Latest annual revenue, its currency, a display label (e.g. 436B USD) and the date it was reported. |
| revenue_annual_range_from · _to · _currency · _formatted | number · string | Annual revenue range when only a range is known, e.g. 10B+ USD. |
| revenue_annual_previous_value (+ _currency, _formatted, _date) | number · string | The previous annual revenue figure, for comparison. |
| revenue_annual_growth · _growth_pct · _growth_period_days (+ _currency, _formatted) | number | Change between the previous and latest annual figures: absolute, in percent, and the number of days between them. |
| revenue_quarterly (+ the same _previous_value and _growth fields) | number · string | The same set of fields for quarterly revenue. |
| is_profitable | boolean | Positive net income in the latest fiscal year. |
| latest_fy_period_end_date · latest_fy_currency | string | End date and reporting currency of the latest fiscal year. |
| latest_fy_revenue · latest_fy_net_income · latest_fy_ebitda | number | Latest fiscal year figures in the reporting currency; each has _formatted, _usd (converted to USD) and _usd_formatted variants. |
| latest_fy_net_income_range · latest_fy_ebitda_range (+ _formatted) | enum | Range keys: lt_0, 0_1m, 1m_10m, 10m_100m, 100m_1b, gte_1b (USD). |
| latest_fy_gross_profit_margin · latest_fy_ebit_margin · latest_fy_ebitda_margin | number | Margins as fractions: 0.469 = 46.9%. |
| latest_fy_earnings_per_share | number | Earnings per share for the latest fiscal year. |
| is_public · ticker · stock_ticker | boolean · string · object[] | Whether the company is listed, its main ticker, and every listing as ticker and exchange. |
| ipo_date · ipo_share_price · ipo_share_price_currency | string · number | IPO date and price, for listed companies. |
| latest_marketcap (+ _currency, _formatted, _usd, _usd_formatted, _date) | number · string | Latest market capitalisation and the date it was observed. |
| marketcap_range · marketcap_range_formatted | enum · string | Range key: lt_100m, 100m_1b, 1b_10b, 10b_100b, 100b_1t, gte_1t (USD). |
| income_statements | object[] | Historical statements, one per period: period_type (year, q1…q4), period_end_date, currency, revenue, gross_profit, ebit, ebitda, net_income, pre_tax_profit, interest_income, interest_expense (each with _formatted), ebit_margin and ebitda_margin (fractions). |
| stock_information | object[] | Market history: date, closing_price, marketcap (+ marketcap_formatted), currency. |
hiring3 creditsRecruiting activity: open job postings now and over time.| Field | Type | Meaning |
|---|---|---|
| active_job_postings_count | integer | Number of job postings currently open. |
| active_job_postings_count_change | object | Change in open postings: current, absolute change_monthly, change_quarterly, change_yearly, and the same in percent (…_percentage). |
| active_job_postings_count_by_month | object[] | Monthly history, most recent first: date, active_job_postings_count. |
funding2 creditsFundraising history: totals, the last round and every funding event.| Field | Type | Meaning |
|---|---|---|
| total_amount_raised (+ _currency, _formatted) | number · string | Total raised across all rounds, e.g. 18.2B USD. |
| num_funding_rounds | integer | Number of funding rounds. |
| last_funding_round_name | string | Type of the last round, e.g. Series B, Secondary Market, Post-IPO Debt. |
| last_funding_round_announced_date | string | Announcement date of the last round (YYYY-MM-DD). |
| last_funding_round_amount_raised (+ _currency, _formatted) | number · string | Amount of the last round, when disclosed. |
| last_funding_round_num_investors · last_funding_round_lead_investors | integer · string[] | Number of investors and the lead investors of the last round. |
| funding_events | object[] | Every round: name (round type), announced_date, amount_raised (+ _currency, _formatted), lead_investors, num_investors. |
technographics2 creditsThe technologies and tools the company uses.| Field | Type | Meaning |
|---|---|---|
| num_technologies_used | integer | Number of technologies detected. |
| technologies_used | object[] | One item per technology: technology (name, e.g. snowflake), domain (the vendor's website), categories and parent_categories (e.g. data_warehousing), description, pricing_data (min_usd, max_usd, average_spend, interval, tags when known), and first_verified_at / last_verified_at (when it was first and last detected). |
acquisitions2 creditsMergers and acquisitions made by, or of, the company.| Field | Type | Meaning |
|---|---|---|
| num_acquisitions | integer | Number of companies acquired. |
| acquisition_list | object[] | Each acquisition: acquiree_name, announced_date, price (+ currency, price_formatted) when disclosed. |
| acquired_by_summary | object | null | Who acquired this company, when it has been acquired; otherwise null. |
firmographics1 creditThe full company profile: names, descriptions, classification, size, headquarters and all offices, logo and social links.| Field | Type | Meaning |
|---|---|---|
| company_name · friendly_company_name · company_legal_name | string | Usual name, short display name, and registered legal name (e.g. Stripe, LLC.). |
| company_name_aliases | string[] | Other names the company is known by. |
| linkedin_id | string | The company's LinkedIn ID. |
| domain · website · website_aliases | string · string[] | Main domain, homepage URL, and other URLs of the company's sites. |
| description · description_short · meta_description | string | Long description, one-sentence summary, and the description from the company's website. |
| industry · type | string | Industry label and company type (same values as search). |
| specialities · categories_and_keywords | string[] | Specialities the company lists, and topic tags describing what it does (used by the search keywords filter). |
| sic_codes · naics_codes | string[] | Industry classification codes. |
| is_b2b | boolean | Whether the company mainly sells to businesses. |
| founded_year | integer | Founding year. |
| size_range | string | Employee size as a label, e.g. 5001-10,000 employees. |
| revenue_range · revenue_range_formatted | enum · string | Revenue range key and label (same as snapshot). |
| activity_status · activity_status_comment | string | Operating status, e.g. active, with detail, e.g. Independent Company. |
| hq_location · hq_full_address · hq_street · hq_city · hq_state · hq_zipcode | string | Headquarters as a display string, full address, and its parts. |
| hq_country · hq_country_iso2 · hq_country_iso3 | string | Headquarters country name and ISO codes (US, USA). |
| hq_region | string[] | World regions of the headquarters, e.g. Americas, Northern America, AMER. |
| company_locations | object[] | Every known office: location_address, and is_primary (true for the headquarters). |
| company_logo | string | Logo image URL (Skrapp CDN). |
| linkedin_url · crunchbase_url | string | LinkedIn and Crunchbase pages. |
| twitter_url · facebook_url · instagram_url · youtube_url · github_url · reddit_url · discord_url · pinterest_url · tiktok_url | string[] | null | Social profiles, a list per network (a company may have several). |
| is_public · ticker | boolean · string | Listed status and main ticker (full market data is in financials). |
competitors1 creditCompanies similar to this one, with a similarity score and the reason.| Field | Type | Meaning |
|---|---|---|
| similar_companies_detailed | object[] | Ranked similar companies: company_name, domain, score (0–1, higher is closer), position (rank) and reason (why they are similar). |
| competitors | object[] | Competitor names as listed by data sources: company_name, similarity_score (may be null). |
| competitors_websites | string[] | null | Competitor websites, when available. |
social1 creditAudience size on social networks and how it changes.| Field | Type | Meaning |
|---|---|---|
| followers_count_linkedin · followers_count_twitter · followers_count_owler | integer | Followers on LinkedIn, X/Twitter and Owler. |
| linkedin_followers_count_change | object | LinkedIn follower change: current, absolute change_monthly, change_quarterly, change_yearly, and the same in percent (…_percentage). |
traffic1 creditWebsite audience: visits, their change, global rank and main topics.| Field | Type | Meaning |
|---|---|---|
| total_website_visits_monthly | integer | Estimated website visits per month. |
| total_website_visits_change | object | Change in monthly visits over time. |
| visits_change_monthly | object[] | Monthly visit history. |
| rank_global | integer | Global website traffic rank (lower is bigger). |
| top_topics | string[] | Main topics of the website's audience. |
contacts1 creditGeneric company contact points (not individual people).| Field | Type | Meaning |
|---|---|---|
| company_emails | string[] | Published company email addresses, e.g. press or support addresses. |
| company_phone_numbers | object[] | Published phone numbers: phone (display), e164 (international format, e.g. +18889262289), country_code. |
Free plans can enrich for 14 days after sign-up. After that, the endpoint returns 403 and nothing is charged. Paid plans have no time limit.
{
"status": 403,
"error": "FORBIDDEN",
"message": "Company enrichment is available on the free plan for 14 days after sign-up. Your trial ended on 2026-09-30 at 10:52 UTC. Upgrade your account at https://skrapp.io/pricing to continue.",
"reason": "TRIAL_EXPIRED",
"trial_ended_at": "2026-09-30T10:52:00.000Z",
"upgrade_url": "https://skrapp.io/pricing"
}No error is charged.
| Status | When | Response body |
|---|---|---|
| 400 | No identifier or more than one, an identifier in the wrong format, or an unknown category key. | — |
| 401 | Missing or invalid API key. | — |
| 402 | Not enough credits for this request. required counts only the categories that would be charged (not those already entitled or empty); categories lists their costs. | {"status":402,"error":"PAYMENT_REQUIRED","message":"Not enough credits: this request needs 25 and 3 are available.","required":25,"available":3,"categories":{"firmographics":1,"headcount":3,"…":"…"}} |
| 403 | Free plan after its 14-day trial (TRIAL_EXPIRED). | — |
| 404 | "No company matches the given identifier." | — |
| 502 | "Data gateway enrichment is temporarily unavailable. Please retry shortly." | — |
For a batch, see Company bulk enrich. Caching: private, no-store.
curl "https://api.skrapp.io/api/v3/companies/enrich?domain=stripe.com&categories=firmographics,headcount,funding" \
-H "X-Access-Key: YOUR_API_KEY"{
"id": "8342903258370330161",
"company_name": "Stripe",
"domain": "stripe.com",
"last_updated_at": "2026-05-28T00:00:00.000Z",
"total_cost": 5,
"categories": {
"firmographics": {
"cost": 0,
"data": {
"company_name": "Stripe",
"company_legal_name": "Stripe, LLC.",
"domain": "stripe.com",
"description_short": "Stripe, Inc. is a payment-processing software provider that serves businesses of various sizes.",
"industry": "Technology, Information and Internet",
"type": "Privately Held",
"founded_year": 2010,
"hq_location": "South San Francisco, California, United States",
"is_public": false,
"…": "…"
}
},
"headcount": {
"cost": 3,
"data": {
"employees_count": 15356,
"employees_range": "10,001+",
"employees_count_change": {
"current": 15356, "change_monthly": 417, "change_quarterly": 1057,
"change_monthly_percentage": 2.79, "change_quarterly_percentage": 7.39, "…": "…"
},
"employees_count_by_month": [ { "date": "2026-05-16", "employees_count": 15221 } ],
"key_executives": [ { "member_full_name": "Sam Hinton-Smith", "member_position_title": "London Site Lead" } ],
"…": "…"
}
},
"funding": {
"cost": 2,
"data": {
"total_amount_raised": 18198372725,
"total_amount_raised_currency": "USD",
"total_amount_raised_formatted": "18.2B USD",
"num_funding_rounds": 30,
"last_funding_round_name": "Secondary Market",
"last_funding_round_announced_date": "2026-03-01",
"last_funding_round_lead_investors": ["Robinhood Ventures"],
"funding_events": [
{ "name": "Series A", "announced_date": "2012-02-01", "amount_raised": 18000000,
"amount_raised_currency": "USD", "amount_raised_formatted": "18M USD", "num_investors": 1 }
],
"…": "…"
}
}
}
}{
"status": 402,
"error": "PAYMENT_REQUIRED",
"message": "Not enough credits: this request needs 25 and 3 are available.",
"required": 25,
"available": 3,
"categories": { "firmographics": 1, "headcount": 3, "…": "…" }
}/api/v3/companies/bulk-enrichv3Credits: Same as Company enrich, per company; all or nothing for the batch. See the entitlement rule.
Enrich up to 20 companies in one request. It is Company enrich run on a list: the same categories, prices, entitlement rule, category fields and free-plan trial. This section only covers what differs.
| Company enrich | Company bulk enrich | |
|---|---|---|
| Method and input | GET, identifier and categories in the query | POST, a JSON body with a companies list and one categories list for all of them |
| Companies | 1 | 1–20, results in input order |
| Company not found | 404 for the request | That item gets status: "not_found"; the others still succeed |
| Upstream failure | 502 for the request | That item gets status: "error", is not charged and can be retried alone |
| Not enough credits | 402, nothing charged | 402 for the whole batch, nothing charged; the body breaks the cost down per company |
| Same company twice | — | Inputs that resolve to the same company are fetched and charged once; the cost shows on the first, 0 on the others |
Cost of a batch
Each found company is priced exactly as a single Company enrich: only categories your account isn't yet entitled to, and that have data, are charged. The batch's total_cost is the sum of every company's total_cost.
| Parameter | Type | Description |
|---|---|---|
companiesrequired | object[] 1–20 | The companies to enrich. Each item has exactly one identifier: id or internalId (internal ID), domain, or name, as in Company enrich. One invalid item rejects the whole request with 400, naming its position. |
categoriesoptional | string[] | Category keys from Categories & Credits, applied to every company. Omit, or send ["all"], for all 12. Unknown keys return 400.Default: all 12 |
{ total_cost, results }, with one result per input, in the same order.
| Field | Type | Description |
|---|---|---|
total_cost | integer | Credits charged by the whole request: the sum of the found companies' total_cost. |
results | object[] | One item per input company, in input order. |
input | object | The identifier exactly as you sent it, to match results to inputs. |
status | enum | found, not_found or error. |
(when found) | — | Every field of the Company enrich response: id, company_name, domain, last_updated_at, total_cost (this company) and categories with each category's cost and data. |
message | string | Only for not_found ("No company matches the given identifier.") and error ("The Data gateway could not enrich this company. It was not charged; please retry it."). |
Request-level errors stop the whole batch and charge nothing. Per-company problems are reported in results[].status instead.
| Status | When | Response body |
|---|---|---|
| 400 | Empty or more than 20 companies, an item with no identifier or several, or an unknown category key. The message names the item's position. | — |
| 401 | Missing or invalid API key. | — |
| 402 | The batch needs more credits than are available. categories totals the cost per category across the batch; companies gives each company's chargeable categories, keyed by internal ID. Only categories that would actually be charged appear. | — |
| 403 | Free plan after its 14-day trial (TRIAL_EXPIRED, same body as Company enrich). | — |
| 413 | Body larger than 100 kB. | — |
Caching: private, no-store.
curl -X POST "https://api.skrapp.io/api/v3/companies/bulk-enrich" \
-H "X-Access-Key: YOUR_API_KEY" \
-H "Content-Type: application/json" \
-d '{
"companies": [
{ "domain": "stripe.com" },
{ "internalId": "5582989491351854253" },
{ "name": "Stripe" },
{ "domain": "unknown-company-example.io" }
],
"categories": ["headcount", "funding"]
}'{
"total_cost": 10,
"results": [
{
"input": { "domain": "stripe.com" },
"status": "found",
"id": "8342903258370330161",
"company_name": "Stripe",
"domain": "stripe.com",
"last_updated_at": "2026-05-28T00:00:00.000Z",
"total_cost": 5,
"categories": {
"headcount": { "cost": 3, "data": { "employees_count": 15356, "employees_range": "10,001+", "…": "…" } },
"funding": { "cost": 2, "data": { "total_amount_raised_formatted": "18.2B USD", "num_funding_rounds": 30, "…": "…" } }
}
},
{
"input": { "internalId": "5582989491351854253" },
"status": "found",
"id": "5582989491351854253",
"company_name": "Apple",
"domain": "apple.com",
"last_updated_at": "2026-09-15T13:54:51.646Z",
"total_cost": 5,
"categories": {
"headcount": { "cost": 3, "data": { "employees_count": 180689, "employees_range": "10,001+", "…": "…" } },
"funding": { "cost": 2, "data": { "total_amount_raised_formatted": "10.8B USD", "num_funding_rounds": 8, "…": "…" } }
}
},
{
"input": { "name": "Stripe" },
"status": "found",
"id": "8342903258370330161",
"company_name": "Stripe",
"domain": "stripe.com",
"last_updated_at": "2026-05-28T00:00:00.000Z",
"total_cost": 0,
"categories": {
"headcount": { "cost": 0, "data": { "employees_count": 15356, "…": "…" } },
"funding": { "cost": 0, "data": { "total_amount_raised_formatted": "18.2B USD", "…": "…" } }
}
},
{
"input": { "domain": "unknown-company-example.io" },
"status": "not_found",
"message": "No company matches the given identifier."
}
]
}{
"status": 402,
"error": "PAYMENT_REQUIRED",
"message": "Not enough credits: this request needs 10 and 3 are available.",
"required": 10,
"available": 3,
"categories": { "headcount": 6, "funding": 4 },
"companies": {
"8342903258370330161": { "headcount": 3, "funding": 2 },
"5582989491351854253": { "headcount": 3, "funding": 2 }
}
}/v3/verifyv3Credits: 1 credit per email, unless already verified or found by your account; shown in consumedCredit. See Credits.
Check whether an email address is deliverable before you send to it. Add enrich=true to also get the company behind a professional address.
| Parameter | Type | Description |
|---|---|---|
emailrequired | string | The email address to verify. It is not format-checked up front: a malformed address returns 200 with email_status: "invalid" and format: "invalid", and is charged 1 credit like any other verification. |
enrichoptional | boolean | true (or 1) adds companyData for professional addresses. Company data only; no person data. No extra credit.Default: false |
| Field | Type | Description |
|---|---|---|
email | string | The address that was verified, as sent. |
domain | string | The domain part of the address. |
email_status | string | valid, invalid, catch-all or unknown. See Verification statuses. |
message | string | Human-readable explanation of the result. Absent when the verification could not complete (status unknown). |
format | string | valid or invalid: whether the address is syntactically correct. Bad syntax is reported here, not as an HTTP error. |
mailbox_status | string | valid or invalid: the result of the mail-server check on this request. It can be invalid while email_status is valid, so always decide on email_status. |
mailbox_type | string | professional (company domain), webmail (free provider such as Gmail or Outlook.com) or temporary (disposable address). This is how free and disposable addresses are flagged; there are no separate boolean flags. |
mailbox_exchange | string | The mail server (MX host) for the domain. Absent when it was not determined on this request. |
consumedCredit | 0 | 1 | Credits charged by this verification. See Credits. |
companyData | object | null | Only with enrich=true. Absent when enrich is off, or when the address is not professional (webmail or disposable). null when the company is not found or the lookup fails. Otherwise every field below is present, null when unknown. |
id | string | null | Encoded company ID. |
name | string | null | Company name. |
domain | string | null | Main domain. |
website | string | null | Website URL. |
industry | string | null | Industry label. |
type | string | null | Company type. |
logo_url | string | null | Logo image URL. |
employee_count_range | string | null | Employee range with thousands separators, e.g. 1,001-5,000, 10,001+. |
founded | integer | null | Founding year. |
revenue | string | null | Revenue range label, e.g. 10B+ USD. |
address | string | null | Headquarters address. |
city | string | null | Headquarters city. |
country | string | null | Headquarters country. |
linkedin_url | string | null | LinkedIn company page. |
| Status | Meaning | What to do |
|---|---|---|
| valid | The mailbox exists and accepts mail. Addresses Skrapp already knows to be valid are also returned as valid. | Safe to send. |
| catch-all | The domain accepts every address, so the mailbox cannot be confirmed. | Send with care. |
| invalid | The mailbox does not exist or cannot receive mail. | Do not send. |
| unknown | The mail server did not give a usable answer, or verification failed after retries. Charged. | Retry later (charged again). |
Free and disposable addresses are flagged through mailbox_type: webmail for free providers, temporary for disposable addresses. Role addresses (such as info@) are not flagged.
| Status | When | Response body |
|---|---|---|
| 400 | email is missing. | {"statusCode":400,"message":"Bad Request"} |
| 401 | Missing or invalid key (the body says 403). | {"status":403,"message":"Not authorized"} |
| 403 | No credits left. | {"message":"Not enough credits","status":403} |
| 429 | Free plans: more than 100 verifications per IP in 24 h. | — |
| 503 | Authentication temporarily unavailable. Retry. | — |
curl "https://api.skrapp.io/v3/verify?email=jane.doe@acme.com&enrich=true" \
-H "X-Access-Key: YOUR_API_KEY"{
"email": "jane.doe@acme.com",
"domain": "acme.com",
"email_status": "valid",
"message": "Email is valid and successfully reachable.",
"format": "valid",
"mailbox_status": "valid",
"mailbox_type": "professional",
"mailbox_exchange": "aspmx.l.google.com",
"companyData": {
"id": "eMjwWd8bgOC5yKmKEo_G_cfAe7lFFIP5_uJkheLKRuF0CQc",
"name": "Acme Corp",
"domain": "acme.com",
"website": "https://www.acme.com",
"industry": "Software Development",
"type": "Privately Held",
"logo_url": "https://logos-cdn.skrapp.io/logos/acme.com",
"employee_count_range": "51-200",
"founded": 2012,
"revenue": "10M-50M USD",
"address": "100 Market Street, San Francisco, California, United States",
"city": "San Francisco",
"country": "United States",
"linkedin_url": "https://www.linkedin.com/company/acme-corp"
},
"consumedCredit": 1
}{
"email": "jane.doe@gmail.com",
"domain": "gmail.com",
"email_status": "valid",
"message": "Email is valid and successfully reachable.",
"format": "valid",
"mailbox_status": "valid",
"mailbox_type": "webmail",
"mailbox_exchange": "gmail-smtp-in.l.google.com",
"consumedCredit": 0
}/v3/verify_bulkv3Credits: Same as Email Verifier, per email. Needs at least as many credits left as emails sent. See Credits.
Verify up to 50 addresses in one call by repeating the email parameter. The request is synchronous: every address is verified inside the request and the results come back in the same response.
| Parameter | Type | Description |
|---|---|---|
emailrequired | string, repeated | One address per email= parameter, 2 to 50 of them. For a single address, use Email Verifier. |
An array of verification results, in the order sent, each with the same fields as Email Verifier and never companyData. If an address fails to verify for an internal reason it is left out, so the array can be shorter than the input: match results by email, not by position.
| Field | Type | Description |
|---|---|---|
[].email | string | The address that was verified, as sent. |
[].domain | string | The domain part of the address. |
[].email_status | string | valid, invalid, catch-all or unknown. See Verification statuses. |
[].message | string | Human-readable explanation of the result. Absent when the verification could not complete (status unknown). |
[].format | string | valid or invalid: whether the address is syntactically correct. Bad syntax is reported here, not as an HTTP error. |
[].mailbox_status | string | valid or invalid: the result of the mail-server check on this request. It can be invalid while email_status is valid, so always decide on email_status. |
[].mailbox_type | string | professional (company domain), webmail (free provider such as Gmail or Outlook.com) or temporary (disposable address). This is how free and disposable addresses are flagged; there are no separate boolean flags. |
[].mailbox_exchange | string | The mail server (MX host) for the domain. Absent when it was not determined on this request. |
[].consumedCredit | 0 | 1 | Credits charged by this verification. See Credits. |
| Status | When | Response body |
|---|---|---|
| 400 | Fewer than 2 or more than 50 email values. | {"statusCode":400,"message":"Bad Request"} |
| 401 | Missing or invalid key (the body says 403). | — |
| 403 | Fewer credits left than emails sent. | {"message":"Not enough credits","status":403} |
curl "https://api.skrapp.io/v3/verify_bulk?email=jane.doe@acme.com&email=john@globex.com" \
-H "X-Access-Key: YOUR_API_KEY"[
{
"email": "jane.doe@acme.com",
"domain": "acme.com",
"email_status": "valid",
"message": "Email is valid and successfully reachable.",
"format": "valid",
"mailbox_status": "valid",
"mailbox_type": "professional",
"mailbox_exchange": "aspmx.l.google.com",
"consumedCredit": 1
},
{
"email": "john@globex.com",
"domain": "globex.com",
"email_status": "unknown",
"format": "valid",
"mailbox_status": "valid",
"mailbox_type": "professional",
"mailbox_exchange": "mx.globex.com",
"consumedCredit": 1
}
]Lists hold the leads you save. These endpoints read and change your lists. They are all free and have no rate limit.
Shapes to know
id. Create list returns a listPath (/app/list/<id>), not an ID: the ID is the last path segment.next_start are numeric strings; list IDs are numbers.status field in bodies is sometimes a string ("404") and sometimes a number (404). Rely on the HTTP status code.PUT; renaming uses POST …/edit.| Endpoint | Purpose |
|---|---|
| GET /api/v2/account-lists | List your lists |
| GET /api/v2/list/:listId | Get a list: metadata and counts |
| GET /api/v2/list/:listId/leads | List a list's leads |
| PUT /api/v2/list/create | Create a list |
| POST /api/v2/list/:listId/edit | Rename a list |
| DELETE /api/v2/list/:listId | Delete a list |
| POST /api/v2/list/:listId/load | Add leads to a list |
| POST /api/v2/list/leads/delete | Delete leads |
| DELETE /api/v2/list/lead/:leadId | Delete a lead |
/api/v2/account-listsv2Credits: Free.
Return your lists, newest first, in one of two modes. Cursor mode (the default, or whenever last_list_id is sent) returns a plain array of up to 50 lists. Page mode (send page) returns { total_count, data }. Lead counts are not included: use Get a list or the lists of Account.
| Parameter | Type | Description |
|---|---|---|
last_list_idoptional | integer | Cursor mode: return lists with an ID lower than this one. Pass the last id of the previous call to get the next 50. |
pageoptional | integer ≥ 1 | Page mode: the page number, starting at 1. Ignored when last_list_id is sent. |
pageSizeoptional | integer | Page mode: lists per page.Default: 50 |
keywordoptional | string | Filter by list name, case-insensitive. Cursor mode matches names that start with it; page mode matches names that contain it. |
An array of up to 50 lists.
| Field | Type | Description |
|---|---|---|
[].id | integer | List ID. |
[].name | string | List name. |
[].path | string | App path, /app/list/<id>. |
[].frozen | boolean | true when the list is locked. |
| Field | Type | Description |
|---|---|---|
total_count | string | Total matching lists, as a numeric string. |
data | object[] | This page of lists: id, name, path, frozen. |
| Status | When | Response body |
|---|---|---|
| 404 | No list matches (an empty result returns 404, not []). | {"status":404,"message":"Not found"} |
curl "https://api.skrapp.io/api/v2/account-lists" \
-H "X-Access-Key: YOUR_API_KEY"[
{ "id": 17430846, "name": "Q4 outbound", "path": "/app/list/17430846", "frozen": false },
{ "id": 17429843, "name": "Acme accounts", "path": "/app/list/17429843", "frozen": false },
{ "id": 17266481, "name": "Enrichment test", "path": "/app/list/17266481", "frozen": false }
]curl "https://api.skrapp.io/api/v2/account-lists?page=1&pageSize=2&keyword=acme" \
-H "X-Access-Key: YOUR_API_KEY"{
"total_count": "1",
"data": [
{ "id": 17429843, "name": "Acme accounts", "path": "/app/list/17429843", "frozen": false }
]
}/api/v2/list/:listIdv2Credits: Free.
Return one list's metadata: name, type, creation date, lead and email counts, counts per email status, and whether it is frozen.
| Parameter | Type | Description |
|---|---|---|
listIdrequired | integer (path) | The list ID. |
preloadoptional | boolean | Send exactly true to also return the first 25 leads in preload.Default: false |
| Field | Type | Description |
|---|---|---|
list_id | integer | List ID. |
name | string | List name. |
creation_date | string | Creation time, ISO 8601. |
type | string | List type code, e.g. lds for a list of leads. |
count_leads | integer | Number of leads. |
count_leads_emails | integer | Number of leads with an email. |
valid_count | integer | Leads whose email is valid. |
invalid_count | integer | Leads whose email is invalid. |
catch_all_count | integer | Leads whose email is catch-all. |
unknown_count | integer | Leads whose email is unknown. |
pending_or_null_count | integer | Leads with no email or a verification still pending. |
frozen | boolean | true when the list is locked. |
preload | object[] | Only with preload=true: the first 25 leads, same fields as List a list's leads. |
| Status | When | Response body |
|---|---|---|
| 400 | listId is not a number. | {"status":"400","message":"Bad request"} |
| 404 | The list does not exist, is deleted or is not yours. | {"status":"404","message":"Not found"} |
curl "https://api.skrapp.io/api/v2/list/17430846" \
-H "X-Access-Key: YOUR_API_KEY"{
"list_id": 17430846,
"name": "Q4 outbound",
"creation_date": "2026-10-10T21:17:48.959Z",
"type": "lds",
"count_leads": 150,
"count_leads_emails": 150,
"invalid_count": 39,
"valid_count": 77,
"unknown_count": 3,
"catch_all_count": 31,
"pending_or_null_count": 0,
"frozen": false
}/api/v2/list/:listId/leadsv2Credits: Free.
Page through the leads of one list, newest first, optionally filtered by keyword.
Pagination: start is a cursor
start is an opaque cursor, not an offset. Leave it out for the first page, then pass the next_start of the previous response. When a page comes back with an empty data, there are no more leads (next_start is then absent).
| Parameter | Type | Description |
|---|---|---|
listIdrequired | integer (path) | The list ID. |
startoptional | string | Cursor: the next_start of the previous page. Omit for the first page. |
sizeoptional | integer | Leads per page, at most 500 (larger values are capped).Default: 25 |
kwoptional | string | Keyword, case-insensitive. Matches anywhere in the name, title, company, location or email. |
| Field | Type | Description |
|---|---|---|
data | object[] | This page of leads. |
id | string | Lead ID (numeric string). Use it with Delete lead. |
name | string | Full name. |
first_n | string | First name. |
last_n | string | Last name. |
email | string | null | Email address, when one was found or added. |
email_status | string | null | valid, invalid, catch-all or unknown. |
title | string | Job title. |
company | string | Company name. |
linkedin_url | string | null | LinkedIn profile path as stored, e.g. /in/jane-doe-0a1b2c3. It may be relative and is not always a full URL. |
img_url | null | Always null on this endpoint. |
location | string | Lead location. |
domain | string | Company domain. |
company_industry | string | null | Company industry. |
company_founded | string | null | Founding year, as a string, e.g. "2008". |
company_size | string | null | Employee range, e.g. 11-50. |
company_hq | object | null | Company headquarters. Keys are present only when known. |
city | string | City. |
state | string | State or region. |
country | string | Country. |
next_start | string | Cursor for the next page. Absent when data is empty. |
count_results | integer | Only with kw: leads matching the keyword. |
count_results_emails | integer | Only with kw: matching leads that have an email. |
A list that does not exist or is not yours returns 200 with {"data": []}, not 404.
| Status | When | Response body |
|---|---|---|
| 400 | listId is not a number. | {"status":"400","message":"Bad request"} |
| 404 | The leads could not be read. | {"status":"404","message":"Not found"} |
curl "https://api.skrapp.io/api/v2/list/17430846/leads?size=2" \
-H "X-Access-Key: YOUR_API_KEY"{
"next_start": "4452508940",
"data": [
{
"id": "4452509027",
"name": "Jane Doe",
"first_n": "Jane",
"last_n": "Doe",
"email": "jane.doe@acme-bio.com",
"email_status": "valid",
"title": "Research Associate",
"company": "Acme Therapeutics",
"linkedin_url": "/in/jane-doe-0a1b2c3",
"img_url": null,
"location": "Manchester, England, United Kingdom",
"domain": "acme-bio.com",
"company_industry": "Biotechnology",
"company_founded": "2008",
"company_size": "11-50",
"company_hq": { "city": "Manchester", "country": "United Kingdom" }
},
{
"id": "4452508940",
"name": "John Smith",
"first_n": "John",
"last_n": "Smith",
"email": "john.smith@acmecapital.com",
"email_status": "catch-all",
"title": "CEO & Co-Founder",
"company": "Acme Capital",
"linkedin_url": "/in/john-smith-4d5e6f7",
"img_url": null,
"location": "Portland, Oregon, United States",
"domain": "acmecapital.com",
"company_industry": "Real Estate",
"company_founded": "2012",
"company_size": "51-200",
"company_hq": { "city": "Portland", "state": "Oregon", "country": "United States" }
}
]
}curl "https://api.skrapp.io/api/v2/list/17430846/leads?size=2&start=4452508940" \
-H "X-Access-Key: YOUR_API_KEY"/api/v2/list/createv2Credits: Free.
Create an empty list. Note the PUT verb, and that the response gives the list path, not the ID: the ID is the last segment of listPath. To create a list and fill it in one call, use Add leads to a list with listId 0.
| Parameter | Type | Description |
|---|---|---|
namerequired | string | The list name. Must not be empty. |
sourceoptional | string | Optional label of where the list comes from. |
| Field | Type | Description |
|---|---|---|
listPath | string | App path of the new list, /app/list/<id>. |
| Status | When | Response body |
|---|---|---|
| 400 | name missing or empty. | {"status":"400","message":"Bad request"} |
| 500 | The list could not be created. | {"status":"500","message":"Internal server error"} |
curl -X PUT "https://api.skrapp.io/api/v2/list/create" \
-H "X-Access-Key: YOUR_API_KEY" \
-H "Content-Type: application/json" \
-d '{ "name": "Q4 outbound" }'{
"listPath": "/app/list/17430846"
}/api/v2/list/:listId/editv2Credits: Free.
Change the name of a list. Success returns 201 with a status body.
| Parameter | Type | Description |
|---|---|---|
listIdrequired | integer (path) | The list ID. |
listNamerequired | string (body) | The new name. Leading and trailing spaces are trimmed. |
| Field | Type | Description |
|---|---|---|
status | number | Always 201. |
message | string | Always Updated. |
| Status | When | Response body |
|---|---|---|
| 400 | listId is not a number, or listName is missing or empty. | {"status":400,"message":"Bad request"} |
| 401 | The list does not exist or is not yours. | {"status":401,"message":"Unauthorized update"} |
curl -X POST "https://api.skrapp.io/api/v2/list/17430846/edit" \
-H "X-Access-Key: YOUR_API_KEY" \
-H "Content-Type: application/json" \
-d '{ "listName": "Q4 outbound — EMEA" }'{
"status": 201,
"message": "Updated"
}/api/v2/list/:listIdv2Credits: Free.
Delete a list and its leads.
| Parameter | Type | Description |
|---|---|---|
listIdrequired | integer | The list ID. |
| Field | Type | Description |
|---|---|---|
status | string | Always "200" (a string). |
message | string | Always List deleted. |
| Status | When | Response body |
|---|---|---|
| 403 | The list cannot be deleted. | {"status":"403","message":"Forbidden"} |
| 404 | The list does not exist or is not yours. | {"status":"404","message":"Not found"} |
curl -X DELETE "https://api.skrapp.io/api/v2/list/17430846" \
-H "X-Access-Key: YOUR_API_KEY"{
"status": "200",
"message": "List deleted"
}/api/v2/list/:listId/loadv2Credits: Free. Adding leads does not find or verify emails.
Save up to 10,000 leads in a list in one request. Use listId 0 to create a new list and fill it in the same call. Leads you send are stored as given: send the email and quality you got from the Email Finder to keep them. Errors on this endpoint follow the Email Verifier error shapes.
| Parameter | Type | Description |
|---|---|---|
listIdrequired | integer (path) | The list to add to, or 0 to create a new list first. |
listNameoptional | string (body) | Name of the new list when listId is 0. Default unnamed list. |
sourceoptional | string (body) | Label of where the new list comes from, when listId is 0. Default app. |
leadsoptional | object[] (body) | The leads to add, at most 10,000. Fields per lead are below. Omit it (or send []) to only create the list. |
| Parameter | Type | Description |
|---|---|---|
nameoptional | string | Full name. |
firstNameoptional | string | First name. |
lastNameoptional | string | Last name. |
emailoptional | string | Email address. |
qualityoptional | object | Email status as returned by the Email Finder: { "status": "valid", "status_message": "…" }. status is saved as the lead's email_status. |
titleoptional | string | Job title. |
companyoptional | string | Company name. |
domainoptional | string | Company domain. |
companyIdoptional | string | Encoded company ID (as in Companies search results). |
linkedinUrloptional | string | LinkedIn profile URL. |
linkedinIdoptional | number | LinkedIn member ID. |
locationoptional | string | Location text; the country is read from it. |
imgUrloptional | string | Profile picture URL. |
| Field | Type | Description |
|---|---|---|
listPath | string | App path of the list, /app/list/<id> (the new list when listId was 0). |
inserted | integer | Leads added to the list. |
updated | integer | Leads that were already in the list and were updated. |
message | string | Only when no leads were sent: Nothing to save. Empty payload. |
| Status | When | Response body |
|---|---|---|
| 400 | The list does not exist or is not yours. | {"status":400,"message":"Failed to load lead: list not found or user not authorized to access the list."} |
| 400 | More than 10,000 leads, or an invalid body. | — |
| 401 | Missing or invalid key (the body says 403). | — |
| 403 | The list is frozen. | {"statusCode":403,"message":"List 17430846 is currently frozen.","error":"Forbidden"} |
curl -X POST "https://api.skrapp.io/api/v2/list/0/load" \
-H "X-Access-Key: YOUR_API_KEY" \
-H "Content-Type: application/json" \
-d '{
"listName": "Q4 outbound",
"leads": [
{
"firstName": "Jane",
"lastName": "Doe",
"email": "jane.doe@acme.com",
"quality": { "status": "valid" },
"title": "Head of Growth",
"company": "Acme Corp",
"domain": "acme.com",
"location": "San Francisco, California, United States"
}
]
}'{
"listPath": "/app/list/17430846",
"inserted": 1,
"updated": 0
}/api/v2/list/leads/deletev2Credits: Free.
Delete up to 1,000 leads in one request, from any of your lists. IDs that are not yours are skipped; deletedCount says how many were deleted.
| Parameter | Type | Description |
|---|---|---|
idsrequired | integer[] 1–1000 | Lead IDs to delete (the id of each lead). |
| Field | Type | Description |
|---|---|---|
status | string | Always "200". |
message | string | Always Leads deleted. |
deletedCount | integer | Number of leads deleted. |
| Status | When | Response body |
|---|---|---|
| 400 | ids missing, empty, longer than 1,000 or not integers. The body names the problem. | {"error":"\"ids\" must contain at least 1 items"} |
| 500 | The leads could not be deleted. | {"status":"500","message":"Internal server error"} |
curl -X POST "https://api.skrapp.io/api/v2/list/leads/delete" \
-H "X-Access-Key: YOUR_API_KEY" \
-H "Content-Type: application/json" \
-d '{ "ids": [4452509027, 4452508940] }'{
"status": "200",
"message": "Leads deleted",
"deletedCount": 2
}/api/v2/list/lead/:leadIdv2Credits: Free.
Delete one lead from its list.
| Parameter | Type | Description |
|---|---|---|
leadIdrequired | integer | The lead ID (id in the lead rows). |
| Field | Type | Description |
|---|---|---|
status | string | Always "200". |
message | string | Always Lead deleted. |
| Status | When | Response body |
|---|---|---|
| 403 | The lead cannot be deleted. | {"status":"403","message":"Forbidden"} |
| 404 | The lead does not exist or is not yours. | {"status":"404","message":"Not found"} |
curl -X DELETE "https://api.skrapp.io/api/v2/list/lead/4452509027" \
-H "X-Access-Key: YOUR_API_KEY"{
"status": "200",
"message": "Lead deleted"
}