SkrappAPI Reference
Get your API key

Skrapp API

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.

Base URL

Every endpoint is served from https://api.skrapp.io, followed by the path prefix of its version.

EndpointsVersionPath 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.

Your first call
# 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"

Authentication

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.

Authenticated request
curl "https://api.skrapp.io/api/v2/account" \
  -H "X-Access-Key: YOUR_API_KEY"

Errors

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.

  • 4xx: the request will not succeed on retry without a change. The exceptions are 408 and 429, which you can retry after a pause.
  • 5xx: temporary. Retry with backoff. Some 5xx responses may arrive as plain text instead of JSON.
  • Requests rejected with an error are not charged, except where an endpoint says otherwise.

Email Finder and Bulk Email Finder

Applies to /api/v2/find and /api/v2/find_bulk.

StatusWhenResponse body
400A required parameter is missing (Email Finder).{"status":400,"message":"Bad Request."}
400The body is empty or not a JSON array (Bulk Email Finder).{"code":400,"message":"Bad Request."}
400More than 500 rows (Bulk Email Finder).{"status":400,"limit":500,"message":"Payload too big. Limit is 500"}
400The body is not valid JSON.{"status":400,"response":"Bad JSON Format","error":"JSON"}
403Missing or invalid API key.{"status":403,"message":"Not authorized"}
403No 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"}
403Bulk Email Finder: fewer credits left than rows sent.{"status":403,"message":"Insufficient credits."}
403Free plans: the daily per-IP limit is reached, or the request was blocked by abuse protection. See Rate limits.{"status":403,"message":"Forbidden."}
404No 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"}
408The 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."}
429Too many requests for the credits you have left. See Rate limits.{"status":429,"message":"Too Many Requests"}
500Unexpected server error. Retry with backoff.{"status":500,"response":"Internal Server Error.","error":"<message>"}

Company data

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.

Validation error
{
  "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, …"
  ]
}
Rate limited
{
  "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"
}
StatusWhenResponse body
400Invalid parameters or body, invalid JSON, identifier in the wrong format.—
401No 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.—
402Company enrichment needs more credits than are available. Nothing is charged (see the entitlement rule). Only the company enrichment endpoints return 402.—
403Free plan after its 14-day trial: enrichment (TRIAL_EXPIRED) or a premium search filter (FILTER_LOCKED).—
404No company matches the identifier.—
413Body larger than 100 kB.—
429Rate limit reached.—
502Company data temporarily unavailable. Retry.—
503Authentication is temporarily unavailable: "Authentication is temporarily unavailable. Please retry shortly."—

Behaviour to know

  • Unknown fields in a company request body or query are silently ignored, so a misspelled filter does nothing instead of returning an error.

Phone lookup

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.

Email Verifier, Bulk Email Verifier and Add leads to a list

Applies to /v3/verify, /v3/verify_bulk and POST /api/v2/list/:listId/load.

StatusWhenResponse body
400Invalid or missing parameters. Detailed validation messages are not returned.{"statusCode":400,"message":"Bad Request"}
401Missing or invalid API key. The HTTP status is 401, but the body says 403.{"status":403,"message":"Not authorized"}
403Not enough credits for the request.{"message":"Not enough credits","status":403}
429Email Verifier, free plans: the daily per-IP limit is reached. See Rate limits.—
503Authentication is temporarily unavailable. Retry shortly.{"status":503,"message":"Authentication temporarily unavailable","reason":"auth_unavailable"}

Account and Lists

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.

StatusWhenResponse body
400Invalid path ID or body.{"status":"400","message":"Bad request"}
403Missing or invalid API key.{"status":403,"message":"Not authorized"}
404The account, list or lead was not found, or the result is empty.{"status":404,"message":"Not found"}
500Unexpected server error. Retry with backoff.{"status":"500","message":"Internal server error"}

Credits

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).

At a glance

ActionCost
Email Finder, Bulk Email Finder1 credit per email found for the first time. Not found is free.
Email Verifier, Bulk Email Verifier1 credit per email, unless already verified or found by your account.
Company enrich, Company bulk enrich1–5 credits per category, once per company and category (entitlement rule).
Phone lookup, Phone bulk lookup5 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 snapshotFree

Email Finder

  • 1 credit only when an email is found, and only if your account has never found that email before and has not already verified it.
  • Not found is free. A 404 never costs a credit.
  • Re-finding the same email is free.
  • The same rules apply to every row of a Bulk Email Finder request.
  • Before searching, your account needs at least one credit left in an active credit period, or the request returns 403 (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.

Refund of invalid results

The Email Finder verifies each email before answering. When the email it charged for turns out invalid or unknown, the credit is returned automatically:

  • Refunded when quality.status is invalid or unknown.
  • Paid plans only. Free plans are never refunded.
  • Only the first time your account found that email (a repeat find was free anyway).
  • catch-all and valid results stay charged.
  • The response does not show the refund. Check credit.email.used in Account if you need to reconcile.

Company enrichment

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.

Phone lookup

  • 5 credits per person number found · 1 when only company numbers are found. Not found is free.
  • Phone bulk lookup: same as Phone lookup, per person; all or nothing for the batch.
  • Free plan: included, uses your credits.
  • No error is charged.

Email Verifier

  • 1 credit per email, whatever the result, including invalid and malformed addresses (format: "invalid").
  • Free when your account already verified that email with a result other than 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.
  • No refunds on the verifier side.
  • A Bulk Email Verifier request needs at least as many credits left as emails sent, or it returns 403.

Rate limits

Limits depend on the endpoint and on your plan. Daily windows are UTC days and reset at 00:00 UTC.

EndpointFree planPaid planWhen exceeded
GET /api/v2/find150 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_bulkEach row counts toward the 150 per IP per UTC day.No limit.403 Forbidden.
GET /v3/verify100 requests per IP per 24 h.No limit.429
GET /v3/verify_bulkNo limit.No limit.—
Account and ListsNo limit.No limit.—
POST /api/v3/companies/search20 / min · 50 / day · page ≤ 20 · first 100 rows100 / min · 2,000 / day · page ≤ 100 · first 1,000 rows429 (rate) · 400 (page size, rows)
GET /api/v3/companies/snapshot200 / min · 500 distinct companies / day500 / min · 5,000 distinct companies / day429
Company enrich, Company bulk enrichNo 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).

