Your overdue book, worked on the ground. Your money never touches us.
Push delinquent loans over a signed API. Verified field partners visit the borrower, collect on your own payment rails, and every outcome streams back to your LMS as a sequenced webhook. We hold the record, never the rupees.
We never hold, route, or touch your borrowers' money.
Collections land straight in your account — via your own static QR and bank details, or a payment link minted by your gateway. There is no pass-through account, no nodal account, and no float sitting with us.
Because of that, cash is not accepted on your cases. The partner app removes the option entirely and the API rejects it. A payment.collected event is only ever emitted for money verifiably booked in your account — proof-verified by our ops, or confirmed by you. We never announce money before it exists.
Five events, one sequence, no ambiguity.
Your system sees a deliberately simple four-state model. Internal operational sub-states are mapped underneath, so we can evolve them without ever breaking you.
Validated and accepted. Push with ?dryRun=1 first for row-level validation that commits nothing.
Assignment is ours to manage. You are told when it happens, not asked to arrange it.
Outcomes include ptp with a committed date, refused, not_available, and wrong_address or shifted — your cue to push a corrected address. Just re-send the row.
Payloads carry absolute values, never deltas — a missed intermediate event can never corrupt your books. Partial payments keep the case open.
Includes a recall you initiate. The exit is tested before you go live, so you know it works before you need it.
Three ways in. One needs no engineering at all.
Set per organisation at onboarding, changeable later. Most teams see their first case.received webhook within an hour of receiving sandbox credentials.
Push APIrecommended
You POST batches of overdue loans to our API. Real-time, content-hash deduped, with an optional Idempotency-Key.
1–2 engineer-days
Pull API
We fetch from a read endpoint you expose, every 30 minutes. Built for systems that cannot make outbound calls.
~1 engineer-day
CSV
Send a file and our ops import it, with batch history and rollback. The way to start before any engineering is scheduled.
Live immediately
Sign the request
Every call carries an HMAC-SHA256 signature over the canonical request. Keys are environment-locked — a test key is rejected on production, and vice versa.
// canonical string -> HMAC-SHA256 -> header
const canonical = [method, path, timestamp, bodyHash].join('\n');
const sig = crypto
.createHmac('sha256', process.env.FP_SECRET)
.update(canonical)
.digest('hex');
await fetch('https://gig.quikkred.in/api/v1/partner/cases', {
method: 'POST',
headers: {
'X-FP-Key': process.env.FP_KEY,
'X-FP-Timestamp': timestamp,
'X-FP-Signature': sig,
'Idempotency-Key': batchId,
},
body: JSON.stringify({ fullSnapshot: false, cases }),
});Receive the event
Identical envelope on the webhook and the poll API. Dedupe on eventId; apply only if sequence beats the last you applied for that loan; on a gap, fetch the authoritative snapshot.
{
"eventId": "evt_01a2b3c4d5e6f7a8b9c0",
"type": "payment.collected",
"occurredAt": "2026-07-23T09:31:00.000Z",
"version": 1,
"lenderCode": "YOURORG",
"sourceLoanNumber": "LN-2026-0001",
"sequence": 3,
"payload": {
"amount": 3000,
"mode": "upi",
"reference": "UTR2026072312345",
"totalCollected": 3000,
"outstandingAfter": 9500
}
}Two rails. Both end in your account.
| Mode A — your static QR / bank | Mode B — your gateway's links | |
|---|---|---|
| Money lands in | Your bank, directly | Your gateway, directly |
| Borrower pays via | Your fixed UPI QR or bank transfer, shown in the partner app | A link minted by your gateway, delivered over WhatsApp and email |
| Confirmation | Partner uploads proof, our ops verify with OCR and duplicate-UTR checks, then webhook | You call payments/confirm on capture, then instant webhook |
| You build | Nothing | A mint-link endpoint and one confirm call |
| Confirmation latency | Ops verification, typically same day | Instant |
| Best for | Fastest start, no gateway required | Fully automatic confirmation |
| Cash | Never accepted | Never accepted |
Nothing lost. Nothing applied twice. Order always recoverable.
Every business event is written to a durable event store in the same database transaction as the case change. An update cannot exist without its event.
Webhook retry ladder
A second independent path
If your endpoint is down for a week, nothing is lost. The poll API serves the identical events from the same store, and parked events stay self-serve replayable for 30 days.
Replays are normal, not errors
Delivery is at-least-once, so you dedupe on eventId. Batch pushes dedupe on content hash; a duplicate payment confirm returns 409 DUPLICATE_CONFIRMATION with the original booking attached.
Out-of-order is handled
Under concurrent delivery a case.closed can genuinely arrive before the payment.collected that caused it. Absolute totals mean a sequence-aware receiver needs no special case.
Sandbox to production, with a checklist you walk together.
Production credentials are issued only when every box is ticked — jointly, with your integration contact.
A short wizard — entity details, CIN or LLPIN, RBI licence, business and technical contacts, expected volume and operating states. Email verified, no login needed, and you get a tracking link.
Our ops team reviews and approves, which creates your organisation and its immutable lender code.
Integration mode, webhook URL and event subscriptions, payment mode and branding are configured. Test keys issued — the secret is shown exactly once. A runnable reference implementation, mock LMS and dashboard included, is yours to clone.
Push a real batch with ?dryRun=1 until zero row errors. We send a deliberate replay to prove your eventId dedupe, and test a sequence gap. Recall tested.
Legal signs off the disclosure wording on a sample receipt. Live keys issued on production. First push is a small batch with ops on standby both sides, then your full book with fullSnapshot: true.
The ones your risk team will ask.
Who is the lender of record?
You are, throughout. Fieldproof is a service provider running the field operation on your behalf. Your lender-of-record disclosure is printed on every borrower receipt in wording your legal team approves at onboarding, and borrower-facing screens are re-skinned with your logo and brand colour.
Can a field partner take cash?
No. This is enforced in two places, not just policy: the partner app removes the option entirely, and the API rejects cash as a payment mode. Every collection runs on your own rail, which is what lets us guarantee that a payment.collected event always corresponds to money already booked in your account.
What happens if we want a case back?
Recall it through the API at any point. The case moves to closed_unrecovered and stops being worked. Recall is one of the items we test together before you go live, precisely so you know the exit works before you need it.
What if our webhook endpoint goes down?
Nothing is lost. Delivery retries on a ladder out to 24 hours, then parks the event as self-serve replayable for 30 days. The poll API is a completely independent second path to the same event store, so you can also just catch up by reading.
Can another lender on the platform see our data?
Isolation is enforced at the query layer rather than by convention, and covered by an automated cross-tenant test matrix. A probe with another organisation's key returns 404 — it does not even reveal that the record exists.
We cannot make outbound API calls from our LMS. Is that fatal?
No. Use pull mode: expose one read endpoint and we fetch from you every 30 minutes. If even that is blocked, start on CSV with zero engineering and migrate later — the integration mode is a per-organisation setting you can change.
Send us one overdue case. See it close.
Apply in about ten minutes, no login required. Sandbox credentials, a runnable reference implementation, and a named integration contact.