API Reference
Base URL https://api.apiclx.com. Every endpoint takes JSON and returns JSON.
Every billable call reports exactly what it charged in the charged object of its response,
and every charge is auditable on the usage ledger.
POST/v1/onboardfree
Instant self-serve provisioning. Returns an account id and an API key immediately (the
key is shown exactly once). Request upstream integrations by name; they start locked until you submit
credentials and an operator approves. If card billing is enabled and you pass amount_usd
(min 20), the response includes a Stripe checkout_url to load your first credits.
Authentication
Pass your API key as a Bearer token on every request. Keys are scoped to one account and carry that account's balance and rate card. Rotate keys anytime; old keys die instantly.
Metering & billing
Accounts are prepaid. The gateway checks your balance before execution -
if it can't cover the call you get 402 payment_required and nothing runs, nothing is charged.
The debit posts atomically at execution start; if the platform fails mid-run (our side, not a payload
problem), the charge auto-credits back and the ledger shows both entries.
| Endpoint | Rate | Charged when |
|---|---|---|
| POST /v1/arive/run | $1.40 | run accepted → job starts |
| POST /v1/uwm/run | $2.00 | run accepted → job starts |
| POST /v1/loansifter/price | $1.50 | every price execution (each payload send) |
| POST /v1/mail/lookup | $0.50 | every lookup, hit or miss |
| POST /v1/avm/value | $2.50 | per address resolved |
| POST /v1/fees/escrow | $1.00 | per quote generated |
| POST /v1/tax/lookup | $0.75 | per parcel resolved |
| GET /v1/jobs/:id · /v1/usage · /v1/balance | free | - |
Services & credentials
Endpoints split into two classes. Data services (Home Value, Escrow Fees, Property Tax, Mail Lookup) run on our infrastructure and are live the moment your account has credits. Upstream integrations (LOS, PPE/Optimal Blue, lender) run against your accounts, so they require your credentials and an operator approval before the endpoint unlocks. Credentials are encrypted at rest (AES-256-GCM) and never returned by the API.
Submit the login your automation uses for that upstream. The exact fields mirror how each
integration authenticates. On submit, the service moves to pending_approval and an operator
is alerted. Resubmit anytime to rotate.
Codes: service_not_enabled (never requested),
service_awaiting_credentials (requested, no creds yet), service_pending_approval
(creds in, awaiting operator). None of these charge, the call is refused before the meter runs.
Idempotency
Send an Idempotency-Key header (any unique string, e.g. a UUID) on billable
POSTs. Retrying with the same key within 24h returns the original response and is never charged twice.
Without the header, every send is a fresh, billed execution.
Errors
Errors are JSON with a stable machine code. Validation failures are never charged.
| HTTP | code | Meaning |
|---|---|---|
| 400 | invalid_payload | Schema validation failed, details lists each field. Not charged. |
| 401 | invalid_key | Missing, revoked, or malformed API key. |
| 402 | payment_required | Balance can't cover this call. Fund the account; nothing ran. |
| 409 | duplicate_run | An identical run is already in flight for this file (idempotency window). |
| 422 | upstream_rejected | The upstream system rejected the file (their validation). Charged, the run executed. Details included. |
| 429 | rate_limited | Per-key rate limit hit. Retry-After header included. |
| 500 | platform_error | Our fault. Auto-credited; safe to retry with the same Idempotency-Key. |
POST/v1/arive/run$1.40 / run
Creates and populates a complete LOS loan file from one payload. Asynchronous: the response
returns a job immediately; poll job status or register a
webhook for completion. Typical completion: 2 to 4 minutes.
| Symptom | Cause | Fix |
|---|---|---|
| job stuck in queued | runs are serialized per upstream; a long run is ahead of yours | poll /v1/jobs/:id; queued longer than 10 min auto-fails and auto-credits |
| 422 upstream_rejected | the LOS rejected a field (bad state code, missing SSN format) | read result.warnings and details, correct the payload, resend with a NEW Idempotency-Key |
| duplicate file created | two sends without an Idempotency-Key | always send Idempotency-Key; retries then return the original job |
POST/v1/uwm/run$2.00 / run
Full lender-side cycle: imports the loan into UWM EASE, triggers the soft-credit pull,
reads liabilities back, and returns a MISMO 3.4 export. Asynchronous. Requires borrower consent
attestation in the payload, runs without it are rejected with 400 (not charged).
| Symptom | Cause | Fix |
|---|---|---|
| 400 on submit | missing credit.consent attestation | include consent.attested_by, method, and timestamp; runs never start without it |
| job failed: upstream_maintenance | the lender portal has a recurring outage window | safe to retry with the same Idempotency-Key; the charge auto-credited |
| liabilities array empty | thin credit file or credit still processing upstream | re-run outputs ["liabilities"] after a few minutes; only the run charge applied, re-reads of a completed job are free |
GET/v1/jobs/:idfree
Status of an asynchronous run. States: queued → running → succeeded | failed.
A failed job caused by the platform is auto-credited and shows "credited": true.
POST/v1/loansifter/price$1.50 / price
A complete PPE pricing scenario, synchronous. You are charged each time you press price, i.e., every payload send is one metered execution, whether one product or forty comes back.
| Symptom | Cause | Fix |
|---|---|---|
| products: [] | no eligible products for the scenario (LTV/FICO/state caps) | check scenario.ltv in the response; loosen the scenario. The call is still charged, it executed |
| 422 upstream_rejected | purpose/state combination the PPE refuses (e.g. TX cash-out rules) | price it as rate_term or a HELOC product set instead |
| slow responses (10s+) | cold PPE session being re-established | normal on the first call of the hour; subsequent calls return in 2 to 4s |
POST/v1/mail/lookup$0.50 / lookup
Direct-mail response resolution. Your call center takes an inbound mailer call, sends the
mailer ID (and anything else the caller gives you) as JSON, the API returns the matched prospect record
as JSON. Charged per lookup, hit or miss (match is null on a miss).
| Symptom | Cause | Fix |
|---|---|---|
| match: null on a good ID | the mail piece is from a drop not yet in the index | drops load within 24h of mailing; retry the next day, or pass caller.phone for a phone-first match |
| low confidence (< 0.6) | several prospects share the ID prefix | send caller.zip or caller.name; alternates[] lists the runners-up |
| 429 rate_limited | burst of lookups from a call-center spike | respect Retry-After (seconds); the limiter refills continuously |
POST/v1/avm/value$2.50 / address
Institutional-grade automated valuation (HouseCanary-class data). Synchronous.
| Symptom | Cause | Fix |
|---|---|---|
| 422 address_not_found | the address doesn't normalize to a residential parcel | send unit numbers separately, drop suite/apt text from address, verify the zip |
| low confidence (< 0.7) | thin comparables in the area | the range object is the honest answer; treat value as a midpoint, not gospel |
POST/v1/fees/escrow$1.00 / quote
County-accurate escrow, title, and recording fees for a purchase or refinance, itemized for your Loan Estimate. Synchronous.
| Symptom | Cause | Fix |
|---|---|---|
| 400 invalid_payload: county | county name misspelled or not in the state | use the county exactly as the USPS/city lookup returns it; no 'County' suffix |
| quote seems high/low | purchase vs refinance rates differ by state program | confirm the transaction field; refinance reissue rates apply only when transaction=refinance |
POST/v1/tax/lookup$0.75 / parcel
The property's current county tax bill, the number underwriting actually uses, not an estimate. Synchronous.
| Symptom | Cause | Fix |
|---|---|---|
| 422 parcel_not_found | new construction or a recent split not yet on the county roll | retry next quarter or use /v1/avm/value's tax estimate field as a stopgap |
| annual looks stale | county publishes annually; mid-year increases lag | the year field tells you the roll year the figure is from |
GET/v1/usage?from=2026-08-01&to=2026-08-12free
Your metering ledger: one row per charge or credit, traceable to the request that caused it.
GET /v1/balance returns just the current balance.
Webhooks
Async runs POST their final state to your webhook_url, signed with your webhook
secret (HMAC-SHA256 of the raw body in the X-Apiclx-Signature header). Retries with backoff for
24h until you return 2xx.