@vitrina/api 13.1.0 → 13.3.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/dist/index.d.cts CHANGED
@@ -2058,6 +2058,10 @@ interface paths {
2058
2058
  treatment_price?: "unset" | "first_ask" | "never";
2059
2059
  /** @description «Ofrecer lista de espera si la primera hora está a más de 7 días» (#3314). Default false. */
2060
2060
  far_slot_waitlist?: boolean;
2061
+ /** @description «Dolor: ofrecer las primeras horas de hoy o mañana» (D72). A patient in pain is offered today's / tomorrow's first slots in the same turn; a handoff becomes a heads-up to reception, not the answer. Default false; true for the agent a new clinic's onboarding creates. */
2062
+ urgency_slots?: boolean;
2063
+ /** @description «Especialista a más de 7 días: ofrecer también una evaluación general esta semana» (D74). `find_slots` then also reports the clinic's general evaluation slots of the next 7 days. Default false. */
2064
+ specialist_fallback?: boolean;
2061
2065
  };
2062
2066
  /** @description The `draft_version` version you last read (the `X-Config-Version` response header, or the version field in the body). If it is no longer current the write is refused with 409 `VERSION_CONFLICT` and nothing is written; the error carries the current version and a diff hint. Optional for backward compatibility (an omitted value is accepted and logged), but send it: without it two editors silently overwrite each other. The `If-Match` header is accepted as an alternative. */
2063
2067
  expected_version?: number | null;
@@ -2241,7 +2245,7 @@ interface paths {
2241
2245
  };
2242
2246
  /**
2243
2247
  * Read the agent’s behaviour policies
2244
- * @description Per-agent switches that change what the agent says (#3312/#3314): `treatment_price` (`unset` | `first_ask` | `never`, healthcare) and `far_slot_waitlist`. `live` is what runs today, `draft` what is staged (null = nothing staged). Every default is the agent’s behaviour before policies existed: nothing is added to its prompt while a policy is unset. `price_policy_conflicts` lists lines of the agent’s own instructions (draft when staged) and active skills that already state a price rule, so a client can reconcile them before publishing. Change them with `PUT /ai-agents/{id}/draft` (`behavior_policies`) and `POST /ai-agents/{id}/publish`.
2248
+ * @description Per-agent switches that change what the agent says (#3312/#3314): `treatment_price` (`unset` | `first_ask` | `never`, healthcare) and `far_slot_waitlist`, `urgency_slots` (D72) and `specialist_fallback` (D74). `live` is what runs today, `draft` what is staged (null = nothing staged). Every default is the agent’s behaviour before policies existed: nothing is added to its prompt while a policy is unset. `price_policy_conflicts` lists lines of the agent’s own instructions (draft when staged) and active skills that already state a price rule, so a client can reconcile them before publishing. Change them with `PUT /ai-agents/{id}/draft` (`behavior_policies`) and `POST /ai-agents/{id}/publish`.
2245
2249
  */