Company data rate-limit headers

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.

HeaderMeaning
X-RateLimit-Limit-MinuteRequests allowed this minute
X-RateLimit-Remaining-MinuteRequests left this minute
X-RateLimit-Limit-DayRequests allowed today (UTC)
X-RateLimit-Remaining-DayRequests left today
Retry-AfterSeconds to wait, on 429 only

Account

GET/api/v2/accountv2

Credits: 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.

Response 200

FieldTypeDescription
namestringAccount name.
emailstringAccount email.
packagestringPlan name, e.g. Professional 5K.
packageRDatenumberEnd 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.
creditobjectCredit balance.
emailobjectCredits for finding, verifying and enriching. Remaining = quota - used.
quotaintegerCredits in the current period.
usedintegerCredits used so far, at most quota. Equal to quota once the period has ended.
lists_countintegerNumber of lists on the account.
listsobject[]The 50 most recent lists. For all lists, use List your lists.
idintegerList ID.
namestringList name.
pathstringApp path of the list, /app/list/<id>.
frozenbooleantrue when the list is locked and cannot be changed.
sizeintegerNumber of leads in the list.

Errors

StatusWhenResponse body
403Missing or invalid key.{"status":403,"message":"Not authorized"}
404Account not found.{"status":404,"message":"Not found"}
Request
curl "https://api.skrapp.io/api/v2/account" \
  -H "X-Access-Key: YOUR_API_KEY"
200 — response
{
  "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 }
  ]
}

Email Finder

GET/api/v2/findv2

Credits: 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

  • A name: fullName, or firstName and lastName together.
  • A company: domain or company. When both are sent, domain wins.
  • Anything else returns 400 {"status":400,"message":"Bad Request."}.

Query parameters

ParameterTypeDescription
firstNamewith lastNamestringThe person's first name. Send with lastName, or send fullName instead.
lastNamewith firstNamestringThe person's last name.
fullNameor first + laststringThe full name, parsed into first and last name. Takes priority over firstName and lastName when sent.
domainor companystringThe 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 domainstringThe company name, resolved to its domain from Skrapp company data. If it cannot be resolved, the response is 404.
countryoptionalstringCountry name or ISO 2-letter code. Used only for companies with 1,000+ employees, to pick a country-specific email domain.
includeCompanyDataoptionalstringSend 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.

Response 200

An email was found. Fields that do not apply are absent rather than null.

FieldTypeDescription
emailstringThe email address found.
patternstringThe address pattern used at this domain, e.g. {first}.{last} or {f}{last}. Placeholders: {first}, {last}, {f} (first initial), {l} (last initial). Informational.
qualityobjectThe verification result for email.
statusstringvalid, invalid, catch-all or unknown. See Verification statuses.
status_messagestringA sentence explaining the status, e.g. "jane.doe@acme.com is a valid email address." Absent when verification could not complete (status unknown).
companyDataobjectOnly 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.
idstringEncoded company ID (the same form as id in Companies search results).
namestringCompany name.
domainstringMain company domain.
websitestringWebsite URL.
industrystringIndustry label.
typestringCompany type, e.g. Privately Held.
foundedintegerFounding year.
linkedin_urlstringLinkedIn company page.
revenuestringRevenue range as a label, e.g. 10M-50M USD.
employee_count_rangestringEmployee range without thousands separators: 2-10, 11-50, 51-200, 201-500, 501-1000, 1001-5000, 5001-10000, 10001+.
addressstringHeadquarters address on one line.
citystringHeadquarters city.
countrystringHeadquarters country.
geo_areastringHeadquarters state or region.
logo_urlstringLogo image URL.

Errors

StatusWhenResponse body
400No name, or no domain or company.{"status":400,"message":"Bad Request."}
403Missing or invalid key; no credits left (email_limit_exeeded); free-plan daily IP limit. See Errors.—
404No email found, or the company could not be resolved. Free.{"status":"404","message":"Not found"}
408Timed out after 10 s. Not charged; retry.—
429Burst above the credits you have left. See Rate limits.—
Request: name + domain
curl "https://api.skrapp.io/api/v2/find?firstName=Jane&lastName=Doe&domain=acme.com" \
  -H "X-Access-Key: YOUR_API_KEY"
200 — found
{
  "email": "jane.doe@acme.com",
  "pattern": "{first}.{last}",
  "quality": {
    "status": "valid",
    "status_message": "jane.doe@acme.com is a valid email address."
  }
}
Request: full name + company + company data
curl "https://api.skrapp.io/api/v2/find?fullName=Jane%20Doe&company=Acme%20Corp&includeCompanyData=true" \
  -H "X-Access-Key: YOUR_API_KEY"
200 — found, with companyData
{
  "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"
  }
}
404 — not found
{
  "status": "404",
  "message": "Not found"
}

Bulk Email Finder

POST/api/v2/find_bulkv2

Credits: 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

  • The body is a top-level JSON array of rows, not an object. Do not wrap it (e.g. in {"people": [...]}).
  • At most 500 rows. More returns 400 {"status":400,"limit":500,"message":"Payload too big. Limit is 500"}.
  • Each row needs a name (firstName + lastName, or name) and a company (domain or company).
  • The request times out after 60 s (408, not charged).

Row fields

ParameterTypeDescription
tIdoptionalstringYour own ID for the row, echoed back so you can match results to your records.
firstNamewith lastNamestringFirst name. Send with lastName, or send name.
lastNamewith firstNamestringLast name.
nameor first + laststringFull name, parsed into first and last name.
domainone company fieldstringCompany domain. A value that does not look like a domain is treated as a company name.
companyone company fieldstringCompany name, resolved to its domain.
countryoptionalstringCountry name or ISO 2-letter code, used for country-specific domains of large companies. Not echoed back.

Response 200

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.

