Environments & credentials
| Sandbox | Production | |
|---|---|---|
| Purpose | Build + test your integration end-to-end | Live borrower data |
| Base URL | https://alpha-gig.fluxusforge.in | https://gig.fluxusforge.in |
| Accepts | Test keys only (pk_<org>_test_<hex>) | Live keys only (pk_<org>_live_<hex>) |
| Data | Test cases you push. No simulated field agents — assignment, visits and Mode A proof verification are driven by the Fieldproof team on request (sandbox testing) | Real cases, real field partners |
| Signature debugger | POST /debug/echo-signature available | Not available — 403 SANDBOX_ONLY |
| Configuration | Sandbox webhook URL / mint URL / QR / allowlist | Entered again at go-live — nothing carries over (onboarding) |
GET /health returns | env: "test" | env: "live" |
All endpoints live under /api/v1/partner on both hosts.
:::note Legacy hosts
Integrations built against https://alpha-gig.quikkred.in /
https://gig.quikkred.in keep working unchanged — both host pairs serve the
same environments with the same keys. New integrations should use the
fluxusforge.in hosts. Likewise the legacy X-Quikkred-Timestamp /
X-Quikkred-Signature request headers are still accepted as aliases of the
X-Fieldproof-* headers (if both are present, the X-Fieldproof-* value
wins), and webhooks carry both header families.
:::
The environment split is enforced by the servers, not by convention — a
test key presented to production is rejected with 401 UNAUTHORIZED, and so
is a live key on the sandbox. There is no way to accidentally point a test
integration at live data.
Health check
GET /api/v1/partner/health is a signed request like any other and returns a
flat object (no data envelope):
{ "ok": true, "lenderCode": "YOURORG", "env": "test", "serverTime": "2026-08-18T09:31:00.000Z" }
Use it to prove credentials on each host and as your own liveness probe.
Credential model
Your credential has two parts:
apiKeyId— public identifier (pk_<org>_test_<hex>/pk_<org>_live_<hex>), sent asAuthorization: Bearer <apiKeyId>. Identifies your organisation; safe to log.- Secret — an opaque string shown once at issuance and never
transmitted afterwards. It proves possession by
signing every request (HMAC-SHA256 over
METHOD\nPATH\nTIMESTAMP\nRAW_BODY, lowercase hex) and it verifies the webhooks we send you. Store it only in your secrets manager.
Sandbox and production each get their own independent pair.
:::warning Server-to-server only Production does not serve browser CORS headers. Call the API from your backend only — the secret must never reach a browser, mobile app or any other client you do not fully control. :::
Operational properties
| Property | Behaviour |
|---|---|
| Timestamp window | X-Fieldproof-Timestamp (unix milliseconds) must be within ±5 minutes of server time → otherwise 401 TIMESTAMP_SKEW. |
| Rotation | On rotation the new secret becomes active immediately: webhooks are signed with the new secret from that moment; API requests are accepted with the old or the new secret until you ask us to retire the old one. Your webhook receiver must accept multiple secrets before you request a rotation (key security). |
| Revocation | Effective within 60 seconds. |
| Brute-force lockout | 10 signature failures within 300 s lock the key for 900 s → 429 AUTH_LOCKED with a Retry-After header (remaining seconds). No alert is sent to your organisation — watch your own error logs. |
| Rate limits | 60 requests/min per API key, and POST /cases 10 batches/hour per key — dry-runs and idempotent replays count toward the 10. Exceeding either → 429 RATE_LIMITED with Retry-After (errors & rate limits). |
| IP allowlist | Optional, set at onboarding: plain IPv4 addresses or CIDR ranges. Client IP is resolved from CF-Connecting-IP / the last X-Forwarded-For hop; a request from a non-listed IP → 401 UNAUTHORIZED. |
| Egress IPs | Fieldproof does not publish static egress IPs for webhook / pull / mint calls to you. If your firewall requires them, contact [email protected]. |
| Auth before validation | Authentication runs before schema validation — an unauthenticated caller never sees 422 VALIDATION_FAILED details. |
Every response — success or error — carries an X-Request-Id header; quote it
when writing to [email protected].