API Verification Workflow

View as Markdown

This guide is the complete reference for the ApexVerify batch verification lifecycle. It covers every API call, every parameter, every response shape — and the exact order of operations from uploading a file to downloading your results.

Prerequisites: A valid API key (see Your First API Key) and a .txt file containing one email or phone number per line.

Base URL: https://api.apexverify.com
Authentication: All requests require the X-Api-Key: YOUR_API_KEY header.


Lifecycle overview

The batch verification workflow has 7 steps. Each step maps to a specific API endpoint:

StepActionMethodEndpoint
1Upload filePOST/v1/batch
2Configure parametersPUT/v1/batch/{uuid}
3Trigger parsingPATCH/v1/batch/{uuid}
4Check readinessGET/v1/batch/{uuid}/details
5Launch verificationPOST/v1/batch/{uuid}
6Poll for completionGET/v1/batch/{uuid}
7Export resultsGET/v1/batch/{uuid}/export

Step 1: Upload your file

Endpoint: POST /v1/batch
Content-Type: multipart/form-data

Upload a .txt file with one email or phone number per line. The API creates a batch record and returns a batch_uuid that identifies this batch for all subsequent operations.

Request fields

FieldTypeRequiredDescription
filebinaryYes.txt file, UTF-8 encoded, one entry per line
namestringYesBatch display name (1–255 characters)
typeemail | phoneYesVerification type
target_countryISO2 stringYesCountry code (e.g. US, SG, GB)
descriptionstringNoOptional description (max 2,048 chars)

Example

$curl -X POST https://api.apexverify.com/v1/batch \
> -H "X-Api-Key: YOUR_API_KEY" \
> -F "file=@contacts.txt" \
> -F "name=Q2 Lead List" \
> -F "description=Imported from HubSpot export — April 2026" \
> -F "type=email" \
> -F "target_country=US"

Responses

1{
2 "status": "ok",
3 "batch_uuid": "a1b2c3d4-e5f6-7890-abcd-ef1234567890",
4 "created_at": "2026-04-06T10:00:00Z"
5}

Save the batch_uuid. You will pass it to every subsequent request.

Save your batch_uuid — it is the key identifier for this batch in all subsequent calls.


Step 2: Configure verification parameters

Endpoint: PUT /v1/batch/{uuid}
Content-Type: application/json

Set the verification parameters for your batch. You can call this endpoint multiple times — parameters are updated each time. Only type and target_country are required.

Parameters reference

FieldTypeRequiredDefaultDescription
typeemail | phoneYesVerification type
target_countryISO2 stringYesTarget country (e.g. US, GB, SG)
target_audienceinteger 1–23NonullAudience role code
target_market_industryinteger 1–115NonullIndustry vertical code
target_objectiveinteger 1–16NonullCampaign objective code
use_account_cachebooleanNotrueReuse your own previous results
max_account_cache_backoffinteger 1–180No30Days lookback for account cache
use_global_cachebooleanNotrueReuse anonymized global results
max_global_cache_backoffinteger 1–180No30Days lookback for global cache
remove_duplicatebooleanNotrueRemove duplicate rows during prep
remove_wrong_email_formatbooleanNotrueRemove malformed email rows
remove_wrong_phone_formatbooleanNotrueRemove malformed phone rows
CodeAudience
1Agency / Consultants
2Creators & Influencers
3Customer Support & Success
4Developers & Technical Leads
5E-commerce & Retail Managers
6Enterprise Decision-Makers
7Finance & Operations Professionals
8Founders & C-Level Executives
9Freelancers & Solopreneurs
10Government & Public Sector Employees
11HR & Talent Acquisition
12Healthcare Professionals
13Hobbyists & Enthusiasts
14Investors & VCs
15Job Seekers
16Legal Professionals
17Marketing & Sales Professionals
18Non-Profit Leaders & Staff
19Parents & Families
20Product & Project Managers
21Real Estate Professionals
22Small-to-Medium Business (SMB) Owners
23Students & Educators
CodeObjective
1App Installs / Downloads
2Audience Building (Email/Community)
3Brand Awareness & Recall
4Customer Acquisition / Sales
5Free Trial or Freemium Signups
6Lead Generation (Top/Mid-Funnel)
7Loyalty & Referral Program Growth
8Market & Customer Research
9New Market Entry
10Partner & Affiliate Recruitment
11Product Engagement & Feature Adoption
12Sales-Ready Leads (Bottom-Funnel)
13Upsell / Cross-sell Revenue
14User Retention & Churn Reduction
15Waitlist / Pre-order Signups
16Website / App Traffic Acquisition

