FAQ
Getting started
How do we apply?
At fieldproof.fluxusforge.in/apply/
— organisation details, contacts, how you want to send cases (push / pull /
CSV), payment preference and states, verified by email OTP. You get a tracking
link (/apply/status/?token=…). After ops review your organisation code is
assigned, your integration settings are captured (webhook URL + events,
payment mode and artefacts, optional IP allowlist / pull config) and a
sandbox key is issued. Full flow: onboarding.
Can we integrate without building anything?
Yes — CSV: send a file with the documented headers
(LoanNo, CustomerName, mobile, Pincode, Due Amount, …) and Fieldproof
ops upload it for you. Webhooks or the poll API can be added later without
redoing ingestion.
We can't receive webhooks (corporate network). Are we stuck?
No — the poll API (GET /cases/updates)
returns the identical event envelopes by cursor, oldest first, and includes
all event types regardless of your webhook subscription. Many
organisations start polling and add webhooks later.
How do we test on the sandbox?
Use your test key against https://alpha-gig.fluxusforge.in. There are no
simulated field agents on the sandbox: assignment, visit and Mode A
verification events are driven by the Fieldproof team on request. Everything
else you can drive yourself — push and ?dryRun=1, POST /webhooks/test,
delivery replay, the poll feed, recall, and (Mode B) payments/confirm, which
does emit payment.collected / case.closed. POST /debug/echo-signature
(sandbox only) shows you the exact canonical string we computed when a
signature will not match. See sandbox.
Is there a reference implementation we can run? Yes — the "org-simulator" (Node) is distributed by the integration team on request; ask [email protected]. It is not a public download.
What changes at go-live?
Production is configured again from scratch — webhook URL, mint URL and
auth header, QR / bank details, IP allowlist; nothing carries over from the
sandbox. Then a live key is issued and you switch the base URL to
https://gig.fluxusforge.in. Checklist: go-live.
Sending cases
Can the same loan be sent twice?
Safely, yes. Re-sending a row for an existing active case updates it in
place (outstanding, DPD, address…), and an identical batch that was already
committed is a no-op (idempotentReplay: true). Two things to know: omitted
loan.dpd / loan.lateCharges reset to 0 on a re-push, and if the previous
case had closed (collected or closed_unrecovered) a re-push opens a
fresh case with a new caseId and sequence restarting at 1. Within one
batch, send each loan once: if the same sourceLoanNumber appears twice,
the first row is kept and every later duplicate is reported as a per-row
error (visible on a dry run) — see the
data contract.
What does fullSnapshot: true actually do?
It declares "this batch is my complete open book". Active cases absent
from it are flagged for ops review (snapshot_dropped) — they are not
closed automatically, and you only see the count in
summary.flaggedNeedsReview. It must be a single batch (a chunked
snapshot would flag everything missing from each chunk); use it daily or
weekly, never for incremental pushes. It is never applied in pull mode.
What if a borrower pays us directly while a case is active?
Call POST /cases/{loan}/recall (push API). The
case closes as closed_unrecovered with reason: "recalled", the assigned
partner is told to stop, and a case.closed event is emitted. Recall is
idempotent — a second call returns alreadyClosed: true. Your daily
fullSnapshot: true push is the safety net for recalls you missed: cases you
no longer send are surfaced to ops for review.
Our loan numbers contain /. Does that work in GET /cases/{loan}?
Yes — percent-encode the path segment (/api/v1/partner/cases/LN%2F001) and
sign the encoded path exactly as sent. See
signing requests.
Receiving updates
Our webhook sequences have gaps (1 → 4). Did we lose events?
No. sequence counts every event type on the case, including types you
are not subscribed to, so default subscribers (case.received,
payment.collected, case.closed) legitimately see gaps. Apply any event
whose sequence is greater than your watermark for that case, never wait for
a gap to fill, and reconcile with GET /cases/{loan} if you want certainty.
Never skip a payment.collected because of ordering — book it (it is
idempotent on eventId / reference) and gate only your case-state fields.
Because sequence restarts at 1 for a fresh case, key your watermark on
(sourceLoanNumber, caseId) or reset it when you see case.received.
Details: updating your LMS.
Will you alert us if our webhooks start failing or our key gets locked?
No. The platform alerts Fieldproof's internal ops, not your technical
contact. Watch your own side: GET /webhooks/deliveries?status=exhausted
(delivery log), GET /health, and your
client's 401 / 429 rates.
We missed some webhooks during an outage.
Deliveries retry over ≈31 hours (0s, 30s, 2m, 10m, 1h, 6h, 24h), then park
as exhausted and stay replayable for 30 days via
POST /webhooks/deliveries/{eventId}/replay. After 20 consecutive failures
the callback is suspended and probed every 15 minutes; it recovers
automatically and drains the backlog oldest-first. And the poll API always has
the full stream by cursor.
Can we change our webhook URL later?
Yes — ask the Fieldproof team, who set it in your organisation's
Integrations configuration (there is no self-serve API for webhook settings
yet). Sandbox and production URLs are configured separately. Fire
POST /webhooks/test afterwards to see the ping land. Events emitted
while no callback was configured are in the poll feed and can also be
replayed to the new callback on demand.
Can we receive more event types than the default three?
Yes — case.assigned and visit.completed are opt-in via the Fieldproof
team. The poll API already returns every type without any change to your
subscription.
A payment.collected amount differs from what the partner said was collected.
The event carries the operator-verified amount (Mode A — it may differ
from the partner's claim, and a rejected proof emits nothing) or the amount
you confirmed (Mode B). Trust the event. In GET /cases/{loan},
visits[].amountCollected before verification is the partner's unverified
claim.
How fresh is GET /cases/{loan}?
It reads the current case record, which is updated before the corresponding
event is written — so it reflects at least every event already emitted to you.
It prefers the active case for that loan, otherwise the most recent one, and
includes the last 20 visits.
Payments
Do you collect cash?
No. Borrowers pay on your rails only (how money flows);
the partner app removes the cash option on your cases entirely and
payments/confirm rejects mode: "cash".
What happens on a partial payment?
- Mode B (your gateway): you confirm the amount; the case stays
in_progress, detaches from the partner and re-enters the marketplace after a cool-down (default 48 h) for another attempt;payment.collectedis emitted with the incrementalamountand absolutetotalCollected/outstandingAfter. - Mode A (static QR): the partner uploads proof, ops verify it, and
payment.collectedis emitted with the verified amount. - Full clearance: in Mode B a confirmed amount of ≥99% of the
remaining outstanding (1% tolerance) completes the case —
payment.collectedthencase.closedwithstatus: "collected",reason: "full_settlement". In Mode A the same pair fires when ops verify the payment that clears the case.
We got a 409 from payments/confirm. Do we refund?
| Code | Meaning | Refund? |
|---|---|---|
DUPLICATE_CONFIRMATION | Same reference already booked (error.caseId returned) | No — treat as success |
CASE_ALREADY_COLLECTED | Case was already fully collected; this is money not owed | Yes, refund the borrower |
AMOUNT_EXCEEDS_OUTSTANDING | Amount more than 101% of what remained | Refund / adjust the excess |
CASE_CLOSED | Case was recalled or written off first | Yes, refund the borrower |
A 5xx from confirm is safe to retry — the retry resumes and completes.
Full list: errors.
Do you issue receipts to borrowers? No. The regulatory disclosure text you provide is shown on the agent's payment and ID screens, but the platform does not issue PDF receipts on your behalf — receipts remain your system's responsibility.
Security
Can you give us your egress IPs for our firewall?
We do not publish static egress IPs. Authenticate webhooks by their HMAC
signature and your mint endpoint by the Authorization value you registered.
If your policy strictly requires source IPs, contact [email protected]
before go-live. More: security.
How does key rotation affect our webhook receiver? Webhooks are signed with the new secret from the moment of rotation, while your requests are accepted with old or new until the old one is retired. Deploy verification against multiple secrets before you request a rotation. See key security.
Support
- Everything goes to [email protected] — integration questions, sandbox lifecycle events, webhook / event-subscription changes, key rotation and revocation, egress-IP requirements, and security disclosures.
- Include the
X-Request-Idheader of any failing call; it lets us trace the exact request. - There are no automatic delivery-failure or lockout alerts to your side — see "Will you alert us…" above.