Skip to main content

Quickstart

You need your sandbox credentials (onboarding); the sandbox base URL is https://alpha-gig.quikkred.in. Three steps: verify auth → push one case → receive the webhook.

1. Verify your credentials

Every request is HMAC-signed (full spec). Minimal signed GET:

health-check.js (Node 18+)
const crypto = require("crypto");

const BASE = "https://alpha-gig.quikkred.in"; // sandbox (test keys); production: https://gig.quikkred.in
const KEY = process.env.QK_KEY_ID; // pk_yourorg_test_...
const SECRET = process.env.QK_SECRET;

async function call(method, path, bodyObj) {
const body = bodyObj ? JSON.stringify(bodyObj) : "";
const ts = Date.now().toString();
const canonical = `${method}\n${path.split("?")[0]}\n${ts}\n${body}`;
const sig = crypto.createHmac("sha256", SECRET).update(canonical).digest("hex");
const res = await fetch(BASE + path, {
method,
headers: {
authorization: `Bearer ${KEY}`,
"content-type": "application/json",
"x-quikkred-timestamp": ts,
"x-quikkred-signature": sig,
},
...(bodyObj ? { body } : {}),
});
return { status: res.status, json: await res.json() };
}

call("GET", "/api/v1/partner/health").then(console.log);
// → { status: 200, json: { ok: true, lenderCode: "YOURORG", env: "test", ... } }

A 401 SIGNATURE_INVALID? Use the signature debugger — it shows the exact canonical string the server computed so you can diff yours.

2. Push a case (dry-run first)

const batch = {
rows: [{
sourceLoanNumber: "LN-2026-0001", // your stable loan ID
borrower: {
name: "Test Borrower",
phone: "9876543210", // Indian mobile
address: { line1: "12 MG Road", city: "Bengaluru", pincode: "560001" },
},
loan: { outstandingAmount: 12500, dpd: 45, emiAmount: 2500 },
}],
};

// Validate without writing:
await call("POST", "/api/v1/partner/cases?dryRun=1", batch);
// → summary: { created: 1, errored: 0 }, errors: []

// Commit:
await call("POST", "/api/v1/partner/cases", batch);

Re-sending the identical batch is always a safe no-op, and re-sending a row for an existing loan updates it — duplicates are impossible by design (reliability).

3. Receive your first webhook

Within seconds of the commit, your registered endpoint receives a signed case.received event:

{
"eventId": "evt_9f2c81a4d0b1e6a2c3d4",
"type": "case.received",
"occurredAt": "2026-07-23T09:31:00.000Z",
"version": 1,
"lenderCode": "YOURORG",
"sourceLoanNumber": "LN-2026-0001",
"sequence": 1,
"payload": { "sourceLoanNumber": "LN-2026-0001", "caseId": "CC-2026-XXXXXXX", "status": "pending" }
}

Your receiver must verify the signature, respond 2xx fast, and dedupe on eventId — the webhooks page has the complete receiver contract and copy-paste receivers in Node and Python.

No endpoint yet? The same events are available by polling:

await call("GET", "/api/v1/partner/cases/updates?limit=50");

Where to go next