Both caches are enabled by default and provide a 50% credit refund for cache-hit records:

  • Account cache — reuses results from your own previous batches. Fully private.
  • Global cache — reuses anonymized, aggregated results from across all accounts. No PII is ever shared. By enabling this, you also contribute anonymized results back to the global pool.

The system always checks account cache first, then global cache.

max_account_cache_backoff and max_global_cache_backoff control the lookback window in days (1–180). A shorter window gives fresher results; a longer window maximizes cache hits and lowers cost.

Example

$curl -X PUT https://api.apexverify.com/v1/batch/a1b2c3d4-e5f6-7890-abcd-ef1234567890 \
> -H "X-Api-Key: YOUR_API_KEY" \
> -H "Content-Type: application/json" \
> -d '{
> "type": "email",
> "target_country": "US",
> "target_audience": 17,
> "target_market_industry": 46,
> "target_objective": 6,
> "use_account_cache": true,
> "use_global_cache": true,
> "max_account_cache_backoff": 60,
> "max_global_cache_backoff": 30
> }'

Response

1{ "message": "Success" }

Adjust and re-configure freely. You can call PUT as many times as you need — parameters are not locked until verification is launched. After changing parameters, always re-trigger parsing (Step 3) to recalculate cost and content summary.


Step 3: Trigger parsing and preparation

Endpoint: PATCH /v1/batch/{uuid}
Request body: None

This triggers asynchronous content parsing. The server reads your uploaded file, validates each row, removes duplicates and malformed entries (per your configuration), and calculates the estimated verification cost.

Example

$curl -X PATCH https://api.apexverify.com/v1/batch/a1b2c3d4-e5f6-7890-abcd-ef1234567890 \
> -H "X-Api-Key: YOUR_API_KEY"

Responses

1{ "status": "ok" }

Parsing has been triggered. The batch transitions to parsing_content status. Poll GET /v1/batch/{uuid} until it reaches ready_for_verification.

Re-parsing after parameter changes

PATCH is idempotent and can be called multiple times. If you update parameters via PUT after an initial PATCH, simply call PATCH again to re-parse with the new configuration. There is no limit on re-parses before the batch is launched. Each re-parse recalculates the cost and content summary.

Typical iterate-and-refine flow:

PUT → set parameters
PATCH → trigger parsing
↓ check GET /v1/batch/{uuid}/details
↓ cost too high? adjust cache settings
PUT → update cache settings
PATCH → re-parse with new settings
↓ cost acceptable
POST → launch verification

Parsing result fields

Once parsing is complete (status = ready_for_verification), the found_content field in GET /v1/batch/{uuid}/details shows:

FieldTypeDescription
valid_emailintegerRows parsed as valid email format — will be verified
wrong_emailintegerRows rejected as invalid format
duplicate_emailintegerRows removed as duplicates

Credits are charged for valid_email count only.


Step 4: Check batch readiness

Endpoint: GET /v1/batch/{uuid}/details

Returns detailed batch information, including status, parameters, parsing summary, verification cost, and (after completion) statistics. The response shape is discriminated by the status field.

Status discriminator

status valueResponse schemaMeaning
parsing_contentBaseBatchDetailsModelResponseParsing in progress — wait
internal_errorBaseBatchDetailsModelResponseSystem error during parsing
ready_for_verificationPendingBatchDetailsModelResponseReady to launch
verification_ongoingPendingBatchDetailsModelResponseVerification is running
verification_doneFinalBatchDetailsModelResponseComplete — results available

Example

$curl -X GET https://api.apexverify.com/v1/batch/a1b2c3d4-e5f6-7890-abcd-ef1234567890/details \
> -H "X-Api-Key: YOUR_API_KEY"

