APIUpdated 2026-10-13

API Quickstart: Authentication, Sandbox, and Errors

Create an API key, make your first calls, and handle rate limits and the error envelope.

The Acquired Data API lets you run everything the dashboard can do — skip tracing, DNC scrubbing, property pulls, and buyer searches — from your own code. All endpoints live under a single base URL; property data has a newer v2 surface alongside it (same key, same error envelope):

Base URL
https://www.acquired-data.com/api/v1
https://www.acquired-data.com/api/v2   (property pulls and enrichment)

Integrations built against the previous base URL, https://data.acquiredcrm.com/api/v1, continue to work — no migration required. New integrations should use the base URL above.

Create an API key

Go to Dashboard → Webhooks → API Keys and create a key. Keys look like ad_live_... and are shown once, at creation time — copy it into your secrets manager immediately. If you lose a key, revoke it and create a new one. Every request authenticates with a standard bearer header:

Authentication header
Authorization: Bearer ad_live_XXXX

API usage bills against the same credit balance as the dashboard, at your account's per-operation rates.

The in-dashboard API Documentation page with an endpoint sidebar, an Overview showing the Authorization Bearer header, and a per-account pricing table.
Dashboard → API Docs — the full reference, including your account's own pricing table.

Your first two calls

Start with GET /me — it verifies your key and returns your credit balances plus the environment your account is running in:

Request
curl https://www.acquired-data.com/api/v1/me \
  -H "Authorization: Bearer ad_live_XXXX"
Response
{
  "email": "you@company.com",
  "credits_balance": 52689,
  "monthly_credits": 30000,
  "purchased_credits": 22689,
  "environment": "production"
}

Then fetch GET /pricing. Pricing is per account — custom rates override the platform defaults — so always read your own numbers instead of hardcoding them:

Request
curl https://www.acquired-data.com/api/v1/pricing \
  -H "Authorization: Bearer ad_live_XXXX"
Response
{
  "currency": "credits",
  "per_record": {
    "base_trace": 1,
    "single_trace": 2,
    "llc_trust_trace": 6,
    "property_pull": 1,
    "buyer_profile": 70,
    "cached_buyer_profile": 10
  },
  "add_ons": {
    "dnc": 0.5,
    "phone_verification": 0,
    "litigator": 0.5,
    "deceased": 0,
    "tested_emails": 0.1,
    "data_verification": 0.9,
    "family_contacts": 1,
    "verified_contact": 1,
    "property_valuation": 0,
    "property_liens": 0
  },
  "property_data": {
    "credit_per_record": 1,
    "free_records_per_period": 30000,
    "free_records_remaining": 27410,
    "period_end": "2026-11-03T00:00:00Z"
  },
  "notes": "Costs are per record, in credits. LLC/Trust-owned records bill at llc_trust_trace instead of base_trace; trace add-ons are charged per record on top. Property pulls and enrichment are 1 credit per record with every dataset included; subscribers' plan credits double as free records each period."
}

Property data is the one flat rate: property_pull is always 1 credit per record with everything included, and the property_data block reports how many free records your subscription still has this period (see property pulls and enrichment).

Sandbox vs. production

The environment field on /me (and on every job response) tells you which mode your account is in. In sandbox, requests return realistic sample data and never bill credits — ideal for wiring up your integration end to end. In production, every operation runs against live data and charges credits. Contact support to switch your account between environments.

One exception: the property endpoints — POST /api/v1/enrich, POST /api/v2/enrich, and /api/v1/property-pulls / /api/v2/property-pulls — always run live against our own property database and charge credits (or use free records) regardless of the account environment; their responses report environment: "production" even on a sandbox account. Test them with small counts.

Rate limiting

Each key is limited to 60 requests per minute. Exceeding it returns 429 rate_limited with a Retry-After header (seconds until the window resets). Bulk operations run one job of each kind per account at a time. Skip-trace jobs submitted while one is running are queued (up to five, started automatically in order — the 202 says "queued" with a queue_position); once five are waiting, a submission returns 429 queue_full. A synchronous call (single trace) made while a bulk job is running, or a concurrent job of another kind, returns 429 job_in_progress — wait for the running job to resolve, or honor Retry-After.

Error envelope

Every error response uses one consistent envelope:

Error envelope
{
  "error": {
    "code": "insufficient_credits",
    "message": "Not enough credits for this job."
  }
}
StatusCodeWhen
401unauthorizedMissing, malformed, or revoked API key
402insufficient_creditsNot enough credits — top up in Billing
403lockdownPlatform temporarily locked by an administrator
404not_foundResource doesn't exist or belongs to another account
409job_not_completeResults or a webhook retry requested before the job resolved
422validation_errorBad request body — the message lists the offending fields
429job_in_progressA synchronous call was made while a bulk job is running on this account — retry after Retry-After
429queue_fullAlready 5 bulk jobs waiting on this account — retry after Retry-After
429rate_limitedOver 60 requests/minute on this key — retry after Retry-After
500internal_errorUnexpected failure — safe to retry

Endpoint index

EndpointWhat it does
GET /v1/me · GET /v1/pricingAccount snapshot and your live per-record rates.
POST /v1/trace · POST /v1/jobs · GET /v1/jobs/{id}Single and bulk skip tracing, with results and completion webhooks.
POST /v1/dnc-jobs · POST /v1/phone-scrubsDNC/TCPA scrubbing of traced rows, and of phone numbers you already have.
POST /v2/property-pulls · POST /v2/property-pulls/countPull filtered property lists from the property database; count matches for free first.
GET /v2/property-pulls · GET /v2/property-pulls/{id} · GET /v2/property-pulls/{id}/resultsList pulls, check one, and page through its records as JSON.
GET /v2/property-pulls/quota · GET /v2/property-pulls/list-stacksYour free-record allowance this period, and the List Stack slugs you can filter by.
POST /v2/enrichFull property record for a single address.
POST /v1/property-pulls · POST /v1/enrichBackward-compatible v1 property endpoints (same bodies, now 1 credit per record).
POST /v1/buyersLikely buyers for a property address.

Next steps

Keep reading