2246
2250
  get: {
2247
2251
  parameters: {
@@ -2265,11 +2269,15 @@ interface paths {
2265
2269
  * "data": {
2266
2270
  * "live": {
2267
2271
  * "treatment_price": "unset",
2268
- * "far_slot_waitlist": false
2272
+ * "far_slot_waitlist": false,
2273
+ * "urgency_slots": false,
2274
+ * "specialist_fallback": false
2269
2275
  * },
2270
2276
  * "draft": {
2271
2277
  * "treatment_price": "first_ask",
2272
- * "far_slot_waitlist": false
2278
+ * "far_slot_waitlist": false,
2279
+ * "urgency_slots": true,
2280
+ * "specialist_fallback": false
2273
2281
  * },
2274
2282
  * "price_policy_conflicts": [
2275
2283
  * {
@@ -2291,6 +2299,10 @@ interface paths {
2291
2299
  treatment_price: "unset" | "first_ask" | "never";
2292
2300
  /** @description «Ofrecer lista de espera si la primera hora está a más de 7 días» (#3314). Default false. */
2293
2301
  far_slot_waitlist: boolean;
2302
+ /** @description «Dolor: ofrecer las primeras horas de hoy o mañana» (D72). A patient in pain is offered today's / tomorrow's first slots in the same turn; a handoff becomes a heads-up to reception, not the answer. Default false; true for the agent a new clinic's onboarding creates. */
2303
+ urgency_slots: boolean;
2304
+ /** @description «Especialista a más de 7 días: ofrecer también una evaluación general esta semana» (D74). `find_slots` then also reports the clinic's general evaluation slots of the next 7 days. Default false. */
2305
+ specialist_fallback: boolean;
2294
2306
  };
2295
2307
  draft: {
2296
2308
  /**
@@ -2300,6 +2312,10 @@ interface paths {
2300
2312
  treatment_price: "unset" | "first_ask" | "never";
2301
2313
  /** @description «Ofrecer lista de espera si la primera hora está a más de 7 días» (#3314). Default false. */
2302
2314
  far_slot_waitlist: boolean;
2315
+ /** @description «Dolor: ofrecer las primeras horas de hoy o mañana» (D72). A patient in pain is offered today's / tomorrow's first slots in the same turn; a handoff becomes a heads-up to reception, not the answer. Default false; true for the agent a new clinic's onboarding creates. */
2316
+ urgency_slots: boolean;
2317
+ /** @description «Especialista a más de 7 días: ofrecer también una evaluación general esta semana» (D74). `find_slots` then also reports the clinic's general evaluation slots of the next 7 days. Default false. */
2318
+ specialist_fallback: boolean;
2303
2319
  } | null;
2304
2320
  price_policy_conflicts: {
2305
2321
  /** @enum {string} */
@@ -86911,7 +86927,7 @@ interface paths {
86911
86927
  };
86912
86928
  /**
86913
86929
  * Agenda for a window, any engine, by professional and branch
86914
- * @description Mirrored AND native appointments between `from` (inclusive) and `to` (EXCLUSIVE), bare `YYYY-MM-DD` days in the clinic's timezone; the window may not exceed 8 days. Cancelled citas are INCLUDED (the grid draws them muted). Unlike `GET /clinic/agenda`, `professional_id` and `location_id` are VITRINA uuids — `clinic_professional.id` and `location.id` — so one query serves a Medilink, a Reservo and a native clinic. Each row still carries the vendor's own ids under `vendor` for provenance: a row with `vendor.professional_id` set and `professional: null` is a roster gap, never a cita nobody is attending. Never calls the clinic API. `flags` are the clinical alerts the clinic shows on the block: clinical-record content, returned to an API key or personal token only when it also holds `clinic_record:read`. `booking_kind` is the cita's Tipo de agendamiento: `new` (Nuevo: it would be a primera visita and the patient never booked before), `new_rebooked` (Nuevo · reagenda: a primera visita, but the patient had earlier bookings and never came) or `in_treatment` (En tratamiento: every other cita); null on a row that is not a patient's cita. It uses the primera-visita rule Vitrina Ads counts, so a patient back after 12 months without an attended cita is `new`. `origin` is the patient's Origen (`kind` `meta` with the ad, ad set and campaign names, or `organic`) — the attribution Vitrina Ads reports, one definition; null on a row that is not a patient's cita. Filter with `origin=meta|organic|unknown` and, for Meta, `origin_ad_id` (a Meta ad id): rows that are not a patient's cita never match. `is_diagnosis` marks a diagnosis cita — a primera visita (`booking_kind` `new` / `new_rebooked`), an entry prestación the clinic confirmed, or a cita the clinic named as an evaluación / diagnóstico (the prestación, or the vendor's tratamiento label) unless its prestación is confirmed not to be an entry; `diagnosis=true` returns only those.
86930
+ * @description Mirrored AND native appointments between `from` (inclusive) and `to` (EXCLUSIVE), bare `YYYY-MM-DD` days in the clinic's timezone; the window may not exceed 8 days. Cancelled citas are INCLUDED (the grid draws them muted). Unlike `GET /clinic/agenda`, `professional_id` and `location_id` are VITRINA uuids — `clinic_professional.id` and `location.id` — so one query serves a Medilink, a Reservo and a native clinic. Each row still carries the vendor's own ids under `vendor` for provenance: a row with `vendor.professional_id` set and `professional: null` is a roster gap, never a cita nobody is attending. Never calls the clinic API. `flags` are the clinical alerts the clinic shows on the block: clinical-record content, returned to an API key or personal token only when it also holds `clinic_record:read`. `booking_kind` is the cita's Tipo de agendamiento: `new` (Nuevo: it would be a primera visita and the patient never booked before), `new_rebooked` (Nuevo · reagenda: a primera visita, but the patient had earlier bookings and never came) or `in_treatment` (En tratamiento: every other cita); null on a row that is not a patient's cita. It uses the primera-visita rule Vitrina Ads counts, so a patient back after 12 months without an attended cita is `new`. `origin` is the patient's Origen (`kind` `meta` with the ad, ad set and campaign names, or `organic`) — the attribution Vitrina Ads reports, one definition; null on a row that is not a patient's cita. Filter with `origin=meta|organic|unknown` and, for Meta, `origin_ad_id` (a Meta ad id): rows that are not a patient's cita never match. `is_diagnosis` marks a diagnosis cita — a primera visita (`booking_kind` `new` / `new_rebooked`), an entry prestación the clinic confirmed, or a cita the clinic named as an evaluación / diagnóstico (the prestación, or the vendor's tratamiento label) unless its prestación is confirmed not to be an entry; `diagnosis=true` returns only those. `booked_via` says how the cita was booked: `agent` (Vitrina's AI agent, with the conversation `channel`), `online` (the patient on a booking page), `whatsapp` (a person booked it within 48 h of a WhatsApp exchange with the patient), `staff` (a team member in Vitrina, `by`), `vendor` (keyed straight into the clinic's system) or `calendar`; `booked_at` is the vendor's own creation time when known. `patient_paid` is what the patient paid on their plans, all time (espejo de ingresos abonos plus presupuesto allocations), returned only to a caller holding `clinic_money:read`.
86915
86931
  *
86916
86932
  * **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`.
86917
86933
  */
@@ -86983,6 +86999,13 @@ interface paths {
86983
86999
  * "money": null,
86984
87000
  * "booking_kind": "new",
86985
87001
  * "is_diagnosis": true,
87002
+ * "booked_via": {
87003
+ * "kind": "agent",
87004
+ * "channel": "whatsapp",
87005
+ * "by": null,
87006
+ * "booked_at": "2026-09-21T18:04:00.000Z"
87007
+ * },
87008
+ * "patient_paid": 250000,
86986
87009
  * "flags": [
86987
87010
  * {
86988
87011
  * "id": "13131313-0000-4000-8000-000000000001",
@@ -87274,6 +87297,276 @@ interface paths {
87274
87297
  patch?: never;
87275
87298
  trace?: never;
87276
87299
  };
87300
+ "/clinic/agenda/month": {
87301
+ parameters: {
87302
+ query?: never;
87303
+ header?: never;
87304
+ path?: never;
87305
+ cookie?: never;
87306
+ };
87307
+ /**
87308
+ * Agenda month: citas per day, by Origen
87309
+ * @description Counts per day of one `month` (`YYYY-MM`, the clinic's clock), read in one pass: `citas` (patients' citas that still stand), split by Origen (`meta`, `organic`, `unknown` — the same resolver as the feed and Vitrina Ads), `diagnosis` (diagnosis citas among them, the feed's `is_diagnosis` rule) and `cancelled` (anuladas, counted apart). Blocks and the workspace's own events never count. Optional `location_id` / `professional_id` (Vitrina uuids). Never calls the clinic API.
87310
+ *
87311
+ * **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`.
87312
+ */
87313
+ get: {
87314
+ parameters: {
87315
+ query: {
87316
+ month: string;
87317
+ location_id?: string;
87318
+ professional_id?: string;
87319
+ };
87320
+ header?: never;
87321
+ path?: never;
87322
+ cookie?: never;
87323
+ };
87324
+ requestBody?: never;
87325
+ responses: {
87326
+ /** @description Agenda month */
87327
+ 200: {
87328
+ headers: {
87329
+ [name: string]: unknown;
87330
+ };
87331
+ content: {
87332
+ /**
87333
+ * @example {
87334
+ * "data": {
87335
+ * "month": "2026-10",
87336
+ * "days": [
87337
+ * {
87338
+ * "date": "2026-10-01",
87339
+ * "citas": 42,
87340
+ * "meta": 9,
87341
+ * "organic": 20,
87342
+ * "unknown": 13,
87343
+ * "diagnosis": 7,
87344
+ * "cancelled": 4
87345
+ * },
87346
+ * {
87347
+ * "date": "2026-10-02",
87348
+ * "citas": 38,
87349
+ * "meta": 6,
87350
+ * "organic": 19,
87351
+ * "unknown": 13,
87352
+ * "diagnosis": 5,
87353
+ * "cancelled": 2
87354
+ * }
87355
+ * ]
87356
+ * }
87357
+ * }
87358
+ */
87359
+ "application/json": {
87360
+ data?: unknown;
87361
+ meta?: {
87362
+ [key: string]: unknown;
87363
+ };
87364
+ };
87365
+ };
87366
+ };
87367
+ /** @description Validation error */
87368
+ 400: {
87369
+ headers: {
87370
+ [name: string]: unknown;
87371
+ };
87372
+ content: {
87373
+ "application/json": components["schemas"]["Error"];
87374
+ };
87375
+ };
87376
+ /** @description Unauthorized */
87377
+ 401: {
87378
+ headers: {
87379
+ [name: string]: unknown;
87380
+ };
87381
+ content: {
87382
+ "application/json": components["schemas"]["Error"];
87383
+ };
87384
+ };
87385
+ /** @description Forbidden */
87386
+ 403: {
87387
+ headers: {
87388
+ [name: string]: unknown;
87389
+ };
87390
+ content: {
87391
+ "application/json": components["schemas"]["Error"];
87392
+ };
87393
+ };
87394
+ /** @description Not found */
87395
+ 404: {
87396
+ headers: {
87397
+ [name: string]: unknown;
87398
+ };
87399
+ content: {
87400
+ "application/json": components["schemas"]["Error"];
87401
+ };
87402
+ };
87403
+ /** @description Conflict (incl. Idempotency-Key reuse with different body) */
87404
+ 409: {
87405
+ headers: {
87406
+ [name: string]: unknown;
87407
+ };
87408
+ content: {
87409
+ "application/json": components["schemas"]["Error"];
87410
+ };
87411
+ };
87412
+ /** @description Rate limited */
87413
+ 429: {
87414
+ headers: {
87415
+ [name: string]: unknown;
87416
+ };
87417
+ content: {
87418
+ "application/json": components["schemas"]["Error"];
87419
+ };
87420
+ };
87421
+ };
87422
+ };
87423
+ put?: never;
87424
+ post?: never;
87425
+ delete?: never;
87426
+ options?: never;
87427
+ head?: never;
87428
+ patch?: never;
87429
+ trace?: never;
87430
+ };
87431
+ "/clinic/agenda/free-hours": {
87432
+ parameters: {
87433
+ query?: never;
87434
+ header?: never;
87435
+ path?: never;
87436
+ cookie?: never;
87437
+ };
87438
+ /**
87439
+ * Horas libres: one day of free hours per professional
87440
+ * @description Every free slot of `date` from the clinic's own booking engine (the same read as `GET /clinic/agenda/availability`, whole day), grouped per professional with back-to-back slots merged into `ranges` and `slots` = how many cupos. `especialidad` narrows to the professionals whose specialties or note name it; `especialidades` lists the roster's own, for a picker. `professional_id` is the Vitrina uuid when the roster knows them. For a Dentalink / Medilink clinic this is one live vendor request per call (rate-limited upstream), so read it on demand rather than on a timer. A past day has no free hours.
87441
+ *
87442
+ * **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`.
87443
+ */
87444
+ get: {
87445
+ parameters: {
87446
+ query: {
87447
+ date: string;
87448
+ especialidad?: string;
87449
+ location_id?: string;
87450
+ };
87451
+ header?: never;
87452
+ path?: never;
87453
+ cookie?: never;
87454
+ };
87455
+ requestBody?: never;
87456
+ responses: {
87457
+ /** @description Free hours */
87458
+ 200: {
87459
+ headers: {
87460
+ [name: string]: unknown;
87461
+ };
87462
+ content: {
87463
+ /**
87464
+ * @example {
87465
+ * "data": {
87466
+ * "date": "2026-09-24",
87467
+ * "engine": "native-clinic",
87468
+ * "timezone": "America/Santiago",
87469
+ * "especialidad": null,
87470
+ * "professionals": [
87471
+ * {
87472
+ * "professional_id": "ffffffff-0000-4000-8000-000000000001",
87473
+ * "engine_professional_id": "ffffffff-0000-4000-8000-000000000001",
87474
+ * "name": "Ana Rojas",
87475
+ * "especialidad": "Implantología",
87476
+ * "ranges": [
87477
+ * {
87478
+ * "starts_at": "2026-09-24T12:00:00.000Z",
87479
+ * "ends_at": "2026-09-24T13:30:00.000Z"
87480
+ * },
87481
+ * {
87482
+ * "starts_at": "2026-09-24T17:00:00.000Z",
87483
+ * "ends_at": "2026-09-24T18:00:00.000Z"
87484
+ * }
87485
+ * ],
87486
+ * "slots": 5
87487
+ * }
87488
+ * ],
87489
+ * "especialidades": [
87490
+ * "Endodoncia",
87491
+ * "Implantología",
87492
+ * "Ortodoncia"
87493
+ * ],
87494
+ * "truncated": false
87495
+ * }
87496
+ * }
87497
+ */
87498
+ "application/json": {
87499
+ data?: unknown;
87500
+ meta?: {
87501
+ [key: string]: unknown;
87502
+ };
87503
+ };
87504
+ };
87505
+ };
87506
+ /** @description Validation error */
87507
+ 400: {
87508
+ headers: {
87509
+ [name: string]: unknown;
87510
+ };
87511
+ content: {
87512
+ "application/json": components["schemas"]["Error"];
87513
+ };
87514
+ };
87515
+ /** @description Unauthorized */
87516
+ 401: {
87517
+ headers: {
87518
+ [name: string]: unknown;
87519
+ };
87520
+ content: {
87521
+ "application/json": components["schemas"]["Error"];
87522
+ };
87523
+ };
87524
+ /** @description Forbidden */
87525
+ 403: {
87526
+ headers: {
87527
+ [name: string]: unknown;
87528
+ };
87529
+ content: {
87530
+ "application/json": components["schemas"]["Error"];
87531
+ };
87532
+ };
87533
+ /** @description Not found */
87534
+ 404: {
87535
+ headers: {
87536
+ [name: string]: unknown;
87537
+ };
87538
+ content: {
87539
+ "application/json": components["schemas"]["Error"];
87540
+ };
87541
+ };
87542
+ /** @description Conflict (incl. Idempotency-Key reuse with different body) */
87543
+ 409: {
87544
+ headers: {
87545
+ [name: string]: unknown;
87546
+ };
87547
+ content: {
87548
+ "application/json": components["schemas"]["Error"];
87549
+ };
87550
+ };
87551
+ /** @description Rate limited */
87552
+ 429: {
87553
+ headers: {
87554
+ [name: string]: unknown;
87555
+ };
87556
+ content: {
87557
+ "application/json": components["schemas"]["Error"];
87558
+ };
87559
+ };
87560
+ };
87561
+ };
87562
+ put?: never;
87563
+ post?: never;
87564
+ delete?: never;
87565
+ options?: never;
87566
+ head?: never;
87567
+ patch?: never;
87568
+ trace?: never;
87569
+ };
87277
87570
  "/clinic/agenda/availability": {
87278
87571
  parameters: {
87279
87572
  query?: never;
@@ -101939,7 +102232,7 @@ interface paths {
101939
102232
  };
101940
102233
  /**
101941
102234
  * The «Hoy» strip: is today on track?
101942
- * @description Requires `clinic:read` or `clinic_money:read`; cobrado figures need `clinic_money:read` and are `null` without it. Bookings made today (citas created today, for any date; a cancelled cita is not a booking: an anulación drops out, and a moved cita counts once, as its replacement) with their Tipo de agendamiento judged at the moment of booking, the bookings of the last hour, the same counts for the previous working day, cobrado today and the part from new patients (patients with a primera visita this month; `null` when the clinic's vendor has no payment mirror, e.g. Reservo), and the paces of today's month. The ritmo diario is a catch-up pace: (meta − achieved before today) ÷ working days left, today included, each day weighed by its opening hours against the clinic's longest day (a 9–14 Saturday next to 9–19 weekdays weighs 0.5), times today's weight (`per_day`). Working days come from the clinic's opening hours and holidays, in the clinic's timezone. A figure with no target has a count and no pace. The pace of cobrado is the Meta mensual's, set against the clinic's total cobrado.
102235
+ * @description Requires `clinic:read` or `clinic_money:read`; cobrado figures need `clinic_money:read` and are `null` without it. Bookings made today (citas created today, for any date; an anulación is not a booking; a moved cita stays a booking of the day it was made, and its replacement counts on the day it is re-booked) with their Tipo de agendamiento judged at the moment of booking, the bookings of the last hour, the same counts for the previous working day, cobrado today and the part from new patients (patients with a primera visita this month; `null` when the clinic's vendor has no payment mirror, e.g. Reservo), and the paces of today's month. The ritmo diario is a catch-up pace: (meta − achieved before today) ÷ working days left, today included, each day weighed by its opening hours against the clinic's longest day (a 9–14 Saturday next to 9–19 weekdays weighs 0.5), times today's weight (`per_day`). Working days come from the clinic's opening hours and holidays, in the clinic's timezone. A figure with no target has a count and no pace. The pace of cobrado is the Meta mensual's, set against the clinic's total cobrado.
101943
102236
  *
101944
102237
  * **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`.
101945
102238
  */
@@ -102194,7 +102487,7 @@ interface paths {
102194
102487
  };
102195
102488
  /**
102196
102489
  * The citas behind the «Hoy» numbers
102197
- * @description Requires `clinic:read`. The citas booked on one clinic day (`date`, default today; never a future day): when they were booked (the vendor's own creation time when the mirror carries it — Reservo — else when Vitrina first saw the cita, which is every Dentalink / Medilink cita), the hour of that in the clinic's clock, who the patient is, for when, with which professional, the Tipo de agendamiento judged as of the booking day, the Origen, whether the patient's linked contact had WhatsApp activity from two days before the booking day («Desde WhatsApp»), and the patient's last attended visit before that day. A cancelled cita is not a booking (an anulación; a moved cita counts once, as its replacement).
102490
+ * @description Requires `clinic:read`. The citas booked on one clinic day (`date`, default today; never a future day): when they were booked (the vendor's own creation time when the mirror carries it — Reservo — else when Vitrina first saw the cita, which is every Dentalink / Medilink cita), the hour of that in the clinic's clock, who the patient is, for when, with which professional, the Tipo de agendamiento judged as of the booking day, the Origen, whether the patient's linked contact had WhatsApp activity from two days before the booking day («Desde WhatsApp»), and the patient's last attended visit before that day. An anulación is not a booking; a moved cita («Cambio de fecha») stays a booking of the day it was made.
102198
102491
  *
102199
102492
  * **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`.
102200
102493
  */
package/dist/index.d.ts CHANGED
@@ -2058,6 +2058,10 @@ interface paths {
2058
2058
  treatment_price?: "unset" | "first_ask" | "never";
2059
2059
  /** @description «Ofrecer lista de espera si la primera hora está a más de 7 días» (#3314). Default false. */
2060
2060
  far_slot_waitlist?: boolean;
2061
+ /** @description «Dolor: ofrecer las primeras horas de hoy o mañana» (D72). A patient in pain is offered today's / tomorrow's first slots in the same turn; a handoff becomes a heads-up to reception, not the answer. Default false; true for the agent a new clinic's onboarding creates. */
2062
+ urgency_slots?: boolean;
2063
+ /** @description «Especialista a más de 7 días: ofrecer también una evaluación general esta semana» (D74). `find_slots` then also reports the clinic's general evaluation slots of the next 7 days. Default false. */
2064
+ specialist_fallback?: boolean;
2061
2065
  };
2062
2066
  /** @description The `draft_version` version you last read (the `X-Config-Version` response header, or the version field in the body). If it is no longer current the write is refused with 409 `VERSION_CONFLICT` and nothing is written; the error carries the current version and a diff hint. Optional for backward compatibility (an omitted value is accepted and logged), but send it: without it two editors silently overwrite each other. The `If-Match` header is accepted as an alternative. */
2063
2067
  expected_version?: number | null;
@@ -2241,7 +2245,7 @@ interface paths {
2241
2245
  };
2242
2246
  /**
2243
2247
  * Read the agent’s behaviour policies
2244
- * @description Per-agent switches that change what the agent says (#3312/#3314): `treatment_price` (`unset` | `first_ask` | `never`, healthcare) and `far_slot_waitlist`. `live` is what runs today, `draft` what is staged (null = nothing staged). Every default is the agent’s behaviour before policies existed: nothing is added to its prompt while a policy is unset. `price_policy_conflicts` lists lines of the agent’s own instructions (draft when staged) and active skills that already state a price rule, so a client can reconcile them before publishing. Change them with `PUT /ai-agents/{id}/draft` (`behavior_policies`) and `POST /ai-agents/{id}/publish`.
2248
+ * @description Per-agent switches that change what the agent says (#3312/#3314): `treatment_price` (`unset` | `first_ask` | `never`, healthcare) and `far_slot_waitlist`, `urgency_slots` (D72) and `specialist_fallback` (D74). `live` is what runs today, `draft` what is staged (null = nothing staged). Every default is the agent’s behaviour before policies existed: nothing is added to its prompt while a policy is unset. `price_policy_conflicts` lists lines of the agent’s own instructions (draft when staged) and active skills that already state a price rule, so a client can reconcile them before publishing. Change them with `PUT /ai-agents/{id}/draft` (`behavior_policies`) and `POST /ai-agents/{id}/publish`.
2245
2249
  */
2246
2250
  get: {
2247
2251
  parameters: {
@@ -2265,11 +2269,15 @@ interface paths {
2265
2269
  * "data": {
2266
2270
  * "live": {
2267
2271
  * "treatment_price": "unset",
2268
- * "far_slot_waitlist": false
2272
+ * "far_slot_waitlist": false,
2273
+ * "urgency_slots": false,
2274
+ * "specialist_fallback": false
2269
2275
  * },
2270
2276
  * "draft": {
2271
2277
  * "treatment_price": "first_ask",
2272
- * "far_slot_waitlist": false
2278
+ * "far_slot_waitlist": false,
2279
+ * "urgency_slots": true,
2280
+ * "specialist_fallback": false
2273
2281
  * },
2274
2282
  * "price_policy_conflicts": [
2275
2283
  * {
@@ -2291,6 +2299,10 @@ interface paths {
2291
2299
  treatment_price: "unset" | "first_ask" | "never";
2292
2300
  /** @description «Ofrecer lista de espera si la primera hora está a más de 7 días» (#3314). Default false. */
2293
2301
  far_slot_waitlist: boolean;
2302
+ /** @description «Dolor: ofrecer las primeras horas de hoy o mañana» (D72). A patient in pain is offered today's / tomorrow's first slots in the same turn; a handoff becomes a heads-up to reception, not the answer. Default false; true for the agent a new clinic's onboarding creates. */
2303
+ urgency_slots: boolean;
2304
+ /** @description «Especialista a más de 7 días: ofrecer también una evaluación general esta semana» (D74). `find_slots` then also reports the clinic's general evaluation slots of the next 7 days. Default false. */
2305
+ specialist_fallback: boolean;
2294
2306
  };
2295
2307
  draft: {
2296
2308
  /**
@@ -2300,6 +2312,10 @@ interface paths {
2300
2312
  treatment_price: "unset" | "first_ask" | "never";
2301
2313
  /** @description «Ofrecer lista de espera si la primera hora está a más de 7 días» (#3314). Default false. */
2302
2314
  far_slot_waitlist: boolean;
2315
+ /** @description «Dolor: ofrecer las primeras horas de hoy o mañana» (D72). A patient in pain is offered today's / tomorrow's first slots in the same turn; a handoff becomes a heads-up to reception, not the answer. Default false; true for the agent a new clinic's onboarding creates. */
2316
+ urgency_slots: boolean;
2317
+ /** @description «Especialista a más de 7 días: ofrecer también una evaluación general esta semana» (D74). `find_slots` then also reports the clinic's general evaluation slots of the next 7 days. Default false. */
2318
+ specialist_fallback: boolean;
2303
2319
  } | null;
2304
2320
  price_policy_conflicts: {
2305
2321
  /** @enum {string} */
@@ -86911,7 +86927,7 @@ interface paths {
86911
86927
  };
86912
86928
  /**
86913
86929
  * Agenda for a window, any engine, by professional and branch
86914
- * @description Mirrored AND native appointments between `from` (inclusive) and `to` (EXCLUSIVE), bare `YYYY-MM-DD` days in the clinic's timezone; the window may not exceed 8 days. Cancelled citas are INCLUDED (the grid draws them muted). Unlike `GET /clinic/agenda`, `professional_id` and `location_id` are VITRINA uuids — `clinic_professional.id` and `location.id` — so one query serves a Medilink, a Reservo and a native clinic. Each row still carries the vendor's own ids under `vendor` for provenance: a row with `vendor.professional_id` set and `professional: null` is a roster gap, never a cita nobody is attending. Never calls the clinic API. `flags` are the clinical alerts the clinic shows on the block: clinical-record content, returned to an API key or personal token only when it also holds `clinic_record:read`. `booking_kind` is the cita's Tipo de agendamiento: `new` (Nuevo: it would be a primera visita and the patient never booked before), `new_rebooked` (Nuevo · reagenda: a primera visita, but the patient had earlier bookings and never came) or `in_treatment` (En tratamiento: every other cita); null on a row that is not a patient's cita. It uses the primera-visita rule Vitrina Ads counts, so a patient back after 12 months without an attended cita is `new`. `origin` is the patient's Origen (`kind` `meta` with the ad, ad set and campaign names, or `organic`) — the attribution Vitrina Ads reports, one definition; null on a row that is not a patient's cita. Filter with `origin=meta|organic|unknown` and, for Meta, `origin_ad_id` (a Meta ad id): rows that are not a patient's cita never match. `is_diagnosis` marks a diagnosis cita — a primera visita (`booking_kind` `new` / `new_rebooked`), an entry prestación the clinic confirmed, or a cita the clinic named as an evaluación / diagnóstico (the prestación, or the vendor's tratamiento label) unless its prestación is confirmed not to be an entry; `diagnosis=true` returns only those.
86930
+ * @description Mirrored AND native appointments between `from` (inclusive) and `to` (EXCLUSIVE), bare `YYYY-MM-DD` days in the clinic's timezone; the window may not exceed 8 days. Cancelled citas are INCLUDED (the grid draws them muted). Unlike `GET /clinic/agenda`, `professional_id` and `location_id` are VITRINA uuids — `clinic_professional.id` and `location.id` — so one query serves a Medilink, a Reservo and a native clinic. Each row still carries the vendor's own ids under `vendor` for provenance: a row with `vendor.professional_id` set and `professional: null` is a roster gap, never a cita nobody is attending. Never calls the clinic API. `flags` are the clinical alerts the clinic shows on the block: clinical-record content, returned to an API key or personal token only when it also holds `clinic_record:read`. `booking_kind` is the cita's Tipo de agendamiento: `new` (Nuevo: it would be a primera visita and the patient never booked before), `new_rebooked` (Nuevo · reagenda: a primera visita, but the patient had earlier bookings and never came) or `in_treatment` (En tratamiento: every other cita); null on a row that is not a patient's cita. It uses the primera-visita rule Vitrina Ads counts, so a patient back after 12 months without an attended cita is `new`. `origin` is the patient's Origen (`kind` `meta` with the ad, ad set and campaign names, or `organic`) — the attribution Vitrina Ads reports, one definition; null on a row that is not a patient's cita. Filter with `origin=meta|organic|unknown` and, for Meta, `origin_ad_id` (a Meta ad id): rows that are not a patient's cita never match. `is_diagnosis` marks a diagnosis cita — a primera visita (`booking_kind` `new` / `new_rebooked`), an entry prestación the clinic confirmed, or a cita the clinic named as an evaluación / diagnóstico (the prestación, or the vendor's tratamiento label) unless its prestación is confirmed not to be an entry; `diagnosis=true` returns only those. `booked_via` says how the cita was booked: `agent` (Vitrina's AI agent, with the conversation `channel`), `online` (the patient on a booking page), `whatsapp` (a person booked it within 48 h of a WhatsApp exchange with the patient), `staff` (a team member in Vitrina, `by`), `vendor` (keyed straight into the clinic's system) or `calendar`; `booked_at` is the vendor's own creation time when known. `patient_paid` is what the patient paid on their plans, all time (espejo de ingresos abonos plus presupuesto allocations), returned only to a caller holding `clinic_money:read`.
86915
86931
  *
86916
86932
  * **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`.
86917
86933
  */
@@ -86983,6 +86999,13 @@ interface paths {
86983
86999
  * "money": null,
86984
87000
  * "booking_kind": "new",
86985
87001
  * "is_diagnosis": true,
87002
+ * "booked_via": {
87003
+ * "kind": "agent",
87004
+ * "channel": "whatsapp",
87005
+ * "by": null,
87006
+ * "booked_at": "2026-09-21T18:04:00.000Z"
87007
+ * },
87008
+ * "patient_paid": 250000,
86986
87009
  * "flags": [
86987
87010
  * {
86988
87011
  * "id": "13131313-0000-4000-8000-000000000001",
@@ -87274,6 +87297,276 @@ interface paths {
87274
87297
  patch?: never;
87275
87298
  trace?: never;
87276
87299
  };
87300
+ "/clinic/agenda/month": {
87301
+ parameters: {
87302
+ query?: never;
87303
+ header?: never;
87304
+ path?: never;
87305
+ cookie?: never;
87306
+ };
87307
+ /**
87308
+ * Agenda month: citas per day, by Origen
87309
+ * @description Counts per day of one `month` (`YYYY-MM`, the clinic's clock), read in one pass: `citas` (patients' citas that still stand), split by Origen (`meta`, `organic`, `unknown` — the same resolver as the feed and Vitrina Ads), `diagnosis` (diagnosis citas among them, the feed's `is_diagnosis` rule) and `cancelled` (anuladas, counted apart). Blocks and the workspace's own events never count. Optional `location_id` / `professional_id` (Vitrina uuids). Never calls the clinic API.
87310
+ *
87311
+ * **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`.
87312
+ */
87313
+ get: {
87314
+ parameters: {
87315
+ query: {
87316
+ month: string;
87317
+ location_id?: string;
87318
+ professional_id?: string;
87319
+ };
87320
+ header?: never;
87321
+ path?: never;
87322
+ cookie?: never;
87323
+ };
87324
+ requestBody?: never;
87325
+ responses: {
87326
+ /** @description Agenda month */
87327
+ 200: {
87328
+ headers: {
87329
+ [name: string]: unknown;
87330
+ };
87331
+ content: {
87332
+ /**
87333
+ * @example {
87334
+ * "data": {
87335
+ * "month": "2026-10",
87336
+ * "days": [
87337
+ * {
87338
+ * "date": "2026-10-01",
87339
+ * "citas": 42,
87340
+ * "meta": 9,
87341
+ * "organic": 20,
87342
+ * "unknown": 13,
87343
+ * "diagnosis": 7,
87344
+ * "cancelled": 4
87345
+ * },
87346
+ * {
87347
+ * "date": "2026-10-02",
87348
+ * "citas": 38,
87349
+ * "meta": 6,
87350
+ * "organic": 19,
87351
+ * "unknown": 13,
87352
+ * "diagnosis": 5,
87353
+ * "cancelled": 2
87354
+ * }
87355
+ * ]
87356
+ * }
87357
+ * }
87358
+ */
87359
+ "application/json": {
87360
+ data?: unknown;
87361
+ meta?: {
87362
+ [key: string]: unknown;
87363
+ };
87364
+ };
87365
+ };
87366
+ };
87367
+ /** @description Validation error */
87368
+ 400: {
87369
+ headers: {
87370
+ [name: string]: unknown;
87371
+ };
87372
+ content: {
87373
+ "application/json": components["schemas"]["Error"];
87374
+ };
87375
+ };
87376
+ /** @description Unauthorized */
87377
+ 401: {
87378
+ headers: {
87379
+ [name: string]: unknown;
87380
+ };
87381
+ content: {
87382
+ "application/json": components["schemas"]["Error"];
87383
+ };
87384
+ };
87385
+ /** @description Forbidden */
87386
+ 403: {
87387
+ headers: {
87388
+ [name: string]: unknown;
87389
+ };
87390
+ content: {
87391
+ "application/json": components["schemas"]["Error"];
87392
+ };
87393
+ };
87394
+ /** @description Not found */
87395
+ 404: {
87396
+ headers: {
87397
+ [name: string]: unknown;
87398
+ };
87399
+ content: {
87400
+ "application/json": components["schemas"]["Error"];
87401
+ };
87402
+ };
87403
+ /** @description Conflict (incl. Idempotency-Key reuse with different body) */
87404
+ 409: {
87405
+ headers: {
87406
+ [name: string]: unknown;
87407
+ };
87408
+ content: {
87409
+ "application/json": components["schemas"]["Error"];
87410
+ };
87411
+ };
87412
+ /** @description Rate limited */
87413
+ 429: {
87414
+ headers: {
87415
+ [name: string]: unknown;
87416
+ };
87417
+ content: {
87418
+ "application/json": components["schemas"]["Error"];
87419
+ };
87420
+ };
87421
+ };
87422
+ };
87423
+ put?: never;
87424
+ post?: never;
87425
+ delete?: never;
87426
+ options?: never;
87427
+ head?: never;
87428
+ patch?: never;
87429
+ trace?: never;
87430
+ };
87431
+ "/clinic/agenda/free-hours": {
87432
+ parameters: {
87433
+ query?: never;
87434
+ header?: never;
87435
+ path?: never;
87436
+ cookie?: never;
87437
+ };
87438
+ /**
87439
+ * Horas libres: one day of free hours per professional
87440
+ * @description Every free slot of `date` from the clinic's own booking engine (the same read as `GET /clinic/agenda/availability`, whole day), grouped per professional with back-to-back slots merged into `ranges` and `slots` = how many cupos. `especialidad` narrows to the professionals whose specialties or note name it; `especialidades` lists the roster's own, for a picker. `professional_id` is the Vitrina uuid when the roster knows them. For a Dentalink / Medilink clinic this is one live vendor request per call (rate-limited upstream), so read it on demand rather than on a timer. A past day has no free hours.
87441
+ *
87442
+ * **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`.
87443
+ */
87444
+ get: {
87445
+ parameters: {
87446
+ query: {
87447
+ date: string;
87448
+ especialidad?: string;
87449
+ location_id?: string;
87450
+ };
87451
+ header?: never;
87452
+ path?: never;
87453
+ cookie?: never;
87454
+ };
87455
+ requestBody?: never;
87456
+ responses: {
87457
+ /** @description Free hours */
87458
+ 200: {
87459
+ headers: {
87460
+ [name: string]: unknown;
87461
+ };
87462
+ content: {
87463
+ /**
87464
+ * @example {
87465
+ * "data": {
87466
+ * "date": "2026-09-24",
87467
+ * "engine": "native-clinic",
87468
+ * "timezone": "America/Santiago",
87469
+ * "especialidad": null,
87470
+ * "professionals": [
87471
+ * {
87472
+ * "professional_id": "ffffffff-0000-4000-8000-000000000001",
87473
+ * "engine_professional_id": "ffffffff-0000-4000-8000-000000000001",
87474
+ * "name": "Ana Rojas",
87475
+ * "especialidad": "Implantología",
87476
+ * "ranges": [
87477
+ * {
87478
+ * "starts_at": "2026-09-24T12:00:00.000Z",
87479
+ * "ends_at": "2026-09-24T13:30:00.000Z"
87480
+ * },
87481
+ * {
87482
+ * "starts_at": "2026-09-24T17:00:00.000Z",
87483
+ * "ends_at": "2026-09-24T18:00:00.000Z"
87484
+ * }
87485
+ * ],
87486
+ * "slots": 5
87487
+ * }
87488
+ * ],
87489
+ * "especialidades": [
87490
+ * "Endodoncia",
87491
+ * "Implantología",
87492
+ * "Ortodoncia"
87493
+ * ],
87494
+ * "truncated": false
87495
+ * }
87496
+ * }
87497
+ */
87498
+ "application/json": {
87499
+ data?: unknown;
87500
+ meta?: {
87501
+ [key: string]: unknown;
87502
+ };
87503
+ };
87504
+ };
87505
+ };
87506
+ /** @description Validation error */
87507
+ 400: {
87508
+ headers: {
87509
+ [name: string]: unknown;
87510
+ };
87511
+ content: {
87512
+ "application/json": components["schemas"]["Error"];
87513
+ };
87514
+ };
87515
+ /** @description Unauthorized */
87516
+ 401: {
87517
+ headers: {
87518
+ [name: string]: unknown;
87519
+ };
87520
+ content: {
87521
+ "application/json": components["schemas"]["Error"];
87522
+ };
87523
+ };
87524
+ /** @description Forbidden */
87525
+ 403: {
87526
+ headers: {
87527
+ [name: string]: unknown;
87528
+ };
87529
+ content: {
87530
+ "application/json": components["schemas"]["Error"];
87531
+ };
87532
+ };
87533
+ /** @description Not found */
87534
+ 404: {
87535
+ headers: {
87536
+ [name: string]: unknown;
87537
+ };
87538
+ content: {
87539
+ "application/json": components["schemas"]["Error"];
87540
+ };
87541
+ };
87542
+ /** @description Conflict (incl. Idempotency-Key reuse with different body) */
87543
+ 409: {
87544
+ headers: {
87545
+ [name: string]: unknown;
87546
+ };
87547
+ content: {
87548
+ "application/json": components["schemas"]["Error"];
87549
+ };
87550
+ };
87551
+ /** @description Rate limited */
87552
+ 429: {
87553
+ headers: {
87554
+ [name: string]: unknown;
87555
+ };
87556
+ content: {
87557
+ "application/json": components["schemas"]["Error"];
87558
+ };
87559
+ };
87560
+ };
87561
+ };
87562
+ put?: never;
87563
+ post?: never;
87564
+ delete?: never;
87565
+ options?: never;
87566
+ head?: never;
87567
+ patch?: never;
87568
+ trace?: never;
87569
+ };
87277
87570
  "/clinic/agenda/availability": {
87278
87571
  parameters: {
87279
87572
  query?: never;
@@ -101939,7 +102232,7 @@ interface paths {
101939
102232
  };
101940
102233
  /**
101941
102234
  * The «Hoy» strip: is today on track?
101942
- * @description Requires `clinic:read` or `clinic_money:read`; cobrado figures need `clinic_money:read` and are `null` without it. Bookings made today (citas created today, for any date; a cancelled cita is not a booking: an anulación drops out, and a moved cita counts once, as its replacement) with their Tipo de agendamiento judged at the moment of booking, the bookings of the last hour, the same counts for the previous working day, cobrado today and the part from new patients (patients with a primera visita this month; `null` when the clinic's vendor has no payment mirror, e.g. Reservo), and the paces of today's month. The ritmo diario is a catch-up pace: (meta − achieved before today) ÷ working days left, today included, each day weighed by its opening hours against the clinic's longest day (a 9–14 Saturday next to 9–19 weekdays weighs 0.5), times today's weight (`per_day`). Working days come from the clinic's opening hours and holidays, in the clinic's timezone. A figure with no target has a count and no pace. The pace of cobrado is the Meta mensual's, set against the clinic's total cobrado.
102235
+ * @description Requires `clinic:read` or `clinic_money:read`; cobrado figures need `clinic_money:read` and are `null` without it. Bookings made today (citas created today, for any date; an anulación is not a booking; a moved cita stays a booking of the day it was made, and its replacement counts on the day it is re-booked) with their Tipo de agendamiento judged at the moment of booking, the bookings of the last hour, the same counts for the previous working day, cobrado today and the part from new patients (patients with a primera visita this month; `null` when the clinic's vendor has no payment mirror, e.g. Reservo), and the paces of today's month. The ritmo diario is a catch-up pace: (meta − achieved before today) ÷ working days left, today included, each day weighed by its opening hours against the clinic's longest day (a 9–14 Saturday next to 9–19 weekdays weighs 0.5), times today's weight (`per_day`). Working days come from the clinic's opening hours and holidays, in the clinic's timezone. A figure with no target has a count and no pace. The pace of cobrado is the Meta mensual's, set against the clinic's total cobrado.
101943
102236
  *
101944
102237
  * **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`.
101945
102238
  */
@@ -102194,7 +102487,7 @@ interface paths {
102194
102487
  };
102195
102488
  /**
102196
102489
  * The citas behind the «Hoy» numbers
102197
- * @description Requires `clinic:read`. The citas booked on one clinic day (`date`, default today; never a future day): when they were booked (the vendor's own creation time when the mirror carries it — Reservo — else when Vitrina first saw the cita, which is every Dentalink / Medilink cita), the hour of that in the clinic's clock, who the patient is, for when, with which professional, the Tipo de agendamiento judged as of the booking day, the Origen, whether the patient's linked contact had WhatsApp activity from two days before the booking day («Desde WhatsApp»), and the patient's last attended visit before that day. A cancelled cita is not a booking (an anulación; a moved cita counts once, as its replacement).
102490
+ * @description Requires `clinic:read`. The citas booked on one clinic day (`date`, default today; never a future day): when they were booked (the vendor's own creation time when the mirror carries it — Reservo — else when Vitrina first saw the cita, which is every Dentalink / Medilink cita), the hour of that in the clinic's clock, who the patient is, for when, with which professional, the Tipo de agendamiento judged as of the booking day, the Origen, whether the patient's linked contact had WhatsApp activity from two days before the booking day («Desde WhatsApp»), and the patient's last attended visit before that day. An anulación is not a booking; a moved cita («Cambio de fecha») stays a booking of the day it was made.
102198
102491
  *
102199
102492
  * **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`.
102200
102493
  */
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@vitrina/api",
3
- "version": "13.1.0",
3
+ "version": "13.3.0",
4
4
  "description": "Typed TypeScript SDK for the Vitrina API pública — generated from the committed openapi.public.json (ADR 0106).",
5
5
  "type": "module",
6
6
  "license": "MIT",