ClearStaq
Log inStart Free Trial

50 documents free. No credit card required.

API Reference

Bank statement analysis over HTTPS

Submit a PDF, receive structured revenue, fraud, and debt analysis via signed webhook. Generate credentials at app.clearstaq.com.

New to the API? Start with the conceptual guide: API & Webhooks overview.

Overview

Submit a bank-statement PDF to https://app.clearstaq.com/api/v1/analyses. The endpoint returns 202 Accepted with an analysis id; the full analysis result is delivered asynchronously to your callback_url as a signed webhook.

API access is available on StaqCore and above. Free-tier orgs cannot generate API keys.

Authentication

Every request must include a bearer token issued from your Integrations settings page. Keep both the cg_live_* key and the whsec_* webhook secret out of version control.

Authorization: Bearer cg_live_YOUR_KEY_HERE

Submit a statement

Multipart upload. Maximum size 25 MB. Only application/pdf is accepted.

ClearStaqAI Fraud Detection (Gemini visual second-pass) is opt-in. Pass clearstaq_ai_enabled=true on a submission to enable it for that request. Defaults to off; the deterministic metadata fraud score always runs.

cURL
Node.js
Python
curl -X POST https://app.clearstaq.com/api/v1/analyses \
  -H "Authorization: Bearer cg_live_YOUR_KEY_HERE" \
  -F "file=@./statement.pdf" \
  -F "callback_url=https://your-app.example.com/hooks/clearstaq" \
  -F "client_ref=customer-123" \
  -F 'metadata={"loan_id":"LN-999"}' \
  # Opt in to the ClearStaqAI visual fraud second-pass (default off):
  # -F "clearstaq_ai_enabled=true"

Receive the result

When the analysis completes, ClearStaq POSTs a signed JSON envelope to your callback_url. Respond with any 2xx status within 10s to acknowledge. Non-2xx responses are retried up to 5 times with exponential backoff (1m, 5m, 30m, 2h, 12h).

POST /hooks/clearstaq HTTP/1.1
Content-Type: application/json
X-ClearStaq-Event: analysis.completed
X-ClearStaq-Delivery: 2f8b0...
X-ClearStaq-Signature: sha256=<hex hmac>

{
  "id": "cb_...",
  "event": "analysis.completed",
  "client_ref": "customer-123",
  "status": "completed",
  "result": { "bank_name": "Chase", "true_revenue": 84250.12, ... }
}

Verify the signature

Compute HMAC-SHA256 over the raw request body using your webhook signing secret and compare (timing-safe) to the X-ClearStaq-Signature header.

Node.js
import crypto from "node:crypto"

// In your webhook handler:
export default function handler(req, res) {
  const signature = req.headers["x-clearstaq-signature"]
  const raw = req.rawBody // the exact JSON bytes ClearStaq sent
  const expected =
    "sha256=" + crypto.createHmac("sha256", process.env.CLEARSTAQ_WEBHOOK_SECRET).update(raw).digest("hex")
  const ok = crypto.timingSafeEqual(Buffer.from(expected), Buffer.from(signature ?? ""))
  if (!ok) return res.status(400).send("bad signature")
  // req.body is the WebhookEnvelope — act on it, then respond 2xx.
  res.status(200).send("ok")
}

Client profiles (multiple statements)

To analyze a client across several statements at once, POST 1–25 PDFs to https://app.clearstaq.com/api/v1/clients. This creates a ClearStaq client in your org (visible in your webapp), parses every statement, and computes an aggregated profile over the valid statements. Incomplete or non-bank statements are excluded from the profile and listed with a failure reason. Billing is per document (same credits as a single analysis), scaled by file count.

Repeat the file field for each PDF (or use files). Max 25 MB per file. client_name is optional — when omitted, the client is named from the dominant account holder once parsed. clearstaq_ai_enabled is opt-in, same as a single submission.

cURL
Node.js
curl -X POST https://app.clearstaq.com/api/v1/clients \
  -H "Authorization: Bearer cg_live_YOUR_KEY_HERE" \
  -F "file=@./statement-jan.pdf" \
  -F "file=@./statement-feb.pdf" \
  -F "client_name=Acme LLC" \
  # Optional: opt in to the ClearStaqAI visual fraud second-pass (default off):
  # -F "clearstaq_ai_enabled=true"

The endpoint returns 202 Accepted with a client_id, a batch_id, and per-document queue state.

{
  "client_id": "8f1c...",
  "batch_id": "2a4d...",
  "documents": [
    { "id": "d1...", "filename": "statement-jan.pdf", "status": "queued" },
    { "id": "d2...", "filename": "statement-feb.pdf", "status": "queued" }
  ]
}

Poll a client profile

Fetch https://app.clearstaq.com/api/v1/clients/{id} to read the aggregated profile and per-document statuses. Poll until counts.completed + counts.failed === counts.total and profile is non-null — the profile is computed asynchronously shortly after the documents finish parsing.

cURL
curl https://app.clearstaq.com/api/v1/clients/<client_id> \
  -H "Authorization: Bearer cg_live_YOUR_KEY_HERE"

# Poll until counts.completed + counts.failed === counts.total
# AND profile is non-null (the profile is computed asynchronously
# shortly after the documents finish parsing).
{
  "id": "8f1c...",
  "name": "Acme LLC",
  "status": "completed",
  "profile": { "true_revenue": 168500.24, "fraud_score": 12, ... },
  "documents": [
    {
      "id": "d1...",
      "filename": "statement-jan.pdf",
      "status": "completed",
      "bank_name": "Chase",
      "period_start": "2025-01-01",
      "period_end": "2025-01-31",
      "fraud_score": 8,
      "failure_reason": null,
      "pages_present": 6,
      "pages_expected": 6,
      "detected_bank": "Chase"
    },
    {
      "id": "d2...",
      "filename": "statement-feb.pdf",
      "status": "failed",
      "failure_reason": "missing_pages",
      "pages_present": 3,
      "pages_expected": 6
    }
  ],
  "counts": { "total": 2, "completed": 1, "failed": 1 }
}

failure_reason values include missing_pages, not_a_bank_statement:<type>, or another reason string; null when the document parsed successfully.

Prefer webhooks? Subscribe to the batch.completed event (via POST /api/v1/webhooks) and ClearStaq POSTs the computed profile to your endpoint once per submission — same HMAC X-ClearStaq-Signature scheme and 5-step retry backoff as analysis.completed. The payload is { event, batch_id, client_id, org_id, counts, profile, created_at }.

Error codes

HTTPCodeMeaning
401unauthorizedMissing or unrecognised API key.
402plan_excludedOrg is on the Free plan.
402insufficient_creditsNo credits remaining and auto top-up is off.
413file_too_largePDF exceeds 25 MB.
415unsupported_media_typeNon-PDF upload.
422invalid_callback_urlcallback_url is invalid.
502parser_unavailableAnalysis service could not accept the job.

OpenAPI spec

Download the machine-readable spec to generate SDKs or import into Postman/Insomnia. openapi.yaml

Start free — no credit card required

Take back your time and automate loan underwriting

Join 500+ lending teams using ClearStaq to parse statements, catch fraud, and verify income — all in under 5 seconds.

No credit card required. 50 free parses/month. Upgrade anytime.