FieldTypeDescription
[].tIdstringYour row ID, echoed.
[].firstNamestringFirst name, parsed and capitalised.
[].lastNamestringLast name, parsed and capitalised.
[].namestring | nullFull name, capitalised, as sent.
[].domainstringOn a hit, the domain of the company that was searched.
[].companystringOn a hit, the company name from Skrapp company data.
[].emailstringThe email found. Absent on a miss.
[].qualityobjectVerification result, same shape as the Email Finder quality. Absent on a miss.
statusstringvalid, invalid, catch-all or unknown.
status_messagestringA 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.

Errors

StatusWhenResponse body
400Empty body, or not a JSON array.{"code":400,"message":"Bad Request."}
400More than 500 rows.{"status":400,"limit":500,"message":"Payload too big. Limit is 500"}
403Fewer credits left than rows sent.{"status":403,"message":"Insufficient credits."}
403Missing or invalid key, no credits left, or free-plan daily IP limit. See Errors.—
408Timed out after 60 s. Not charged; retry.—
Request
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" }
  ]'
200 — results, in input order
[
  {
    "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"
  }
]

Phone lookup

GET/api/v3/people/phonev3

Credits: 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.

Cost
5 credits per person number · 1 for company numbers only
Rate limit
None
Free plan
Included, uses your credits

Query parameters

ParameterTypeDescription
linkedinUrlone identifierstringLinkedIn 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 identifierstringFirst name, e.g. Jane. Send with lastName. Max 100 characters.
lastNameone identifierstringLast name, e.g. Doe. Send with firstName. Max 100 characters.
fullNameone identifierstringFull name, e.g. Jane Doe, instead of firstName and lastName. If you send both, firstName + lastName are tried first. Max 200 characters.
companyDomainoptionalstringThe person's company domain, e.g. example.com. Tried before companyName.
companyNameoptionalstringThe person's company name, e.g. Example Ltd. Prefer companyDomain for an exact company.
countryoptionalISO 3166-1 alpha-2e.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.
  • Or a name with one of 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.
  • A name with only a 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.

Response 200

FieldTypeDescription
idstring | nullThe person's ID. null when no person matched and only company numbers are returned.
company_idstring | nullThe company's ID, the same as in Company enrich. Set only when the numbers are company numbers.
phonesobject[]The numbers found. Empty when the person has no usable number, at no cost.
typeenummobile, direct or company.
phonestringThe number as listed.
phone_e164stringThe number in E.164 format.
country_codestringDialling code, e.g. 44.
country_isostring | nullISO 3166-1 alpha-2 country of the number.
extensionstring | nullExtension, when the number has one.
confidenceenum | nullThe level of confidence_score: high from 0.9, medium from 0.5, low below 0.5. null when only company numbers are returned.
confidence_scorenumber | nullHow 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.
costintegerCredits this request charged.

Errors

No error is charged.

StatusWhenResponse body
400Missing or invalid identifiers, e.g. a name with no company or country. The message names the field.—
401Missing or invalid API key.—
402Not enough credits: this request needs 5 and 2 are available. Nothing is charged.required, available, categories
404No person matches the given identifiers.—
502Phone lookup is temporarily unavailable. Please retry shortly.—

Caching: private, no-store.

Request
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"
200 — a mobile number found
{
  "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
}
402 — not enough credits
{
  "status": 402,
  "error": "PAYMENT_REQUIRED",
  "message": "Not enough credits: this request needs 5 and 2 are available.",
  "required": 5,
  "available": 2,
  "categories": { "phone": 5 }
}

Phone bulk lookup

POST/api/v3/people/phone/bulkv3

Credits: 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.

People per request
1–50
Cost
Same as Phone lookup, per person
Credit check
All or nothing for the batch
Rate limit
None

What differs from Phone lookup

Phone lookupPhone bulk lookup
Method and inputGET, query parametersPOST, JSON body
People11–50, results in input order
Person not found404That item gets status: "not_found"; the others still succeed
Upstream failure502That item gets status: "error", is not charged and can be retried alone
Not enough credits402, nothing charged402 for the whole batch, nothing charged
Same person twice—Charged once; the cost shows on the first, 0 on the others

Body (JSON)

ParameterTypeDescription
peoplerequiredobject[] 1–50Each item takes the Phone lookup query parameters. One invalid item rejects the whole request with 400, naming its position.

Response 200

{ total_cost, results }, with one result per input, in the same order.

FieldTypeDescription
total_costintegerCredits this request charged, for all people.
resultsobject[]One result per input, in the same order.
inputobjectThe item exactly as you sent it, to match results to inputs.
statusenumfound, not_found or error.
(when found)—The Phone lookup response fields: id, company_id, phones, confidence, confidence_score, cost.
messagestringOnly for error: "Phone lookup failed for this entry. Retry it."

Errors

Request-level errors stop the whole batch and charge nothing. Per-person problems are reported in results[].status instead.

StatusWhenResponse body
400Empty or more than 50 people, or an invalid item. The message names the item's position.—
401Missing or invalid API key.—
402Not enough credits for the batch. Nothing is charged.required, available, categories
502Phone lookup is temporarily unavailable. Please retry shortly.—
Request
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"}]}'
200 — one person number, one company number, one not found (arrays shortened)
{
  "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" }
  ]
}

Company data

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.

Endpoints

EndpointWhat it doesCreditsRate limit
POST /companies/searchFilter companies with 60+ filters: keywords, firmographics, location, headcount, hiring, financials, funding, technologies, lookalikes and signalsFreePer plan, minute + day
GET /companies/snapshotThe free company card, by internal ID, domain or nameFreePer plan, minute + distinct companies per day
GET /companies/enrichReturn enrichment data for one company, using creditsPer categoryNone
POST /companies/bulk-enrichEnrich up to 20 companies in one requestPer categoryNone

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.

Company IDs

Two company identifiers appear in responses, and they are not interchangeable.

IdentifierReturned asUse it inExample (Stripe)
Internal ID: numeric string, larger than 2^53: keep it a stringinternal_id in search results; id in snapshot and enrich responsesThe id input of Company snapshot, Company enrich and Company bulk enrich8342903258370330161
Encoded company ID: opaque stringid in search resultsCompanies search filters only: companyIds, exclude.companyIdsBkAautTuXYiAK_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."

Company snapshot

GET/api/v3/companies/snapshotv3

