Skip to main content

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 (Loan No, Customer Name, Mobile, Address, City, State, Pincode, Latitude, Longitude, Due Amount, …) and Fieldproof ops upload it for you. Webhooks or the poll API can be added later without redoing ingestion, and your team can follow cases in the organisation dashboard from day one.

Who can log in to the organisation dashboard? Any organisation connected to Fieldproof — push, pull or CSV. Ask your integration contact for access: Fieldproof grants your first user (normally an Owner) and shares the URL, and Owners add colleagues as Owner, Member (view, edit case data, assign partners) or Viewer (read-only). Sign-in is your work email plus a 6-digit code we email you — there are no passwords. Each user sees only your organisation's cases and payments. See organisation dashboard.

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​

Why are the borrower's coordinates mandatory? Field collection is location-driven. We use the coordinates to offer the case to the nearest partners, for the check-in geofence at the door, and for distance-based partner pay. A pin worked out from a pincode can be kilometres from the house, which sends a partner to the wrong place. So every row — push, pull, CSV or a dashboard edit — needs borrower.address.line1, city, state, pincode and the real latitude / longitude of that address (decimal degrees, at least 4 decimal places, 6 recommended; send them as strings so trailing zeros survive). Your coordinates become the case pin and are never overwritten by our geocoding; the one exception is a pin a partner verified on site, which is kept on later re-pushes unless the address itself changes. One coordinate pair used for rows in different pincodes within the same batch or file is rejected (every row sharing it) as a default or office location. Every rule and error message: data contract.

We don't have coordinates for every borrower yet. What can we do? Ask [email protected] about a coordinate grace period. Fieldproof sets it per organisation, optionally with an end date. During grace, rows with both coordinates missing — empty, or a placeholder such as NA, N/A, null or - — (and/or a missing line1, city or state) still import — we place the case from the pincode / street address as before — and come back in warnings[] (summary.warned counts the rows with warnings). Until our geocoding has located the street address, such a case is "Approximate" and is not offered to partners. Half a pair or a malformed value is always an error, even in grace, and grace ends automatically at its end date. Without a grace period (the default) a row without coordinates is a per-row error. Run ?dryRun=1 on your full export to see where you stand.

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) — unless a loan in it has no live case (collected, closed or recalled, or its row was rejected and it never got one), or your coordinate grace period has started or ended since: then the batch is processed normally (and a loan without a live case gets a fresh case). 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. A loan whose row was rejected for a data error still counts as present; only loans missing from the batch are flagged. 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. Delivery-log rows are kept for 30 days, but POST /webhooks/deliveries/{eventId}/replay rebuilds the delivery from the event store, so any event from the last ≈13 months can be replayed (with an active callback). 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), the amount you confirmed (Mode B), or the amount the Fieldproof collection team recorded on the case (mode: "other" when the recorded mode is outside the documented list, for example IMPS). 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.collected is emitted with the incremental amount and absolute totalCollected / outstandingAfter.
  • Mode A (static QR): the partner uploads proof, ops verify it, and payment.collected is 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.collected then case.closed with status: "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?

CodeMeaningRefund?
DUPLICATE_CONFIRMATIONSame reference already booked (error.caseId returned)No — treat as success
CASE_ALREADY_COLLECTEDCase was already fully collected; this is money not owedYes, refund the borrower
AMOUNT_EXCEEDS_OUTSTANDINGAmount more than 101% of what remainedRefund / adjust the excess
CASE_CLOSEDCase was recalled or written off firstYes, 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-Id header 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.