Longship Junk Removal of Levittown · Levittown, PA · levittownlongshipjunk.com
This API submits a junk-removal quote request. It is the same endpoint the quote form on
this site posts to. Everything here is discoverable from
/.well-known/api-catalog
(RFC 9727), and described formally in the
OpenAPI 3.1 document.
A 200 does not mean the request was delivered.
Read the mail field in the response. "sent" means the office was
notified. "skipped" means the submission was classified as automated and
quarantined — it is stored, but nobody is notified and nobody will call back.
The usual cause is a missing or too-recent t0. See
Getting past the automation filter.
A real person calls or texts the number you send. Only submit for someone who asked you to and who has agreed to be contacted about it. Every submission stores a consent record — the exact consent wording, its version, and a timestamp — against that phone number. What is collected and who receives it is set out in the privacy policy.
| Method | Path | Purpose |
|---|---|---|
POST | /wp-json/lsj/v1/lead | Submit a quote request |
GET | /wp-json/lsj/v1/health | Service health |
None — this is a public, anonymous quote form. Do not send an Origin
header unless it is this site's own origin; a foreign Origin is rejected with
403. Server-to-server callers that send no Origin at all are accepted.
The endpoint quarantines submissions that look scripted. One field decides it:
| Field | What to send |
|---|---|
t0 | Epoch milliseconds marking when you began preparing
the request. It must be at least 3 000 ms in the past and less than
6 hours old when you submit. rendered_at is an accepted alias. |
js | "1". Kept for parity with the browser form. |
This is not a hoop to jump through — it is the honest value. If you
gathered the customer's name, number and job description in a conversation, that conversation
started well over three seconds ago. Stamp t0 when you start collecting, not when
you send.
| Field | Req. | Notes |
|---|---|---|
name | yes | 2–80 characters. A URL anywhere in it is rejected. |
phone | yes | 10–15 digits once non-digits are stripped. US numbers are normalised to E.164. |
t0 | yes | See above. Omit it and the request is quarantined. |
email | no | Optional, but an invalid address fails the request rather than being ignored. |
zip | no | 5-digit ZIP, or a town name if the ZIP is unknown. |
town | no | Town, when sent separately from zip. |
details | no | Up to 2 000 characters. The most useful field for an accurate quote — what the items are, which floor, and whether there are stairs. |
besttime | no | Preferred callback window, free text. |
discount | no | Set when the customer is a senior or a veteran — flags the standing 10% discount. |
sid | no | Idempotency key. Replaying the same value within 10 minutes returns the original response and creates no second record. Send one on every retry. |
source | no | Identify your client here so the operator can tell agent-submitted requests apart. |
photos | no | Up to 5 files, 10 MB each, 25 MB per batch. JPEG, PNG, WEBP, HEIC. Type is read from the bytes, not the filename. Requires multipart/form-data. |
curl -X POST https://levittownlongshipjunk.com/wp-json/lsj/v1/lead \
-F "name=Maria Delgado" \
-F "phone=(267) 555-0142" \
-F "zip=19055" \
-F "details=Sectional couch and a dead chest freezer, basement, one flight up." \
-F "discount=1" \
-F "source=ai-assistant" \
-F "sid=$(uuidgen)" \
-F "js=1" \
-F "t0=$(( $(date +%s) * 1000 - 8000 ))"
A delivered request:
{
"ok": true,
"photos_saved": 0,
"photos_failed": 0,
"photo_errors": [],
"mail": "sent"
}
Errors use the standard WordPress REST envelope: code, message, and
a data object carrying status.
| Status | Code | Meaning |
|---|---|---|
| 400 | lsj_invalid | Validation failed. data.fields maps each bad field to a message you can show the customer. |
| 403 | lsj_bad_origin | A cross-origin Origin header was sent. |
| 413 | lsj_too_large | The whole POST body exceeded the server limit — the photos were too big. |
| 429 | lsj_rate_limited | 5 submissions per IP per 15 minutes. |
| 500 | lsj_store_failed | Nothing was stored. Retry, or call. |
Photos never cost you the request. The text record is committed before any image data is
read, and each photo is attached individually — so a failure on photo 4 keeps
photos 1–3 and the whole record. Check photos_failed and
photo_errors; a non-empty photo_errors with mail: "sent"
is still a delivered request.
5 submissions per IP per 15 minutes, returned as 429. Site-wide, above 40
submissions an hour the endpoint degrades rather than refusing: the text is still stored and
delivered, and photos are skipped with a note in photo_errors.
Pages, posts and service-area content are readable through the standard WordPress REST API at
/wp-json/wp/v2. Its routes and
schemas are listed at /wp-json/.
Quote records are private and are not exposed there.
Call (267) 609-9327. The phone is answered 24/7 — by a person during the day, and after hours by an automated assistant that identifies itself as automated. Answering 24/7 is not the same as hauling 24/7; crews run during working hours.