Waafir
Cookbook

Cookbook

This cookbook is for fintech engineers wiring up their loan portfolio to Waafir's monitoring API. Each recipe walks one task end to end with all three reference clients — cURL, TypeScript, Python — so a reader does not have to translate between languages mentally. The recipes lean toward the failure-and-edge-case paths a real integration hits, not just the happy path.

Who this is for

You have been issued a personal access token (PAT) by your Waafir organization administrator, and you are writing the code that submits your daily loan-tape data — borrowers, loans, scheduled repayments, actual payments, collateral, and collateral valuations — into Waafir. Your data lands in Waafir's bronze archive on submission and is normalised into the silver entity tables by the import worker; from there the daily aggregator powers the investor monitoring tab on any data room linked to the portfolio.

How to use these recipes

Every recipe has the same shape: a short prose lead, three fenced code blocks in fixed order, and a brief verification paragraph. The code blocks are:

  1. cURL — copy-paste against your shell. The least opinionated; useful for one-off probes and CI checks.
  2. TypeScriptfetch-based against the public JSON contracts. No SDK install required; the same shapes a future Waafir TypeScript SDK will wrap.
  3. Pythonrequests-based against the same JSON contracts. The standard library is enough; no Waafir-specific package is required.

Each recipe also cites the friction-scenario identifier it anchors. The full catalog of scenarios lives in docs/implementation/friction-scenarios.md inside the platform repository; the cookbook is the integrator-facing companion to that catalog.

Authentication

All endpoints require a PAT in the Authorization header:

Authorization: Bearer <YOUR_PAT>

A PAT is scoped to a single Waafir organization and carries that organization's identity on every request. Treat it as a secret; rotate it via the dashboard when it leaks. The API base URL throughout these recipes is https://app.waafir.io — replace it with your staging URL if you are integrating against the sandbox tenant first.

Conventions used in the recipes

  • All shell variables in cURL examples are written as ${UPPER_CASE_NAME} so you can export them once and re-use them across recipes.
  • TypeScript and Python examples assume BASE_URL and PAT are read from the environment. Adapt to your configuration loader.
  • The Idempotency-Key header is the platform-wide convention for safe retries; see the retry recipe for the precise semantics.
  • All write endpoints accept your own external_id values — caller-supplied identifiers stay the canonical handle through ingestion, reconciliation, and tape downloads. You never need to learn Waafir's internal UUIDs.

What the cookbook does not cover

The cookbook is task-oriented. For exhaustive endpoint definitions, request and response schemas, and error code references, see the API reference section once it ships alongside the cookbook. For product concepts — what a portfolio is, how it relates to a data room, why the medallion model matters — see Data rooms and the foundational-concepts section.

The recipes

  1. Bulk import a loan tape via async NDJSON — the foundational ingestion flow: presigned upload, commit, poll for completion.
  2. Validate a load with dry-run before committing data — same flow with ?dryRun=true; learn what your file contains before any silver rows are written.
  3. Retry safely with an idempotency key — survive transient network failures without creating duplicate imports.
  4. Inspect partial-failure errors after an import — page through per-row errors when an import lands as partial.
  5. Cancel an in-flight import — stop a long-running import at the next batch boundary without partially-written rows.
  6. Reconcile your data by external ID — confirm a row landed, by your own identifier, and verify daily counts.