Credits: 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.

Credits
None
Free plan
200 / min · 500 companies / day
Paid plan
500 / min · 5,000 companies / day

Quotas

LimitFree planPaid planHow it counts
Requests per minute200500Every request
Companies per UTC day5005,000Distinct 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.

Query parameters: exactly one identifier

ParameterTypeDescription
id · internalIdone ofdigitsThe 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 ofstringCompany 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 ofstringCompany 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."

Response 200

A single company object. Every field below is always present; it is null when we don't have the value.

FieldTypeDescription
idstringThe 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_namestringThe company's usual name, e.g. Stripe.
domainstring | nullThe company's main domain, used for its websites and work emails, without protocol or www., e.g. stripe.com.
domain_regionobject | nullCountry-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.
websitestring | nullFull homepage URL, e.g. https://www.stripe.com.
linkedin_urlstring | nullURL of the company's LinkedIn page.
company_logostring | nullURL of the company logo image, served by Skrapp's CDN; safe to display directly.
industrystring | nullIndustry label, e.g. Software Development. Same values as the companyIndustries search filter.
typestring | nullCompany type: Public Company, Privately Held, Subsidiary, Non-Profit, Government Agency, Educational, Partnership, Self-Employed, Self-Owned or Sole Proprietorship.
employees_rangestring | nullEmployee 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_rangestring | nullAnnual 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_formattedstring | nullThe same range as a label for display, e.g. 10M-50M USD, 10B+ USD.
hq_locationstring | nullHeadquarters as one display string, e.g. South San Francisco, California, United States.
hq_countrystring | nullHeadquarters country name, e.g. United States. Same values as the geoCountries search filter.
hq_statestring | nullHeadquarters state or region, e.g. California, Île-de-France.
hq_citystring | nullHeadquarters city, e.g. South San Francisco.
founded_yearinteger | nullYear the company was founded, e.g. 2010.
activity_statusstring | nullWhether the company is still operating, e.g. Active.

Errors

StatusWhenResponse body
400No 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."—
401Missing 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").

Request
curl "https://api.skrapp.io/api/v3/companies/snapshot?domain=stripe.com" \
  -H "X-Access-Key: YOUR_API_KEY"
200 — response
{
  "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"
}

Company enrich

GET/api/v3/companies/enrichv3

Credits: 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.

Cost
1–5 credits per category · 25 for all
Repeat requests
Free (entitlement)
Rate limit
None
Free plan
14-day trial from sign-up

Entitlement rule: pay once per company and category

How charging works

  1. First enrichment is charged. When your account enriches a category of a company for the first time, the category's credits are charged and your account becomes entitled to it.
  2. Entitled data is free forever. Any later request for that company and category costs 0 and returns the latest data we have, so you can refresh it at no cost. Entitlements don't expire.
  3. Only what you request, and only real data. Categories you don't request are never charged, and a category with no data for that company returns data: null and costs 0.
  4. Per account. Entitlement belongs to the account whose API key made the request; another account enriching the same company pays for it separately.
  5. All or nothing. If the request needs more credits than you have, it returns 402 and nothing is charged or granted. Errors (400, 404, 5xx) are never charged.
Example: enriching Stripe
RequestCategories requestedChargedtotal_cost
1stfirmographicsfirmographics 11
2ndfirmographics,headcount,fundingheadcount 3 + funding 2 (firmographics already entitled)5
3rd, a month laterfirmographics,headcount,fundingnothing: all entitled, data refreshed0
4thallthe 9 remaining categories (19 credits)19

Categories & Credits

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 keyCreditsWhat it contains
signals5Ready-made indicators computed from the company's data: growth trends, revenue per employee, profitability, burn rate and funding momentum.
headcount3Workforce size and its evolution, plus key executives and their arrivals and departures.
financials3Revenue (annual and quarterly), profitability, latest fiscal year results, market data and historical income statements.
hiring3Recruiting activity: open job postings now and over time.
funding2Fundraising history: totals, the last round and every funding event.
technographics2The technologies and tools the company uses.
acquisitions2Mergers and acquisitions made by, or of, the company.
firmographics1The full company profile: names, descriptions, classification, size, headquarters and all offices, logo and social links.
competitors1Companies similar to this one, with a similarity score and the reason.
social1Audience size on social networks and how it changes.
traffic1Website audience: visits, their change, global rank and main topics.
contacts1Generic company contact points (not individual people).

Query parameters

ParameterTypeDescription
id · internalIdone identifierdigitsThe company's internal ID, e.g. a search result's internal_id.
domainone identifierstringCompany website or email domain, e.g. stripe.com.
nameone identifierstringCompany name; the most popular match is used. Prefer domain or id for an exact company, since you are charged for the company returned.
categoriesoptionalstringCategory 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.

Response 200

FieldTypeDescription
idstringThe company's internal ID (keep it a string).
company_name · domainstringCompany name and main domain, to confirm which company was enriched.
last_updated_atISO datetimeWhen this company's data was last refreshed on our side.
total_costintegerCredits charged by this request: the sum of the category costs below. 0 when everything was already entitled or empty.
categoriesobjectOne entry per requested category, keyed by category key.
<key>.costintegerCredits charged for this category by this request: its price on first enrichment, 0 if already entitled or empty.
<key>.dataobject | nullThe category's fields (see Category fields), or null when we have no data for it.

Category fields

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.
FieldTypeMeaning
signals_trendobject[]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
  • period: monthly, quarterly or yearly.
  • trend: growth or decline.
  • value_pct: size of the change in percent (2.79 = 2.79%).
