API documentation
Three services, one consistent response. Every example below uses the published sample values, which demo mode accepts at no cost.
Make your first request
Create a key in your workspace, keep it in an environment variable, and send JSON with the key in the Authorization header.
Every lookup returns the same envelope: request_id, mode, status, service, credits_consumed, data and error.
null inside data means unknown. We never fill a gap with a guess.
curl -X POST https://lookupdock.com/api/v1/email \
-H "Authorization: Bearer $LOOKUPDOCK_KEY" \
-H "Content-Type: application/json" \
-H "Idempotency-Key: $(uuidgen)" \
-d '{"value": "[email protected]"}'
require "net/http"
require "json"
require "securerandom"
uri = URI("https://lookupdock.com/api/v1/email")
request = Net::HTTP::Post.new(uri, "Authorization" => "Bearer #{ENV.fetch("LOOKUPDOCK_KEY")}",
"Content-Type" => "application/json", "Idempotency-Key" => SecureRandom.uuid)
request.body = { value: "[email protected]" }.to_json
response = Net::HTTP.start(uri.host, uri.port, use_ssl: uri.scheme == "https") { |http| http.request(request) }
puts response.code, JSON.parse(response.body)
import os
import uuid
import requests
response = requests.post(
"https://lookupdock.com/api/v1/email",
headers={
"Authorization": f"Bearer {os.environ['LOOKUPDOCK_KEY']}",
"Idempotency-Key": str(uuid.uuid4()),
},
json={"value": "[email protected]"},
timeout=20,
)
print(response.status_code, response.json())
const response = await fetch("https://lookupdock.com/api/v1/email", {
method: "POST",
headers: {
Authorization: `Bearer ${process.env.LOOKUPDOCK_KEY}`,
"Content-Type": "application/json",
"Idempotency-Key": crypto.randomUUID(),
},
body: JSON.stringify({ value: "[email protected]" }),
});
console.log(response.status, await response.json());
Authentication
Send Authorization: Bearer YOUR_KEY with every request. Keys start with lk_, are shown once when created and are stored only as SHA-256 digests. Revoke a key in the workspace at any time; requests with it fail with 401 immediately.
Your email address must be verified before keys work. Never put keys or personal data in URLs.
Idempotency
Add an Idempotency-Key header to retry safely. A repeat with the same key and payload returns the original result without a second check or charge. The same key with a different payload returns 409. A check still running returns 202; a check whose details have expired returns 410 without calling the supplier again.
POST /api/v1/phone
Formatting, country, carrier and line type. Send an E.164 number (starting with +) or add a two-letter country for national numbers.
value(string, required): the phone to check.country(string, optional): two-letter country code for national numbers.
{
"request_id": "req_sample_phone",
"mode": "demo",
"status": "completed",
"service": "phone",
"credits_consumed": 0,
"data": {
"valid": true,
"formatted": "+1 (415) 555-0132",
"country": "US",
"carrier": "Sample carrier",
"line_type": "Mobile",
"active": null,
"uncertain": true,
"sample": true
},
"error": null
}
POST /api/v1/email
Deliverability, disposable and catch-all signals. Catch-all, suspect and timed-out results are uncertain.
value(string, required): the email to check.
{
"request_id": "req_sample_email",
"mode": "demo",
"status": "completed",
"service": "email",
"credits_consumed": 0,
"data": {
"valid": true,
"deliverability": "high",
"disposable": false,
"catch_all": false,
"uncertain": false,
"sample": true
},
"error": null
}
POST /api/v1/ip
Location, network and proxy or VPN signals. Network flags are signals, not proof of fraud.
value(string, required): the ip address to check.
{
"request_id": "req_sample_ip",
"mode": "demo",
"status": "completed",
"service": "ip",
"credits_consumed": 0,
"data": {
"country": "US",
"city": "Sample city",
"asn": null,
"network": "Documentation network",
"vpn": false,
"proxy": false,
"uncertain": true,
"sample": true
},
"error": null
}
GET /api/v1/usage
Returns mode, credits_available, credits_expire_at, total_checks and subscription_status for your account.
Batches
POST /api/v1/batches as multipart form data with file, kind and column_name (and optional country). It returns 202 with the batch id.
GET /api/v1/batches/:id reports status, processed and total. GET /api/v1/batches/:id/download returns the results CSV, with spreadsheet formulas escaped.
Files need a unique, non-empty header row and may contain up to 10,000 data rows, 50 columns and 10 MB.
Errors and status codes
Errors use one shape: {"request_id": "…", "error": {"code": "…", "message": "…"}}.
| Status | Meaning |
|---|---|
200 | Check completed |
202 | Still processing; repeat with the same Idempotency-Key |
401 | Missing, invalid or revoked key |
402 | Not enough credits |
403 | Email address not verified |
409 | Idempotency-Key reused with a different payload |
410 | Details expired |
422 | Invalid input, or a non-sample value in demo mode |
429 | Rate limit reached |
502 | Provider error or uncertain result (no charge) |
503 | Service unavailable |
Limits
- 60 individual checks per minute per account.
- 5 batch uploads per minute per account.
- Values up to 320 characters.
Sample values
Demo mode accepts only these values. They cost nothing and never query live data. Any other value returns a sample-only error.
| Service | Sample value |
|---|---|
| Phone | +14155550132 |
| [email protected] | |
| IP address | 203.0.113.42 |
Data and retention
Lookup inputs and results are encrypted and deleted after seven days; usage counts remain. Uploaded CSV files are not kept. See the privacy notice and data processing terms.