Custodian auth flows
An auth flow is what a bank needs before it sends an entity's data: the files to upload and the consent types it takes. Aleta keeps the catalogue; you open a custodian authority on one of its flows.
Reads need custody:read. Only Aleta writes (the fleet key, with custody:write); anyone else gets 403. Every write takes ?dry_run=true (validates and answers without saving, with the header Aleta-Dry-Run: true) and an Idempotency-Key header (the same key and body answer the first result again; the same key with another body is 409), and is logged in the change list. A flow from the legacy platform is read-only while the legacy platform is master: a write answers 409 legacy_managed. A PATCH or DELETE checks its body first (400 bad_request), then answers 404 not_found, then 403 forbidden, then 409 legacy_managed. A POST checks the caller first: a caller who is not Aleta gets 403 whatever the body. Then a body that is not JSON, lacks id, custodian_id or supported_consent_types, has a value of the wrong type or a field the route does not take is 400 bad_request, before the values are checked.
The flow
idstringThe flow's slug, e.g.
nordea-20260630.custodian_idstring or nullThe bank, as in custodians;
nullwhen the tenant has no row for it.statusstringactive, oroutdatedonce retired: no new authority can be opened on an outdated flow, and the authorities opened on it keep it.expected_filesobject[]{name, description, file_type}: the files to upload, by thenamean upload names.descriptionandfile_typearenullwhen not set.supported_consent_typesstring[]alland/orspecific, each once.created_at, updated_atstringISO 8601 timestamps.
List flows
The catalogue, oldest first, one page at a time (limit, default 100, at most 1000; cursor). The catalogue keeps no history, so the answer's as_of is always today. Any other query parameter is 400.
Optional attributes
custodian_idstringA custodian id (UUID): only this bank's flows.
statusstringactiveoroutdated(any other value is400).
{
"data": [
{
"id": "nordea-20260630",
"custodian_id": "019dff7d-5a85-741e-8437-22e1d5f7c685",
"status": "active",
"expected_files": [
{ "name": "poa", "description": "Signed power of attorney", "file_type": "pdf" }
],
"supported_consent_types": ["all", "specific"],
"created_at": "2026-06-30T08:00:00.000000Z",
"updated_at": "2026-06-30T08:00:00.000000Z"
}
],
"next_cursor": null,
"limit": 100,
"as_of": "2026-10-18"
}
Get a flow
One flow by its slug, as in the list. 404 for an unknown id.
Create a flow
Aleta only. Body {id, custodian_id, expected_files?, supported_consent_types, status?}: id is 1-100 letters, digits, -, _ or .; every expected file {name, description?, file_type} needs a name (unique, trimmed) and a file_type; supported_consent_types is not empty, and a repeated value is kept once; status is active (the default) or outdated. 201 with the flow and Location: /v1/custodian-auth-flows/{id}. A failed check or any other top-level field is 400 bad_request, an unknown bank 404 not_found, an id that exists 409 conflict. An expected file takes only name, description and file_type; any other key in it is a 400.
Change a flow
Aleta only. Any of {expected_files, supported_consent_types, status}, checked as on create; a field you send replaces the stored one, and the bank and the id do not change. status: "active" brings an outdated flow back. 200 with the flow; any other field is 400. An expected file takes only name, description and file_type; any other key in it is a 400.
Retire a flow
Aleta only. Body {reason?} or none; the reason is kept in the change list. Marks the flow outdated and never deletes it: 200 with the flow. A flow already outdated answers 200 unchanged, and nothing is changed or logged. Any other field is 400. PATCH with status: "active" undoes it.