signal_revenue_per_employeenumberAnnual revenue divided by employee count, in the company's revenue currency.
signal_profitabilityobjectis_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_proxyobjectEstimated 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_momentumobjectmomentum (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_stageobjectstage: 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.
FieldTypeMeaning
employees_countintegerCurrent number of employees.
employees_rangestringSize range: 1-10 … 10,001+ (same values as search).
employees_count_changeobjectChange 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_monthobject[]Monthly history, most recent first: date (YYYY-MM-DD) and employees_count.
key_executivesobject[]Senior people at the company: member_full_name, member_position_title.
key_executive_arrivalsobject[]Recent executive hires: member_full_name, member_position_title, arrival_date.
key_executive_departuresobject[]Recent executive departures: member_full_name, member_position_title, departure_date.
key_employee_change_eventsobject[]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.
FieldTypeMeaning
revenue_annual · _currency · _formatted · _datenumber · stringLatest annual revenue, its currency, a display label (e.g. 436B USD) and the date it was reported.
revenue_annual_range_from · _to · _currency · _formattednumber · stringAnnual revenue range when only a range is known, e.g. 10B+ USD.
revenue_annual_previous_value (+ _currency, _formatted, _date)number · stringThe previous annual revenue figure, for comparison.
revenue_annual_growth · _growth_pct · _growth_period_days (+ _currency, _formatted)numberChange 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 · stringThe same set of fields for quarterly revenue.
is_profitablebooleanPositive net income in the latest fiscal year.
latest_fy_period_end_date · latest_fy_currencystringEnd date and reporting currency of the latest fiscal year.
latest_fy_revenue · latest_fy_net_income · latest_fy_ebitdanumberLatest 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)enumRange 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_marginnumberMargins as fractions: 0.469 = 46.9%.
latest_fy_earnings_per_sharenumberEarnings per share for the latest fiscal year.
is_public · ticker · stock_tickerboolean · 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_currencystring · numberIPO date and price, for listed companies.
latest_marketcap (+ _currency, _formatted, _usd, _usd_formatted, _date)number · stringLatest market capitalisation and the date it was observed.
marketcap_range · marketcap_range_formattedenum · stringRange key: lt_100m, 100m_1b, 1b_10b, 10b_100b, 100b_1t, gte_1t (USD).
income_statementsobject[]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_informationobject[]Market history: date, closing_price, marketcap (+ marketcap_formatted), currency.
hiring3 creditsRecruiting activity: open job postings now and over time.
FieldTypeMeaning
active_job_postings_countintegerNumber of job postings currently open.
active_job_postings_count_changeobjectChange in open postings: current, absolute change_monthly, change_quarterly, change_yearly, and the same in percent (…_percentage).
active_job_postings_count_by_monthobject[]Monthly history, most recent first: date, active_job_postings_count.
funding2 creditsFundraising history: totals, the last round and every funding event.
FieldTypeMeaning
total_amount_raised (+ _currency, _formatted)number · stringTotal raised across all rounds, e.g. 18.2B USD.
num_funding_roundsintegerNumber of funding rounds.
last_funding_round_namestringType of the last round, e.g. Series B, Secondary Market, Post-IPO Debt.
last_funding_round_announced_datestringAnnouncement date of the last round (YYYY-MM-DD).
last_funding_round_amount_raised (+ _currency, _formatted)number · stringAmount of the last round, when disclosed.
last_funding_round_num_investors · last_funding_round_lead_investorsinteger · string[]Number of investors and the lead investors of the last round.
funding_eventsobject[]Every round: name (round type), announced_date, amount_raised (+ _currency, _formatted), lead_investors, num_investors.
technographics2 creditsThe technologies and tools the company uses.
FieldTypeMeaning
num_technologies_usedintegerNumber of technologies detected.
technologies_usedobject[]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.
FieldTypeMeaning
num_acquisitionsintegerNumber of companies acquired.
acquisition_listobject[]Each acquisition: acquiree_name, announced_date, price (+ currency, price_formatted) when disclosed.
acquired_by_summaryobject | nullWho 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.
FieldTypeMeaning
company_name · friendly_company_name · company_legal_namestringUsual name, short display name, and registered legal name (e.g. Stripe, LLC.).
company_name_aliasesstring[]Other names the company is known by.
linkedin_idstringThe company's LinkedIn ID.
domain · website · website_aliasesstring · string[]Main domain, homepage URL, and other URLs of the company's sites.
description · description_short · meta_descriptionstringLong description, one-sentence summary, and the description from the company's website.
industry · typestringIndustry label and company type (same values as search).
specialities · categories_and_keywordsstring[]Specialities the company lists, and topic tags describing what it does (used by the search keywords filter).
sic_codes · naics_codesstring[]Industry classification codes.
is_b2bbooleanWhether the company mainly sells to businesses.
founded_yearintegerFounding year.
size_rangestringEmployee size as a label, e.g. 5001-10,000 employees.
revenue_range · revenue_range_formattedenum · stringRevenue range key and label (same as snapshot).
activity_status · activity_status_commentstringOperating status, e.g. active, with detail, e.g. Independent Company.
hq_location · hq_full_address · hq_street · hq_city · hq_state · hq_zipcodestringHeadquarters as a display string, full address, and its parts.
hq_country · hq_country_iso2 · hq_country_iso3stringHeadquarters country name and ISO codes (US, USA).
hq_regionstring[]World regions of the headquarters, e.g. Americas, Northern America, AMER.
company_locationsobject[]Every known office: location_address, and is_primary (true for the headquarters).
company_logostringLogo image URL (Skrapp CDN).
linkedin_url · crunchbase_urlstringLinkedIn and Crunchbase pages.
twitter_url · facebook_url · instagram_url · youtube_url · github_url · reddit_url · discord_url · pinterest_url · tiktok_urlstring[] | nullSocial profiles, a list per network (a company may have several).
is_public · tickerboolean · stringListed status and main ticker (full market data is in financials).
competitors1 creditCompanies similar to this one, with a similarity score and the reason.
FieldTypeMeaning
similar_companies_detailedobject[]Ranked similar companies: company_name, domain, score (0–1, higher is closer), position (rank) and reason (why they are similar).
competitorsobject[]Competitor names as listed by data sources: company_name, similarity_score (may be null).
competitors_websitesstring[] | nullCompetitor websites, when available.
social1 creditAudience size on social networks and how it changes.
FieldTypeMeaning
followers_count_linkedin · followers_count_twitter · followers_count_owlerintegerFollowers on LinkedIn, X/Twitter and Owler.
linkedin_followers_count_changeobjectLinkedIn 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.
FieldTypeMeaning
total_website_visits_monthlyintegerEstimated website visits per month.
total_website_visits_changeobjectChange in monthly visits over time.
visits_change_monthlyobject[]Monthly visit history.
rank_globalintegerGlobal website traffic rank (lower is bigger).
top_topicsstring[]Main topics of the website's audience.
contacts1 creditGeneric company contact points (not individual people).
FieldTypeMeaning
company_emailsstring[]Published company email addresses, e.g. press or support addresses.
company_phone_numbersobject[]Published phone numbers: phone (display), e164 (international format, e.g. +18889262289), country_code.

