Send leads to Juiced from your own code
This guide is for developers and AI-built funnels (Lovable, Replit, Bolt or your own site). The route is direct: your server or a serverless function POSTs JSON to the Juiced API with your token in the Authorization header.
Route: direct. POST a JSON body with top-level keys to https://usejuiced.com/api/v1/leads from server-side code, with Authorization: Bearer <token>.
You need a Juiced source with a bearer token (or API key and secret for Basic Auth) and somewhere to run server code: an API route, a serverless function or an edge function.
The gotcha: never put the token in browser code. Anyone can read it there. Have the form call your own function, and let that function call Juiced.
Before you start
- Juiced: a source with Test mode on, a bearer token from its Authentication tab (or the API Key and API Secret for Basic Auth), and the Field Reference from View API Spec, which lists each field's type and whether it is required for post and for ping.
- Your stack: server-side code that can make an HTTPS request and read a secret: a backend route, a serverless function or an edge function. AI app builders generate these on request.
Step by step
-
Create a Juiced source and copy a token
In Juiced, go to Ingest > Sources > New source, turn on Test mode and click Create source. On the Authentication tab click New bearer token > Create token and copy it (it is shown once). Open Overview > More actions (⋯) > View API Spec for the endpoint, an example cURL and the field list. Walkthrough: setting up a source.
-
Store the token as a server-side secret
Save the token as an environment variable or secret, for example
JUICED_TOKEN, never in front-end code or a public build variable. In Lovable, add it under More > Settings > Secrets with Add secret. Lovable's docs say secrets are injected into Edge Functions and server-side integrations and never reach the browser, while values inVITE_variables are public (Lovable secrets, connecting any API). Other platforms have an equivalent secrets setting. -
Send the lead from your server
Have your form submit to your own function. That function builds a JSON object whose keys match the Juiced field titles and POSTs it to
https://usejuiced.com/api/v1/leadswith theAuthorization,Content-Type: application/jsonandAccept: application/jsonheaders. See the examples below. -
Handle the response
A
201means Juiced received the lead; readdata.status,data.priceanddata.id. Errors returnerror.code: branch on the code, not the message. A401(unauthenticated) means missing or invalid credentials. A422returnsvalidation_failedwitherrorskeyed by field,quota_reachedorping_mismatch, so fix the data and resend rather than retrying as is. Details: v1 leads endpoint. -
Test with test zips and check the log
With test mode on, send
zipvalues00001(accepted, Assigned),00002(duplicate),00003(rejected, Audit),00004(rejected, Unassigned) and00005(accepted, Marketplace), and check your code handles each. In Juiced open Entries > Incoming logs, filter Test mode > Test only, open a log and click Post to see the payload as received and the response. Turn test mode off before going live.
Example request
cURL with a bearer token:
curl -X POST https://usejuiced.com/api/v1/leads \
-H "Authorization: Bearer <your token>" \
-H "Content-Type: application/json" \
-H "Accept: application/json" \
-d '{"first_name":"Jane","last_name":"Doe","email":"jane@example.com","phone":"5555550100","zip":"00001"}'
For Basic Auth, replace the Authorization line with -u "<API Key>:<API Secret>".
JavaScript fetch() in a server or edge function (in a Deno edge function, read the secret with Deno.env.get("JUICED_TOKEN")):
// Runs on the server only. Never ship this token to the browser.
const res = await fetch("https://usejuiced.com/api/v1/leads", {
method: "POST",
headers: {
"Authorization": "Bearer " + process.env.JUICED_TOKEN,
"Content-Type": "application/json",
"Accept": "application/json",
},
body: JSON.stringify({
first_name: lead.first_name,
last_name: lead.last_name,
email: lead.email,
phone: lead.phone,
zip: lead.zip,
utm_source: lead.utm_source,
}),
});
const json = await res.json();
if (res.status === 201) {
// json.data.id, json.data.status, json.data.price
} else if (res.status === 422) {
// json.error.code; json.errors is keyed by field: fix the input, then resend
} else if (res.status === 401) {
// check the token and the Authorization header
}
A 201 body looks like {"data": {"id": "lead_...", "status": "accepted", "price": ...}, "version": "v1"}. With Juiced's default status mapping, data.status is accepted (assigned, posted to a partner, marketplace or Club), rejected (Unassigned, Audit or Uncategorized: received but not sold) or duplicate. data.price is what the source earns, 0 unless accepted. Only top-level JSON keys are documented: no form-encoded bodies, no nested objects, no token in the URL.
Ping then post
To check for matching bids before sending contact details, POST a partial lead to https://usejuiced.com/api/v1/ping with the same headers. zip is required; the Field Reference shows which other fields are required for ping.
POST https://usejuiced.com/api/v1/ping
{ "zip": "00001", "state": "FL" }
Every validated ping returns 200, so read data.status: matched, no_match, duplicate or rejected. Then POST the full lead to /api/v1/leads with ping_id set to data.id, plus bid_id (the chosen bid from data.bids) for non-vendor sources. For the other response fields, see the v1 ping endpoint and ping post in Juiced.
Field mapping
| Your form or app value | Juiced key |
|---|---|
| Name fields | first_name, last_name |
| Email and phone | email, phone |
| Zip or postal code (always required) | zip |
| Address | address_1, address_2, city, state, county |
| Custom questions | A field you add on the lead category or the source's Fields tab |
| UTM values read from the page URL | utm_source, utm_campaign (add them as fields first) |
| TrustedForm or Jornaya value | trusted_form_cert_url or jornaya_leadid |
Keys must match the field Title exactly: letters, numbers and underscores, starting with a letter or underscore. Unknown keys show in the post inspector but are not saved, and List of Values fields accept only their listed values.
TrustedForm and Jornaya
If your page runs the TrustedForm script, it adds a hidden input named xxTrustedFormCertUrl to the form; the script must load after the form exists and in the same window as the form (TrustedForm Certify docs). Send that value to your function and pass it on as trusted_form_cert_url, a field you add to the source (Type: URL, Deliverable if buyers need it). See passing consent certificates.
Troubleshooting
- Duplicates on retry. Send a
transaction_id(up to 255 characters) with each lead: resending the sametransaction_idwith the same payload returns the original response, so retries are safe. See duplicate lead checking. - 401 Unauthorized. Use
Bearer, one space, then the token, with no line break. A new token expires the previous one 24 hours later, so update the secret and redeploy. - 429 rate_limited. Wait for the time in the
Retry-Afterheader, then resend. - 422 on every lead. Read
error.codeanderrors. Usuallyzipis missing, a key does not match a field title, or values are nested under an object instead of top level. - A CORS error in the browser. The browser is calling Juiced directly, which also exposes the token. Move the call into your server or edge function.
- 201 with status rejected. Received but not sold. Open the log to see why.
More fixes: webhook troubleshooting.
Frequently asked
Does Juiced have an API for sending leads?
Yes. POST JSON to https://usejuiced.com/api/v1/leads with a bearer token or Basic Auth. zip is always required, and the response returns data.id, data.status and data.price.
Can I call the Juiced API from browser JavaScript?
No. The token would be visible to anyone who opens the page. Call Juiced from a server route, serverless function or edge function and keep the token in a server-side secret.
How do I send leads to Juiced from a Lovable app?
Store the token under More > Settings > Secrets, ask Lovable to create a server or edge function that posts the form data to the Juiced leads endpoint, and have the form call that function.
How does ping post work with the Juiced API?
POST a partial lead to /api/v1/ping and read data.status (matched or no_match). Then POST the full lead to /api/v1/leads with ping_id set to the ping’s data.id.
What does a 422 from Juiced mean?
The lead was refused. Read error.code: validation_failed comes with an errors object keyed by field, for example a missing zip. quota_reached and ping_mismatch are the other codes. Fix the data and resend.
Route every API lead to the right buyer
Juiced routes each lead to buyers by bids, caps and criteria, and leads no buyer takes can go to your marketplace.
Scale your lead business, without limits
Juiced puts you in full control of your leads, routing, and revenue, so you can automate, optimize, and grow without chaos.