Response examples

Returned when status is parsing_content or internal_error:

1{
2 "batch_uuid": "a1b2c3d4-e5f6-7890-abcd-ef1234567890",
3 "name": "Q2 Lead List",
4 "description": "Imported from HubSpot export — April 2026",
5 "status": "parsing_content",
6 "created_at": "2026-04-06T10:00:00Z",
7 "updated_at": "2026-04-06T10:00:05Z",
8 "parameters": {
9 "type": "email",
10 "target_country": "US"
11 }
12}

If status is internal_error, an unexpected error occurred during parsing. Contact support at contact@apexverify.com and include your batch_uuid so the team can investigate.


Step 5: Launch verification

Endpoint: POST /v1/batch/{uuid}
Request body: None

Starts the verification job. The batch must be in ready_for_verification status before calling this endpoint.

Example

$curl -X POST https://api.apexverify.com/v1/batch/a1b2c3d4-e5f6-7890-abcd-ef1234567890 \
> -H "X-Api-Key: YOUR_API_KEY"

Responses

1{ "status": "ok" }

Verification has started. Proceed to Step 6 to poll for completion.

Insufficient credits? If your account doesn’t have enough credits to cover the net_email_cost or net_phone_cost, the API returns 402 Payment Required. Top up your credits from the Dashboard and retry.


Step 6: Poll for completion

Endpoint: GET /v1/batch/{uuid}

This lightweight status endpoint returns the batch’s current state. Poll it periodically until the status reaches verification_done.

Example

$curl -X GET https://api.apexverify.com/v1/batch/a1b2c3d4-e5f6-7890-abcd-ef1234567890 \
> -H "X-Api-Key: YOUR_API_KEY"

Status values

statusMeaning
parsing_contentBatch is being prepared
ready_for_verificationWaiting to be launched
verification_ongoingVerification is running — keep polling
verification_doneComplete — ready to export
internal_errorError — contact support

Polling loop example

$BATCH_UUID="a1b2c3d4-e5f6-7890-abcd-ef1234567890"
$API_KEY="YOUR_API_KEY"
$DELAY=5
$
$while true; do
$ STATUS=$(curl -s -X GET "https://api.apexverify.com/v1/batch/$BATCH_UUID" \
> -H "X-Api-Key: $API_KEY" | jq -r '.status')
$
$ echo "Status: $STATUS"
$
$ if [ "$STATUS" = "verification_done" ]; then
$ echo "Verification complete — ready to export."
$ break
$ elif [ "$STATUS" = "internal_error" ]; then
$ echo "Error encountered. Contact support with batch_uuid: $BATCH_UUID"
$ break
$ fi
$
$ sleep $DELAY
$ DELAY=$((DELAY < 60 ? DELAY * 2 : 60)) # exponential backoff, cap at 60s
$done

Use exponential backoff when polling. Start with a 5-second interval and double it each cycle, capping at 60 seconds. This avoids unnecessary API calls and stays well within the 180 requests/minute rate limit. See API Rate Limits for details.


Step 7: Export your results

Endpoint: GET /v1/batch/{uuid}/export

Once verification_done, export your results. Two formats are available: structured JSON or a formatted XLSX spreadsheet.

Query parameters

ParameterTypeRequiredDefaultDescription
formatxlsx | jsonYesOutput format
include_detailsbooleanNotrueInclude per-row result fields in JSON
include_statisticsbooleanNotrueInclude aggregate stats section in JSON

Returns a JSON object keyed by the original email or phone value. Each key maps to a full result object.

Request

$curl -X GET "https://api.apexverify.com/v1/batch/a1b2c3d4-e5f6-7890-abcd-ef1234567890/export?format=json&include_details=true&include_statistics=true" \
> -H "X-Api-Key: YOUR_API_KEY"

Email result structure

