@vitrina/api 11.42.0 → 11.43.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.
Files changed (3) hide show
  1. package/dist/index.d.cts +2335 -417
  2. package/dist/index.d.ts +2335 -417
  3. package/package.json +1 -1
package/dist/index.d.cts CHANGED
@@ -16350,7 +16350,7 @@ interface paths {
16350
16350
  };
16351
16351
  /**
16352
16352
  * A vehicle's change history (Historial)
16353
- * @description Reverse-chronological audit trail for this vehicle — created, field edits (with a before→after diff), publish/unpublish/cierre, and Override local protect/release — with teammate actors resolved to display names. The UI merges it with /activity (leads) into one "Leads y cambios" timeline.
16353
+ * @description Reverse-chronological audit trail for this vehicle — created, field edits (with a before→after diff), publish/unpublish/cierre, and Override local protect/release — with teammate actors resolved to display names. It also carries the deal's milestones, read from each document's own audit rows: nota de compra emitted/voided (`purchase_note_issued`, `purchase_note_voided`), nota de venta emitted/approved/voided (`sale_note_issued`, `sale_note_approved`, `sale_note_voided`), contrato de compraventa first printed (`compraventa_printed`), mandato de consignación first printed (`mandato_issued`), a signed copy filed (`signed_copy_filed`, with `metadata.signed_document_type`) and the liquidación paid to the consignor (`liquidacion_paid`). `metadata.folio` names the document when it has one. Each document type appears only for a caller holding its read scope (`purchase_notes:read`, `sale_notes:read`, `consignments:read`; signed copies also need `vehicle_registry:read`). A download of the Resumen del negocio is `deal_settlement_downloaded`. The UI merges it with /activity (leads) into one "Leads y cambios" timeline.
16354
16354
  */
