Skip to content
Faldaro
All guides

API reference

A versioned HTTP API for the two things another system usually wants: evaluate a payload against a form's rules without storing anything, and file a submission. Authenticated by an API key, bounded by exactly the privileges that key was granted.

Base URL and authentication

Every request carries an API key as a bearer token. A session token from the app works identically — the server builds the same caller either way — but a key is what you want for a machine: it is created for one system, granted one explicit set of privileges, and revoked without disturbing anyone's login.

https://faldaro.app/api/platform/v1/…
Authorization: Bearer ffk_your_token_here
Content-Type: application/json

The versioned promise

Everything under /v1 is a frozen contract. Fields are added to responses, never renamed or removed; a change that would break your integration arrives as /v2 instead. The shapes are deliberately narrower than what the app itself uses, so nothing you depend on moves when the interface does.

The service generates a machine-readable OpenAPI description of this surface at /v3/api-docs. A self-hosted deployment can reach it directly on the service; it is deliberately not published through the hosted application origin, so on Faldaro-hosted plans this page is the reference.

Evaluate a payload

Runs the form's live rules over the values you send — computed fields, hidden fields, outcomes and validation problems — and stores nothing. This is the rating call: price a quote, score an intake, or check a payload before filing it.

POST /api/platform/v1/forms/{formId}/evaluate

{"data": {"units": 4}}
{
  "valid": false,
  "calculatedData": {"total": 100},
  "hiddenFields": [],
  "outcomes": [],
  "problems": [{"field": "applicant", "message": "Applicant is required"}]
}
FieldMeaning
valid Whether this payload as a whole would be accepted as a complete submission. A missing required value counts — unlike the in-app preview, which is lenient because a form is still being filled in.
calculatedDataEvery computed field, keyed by slug.
hiddenFieldsSlugs the rules hid for this payload.
outcomesNamed flags the rules raised — id, message, severity.
problemsValidation failures — field and message.

Requires submission:write. Evaluation always runs against the live version.

File a submission

Creates a real submission through the same path the app uses: the engine re-runs server-side, a reference number allocates exactly once, and every configured effect — notifications, documents, integrations, delivery — fires as authored.

POST /api/platform/v1/forms/{formId}/submissions

{"data": {"applicant": "Ada Lovelace", "units": 4}}

Answers 201 with the stored submission: id, formId, formVersionId, workflowState, data, calculatedData, hiddenFields and outcomes. Send "draft": true alongside data to save a partial record that required-field validation does not yet bind.

Requires submission:write.

Rate limits

Every caller has a request budget — 120 a minute by default, and deployments may tune it. Going over answers 429 with a Retry-After header and a stable code:

{"error": "Rate limit exceeded. Retry after 34 seconds.", "code": "RATE_LIMITED"}

The budget is counted per key, not per address, so one integration exhausting its window never slows another — and machine traffic sharing one IP is not punished for it. Honour Retry-After and continue.

Errors

StatusMeans
401Missing, malformed, expired or revoked credential.
403The key authenticated but lacks the privilege this call needs.
404No such form — including a form that exists but is not yours, and one never published.
422The request was understood and refused; the body says why.
429Over the request budget; wait Retry-After seconds.

A form belonging to another organisation is reported as missing rather than forbidden — whether it exists is not something an unauthorised caller gets to learn.

Beyond /v1

The app's own API — folders, forms, reports, admin — is reachable with the same key and the same privilege rules, and is what the API keys guide shows with curl. It is deliberately not versioned: it changes when the interface changes. Build integrations you intend to keep on /v1, and tell us what belongs there next.

If the caller is a model rather than a script, the MCP server wraps this surface as tools — same key, same privileges, with the schemas and annotations an MCP client expects.