1{
2 "alice@example.com": {
3 "email": "alice@example.com",
4 "valid": true,
5 "wrong": false,
6 "unknown": false,
7 "quality": "good",
8 "result": "ok",
9 "is_syntax_error": false,
10 "is_free": false,
11 "is_role": false,
12 "is_disposable": false,
13 "is_catch_all": false
14 },
15 "info@company.org": {
16 "email": "info@company.org",
17 "valid": true,
18 "wrong": false,
19 "unknown": false,
20 "quality": "risky",
21 "result": "ok",
22 "is_syntax_error": false,
23 "is_free": false,
24 "is_role": true,
25 "is_disposable": false,
26 "is_catch_all": false
27 }
28}

Email result field reference

FieldTypeValuesDescription
validbooleanDeliverable and safe to contact
wrongbooleanInvalid or undeliverable
unknownbooleanInconclusive result
qualitystringgood, bad, risky, unknownOverall quality signal
resultstringok, invalid, error, unknownSMTP-level result
is_syntax_errorbooleanFails RFC 5321/5322 syntax validation
is_freebooleanFree provider (Gmail, Yahoo, Outlook…)
is_rolebooleanRole address (info@, admin@, support@…)
is_disposablebooleanKnown disposable/one-time inbox service
is_catch_allbooleanDomain accepts all addresses

Phone result structure

1{
2 "+6591234567": {
3 "phone": "+6591234567",
4 "valid": true,
5 "wrong": false,
6 "unknown": false,
7 "type": "mobile",
8 "status": "live",
9 "is_syntax_error": false,
10 "is_ported": false,
11 "current_network_mcc": "525",
12 "current_network_mnc": "01",
13 "operator": "Singtel"
14 }
15}

Phone result field reference

FieldTypeValuesDescription
validbooleanActive and reachable number
wrongbooleanInvalid number
unknownbooleanInconclusive result
typestringmobile, landline, mobile_or_landline, voip, toll_free, premium, shared_cost, pager, voicemail_only, bad_format, unknownNumber classification
statusstringlive, dead, absent_subscriber, no_teleservice_provisioned, not_available_network_only, no_coverage, not_applicable, inconclusiveLive network status
is_syntax_errorbooleanFails E.164 format validation
is_portedbooleanNumber has been ported to a different carrier
current_network_mccstring|nullMobile Country Code of current network
current_network_mncstring|nullMobile Network Code of current network
operatorstring|nullCurrent network operator name

Complete workflow: end-to-end example

$API_KEY="YOUR_API_KEY"
$BASE="https://api.apexverify.com"
$
$# 1. Upload
$UPLOAD=$(curl -s -X POST $BASE/v1/batch \
> -H "X-Api-Key: $API_KEY" \
> -F "file=@contacts.txt" \
> -F "name=April Campaign" \
> -F "type=email" \
> -F "target_country=US")
$UUID=$(echo $UPLOAD | jq -r '.batch_uuid')
$echo "Batch UUID: $UUID"
$
$# 2. Configure parameters
$curl -s -X PUT "$BASE/v1/batch/$UUID" \
> -H "X-Api-Key: $API_KEY" \
> -H "Content-Type: application/json" \
> -d '{"type":"email","target_country":"US","use_account_cache":true,"use_global_cache":true}'
$
$# 3. Trigger parsing
$curl -s -X PATCH "$BASE/v1/batch/$UUID" \
> -H "X-Api-Key: $API_KEY"
$
$# 4. Wait for ready_for_verification (simplified — use polling loop in production)
$sleep 10
$
$# 5. Launch verification
$curl -s -X POST "$BASE/v1/batch/$UUID" \
> -H "X-Api-Key: $API_KEY"
$
$# 6. Poll until done
$DELAY=5
$while true; do
$ STATUS=$(curl -s "$BASE/v1/batch/$UUID" -H "X-Api-Key: $API_KEY" | jq -r '.status')
$ [ "$STATUS" = "verification_done" ] && break
$ sleep $DELAY
$ DELAY=$((DELAY < 60 ? DELAY * 2 : 60))
$done
$
$# 7. Export JSON results
$curl -s "$BASE/v1/batch/$UUID/export?format=json" \
> -H "X-Api-Key: $API_KEY" > results.json
$
$# OR export XLSX
$curl -s "$BASE/v1/batch/$UUID/export?format=xlsx" \
> -H "X-Api-Key: $API_KEY" \
> -o results.xlsx

What’s Next?