Skip to navigation

Verification Tiers

Add verification_tier to a Contact Profile Refresh Request to choose how thoroughly Dealsignal verifies each profile and its contact details. The response then reports every requested field with its verification status, and you are charged only for what is delivered.

A request with no verification_tier works as described in the Overview.


Choose a tier

quickstandardpremium
Profile verified within60 days30 days7 days
Work email checkMail serverInbox, one passInbox, several passes
Email delivered atVerified or ValidVerifiedVerified
direct_phone, mobile_numberNot availableValidated, no callValidated, then called
Phone delivered at—Valid or betterValid or better
corporate_phoneNot availableReturned as storedReturned as stored, can take longer
Profile that can’t be refreshed automaticallyClosed, no chargeClosed, no chargeTried further
Typical time1–15 minutes15–60 minutesWithin 1 business day
Maximum credits per profile0.351.502.50

On premium, profiles that refresh automatically are usually ready within an hour.


Send a request

The call is the same as any refresh request, with verification_tier at the top level:

curl -X POST "https://app.dealsignal.com/api/v1/contact_profile_refresh_requests" \
-H "X-Api-Key: YOUR_API_KEY" \
-H "Content-Type: application/json" \
-H "Accept: application/json" \
-d '{
"verification_tier": "standard",
"requested_attributes": [
{ "name": "contact_profile", "priority_order": 0 },
{ "name": "email", "priority_order": 1 },
{ "name": "mobile_number", "priority_order": 2 }
],
"profiles": [
{ "linkedin_url": "https://www.linkedin.com/in/sam-lee-example",
"company_name": "Acme Corp",
"metadata": { "crm_record": "003Dn00000AbCdE" } }
]
}'
  • Values: quick, standard, premium. Any other value is rejected with 422 and nothing is created. For a request without a tier, leave verification_tier out.
  • Daily limit: an account can send up to 1,500 profiles a day in requests with a verification_tier; test requests don’t count. A request that would go over is rejected whole with 422, for example Requests with a verification_tier are limited to 1500 profiles a day per account: 1450 sent today, this request has 100.
  • requested_attributes: contact_profile, email, direct_phone, mobile_number, corporate_phone. On quick, phones are dropped from the request: they are neither returned nor charged.
  • Test mode: with test: true the response has no tier fields and nothing is charged, but your balance must still cover the tier’s maximum.
  • Retries: see Idempotent requests from Clay. To run the same records again with another tier within 15 minutes, use new keys.

Then poll request_status as usual. On standard and premium the result can arrive long after the create call, so a tool that can’t poll repeatedly can set a webhook: it carries the same fields. A profile can arrive more than once, including one already finished in the create response, so deduplicate on your key in metadata. A delivery that fails (anything but a 2xx within 60 seconds) is retried eight times over about 27 hours, at intervals from 1 minute to 12 hours.


Read the result

Each profile carries these fields next to custom_columns and contact_data:

FieldDescription
tierThe tier that ran.
deliverednull while the profile is in progress. true: the result is final. false: the contact is not delivered and not charged; this is also final.
delivery_reasonWhy delivered is false — see Not delivered. null otherwise.
pending_fieldsRequested fields still being worked on.
in_progressInterim values of fields that are not delivered yet: those in pending_fields, and a phone that is ready but waits for the email. Each has the target status the tier needs (none on corporate_phone). Not charged, and they can change or disappear.
credits_chargedCredits charged for this profile so far. Final once the request’s status is completed.
tier_satisfiedtrue when the profile is finished and every requested field reached the tier’s status or ended Not Found. An email that ended Not Found reads tier_satisfied: true with delivered: false, so use delivered to decide.

A profile is finished when delivered is not null. An empty pending_fields is not enough: it can also be empty while the profile itself is still being refreshed, for example on a request for contact_profile only.

contact_data contains only fields that have reached the requested tier’s verification status. in_progress is interim and is not suitable for accuracy comparisons or production sends.

While a profile is in progress, contact_data shows the profile as currently stored, and each requested field is null until it is delivered:

{
"custom_columns": { "linkedin_url": "https://www.linkedin.com/in/sam-lee-example", "company_name": "Acme Corp" },
"tier": "standard",
"delivered": null,
"delivery_reason": null,
"tier_satisfied": false,
"credits_charged": 0.0,
"pending_fields": ["email", "mobile_number"],
"in_progress": {
"email": { "value": "sam.lee@acme.example", "status": "Valid", "verified_at": "2026-10-20T09:12:00.000Z", "verification_method": "smtp", "target": "Verified" }
},
"contact_data": { "id": 456, "first_name": "Sam", "company_name": "Acme Corp", "...": "…", "email": null, "mobile_number": null }
}

