Clinic bank feed
The clinic's bank movements, from e-mail, Fintoc or the bank's own API, normalized into one shape to reconcile the till.
Download the full API pública projection: openapi.json.
| Method | Path | What it does |
|---|---|---|
GET | /clinic/bank-feed/connections | Connected bank links |
POST | /clinic/bank-feed/connections/{id}/disconnect | Disconnect a bank link |
POST | /clinic/bank-feed/connections/{id}/sync | Sincronizar ahora — enqueue a pull of one bank link |
POST | /clinic/bank-feed/email/pull | Re-read bank e-mails still in the inbox for a window |
POST | /clinic/bank-feed/fintoc/connect | Connect a bank through Fintoc |
GET | /clinic/bank-feed/sources | Bank feed sources available to this clinic |
GET /clinic/bank-feed/connections
Connected bank links
Every bank link this clinic connected through an API source, enabled or not, with masked account numbers and the last sync result. Requires clinic_money:read.
Connected apps: every patient and contact in the response is a Seudónimo de paciente — initials plus a stable number, "M.F. · #1001" — unless the clinic allowed patient names, with RUT, phone and email masked in free text and meta.patient_privacy saying so. Clinical alerts (flags) are withheld in both modes, and a non-JSON body (an export, a file) is refused with 403 CONNECTED_APP_SENSITIVE_DATA.
curl https://api.vitrinadev.com/api/v1/clinic/bank-feed/connections \
-H "Authorization: Bearer $VITRINA_KEY"Example response (200)
{
"data": [
{
"id": "bf0bf0bf-0000-4000-8000-000000000001",
"provider": "fintoc",
"institution_name": "Banco de Chile",
"holder_name": "Clínica Ejemplo SpA",
"accounts": [
{
"id": "acc_9Xz2Lm",
"number_masked": "••••4821"
}
],
"enabled": true,
"connected_at": "2026-09-20T14:02:11.000Z",
"disconnected_at": null,
"last_sync_at": "2026-09-22T09:00:04.000Z",
"last_sync_status": "ok",
"last_sync_error": null,
"sync_cursor": "2026-09-22"
}
]
}Answers: 200 · 400 · 401 · 403 · 404 · 409 · 429
POST /clinic/bank-feed/connections/{id}/disconnect
Disconnect a bank link
Reversible: the connection survives disabled (its movements stay in the ledger), stops syncing and stops counting as a billed bank from the next period. Requires clinic_money:write.
Connected apps: every patient and contact in the response is a Seudónimo de paciente — initials plus a stable number, "M.F. · #1001" — unless the clinic allowed patient names, with RUT, phone and email masked in free text and meta.patient_privacy saying so. Clinical alerts (flags) are withheld in both modes, and a non-JSON body (an export, a file) is refused with 403 CONNECTED_APP_SENSITIVE_DATA.
| Parameter | In | Type | Required | Constraints |
|---|---|---|---|---|
id | path | uuid | yes |
curl -X POST https://api.vitrinadev.com/api/v1/clinic/bank-feed/connections/<id>/disconnect \
-H "Authorization: Bearer $VITRINA_KEY"Answers: 204 · 400 · 401 · 403 · 404 · 409 · 429
POST /clinic/bank-feed/connections/{id}/sync
Sincronizar ahora — enqueue a pull of one bank link
Enqueues the SAME job the daily tick uses; the stable per-connection jobId dedups with an in-flight sync. Requires clinic_money:write.
Connected apps: every patient and contact in the response is a Seudónimo de paciente — initials plus a stable number, "M.F. · #1001" — unless the clinic allowed patient names, with RUT, phone and email masked in free text and meta.patient_privacy saying so. Clinical alerts (flags) are withheld in both modes, and a non-JSON body (an export, a file) is refused with 403 CONNECTED_APP_SENSITIVE_DATA.
| Parameter | In | Type | Required | Constraints |
|---|---|---|---|---|
id | path | uuid | yes |
curl -X POST https://api.vitrinadev.com/api/v1/clinic/bank-feed/connections/<id>/sync \
-H "Authorization: Bearer $VITRINA_KEY"Example response (202)
{
"data": {
"enqueued": true
}
}Answers: 202 · 400 · 401 · 403 · 404 · 409 · 429
POST /clinic/bank-feed/email/pull
Re-read bank e-mails still in the inbox for a window
Runs the e-mail source of the bank feed over [from, to] (Santiago days, ≤ 92 days): bank comprobantes that are still conversations in a connected mailbox become bank_movement rows (provenance backfill — historical, never announced to anyone). Idempotent. Requires clinic_money:write.
Connected apps: every patient and contact in the response is a Seudónimo de paciente — initials plus a stable number, "M.F. · #1001" — unless the clinic allowed patient names, with RUT, phone and email masked in free text and meta.patient_privacy saying so. Clinical alerts (flags) are withheld in both modes, and a non-JSON body (an export, a file) is refused with 403 CONNECTED_APP_SENSITIVE_DATA.
curl -X POST https://api.vitrinadev.com/api/v1/clinic/bank-feed/email/pull \
-H "Authorization: Bearer $VITRINA_KEY" \
-H "Content-Type: application/json" \
-d '{
"from": "2026-09-01",
"to": "2026-09-22"
}'Example response (200)
{
"data": {
"drafts": 0,
"inserted": 3,
"deduped": 1,
"cross_source_twins": 1
}
}Answers: 200 · 400 · 401 · 403 · 404 · 409 · 429
POST /clinic/bank-feed/fintoc/connect
Connect a bank through Fintoc
Send the exchange_token Fintoc's widget returns (or a link_token). The server swaps it for the long-lived link token, stores it encrypted, and queues the first pull. Requires the bank_feed_fintoc add-on — without it the answer is 402 ENTITLEMENT_NOT_ACTIVE (the upsell). Reconnecting the same bank updates its connection. Requires clinic_money:write.
Connected apps: every patient and contact in the response is a Seudónimo de paciente — initials plus a stable number, "M.F. · #1001" — unless the clinic allowed patient names, with RUT, phone and email masked in free text and meta.patient_privacy saying so. Clinical alerts (flags) are withheld in both modes, and a non-JSON body (an export, a file) is refused with 403 CONNECTED_APP_SENSITIVE_DATA.
curl -X POST https://api.vitrinadev.com/api/v1/clinic/bank-feed/fintoc/connect \
-H "Authorization: Bearer $VITRINA_KEY" \
-H "Content-Type: application/json" \
-d '{
"exchange_token": "exch_7f3a9b2c1d"
}'Example response (201)
{
"data": {
"id": "bf0bf0bf-0000-4000-8000-000000000001",
"provider": "fintoc",
"institution_name": "Banco de Chile",
"holder_name": "Clínica Ejemplo SpA",
"accounts": [
{
"id": "acc_9Xz2Lm",
"number_masked": "••••4821"
}
],
"enabled": true,
"connected_at": "2026-09-20T14:02:11.000Z",
"disconnected_at": null,
"last_sync_at": "2026-09-22T09:00:04.000Z",
"last_sync_status": "ok",
"last_sync_error": null,
"sync_cursor": "2026-09-22"
}
}Answers: 201 · 400 · 401 · 403 · 404 · 409 · 429
GET /clinic/bank-feed/sources
Bank feed sources available to this clinic
The e-mail rail (free, always on), Fintoc (optional add-on bank_feed_fintoc, billed per connected bank per month at the provider's list price — price_clp_per_bank_month is null until it is set) and BCI API Market (not configured until the partner approval lands). Requires clinic_money:read.
Connected apps: every patient and contact in the response is a Seudónimo de paciente — initials plus a stable number, "M.F. · #1001" — unless the clinic allowed patient names, with RUT, phone and email masked in free text and meta.patient_privacy saying so. Clinical alerts (flags) are withheld in both modes, and a non-JSON body (an export, a file) is refused with 403 CONNECTED_APP_SENSITIVE_DATA.
curl https://api.vitrinadev.com/api/v1/clinic/bank-feed/sources \
-H "Authorization: Bearer $VITRINA_KEY"Example response (200)
{
"data": {
"email": {
"available": true,
"billed": false
},
"fintoc": {
"configured": true,
"entitled": true,
"feature": "bank_feed_fintoc",
"price_clp_per_bank_month": null,
"connected_banks": 1
},
"bci_api_market": {
"configured": false,
"reason": "BCI API Market production access is pending partner approval."
}
}
}Answers: 200 · 400 · 401 · 403 · 404 · 409 · 429
Templates and retention
The texts and the questions before anybody signs or answers them, and how many years each kind of document is kept. They name no patient, and are therefore not sensitive.
Companies
The organisations contacts belong to. They group people; the legal identity lives on the contact that represents the company.