Integrations · Beta
Skrap.ai for Clay
Before you start
- A Skrap API key: in the app, Settings → API keys & MCP (paid plans).
- A Clay table with an Email column and/or First Name, Last Name and Company Domain (or Company Name) columns.
- A Clay plan that includes the HTTP API enrichment.
| Step | Clay column | Runs when |
|---|---|---|
| 1 | Skrap verify | Email is not empty |
| 2 | Skrap find (by domain) | Company Domain is not empty, and Email is empty or Skrap verify status is invalid |
| 3 | Skrap find (by company) | Company Domain is empty, Company Name is not empty, and Email is empty or Skrap verify status is invalid |
Connect your API key once
- In Clay, add an enrichment column and pick HTTP API.
- Under the account / authentication option, add a new HTTP API (Headers) account named Skrap.
- Add the three headers below. Clay stores them for the whole workspace, so every Skrap column reuses them and the key never sits in a column.
x-api-key: <YOUR_SKRAP_API_KEY>Content-Type: application/jsonx-skrap-client: clayx-skrap-client: clay labels these calls as Clay in your Skrap usage pages. It is optional.Add the columns
In the Body box, type / and choose the column wherever the recipe shows {{Column}}. Keep the domain and company columns in separate find columns: an empty company or domain value is refused by the API.
1. Skrap verify
Add an HTTP API column named Skrap verify. It runs first, so you only pay to find emails for rows that need one.
https://api.skrap.ai/api/v2/verify-email{ "email": "{{Email}}"}| Setting | Value |
|---|---|
| Only run if | Email is not empty |
| Field paths to return | status, retryable, score, checks.catchAll, checks.disposable, checks.roleAccount, didYouMean |
| Rate limit | 100 requests per 60 seconds |
| Credits | 1 credit when the status is valid or risky. Invalid and unknown are free. |
2. Skrap find (by domain)
For rows with a company domain. It runs only when Email is empty or Skrap verify says invalid. A website URL in the domain column works too.
https://api.skrap.ai/api/v2/find-email1{2 "firstName": "{{First Name}}",3 "lastName": "{{Last Name}}",4 "domain": "{{Company Domain}}",5 "linkedinUrl": "{{LinkedIn URL}}"6}| Setting | Value |
|---|---|
| Only run if | Company Domain is not empty, and Email is empty or Skrap verify status is invalid |
| Field paths to return | emails.0.email, emails.0.status, status, pendingRefinement, requestId |
| Rate limit | 100 requests per 60 seconds |
| Credits | 1 credit only when an email is found (valid or risky). |
3. Skrap find (by company)
For rows with a company name but no domain. Skrap matches the name to a domain first; a name it cannot match answers HTTP 400 and is free.
https://api.skrap.ai/api/v2/find-email1{2 "firstName": "{{First Name}}",3 "lastName": "{{Last Name}}",4 "company": "{{Company Name}}",5 "linkedinUrl": "{{LinkedIn URL}}"6}| Setting | Value |
|---|---|
| Only run if | Company Domain is empty, Company Name is not empty, and Email is empty or Skrap verify status is invalid |
| Field paths to return | emails.0.email, emails.0.status, status, pendingRefinement, requestId, needsCompanyConfirmation |
| Rate limit | 100 requests per 60 seconds |
| Credits | 1 credit only when an email is found (valid or risky). A company name Skrap cannot match answers HTTP 400 and is free. |
4. Best email (optional)
Optional: a formula column that keeps the original email when it verified as valid or risky, and otherwise takes the found one.
The rule: The original Email when Skrap verify is valid or risky; otherwise the email from Skrap find (by domain) or Skrap find (by company) when its status is valid or risky; otherwise empty. Paste it into Clay's formula generator, or adapt this example to your column names:
1// Clay formula column "Best email" (Formula, JavaScript)2["valid", "risky"].includes({{Skrap verify}}?.status)3 ? {{Email}}4 : ["valid", "risky"].includes({{Skrap find (by domain)}}?.emails?.[0]?.status)5 ? {{Skrap find (by domain)}}.emails[0].email6 : ["valid", "risky"].includes({{Skrap find (by company)}}?.emails?.[0]?.status)7 ? {{Skrap find (by company)}}.emails[0].email8 : ""What comes back
| Field path | Meaning |
|---|---|
status | Verify: valid, risky, invalid or unknown. Find: the best status of the found email. |
emails.0.email / emails.0.status | Find: the email found and its status (empty when nothing was found). |
retryable | true when an unknown was caused by something temporary: run the cell again later. |
pendingRefinement / requestId | Find: the mail server is slow to answer. Run the cell again later, or call GET /api/v1/find-email/refinement/{requestId}. Not charged until it settles. |
checks.catchAll, checks.disposable, checks.roleAccount | Verify: why an address is risky. |
didYouMean | Verify: a typo fix such as gmail.com for gmial.com. |
Every field is documented in the API reference; statuses are explained in Verification statuses.
Rate limits & errors
- Set the column's rate limit to about 100 requests per 60 seconds per API key (Professional keys allow 120 requests a minute, Enterprise 600).
- Slow mail servers can take up to about 50 seconds to answer a verification. Clay keeps waiting, so leave the timeout at its default.
- A 429 answer means too many requests at once: lower the rate limit and re-run the failed cells. A 402 answer means the account is out of credits.
The whole recipe
The same setup as one JSON file, for your team's notes or for building the columns with Clay's AI setup. Download it from /docs/clay/recipe.json.
1{2 "name": "Skrap.ai for Clay: verify, then find",3 "version": "2026-11-11",4 "docs": "https://skrap.ai/docs/clay",5 "about": "HTTP API enrichment columns for a Clay table. Step 1 verifies the emails you already have. Steps 2 and 3 find a work email only where the email is missing or invalid. Paste each value into the matching box of a Clay HTTP API column; {{Column}} means: type / in Clay and pick that column.",6 "account": {7 "clayAccountType": "HTTP API (Headers)",8 "name": "Skrap",9 "headers": {10 "x-api-key": "<YOUR_SKRAP_API_KEY>",11 "Content-Type": "application/json",12 "x-skrap-client": "clay"13 }14 },15 "inputColumns": [16 "Email",17 "First Name",18 "Last Name",19 "Company Domain",20 "Company Name",21 "LinkedIn URL"22 ],23 "rateLimit": {24 "requests": 100,25 "perSeconds": 60,26 "note": "Stay under your plan's per-key limit (Professional 120 requests/minute, Enterprise 600)."27 },28 "columns": [29 {30 "step": 1,31 "name": "Skrap verify",32 "method": "POST",33 "endpoint": "https://api.skrap.ai/api/v2/verify-email",34 "body": {35 "email": "{{Email}}"36 },37 "onlyRunIf": "Email is not empty",38 "runIf": {39 "all": [40 {41 "column": "Email",42 "op": "not_empty"43 }44 ]45 },46 "fieldPaths": [47 "status",48 "retryable",49 "score",50 "checks.catchAll",51 "checks.disposable",52 "checks.roleAccount",53 "didYouMean"54 ],55 "credits": "1 credit when the status is valid or risky. Invalid and unknown are free."56 },57 {58 "step": 2,59 "name": "Skrap find (by domain)",60 "method": "POST",61 "endpoint": "https://api.skrap.ai/api/v2/find-email",62 "body": {63 "firstName": "{{First Name}}",64 "lastName": "{{Last Name}}",65 "domain": "{{Company Domain}}",66 "linkedinUrl": "{{LinkedIn URL}}"67 },68 "onlyRunIf": "Company Domain is not empty, and Email is empty or Skrap verify status is invalid",69 "runIf": {70 "all": [71 {72 "column": "Company Domain",73 "op": "not_empty"74 },75 {76 "any": [77 {78 "column": "Email",79 "op": "empty"80 },81 {82 "column": "Skrap verify.status",83 "op": "in",84 "values": [85 "invalid"86 ]87 }88 ]89 }90 ]91 },92 "fieldPaths": [93 "emails.0.email",94 "emails.0.status",95 "status",96 "pendingRefinement",97 "requestId"98 ],99 "credits": "1 credit only when an email is found (valid or risky)."100 },101 {102 "step": 3,103 "name": "Skrap find (by company)",104 "method": "POST",105 "endpoint": "https://api.skrap.ai/api/v2/find-email",106 "body": {107 "firstName": "{{First Name}}",108 "lastName": "{{Last Name}}",109 "company": "{{Company Name}}",110 "linkedinUrl": "{{LinkedIn URL}}"111 },112 "onlyRunIf": "Company Domain is empty, Company Name is not empty, and Email is empty or Skrap verify status is invalid",113 "runIf": {114 "all": [115 {116 "column": "Company Domain",117 "op": "empty"118 },119 {120 "column": "Company Name",121 "op": "not_empty"122 },123 {124 "any": [125 {126 "column": "Email",127 "op": "empty"128 },129 {130 "column": "Skrap verify.status",131 "op": "in",132 "values": [133 "invalid"134 ]135 }136 ]137 }138 ]139 },140 "fieldPaths": [141 "emails.0.email",142 "emails.0.status",143 "status",144 "pendingRefinement",145 "requestId",146 "needsCompanyConfirmation"147 ],148 "credits": "1 credit only when an email is found (valid or risky). A company name Skrap cannot match answers HTTP 400 and is free."149 }150 ],151 "bestEmail": {152 "name": "Best email",153 "clayColumnType": "Formula",154 "rule": "The original Email when Skrap verify is valid or risky; otherwise the email from Skrap find (by domain) or Skrap find (by company) when its status is valid or risky; otherwise empty."155 }156}FAQ
- How are credits used?
- 1 Skrap credit per Valid or Risky verification and per email found. Invalid, Unknown, not-found and company-not-matched answers are free. Clay does not charge Clay credits for your own HTTP API calls.
- Why is it in Beta?
- The recipe uses Skrap's public API, which is stable. We call it Beta while we collect feedback on the column setup. A one-click Clay integration may follow.
- Can I verify the emails Skrap finds?
- They are already verified: every found email comes back with its status, so there is no need for a second verify column.
- Does Skrap see my Clay table?
- No. Clay sends only the fields you put in each column's body (the email, or the name and company) to api.skrap.ai.