response_format=summary and response_format=changes have no tier fields. Use the full format to read them and to tell whether a contact was delivered.

Field objects

email, mobile_number, direct_phone and corporate_phone appear in contact_data when requested, next to the 33 profile keys:

KeyDescription
valueThe email or phone number. null when it is not delivered.
statusVerified, Valid, Unverified or Not Found — see below.
verified_atWhen this value was last verified.
verification_methodHow it was verified — see below. null when the value was not checked by one of these methods, on a Not Found field, and on corporate_phone.
dial_resultPhones only: the outcome of the call — see below. null when no call was logged.
guaranteedpremium only: true when the contact replied to the email or answered the call in person.
statusEmailPhone
VerifiedPassed all the tier’s checks.The call reached the contact or their own voicemail.
ValidFound, but not fully verified: treat it as risky, for example on a catch-all domain.The number is valid, but no call confirmed that it is the contact’s.
UnverifiedFound, but failed the check, for example the address bounced. value is null.The number is wrong. value is null.
Not FoundNothing found at this tier’s depth, or only a value not verified within the tier’s window. value is null.Same as for email.
verification_methodMeaning
smtpMail server check.
inbox_singleInbox check, one pass.
inbox_tripleInbox check, several passes.
validation_onlyNumber format and carrier check, no call.
dial_aiAutomated call.
dial_resultstatus
Connected to ContactVerified
Voicemail of ContactVerified
Generic VoicemailValid
Connected, identity not confirmedValid
Connected, declined to confirmValid
No AnswerValid
Wrong NumberUnverified

A phone that is ready waits in in_progress until the email finishes, because the contact is delivered only with its email.

corporate_phone is company data, returned as stored with its stored status, or as Not Found. Tier statuses and windows don’t apply to it, and it is not charged. On premium it can stay in pending_fields while it is being worked on.

Not delivered

If you request email, the contact is delivered only with it. This is decided as soon as the email check ends, even if a phone is still being called. contact_data is then {} and nothing is charged.

delivery_reasonTiersWhat happened
email_not_foundAllNo email verified within the tier’s window was found.
email_below_tierAllAn email was found, but it did not reach the status the tier delivers.
profile_not_foundAllThe contact’s profile could not be found.
profile_outdatedquick, standardNo copy of the profile checked recently enough was available. premium may resolve it.
profile_failedquick, standardThe profile could not be refreshed, for example because there is no usable LinkedIn URL. Retry, or use premium.
profile_not_refreshedpremiumThe refresh did not succeed, and the stored profile is older than the tier’s window.
no_current_employerAllThe profile shows no current employer. This one keeps the 33 profile keys in contact_data; every requested field reads Not Found.

A request that doesn’t ask for email is delivered once everything has finished.

Which job the result describes

On a request with a tier, the email and phones belong to a job the contact holds now: the employer you named in company_name if they still work there, otherwise their main current job. company_name, title, company_website, seniorities and departments describe that job.

The first refresh of a contact for your account can also report a move. When Dealsignal recognises company_name as a job the contact has left, changed_company reads true, and in the changes format ds_baseline_primary_company names that job. The result is for the current job and charged as usual, or no_current_employer if there is none. Any other first refresh follows the rules in the Overview.


Pricing

TierProfile+ Work email+ PhoneMaximum per profile
quick0.250.10Not available0.35
standard0.250.750.501.50
premium0.251.251.00 when Verified, 0.50 when Valid2.50
  • You pay for what is delivered. A field is charged only if its value is in contact_data.
  • Not charged: every profile with delivered: false, and corporate_phone on every tier.
  • One phone price. direct_phone and mobile_number are charged once per profile, at the best status among the phones you requested. On standard, a phone already confirmed by an earlier call goes out as Verified at the same 0.50.
  • Balance check. The call is rejected with 422 when your balance doesn’t cover the maximum for the attributes you request.
  • Every delivered contact is charged, including contacts you’ve requested before.

Freshness

The tier’s window (60, 30 or 7 days) does two things:

  • Decides what gets refreshed. A profile last verified inside the window is returned as it is; an older one is refreshed. contact_refresh_time overrides this, and 0 refreshes every profile.
  • Decides what can be delivered. An email or phone is delivered and charged only if it was verified inside the window, counted back from the request’s creation. contact_refresh_time doesn’t change this.