Free plan: 14-day trial

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.

403 — trial expired
{
  "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"
}

Errors

No error is charged.

StatusWhenResponse body
400No identifier or more than one, an identifier in the wrong format, or an unknown category key.—
401Missing or invalid API key.—
402Not 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,"…":"…"}}
403Free 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.

Request
curl "https://api.skrapp.io/api/v3/companies/enrich?domain=stripe.com&categories=firmographics,headcount,funding" \
  -H "X-Access-Key: YOUR_API_KEY"
200 — 2nd request of the example (arrays shortened)
{
  "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 }
        ],
        "…": "…"
      }
    }
  }
}
402 — not enough credits
{
  "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, "…": "…" }
}

Company bulk enrich

POST/api/v3/companies/bulk-enrichv3

Credits: 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.

Companies per request
1–20
Cost
Same as Company enrich, per company
Credit check
All or nothing for the batch
Rate limit
None

What differs from Company enrich

Company enrichCompany bulk enrich
Method and inputGET, identifier and categories in the queryPOST, a JSON body with a companies list and one categories list for all of them
Companies11–20, results in input order
Company not found404 for the requestThat item gets status: "not_found"; the others still succeed
Upstream failure502 for the requestThat item gets status: "error", is not charged and can be retried alone
Not enough credits402, nothing charged402 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.

Body (JSON)

ParameterTypeDescription
companiesrequiredobject[] 1–20The 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.
categoriesoptionalstring[]Category keys from Categories & Credits, applied to every company. Omit, or send ["all"], for all 12. Unknown keys return 400.Default: all 12

Response 200

{ total_cost, results }, with one result per input, in the same order.

FieldTypeDescription
total_costintegerCredits charged by the whole request: the sum of the found companies' total_cost.
resultsobject[]One item per input company, in input order.
inputobjectThe identifier exactly as you sent it, to match results to inputs.
statusenumfound, 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.
messagestringOnly 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.").

Errors

Request-level errors stop the whole batch and charge nothing. Per-company problems are reported in results[].status instead.

StatusWhenResponse body
400Empty or more than 20 companies, an item with no identifier or several, or an unknown category key. The message names the item's position.—
401Missing or invalid API key.—
402The 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.—
403Free plan after its 14-day trial (TRIAL_EXPIRED, same body as Company enrich).—
413Body larger than 100 kB.—

Caching: private, no-store.

Request
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"]
  }'
200 — Stripe and Apple charged, duplicate free, one not found
{
  "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."
    }
  ]
}
402 — not enough credits for the batch
{
  "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 }
  }
}

Email Verifier

GET/v3/verifyv3

Credits: 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.

Query parameters

ParameterTypeDescription
emailrequiredstringThe 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.
enrichoptionalbooleantrue (or 1) adds companyData for professional addresses. Company data only; no person data. No extra credit.Default: false

Response 200

