Skip to main content

Webhooks

Webhooks let GOFINFI push events to your GO app or crm account the moment something happens. In Sandbox, we emit realistic demo payloads so teams get instant feedback.

Configure your endpoint

Set your HTTPS endpoint in the dashboard (per agency/install). Example:

https://{your-crm-subdomain}.yourcrm.com/api/webhooks/gofinfi

You can rotate secrets and change the destination anytime.

Delivery & security

All webhook requests include:

  • X-Gofinfi-Event: event type (e.g., softpull.completed)
  • X-Gofinfi-Id: event id (e.g., evt_sp_9xZQ1)
  • X-Gofinfi-Timestamp: UNIX seconds
  • X-Gofinfi-Signature: sha256= HMAC of "{timestamp}.{raw_body}" using your webhook secret

Retries: up to 3 attempts with exponential backoff (2^n seconds, capped at 30s) on non-2xx responses. Idempotency: use X-Gofinfi-Id to de-dupe repeated deliveries.

Verify signatures

Node.js

import crypto from "crypto";

export function verifyGofinfiSignature(rawBody, headers, secret) {
const ts = headers["x-gofinfi-timestamp"];
const sig = String(headers["x-gofinfi-signature"] || "");
const payload = `${ts}.${rawBody}`;
const hmac = crypto.createHmac("sha256", secret).update(payload).digest("hex");
if (!sig.startsWith("sha256=")) return false;
const provided = sig.replace("sha256=", "");
return crypto.timingSafeEqual(Buffer.from(hmac, "hex"), Buffer.from(provided, "hex"));
}

Python

import hmac, hashlib

def verify_gofinfi_signature(raw_body: bytes, headers: dict, secret: str) -> bool:
ts = headers.get("x-gofinfi-timestamp", "")
sig = headers.get("x-gofinfi-signature", "")
if not sig.startswith("sha256="):
return False
base = f"{ts}.{raw_body.decode('utf-8')}".encode("utf-8")
digest = hmac.new(secret.encode("utf-8"), base, hashlib.sha256).hexdigest()
provided = sig.replace("sha256=", "")
return hmac.compare_digest(digest, provided)

Event types (Sandbox default)

  • softpull.completed — A soft pull finished; includes summary data and tracking fields.
  • webhook.delivery.attempted / .succeeded / .failed — Delivery lifecycle diagnostics (optional to subscribe).

softpull.completed schema (abridged)

Headers

X-Gofinfi-Event: softpull.completed
X-Gofinfi-Id: evt_sp_9xZQ1
X-Gofinfi-Timestamp: 1730132712
X-Gofinfi-Signature: sha256=...

Body

{
"type": "softpull.completed",
"id": "evt_sp_9xZQ1",
"created": "2025-10-28T19:05:12Z",
"agency_id": "ag_7Qm2JrB",
"sandbox": true,
"request_id": "sp_7Aq3xV9m",
"bureau": "Experian",
"score_detail": { "model": "VantageScore 3.0", "value": 682 },
"summary": {
"inquiries": 2,
"accounts": 11,
"open_accounts": 7,
"closed_accounts": 4,
"utilization": 34,
"credit_limit": 13900,
"balance": 281451,
"risk_level": "Moderate"
},
"tracking_id": "demo-001"
}

PII note: In Sandbox, PII is redacted by design. In Production, you are responsible for consent capture, storage minimization, and honoring regulatory requirements.

Responding to webhooks

Return 2xx within 10s. If your handler needs extra processing time, enqueue internally and ack immediately.

Example 200 response

HTTP/1.1 200 OK
Content-Type: application/json

{"received": true}

Testing

  • Use the dashboard to send test events.
  • In your GO, app or CRM, add a workflow that logs inbound payloads so your team sees instant results.
  • Rotate secrets and re-test before going live.