Skip to main content
The Juiced API lets you submit leads programmatically, check pricing before committing, and integrate your lead sources directly with the platform.
Sending leads from a form builder, funnel, ad platform, CRM or another lead platform? See Sending leads from other tools.

Base URL

All API requests go to this base URL.

Versioning

Build on v1, the endpoints under /api/v1. The original unversioned endpoints (/api/ping and /api/leads) are now the legacy API. They keep working, but they’re frozen and deprecated, so new features and fixes land in v1 only. Already integrated with the legacy endpoints? See Migrating from the legacy API.

Headers

All requests must include these headers.

Partner attribution

If you’re integrating on behalf of a partner, include their public ID in the X-Partner-Id header on pings. Juiced records the ping against that partner when the partner is linked to the source whose credentials you use, so it shows up in their ping logs. Lead posts ignore the header.
The header is optional (requests without it still succeed), but including it is strongly recommended for any partner-mediated integration.

Authentication

The API supports two authentication methods.

Basic Authentication

Use your source’s API key and secret, Base64-encoded in the format api_key:api_secret.

Bearer Token

Use a bearer token generated for your source.
You can find your API credentials in your source settings within Juiced.

Endpoints

Ping-post workflow

The typical integration flow uses both endpoints.
  1. Ping with partial lead data (at minimum, a zip code) to check for matching bids and get pricing.
  2. Post the full lead with the ping’s id as ping_id if the price is acceptable.
This two-step process lets you make informed decisions about which leads to sell and at what price before committing. You can also skip the ping and instead post the lead directly if you don’t need to check pricing first.

Source-specific fields

The exact fields available (and which ones are required) depend on your source and lead category configuration. The documentation here covers the standard fields, but your source may have additional requirements.
For the exact API spec tailored to your source (including your credentials and all configured fields), visit Sources → [Your Source] → View API Spec in your Juiced admin dashboard. If it still shows /api/ping or /api/leads, use the /api/v1/ paths instead.

Safe retries

Network hiccups happen, and a lead you can’t confirm is a lead you’re tempted to send twice. Add a transaction_id to each lead post (your own order or lead number works well, up to 255 characters) and retries become safe. Transaction IDs are scoped to the source sending them, and test-mode posts are tracked separately from live ones.
  • Same transaction_id, same payload returns the original status and body again, without creating another lead.
  • Same transaction_id, different payload returns 409 (idempotency_conflict on v1).
  • The first attempt is still processing returns 409 with a Retry-After header (idempotency_in_progress on v1). Wait and send the same request again.
  • The outcome couldn’t be confirmed returns 409 (idempotency_reserved on v1). The lead may already have been delivered, so don’t resubmit it. It’s held for review.
A post that didn’t create a lead (it failed validation, hit a lead quota, or failed on our side) doesn’t use up its transaction_id, so you can fix the payload and send it again with the same ID. A lead rejected for not matching its ping was still recorded, so its transaction_id stays taken.

Rate limits

The API accepts up to 240 requests a minute, counting pings and leads together. Past that, it returns 429 with a Retry-After header giving the seconds to wait (rate_limited on v1).

Test mode

Turn on test mode from the source’s edit form to try your integration. While it’s on, these zip codes return fixed outcomes on both pings and posts. 00001 is priced at 25 dollars and 00005 at 15, on both the ping and the lead. The other zips are priced at 0. Vendor sources get the ping price as price. Other sources get a single bid named Test Mode at that price on 00001 and 00005, and an empty bids list on the other zips. Lead statuses assume the source’s default status responses mapping. With any other zip, pings are matched as usual (including pings to your partners), and leads are marked as test data and never distributed. Those leads are moved to Audit unless they’re duplicates or can’t be categorized. Stick to the zips above while you build, and turn test mode off before going live.

Errors

The API uses standard HTTP status codes. A ping that passes validation always returns 200. A lead that passes validation returns 201 whatever its outcome, unless it doesn’t match its ping (422). Check the status in the body for the outcome. Every v1 error uses the same envelope. Branch on error.code, which is stable, rather than on message.

Request IDs

Every v1 response, errors included, carries an X-Request-Id header such as req_01jbx8k6y3a5c7e9g1j3m5p7rt. Log it with your request, and quote it when you contact support so we can find the exact request.

Migrating from the legacy API

Deprecation headers

Every legacy ping and lead response carries two headers that announce its replacement.
Deprecation is the date the legacy API was deprecated, as @ plus a Unix timestamp (RFC 9745). Link points to the v1 endpoint that replaces the one you called. There’s no Sunset header yet, which means no shutdown date has been set.

Moving from legacy to v1

  1. Change the path from /api/ping to /api/v1/ping and from /api/leads to /api/v1/leads. Credentials and field names stay the same, but ID values change (steps 2 and 4).
  2. Read results from data. A ping’s ping_id and message become data.id and data.status, and its price (vendors) or bids move under data too. A lead’s lead_public_id and status become data.id and data.status, and lead_uuid is gone. Each bid’s id, customer_id and partner_id become public IDs.
  3. Update the values you compare against. Ping messages become matched, no_match, duplicate and rejected, and the lead status success becomes accepted.
  4. Send the v1 ping’s data.id as ping_id on the lead and, if you echo a bid, its bids[].id as bid_id. v1 rejects the UUIDs the legacy API returns, so post a legacy ping’s lead to the legacy API.
  5. Handle errors by error.code rather than by message.
One transaction_id is one lead, whichever version it arrives on. If you retry a lead on a different version from the one you first sent it to, Juiced won’t create a second lead. You get a 409 instead (idempotency_version_mismatch on v1), and v1 names the original lead in error.lead_id. Finish in-flight retries on the version they started on.

Legacy errors

The legacy endpoints keep their original error bodies. Validation errors return 422 with a message and an errors object keyed by field. Transaction conflicts (409) and a lead that doesn’t match its ping return a single error string. Everything else returns a message. See Submit a Lead (Legacy) for every legacy response.