FieldTypeDescription
emailstringThe address that was verified, as sent.
domainstringThe domain part of the address.
email_statusstringvalid, invalid, catch-all or unknown. See Verification statuses.
messagestringHuman-readable explanation of the result. Absent when the verification could not complete (status unknown).
formatstringvalid or invalid: whether the address is syntactically correct. Bad syntax is reported here, not as an HTTP error.
mailbox_statusstringvalid 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_typestringprofessional (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_exchangestringThe mail server (MX host) for the domain. Absent when it was not determined on this request.
consumedCredit0 | 1Credits charged by this verification. See Credits.
companyDataobject | nullOnly 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.
idstring | nullEncoded company ID.
namestring | nullCompany name.
domainstring | nullMain domain.
websitestring | nullWebsite URL.
industrystring | nullIndustry label.
typestring | nullCompany type.
logo_urlstring | nullLogo image URL.
employee_count_rangestring | nullEmployee range with thousands separators, e.g. 1,001-5,000, 10,001+.
foundedinteger | nullFounding year.
revenuestring | nullRevenue range label, e.g. 10B+ USD.
addressstring | nullHeadquarters address.
citystring | nullHeadquarters city.
countrystring | nullHeadquarters country.
linkedin_urlstring | nullLinkedIn company page.

Verification statuses

StatusMeaningWhat to do
validThe mailbox exists and accepts mail. Addresses Skrapp already knows to be valid are also returned as valid.Safe to send.
catch-allThe domain accepts every address, so the mailbox cannot be confirmed.Send with care.
invalidThe mailbox does not exist or cannot receive mail.Do not send.
unknownThe 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.

Errors

StatusWhenResponse body
400email is missing.{"statusCode":400,"message":"Bad Request"}
401Missing or invalid key (the body says 403).{"status":403,"message":"Not authorized"}
403No credits left.{"message":"Not enough credits","status":403}
429Free plans: more than 100 verifications per IP in 24 h.—
503Authentication temporarily unavailable. Retry.—
Request
curl "https://api.skrapp.io/v3/verify?email=jane.doe@acme.com&enrich=true" \
  -H "X-Access-Key: YOUR_API_KEY"
200 — professional address, enriched
{
  "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
}
200 — webmail, already verified (free)
{
  "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
}

Bulk Email Verifier

GET/v3/verify_bulkv3

Credits: 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.

Query parameters

ParameterTypeDescription
emailrequiredstring, repeatedOne address per email= parameter, 2 to 50 of them. For a single address, use Email Verifier.

Response 200

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.

FieldTypeDescription
[].emailstringThe address that was verified, as sent.
[].domainstringThe domain part of the address.
[].email_statusstringvalid, invalid, catch-all or unknown. See Verification statuses.
[].messagestringHuman-readable explanation of the result. Absent when the verification could not complete (status unknown).
[].formatstringvalid or invalid: whether the address is syntactically correct. Bad syntax is reported here, not as an HTTP error.
[].mailbox_statusstringvalid 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_typestringprofessional (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_exchangestringThe mail server (MX host) for the domain. Absent when it was not determined on this request.
[].consumedCredit0 | 1Credits charged by this verification. See Credits.

Errors

StatusWhenResponse body
400Fewer than 2 or more than 50 email values.{"statusCode":400,"message":"Bad Request"}
401Missing or invalid key (the body says 403).—
403Fewer credits left than emails sent.{"message":"Not enough credits","status":403}
Request
curl "https://api.skrapp.io/v3/verify_bulk?email=jane.doe@acme.com&email=john@globex.com" \
  -H "X-Access-Key: YOUR_API_KEY"
200 — results
[
  {
    "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

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

  • Lists are identified by a numeric id. Create list returns a listPath (/app/list/<id>), not an ID: the ID is the last path segment.
  • Lead IDs and next_start are numeric strings; list IDs are numbers.
  • The status field in bodies is sometimes a string ("404") and sometimes a number (404). Rely on the HTTP status code.
  • Create list uses PUT; renaming uses POST …/edit.
  • A frozen list is locked: leads cannot be added to it (403).

Endpoints

EndpointPurpose
GET /api/v2/account-listsList your lists
GET /api/v2/list/:listIdGet a list: metadata and counts
GET /api/v2/list/:listId/leadsList a list's leads
PUT /api/v2/list/createCreate a list
POST /api/v2/list/:listId/editRename a list
DELETE /api/v2/list/:listIdDelete a list
POST /api/v2/list/:listId/loadAdd leads to a list
POST /api/v2/list/leads/deleteDelete leads
DELETE /api/v2/list/lead/:leadIdDelete a lead

List your lists

GET/api/v2/account-listsv2

Credits: 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.

Query parameters

ParameterTypeDescription
last_list_idoptionalintegerCursor mode: return lists with an ID lower than this one. Pass the last id of the previous call to get the next 50.
pageoptionalinteger ≥ 1Page mode: the page number, starting at 1. Ignored when last_list_id is sent.
pageSizeoptionalintegerPage mode: lists per page.Default: 50
keywordoptionalstringFilter by list name, case-insensitive. Cursor mode matches names that start with it; page mode matches names that contain it.

Response 200 — cursor mode

An array of up to 50 lists.

FieldTypeDescription
[].idintegerList ID.
[].namestringList name.
[].pathstringApp path, /app/list/<id>.
[].frozenbooleantrue when the list is locked.

Response 200 — page mode

FieldTypeDescription
total_countstringTotal matching lists, as a numeric string.
dataobject[]This page of lists: id, name, path, frozen.

Errors

StatusWhenResponse body
404No list matches (an empty result returns 404, not []).{"status":404,"message":"Not found"}
Request — cursor mode
curl "https://api.skrapp.io/api/v2/account-lists" \
  -H "X-Access-Key: YOUR_API_KEY"
200 — cursor mode
[
  { "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 }
]
Request — page mode
curl "https://api.skrapp.io/api/v2/account-lists?page=1&pageSize=2&keyword=acme" \
  -H "X-Access-Key: YOUR_API_KEY"
200 — page mode
{
  "total_count": "1",
  "data": [
    { "id": 17429843, "name": "Acme accounts", "path": "/app/list/17429843", "frozen": false }
  ]
}

Get a list

GET/api/v2/list/:listIdv2

Credits: Free.

Return one list's metadata: name, type, creation date, lead and email counts, counts per email status, and whether it is frozen.

Parameters

ParameterTypeDescription
listIdrequiredinteger (path)The list ID.
preloadoptionalbooleanSend exactly true to also return the first 25 leads in preload.Default: false

Response 200

FieldTypeDescription
list_idintegerList ID.
namestringList name.
creation_datestringCreation time, ISO 8601.
typestringList type code, e.g. lds for a list of leads.
count_leadsintegerNumber of leads.
count_leads_emailsintegerNumber of leads with an email.
valid_countintegerLeads whose email is valid.
invalid_countintegerLeads whose email is invalid.
catch_all_countintegerLeads whose email is catch-all.
unknown_countintegerLeads whose email is unknown.
pending_or_null_countintegerLeads with no email or a verification still pending.
frozenbooleantrue when the list is locked.
preloadobject[]Only with preload=true: the first 25 leads, same fields as List a list's leads.

Errors

StatusWhenResponse body
400listId is not a number.{"status":"400","message":"Bad request"}
404The list does not exist, is deleted or is not yours.{"status":"404","message":"Not found"}
Request
curl "https://api.skrapp.io/api/v2/list/17430846" \
  -H "X-Access-Key: YOUR_API_KEY"
200 — response
{
  "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
}

List a list's leads

GET/api/v2/list/:listId/leadsv2

Credits: 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).

Parameters

ParameterTypeDescription
listIdrequiredinteger (path)The list ID.
startoptionalstringCursor: the next_start of the previous page. Omit for the first page.
sizeoptionalintegerLeads per page, at most 500 (larger values are capped).Default: 25
kwoptionalstringKeyword, case-insensitive. Matches anywhere in the name, title, company, location or email.

Response 200

FieldTypeDescription
dataobject[]This page of leads.
idstringLead ID (numeric string). Use it with Delete lead.
namestringFull name.
first_nstringFirst name.
last_nstringLast name.
emailstring | nullEmail address, when one was found or added.
email_statusstring | nullvalid, invalid, catch-all or unknown.
titlestringJob title.
companystringCompany name.
linkedin_urlstring | nullLinkedIn profile path as stored, e.g. /in/jane-doe-0a1b2c3. It may be relative and is not always a full URL.
img_urlnullAlways null on this endpoint.
locationstringLead location.
domainstringCompany domain.
company_industrystring | nullCompany industry.
company_foundedstring | nullFounding year, as a string, e.g. "2008".
company_sizestring | nullEmployee range, e.g. 11-50.
company_hqobject | nullCompany headquarters. Keys are present only when known.
citystringCity.
statestringState or region.
countrystringCountry.
next_startstringCursor for the next page. Absent when data is empty.
count_resultsintegerOnly with kw: leads matching the keyword.
count_results_emailsintegerOnly with kw: matching leads that have an email.

A list that does not exist or is not yours returns 200 with {"data": []}, not 404.

Errors

StatusWhenResponse body
400listId is not a number.{"status":"400","message":"Bad request"}
404The leads could not be read.{"status":"404","message":"Not found"}
Request — first page
curl "https://api.skrapp.io/api/v2/list/17430846/leads?size=2" \
  -H "X-Access-Key: YOUR_API_KEY"
200 — response
{
  "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" }
    }
  ]
}
Request — next page
curl "https://api.skrapp.io/api/v2/list/17430846/leads?size=2&start=4452508940" \
  -H "X-Access-Key: YOUR_API_KEY"

Create a list

PUT/api/v2/list/createv2

Credits: 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.

Body (JSON)

ParameterTypeDescription
namerequiredstringThe list name. Must not be empty.
sourceoptionalstringOptional label of where the list comes from.

Response 200

FieldTypeDescription
listPathstringApp path of the new list, /app/list/<id>.

Errors

StatusWhenResponse body
400name missing or empty.{"status":"400","message":"Bad request"}
500The list could not be created.{"status":"500","message":"Internal server error"}
Request
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" }'
200 — response
{
  "listPath": "/app/list/17430846"
}

Rename a list

POST/api/v2/list/:listId/editv2

Credits: Free.

Change the name of a list. Success returns 201 with a status body.

Parameters

ParameterTypeDescription
listIdrequiredinteger (path)The list ID.
listNamerequiredstring (body)The new name. Leading and trailing spaces are trimmed.

Response 201

FieldTypeDescription
statusnumberAlways 201.
messagestringAlways Updated.

Errors

StatusWhenResponse body
400listId is not a number, or listName is missing or empty.{"status":400,"message":"Bad request"}
401The list does not exist or is not yours.{"status":401,"message":"Unauthorized update"}
Request
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" }'
201 — response
{
  "status": 201,
  "message": "Updated"
}

Delete a list

DELETE/api/v2/list/:listIdv2

Credits: Free.

Delete a list and its leads.

Path parameters

ParameterTypeDescription
listIdrequiredintegerThe list ID.

Response 200

FieldTypeDescription
statusstringAlways "200" (a string).
messagestringAlways List deleted.

Errors

StatusWhenResponse body
403The list cannot be deleted.{"status":"403","message":"Forbidden"}
404The list does not exist or is not yours.{"status":"404","message":"Not found"}
Request
curl -X DELETE "https://api.skrapp.io/api/v2/list/17430846" \
  -H "X-Access-Key: YOUR_API_KEY"
200 — response
{
  "status": "200",
  "message": "List deleted"
}

Add leads to a list

POST/api/v2/list/:listId/loadv2

Credits: 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.

Parameters

ParameterTypeDescription
listIdrequiredinteger (path)The list to add to, or 0 to create a new list first.
listNameoptionalstring (body)Name of the new list when listId is 0. Default unnamed list.
sourceoptionalstring (body)Label of where the new list comes from, when listId is 0. Default app.
leadsoptionalobject[] (body)The leads to add, at most 10,000. Fields per lead are below. Omit it (or send []) to only create the list.

Lead fields

ParameterTypeDescription
nameoptionalstringFull name.
firstNameoptionalstringFirst name.
lastNameoptionalstringLast name.
emailoptionalstringEmail address.
qualityoptionalobjectEmail status as returned by the Email Finder: { "status": "valid", "status_message": "…" }. status is saved as the lead's email_status.
titleoptionalstringJob title.
companyoptionalstringCompany name.
domainoptionalstringCompany domain.
companyIdoptionalstringEncoded company ID (as in Companies search results).
linkedinUrloptionalstringLinkedIn profile URL.
linkedinIdoptionalnumberLinkedIn member ID.
locationoptionalstringLocation text; the country is read from it.
imgUrloptionalstringProfile picture URL.

Response 200

FieldTypeDescription
listPathstringApp path of the list, /app/list/<id> (the new list when listId was 0).
insertedintegerLeads added to the list.
updatedintegerLeads that were already in the list and were updated.
messagestringOnly when no leads were sent: Nothing to save. Empty payload.

Errors

StatusWhenResponse body
400The 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."}
400More than 10,000 leads, or an invalid body.—
401Missing or invalid key (the body says 403).—
403The list is frozen.{"statusCode":403,"message":"List 17430846 is currently frozen.","error":"Forbidden"}
Request — new list with leads
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"
      }
    ]
  }'
