Background lookup jobs: submit and retrieve results
Submit asynchronous phone lookup work using the existing jobs API, track status and retrieve results. Product pricing still applies.
When should I use a background job?
Use the jobs API when your application can submit work and collect results later instead of waiting for a synchronous lookup request. The submission endpoint is POST /api/v1/jobs; follow the reference below for supported fields, status and result retrieval.
Does using a job change inclusion prices?
No. Selected products and your account rates determine costs. Processing a job does not make CNAM, messaging or trust free. Review the documented billing outcome and retrieve the results before deciding whether any retry is necessary.
Continue with the right guide
- LRN lookup: one number and optional inclusions
- Enhanced LRN: carrier details for one number
- Bulk LRN lookup: lists of numbers
- Background lookup jobs: submit and retrieve results
- Lookup pricing and inclusion costs
- MCP Server – Phone Intelligence for AI Agents
- API Authentication
- Understanding carrier classifications
- Python SDK
- TypeScript SDK
Async Jobs API
For lists beyond the 1,000-number synchronous cap, submit an async job: up to 100,000 numbers per job (JSON array or CSV upload), processed in the background with the same per-lookup pricing. Balance is reserved at submission and settled on completion; invalid rows are skipped, reported with specific reasons, and never charged.
Submit — JSON array
curl -s https://verirouteintel.com/api/v1/jobs \
-H "Authorization: Bearer YOUR_API_KEY" \
-H "Content-Type: application/json" \
-d '{
"phone_numbers": ["13364086644", "12025551234"],
"include_enhanced": true,
"webhook_url": "https://example.com/hooks/vri",
"webhook_secret": "your-shared-secret"
}'
Submit — CSV upload
Multipart field file, numbers in the first column, up to 50MB. Options go in ordinary form fields.
curl -s https://verirouteintel.com/api/v1/jobs \
-H "Authorization: Bearer YOUR_API_KEY" \
-F "file=@numbers.csv" \
-F "include_enhanced=true"
Response (202 Accepted)
{
"job_id": "0f8b7c2a-1d2e-4a5b-9c3d-7e6f5a4b3c2d",
"status": "SUBMITTED",
"summary": {
"submitted": 4, "unique": 2, "duplicates_removed": 1,
"invalid": 1,
"invalid_examples": [
{ "input": "11440647558", "error": "Invalid area code: 144. Area codes cannot start with 0 or 1." }
],
"processed": 0, "failed": 0
},
"billing": { "estimated_cost": 0.001, "actual_cost": null, "billing_status": null },
"links": {
"status_url": "https://verirouteintel.com/api/v1/jobs/0f8b7c2a-.../",
"results_url": null
},
"webhook": { "configured": true, "status": null }
}
Check status
Returns the same shape with live counts, billing.actual_cost once settled, and links.results_url when the job completes. GET /api/v1/jobs lists your 50 most recent jobs.
Download results
Streams the result CSV. Until the job completes this returns 409 with the current status.
Completion webhook
Supply webhook_url at submission and we POST a job.completed event when the job finishes. With a webhook_secret, the request carries an HMAC-SHA256 signature you can verify:
{
"event": "job.completed",
"timestamp": "2026-09-01T15:04:05+00:00",
"job": {
"id": "0f8b7c2a-...", "status": "COMPLETED",
"total_numbers": 2, "processed_numbers": 2, "failed_numbers": 0,
"billing_status": "COMPLETED",
"options": { "lrn": true, "enhanced_lrn": true, "cnam": false, "spam": false, "messaging_provider": false }
},
"download_url": "https://verirouteintel.com/api/v1/jobs/0f8b7c2a-.../results",
"retry_available": false
}
Headers: X-Webhook-Event, X-Webhook-Job-Id, X-Webhook-Timestamp, and (when a secret is set) X-Webhook-Signature: sha256=<hex>. Verify it:
import hmac, hashlib
def verify(raw_body: bytes, secret: str, signature_header: str) -> bool:
expected = hmac.new(secret.encode(), raw_body, hashlib.sha256).hexdigest()
return hmac.compare_digest(f"sha256={expected}", signature_header)
Delivery is retried on failure; the webhook must answer 2xx within 10 seconds. Webhook URLs must be publicly reachable (private/loopback addresses are rejected at submission).
Limits & billing
- Up to 100,000 numbers per job (JSON or CSV; CSV files up to 50MB). Test keys cannot submit jobs — use a live key.
- The full estimated cost is reserved from your balance at submission and settled to actual usage on completion — a job you can't fund is refused with a
402and nothing is created. - Duplicates are removed (charged once); invalid rows are skipped, reported, and never charged.
- Prefer an AI-agent interface? The same engine is exposed over MCP (
vri_submit_job, up to 10,000 numbers).
Product prices · public rates
Each selected product adds its per-number cost. Estimates do not submit lookups or charge your wallet.
- lrn
- $0.000500 per number
- enhanced_lrn
- $0.000000 per number
- messaging_provider
- $0.000900 per number
- cnam
- $0.006000 per number
- spam
- $0.007000 per number