Developers / CLI · SDK · REST
Skip trace in
one command.
Turn a US property address into the owner's name, phone numbers with DNC flags, emails, and mailing address. One npm package gives you a CLI and a typed JS/TS SDK; the REST API works from any language. It is the same flat 4¢ per match as the dashboard rate sheet, and misses are always free.
npm install -g skiptrace
Get an API Key
- 4¢per match
- $0per miss
- 1package, 3 ways in
For AI Agents
Vibe coder?
Copy a ready-made brief with the endpoint, auth, SDK, and error handling, then paste it into your AI coding agent and let it wire up DataSkip for you.
- Claude
- Codex
- Cursor
Everything your agent needs, in one paste.
01 / CLI
From your terminal
Create an API key in the dashboard (Settings → API), save it once, then trace addresses straight from your shell. Exit codes are script-friendly: 0 match, 1 miss, 2 usage error, 3 API error.
$ skiptrace config set-key pc_xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx
$ skiptrace "123 Example St, Phoenix AZ 85001"
$ skiptrace lookup "44 Pine St" --city Bridgewater --state MA --zip 02324
$ skiptrace "123 Main St, Austin TX 78701" --json | jq '.phones'
02 / npm package
From your code
The skiptrace package imports as a typed library. The API key falls back to the SKIPTRACE_API_KEY env var, then the saved CLI config, so new SkipTrace() with no arguments just works.
import { SkipTrace, ApiError } from 'skiptrace';
const st = new SkipTrace({ apiKey: process.env.SKIPTRACE_API_KEY });
try {
const result = await st.skip('123 Example St, Phoenix AZ 85001');
if (result.found) {
console.log(result.contact.fullName, result.phones, result.emails);
}
} catch (err) {
if (err instanceof ApiError && err.status === 402) {
// insufficient balance
}
}
import { SkipTrace, ApiError } from 'skiptrace';
const st = new SkipTrace({ apiKey: process.env.SKIPTRACE_API_KEY });
try {
const result = await st.skip('123 Example St, Phoenix AZ 85001');
if (result.found) {
console.log(result.contact.fullName, result.phones, result.emails);
}
} catch (err) {
if (err instanceof ApiError && err.status === 402) {
// insufficient balance
}
}
import { SkipTrace, ApiError } from 'skiptrace';
import type { LookupInput, LookupResponse } from 'skiptrace';
const st = new SkipTrace({ apiKey: process.env.SKIPTRACE_API_KEY });
const input: LookupInput = { address: '44 Pine St', city: 'Bridgewater', state: 'MA', zip: '02324' };
const result: LookupResponse = await st.skip(input);
if (result.found && result.contact) {
console.log(result.contact.fullName, result.phones, result.emails);
}
03 / REST API
From anywhere
One endpoint, any language, with your API key as a Bearer token. A hit charges 4¢ and returns the full contact; a miss returns found: false and charges nothing.
POST https://app.dataskip.io/api/v1/skip-trace
$ curl -X POST https://app.dataskip.io/api/v1/skip-trace \
-H "Authorization: Bearer pc_xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx" \
-H "Content-Type: application/json" \
-d '{
"address": "44 Pine St",
"city": "Bridgewater",
"state": "MA",
"zip": "02324"
}'
$ curl -X POST https://app.dataskip.io/api/v1/skip-trace \
-H "Authorization: Bearer pc_xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx" \
-H "Content-Type: application/json" \
-d '{
"address": "44 Pine St",
"city": "Bridgewater",
"state": "MA",
"zip": "02324"
}'
import os
import requests
resp = requests.post(
"https://app.dataskip.io/api/v1/skip-trace",
headers={"Authorization": f"Bearer {os.environ['SKIPTRACE_API_KEY']}"},
json={"address": "44 Pine St", "city": "Bridgewater", "state": "MA", "zip": "02324"},
)
data = resp.json()
if data["found"]:
print(data["contact"]["fullName"], data["phones"], data["emails"])
<?php
$ch = curl_init('https://app.dataskip.io/api/v1/skip-trace');
curl_setopt_array($ch, [
CURLOPT_RETURNTRANSFER => true,
CURLOPT_POST => true,
CURLOPT_HTTPHEADER => [
'Authorization: Bearer ' . getenv('SKIPTRACE_API_KEY'),
'Content-Type: application/json',
],
CURLOPT_POSTFIELDS => json_encode(['address' => '44 Pine St', 'city' => 'Bridgewater', 'state' => 'MA', 'zip' => '02324']),
]);
$data = json_decode(curl_exec($ch), true);
if ($data['found']) {
echo $data['contact']['fullName'];
}
{
"success": true,
"found": true,
"charged": 4,
"contact": {
"firstName": "J•••",
"lastName": "C•••••",
"fullName": "J••• C•••••",
"propertyAddress": "44 Pine St",
"propertyCity": "Bridgewater",
"propertyState": "MA",
"propertyZip": "02324",
"mailingAddress": "44 Pine St",
"mailingCity": "Bridgewater",
"mailingState": "MA",
"mailingZip": "02324"
},
"phones": [
{ "number": "(•••) •••-0182", "type": "mobile", "dnc": false },
{ "number": "(•••) •••-4415", "type": "landline", "dnc": true }
],
"emails": ["j•••••@•••••.com"]
}
| Status | Meaning |
|---|---|
| 200 | Lookup ran. Check found: a miss is still 200 with contact: null and no charge. |
| 400 | Missing or invalid address in the JSON body. |
| 401 | Missing or invalid API key. |
| 402 | Insufficient balance to cover a match. Top up in the dashboard. |
| 429 | Rate limited. Retry after the indicated delay. |
Ship it in an
afternoon.
Get Your API Key
4¢ per match · misses free · support@dataskip.io