200 — response
{
  "listPath": "/app/list/17430846",
  "inserted": 1,
  "updated": 0
}

Delete leads

POST/api/v2/list/leads/deletev2

Credits: 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.

Body (JSON)

ParameterTypeDescription
idsrequiredinteger[] 1–1000Lead IDs to delete (the id of each lead).

Response 200

FieldTypeDescription
statusstringAlways "200".
messagestringAlways Leads deleted.
deletedCountintegerNumber of leads deleted.

Errors

StatusWhenResponse body
400ids missing, empty, longer than 1,000 or not integers. The body names the problem.{"error":"\"ids\" must contain at least 1 items"}
500The leads could not be deleted.{"status":"500","message":"Internal server error"}
Request
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] }'
200 — response
{
  "status": "200",
  "message": "Leads deleted",
  "deletedCount": 2
}

Delete a lead

DELETE/api/v2/list/lead/:leadIdv2

Credits: Free.

Delete one lead from its list.

Path parameters

ParameterTypeDescription
leadIdrequiredintegerThe lead ID (id in the lead rows).

Response 200

FieldTypeDescription
statusstringAlways "200".
messagestringAlways Lead deleted.

Errors

StatusWhenResponse body
403The lead cannot be deleted.{"status":"403","message":"Forbidden"}
404The lead does not exist or is not yours.{"status":"404","message":"Not found"}
Request
curl -X DELETE "https://api.skrapp.io/api/v2/list/lead/4452509027" \
  -H "X-Access-Key: YOUR_API_KEY"
200 — response
{
  "status": "200",
  "message": "Lead deleted"
}