API
REST-first. The same contract for the UI and your integrators.
Public OpenAPI 3.0, PATCH-based auto-save, optimistic concurrency with RowVersion, webhooks. The interface cifraHQ uses is the one you consume.
What makes this API different
Contract
Public OpenAPI 3.0
The same spec our frontend consumes. No private API you have to beg for.
Concurrency
RowVersion on everything
Every entity carries a <code>RowVersion</code>. 409 Conflict responses return the full current state so you can resolve.
Auto-save
PATCH on every field
No save button. The client chains the returned <code>RowVersion</code> for pipelining.
CRUD + PATCH + sub-resources for transitions
- Standard CRUD on every resource:
GET /api/invoices,POST /api/invoices,GET /api/invoices/{id}. - PATCH for partial update. Each field change is an independent PATCH. There is no "save document" — there are 40 PATCHes that chained.
- State transitions as POST sub-resources.
POST /api/invoices/{id}/post,/approve,/void. Semantically clear; never a PATCH that mutates state. - Query-string filters. Convention
?field.operator=value, e.g.?customerId.eq=12&status.in=Posted,Released. - Useful 409 responses. When RowVersion doesn't match, the response includes the full current entity. The client decides: merge, overwrite, discard.
How it works under the hood
- Debounced on text to avoid a PATCH per keystroke; numeric values and dropdowns fire on blur.
- Per-entity pipelining. Each PATCH returns the new
RowVersion; the client uses it for the next PATCH. No synchronous wait between fields. - Tolerant validation while Draft. The API accepts partial state while the document is in
Draft; onlyPOST /postapplies strict validation. - Per-session queueing. The same user editing the same entity serializes their saves — no race conditions inside one session.
- Post-commit side effects via Hangfire. Emails, PDFs, webhooks and analytics caches enqueue after commit. The main transaction never waits for them.
Business events, not CRUD events
- Typed events.
invoice.posted,payment.applied,period.closed. Not "row inserted". - Exponential-backoff retries. Hangfire queue with per-category policy (post-transaction: 3 attempts).
- HMAC-signed on every delivery for verification.
- Delivery audit visible in the admin panel. You see which webhook failed and why.
Review the spec with your team
We'll share the public OpenAPI and a sandbox to test integration flows.