16355
16355
  get: {
16356
16356
  parameters: {
@@ -16375,6 +16375,22 @@ interface paths {
16375
16375
  * @example {
16376
16376
  * "data": [
16377
16377
  * {
16378
+ * "id": "99999999-0000-4000-8000-000000000005",
16379
+ * "action": "sale_notes.approve",
16380
+ * "kind": "sale_note_approved",
16381
+ * "actor": {
16382
+ * "kind": "user",
16383
+ * "id": "11111111-0000-4000-8000-000000000001",
16384
+ * "name": "Ana Torres"
16385
+ * },
16386
+ * "changes": [],
16387
+ * "metadata": {
16388
+ * "folio": "V-13",
16389
+ * "vehicle_id": "e1e1e1e1-0000-4000-8000-000000000001"
16390
+ * },
16391
+ * "at": "2026-09-18T15:02:11.000Z"
16392
+ * },
16393
+ * {
16378
16394
  * "id": "99999999-0000-4000-8000-000000000003",
16379
16395
  * "action": "vehicles.create",
16380
16396
  * "kind": "created",
@@ -33834,7 +33850,7 @@ interface paths {
33834
33850
  };
33835
33851
  /**
33836
33852
  * Print the nota de compra
33837
- * @description The nota de compra as a printable PDF (`application/pdf`, served `inline`) on the dealership’s paper: folio, seller, vehicle, lines and totals. Rendered on demand and not stored. Any status prints; a voided note says «Anulada». Accepts the UUID or the folio (`P-47`). Requires `purchase_notes:read`.
33853
+ * @description The nota de compra as a printable PDF (`application/pdf`, served `inline`) on the dealership’s paper, drawn from the workspace’s default nota de compra template (the standard text when there is none): folio, the seller and the dealership with RUT and domicilio, the vehicle, the price with its retentions and the amount paid to the seller, detail lines and signatures. A fact the seller’s contact lacks prints «【PENDIENTE: …】» rather than refusing the print. Rendered on demand and not stored. Any status prints; a voided note says «Anulada». Accepts the UUID or the folio (`P-47`). Requires `purchase_notes:read`.
33838
33854
  */
33839
33855
  get: {
33840
33856
  parameters: {
@@ -34420,7 +34436,7 @@ interface paths {
34420
34436
  };
34421
34437
  /**
34422
34438
  * Placeholder values of the latest issued document of a template's type
34423
- * @description What the template preview renders against: the `{{NAME}}` values of the most recent documento emitido of the template's document type, built by the SAME code that prints that document, so the preview cannot drift from the print. Covers `sale_note`, `compraventa`, `deal_settlement` (Resumen del negocio), `consignment` (mandato) and `consignment_settlement` (liquidación); nota de compra, reserva, cotización and ficha técnica print fixed layouts and have no values source. `source` names the document (`display_id`: the folio such as `V-12`, or the patente for a consignment, and when it was issued); it is `null` — with an empty `values` — when none exists or the type has no values source; the caller then falls back to the vocabulary examples. A fact the document lacks is absent from `values`, never blank. The values carry buyer/owner identity and money, so this requires `document_templates:read` AND the read scope of that document (`sale_notes:read` for nota de venta and compraventa, `consignments:read` for the two consignment families, `dealership_economics:read` for the Resumen del negocio). Writes and issues nothing.
34439
+ * @description What the template preview renders against: the `{{NAME}}` values of the most recent documento emitido of the template's document type, built by the SAME code that prints that document, so the preview cannot drift from the print. Covers `sale_note`, `compraventa`, `deal_settlement` (Resumen del negocio), `consignment` (mandato), `consignment_settlement` (liquidación) and `purchase_note` (nota de compra); reserva, cotización and ficha técnica print fixed layouts and have no values source. The designed blocks (`BLOQUE_PARTES`, `BLOQUE_VEHICULO`, `BLOQUE_PRECIO`, `BLOQUE_FIRMAS`) are values too: each is the block's text form filled with the same document's values (a fact the document lacks reads «【PENDIENTE: …】»). `source` names the document (`display_id`: the folio such as `V-12`, or the patente for a consignment, and when it was issued); it is `null` — with an empty `values` — when none exists or the type has no values source; the caller then falls back to the vocabulary examples. A fact the document lacks is absent from `values`, never blank. The values carry buyer/owner identity and money, so this requires `document_templates:read` AND the read scope of that document (`sale_notes:read` for nota de venta and compraventa, `consignments:read` for the two consignment families, `dealership_economics:read` for the Resumen del negocio, `purchase_notes:read` for the nota de compra). Writes and issues nothing.
34424
34440
  */
34425
34441
  get: {
34426
34442
  parameters: {
@@ -39637,6 +39653,205 @@ interface paths {
39637
39653
  patch?: never;
39638
39654
  trace?: never;
39639
39655
  };
39656
+ "/margin/preview": {
39657
+ parameters: {
39658
+ query?: never;
39659
+ header?: never;
39660
+ path?: never;
39661
+ cookie?: never;
39662
+ };
39663
+ get?: never;
39664
+ put?: never;
39665
+ /**
39666
+ * Preview the margin of a nota de venta being written
39667
+ * @description The margin a nota de venta WOULD leave if the unit sold today at `net_clp` — what the nota de venta form shows while the price is typed. The same preview the Resumen del negocio serves for a car with no live nota de venta (`GET /vehicles/{id}/deal-settlement`, `state: preview`), at the typed price instead of the published one: no add-ons, no seller commissions, and the one margin definition. The body is the deal-margin DTO of `GET /margin/deals/{id}` without `sale_note_id`, `display_id` and `salesperson_id` — no document exists yet.
39668
+ *
39669
+ * **A consigned unit is previewed on its contract’s economics**: the split is projected from the active contract’s comisión exactly as the liquidación will compute it (`settlement` carries the projection), so the dealership’s revenue is the comisión, never the whole price. A contract with no comisión on file has no split to project: its revenue is `null` with a `liquidacion` gap.
39670
+ *
39671
+ * `net_clp` is NET of IVA (cifras del negocio, ADR 0114 §2.2). The price a buyer agrees to on an afecto sale includes IVA, like the published price: send `round(price / 1,19)`. Writes nothing. Requires `dealership_economics:read`; 404 for a unit outside the workspace.
39672
+ */
39673
+ post: {
39674
+ parameters: {
39675
+ query?: never;
39676
+ header?: {
39677
+ /** @description Replay-safe retries: resending the SAME key with the SAME body returns the original response (`X-Idempotent-Replay: 1`) instead of creating a second copy — safe to send whenever a response might not have arrived. The same key with a DIFFERENT body answers `409 IDEMPOTENCY_KEY_CONFLICT`; use a fresh key per operation. */
39678
+ "Idempotency-Key"?: string;
39679
+ };
39680
+ path?: never;
39681
+ cookie?: never;
39682
+ };
39683
+ requestBody?: {
39684
+ content: {
39685
+ /**
39686
+ * @example {
39687
+ * "vehicle_id": "e5e5e5e5-0000-4000-8000-000000000002",
39688
+ * "net_clp": 10000000
39689
+ * }
39690
+ */
39691
+ "application/json": {
39692
+ /**
39693
+ * Format: uuid
39694
+ * @description The unit being sold.
39695
+ * @example 4b1c2d3e-5f60-4a7b-8c9d-0e1f2a3b4c5d
39696
+ */
39697
+ vehicle_id: string;
39698
+ /**
39699
+ * @description The sale price the nota de venta would record, NET of IVA, in whole CLP pesos. On an afecto sale that is the price the buyer pays divided by 1,19 (rounded); on an exento sale it is the price.
39700
+ * @example 10084034
39701
+ */
39702
+ net_clp: number;
39703
+ /**
39704
+ * @description The leg the sale would be issued under. Omitted = the leg the unit’s tenencia suggests (`consignante` for a consigned unit, `automotora` otherwise).
39705
+ * @enum {string}
39706
+ */
39707
+ seller_of_record?: "consignante" | "retoma" | "automotora";
39708
+ };
39709
+ };
39710
+ };
39711
+ responses: {
39712
+ /** @description The previewed deal margin */
39713
+ 200: {
39714
+ headers: {
39715
+ [name: string]: unknown;
39716
+ };
39717
+ content: {
39718
+ /**
39719
+ * @example {
39720
+ * "data": {
39721
+ * "vehicle_id": "e5e5e5e5-0000-4000-8000-000000000002",
39722
+ * "issued_at": "2026-09-29T15:00:00.000Z",
39723
+ * "period": "2026-09",
39724
+ * "regime": "consignacion",
39725
+ * "ingresos_clp": 800000,
39726
+ * "revenue_terms": {
39727
+ * "precio_venta_clp": 10000000,
39728
+ * "add_on_charges_clp": 0,
39729
+ * "pass_through_clp": 0,
39730
+ * "pass_through_paid_out_clp": 0,
39731
+ * "dealer_take_clp": 800000
39732
+ * },
39733
+ * "costo_venta_clp": 0,
39734
+ * "margen_bruto_clp": 800000,
39735
+ * "deductions": {
39736
+ * "comisiones_vendedores_clp": 0,
39737
+ * "gastos_adicionales_clp": 120000,
39738
+ * "gastos_unidad_clp": 120000,
39739
+ * "ingresos_unidad_clp": 0,
39740
+ * "desembolsos_add_on_clp": 0,
39741
+ * "gastos_fijos_clp": null
39742
+ * },
39743
+ * "margen_neto_clp": 680000,
39744
+ * "settlement": {
39745
+ * "settlement_mode": "stated_commission",
39746
+ * "amount_venta_clp": 10000000,
39747
+ * "monto_owner_clp": 9200000,
39748
+ * "deducciones_clp": 0
39749
+ * },
39750
+ * "cost_rollup": {
39751
+ * "acquisition_net_clp": 0,
39752
+ * "expense_total_clp": 120000,
39753
+ * "income_total_clp": 0,
39754
+ * "total_cost_clp": 120000,
39755
+ * "dealership_cost_clp": 120000,
39756
+ * "by_party": {
39757
+ * "automotora": {
39758
+ * "acquisition_clp": 0,
39759
+ * "expense_clp": 120000,
39760
+ * "income_clp": 0,
39761
+ * "total_clp": 120000
39762
+ * },
39763
+ * "dueno": {
39764
+ * "acquisition_clp": 0,
39765
+ * "expense_clp": 0,
39766
+ * "income_clp": 0,
39767
+ * "total_clp": 0
39768
+ * },
39769
+ * "cliente": {
39770
+ * "acquisition_clp": 0,
39771
+ * "expense_clp": 0,
39772
+ * "income_clp": 0,
39773
+ * "total_clp": 0
39774
+ * }
39775
+ * },
39776
+ * "entry_count": 2,
39777
+ * "complete": true,
39778
+ * "gaps": []
39779
+ * },
39780
+ * "complete": true,
39781
+ * "gaps": []
39782
+ * }
39783
+ * }
39784
+ */
39785
+ "application/json": {
39786
+ data?: unknown;
39787
+ meta?: {
39788
+ [key: string]: unknown;
39789
+ };
39790
+ };
39791
+ };
39792
+ };
39793
+ /** @description Validation error */
39794
+ 400: {
39795
+ headers: {
39796
+ [name: string]: unknown;
39797
+ };
39798
+ content: {
39799
+ "application/json": components["schemas"]["Error"];
39800
+ };
39801
+ };
39802
+ /** @description Unauthorized */
39803
+ 401: {
39804
+ headers: {
39805
+ [name: string]: unknown;
39806
+ };
39807
+ content: {
39808
+ "application/json": components["schemas"]["Error"];
39809
+ };
39810
+ };
39811
+ /** @description Forbidden */
39812
+ 403: {
39813
+ headers: {
39814
+ [name: string]: unknown;
39815
+ };
39816
+ content: {
39817
+ "application/json": components["schemas"]["Error"];
39818
+ };
39819
+ };
39820
+ /** @description Not found */
39821
+ 404: {
39822
+ headers: {
39823
+ [name: string]: unknown;
39824
+ };
39825
+ content: {
39826
+ "application/json": components["schemas"]["Error"];
39827
+ };
39828
+ };
39829
+ /** @description Conflict (incl. Idempotency-Key reuse with different body) */
39830
+ 409: {
39831
+ headers: {
39832
+ [name: string]: unknown;
39833
+ };
39834
+ content: {
39835
+ "application/json": components["schemas"]["Error"];
39836
+ };
39837
+ };
39838
+ /** @description Rate limited */
39839
+ 429: {
39840
+ headers: {
39841
+ [name: string]: unknown;
39842
+ };
39843
+ content: {
39844
+ "application/json": components["schemas"]["Error"];
39845
+ };
39846
+ };
39847
+ };
39848
+ };
39849
+ delete?: never;
39850
+ options?: never;
39851
+ head?: never;
39852
+ patch?: never;
39853
+ trace?: never;
39854
+ };
39640
39855
  "/margin/export": {
39641
39856
  parameters: {
39642
39857
  query?: never;
@@ -71823,6 +72038,263 @@ interface paths {
71823
72038
  patch?: never;
71824
72039
  trace?: never;
71825
72040
  };
72041
+ "/clinic/insights/resultados": {
72042
+ parameters: {
72043
+ query?: never;
72044
+ header?: never;
72045
+ path?: never;
72046
+ cookie?: never;
72047
+ };
72048
+ /**
72049
+ * «Tu agenda con Vitrina»: what the AI did for the diary
72050
+ * @description One canonical read of what Vitrina's agent did for the clinic's agenda, aggregates only (never a patient, cita or conversation id). A cita is «agendada por Vitrina» when the agent booked it in a conversation (`source = 'agent'` and no public booking page); the window is on the day the cita HAPPENS (`starts_at`), blocks and holds out. Blocks: `bookings` (count and share of the agenda, with the previous period of the same length); `money` (the value of those citas — pipeline — and the CASH their patients paid in the period from the day Vitrina booked them, read from the revenue mirror when it is on, else from the native ledger; `null` with `withheld: true` for a caller without `clinic_money:read`); `out_of_hours` (bookings made while the workspace was closed per its business hours, plus a weekday × hour heatmap; `null` when no hours are configured); `autonomy` (bookings with no team message in the conversation, from the patient's first message of the 7 days before); `time_to_book` (median and p95, first patient message → booking); `hours_returned` (AI bookings × 10 minutes, a stated rule); `recovery` (no-shows over known attendance, and no-shows / cancellations the same patient booked again within 30 days, with how many of those Vitrina booked); `confirmation` (attendance of confirmed vs unconfirmed citas, the `confirmaciones` report's own figures); `ads` (cost per cita agendada / asistida / paciente que pagó = the Ads overview's spend ÷ its counts for the same dates; `not_active` without Vitrina Ads); `reminders` (reminders that did not go out, by cause). Every block carries a printable `rule`; every rate is `null` — never 0 — without a denominator, and measured figures carry `measured` / `unknown` counts. Requires `clinic:read`. Accepts `from` / `to` (bare `YYYY-MM-DD`, `to` inclusive; default the 90 days ending today in the clinic's zone) and `location_id`.
72051
+ *
72052
+ * **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`.
72053
+ */
72054
+ get: {
72055
+ parameters: {
72056
+ query?: {
72057
+ /** @description First day of the window (by the day the cita happens), inclusive. Defaults to 90 days before `to`. */
72058
+ from?: string;
72059
+ /** @description Last day of the window, INCLUSIVE. Defaults to today in the clinic's zone. */
72060
+ to?: string;
72061
+ /** @description One sucursal. Omit for all of them. */
72062
+ location_id?: string;
72063
+ };
72064
+ header?: never;
72065
+ path?: never;
72066
+ cookie?: never;
72067
+ };
72068
+ requestBody?: never;
72069
+ responses: {
72070
+ /** @description Tu agenda con Vitrina */
72071
+ 200: {
72072
+ headers: {
72073
+ [name: string]: unknown;
72074
+ };
72075
+ content: {
72076
+ /**
72077
+ * @example {
72078
+ * "data": {
72079
+ * "from": "2026-07-01",
72080
+ * "to": "2026-09-28",
72081
+ * "timezone": "America/Santiago",
72082
+ * "location_id": null,
72083
+ * "family": "clinic",
72084
+ * "previous_period": {
72085
+ * "from": "2026-04-02",
72086
+ * "to": "2026-06-30"
72087
+ * },
72088
+ * "bookings": {
72089
+ * "ai": 286,
72090
+ * "agenda_total": 2011,
72091
+ * "share_pct": 14.2,
72092
+ * "previous": {
72093
+ * "ai": 240,
72094
+ * "agenda_total": 1950,
72095
+ * "share_pct": 12.3
72096
+ * },
72097
+ * "rule": "Citas del período (por la fecha de la cita) que agendó el asistente de Vitrina en una conversación, ÷ todas las citas del período."
72098
+ * },
72099
+ * "money": {
72100
+ * "applies": true,
72101
+ * "withheld": false,
72102
+ * "booked_clp": 11400000,
72103
+ * "booked_priced": 271,
72104
+ * "booked_unpriced": 15,
72105
+ * "agenda_clp": 96000000,
72106
+ * "clp_share_pct": 11.9,
72107
+ * "paid_clp": 7250000,
72108
+ * "paid_patients": 164,
72109
+ * "unlinked": 4,
72110
+ * "regime": "mirror",
72111
+ * "previous": {
72112
+ * "booked_clp": 9800000,
72113
+ * "paid_clp": 6100000
72114
+ * },
72115
+ * "rule_booked": "Valor de las citas que agendó Vitrina: el precio de sus prestaciones, o el del catálogo. Es lo agendado, no lo cobrado.",
72116
+ * "rule_paid": "Pagos recibidos en el período por los pacientes que Vitrina agendó, desde el día en que los agendó."
72117
+ * },
72118
+ * "out_of_hours": {
72119
+ * "configured": true,
72120
+ * "count": 111,
72121
+ * "pct": 38.8,
72122
+ * "previous_pct": 36.1,
72123
+ * "heatmap": [
72124
+ * {
72125
+ * "weekday": 1,
72126
+ * "hour": 21,
72127
+ * "count": 9
72128
+ * },
72129
+ * {
72130
+ * "weekday": 6,
72131
+ * "hour": 11,
72132
+ * "count": 14
72133
+ * }
72134
+ * ],
72135
+ * "rule": "Citas que Vitrina agendó mientras tu negocio estaba cerrado, según tu horario de atención (incluye feriados)."
72136
+ * },
72137
+ * "autonomy": {
72138
+ * "no_human": 158,
72139
+ * "pct": 56.6,
72140
+ * "measured": 279,
72141
+ * "unknown": 7,
72142
+ * "previous_pct": 52,
72143
+ * "rule": "Citas de Vitrina en las que nadie de tu equipo escribió en la conversación antes de agendar."
72144
+ * },
72145
+ * "time_to_book": {
72146
+ * "median_seconds": 734,
72147
+ * "p95_seconds": 80100,
72148
+ * "p95_phrase": "5 de cada 100 personas tardan más de 22 h 15 min en quedar agendadas.",
72149
+ * "measured": 279,
72150
+ * "unknown": 7,
72151
+ * "previous_median_seconds": 910,
72152
+ * "rule": "Tiempo desde el primer mensaje del paciente hasta que su cita quedó agendada (la mediana)."
72153
+ * },
72154
+ * "hours_returned": {
72155
+ * "minutes_per_booking": 10,
72156
+ * "hours": 47.7,
72157
+ * "rule": "Cada cita que agenda Vitrina ahorra 10 minutos de responder y agendar a mano."
72158
+ * },
72159
+ * "recovery": {
72160
+ * "window_days": 30,
72161
+ * "known_attendance": 1063,
72162
+ * "unknown_attendance": 21,
72163
+ * "no_show_pct": 10.2,
72164
+ * "no_show": {
72165
+ * "count": 108,
72166
+ * "recovered": 37,
72167
+ * "recovered_via_vitrina": 17,
72168
+ * "recovered_pct": 34.6,
72169
+ * "via_vitrina_pct": 15.9,
72170
+ * "pending": 12,
72171
+ * "unlinked": 1
72172
+ * },
72173
+ * "cancelled": {
72174
+ * "count": 240,
72175
+ * "recovered": 26,
72176
+ * "recovered_via_vitrina": 11,
72177
+ * "recovered_pct": 10.8,
72178
+ * "via_vitrina_pct": 4.6,
72179
+ * "pending": 18,
72180
+ * "unlinked": 0
72181
+ * },
72182
+ * "rule_no_show": "Citas pasadas marcadas como «no asistió» ÷ citas con asistencia conocida (asistió + no asistió).",
72183
+ * "rule_recovered": "Una cita perdida se recupera cuando el mismo paciente agenda otra dentro de 30 días."
72184
+ * },
72185
+ * "confirmation": {
72186
+ * "applies": true,
72187
+ * "confirmed_attendance_pct": 93.1,
72188
+ * "unconfirmed_attendance_pct": 78.4,
72189
+ * "confirmed_closed": 610,
72190
+ * "unconfirmed_closed": 212,
72191
+ * "rule": "Asistencia de las citas cuyo paciente confirmó el recordatorio, frente a las que nunca respondieron."
72192
+ * },
72193
+ * "ads": {
72194
+ * "state": "active",
72195
+ * "spend_clp": 1648000,
72196
+ * "booked": 58,
72197
+ * "attended": 41,
72198
+ * "paid": 22,
72199
+ * "cost_per_booked": 28414,
72200
+ * "cost_per_attended": 40195,
72201
+ * "cost_per_paid": 74909,
72202
+ * "rule": "Inversión en anuncios del período ÷ citas agendadas, asistidas y pacientes que pagaron por primera vez, según Vitrina Ads para las mismas fechas."
72203
+ * },
72204
+ * "reminders": {
72205
+ * "applies": true,
72206
+ * "sent": 721,
72207
+ * "failed": 120,
72208
+ * "failed_pct": 14.3,
72209
+ * "by_cause": [
72210
+ * {
72211
+ * "cause": "no_whatsapp",
72212
+ * "count": 61
72213
+ * },
72214
+ * {
72215
+ * "cause": "no_phone",
72216
+ * "count": 38
72217
+ * },
72218
+ * {
72219
+ * "cause": "meta_payment_block",
72220
+ * "count": 21
72221
+ * }
72222
+ * ],
72223
+ * "rule": "Recordatorios de citas del período que no salieron, agrupados por la causa que registró el envío."
72224
+ * },
72225
+ * "truncated": false
72226
+ * }
72227
+ * }
72228
+ */
72229
+ "application/json": {
72230
+ data: components["schemas"]["AgendaResults"];
72231
+ };
72232
+ };
72233
+ };
72234
+ /** @description Validation error */
72235
+ 400: {
72236
+ headers: {
72237
+ [name: string]: unknown;
72238
+ };
72239
+ content: {
72240
+ "application/json": components["schemas"]["Error"];
72241
+ };
72242
+ };
72243
+ /** @description Unauthorized */
72244
+ 401: {
72245
+ headers: {
72246
+ [name: string]: unknown;
72247
+ };
72248
+ content: {
72249
+ "application/json": components["schemas"]["Error"];
72250
+ };
72251
+ };
72252
+ /** @description Forbidden */
72253
+ 403: {
72254
+ headers: {
72255
+ [name: string]: unknown;
72256
+ };
72257
+ content: {
72258
+ "application/json": components["schemas"]["Error"];
72259
+ };
72260
+ };
72261
+ /** @description Not found */
72262
+ 404: {
72263
+ headers: {
72264
+ [name: string]: unknown;
72265
+ };
72266
+ content: {
72267
+ "application/json": components["schemas"]["Error"];
72268
+ };
72269
+ };
72270
+ /** @description Conflict (incl. Idempotency-Key reuse with different body) */
72271
+ 409: {
72272
+ headers: {
72273
+ [name: string]: unknown;
72274
+ };
72275
+ content: {
72276
+ "application/json": components["schemas"]["Error"];
72277
+ };
72278
+ };
72279
+ /** @description Rate limited */
72280
+ 429: {
72281
+ headers: {
72282
+ [name: string]: unknown;
72283
+ };
72284
+ content: {
72285
+ "application/json": components["schemas"]["Error"];
72286
+ };
72287
+ };
72288
+ };
72289
+ };
72290
+ put?: never;
72291
+ post?: never;
72292
+ delete?: never;
72293
+ options?: never;
72294
+ head?: never;
72295
+ patch?: never;
72296
+ trace?: never;
72297
+ };
71826
72298
  "/clinic/insights/comercial": {
71827
72299
  parameters: {
71828
72300
  query?: never;
@@ -78644,6 +79116,7 @@ interface paths {
78644
79116
  active?: boolean | null;
78645
79117
  filtered?: boolean | null;
78646
79118
  aiReplied?: boolean | null;
79119
+ fromAd?: boolean | null;
78647
79120
  sort?: "created_at" | "updated_at" | "last_message_date";
78648
79121
  order?: "asc" | "desc";
78649
79122
  include?: "counts";
@@ -92819,7 +93292,7 @@ interface paths {
92819
93292
  patch?: never;
92820
93293
  trace?: never;
92821
93294
  };
92822
- "/insights/overview/live": {
93295
+ "/insights/resultados": {
92823
93296
  parameters: {
92824
93297
  query?: never;
92825
93298
  header?: never;
@@ -92827,19 +93300,26 @@ interface paths {
92827
93300
  cookie?: never;
92828
93301
  };
92829
93302
  /**
92830
- * Current live activity
92831
- * @description A now-snapshot: open conversations, who is waiting, what is in flight. The one report that takes NO range — it describes the present, so `from`/`to` would mean nothing and are not accepted.
93303
+ * What the AI did for the agenda (any vertical)
93304
+ * @description The same facts as `GET /clinic/insights/resultados`, for any vertical, with the vertical's vocabulary (`family`: a dealer reads visits and test drives, `clientes`). Blocks with no data for the vertical come back `applies: false` (money, confirmation, reminders for a dealer) rather than as zeros. Aggregates only. Requires `analytics:read`; CLP figures additionally require `clinic_money:read`. Accepts `from` / `to` (bare `YYYY-MM-DD`, `to` inclusive; default the 90 days ending today) and `location_id`.
92832
93305
  */
92833
93306
  get: {
92834
93307
  parameters: {
92835
- query?: never;
93308
+ query?: {
93309
+ /** @description First day of the window (by the day the cita happens), inclusive. Defaults to 90 days before `to`. */
93310
+ from?: string;
93311
+ /** @description Last day of the window, INCLUSIVE. Defaults to today in the clinic's zone. */
93312
+ to?: string;
93313
+ /** @description One sucursal. Omit for all of them. */
93314
+ location_id?: string;
93315
+ };
92836
93316
  header?: never;
92837
93317
  path?: never;
92838
93318
  cookie?: never;
92839
93319
  };
92840
93320
  requestBody?: never;
92841
93321
  responses: {
92842
- /** @description Live activity snapshot */
93322
+ /** @description Tu día con Vitrina */
92843
93323
  200: {
92844
93324
  headers: {
92845
93325
  [name: string]: unknown;
@@ -92848,28 +93328,158 @@ interface paths {
92848
93328
  /**
92849
93329
  * @example {
92850
93330
  * "data": {
92851
- * "open": 14,
92852
- * "unattended": 0,
92853
- * "unassigned": 1,
92854
- * "pending": 0,
92855
- * "agents_online": 1,
92856
- * "agents_busy": 0,
92857
- * "agents_offline": 4
92858
- * },
92859
- * "meta": {
92860
- * "window": {
92861
- * "kind": "instant",
92862
- * "at": "2026-09-22T16:38:43.071Z",
92863
- * "label": "ahora"
92864
- * }
93331
+ * "from": "2026-07-01",
93332
+ * "to": "2026-09-28",
93333
+ * "timezone": "America/Santiago",
93334
+ * "location_id": null,
93335
+ * "family": "clinic",
93336
+ * "previous_period": {
93337
+ * "from": "2026-04-02",
93338
+ * "to": "2026-06-30"
93339
+ * },
93340
+ * "bookings": {
93341
+ * "ai": 286,
93342
+ * "agenda_total": 2011,
93343
+ * "share_pct": 14.2,
93344
+ * "previous": {
93345
+ * "ai": 240,
93346
+ * "agenda_total": 1950,
93347
+ * "share_pct": 12.3
93348
+ * },
93349
+ * "rule": "Citas del período (por la fecha de la cita) que agendó el asistente de Vitrina en una conversación, ÷ todas las citas del período."
93350
+ * },
93351
+ * "money": {
93352
+ * "applies": true,
93353
+ * "withheld": false,
93354
+ * "booked_clp": 11400000,
93355
+ * "booked_priced": 271,
93356
+ * "booked_unpriced": 15,
93357
+ * "agenda_clp": 96000000,
93358
+ * "clp_share_pct": 11.9,
93359
+ * "paid_clp": 7250000,
93360
+ * "paid_patients": 164,
93361
+ * "unlinked": 4,
93362
+ * "regime": "mirror",
93363
+ * "previous": {
93364
+ * "booked_clp": 9800000,
93365
+ * "paid_clp": 6100000
93366
+ * },
93367
+ * "rule_booked": "Valor de las citas que agendó Vitrina: el precio de sus prestaciones, o el del catálogo. Es lo agendado, no lo cobrado.",
93368
+ * "rule_paid": "Pagos recibidos en el período por los pacientes que Vitrina agendó, desde el día en que los agendó."
93369
+ * },
93370
+ * "out_of_hours": {
93371
+ * "configured": true,
93372
+ * "count": 111,
93373
+ * "pct": 38.8,
93374
+ * "previous_pct": 36.1,
93375
+ * "heatmap": [
93376
+ * {
93377
+ * "weekday": 1,
93378
+ * "hour": 21,
93379
+ * "count": 9
93380
+ * },
93381
+ * {
93382
+ * "weekday": 6,
93383
+ * "hour": 11,
93384
+ * "count": 14
93385
+ * }
93386
+ * ],
93387
+ * "rule": "Citas que Vitrina agendó mientras tu negocio estaba cerrado, según tu horario de atención (incluye feriados)."
93388
+ * },
93389
+ * "autonomy": {
93390
+ * "no_human": 158,
93391
+ * "pct": 56.6,
93392
+ * "measured": 279,
93393
+ * "unknown": 7,
93394
+ * "previous_pct": 52,
93395
+ * "rule": "Citas de Vitrina en las que nadie de tu equipo escribió en la conversación antes de agendar."
93396
+ * },
93397
+ * "time_to_book": {
93398
+ * "median_seconds": 734,
93399
+ * "p95_seconds": 80100,
93400
+ * "p95_phrase": "5 de cada 100 personas tardan más de 22 h 15 min en quedar agendadas.",
93401
+ * "measured": 279,
93402
+ * "unknown": 7,
93403
+ * "previous_median_seconds": 910,
93404
+ * "rule": "Tiempo desde el primer mensaje del paciente hasta que su cita quedó agendada (la mediana)."
93405
+ * },
93406
+ * "hours_returned": {
93407
+ * "minutes_per_booking": 10,
93408
+ * "hours": 47.7,
93409
+ * "rule": "Cada cita que agenda Vitrina ahorra 10 minutos de responder y agendar a mano."
93410
+ * },
93411
+ * "recovery": {
93412
+ * "window_days": 30,
93413
+ * "known_attendance": 1063,
93414
+ * "unknown_attendance": 21,
93415
+ * "no_show_pct": 10.2,
93416
+ * "no_show": {
93417
+ * "count": 108,
93418
+ * "recovered": 37,
93419
+ * "recovered_via_vitrina": 17,
93420
+ * "recovered_pct": 34.6,
93421
+ * "via_vitrina_pct": 15.9,
93422
+ * "pending": 12,
93423
+ * "unlinked": 1
93424
+ * },
93425
+ * "cancelled": {
93426
+ * "count": 240,
93427
+ * "recovered": 26,
93428
+ * "recovered_via_vitrina": 11,
93429
+ * "recovered_pct": 10.8,
93430
+ * "via_vitrina_pct": 4.6,
93431
+ * "pending": 18,
93432
+ * "unlinked": 0
93433
+ * },
93434
+ * "rule_no_show": "Citas pasadas marcadas como «no asistió» ÷ citas con asistencia conocida (asistió + no asistió).",
93435
+ * "rule_recovered": "Una cita perdida se recupera cuando el mismo paciente agenda otra dentro de 30 días."
93436
+ * },
93437
+ * "confirmation": {
93438
+ * "applies": true,
93439
+ * "confirmed_attendance_pct": 93.1,
93440
+ * "unconfirmed_attendance_pct": 78.4,
93441
+ * "confirmed_closed": 610,
93442
+ * "unconfirmed_closed": 212,
93443
+ * "rule": "Asistencia de las citas cuyo paciente confirmó el recordatorio, frente a las que nunca respondieron."
93444
+ * },
93445
+ * "ads": {
93446
+ * "state": "active",
93447
+ * "spend_clp": 1648000,
93448
+ * "booked": 58,
93449
+ * "attended": 41,
93450
+ * "paid": 22,
93451
+ * "cost_per_booked": 28414,
93452
+ * "cost_per_attended": 40195,
93453
+ * "cost_per_paid": 74909,
93454
+ * "rule": "Inversión en anuncios del período ÷ citas agendadas, asistidas y pacientes que pagaron por primera vez, según Vitrina Ads para las mismas fechas."
93455
+ * },
93456
+ * "reminders": {
93457
+ * "applies": true,
93458
+ * "sent": 721,
93459
+ * "failed": 120,
93460
+ * "failed_pct": 14.3,
93461
+ * "by_cause": [
93462
+ * {
93463
+ * "cause": "no_whatsapp",
93464
+ * "count": 61
93465
+ * },
93466
+ * {
93467
+ * "cause": "no_phone",
93468
+ * "count": 38
93469
+ * },
93470
+ * {
93471
+ * "cause": "meta_payment_block",
93472
+ * "count": 21
93473
+ * }
93474
+ * ],
93475
+ * "rule": "Recordatorios de citas del período que no salieron, agrupados por la causa que registró el envío."
93476
+ * },
93477
+ * "truncated": false
92865
93478
  * }
92866
93479
  * }
92867
93480
  */
92868
93481
  "application/json": {
92869
- data?: unknown;
92870
- meta?: {
92871
- [key: string]: unknown;
92872
- };
93482
+ data: components["schemas"]["AgendaResults"];
92873
93483
  };
92874
93484
  };
92875
93485
  };
@@ -92937,7 +93547,7 @@ interface paths {
92937
93547
  patch?: never;
92938
93548
  trace?: never;
92939
93549
  };
92940
- "/insights/overview/heatmap": {
93550
+ "/insights/overview/live": {
92941
93551
  parameters: {
92942
93552
  query?: never;
92943
93553
  header?: never;
@@ -92945,32 +93555,19 @@ interface paths {
92945
93555
  cookie?: never;
92946
93556
  };
92947
93557
  /**
92948
- * Activity heatmap by day and hour
92949
- * @description The only report that accepts `tz`. Pass the viewer’s IANA zone (`America/Santiago`) and the day/hour buckets follow their wall clock; omit it and the grid is UTC, which shifts a Chilean workspace’s busy hours by three or four columns depending on DST. The name is validated by Postgres, so an unknown zone is a 500 rather than a 400.
93558
+ * Current live activity
93559
+ * @description A now-snapshot: open conversations, who is waiting, what is in flight. The one report that takes NO range — it describes the present, so `from`/`to` would mean nothing and are not accepted.
92950
93560
  */
92951
93561
  get: {
92952
93562
  parameters: {
92953
- query?: {
92954
- /** @description Which period. Omit it (with `from`/`to`) for an explicit range — the shape every ranged Insights report has always accepted, and which still works unchanged. The calendar windows are the DEALERSHIP’s (America/Santiago), so a month closes when a person would say it closed. */
92955
- window?: "24h" | "7d" | "30d" | "90d" | "calendar_month" | "calendar_year" | "custom";
92956
- /** @description `window=calendar_month` only. ISO month, `YYYY-MM`. Defaults to the month in progress. */
92957
- month?: string;
92958
- /** @description `window=calendar_year` only. `YYYY`. Defaults to the year in progress. */
92959
- year?: string;
92960
- /** @description Explicit range only. Checked for non-emptiness and handed to Postgres, so a malformed value surfaces as a 500 from the query rather than a 400 from the edge — send an ISO-8601 instant. */
92961
- from?: string;
92962
- /** @description Explicit range only. ISO instant, see `from`. */
92963
- to?: string;
92964
- /** @description IANA timezone for the date/hour buckets. Defaults to UTC. */
92965
- tz?: string;
92966
- };
93563
+ query?: never;
92967
93564
  header?: never;
92968
93565
  path?: never;
92969
93566
  cookie?: never;
92970
93567
  };
92971
93568
  requestBody?: never;
92972
93569
  responses: {
92973
- /** @description Day/hour activity buckets */
93570
+ /** @description Live activity snapshot */
92974
93571
  200: {
92975
93572
  headers: {
92976
93573
  [name: string]: unknown;
@@ -92979,27 +93576,19 @@ interface paths {
92979
93576
  /**
92980
93577
  * @example {
92981
93578
  * "data": {
92982
- * "buckets": [
92983
- * {
92984
- * "day": 1,
92985
- * "hour": 10,
92986
- * "conversations": 3
92987
- * },
92988
- * {
92989
- * "day": 1,
92990
- * "hour": 11,
92991
- * "conversations": 5
92992
- * }
92993
- * ]
93579
+ * "open": 14,
93580
+ * "unattended": 0,
93581
+ * "unassigned": 1,
93582
+ * "pending": 0,
93583
+ * "agents_online": 1,
93584
+ * "agents_busy": 0,
93585
+ * "agents_offline": 4
92994
93586
  * },
92995
93587
  * "meta": {
92996
93588
  * "window": {
92997
- * "kind": "rolling",
92998
- * "preset": "7d",
92999
- * "hours": 168,
93000
- * "from": "2026-09-15T16:38:51.000Z",
93001
- * "to": "2026-09-22T16:38:51.000Z",
93002
- * "label": "últimos 7d"
93589
+ * "kind": "instant",
93590
+ * "at": "2026-09-22T16:38:43.071Z",
93591
+ * "label": "ahora"
93003
93592
  * }
93004
93593
  * }
93005
93594
  * }
@@ -93076,7 +93665,7 @@ interface paths {
93076
93665
  patch?: never;
93077
93666
  trace?: never;
93078
93667
  };
93079
- "/insights/calls": {
93668
+ "/insights/overview/heatmap": {
93080
93669
  parameters: {
93081
93670
  query?: never;
93082
93671
  header?: never;
@@ -93084,8 +93673,8 @@ interface paths {
93084
93673
  cookie?: never;
93085
93674
  };
93086
93675
  /**
93087
- * Voice call statistics
93088
- * @description Voice-channel call stats for the window. Served by the voice insights service rather than the general reporting one, so its shape does not match the other reports.
93676
+ * Activity heatmap by day and hour
93677
+ * @description The only report that accepts `tz`. Pass the viewer’s IANA zone (`America/Santiago`) and the day/hour buckets follow their wall clock; omit it and the grid is UTC, which shifts a Chilean workspace’s busy hours by three or four columns depending on DST. The name is validated by Postgres, so an unknown zone is a 500 rather than a 400.
93089
93678
  */
93090
93679
  get: {
93091
93680
  parameters: {
@@ -93100,6 +93689,8 @@ interface paths {
93100
93689
  from?: string;
93101
93690
  /** @description Explicit range only. ISO instant, see `from`. */
93102
93691
  to?: string;
93692
+ /** @description IANA timezone for the date/hour buckets. Defaults to UTC. */
93693
+ tz?: string;
93103
93694
  };
93104
93695
  header?: never;
93105
93696
  path?: never;
@@ -93107,7 +93698,7 @@ interface paths {
93107
93698
  };
93108
93699
  requestBody?: never;
93109
93700
  responses: {
93110
- /** @description Call statistics */
93701
+ /** @description Day/hour activity buckets */
93111
93702
  200: {
93112
93703
  headers: {
93113
93704
  [name: string]: unknown;
@@ -93116,30 +93707,18 @@ interface paths {
93116
93707
  /**
93117
93708
  * @example {
93118
93709
  * "data": {
93119
- * "range": {
93120
- * "from": "2026-09-15T16:38:51.540Z",
93121
- * "to": "2026-09-22T16:38:51.540Z"
93122
- * },
93123
- * "calls": {
93124
- * "total": 6,
93125
- * "answered": 5,
93126
- * "avg_duration_s": 142,
93127
- * "by_outcome": {
93128
- * "completed": 5,
93129
- * "no_answer": 1
93130
- * },
93131
- * "by_direction": {
93132
- * "inbound": 4,
93133
- * "outbound": 2
93710
+ * "buckets": [
93711
+ * {
93712
+ * "day": 1,
93713
+ * "hour": 10,
93714
+ * "conversations": 3
93134
93715
  * },
93135
- * "by_amd": {}
93136
- * },
93137
- * "latency": {
93138
- * "voice_to_voice": 820,
93139
- * "voice_llm_turn": 410,
93140
- * "voice_llm_first_token": 190,
93141
- * "tool_execution": 260
93142
- * }
93716
+ * {
93717
+ * "day": 1,
93718
+ * "hour": 11,
93719
+ * "conversations": 5
93720
+ * }
93721
+ * ]
93143
93722
  * },
93144
93723
  * "meta": {
93145
93724
  * "window": {
@@ -93225,7 +93804,7 @@ interface paths {
93225
93804
  patch?: never;
93226
93805
  trace?: never;
93227
93806
  };
93228
- "/insights/conversations": {
93807
+ "/insights/calls": {
93229
93808
  parameters: {
93230
93809
  query?: never;
93231
93810
  header?: never;
@@ -93233,8 +93812,8 @@ interface paths {
93233
93812
  cookie?: never;
93234
93813
  };
93235
93814
  /**
93236
- * Conversation volume and resolution
93237
- * @description Volume, resolution and handling time over the window — the top-level view the other reports break down.
93815
+ * Voice call statistics
93816
+ * @description Voice-channel call stats for the window. Served by the voice insights service rather than the general reporting one, so its shape does not match the other reports.
93238
93817
  */
93239
93818
  get: {
93240
93819
  parameters: {
@@ -93256,7 +93835,7 @@ interface paths {
93256
93835
  };
93257
93836
  requestBody?: never;
93258
93837
  responses: {
93259
- /** @description Conversation volume and resolution */
93838
+ /** @description Call statistics */
93260
93839
  200: {
93261
93840
  headers: {
93262
93841
  [name: string]: unknown;
@@ -93265,84 +93844,30 @@ interface paths {
93265
93844
  /**
93266
93845
  * @example {
93267
93846
  * "data": {
93268
- * "conversations": {
93269
- * "total": 18,
93270
- * "delta_pct": 17,
93271
- * "series": [
93272
- * {
93273
- * "bucket": "2026-09-21",
93274
- * "value": 0
93275
- * },
93276
- * {
93277
- * "bucket": "2026-09-22",
93278
- * "value": 18
93279
- * }
93280
- * ]
93281
- * },
93282
- * "messages_in": {
93283
- * "total": 11,
93284
- * "delta_pct": null,
93285
- * "series": [
93286
- * {
93287
- * "bucket": "2026-09-22",
93288
- * "value": 10
93289
- * }
93290
- * ]
93291
- * },
93292
- * "messages_out": {
93293
- * "total": 25,
93294
- * "delta_pct": null,
93295
- * "series": [
93296
- * {
93297
- * "bucket": "2026-09-22",
93298
- * "value": 25
93299
- * }
93300
- * ]
93301
- * },
93302
- * "first_response_seconds": {
93303
- * "avg": 728.65,
93304
- * "delta_pct": null,
93305
- * "series": [
93306
- * {
93307
- * "bucket": "2026-09-22",
93308
- * "value": 728.65
93309
- * }
93310
- * ]
93311
- * },
93312
- * "first_response_p50_seconds": 388.36,
93313
- * "first_response_p90_seconds": 1411.41,
93314
- * "resolution_seconds": {
93315
- * "avg": 9891.67,
93316
- * "delta_pct": -91.3,
93317
- * "series": [
93318
- * {
93319
- * "bucket": "2026-09-22",
93320
- * "value": 9891.67
93321
- * }
93322
- * ]
93323
- * },
93324
- * "resolutions": {
93325
- * "total": 5,
93326
- * "delta_pct": -16.7,
93327
- * "series": [
93328
- * {
93329
- * "bucket": "2026-09-22",
93330
- * "value": 4
93331
- * }
93332
- * ]
93847
+ * "range": {
93848
+ * "from": "2026-09-15T16:38:51.540Z",
93849
+ * "to": "2026-09-22T16:38:51.540Z"
93333
93850
  * },
93334
- * "customer_wait_seconds": {
93335
- * "avg": 728.65,
93336
- * "delta_pct": null,
93337
- * "series": [
93338
- * {
93339
- * "bucket": "2026-09-22",
93340
- * "value": 728.65
93341
- * }
93342
- * ]
93851
+ * "calls": {
93852
+ * "total": 6,
93853
+ * "answered": 5,
93854
+ * "avg_duration_s": 142,
93855
+ * "by_outcome": {
93856
+ * "completed": 5,
93857
+ * "no_answer": 1
93858
+ * },
93859
+ * "by_direction": {
93860
+ * "inbound": 4,
93861
+ * "outbound": 2
93862
+ * },
93863
+ * "by_amd": {}
93343
93864
  * },
93344
- * "facturables": 4,
93345
- * "solo_humano": 14
93865
+ * "latency": {
93866
+ * "voice_to_voice": 820,
93867
+ * "voice_llm_turn": 410,
93868
+ * "voice_llm_first_token": 190,
93869
+ * "tool_execution": 260
93870
+ * }
93346
93871
  * },
93347
93872
  * "meta": {
93348
93873
  * "window": {
@@ -93428,7 +93953,7 @@ interface paths {
93428
93953
  patch?: never;
93429
93954
  trace?: never;
93430
93955
  };
93431
- "/insights/agents": {
93956
+ "/insights/conversations": {
93432
93957
  parameters: {
93433
93958
  query?: never;
93434
93959
  header?: never;
@@ -93436,8 +93961,8 @@ interface paths {
93436
93961
  cookie?: never;
93437
93962
  };
93438
93963
  /**
93439
- * Human agent performance
93440
- * @description Per-human-agent throughput and response times. `/insights/ai-agents` is the machine-side counterpart; the two are not comparable row for row, because a human is assigned a conversation and an AI agent runs turns within one.
93964
+ * Conversation volume and resolution
93965
+ * @description Volume, resolution and handling time over the window — the top-level view the other reports break down.
93441
93966
  */
93442
93967
  get: {
93443
93968
  parameters: {
@@ -93459,7 +93984,7 @@ interface paths {
93459
93984
  };
93460
93985
  requestBody?: never;
93461
93986
  responses: {
93462
- /** @description Human agent performance */
93987
+ /** @description Conversation volume and resolution */
93463
93988
  200: {
93464
93989
  headers: {
93465
93990
  [name: string]: unknown;
@@ -93467,20 +93992,86 @@ interface paths {
93467
93992
  content: {
93468
93993
  /**
93469
93994
  * @example {
93470
- * "data": [
93471
- * {
93472
- * "user_id": "11111111-0000-4000-8000-000000000001",
93473
- * "name": "Carolina Muñoz",
93474
- * "email": "carolina@example.cl",
93475
- * "conversations": 8,
93476
- * "replies": 5,
93477
- * "avg_first_response_seconds": 733.76,
93478
- * "avg_response_seconds": 28197.49,
93479
- * "avg_resolution_seconds": 9891.67,
93480
- * "avg_customer_wait_seconds": 733.76,
93481
- * "resolutions": 4
93482
- * }
93483
- * ],
93995
+ * "data": {
93996
+ * "conversations": {
93997
+ * "total": 18,
93998
+ * "delta_pct": 17,
93999
+ * "series": [
94000
+ * {
94001
+ * "bucket": "2026-09-21",
94002
+ * "value": 0
94003
+ * },
94004
+ * {
94005
+ * "bucket": "2026-09-22",
94006
+ * "value": 18
94007
+ * }
94008
+ * ]
94009
+ * },
94010
+ * "messages_in": {
94011
+ * "total": 11,
94012
+ * "delta_pct": null,
94013
+ * "series": [
94014
+ * {
94015
+ * "bucket": "2026-09-22",
94016
+ * "value": 10
94017
+ * }
94018
+ * ]
94019
+ * },
94020
+ * "messages_out": {
94021
+ * "total": 25,
94022
+ * "delta_pct": null,
94023
+ * "series": [
94024
+ * {
94025
+ * "bucket": "2026-09-22",
94026
+ * "value": 25
94027
+ * }
94028
+ * ]
94029
+ * },
94030
+ * "first_response_seconds": {
94031
+ * "avg": 728.65,
94032
+ * "delta_pct": null,
94033
+ * "series": [
94034
+ * {
94035
+ * "bucket": "2026-09-22",
94036
+ * "value": 728.65
94037
+ * }
94038
+ * ]
94039
+ * },
94040
+ * "first_response_p50_seconds": 388.36,
94041
+ * "first_response_p90_seconds": 1411.41,
94042
+ * "resolution_seconds": {
94043
+ * "avg": 9891.67,
94044
+ * "delta_pct": -91.3,
94045
+ * "series": [
94046
+ * {
94047
+ * "bucket": "2026-09-22",
94048
+ * "value": 9891.67
94049
+ * }
94050
+ * ]
94051
+ * },
94052
+ * "resolutions": {
94053
+ * "total": 5,
94054
+ * "delta_pct": -16.7,
94055
+ * "series": [
94056
+ * {
94057
+ * "bucket": "2026-09-22",
94058
+ * "value": 4
94059
+ * }
94060
+ * ]
94061
+ * },
94062
+ * "customer_wait_seconds": {
94063
+ * "avg": 728.65,
94064
+ * "delta_pct": null,
94065
+ * "series": [
94066
+ * {
94067
+ * "bucket": "2026-09-22",
94068
+ * "value": 728.65
94069
+ * }
94070
+ * ]
94071
+ * },
94072
+ * "facturables": 4,
94073
+ * "solo_humano": 14
94074
+ * },
93484
94075
  * "meta": {
93485
94076
  * "window": {
93486
94077
  * "kind": "rolling",
@@ -93565,7 +94156,7 @@ interface paths {
93565
94156
  patch?: never;
93566
94157
  trace?: never;
93567
94158
  };
93568
- "/insights/ai-agents": {
94159
+ "/insights/agents": {
93569
94160
  parameters: {
93570
94161
  query?: never;
93571
94162
  header?: never;
@@ -93573,8 +94164,8 @@ interface paths {
93573
94164
  cookie?: never;
93574
94165
  };
93575
94166
  /**
93576
- * Per-AI-agent performance breakdown
93577
- * @description One row per `ai_agent`. `/insights/bots` answers the same question in aggregate — use that for a single headline number and this to find which agent moved it.
94167
+ * Human agent performance
94168
+ * @description Per-human-agent throughput and response times. `/insights/ai-agents` is the machine-side counterpart; the two are not comparable row for row, because a human is assigned a conversation and an AI agent runs turns within one.
93578
94169
  */
93579
94170
  get: {
93580
94171
  parameters: {
@@ -93596,7 +94187,7 @@ interface paths {
93596
94187
  };
93597
94188
  requestBody?: never;
93598
94189
  responses: {
93599
- /** @description Per-AI-agent performance breakdown */
94190
+ /** @description Human agent performance */
93600
94191
  200: {
93601
94192
  headers: {
93602
94193
  [name: string]: unknown;
@@ -93606,22 +94197,16 @@ interface paths {
93606
94197
  * @example {
93607
94198
  * "data": [
93608
94199
  * {
93609
- * "ai_agent_id": "a3a3a3a3-0000-4000-8000-000000000001",
93610
- * "name": "Asistente de ventas",
93611
- * "status": "active",
93612
- * "is_default": true,
93613
- * "conversations": 12,
93614
- * "responses": 30,
93615
- * "avg_response_seconds": 4.2,
93616
- * "automated_conversations": 8,
93617
- * "handoffs": 2,
93618
- * "resolutions": 4,
93619
- * "tool_calls": 21,
93620
- * "cost_usd": 0.0508,
93621
- * "tokens": 322522,
93622
- * "avg_gen_latency_ms": 7938,
93623
- * "handoffs_requested": 2,
93624
- * "handoffs_answered": 2
94200
+ * "user_id": "11111111-0000-4000-8000-000000000001",
94201
+ * "name": "Carolina Muñoz",
94202
+ * "email": "carolina@example.cl",
94203
+ * "conversations": 8,
94204
+ * "replies": 5,
94205
+ * "avg_first_response_seconds": 733.76,
94206
+ * "avg_response_seconds": 28197.49,
94207
+ * "avg_resolution_seconds": 9891.67,
94208
+ * "avg_customer_wait_seconds": 733.76,
94209
+ * "resolutions": 4
93625
94210
  * }
93626
94211
  * ],
93627
94212
  * "meta": {
@@ -93708,7 +94293,7 @@ interface paths {
93708
94293
  patch?: never;
93709
94294
  trace?: never;
93710
94295
  };
93711
- "/insights/bots": {
94296
+ "/insights/ai-agents": {
93712
94297
  parameters: {
93713
94298
  query?: never;
93714
94299
  header?: never;
@@ -93716,8 +94301,8 @@ interface paths {
93716
94301
  cookie?: never;
93717
94302
  };
93718
94303
  /**
93719
- * Aggregate AI handling
93720
- * @description AI handling across the workspace as one figure, not split by agent. The aggregate counterpart to `/insights/ai-agents`.
94304
+ * Per-AI-agent performance breakdown
94305
+ * @description One row per `ai_agent`. `/insights/bots` answers the same question in aggregate — use that for a single headline number and this to find which agent moved it.
93721
94306
  */
93722
94307
  get: {
93723
94308
  parameters: {
@@ -93739,7 +94324,7 @@ interface paths {
93739
94324
  };
93740
94325
  requestBody?: never;
93741
94326
  responses: {
93742
- /** @description Aggregate AI handling */
94327
+ /** @description Per-AI-agent performance breakdown */
93743
94328
  200: {
93744
94329
  headers: {
93745
94330
  [name: string]: unknown;
@@ -93747,43 +94332,26 @@ interface paths {
93747
94332
  content: {
93748
94333
  /**
93749
94334
  * @example {
93750
- * "data": {
93751
- * "conversations": 12,
93752
- * "automated_conversations": 8,
93753
- * "total_conversations": 18,
93754
- * "engaged_conversations": 11,
93755
- * "deflection_rate": 0.44,
93756
- * "total_responses": 30,
93757
- * "avg_response_seconds": 4.2,
93758
- * "resolutions": 4,
93759
- * "handoff_rate": 0.17,
93760
- * "resolved_by_bot": 3,
93761
- * "resolved_by_human": 1,
93762
- * "resolved_by_auto": 0,
93763
- * "cost_usd": 0.0508,
93764
- * "cost_per_conversation": 0.0042,
93765
- * "tokens": 322522,
93766
- * "avg_gen_latency_ms": 7938,
93767
- * "tool_calls": 21,
93768
- * "resolutions_series": [
93769
- * {
93770
- * "bucket": "2026-09-22",
93771
- * "value": 3
93772
- * }
93773
- * ],
93774
- * "handoff_series": [
93775
- * {
93776
- * "bucket": "2026-09-22",
93777
- * "value": 1
93778
- * }
93779
- * ],
93780
- * "cost_series": [
93781
- * {
93782
- * "bucket": "2026-09-22",
93783
- * "value": 0.0064
93784
- * }
93785
- * ]
93786
- * },
94335
+ * "data": [
94336
+ * {
94337
+ * "ai_agent_id": "a3a3a3a3-0000-4000-8000-000000000001",
94338
+ * "name": "Asistente de ventas",
94339
+ * "status": "active",
94340
+ * "is_default": true,
94341
+ * "conversations": 12,
94342
+ * "responses": 30,
94343
+ * "avg_response_seconds": 4.2,
94344
+ * "automated_conversations": 8,
94345
+ * "handoffs": 2,
94346
+ * "resolutions": 4,
94347
+ * "tool_calls": 21,
94348
+ * "cost_usd": 0.0508,
94349
+ * "tokens": 322522,
94350
+ * "avg_gen_latency_ms": 7938,
94351
+ * "handoffs_requested": 2,
94352
+ * "handoffs_answered": 2
94353
+ * }
94354
+ * ],
93787
94355
  * "meta": {
93788
94356
  * "window": {
93789
94357
  * "kind": "rolling",
@@ -93868,7 +94436,7 @@ interface paths {
93868
94436
  patch?: never;
93869
94437
  trace?: never;
93870
94438
  };
93871
- "/insights/tags": {
94439
+ "/insights/bots": {
93872
94440
  parameters: {
93873
94441
  query?: never;
93874
94442
  header?: never;
@@ -93876,8 +94444,8 @@ interface paths {
93876
94444
  cookie?: never;
93877
94445
  };
93878
94446
  /**
93879
- * Volume by tag
93880
- * @description Conversation counts grouped by the tags applied to them.
94447
+ * Aggregate AI handling
94448
+ * @description AI handling across the workspace as one figure, not split by agent. The aggregate counterpart to `/insights/ai-agents`.
93881
94449
  */
93882
94450
  get: {
93883
94451
  parameters: {
@@ -93899,7 +94467,7 @@ interface paths {
93899
94467
  };
93900
94468
  requestBody?: never;
93901
94469
  responses: {
93902
- /** @description Volume by tag */
94470
+ /** @description Aggregate AI handling */
93903
94471
  200: {
93904
94472
  headers: {
93905
94473
  [name: string]: unknown;
@@ -93907,26 +94475,43 @@ interface paths {
93907
94475
  content: {
93908
94476
  /**
93909
94477
  * @example {
93910
- * "data": [
93911
- * {
93912
- * "key": "__none__",
93913
- * "label": "Sin etiqueta",
93914
- * "conversations": 17,
93915
- * "avg_first_response_seconds": 728.65,
93916
- * "avg_resolution_seconds": 9891.67,
93917
- * "avg_customer_wait_seconds": 728.65,
93918
- * "resolutions": 4
93919
- * },
93920
- * {
93921
- * "key": "e1e1e1e1-9000-4000-8000-000000000001",
93922
- * "label": "garantia",
93923
- * "conversations": 1,
93924
- * "avg_first_response_seconds": 0,
93925
- * "avg_resolution_seconds": 0,
93926
- * "avg_customer_wait_seconds": 0,
93927
- * "resolutions": 0
93928
- * }
93929
- * ],
94478
+ * "data": {
94479
+ * "conversations": 12,
94480
+ * "automated_conversations": 8,
94481
+ * "total_conversations": 18,
94482
+ * "engaged_conversations": 11,
94483
+ * "deflection_rate": 0.44,
94484
+ * "total_responses": 30,
94485
+ * "avg_response_seconds": 4.2,
94486
+ * "resolutions": 4,
94487
+ * "handoff_rate": 0.17,
94488
+ * "resolved_by_bot": 3,
94489
+ * "resolved_by_human": 1,
94490
+ * "resolved_by_auto": 0,
94491
+ * "cost_usd": 0.0508,
94492
+ * "cost_per_conversation": 0.0042,
94493
+ * "tokens": 322522,
94494
+ * "avg_gen_latency_ms": 7938,
94495
+ * "tool_calls": 21,
94496
+ * "resolutions_series": [
94497
+ * {
94498
+ * "bucket": "2026-09-22",
94499
+ * "value": 3
94500
+ * }
94501
+ * ],
94502
+ * "handoff_series": [
94503
+ * {
94504
+ * "bucket": "2026-09-22",
94505
+ * "value": 1
94506
+ * }
94507
+ * ],
94508
+ * "cost_series": [
94509
+ * {
94510
+ * "bucket": "2026-09-22",
94511
+ * "value": 0.0064
94512
+ * }
94513
+ * ]
94514
+ * },
93930
94515
  * "meta": {
93931
94516
  * "window": {
93932
94517
  * "kind": "rolling",
@@ -94011,7 +94596,7 @@ interface paths {
94011
94596
  patch?: never;
94012
94597
  trace?: never;
94013
94598
  };
94014
- "/insights/channels": {
94599
+ "/insights/tags": {
94015
94600
  parameters: {
94016
94601
  query?: never;
94017
94602
  header?: never;
@@ -94019,8 +94604,8 @@ interface paths {
94019
94604
  cookie?: never;
94020
94605
  };
94021
94606
  /**
94022
- * Volume by channel
94023
- * @description Grouped by messaging channel (WhatsApp, Instagram, email, voice, …), so a channel with no traffic in the window is simply absent rather than present with a zero.
94607
+ * Volume by tag
94608
+ * @description Conversation counts grouped by the tags applied to them.
94024
94609
  */
94025
94610
  get: {
94026
94611
  parameters: {
@@ -94042,7 +94627,7 @@ interface paths {
94042
94627
  };
94043
94628
  requestBody?: never;
94044
94629
  responses: {
94045
- /** @description Volume by channel */
94630
+ /** @description Volume by tag */
94046
94631
  200: {
94047
94632
  headers: {
94048
94633
  [name: string]: unknown;
@@ -94052,18 +94637,18 @@ interface paths {
94052
94637
  * @example {
94053
94638
  * "data": [
94054
94639
  * {
94055
- * "key": "00000000-0000-4000-8000-000000005001",
94056
- * "label": "WhatsApp · Acme",
94057
- * "conversations": 5,
94058
- * "avg_first_response_seconds": 450.43,
94059
- * "avg_resolution_seconds": 101.4,
94060
- * "avg_customer_wait_seconds": 450.43,
94061
- * "resolutions": 1
94640
+ * "key": "__none__",
94641
+ * "label": "Sin etiqueta",
94642
+ * "conversations": 17,
94643
+ * "avg_first_response_seconds": 728.65,
94644
+ * "avg_resolution_seconds": 9891.67,
94645
+ * "avg_customer_wait_seconds": 728.65,
94646
+ * "resolutions": 4
94062
94647
  * },
94063
94648
  * {
94064
- * "key": "__none__",
94065
- * "label": "Directo / sin canal",
94066
- * "conversations": 4,
94649
+ * "key": "e1e1e1e1-9000-4000-8000-000000000001",
94650
+ * "label": "garantia",
94651
+ * "conversations": 1,
94067
94652
  * "avg_first_response_seconds": 0,
94068
94653
  * "avg_resolution_seconds": 0,
94069
94654
  * "avg_customer_wait_seconds": 0,
@@ -94154,7 +94739,7 @@ interface paths {
94154
94739
  patch?: never;
94155
94740
  trace?: never;
94156
94741
  };
94157
- "/insights/teams": {
94742
+ "/insights/channels": {
94158
94743
  parameters: {
94159
94744
  query?: never;
94160
94745
  header?: never;
@@ -94162,8 +94747,8 @@ interface paths {
94162
94747
  cookie?: never;
94163
94748
  };
94164
94749
  /**
94165
- * Volume by team
94166
- * @description Conversation counts grouped by the team they were routed to.
94750
+ * Volume by channel
94751
+ * @description Grouped by messaging channel (WhatsApp, Instagram, email, voice, …), so a channel with no traffic in the window is simply absent rather than present with a zero.
94167
94752
  */
94168
94753
  get: {
94169
94754
  parameters: {
@@ -94185,7 +94770,7 @@ interface paths {
94185
94770
  };
94186
94771
  requestBody?: never;
94187
94772
  responses: {
94188
- /** @description Volume by team */
94773
+ /** @description Volume by channel */
94189
94774
  200: {
94190
94775
  headers: {
94191
94776
  [name: string]: unknown;
@@ -94195,18 +94780,18 @@ interface paths {
94195
94780
  * @example {
94196
94781
  * "data": [
94197
94782
  * {
94198
- * "key": "__none__",
94199
- * "label": "Sin equipo",
94200
- * "conversations": 18,
94201
- * "avg_first_response_seconds": 728.65,
94202
- * "avg_resolution_seconds": 9891.67,
94203
- * "avg_customer_wait_seconds": 728.65,
94204
- * "resolutions": 4
94783
+ * "key": "00000000-0000-4000-8000-000000005001",
94784
+ * "label": "WhatsApp · Acme",
94785
+ * "conversations": 5,
94786
+ * "avg_first_response_seconds": 450.43,
94787
+ * "avg_resolution_seconds": 101.4,
94788
+ * "avg_customer_wait_seconds": 450.43,
94789
+ * "resolutions": 1
94205
94790
  * },
94206
94791
  * {
94207
- * "key": "cccccccc-0000-4000-8000-000000000001",
94208
- * "label": "Marketing",
94209
- * "conversations": 0,
94792
+ * "key": "__none__",
94793
+ * "label": "Directo / sin canal",
94794
+ * "conversations": 4,
94210
94795
  * "avg_first_response_seconds": 0,
94211
94796
  * "avg_resolution_seconds": 0,
94212
94797
  * "avg_customer_wait_seconds": 0,
@@ -94297,7 +94882,7 @@ interface paths {
94297
94882
  patch?: never;
94298
94883
  trace?: never;
94299
94884
  };
94300
- "/insights/sources": {
94885
+ "/insights/teams": {
94301
94886
  parameters: {
94302
94887
  query?: never;
94303
94888
  header?: never;
@@ -94305,8 +94890,8 @@ interface paths {
94305
94890
  cookie?: never;
94306
94891
  };
94307
94892
  /**
94308
- * Volume by origin
94309
- * @description The same row shape as `/insights/channels`, grouped by where the conversation CAME FROM (`mercadolibre`, `yapo`, `chileautos`, `ai_agent`, `website`, …) rather than which messaging account it rode in on. The two are not interchangeable: marketplace leads all arrive on the same WhatsApp number, so `/insights/channels` collapses every paid origin into one row. Unlike channels there is no catalogue to zero-fill from, so an origin with no traffic is absent rather than present with a zero; `__none__` is the no-origin bucket.
94893
+ * Volume by team
94894
+ * @description Conversation counts grouped by the team they were routed to.
94310
94895
  */
94311
94896
  get: {
94312
94897
  parameters: {
@@ -94328,7 +94913,7 @@ interface paths {
94328
94913
  };
94329
94914
  requestBody?: never;
94330
94915
  responses: {
94331
- /** @description Volume by origin */
94916
+ /** @description Volume by team */
94332
94917
  200: {
94333
94918
  headers: {
94334
94919
  [name: string]: unknown;
@@ -94339,17 +94924,17 @@ interface paths {
94339
94924
  * "data": [
94340
94925
  * {
94341
94926
  * "key": "__none__",
94342
- * "label": "Directo / sin origen",
94343
- * "conversations": 14,
94927
+ * "label": "Sin equipo",
94928
+ * "conversations": 18,
94344
94929
  * "avg_first_response_seconds": 728.65,
94345
94930
  * "avg_resolution_seconds": 9891.67,
94346
94931
  * "avg_customer_wait_seconds": 728.65,
94347
94932
  * "resolutions": 4
94348
94933
  * },
94349
94934
  * {
94350
- * "key": "website",
94351
- * "label": "Sitio web",
94352
- * "conversations": 4,
94935
+ * "key": "cccccccc-0000-4000-8000-000000000001",
94936
+ * "label": "Marketing",
94937
+ * "conversations": 0,
94353
94938
  * "avg_first_response_seconds": 0,
94354
94939
  * "avg_resolution_seconds": 0,
94355
94940
  * "avg_customer_wait_seconds": 0,
@@ -94440,7 +95025,7 @@ interface paths {
94440
95025
  patch?: never;
94441
95026
  trace?: never;
94442
95027
  };
94443
- "/insights/leads": {
95028
+ "/insights/sources": {
94444
95029
  parameters: {
94445
95030
  query?: never;
94446
95031
  header?: never;
@@ -94448,8 +95033,8 @@ interface paths {
94448
95033
  cookie?: never;
94449
95034
  };
94450
95035
  /**
94451
- * Lead capture
94452
- * @description Leads created over the window and where they came from.
95036
+ * Volume by origin
95037
+ * @description The same row shape as `/insights/channels`, grouped by where the conversation CAME FROM (`mercadolibre`, `yapo`, `chileautos`, `ai_agent`, `website`, …) rather than which messaging account it rode in on. The two are not interchangeable: marketplace leads all arrive on the same WhatsApp number, so `/insights/channels` collapses every paid origin into one row. Unlike channels there is no catalogue to zero-fill from, so an origin with no traffic is absent rather than present with a zero; `__none__` is the no-origin bucket.
94453
95038
  */
94454
95039
  get: {
94455
95040
  parameters: {
@@ -94471,7 +95056,7 @@ interface paths {
94471
95056
  };
94472
95057
  requestBody?: never;
94473
95058
  responses: {
94474
- /** @description Lead capture */
95059
+ /** @description Volume by origin */
94475
95060
  200: {
94476
95061
  headers: {
94477
95062
  [name: string]: unknown;
@@ -94479,60 +95064,26 @@ interface paths {
94479
95064
  content: {
94480
95065
  /**
94481
95066
  * @example {
94482
- * "data": {
94483
- * "open": 16,
94484
- * "won": 2,
94485
- * "lost": 1,
94486
- * "unqualified": 0,
94487
- * "total_value_open": 19407775,
94488
- * "total_value_won": 4500000,
94489
- * "total_value_open_by_currency": {
94490
- * "CLP": 19399000
94491
- * },
94492
- * "total_value_won_by_currency": {
94493
- * "CLP": 4500000
95067
+ * "data": [
95068
+ * {
95069
+ * "key": "__none__",
95070
+ * "label": "Directo / sin origen",
95071
+ * "conversations": 14,
95072
+ * "avg_first_response_seconds": 728.65,
95073
+ * "avg_resolution_seconds": 9891.67,
95074
+ * "avg_customer_wait_seconds": 728.65,
95075
+ * "resolutions": 4
94494
95076
  * },
94495
- * "is_mixed_currency": false,
94496
- * "is_mixed_currency_open": false,
94497
- * "win_rate": 0.67,
94498
- * "avg_cycle_seconds": 432000,
94499
- * "created_series": [
94500
- * {
94501
- * "bucket": "2026-09-22",
94502
- * "value": 6
94503
- * }
94504
- * ],
94505
- * "won_series": [
94506
- * {
94507
- * "bucket": "2026-09-22",
94508
- * "value": 1
94509
- * }
94510
- * ],
94511
- * "revenue_series": [
94512
- * {
94513
- * "bucket": "2026-09-22",
94514
- * "value": 4500000,
94515
- * "value_by_currency": {
94516
- * "CLP": 4500000
94517
- * },
94518
- * "is_mixed_currency": false
94519
- * }
94520
- * ],
94521
- * "funnel": [
94522
- * {
94523
- * "stage_id": "55555555-0000-4000-8000-000000000001",
94524
- * "stage_name": "Nuevo",
94525
- * "position": 0,
94526
- * "open_count": 9,
94527
- * "total_value": 19401030,
94528
- * "total_value_by_currency": {
94529
- * "CLP": 19399000
94530
- * },
94531
- * "is_mixed_currency": false,
94532
- * "median_time_in_stage_hours": 6.5
94533
- * }
94534
- * ]
94535
- * },
95077
+ * {
95078
+ * "key": "website",
95079
+ * "label": "Sitio web",
95080
+ * "conversations": 4,
95081
+ * "avg_first_response_seconds": 0,
95082
+ * "avg_resolution_seconds": 0,
95083
+ * "avg_customer_wait_seconds": 0,
95084
+ * "resolutions": 0
95085
+ * }
95086
+ * ],
94536
95087
  * "meta": {
94537
95088
  * "window": {
94538
95089
  * "kind": "rolling",
@@ -94617,7 +95168,7 @@ interface paths {
94617
95168
  patch?: never;
94618
95169
  trace?: never;
94619
95170
  };
94620
- "/insights/csat": {
95171
+ "/insights/leads": {
94621
95172
  parameters: {
94622
95173
  query?: never;
94623
95174
  header?: never;
@@ -94625,8 +95176,8 @@ interface paths {
94625
95176
  cookie?: never;
94626
95177
  };
94627
95178
  /**
94628
- * Estimated satisfaction
94629
- * @description CSAT is AI-ESTIMATED from the conversation, not collected from a survey — no customer was asked to rate anything. Read it as a model judgement about tone and outcome, which is why it exists for every conversation rather than the small fraction that would answer a survey.
95179
+ * Lead capture
95180
+ * @description Leads created over the window and where they came from.
94630
95181
  */
94631
95182
  get: {
94632
95183
  parameters: {
@@ -94648,7 +95199,7 @@ interface paths {
94648
95199
  };
94649
95200
  requestBody?: never;
94650
95201
  responses: {
94651
- /** @description Estimated satisfaction */
95202
+ /** @description Lead capture */
94652
95203
  200: {
94653
95204
  headers: {
94654
95205
  [name: string]: unknown;
@@ -94657,27 +95208,58 @@ interface paths {
94657
95208
  /**
94658
95209
  * @example {
94659
95210
  * "data": {
94660
- * "total_responses": 9,
94661
- * "satisfaction_score": 0.82,
94662
- * "response_rate": 0.5,
94663
- * "positive": 7,
94664
- * "neutral": 1,
94665
- * "negative": 1,
94666
- * "recommend_rate": 0.78,
94667
- * "avg_confidence": 0.9,
94668
- * "review_requests_sent": 18,
94669
- * "resolved_tickets": 5,
94670
- * "distribution": {
94671
- * "positive": 7,
94672
- * "neutral": 1,
94673
- * "negative": 1
95211
+ * "open": 16,
95212
+ * "won": 2,
95213
+ * "lost": 1,
95214
+ * "unqualified": 0,
95215
+ * "total_value_open": 19407775,
95216
+ * "total_value_won": 4500000,
95217
+ * "total_value_open_by_currency": {
95218
+ * "CLP": 19399000
94674
95219
  * },
94675
- * "resolution_quality": {
94676
- * "good": 8,
94677
- * "poor": 1
95220
+ * "total_value_won_by_currency": {
95221
+ * "CLP": 4500000
94678
95222
  * },
94679
- * "agent_performance": {},
94680
- * "recent": []
95223
+ * "is_mixed_currency": false,
95224
+ * "is_mixed_currency_open": false,
95225
+ * "win_rate": 0.67,
95226
+ * "avg_cycle_seconds": 432000,
95227
+ * "created_series": [
95228
+ * {
95229
+ * "bucket": "2026-09-22",
95230
+ * "value": 6
95231
+ * }
95232
+ * ],
95233
+ * "won_series": [
95234
+ * {
95235
+ * "bucket": "2026-09-22",
95236
+ * "value": 1
95237
+ * }
95238
+ * ],
95239
+ * "revenue_series": [
95240
+ * {
95241
+ * "bucket": "2026-09-22",
95242
+ * "value": 4500000,
95243
+ * "value_by_currency": {
95244
+ * "CLP": 4500000
95245
+ * },
95246
+ * "is_mixed_currency": false
95247
+ * }
95248
+ * ],
95249
+ * "funnel": [
95250
+ * {
95251
+ * "stage_id": "55555555-0000-4000-8000-000000000001",
95252
+ * "stage_name": "Nuevo",
95253
+ * "position": 0,
95254
+ * "open_count": 9,
95255
+ * "total_value": 19401030,
95256
+ * "total_value_by_currency": {
95257
+ * "CLP": 19399000
95258
+ * },
95259
+ * "is_mixed_currency": false,
95260
+ * "median_time_in_stage_hours": 6.5
95261
+ * }
95262
+ * ]
94681
95263
  * },
94682
95264
  * "meta": {
94683
95265
  * "window": {
@@ -94763,7 +95345,7 @@ interface paths {
94763
95345
  patch?: never;
94764
95346
  trace?: never;
94765
95347
  };
94766
- "/insights/sla": {
95348
+ "/insights/csat": {
94767
95349
  parameters: {
94768
95350
  query?: never;
94769
95351
  header?: never;
@@ -94771,8 +95353,8 @@ interface paths {
94771
95353
  cookie?: never;
94772
95354
  };
94773
95355
  /**
94774
- * SLA compliance
94775
- * @description Breach and compliance counts against the workspace SLA policies. A window with no policy configured reports nothing to comply with, not full compliance.
95356
+ * Estimated satisfaction
95357
+ * @description CSAT is AI-ESTIMATED from the conversation, not collected from a survey — no customer was asked to rate anything. Read it as a model judgement about tone and outcome, which is why it exists for every conversation rather than the small fraction that would answer a survey.
94776
95358
  */
94777
95359
  get: {
94778
95360
  parameters: {
@@ -94794,7 +95376,7 @@ interface paths {
94794
95376
  };
94795
95377
  requestBody?: never;
94796
95378
  responses: {
94797
- /** @description SLA compliance */
95379
+ /** @description Estimated satisfaction */
94798
95380
  200: {
94799
95381
  headers: {
94800
95382
  [name: string]: unknown;
@@ -94803,32 +95385,178 @@ interface paths {
94803
95385
  /**
94804
95386
  * @example {
94805
95387
  * "data": {
94806
- * "has_policies": true,
94807
- * "policy_count": 2,
94808
- * "target_first_response_minutes": 15,
94809
- * "target_resolution_minutes": 480,
94810
- * "tracked": 18,
94811
- * "breached": 2,
94812
- * "hits": 16,
94813
- * "hit_rate": 0.89,
94814
- * "first_response": {
94815
- * "evaluated": 18,
94816
- * "breached": 1,
94817
- * "hit_rate": 0.94
95388
+ * "total_responses": 9,
95389
+ * "satisfaction_score": 0.82,
95390
+ * "response_rate": 0.5,
95391
+ * "positive": 7,
95392
+ * "neutral": 1,
95393
+ * "negative": 1,
95394
+ * "recommend_rate": 0.78,
95395
+ * "avg_confidence": 0.9,
95396
+ * "review_requests_sent": 18,
95397
+ * "resolved_tickets": 5,
95398
+ * "distribution": {
95399
+ * "positive": 7,
95400
+ * "neutral": 1,
95401
+ * "negative": 1
94818
95402
  * },
94819
- * "resolution": {
94820
- * "evaluated": 5,
94821
- * "breached": 1,
94822
- * "hit_rate": 0.8
95403
+ * "resolution_quality": {
95404
+ * "good": 8,
95405
+ * "poor": 1
94823
95406
  * },
94824
- * "by_policy": [
94825
- * {
94826
- * "policy_id": "cccccccc-1000-4000-8000-000000000001",
94827
- * "name": "SLA estándar",
94828
- * "hit_rate": 0.89
94829
- * }
94830
- * ],
94831
- * "breaches": []
95407
+ * "agent_performance": {},
95408
+ * "recent": []
95409
+ * },
95410
+ * "meta": {
95411
+ * "window": {
95412
+ * "kind": "rolling",
95413
+ * "preset": "7d",
95414
+ * "hours": 168,
95415
+ * "from": "2026-09-15T16:38:51.000Z",
95416
+ * "to": "2026-09-22T16:38:51.000Z",
95417
+ * "label": "últimos 7d"
95418
+ * }
95419
+ * }
95420
+ * }
95421
+ */
95422
+ "application/json": {
95423
+ data?: unknown;
95424
+ meta?: {
95425
+ [key: string]: unknown;
95426
+ };
95427
+ };
95428
+ };
95429
+ };
95430
+ /** @description Validation error */
95431
+ 400: {
95432
+ headers: {
95433
+ [name: string]: unknown;
95434
+ };
95435
+ content: {
95436
+ "application/json": components["schemas"]["Error"];
95437
+ };
95438
+ };
95439
+ /** @description Unauthorized */
95440
+ 401: {
95441
+ headers: {
95442
+ [name: string]: unknown;
95443
+ };
95444
+ content: {
95445
+ "application/json": components["schemas"]["Error"];
95446
+ };
95447
+ };
95448
+ /** @description Forbidden */
95449
+ 403: {
95450
+ headers: {
95451
+ [name: string]: unknown;
95452
+ };
95453
+ content: {
95454
+ "application/json": components["schemas"]["Error"];
95455
+ };
95456
+ };
95457
+ /** @description Not found */
95458
+ 404: {
95459
+ headers: {
95460
+ [name: string]: unknown;
95461
+ };
95462
+ content: {
95463
+ "application/json": components["schemas"]["Error"];
95464
+ };
95465
+ };
95466
+ /** @description Conflict (incl. Idempotency-Key reuse with different body) */
95467
+ 409: {
95468
+ headers: {
95469
+ [name: string]: unknown;
95470
+ };
95471
+ content: {
95472
+ "application/json": components["schemas"]["Error"];
95473
+ };
95474
+ };
95475
+ /** @description Rate limited */
95476
+ 429: {
95477
+ headers: {
95478
+ [name: string]: unknown;
95479
+ };
95480
+ content: {
95481
+ "application/json": components["schemas"]["Error"];
95482
+ };
95483
+ };
95484
+ };
95485
+ };
95486
+ put?: never;
95487
+ post?: never;
95488
+ delete?: never;
95489
+ options?: never;
95490
+ head?: never;
95491
+ patch?: never;
95492
+ trace?: never;
95493
+ };
95494
+ "/insights/sla": {
95495
+ parameters: {
95496
+ query?: never;
95497
+ header?: never;
95498
+ path?: never;
95499
+ cookie?: never;
95500
+ };
95501
+ /**
95502
+ * SLA compliance
95503
+ * @description Breach and compliance counts against the workspace SLA policies. A window with no policy configured reports nothing to comply with, not full compliance.
95504
+ */
95505
+ get: {
95506
+ parameters: {
95507
+ query?: {
95508
+ /** @description Which period. Omit it (with `from`/`to`) for an explicit range — the shape every ranged Insights report has always accepted, and which still works unchanged. The calendar windows are the DEALERSHIP’s (America/Santiago), so a month closes when a person would say it closed. */
95509
+ window?: "24h" | "7d" | "30d" | "90d" | "calendar_month" | "calendar_year" | "custom";
95510
+ /** @description `window=calendar_month` only. ISO month, `YYYY-MM`. Defaults to the month in progress. */
95511
+ month?: string;
95512
+ /** @description `window=calendar_year` only. `YYYY`. Defaults to the year in progress. */
95513
+ year?: string;
95514
+ /** @description Explicit range only. Checked for non-emptiness and handed to Postgres, so a malformed value surfaces as a 500 from the query rather than a 400 from the edge — send an ISO-8601 instant. */
95515
+ from?: string;
95516
+ /** @description Explicit range only. ISO instant, see `from`. */
95517
+ to?: string;
95518
+ };
95519
+ header?: never;
95520
+ path?: never;
95521
+ cookie?: never;
95522
+ };
95523
+ requestBody?: never;
95524
+ responses: {
95525
+ /** @description SLA compliance */
95526
+ 200: {
95527
+ headers: {
95528
+ [name: string]: unknown;
95529
+ };
95530
+ content: {
95531
+ /**
95532
+ * @example {
95533
+ * "data": {
95534
+ * "has_policies": true,
95535
+ * "policy_count": 2,
95536
+ * "target_first_response_minutes": 15,
95537
+ * "target_resolution_minutes": 480,
95538
+ * "tracked": 18,
95539
+ * "breached": 2,
95540
+ * "hits": 16,
95541
+ * "hit_rate": 0.89,
95542
+ * "first_response": {
95543
+ * "evaluated": 18,
95544
+ * "breached": 1,
95545
+ * "hit_rate": 0.94
95546
+ * },
95547
+ * "resolution": {
95548
+ * "evaluated": 5,
95549
+ * "breached": 1,
95550
+ * "hit_rate": 0.8
95551
+ * },
95552
+ * "by_policy": [
95553
+ * {
95554
+ * "policy_id": "cccccccc-1000-4000-8000-000000000001",
95555
+ * "name": "SLA estándar",
95556
+ * "hit_rate": 0.89
95557
+ * }
95558
+ * ],
95559
+ * "breaches": []
94832
95560
  * },
94833
95561
  * "meta": {
94834
95562
  * "window": {
@@ -97321,6 +98049,593 @@ interface paths {
97321
98049
  patch?: never;
97322
98050
  trace?: never;
97323
98051
  };
98052
+ "/ads/report": {
98053
+ parameters: {
98054
+ query?: never;
98055
+ header?: never;
98056
+ path?: never;
98057
+ cookie?: never;
98058
+ };
98059
+ /**
98060
+ * Reporte: campaigns, ad sets or ads with their funnel, costs and cash return
98061
+ * @description One table at `level` (campaign, ad set or ad) for the window. Per row: the spend and the cash credited by the attribution engine, Vitrina’s own conversational funnel (conversations each ad opened → answered → citas → attended → closes) with the cost of each step, «Retorno» = cash ÷ spend (`null` when no payment was recorded in the period), and Meta’s own figures apart. `tail` holds the period’s conversations with no ad behind them, so from-ads + tail = the workspace total; `reconciliation` states Σ spend against `/ads/overview`. A failed read is `null`, never 0.
98062
+ */
98063
+ get: {
98064
+ parameters: {
98065
+ query: {
98066
+ /** @description Window start (inclusive), YYYY-MM-DD. */
98067
+ from: string;
98068
+ /** @description Window end (inclusive), YYYY-MM-DD. */
98069
+ to: string;
98070
+ /** @description The attribution model. Defaults to `last_touch`. */
98071
+ model?: string;
98072
+ /** @description `1` serves the deterministic sample dataset («Ver con datos de ejemplo»): same shapes, invented but internally consistent figures, no entitlement required (the scope still is). A sandbox workspace is always served the sample, with or without this parameter. */
98073
+ sample?: "1" | "true";
98074
+ /** @description Campaña, conjunto (ad set) or anuncio. Default `campaign`. */
98075
+ level?: "campaign" | "ad_set" | "ad";
98076
+ };
98077
+ header?: never;
98078
+ path?: never;
98079
+ cookie?: never;
98080
+ };
98081
+ requestBody?: never;
98082
+ responses: {
98083
+ /** @description The report at the requested level */
98084
+ 200: {
98085
+ headers: {
98086
+ [name: string]: unknown;
98087
+ };
98088
+ content: {
98089
+ /**
98090
+ * @example {
98091
+ * "data": {
98092
+ * "level": "campaign",
98093
+ * "window": {
98094
+ * "from": "2026-08-30",
98095
+ * "to": "2026-09-28"
98096
+ * },
98097
+ * "rows": [
98098
+ * {
98099
+ * "external_id": "120211000000000001",
98100
+ * "level": "campaign",
98101
+ * "name": "Implantes · Septiembre",
98102
+ * "parent": null,
98103
+ * "thumbnail_url": null,
98104
+ * "spark": [
98105
+ * 13200,
98106
+ * 14100,
98107
+ * 13900
98108
+ * ],
98109
+ * "spend": 412300,
98110
+ * "funnel": {
98111
+ * "conversations": 120,
98112
+ * "replied": 110,
98113
+ * "appointments": 20,
98114
+ * "attended": 12,
98115
+ * "closes": 2
98116
+ * },
98117
+ * "cost_per": {
98118
+ * "conversation": 3436,
98119
+ * "appointment": 20615,
98120
+ * "attended": 34358,
98121
+ * "close": 206150
98122
+ * },
98123
+ * "cash": 0,
98124
+ * "return": null,
98125
+ * "meta": {
98126
+ * "conversations_started": 131,
98127
+ * "cost_per_conversation": 3147
98128
+ * }
98129
+ * }
98130
+ * ],
98131
+ * "tail": [
98132
+ * {
98133
+ * "key": "direct",
98134
+ * "conversations": 210
98135
+ * },
98136
+ * {
98137
+ * "key": "website",
98138
+ * "conversations": 40
98139
+ * }
98140
+ * ],
98141
+ * "totals": {
98142
+ * "spend": 412300,
98143
+ * "funnel": {
98144
+ * "conversations": 120,
98145
+ * "replied": 110,
98146
+ * "appointments": 20,
98147
+ * "attended": 12,
98148
+ * "closes": 2
98149
+ * },
98150
+ * "cost_per": {
98151
+ * "conversation": 3436,
98152
+ * "appointment": 20615,
98153
+ * "attended": 34358,
98154
+ * "close": 206150
98155
+ * },
98156
+ * "cash": 0,
98157
+ * "return": null,
98158
+ * "meta": {
98159
+ * "conversations_started": 131,
98160
+ * "cost_per_conversation": 3147
98161
+ * }
98162
+ * },
98163
+ * "pipeline": {
98164
+ * "closed_count": 3,
98165
+ * "closed_value": 93082
98166
+ * },
98167
+ * "cash_recorded": false,
98168
+ * "reconciliation": {
98169
+ * "overview_spend": 412300,
98170
+ * "spend_matches": true,
98171
+ * "conversations_total": 370,
98172
+ * "conversations_from_ads": 120,
98173
+ * "conversations_without_ad": 250
98174
+ * }
98175
+ * }
98176
+ * }
98177
+ */
98178
+ "application/json": {
98179
+ data: components["schemas"]["AdsReport"];
98180
+ };
98181
+ };
98182
+ };
98183
+ /** @description Validation error */
98184
+ 400: {
98185
+ headers: {
98186
+ [name: string]: unknown;
98187
+ };
98188
+ content: {
98189
+ "application/json": components["schemas"]["Error"];
98190
+ };
98191
+ };
98192
+ /** @description Unauthorized */
98193
+ 401: {
98194
+ headers: {
98195
+ [name: string]: unknown;
98196
+ };
98197
+ content: {
98198
+ "application/json": components["schemas"]["Error"];
98199
+ };
98200
+ };
98201
+ /** @description Vitrina Ads is not active for this workspace. `error.code` is `ENTITLEMENT_NOT_ACTIVE`, `error.details.feature` is `vitrina_ads`. */
98202
+ 402: {
98203
+ headers: {
98204
+ [name: string]: unknown;
98205
+ };
98206
+ content: {
98207
+ /**
98208
+ * @example {
98209
+ * "error": {
98210
+ * "code": "ENTITLEMENT_NOT_ACTIVE",
98211
+ * "message": "El complemento Vitrina Ads no está activo en este espacio de trabajo.",
98212
+ * "details": {
98213
+ * "required": [
98214
+ * "vitrina_ads"
98215
+ * ],
98216
+ * "active": [],
98217
+ * "feature": "vitrina_ads",
98218
+ * "entitlement_state": "off"
98219
+ * }
98220
+ * }
98221
+ * }
98222
+ */
98223
+ "application/json": components["schemas"]["Error"];
98224
+ };
98225
+ };
98226
+ /** @description Forbidden */
98227
+ 403: {
98228
+ headers: {
98229
+ [name: string]: unknown;
98230
+ };
98231
+ content: {
98232
+ "application/json": components["schemas"]["Error"];
98233
+ };
98234
+ };
98235
+ /** @description Not found */
98236
+ 404: {
98237
+ headers: {
98238
+ [name: string]: unknown;
98239
+ };
98240
+ content: {
98241
+ "application/json": components["schemas"]["Error"];
98242
+ };
98243
+ };
98244
+ /** @description Vitrina Ads is active but the delegated key has not finished rotating (`ADS_KEY_NEEDS_REMINT`) — retry once `GET /ads/state` reports `needs_remint: false`. Also the generic conflict of a write. */
98245
+ 409: {
98246
+ headers: {
98247
+ [name: string]: unknown;
98248
+ };
98249
+ content: {
98250
+ /**
98251
+ * @example {
98252
+ * "error": {
98253
+ * "code": "ADS_KEY_NEEDS_REMINT",
98254
+ * "message": "Vitrina Ads is active but the delegated key has not finished rotating (key_kind: core)",
98255
+ * "details": {
98256
+ * "key_kind": "core"
98257
+ * }
98258
+ * }
98259
+ * }
98260
+ */
98261
+ "application/json": components["schemas"]["Error"];
98262
+ };
98263
+ };
98264
+ /** @description Rate limited */
98265
+ 429: {
98266
+ headers: {
98267
+ [name: string]: unknown;
98268
+ };
98269
+ content: {
98270
+ "application/json": components["schemas"]["Error"];
98271
+ };
98272
+ };
98273
+ };
98274
+ };
98275
+ put?: never;
98276
+ post?: never;
98277
+ delete?: never;
98278
+ options?: never;
98279
+ head?: never;
98280
+ patch?: never;
98281
+ trace?: never;
98282
+ };
98283
+ "/ads/report/export": {
98284
+ parameters: {
98285
+ query?: never;
98286
+ header?: never;
98287
+ path?: never;
98288
+ cookie?: never;
98289
+ };
98290
+ /**
98291
+ * Export the Reporte (aggregates only)
98292
+ * @description The same table as `GET /ads/report`, as a file. CSV: `;`, Spanish headers, `dd-mm-aaaa` dates, a preamble with the period, the model and «Retorno = caja». XLSX: the table plus a «Notas» sheet. No row names a person. Audited as `ads.report.export`.
98293
+ */
98294
+ get: {
98295
+ parameters: {
98296
+ query: {
98297
+ /** @description Window start (inclusive), YYYY-MM-DD. */
98298
+ from: string;
98299
+ /** @description Window end (inclusive), YYYY-MM-DD. */
98300
+ to: string;
98301
+ /** @description The attribution model. Defaults to `last_touch`. */
98302
+ model?: string;
98303
+ /** @description `1` serves the deterministic sample dataset («Ver con datos de ejemplo»): same shapes, invented but internally consistent figures, no entitlement required (the scope still is). A sandbox workspace is always served the sample, with or without this parameter. */
98304
+ sample?: "1" | "true";
98305
+ /** @description Campaña, conjunto (ad set) or anuncio. Default `campaign`. */
98306
+ level?: "campaign" | "ad_set" | "ad";
98307
+ /** @description `csv`: `;`-separated, Spanish headers, `dd-mm-aaaa` dates, a preamble with the period, the model and «Retorno = caja». `xlsx`: the same table plus a «Notas» sheet. Aggregates only — no person rows. */
98308
+ format?: "csv" | "xlsx";
98309
+ };
98310
+ header?: never;
98311
+ path?: never;
98312
+ cookie?: never;
98313
+ };
98314
+ requestBody?: never;
98315
+ responses: {
98316
+ /** @description The file */
98317
+ 200: {
98318
+ headers: {
98319
+ [name: string]: unknown;
98320
+ };
98321
+ content: {
98322
+ "text/csv": string;
98323
+ "application/vnd.openxmlformats-officedocument.spreadsheetml.sheet": string;
98324
+ };
98325
+ };
98326
+ /** @description Validation error */
98327
+ 400: {
98328
+ headers: {
98329
+ [name: string]: unknown;
98330
+ };
98331
+ content: {
98332
+ "application/json": components["schemas"]["Error"];
98333
+ };
98334
+ };
98335
+ /** @description Unauthorized */
98336
+ 401: {
98337
+ headers: {
98338
+ [name: string]: unknown;
98339
+ };
98340
+ content: {
98341
+ "application/json": components["schemas"]["Error"];
98342
+ };
98343
+ };
98344
+ /** @description Vitrina Ads is not active for this workspace. `error.code` is `ENTITLEMENT_NOT_ACTIVE`, `error.details.feature` is `vitrina_ads`. */
98345
+ 402: {
98346
+ headers: {
98347
+ [name: string]: unknown;
98348
+ };
98349
+ content: {
98350
+ /**
98351
+ * @example {
98352
+ * "error": {
98353
+ * "code": "ENTITLEMENT_NOT_ACTIVE",
98354
+ * "message": "El complemento Vitrina Ads no está activo en este espacio de trabajo.",
98355
+ * "details": {
98356
+ * "required": [
98357
+ * "vitrina_ads"
98358
+ * ],
98359
+ * "active": [],
98360
+ * "feature": "vitrina_ads",
98361
+ * "entitlement_state": "off"
98362
+ * }
98363
+ * }
98364
+ * }
98365
+ */
98366
+ "application/json": components["schemas"]["Error"];
98367
+ };
98368
+ };
98369
+ /** @description Forbidden */
98370
+ 403: {
98371
+ headers: {
98372
+ [name: string]: unknown;
98373
+ };
98374
+ content: {
98375
+ "application/json": components["schemas"]["Error"];
98376
+ };
98377
+ };
98378
+ /** @description Not found */
98379
+ 404: {
98380
+ headers: {
98381
+ [name: string]: unknown;
98382
+ };
98383
+ content: {
98384
+ "application/json": components["schemas"]["Error"];
98385
+ };
98386
+ };
98387
+ /** @description Vitrina Ads is active but the delegated key has not finished rotating (`ADS_KEY_NEEDS_REMINT`) — retry once `GET /ads/state` reports `needs_remint: false`. Also the generic conflict of a write. */
98388
+ 409: {
98389
+ headers: {
98390
+ [name: string]: unknown;
98391
+ };
98392
+ content: {
98393
+ /**
98394
+ * @example {
98395
+ * "error": {
98396
+ * "code": "ADS_KEY_NEEDS_REMINT",
98397
+ * "message": "Vitrina Ads is active but the delegated key has not finished rotating (key_kind: core)",
98398
+ * "details": {
98399
+ * "key_kind": "core"
98400
+ * }
98401
+ * }
98402
+ * }
98403
+ */
98404
+ "application/json": components["schemas"]["Error"];
98405
+ };
98406
+ };
98407
+ /** @description Rate limited */
98408
+ 429: {
98409
+ headers: {
98410
+ [name: string]: unknown;
98411
+ };
98412
+ content: {
98413
+ "application/json": components["schemas"]["Error"];
98414
+ };
98415
+ };
98416
+ };
98417
+ };
98418
+ put?: never;
98419
+ post?: never;
98420
+ delete?: never;
98421
+ options?: never;
98422
+ head?: never;
98423
+ patch?: never;
98424
+ trace?: never;
98425
+ };
98426
+ "/ads/ads/{id}": {
98427
+ parameters: {
98428
+ query?: never;
98429
+ header?: never;
98430
+ path?: never;
98431
+ cookie?: never;
98432
+ };
98433
+ /**
98434
+ * The ad sheet: creative, funnel and the people it brought (masked)
98435
+ * @description One ad: the creative and delivery metrics, the SAME funnel/costs/cash as its Reporte row for the window, and the conversations it opened (a label, the furthest stage, its value). Never a phone or an e-mail; for healthcare the label is always initials. There is no export of people.
98436
+ */
98437
+ get: {
98438
+ parameters: {
98439
+ query: {
98440
+ /** @description Window start (inclusive), YYYY-MM-DD. */
98441
+ from: string;
98442
+ /** @description Window end (inclusive), YYYY-MM-DD. */
98443
+ to: string;
98444
+ /** @description The attribution model. Defaults to `last_touch`. */
98445
+ model?: string;
98446
+ /** @description `1` serves the deterministic sample dataset («Ver con datos de ejemplo»): same shapes, invented but internally consistent figures, no entitlement required (the scope still is). A sandbox workspace is always served the sample, with or without this parameter. */
98447
+ sample?: "1" | "true";
98448
+ };
98449
+ header?: never;
98450
+ path: {
98451
+ id: string;
98452
+ };
98453
+ cookie?: never;
98454
+ };
98455
+ requestBody?: never;
98456
+ responses: {
98457
+ /** @description The ad sheet */
98458
+ 200: {
98459
+ headers: {
98460
+ [name: string]: unknown;
98461
+ };
98462
+ content: {
98463
+ /**
98464
+ * @example {
98465
+ * "data": {
98466
+ * "ad": {
98467
+ * "external_id": "120212000000000009",
98468
+ * "name": "Video testimonio 15s",
98469
+ * "ad_set": {
98470
+ * "external_id": "120213000000000004",
98471
+ * "name": "INTERESES"
98472
+ * },
98473
+ * "campaign": {
98474
+ * "external_id": "120211000000000001"
98475
+ * },
98476
+ * "thumbnail_url": null,
98477
+ * "title": "Implantes en un día",
98478
+ * "body": "Agenda tu evaluación.",
98479
+ * "has_video": true,
98480
+ * "spend": 168000,
98481
+ * "impressions": 24100,
98482
+ * "clicks": 337,
98483
+ * "ctr": 1.4,
98484
+ * "cpm": 6971,
98485
+ * "cpc": 498,
98486
+ * "cash_count": 0,
98487
+ * "cash_value": 0,
98488
+ * "meta_conversations_started": 22
98489
+ * },
98490
+ * "window": {
98491
+ * "from": "2026-08-30",
98492
+ * "to": "2026-09-28"
98493
+ * },
98494
+ * "row": {
98495
+ * "spend": 412300,
98496
+ * "funnel": {
98497
+ * "conversations": 120,
98498
+ * "replied": 110,
98499
+ * "appointments": 20,
98500
+ * "attended": 12,
98501
+ * "closes": 2
98502
+ * },
98503
+ * "cost_per": {
98504
+ * "conversation": 3436,
98505
+ * "appointment": 20615,
98506
+ * "attended": 34358,
98507
+ * "close": 206150
98508
+ * },
98509
+ * "cash": 0,
98510
+ * "return": null,
98511
+ * "meta": {
98512
+ * "conversations_started": 131,
98513
+ * "cost_per_conversation": 3147
98514
+ * }
98515
+ * },
98516
+ * "cash_recorded": false,
98517
+ * "people": [
98518
+ * {
98519
+ * "conversation_id": "00000000-0000-4000-8000-00000000c0a1",
98520
+ * "contact_id": "00000000-0000-4000-8000-00000000c0a2",
98521
+ * "label": "M. R.",
98522
+ * "masked": true,
98523
+ * "stage": "closed_won",
98524
+ * "stage_at": "2026-09-25T15:00:00.000Z",
98525
+ * "opened_at": "2026-09-20T13:10:00.000Z",
98526
+ * "value": 1250000
98527
+ * }
98528
+ * ],
98529
+ * "people_more": false,
98530
+ * "people_hidden": false
98531
+ * }
98532
+ * }
98533
+ */
98534
+ "application/json": {
98535
+ data: components["schemas"]["AdsAdSheet"];
98536
+ };
98537
+ };
98538
+ };
98539
+ /** @description Validation error */
98540
+ 400: {
98541
+ headers: {
98542
+ [name: string]: unknown;
98543
+ };
98544
+ content: {
98545
+ "application/json": components["schemas"]["Error"];
98546
+ };
98547
+ };
98548
+ /** @description Unauthorized */
98549
+ 401: {
98550
+ headers: {
98551
+ [name: string]: unknown;
98552
+ };
98553
+ content: {
98554
+ "application/json": components["schemas"]["Error"];
98555
+ };
98556
+ };
98557
+ /** @description Vitrina Ads is not active for this workspace. `error.code` is `ENTITLEMENT_NOT_ACTIVE`, `error.details.feature` is `vitrina_ads`. */
98558
+ 402: {
98559
+ headers: {
98560
+ [name: string]: unknown;
98561
+ };
98562
+ content: {
98563
+ /**
98564
+ * @example {
98565
+ * "error": {
98566
+ * "code": "ENTITLEMENT_NOT_ACTIVE",
98567
+ * "message": "El complemento Vitrina Ads no está activo en este espacio de trabajo.",
98568
+ * "details": {
98569
+ * "required": [
98570
+ * "vitrina_ads"
98571
+ * ],
98572
+ * "active": [],
98573
+ * "feature": "vitrina_ads",
98574
+ * "entitlement_state": "off"
98575
+ * }
98576
+ * }
98577
+ * }
98578
+ */
98579
+ "application/json": components["schemas"]["Error"];
98580
+ };
98581
+ };
98582
+ /** @description Forbidden */
98583
+ 403: {
98584
+ headers: {
98585
+ [name: string]: unknown;
98586
+ };
98587
+ content: {
98588
+ "application/json": components["schemas"]["Error"];
98589
+ };
98590
+ };
98591
+ /** @description Not found */
98592
+ 404: {
98593
+ headers: {
98594
+ [name: string]: unknown;
98595
+ };
98596
+ content: {
98597
+ "application/json": components["schemas"]["Error"];
98598
+ };
98599
+ };
98600
+ /** @description Vitrina Ads is active but the delegated key has not finished rotating (`ADS_KEY_NEEDS_REMINT`) — retry once `GET /ads/state` reports `needs_remint: false`. Also the generic conflict of a write. */
98601
+ 409: {
98602
+ headers: {
98603
+ [name: string]: unknown;
98604
+ };
98605
+ content: {
98606
+ /**
98607
+ * @example {
98608
+ * "error": {
98609
+ * "code": "ADS_KEY_NEEDS_REMINT",
98610
+ * "message": "Vitrina Ads is active but the delegated key has not finished rotating (key_kind: core)",
98611
+ * "details": {
98612
+ * "key_kind": "core"
98613
+ * }
98614
+ * }
98615
+ * }
98616
+ */
98617
+ "application/json": components["schemas"]["Error"];
98618
+ };
98619
+ };
98620
+ /** @description Rate limited */
98621
+ 429: {
98622
+ headers: {
98623
+ [name: string]: unknown;
98624
+ };
98625
+ content: {
98626
+ "application/json": components["schemas"]["Error"];
98627
+ };
98628
+ };
98629
+ };
98630
+ };
98631
+ put?: never;
98632
+ post?: never;
98633
+ delete?: never;
98634
+ options?: never;
98635
+ head?: never;
98636
+ patch?: never;
98637
+ trace?: never;
98638
+ };
97324
98639
  "/ads/overview": {
97325
98640
  parameters: {
97326
98641
  query?: never;
@@ -97906,6 +99221,17 @@ interface paths {
97906
99221
  * "attributed_outcomes": 1,
97907
99222
  * "partial": false
97908
99223
  * }
99224
+ * ],
99225
+ * "gaps": [
99226
+ * {
99227
+ * "from": "2026-09-12",
99228
+ * "to": "2026-09-15",
99229
+ * "cause": "meta_disconnected",
99230
+ * "metrics": [
99231
+ * "spend"
99232
+ * ],
99233
+ * "incident_id": "b1b1b1b1-0000-4000-8000-000000000002"
99234
+ * }
97909
99235
  * ]
97910
99236
  * }
97911
99237
  * }
@@ -98015,6 +99341,186 @@ interface paths {
98015
99341
  patch?: never;
98016
99342
  trace?: never;
98017
99343
  };
99344
+ "/ads/measurement": {
99345
+ parameters: {
99346
+ query?: never;
99347
+ header?: never;
99348
+ path?: never;
99349
+ cookie?: never;
99350
+ };
99351
+ /**
99352
+ * Measurement incidents: what stopped measuring, since when
99353
+ * @description The measurement watchdog’s ledger (W1.1, «Vigilancia de la medición»). `open` are the legs broken right now — the Meta ad account read (disconnected or stale), the site tag’s heartbeat, the Conversions API sends, a WhatsApp channel, clinic facts not reaching the attribution — each with the day the data stopped and its ONE fix (`action.path`). `recent` are the ones resolved in the last 14 days, with who fixed them.
99354
+ *
99355
+ * The owner and admins are told by WhatsApp and email at +0 h, +3 d and +7 d while an incident stays open. `/ads/overview` and `/ads/campaigns` carry the same incidents as `gaps` over their window.
99356
+ */
99357
+ get: {
99358
+ parameters: {
99359
+ query?: {
99360
+ /** @description `1` serves the deterministic sample dataset («Ver con datos de ejemplo»): same shapes, invented but internally consistent figures, no entitlement required (the scope still is). A sandbox workspace is always served the sample, with or without this parameter. */
99361
+ sample?: "1" | "true";
99362
+ };
99363
+ header?: never;
99364
+ path?: never;
99365
+ cookie?: never;
99366
+ };
99367
+ requestBody?: never;
99368
+ responses: {
99369
+ /** @description Open and recently resolved incidents */
99370
+ 200: {
99371
+ headers: {
99372
+ [name: string]: unknown;
99373
+ };
99374
+ content: {
99375
+ /**
99376
+ * @example {
99377
+ * "data": {
99378
+ * "open": [
99379
+ * {
99380
+ * "id": "b1b1b1b1-0000-4000-8000-000000000001",
99381
+ * "cause": "tag_silent",
99382
+ * "label": "Etiqueta del sitio sin señal",
99383
+ * "sentence": "La etiqueta de tu sitio web no envía visitas desde el 20 sep",
99384
+ * "action": {
99385
+ * "label": "Revisar la etiqueta",
99386
+ * "path": "/anuncios/activar?paso=tag"
99387
+ * },
99388
+ * "since": "2026-09-20T14:05:00.000Z",
99389
+ * "opened_at": "2026-09-27T15:00:00.000Z",
99390
+ * "resolved_at": null,
99391
+ * "resolution": null,
99392
+ * "resolved_by_name": null,
99393
+ * "metrics": []
99394
+ * }
99395
+ * ],
99396
+ * "recent": [
99397
+ * {
99398
+ * "id": "b1b1b1b1-0000-4000-8000-000000000002",
99399
+ * "cause": "meta_disconnected",
99400
+ * "label": "Meta Ads desconectado",
99401
+ * "sentence": "Tus anuncios de Meta dejaron de medirse el 12 sep",
99402
+ * "action": {
99403
+ * "label": "Reconectar Meta",
99404
+ * "path": "/anuncios/activar?paso=meta"
99405
+ * },
99406
+ * "since": "2026-09-12T11:20:00.000Z",
99407
+ * "opened_at": "2026-09-12T12:00:00.000Z",
99408
+ * "resolved_at": "2026-09-15T13:42:00.000Z",
99409
+ * "resolution": "reconnected",
99410
+ * "resolved_by_name": "Camila",
99411
+ * "metrics": [
99412
+ * "spend"
99413
+ * ]
99414
+ * }
99415
+ * ]
99416
+ * }
99417
+ * }
99418
+ */
99419
+ "application/json": {
99420
+ data: components["schemas"]["AdsMeasurement"];
99421
+ };
99422
+ };
99423
+ };
99424
+ /** @description Validation error */
99425
+ 400: {
99426
+ headers: {
99427
+ [name: string]: unknown;
99428
+ };
99429
+ content: {
99430
+ "application/json": components["schemas"]["Error"];
99431
+ };
99432
+ };
99433
+ /** @description Unauthorized */
99434
+ 401: {
99435
+ headers: {
99436
+ [name: string]: unknown;
99437
+ };
99438
+ content: {
99439
+ "application/json": components["schemas"]["Error"];
99440
+ };
99441
+ };
99442
+ /** @description Vitrina Ads is not active for this workspace. `error.code` is `ENTITLEMENT_NOT_ACTIVE`, `error.details.feature` is `vitrina_ads`. */
99443
+ 402: {
99444
+ headers: {
99445
+ [name: string]: unknown;
99446
+ };
99447
+ content: {
99448
+ /**
99449
+ * @example {
99450
+ * "error": {
99451
+ * "code": "ENTITLEMENT_NOT_ACTIVE",
99452
+ * "message": "El complemento Vitrina Ads no está activo en este espacio de trabajo.",
99453
+ * "details": {
99454
+ * "required": [
99455
+ * "vitrina_ads"
99456
+ * ],
99457
+ * "active": [],
99458
+ * "feature": "vitrina_ads",
99459
+ * "entitlement_state": "off"
99460
+ * }
99461
+ * }
99462
+ * }
99463
+ */
99464
+ "application/json": components["schemas"]["Error"];
99465
+ };
99466
+ };
99467
+ /** @description Forbidden */
99468
+ 403: {
99469
+ headers: {
99470
+ [name: string]: unknown;
99471
+ };
99472
+ content: {
99473
+ "application/json": components["schemas"]["Error"];
99474
+ };
99475
+ };
99476
+ /** @description Not found */
99477
+ 404: {
99478
+ headers: {
99479
+ [name: string]: unknown;
99480
+ };
99481
+ content: {
99482
+ "application/json": components["schemas"]["Error"];
99483
+ };
99484
+ };
99485
+ /** @description Vitrina Ads is active but the delegated key has not finished rotating (`ADS_KEY_NEEDS_REMINT`) — retry once `GET /ads/state` reports `needs_remint: false`. Also the generic conflict of a write. */
99486
+ 409: {
99487
+ headers: {
99488
+ [name: string]: unknown;
99489
+ };
99490
+ content: {
99491
+ /**
99492
+ * @example {
99493
+ * "error": {
99494
+ * "code": "ADS_KEY_NEEDS_REMINT",
99495
+ * "message": "Vitrina Ads is active but the delegated key has not finished rotating (key_kind: core)",
99496
+ * "details": {
99497
+ * "key_kind": "core"
99498
+ * }
99499
+ * }
99500
+ * }
99501
+ */
99502
+ "application/json": components["schemas"]["Error"];
99503
+ };
99504
+ };
99505
+ /** @description Rate limited */
99506
+ 429: {
99507
+ headers: {
99508
+ [name: string]: unknown;
99509
+ };
99510
+ content: {
99511
+ "application/json": components["schemas"]["Error"];
99512
+ };
99513
+ };
99514
+ };
99515
+ };
99516
+ put?: never;
99517
+ post?: never;
99518
+ delete?: never;
99519
+ options?: never;
99520
+ head?: never;
99521
+ patch?: never;
99522
+ trace?: never;
99523
+ };
98018
99524
  "/ads/campaigns": {
98019
99525
  parameters: {
98020
99526
  query?: never;
@@ -98230,6 +99736,17 @@ interface paths {
98230
99736
  * }
98231
99737
  * ]
98232
99738
  * }
99739
+ * ],
99740
+ * "gaps": [
99741
+ * {
99742
+ * "from": "2026-09-12",
99743
+ * "to": "2026-09-15",
99744
+ * "cause": "meta_disconnected",
99745
+ * "metrics": [
99746
+ * "spend"
99747
+ * ],
99748
+ * "incident_id": "b1b1b1b1-0000-4000-8000-000000000002"
99749
+ * }
98233
99750
  * ]
98234
99751
  * }
98235
99752
  * }
@@ -122361,6 +123878,178 @@ interface components {
122361
123878
  from: string;
122362
123879
  to: string;
122363
123880
  };
123881
+ AgendaResults: {
123882
+ from: string;
123883
+ to: string;
123884
+ timezone: string;
123885
+ /** Format: uuid */
123886
+ location_id: string | null;
123887
+ /**
123888
+ * @description Vocabulary: citas/pacientes, visitas/clientes, citas/clientes.
123889
+ * @enum {string}
123890
+ */
123891
+ family: "clinic" | "dealer" | "generic";
123892
+ previous_period: {
123893
+ from: string;
123894
+ to: string;
123895
+ };
123896
+ bookings: {
123897
+ /** @description Citas of the period booked by Vitrina's agent in a conversation (`source='agent'`, not a public booking page). */
123898
+ ai: number;
123899
+ /** @description Every cita of the period (blocks and holds excluded). */
123900
+ agenda_total: number;
123901
+ /** @description Percent, one decimal. `null` — never 0 — with no denominator. */
123902
+ share_pct: number | null;
123903
+ previous: {
123904
+ ai: number;
123905
+ agenda_total: number;
123906
+ /** @description Percent, one decimal. `null` — never 0 — with no denominator. */
123907
+ share_pct: number | null;
123908
+ };
123909
+ rule: string;
123910
+ };
123911
+ money: {
123912
+ /** @description False for a vertical with no priced citas. */
123913
+ applies: boolean;
123914
+ withheld: boolean;
123915
+ /** @description Value of the AI-booked citas whose value is known (pipeline, not cash). */
123916
+ booked_clp: number | null;
123917
+ booked_priced: number;
123918
+ /** @description AI-booked citas with no price — «sin dato». */
123919
+ booked_unpriced: number;
123920
+ /** @description CLP. `null` when unknown or when the caller lacks `clinic_money:read` (`money.withheld`). */
123921
+ agenda_clp: number | null;
123922
+ /** @description Percent, one decimal. `null` — never 0 — with no denominator. */
123923
+ clp_share_pct: number | null;
123924
+ /** @description Cash received in the period by the patients Vitrina booked, from the day it booked them. */
123925
+ paid_clp: number | null;
123926
+ paid_patients: number | null;
123927
+ /** @description AI-booked citas with no patient to match a payment to. */
123928
+ unlinked: number;
123929
+ /** @enum {string|null} */
123930
+ regime: "mirror" | "native" | null;
123931
+ previous: {
123932
+ /** @description CLP. `null` when unknown or when the caller lacks `clinic_money:read` (`money.withheld`). */
123933
+ booked_clp: number | null;
123934
+ /** @description CLP. `null` when unknown or when the caller lacks `clinic_money:read` (`money.withheld`). */
123935
+ paid_clp: number | null;
123936
+ };
123937
+ rule_booked: string;
123938
+ rule_paid: string;
123939
+ };
123940
+ out_of_hours: {
123941
+ /** @description False when the workspace has no business hours; count/pct are then null. */
123942
+ configured: boolean;
123943
+ count: number | null;
123944
+ /** @description Percent, one decimal. `null` — never 0 — with no denominator. */
123945
+ pct: number | null;
123946
+ /** @description Percent, one decimal. `null` — never 0 — with no denominator. */
123947
+ previous_pct: number | null;
123948
+ /** @description AI bookings by weekday × hour of the booking, in `timezone`. Empty cells omitted. */
123949
+ heatmap: {
123950
+ /** @description 1 = Monday … 7 = Sunday. */
123951
+ weekday: number;
123952
+ hour: number;
123953
+ count: number;
123954
+ }[];
123955
+ rule: string;
123956
+ };
123957
+ autonomy: {
123958
+ no_human: number;
123959
+ /** @description Percent, one decimal. `null` — never 0 — with no denominator. */
123960
+ pct: number | null;
123961
+ measured: number;
123962
+ unknown: number;
123963
+ /** @description Percent, one decimal. `null` — never 0 — with no denominator. */
123964
+ previous_pct: number | null;
123965
+ rule: string;
123966
+ };
123967
+ time_to_book: {
123968
+ median_seconds: number | null;
123969
+ p95_seconds: number | null;
123970
+ p95_phrase: string | null;
123971
+ measured: number;
123972
+ unknown: number;
123973
+ previous_median_seconds: number | null;
123974
+ rule: string;
123975
+ };
123976
+ hours_returned: {
123977
+ minutes_per_booking: number;
123978
+ hours: number;
123979
+ rule: string;
123980
+ };
123981
+ recovery: {
123982
+ window_days: number;
123983
+ known_attendance: number;
123984
+ unknown_attendance: number;
123985
+ /** @description Percent, one decimal. `null` — never 0 — with no denominator. */
123986
+ no_show_pct: number | null;
123987
+ no_show: {
123988
+ count: number;
123989
+ recovered: number;
123990
+ recovered_via_vitrina: number;
123991
+ /** @description Percent, one decimal. `null` — never 0 — with no denominator. */
123992
+ recovered_pct: number | null;
123993
+ /** @description Percent, one decimal. `null` — never 0 — with no denominator. */
123994
+ via_vitrina_pct: number | null;
123995
+ /** @description Not recovered yet, still inside the 30 days. */
123996
+ pending: number;
123997
+ /** @description Missed with no identifiable patient. */
123998
+ unlinked: number;
123999
+ };
124000
+ cancelled: {
124001
+ count: number;
124002
+ recovered: number;
124003
+ recovered_via_vitrina: number;
124004
+ /** @description Percent, one decimal. `null` — never 0 — with no denominator. */
124005
+ recovered_pct: number | null;
124006
+ /** @description Percent, one decimal. `null` — never 0 — with no denominator. */
124007
+ via_vitrina_pct: number | null;
124008
+ /** @description Not recovered yet, still inside the 30 days. */
124009
+ pending: number;
124010
+ /** @description Missed with no identifiable patient. */
124011
+ unlinked: number;
124012
+ };
124013
+ rule_no_show: string;
124014
+ rule_recovered: string;
124015
+ };
124016
+ confirmation: {
124017
+ applies: boolean;
124018
+ /** @description Percent, one decimal. `null` — never 0 — with no denominator. */
124019
+ confirmed_attendance_pct: number | null;
124020
+ /** @description Percent, one decimal. `null` — never 0 — with no denominator. */
124021
+ unconfirmed_attendance_pct: number | null;
124022
+ confirmed_closed: number | null;
124023
+ unconfirmed_closed: number | null;
124024
+ rule: string;
124025
+ };
124026
+ ads: {
124027
+ /** @enum {string} */
124028
+ state: "active" | "not_active" | "unavailable";
124029
+ spend_clp: number | null;
124030
+ booked: number | null;
124031
+ attended: number | null;
124032
+ paid: number | null;
124033
+ cost_per_booked: number | null;
124034
+ cost_per_attended: number | null;
124035
+ cost_per_paid: number | null;
124036
+ rule: string;
124037
+ };
124038
+ reminders: {
124039
+ applies: boolean;
124040
+ sent: number;
124041
+ failed: number;
124042
+ /** @description Percent, one decimal. `null` — never 0 — with no denominator. */
124043
+ failed_pct: number | null;
124044
+ by_cause: {
124045
+ /** @enum {string} */
124046
+ cause: "no_patient_link" | "no_phone" | "no_channel" | "opted_out" | "template_not_approved" | "meta_payment_block" | "no_whatsapp" | "window_closed" | "template_rejected" | "send_error";
124047
+ count: number;
124048
+ }[];
124049
+ rule: string;
124050
+ };
124051
+ truncated: boolean;
124052
+ };
122364
124053
  ClinicComercialReport: {
122365
124054
  from: string;
122366
124055
  to: string;
@@ -123178,6 +124867,180 @@ interface components {
123178
124867
  */
123179
124868
  handoff_id?: string;
123180
124869
  };
124870
+ AdsReportRow: {
124871
+ spend: number | null;
124872
+ /** @description Vitrina’s own funnel: conversations each ad OPENED in the period and the stages recorded against them (a campaign / ad set sums its ads). `null` = unknown (the read failed), never 0. */
124873
+ funnel: {
124874
+ conversations: number | null;
124875
+ replied: number | null;
124876
+ appointments: number | null;
124877
+ attended: number | null;
124878
+ closes: number | null;
124879
+ };
124880
+ cost_per: {
124881
+ conversation: number | null;
124882
+ appointment: number | null;
124883
+ attended: number | null;
124884
+ close: number | null;
124885
+ };
124886
+ /** @description Payments credited to the entity (CLP). Cash only. */
124887
+ cash: number | null;
124888
+ /** @description cash ÷ spend. `null` when no payment was recorded in the period (see `cash_recorded`) — the return is unknown then, never 0×. */
124889
+ return: number | null;
124890
+ /** @description Meta’s OWN figures (its 7-day window, every sender) — never added to Vitrina’s. */
124891
+ meta: {
124892
+ conversations_started: number | null;
124893
+ cost_per_conversation: number | null;
124894
+ };
124895
+ /** @description Platform id; `null` for the unmapped bucket. */
124896
+ external_id: string | null;
124897
+ /** @enum {string} */
124898
+ level: "campaign" | "ad_set" | "ad";
124899
+ name: string;
124900
+ /** @description An ad’s ad set / an ad set’s campaign; `null` for a campaign. */
124901
+ parent: {
124902
+ external_id: string | null;
124903
+ name: string | null;
124904
+ } | null;
124905
+ thumbnail_url: string | null;
124906
+ /** @description Daily spend, oldest first; `null` unread. */
124907
+ spark: number[] | null;
124908
+ /**
124909
+ * @description Ads that opened conversations but have no row at this level yet.
124910
+ * @enum {boolean}
124911
+ */
124912
+ unmapped?: true;
124913
+ };
124914
+ AdsReport: {
124915
+ /** @enum {string} */
124916
+ level: "campaign" | "ad_set" | "ad";
124917
+ window: {
124918
+ from: string;
124919
+ to: string;
124920
+ };
124921
+ rows: components["schemas"]["AdsReportRow"][];
124922
+ /** @description «Sin anuncio»: the period’s conversations with no ad behind them. `null` = unknown. */
124923
+ tail: {
124924
+ /** @enum {string} */
124925
+ key: "website" | "portals" | "direct";
124926
+ conversations: number;
124927
+ }[] | null;
124928
+ totals: {
124929
+ spend: number | null;
124930
+ /** @description Vitrina’s own funnel: conversations each ad OPENED in the period and the stages recorded against them (a campaign / ad set sums its ads). `null` = unknown (the read failed), never 0. */
124931
+ funnel: {
124932
+ conversations: number | null;
124933
+ replied: number | null;
124934
+ appointments: number | null;
124935
+ attended: number | null;
124936
+ closes: number | null;
124937
+ };
124938
+ cost_per: {
124939
+ conversation: number | null;
124940
+ appointment: number | null;
124941
+ attended: number | null;
124942
+ close: number | null;
124943
+ };
124944
+ /** @description Payments credited to the entity (CLP). Cash only. */
124945
+ cash: number | null;
124946
+ /** @description cash ÷ spend. `null` when no payment was recorded in the period (see `cash_recorded`) — the return is unknown then, never 0×. */
124947
+ return: number | null;
124948
+ /** @description Meta’s OWN figures (its 7-day window, every sender) — never added to Vitrina’s. */
124949
+ meta: {
124950
+ conversations_started: number | null;
124951
+ cost_per_conversation: number | null;
124952
+ };
124953
+ };
124954
+ /** @description Closes credited to an ad and their recorded value — PIPELINE, never in `return`. */
124955
+ pipeline: {
124956
+ closed_count: number;
124957
+ closed_value: number;
124958
+ } | null;
124959
+ cash_recorded: boolean;
124960
+ reconciliation: {
124961
+ overview_spend: number | null;
124962
+ spend_matches: boolean | null;
124963
+ conversations_total: number | null;
124964
+ conversations_from_ads: number | null;
124965
+ conversations_without_ad: number | null;
124966
+ };
124967
+ };
124968
+ AdsAdSheet: {
124969
+ /** @description The creative and the delivery metrics; `null` when the engine read failed. */
124970
+ ad: {
124971
+ external_id: string;
124972
+ name: string;
124973
+ ad_set: {
124974
+ external_id: string | null;
124975
+ name: string | null;
124976
+ } | null;
124977
+ campaign: {
124978
+ external_id: string;
124979
+ } | null;
124980
+ thumbnail_url: string | null;
124981
+ title: string | null;
124982
+ body: string | null;
124983
+ has_video: boolean;
124984
+ spend: number | null;
124985
+ impressions: number;
124986
+ clicks: number;
124987
+ ctr: number;
124988
+ cpm: number;
124989
+ cpc: number;
124990
+ cash_count: number;
124991
+ cash_value: number;
124992
+ meta_conversations_started: number | null;
124993
+ } | null;
124994
+ window: {
124995
+ from: string;
124996
+ to: string;
124997
+ };
124998
+ /** @description The same figures as the Reporte row for this ad. */
124999
+ row: {
125000
+ spend: number | null;
125001
+ /** @description Vitrina’s own funnel: conversations each ad OPENED in the period and the stages recorded against them (a campaign / ad set sums its ads). `null` = unknown (the read failed), never 0. */
125002
+ funnel: {
125003
+ conversations: number | null;
125004
+ replied: number | null;
125005
+ appointments: number | null;
125006
+ attended: number | null;
125007
+ closes: number | null;
125008
+ };
125009
+ cost_per: {
125010
+ conversation: number | null;
125011
+ appointment: number | null;
125012
+ attended: number | null;
125013
+ close: number | null;
125014
+ };
125015
+ /** @description Payments credited to the entity (CLP). Cash only. */
125016
+ cash: number | null;
125017
+ /** @description cash ÷ spend. `null` when no payment was recorded in the period (see `cash_recorded`) — the return is unknown then, never 0×. */
125018
+ return: number | null;
125019
+ /** @description Meta’s OWN figures (its 7-day window, every sender) — never added to Vitrina’s. */
125020
+ meta: {
125021
+ conversations_started: number | null;
125022
+ cost_per_conversation: number | null;
125023
+ };
125024
+ };
125025
+ cash_recorded: boolean;
125026
+ /** @description The conversations this ad opened, newest first. Healthcare: always initials. Elsewhere a name only with `contacts:read`. No export. */
125027
+ people: {
125028
+ /** Format: uuid */
125029
+ conversation_id: string;
125030
+ /** Format: uuid */
125031
+ contact_id: string | null;
125032
+ /** @description Initials, or the name where allowed. Never a phone or an e-mail. */
125033
+ label: string;
125034
+ masked: boolean;
125035
+ stage: string | null;
125036
+ stage_at: string | null;
125037
+ opened_at: string;
125038
+ value: number | null;
125039
+ }[];
125040
+ people_more: boolean;
125041
+ /** @description The caller lacks `contacts:read`: `people` is empty on purpose. */
125042
+ people_hidden: boolean;
125043
+ };
123181
125044
  AdsOverviewDay: {
123182
125045
  date: string;
123183
125046
  /** @description `null` exactly when the engine could not scope spend. */
@@ -123189,6 +125052,21 @@ interface components {
123189
125052
  /** @description `true` on the day still running (today, America/Santiago): end the solid line before it. */
123190
125053
  partial: boolean;
123191
125054
  };
125055
+ AdsGap: {
125056
+ /** @description First day with missing data, YYYY-MM-DD. */
125057
+ from: string;
125058
+ /** @description Last day with missing data, YYYY-MM-DD; `null` = still ongoing. */
125059
+ to: string | null;
125060
+ /**
125061
+ * @description What broke: `meta_disconnected` / `meta_stale` (the ad account read), `tag_silent` (the site tag stopped reporting), `capi_failing` (the Conversions API sends), `whatsapp_disconnected`, `engine_facts_missing` (clinic payments/plans not reaching the attribution).
125062
+ * @enum {string}
125063
+ */
125064
+ cause: "meta_disconnected" | "meta_stale" | "tag_silent" | "capi_failing" | "whatsapp_disconnected" | "engine_facts_missing";
125065
+ /** @description The figures UNKNOWN inside the gap: draw them as missing (a break in the line, «sin datos»), never as 0. Empty = nothing Vitrina shows is blanked; the window is annotated only. */
125066
+ metrics: ("spend" | "conversations" | "outcomes")[];
125067
+ /** Format: uuid */
125068
+ incident_id: string;
125069
+ };
123192
125070
  AdsOverview: {
123193
125071
  current: {
123194
125072
  spend: number | null;
@@ -123256,6 +125134,44 @@ interface components {
123256
125134
  days?: components["schemas"]["AdsOverviewDay"][];
123257
125135
  /** @description `grain=day` only: every day of the previous window of equal length. */
123258
125136
  previous_days?: components["schemas"]["AdsOverviewDay"][];
125137
+ /** @description Measurement gaps overlapping the window (W1.1). Days inside a gap whose `metrics` list a figure carry NO measured value for it — the engine may report 0 there; render «sin datos», never the 0. */
125138
+ gaps: components["schemas"]["AdsGap"][];
125139
+ };
125140
+ AdsMeasurementIncident: {
125141
+ /** Format: uuid */
125142
+ id: string;
125143
+ /** @enum {string} */
125144
+ cause: "meta_disconnected" | "meta_stale" | "tag_silent" | "capi_failing" | "whatsapp_disconnected" | "engine_facts_missing";
125145
+ /** @description «Meta Ads desconectado». */
125146
+ label: string;
125147
+ /** @description «Tus anuncios de Meta dejaron de medirse el 12 sep». */
125148
+ sentence: string;
125149
+ /** @description The one primary action. */
125150
+ action: {
125151
+ /** @description «Reconectar Meta». */
125152
+ label: string;
125153
+ /** @description Workspace-relative path of the ONE fix, e.g. `/anuncios/activar?paso=meta`. */
125154
+ path: string;
125155
+ };
125156
+ /** @description When the data stopped (ISO instant). */
125157
+ since: string;
125158
+ /** @description When the watchdog opened it (ISO). */
125159
+ opened_at: string;
125160
+ resolved_at: string | null;
125161
+ /**
125162
+ * @description `reconnected` — a member fixed it; `recovered` — the leg came back on its own; `withdrawn` — it was switched off on purpose.
125163
+ * @enum {string|null}
125164
+ */
125165
+ resolution: "reconnected" | "recovered" | "withdrawn" | null;
125166
+ /** @description The member who fixed it. `null` when it recovered on its own, or when the caller lacks `memberships:read`. */
125167
+ resolved_by_name: string | null;
125168
+ metrics: ("spend" | "conversations" | "outcomes")[];
125169
+ };
125170
+ AdsMeasurement: {
125171
+ /** @description Open incidents, oldest first — the banner. */
125172
+ open: components["schemas"]["AdsMeasurementIncident"][];
125173
+ /** @description Incidents resolved in the last 14 days, newest first. */
125174
+ recent: components["schemas"]["AdsMeasurementIncident"][];
123259
125175
  };
123260
125176
  /** @description Present on a conversational row: a message-only objective (`MESSAGES`), or conversations the platform reports, or conversations Vitrina counts. Also present with `data_complete: false` (figures `null`) when a read failed on a row that may be conversational (its objective unknown or in the messaging family) in a workspace with ad-opened conversations. ABSENT otherwise — never a row of zeros, never partial counts. */
123261
125177
  AdsConversational: {
@@ -123314,6 +125230,8 @@ interface components {
123314
125230
  }[] | null;
123315
125231
  conversational?: components["schemas"]["AdsConversational"];
123316
125232
  }[];
125233
+ /** @description Measurement gaps overlapping the window (W1.1). Days inside a gap whose `metrics` list a figure carry NO measured value for it — the engine may report 0 there; render «sin datos», never the 0. */
125234
+ gaps: components["schemas"]["AdsGap"][];
123317
125235
  };
123318
125236
  AdsAttributedSales: {
123319
125237
  data: {