@vitrina/api 11.48.0 → 11.49.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/dist/index.d.cts CHANGED
@@ -104396,6 +104396,409 @@ interface paths {
104396
104396
  patch?: never;
104397
104397
  trace?: never;
104398
104398
  };
104399
+ "/ads/scorecard": {
104400
+ parameters: {
104401
+ query?: never;
104402
+ header?: never;
104403
+ path?: never;
104404
+ cookie?: never;
104405
+ };
104406
+ /**
104407
+ * The one per-ad scorecard (ranking, verdicts, the four returns)
104408
+ * @description Every ad over the COVERED window (`max(from, the first measured day)`): spend and cash (first + recurring) from the attribution engine, people, bookings, attended visits and accepted presupuestos from Vitrina’s own rows (the conversations each ad opened), the four ratios, a rank and ONE verdict. Every Ads surface that speaks about one ad reads this — the best-ad card, Creativos, the actions and «¿Por qué?» never compute a return of their own.
104409
+ *
104410
+ * Ranking: accepted-quote return, then cost per person, then bookings. Cash return sorts first only once the window holds `cash_evidence.min_payments` payments credited to ads. An ad with too little spend or too few people is not ranked (`thin`). The top-ranked ad and any ad returning ≥ 1× are never proposed for a pause. Nothing here is a probability.
104411
+ */
104412
+ get: {
104413
+ parameters: {
104414
+ query?: {
104415
+ /** @description Window start (inclusive), YYYY-MM-DD. */
104416
+ from?: string;
104417
+ /** @description Window end (inclusive), YYYY-MM-DD. */
104418
+ to?: string;
104419
+ /** @description Instead of `from`/`to`: the Creativos rolling window as dates (ending today, America/Santiago; `lifetime` = the last 366 days, the engine’s longest range). Default `28d` when neither is sent. Either way the numbers count from the first measured day. */
104420
+ window?: "7d" | "14d" | "28d" | "lifetime";
104421
+ /** @description The attribution model. Defaults to `last_touch`. */
104422
+ model?: string;
104423
+ /** @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. */
104424
+ sample?: "1" | "true";
104425
+ };
104426
+ header?: never;
104427
+ path?: never;
104428
+ cookie?: never;
104429
+ };
104430
+ requestBody?: never;
104431
+ responses: {
104432
+ /** @description The window’s scorecard */
104433
+ 200: {
104434
+ headers: {
104435
+ [name: string]: unknown;
104436
+ };
104437
+ content: {
104438
+ /**
104439
+ * @example {
104440
+ * "data": {
104441
+ * "window": {
104442
+ * "from": "2026-09-20",
104443
+ * "to": "2026-09-30",
104444
+ * "days": 11
104445
+ * },
104446
+ * "coverage": null,
104447
+ * "basis": "accepted",
104448
+ * "cash_evidence": {
104449
+ * "payments": 3,
104450
+ * "min_payments": 5,
104451
+ * "used_for_ranking": false
104452
+ * },
104453
+ * "evidence": {
104454
+ * "thin": true,
104455
+ * "days": 11,
104456
+ * "min_days": 14
104457
+ * },
104458
+ * "rows": [
104459
+ * {
104460
+ * "ad_external_id": "120212000000000101",
104461
+ * "ad_name": "Implantes 2",
104462
+ * "display_name": "Implantes › INTERESES › Implantes 2",
104463
+ * "ad_set_name": "INTERESES",
104464
+ * "campaign_name": "Implantes",
104465
+ * "campaign_external_id": "120210000000000001",
104466
+ * "thumbnail_url": null,
104467
+ * "spend": 57861,
104468
+ * "people": 52,
104469
+ * "booked": 0,
104470
+ * "attended": 0,
104471
+ * "accepted": {
104472
+ * "count": 1,
104473
+ * "value": 1343355
104474
+ * },
104475
+ * "cash": {
104476
+ * "first": 4990,
104477
+ * "recurring": 0,
104478
+ * "total": 4990,
104479
+ * "payments": 1
104480
+ * },
104481
+ * "fatigue": "active",
104482
+ * "ratios": {
104483
+ * "accepted_return": 23.22,
104484
+ * "cash_return": 0.09,
104485
+ * "first_payment_return": 0.09,
104486
+ * "cost_per_person": 1113
104487
+ * },
104488
+ * "rank": 1,
104489
+ * "verdict": "best"
104490
+ * }
104491
+ * ],
104492
+ * "best_ad_external_id": "120212000000000101"
104493
+ * }
104494
+ * }
104495
+ */
104496
+ "application/json": {
104497
+ data: components["schemas"]["AdsScorecard"];
104498
+ };
104499
+ };
104500
+ };
104501
+ /** @description Validation error */
104502
+ 400: {
104503
+ headers: {
104504
+ [name: string]: unknown;
104505
+ };
104506
+ content: {
104507
+ "application/json": components["schemas"]["Error"];
104508
+ };
104509
+ };
104510
+ /** @description Unauthorized */
104511
+ 401: {
104512
+ headers: {
104513
+ [name: string]: unknown;
104514
+ };
104515
+ content: {
104516
+ "application/json": components["schemas"]["Error"];
104517
+ };
104518
+ };
104519
+ /** @description Vitrina Ads is not active for this workspace. `error.code` is `ENTITLEMENT_NOT_ACTIVE`, `error.details.feature` is `vitrina_ads`. */
104520
+ 402: {
104521
+ headers: {
104522
+ [name: string]: unknown;
104523
+ };
104524
+ content: {
104525
+ /**
104526
+ * @example {
104527
+ * "error": {
104528
+ * "code": "ENTITLEMENT_NOT_ACTIVE",
104529
+ * "message": "El complemento Vitrina Ads no está activo en este espacio de trabajo.",
104530
+ * "details": {
104531
+ * "required": [
104532
+ * "vitrina_ads"
104533
+ * ],
104534
+ * "active": [],
104535
+ * "feature": "vitrina_ads",
104536
+ * "entitlement_state": "off"
104537
+ * }
104538
+ * }
104539
+ * }
104540
+ */
104541
+ "application/json": components["schemas"]["Error"];
104542
+ };
104543
+ };
104544
+ /** @description Forbidden */
104545
+ 403: {
104546
+ headers: {
104547
+ [name: string]: unknown;
104548
+ };
104549
+ content: {
104550
+ "application/json": components["schemas"]["Error"];
104551
+ };
104552
+ };
104553
+ /** @description Not found */
104554
+ 404: {
104555
+ headers: {
104556
+ [name: string]: unknown;
104557
+ };
104558
+ content: {
104559
+ "application/json": components["schemas"]["Error"];
104560
+ };
104561
+ };
104562
+ /** @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. */
104563
+ 409: {
104564
+ headers: {
104565
+ [name: string]: unknown;
104566
+ };
104567
+ content: {
104568
+ /**
104569
+ * @example {
104570
+ * "error": {
104571
+ * "code": "ADS_KEY_NEEDS_REMINT",
104572
+ * "message": "Vitrina Ads is active but the delegated key has not finished rotating (key_kind: core)",
104573
+ * "details": {
104574
+ * "key_kind": "core"
104575
+ * }
104576
+ * }
104577
+ * }
104578
+ */
104579
+ "application/json": components["schemas"]["Error"];
104580
+ };
104581
+ };
104582
+ /** @description Rate limited */
104583
+ 429: {
104584
+ headers: {
104585
+ [name: string]: unknown;
104586
+ };
104587
+ content: {
104588
+ "application/json": components["schemas"]["Error"];
104589
+ };
104590
+ };
104591
+ };
104592
+ };
104593
+ put?: never;
104594
+ post?: never;
104595
+ delete?: never;
104596
+ options?: never;
104597
+ head?: never;
104598
+ patch?: never;
104599
+ trace?: never;
104600
+ };
104601
+ "/ads/funnel": {
104602
+ parameters: {
104603
+ query?: never;
104604
+ header?: never;
104605
+ path?: never;
104606
+ cookie?: never;
104607
+ };
104608
+ /**
104609
+ * The period’s people funnel (a cohort, not event counts)
104610
+ * @description The people whose FIRST contact falls in the window, and how many of them reached each step: booked → attended → quote presented → accepted → paid. Each step is a subset of the one before (`conversion` = the share that moved on). Split «desde anuncios» (`ads`) vs every other origin (`other`) by the same rule as the origin buckets. People who were already clients before the window are outside the funnel: `earlier` carries their accepted plans and payments in it. Counts only — no person is identified.
104611
+ */
104612
+ get: {
104613
+ parameters: {
104614
+ query: {
104615
+ /** @description Window start (inclusive), YYYY-MM-DD. */
104616
+ from: string;
104617
+ /** @description Window end (inclusive), YYYY-MM-DD. */
104618
+ to: string;
104619
+ /** @description The attribution model. Defaults to `last_touch`. */
104620
+ model?: string;
104621
+ /** @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. */
104622
+ sample?: "1" | "true";
104623
+ };
104624
+ header?: never;
104625
+ path?: never;
104626
+ cookie?: never;
104627
+ };
104628
+ requestBody?: never;
104629
+ responses: {
104630
+ /** @description The window’s people funnel */
104631
+ 200: {
104632
+ headers: {
104633
+ [name: string]: unknown;
104634
+ };
104635
+ content: {
104636
+ /**
104637
+ * @example {
104638
+ * "data": {
104639
+ * "window": {
104640
+ * "from": "2026-09-01",
104641
+ * "to": "2026-09-30"
104642
+ * },
104643
+ * "steps": [
104644
+ * {
104645
+ * "key": "contacted",
104646
+ * "ads": 215,
104647
+ * "other": 76,
104648
+ * "total": 291,
104649
+ * "conversion": null
104650
+ * },
104651
+ * {
104652
+ * "key": "booked",
104653
+ * "ads": 24,
104654
+ * "other": 19,
104655
+ * "total": 43,
104656
+ * "conversion": 0.148
104657
+ * },
104658
+ * {
104659
+ * "key": "attended",
104660
+ * "ads": 15,
104661
+ * "other": 14,
104662
+ * "total": 29,
104663
+ * "conversion": 0.674
104664
+ * },
104665
+ * {
104666
+ * "key": "quote_presented",
104667
+ * "ads": 11,
104668
+ * "other": 10,
104669
+ * "total": 21,
104670
+ * "conversion": 0.724
104671
+ * },
104672
+ * {
104673
+ * "key": "accepted",
104674
+ * "ads": 5,
104675
+ * "other": 6,
104676
+ * "total": 11,
104677
+ * "conversion": 0.524
104678
+ * },
104679
+ * {
104680
+ * "key": "paid",
104681
+ * "ads": 3,
104682
+ * "other": 5,
104683
+ * "total": 8,
104684
+ * "conversion": 0.727
104685
+ * }
104686
+ * ],
104687
+ * "earlier": {
104688
+ * "people": 30,
104689
+ * "accepted_count": 30,
104690
+ * "accepted_value": 9412000,
104691
+ * "paid_value": 10625399
104692
+ * },
104693
+ * "credit_known": true
104694
+ * }
104695
+ * }
104696
+ */
104697
+ "application/json": {
104698
+ data: components["schemas"]["AdsPeopleFunnel"];
104699
+ };
104700
+ };
104701
+ };
104702
+ /** @description Validation error */
104703
+ 400: {
104704
+ headers: {
104705
+ [name: string]: unknown;
104706
+ };
104707
+ content: {
104708
+ "application/json": components["schemas"]["Error"];
104709
+ };
104710
+ };
104711
+ /** @description Unauthorized */
104712
+ 401: {
104713
+ headers: {
104714
+ [name: string]: unknown;
104715
+ };
104716
+ content: {
104717
+ "application/json": components["schemas"]["Error"];
104718
+ };
104719
+ };
104720
+ /** @description Vitrina Ads is not active for this workspace. `error.code` is `ENTITLEMENT_NOT_ACTIVE`, `error.details.feature` is `vitrina_ads`. */
104721
+ 402: {
104722
+ headers: {
104723
+ [name: string]: unknown;
104724
+ };
104725
+ content: {
104726
+ /**
104727
+ * @example {
104728
+ * "error": {
104729
+ * "code": "ENTITLEMENT_NOT_ACTIVE",
104730
+ * "message": "El complemento Vitrina Ads no está activo en este espacio de trabajo.",
104731
+ * "details": {
104732
+ * "required": [
104733
+ * "vitrina_ads"
104734
+ * ],
104735
+ * "active": [],
104736
+ * "feature": "vitrina_ads",
104737
+ * "entitlement_state": "off"
104738
+ * }
104739
+ * }
104740
+ * }
104741
+ */
104742
+ "application/json": components["schemas"]["Error"];
104743
+ };
104744
+ };
104745
+ /** @description Forbidden */
104746
+ 403: {
104747
+ headers: {
104748
+ [name: string]: unknown;
104749
+ };
104750
+ content: {
104751
+ "application/json": components["schemas"]["Error"];
104752
+ };
104753
+ };
104754
+ /** @description Not found */
104755
+ 404: {
104756
+ headers: {
104757
+ [name: string]: unknown;
104758
+ };
104759
+ content: {
104760
+ "application/json": components["schemas"]["Error"];
104761
+ };
104762
+ };
104763
+ /** @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. */
104764
+ 409: {
104765
+ headers: {
104766
+ [name: string]: unknown;
104767
+ };
104768
+ content: {
104769
+ /**
104770
+ * @example {
104771
+ * "error": {
104772
+ * "code": "ADS_KEY_NEEDS_REMINT",
104773
+ * "message": "Vitrina Ads is active but the delegated key has not finished rotating (key_kind: core)",
104774
+ * "details": {
104775
+ * "key_kind": "core"
104776
+ * }
104777
+ * }
104778
+ * }
104779
+ */
104780
+ "application/json": components["schemas"]["Error"];
104781
+ };
104782
+ };
104783
+ /** @description Rate limited */
104784
+ 429: {
104785
+ headers: {
104786
+ [name: string]: unknown;
104787
+ };
104788
+ content: {
104789
+ "application/json": components["schemas"]["Error"];
104790
+ };
104791
+ };
104792
+ };
104793
+ };
104794
+ put?: never;
104795
+ post?: never;
104796
+ delete?: never;
104797
+ options?: never;
104798
+ head?: never;
104799
+ patch?: never;
104800
+ trace?: never;
104801
+ };
104399
104802
  "/ads/health": {
104400
104803
  parameters: {
104401
104804
  query?: never;
@@ -130923,6 +131326,10 @@ interface components {
130923
131326
  cash: number | null;
130924
131327
  /** @description cash ÷ spend. `null` when no payment was recorded in the period (see `cash_recorded`) — the return is unknown then, never 0×. */
130925
131328
  return: number | null;
131329
+ /** @description The recorded value of the accepted presupuestos / closed sales of the conversations the entity opened (CLP) — pipeline, never cash. `null` = unknown. */
131330
+ accepted_value?: number | null;
131331
+ /** @description `accepted_value` ÷ spend («Retorno en presupuestos»). `null` = unknown or no spend. */
131332
+ accepted_return?: number | null;
130926
131333
  /** @description Meta’s OWN figures (its 7-day window, every sender) — never added to Vitrina’s. */
130927
131334
  meta: {
130928
131335
  conversations_started: number | null;
@@ -130983,6 +131390,10 @@ interface components {
130983
131390
  cash: number | null;
130984
131391
  /** @description cash ÷ spend. `null` when no payment was recorded in the period (see `cash_recorded`) — the return is unknown then, never 0×. */
130985
131392
  return: number | null;
131393
+ /** @description The recorded value of the accepted presupuestos / closed sales of the conversations the entity opened (CLP) — pipeline, never cash. `null` = unknown. */
131394
+ accepted_value?: number | null;
131395
+ /** @description `accepted_value` ÷ spend («Retorno en presupuestos»). `null` = unknown or no spend. */
131396
+ accepted_return?: number | null;
130986
131397
  /** @description Meta’s OWN figures (its 7-day window, every sender) — never added to Vitrina’s. */
130987
131398
  meta: {
130988
131399
  conversations_started: number | null;
@@ -131054,6 +131465,10 @@ interface components {
131054
131465
  cash: number | null;
131055
131466
  /** @description cash ÷ spend. `null` when no payment was recorded in the period (see `cash_recorded`) — the return is unknown then, never 0×. */
131056
131467
  return: number | null;
131468
+ /** @description The recorded value of the accepted presupuestos / closed sales of the conversations the entity opened (CLP) — pipeline, never cash. `null` = unknown. */
131469
+ accepted_value?: number | null;
131470
+ /** @description `accepted_value` ÷ spend («Retorno en presupuestos»). `null` = unknown or no spend. */
131471
+ accepted_return?: number | null;
131057
131472
  /** @description Meta’s OWN figures (its 7-day window, every sender) — never added to Vitrina’s. */
131058
131473
  meta: {
131059
131474
  conversations_started: number | null;
@@ -131362,6 +131777,102 @@ interface components {
131362
131777
  }[];
131363
131778
  coverage?: components["schemas"]["AdsCoverage"] & unknown;
131364
131779
  };
131780
+ AdsScorecard: {
131781
+ window: {
131782
+ from: string;
131783
+ to: string;
131784
+ days: number;
131785
+ };
131786
+ coverage: components["schemas"]["AdsCoverage"] & (Record<string, never> | null);
131787
+ /**
131788
+ * @description What the ranking sorts by first: the accepted-quote return, or cash once the window holds `cash_evidence.min_payments` payments.
131789
+ * @enum {string}
131790
+ */
131791
+ basis: "accepted" | "cash";
131792
+ cash_evidence: {
131793
+ payments: number;
131794
+ min_payments: number;
131795
+ used_for_ranking: boolean;
131796
+ };
131797
+ evidence: {
131798
+ thin: boolean;
131799
+ days: number;
131800
+ min_days: number;
131801
+ };
131802
+ rows: {
131803
+ ad_external_id: string;
131804
+ ad_name: string | null;
131805
+ /** @description The name to print: `ad_name`; an ad sharing its name with another is printed as «Campaña › Conjunto › Anuncio» (the id’s last digits follow only when even that path repeats). */
131806
+ display_name: string;
131807
+ ad_set_name: string | null;
131808
+ campaign_name: string | null;
131809
+ campaign_external_id: string | null;
131810
+ thumbnail_url: string | null;
131811
+ /** @description Spend over the covered window. */
131812
+ spend: number | null;
131813
+ /** @description Distinct people whose conversation the ad opened in the window. */
131814
+ people: number | null;
131815
+ booked: number | null;
131816
+ attended: number | null;
131817
+ /** @description Accepted presupuestos / closed sales — pipeline, never cash. */
131818
+ accepted: {
131819
+ count: number;
131820
+ value: number;
131821
+ } | null;
131822
+ cash: {
131823
+ first: number;
131824
+ recurring: number;
131825
+ total: number;
131826
+ payments: number;
131827
+ } | null;
131828
+ /**
131829
+ * @description The OBSERVED delivery state (`degraded` = se desgasta).
131830
+ * @enum {string|null}
131831
+ */
131832
+ fatigue: "active" | "paused" | "degraded" | null;
131833
+ ratios: {
131834
+ /** @description Accepted presupuestos / closed sales ÷ spend (×). */
131835
+ accepted_return: number | null;
131836
+ /** @description Cash (first + recurring payments) ÷ spend (×). */
131837
+ cash_return: number | null;
131838
+ /** @description First-payment cash ÷ spend (×). */
131839
+ first_payment_return: number | null;
131840
+ /** @description Spend ÷ people (CLP). */
131841
+ cost_per_person: number | null;
131842
+ };
131843
+ /** @description 1 = the best ad; null = not ranked (too little spend or people). */
131844
+ rank: number | null;
131845
+ /**
131846
+ * @description `best` rank 1 · `pays` returns ≥ 1× · `refresh` returns ≥ 1× but wears out · `pause` meets every pause rule · `thin` too little data · `watch` the rest. Never a probability.
131847
+ * @enum {string}
131848
+ */
131849
+ verdict: "best" | "pays" | "refresh" | "pause" | "watch" | "thin";
131850
+ }[];
131851
+ best_ad_external_id: string | null;
131852
+ };
131853
+ AdsPeopleFunnel: {
131854
+ window: {
131855
+ from: string;
131856
+ to: string;
131857
+ };
131858
+ steps: {
131859
+ /** @enum {string} */
131860
+ key: "contacted" | "booked" | "attended" | "quote_presented" | "accepted" | "paid";
131861
+ ads: number;
131862
+ other: number;
131863
+ total: number;
131864
+ /** @description total ÷ the previous step’s total (0–1). */
131865
+ conversion: number | null;
131866
+ }[];
131867
+ /** @description People whose first contact came BEFORE the window: their accepted plans and payments in it — outside the funnel. */
131868
+ earlier: {
131869
+ people: number;
131870
+ accepted_count: number;
131871
+ accepted_value: number;
131872
+ paid_value: number;
131873
+ };
131874
+ credit_known: boolean;
131875
+ };
131365
131876
  AdsSignalComponent: {
131366
131877
  /** @enum {string} */
131367
131878
  key: "meta" | "origin" | "site_tag";
package/dist/index.d.ts CHANGED
@@ -104396,6 +104396,409 @@ interface paths {
104396
104396
  patch?: never;
104397
104397
  trace?: never;
104398
104398
  };
104399
+ "/ads/scorecard": {
104400
+ parameters: {
104401
+ query?: never;
104402
+ header?: never;
104403
+ path?: never;
104404
+ cookie?: never;
104405
+ };
104406
+ /**
104407
+ * The one per-ad scorecard (ranking, verdicts, the four returns)
104408
+ * @description Every ad over the COVERED window (`max(from, the first measured day)`): spend and cash (first + recurring) from the attribution engine, people, bookings, attended visits and accepted presupuestos from Vitrina’s own rows (the conversations each ad opened), the four ratios, a rank and ONE verdict. Every Ads surface that speaks about one ad reads this — the best-ad card, Creativos, the actions and «¿Por qué?» never compute a return of their own.
104409
+ *
104410
+ * Ranking: accepted-quote return, then cost per person, then bookings. Cash return sorts first only once the window holds `cash_evidence.min_payments` payments credited to ads. An ad with too little spend or too few people is not ranked (`thin`). The top-ranked ad and any ad returning ≥ 1× are never proposed for a pause. Nothing here is a probability.
104411
+ */
104412
+ get: {
104413
+ parameters: {
104414
+ query?: {
104415
+ /** @description Window start (inclusive), YYYY-MM-DD. */
104416
+ from?: string;
104417
+ /** @description Window end (inclusive), YYYY-MM-DD. */
104418
+ to?: string;
104419
+ /** @description Instead of `from`/`to`: the Creativos rolling window as dates (ending today, America/Santiago; `lifetime` = the last 366 days, the engine’s longest range). Default `28d` when neither is sent. Either way the numbers count from the first measured day. */
104420
+ window?: "7d" | "14d" | "28d" | "lifetime";
104421
+ /** @description The attribution model. Defaults to `last_touch`. */
104422
+ model?: string;
104423
+ /** @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. */
104424
+ sample?: "1" | "true";
104425
+ };
104426
+ header?: never;
104427
+ path?: never;
104428
+ cookie?: never;
104429
+ };
104430
+ requestBody?: never;
104431
+ responses: {
104432
+ /** @description The window’s scorecard */
104433
+ 200: {
104434
+ headers: {
104435
+ [name: string]: unknown;
104436
+ };
104437
+ content: {
104438
+ /**
104439
+ * @example {
104440
+ * "data": {
104441
+ * "window": {
104442
+ * "from": "2026-09-20",
104443
+ * "to": "2026-09-30",
104444
+ * "days": 11
104445
+ * },
104446
+ * "coverage": null,
104447
+ * "basis": "accepted",
104448
+ * "cash_evidence": {
104449
+ * "payments": 3,
104450
+ * "min_payments": 5,
104451
+ * "used_for_ranking": false
104452
+ * },
104453
+ * "evidence": {
104454
+ * "thin": true,
104455
+ * "days": 11,
104456
+ * "min_days": 14
104457
+ * },
104458
+ * "rows": [
104459
+ * {
104460
+ * "ad_external_id": "120212000000000101",
104461
+ * "ad_name": "Implantes 2",
104462
+ * "display_name": "Implantes › INTERESES › Implantes 2",
104463
+ * "ad_set_name": "INTERESES",
104464
+ * "campaign_name": "Implantes",
104465
+ * "campaign_external_id": "120210000000000001",
104466
+ * "thumbnail_url": null,
104467
+ * "spend": 57861,
104468
+ * "people": 52,
104469
+ * "booked": 0,
104470
+ * "attended": 0,
104471
+ * "accepted": {
104472
+ * "count": 1,
104473
+ * "value": 1343355
104474
+ * },
104475
+ * "cash": {
104476
+ * "first": 4990,
104477
+ * "recurring": 0,
104478
+ * "total": 4990,
104479
+ * "payments": 1
104480
+ * },
104481
+ * "fatigue": "active",
104482
+ * "ratios": {
104483
+ * "accepted_return": 23.22,
104484
+ * "cash_return": 0.09,
104485
+ * "first_payment_return": 0.09,
104486
+ * "cost_per_person": 1113
104487
+ * },
104488
+ * "rank": 1,
104489
+ * "verdict": "best"
104490
+ * }
104491
+ * ],
104492
+ * "best_ad_external_id": "120212000000000101"
104493
+ * }
104494
+ * }
104495
+ */
104496
+ "application/json": {
104497
+ data: components["schemas"]["AdsScorecard"];
104498
+ };
104499
+ };
104500
+ };
104501
+ /** @description Validation error */
104502
+ 400: {
104503
+ headers: {
104504
+ [name: string]: unknown;
104505
+ };
104506
+ content: {
104507
+ "application/json": components["schemas"]["Error"];
104508
+ };
104509
+ };
104510
+ /** @description Unauthorized */
104511
+ 401: {
104512
+ headers: {
104513
+ [name: string]: unknown;
104514
+ };
104515
+ content: {
104516
+ "application/json": components["schemas"]["Error"];
104517
+ };
104518
+ };
104519
+ /** @description Vitrina Ads is not active for this workspace. `error.code` is `ENTITLEMENT_NOT_ACTIVE`, `error.details.feature` is `vitrina_ads`. */
104520
+ 402: {
104521
+ headers: {
104522
+ [name: string]: unknown;
104523
+ };
104524
+ content: {
104525
+ /**
104526
+ * @example {
104527
+ * "error": {
104528
+ * "code": "ENTITLEMENT_NOT_ACTIVE",
104529
+ * "message": "El complemento Vitrina Ads no está activo en este espacio de trabajo.",
104530
+ * "details": {
104531
+ * "required": [
104532
+ * "vitrina_ads"
104533
+ * ],
104534
+ * "active": [],
104535
+ * "feature": "vitrina_ads",
104536
+ * "entitlement_state": "off"
104537
+ * }
104538
+ * }
104539
+ * }
104540
+ */
104541
+ "application/json": components["schemas"]["Error"];
104542
+ };
104543
+ };
104544
+ /** @description Forbidden */
104545
+ 403: {
104546
+ headers: {
104547
+ [name: string]: unknown;
104548
+ };
104549
+ content: {
104550
+ "application/json": components["schemas"]["Error"];
104551
+ };
104552
+ };
104553
+ /** @description Not found */
104554
+ 404: {
104555
+ headers: {
104556
+ [name: string]: unknown;
104557
+ };
104558
+ content: {
104559
+ "application/json": components["schemas"]["Error"];
104560
+ };
104561
+ };
104562
+ /** @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. */
104563
+ 409: {
104564
+ headers: {
104565
+ [name: string]: unknown;
104566
+ };
104567
+ content: {
104568
+ /**
104569
+ * @example {
104570
+ * "error": {
104571
+ * "code": "ADS_KEY_NEEDS_REMINT",
104572
+ * "message": "Vitrina Ads is active but the delegated key has not finished rotating (key_kind: core)",
104573
+ * "details": {
104574
+ * "key_kind": "core"
104575
+ * }
104576
+ * }
104577
+ * }
104578
+ */
104579
+ "application/json": components["schemas"]["Error"];
104580
+ };
104581
+ };
104582
+ /** @description Rate limited */
104583
+ 429: {
104584
+ headers: {
104585
+ [name: string]: unknown;
104586
+ };
104587
+ content: {
104588
+ "application/json": components["schemas"]["Error"];
104589
+ };
104590
+ };
104591
+ };
104592
+ };
104593
+ put?: never;
104594
+ post?: never;
104595
+ delete?: never;
104596
+ options?: never;
104597
+ head?: never;
104598
+ patch?: never;
104599
+ trace?: never;
104600
+ };
104601
+ "/ads/funnel": {
104602
+ parameters: {
104603
+ query?: never;
104604
+ header?: never;
104605
+ path?: never;
104606
+ cookie?: never;
104607
+ };
104608
+ /**
104609
+ * The period’s people funnel (a cohort, not event counts)
104610
+ * @description The people whose FIRST contact falls in the window, and how many of them reached each step: booked → attended → quote presented → accepted → paid. Each step is a subset of the one before (`conversion` = the share that moved on). Split «desde anuncios» (`ads`) vs every other origin (`other`) by the same rule as the origin buckets. People who were already clients before the window are outside the funnel: `earlier` carries their accepted plans and payments in it. Counts only — no person is identified.
104611
+ */
104612
+ get: {
104613
+ parameters: {
104614
+ query: {
104615
+ /** @description Window start (inclusive), YYYY-MM-DD. */
104616
+ from: string;
104617
+ /** @description Window end (inclusive), YYYY-MM-DD. */
104618
+ to: string;
104619
+ /** @description The attribution model. Defaults to `last_touch`. */
104620
+ model?: string;
104621
+ /** @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. */
104622
+ sample?: "1" | "true";
104623
+ };
104624
+ header?: never;
104625
+ path?: never;
104626
+ cookie?: never;
104627
+ };
104628
+ requestBody?: never;
104629
+ responses: {
104630
+ /** @description The window’s people funnel */
104631
+ 200: {
104632
+ headers: {
104633
+ [name: string]: unknown;
104634
+ };
104635
+ content: {
104636
+ /**
104637
+ * @example {
104638
+ * "data": {
104639
+ * "window": {
104640
+ * "from": "2026-09-01",
104641
+ * "to": "2026-09-30"
104642
+ * },
104643
+ * "steps": [
104644
+ * {
104645
+ * "key": "contacted",
104646
+ * "ads": 215,
104647
+ * "other": 76,
104648
+ * "total": 291,
104649
+ * "conversion": null
104650
+ * },
104651
+ * {
104652
+ * "key": "booked",
104653
+ * "ads": 24,
104654
+ * "other": 19,
104655
+ * "total": 43,
104656
+ * "conversion": 0.148
104657
+ * },
104658
+ * {
104659
+ * "key": "attended",
104660
+ * "ads": 15,
104661
+ * "other": 14,
104662
+ * "total": 29,
104663
+ * "conversion": 0.674
104664
+ * },
104665
+ * {
104666
+ * "key": "quote_presented",
104667
+ * "ads": 11,
104668
+ * "other": 10,
104669
+ * "total": 21,
104670
+ * "conversion": 0.724
104671
+ * },
104672
+ * {
104673
+ * "key": "accepted",
104674
+ * "ads": 5,
104675
+ * "other": 6,
104676
+ * "total": 11,
104677
+ * "conversion": 0.524
104678
+ * },
104679
+ * {
104680
+ * "key": "paid",
104681
+ * "ads": 3,
104682
+ * "other": 5,
104683
+ * "total": 8,
104684
+ * "conversion": 0.727
104685
+ * }
104686
+ * ],
104687
+ * "earlier": {
104688
+ * "people": 30,
104689
+ * "accepted_count": 30,
104690
+ * "accepted_value": 9412000,
104691
+ * "paid_value": 10625399
104692
+ * },
104693
+ * "credit_known": true
104694
+ * }
104695
+ * }
104696
+ */
104697
+ "application/json": {
104698
+ data: components["schemas"]["AdsPeopleFunnel"];
104699
+ };
104700
+ };
104701
+ };
104702
+ /** @description Validation error */
104703
+ 400: {
104704
+ headers: {
104705
+ [name: string]: unknown;
104706
+ };
104707
+ content: {
104708
+ "application/json": components["schemas"]["Error"];
104709
+ };
104710
+ };
104711
+ /** @description Unauthorized */
104712
+ 401: {
104713
+ headers: {
104714
+ [name: string]: unknown;
104715
+ };
104716
+ content: {
104717
+ "application/json": components["schemas"]["Error"];
104718
+ };
104719
+ };
104720
+ /** @description Vitrina Ads is not active for this workspace. `error.code` is `ENTITLEMENT_NOT_ACTIVE`, `error.details.feature` is `vitrina_ads`. */
104721
+ 402: {
104722
+ headers: {
104723
+ [name: string]: unknown;
104724
+ };
104725
+ content: {
104726
+ /**
104727
+ * @example {
104728
+ * "error": {
104729
+ * "code": "ENTITLEMENT_NOT_ACTIVE",
104730
+ * "message": "El complemento Vitrina Ads no está activo en este espacio de trabajo.",
104731
+ * "details": {
104732
+ * "required": [
104733
+ * "vitrina_ads"
104734
+ * ],
104735
+ * "active": [],
104736
+ * "feature": "vitrina_ads",
104737
+ * "entitlement_state": "off"
104738
+ * }
104739
+ * }
104740
+ * }
104741
+ */
104742
+ "application/json": components["schemas"]["Error"];
104743
+ };
104744
+ };
104745
+ /** @description Forbidden */
104746
+ 403: {
104747
+ headers: {
104748
+ [name: string]: unknown;
104749
+ };
104750
+ content: {
104751
+ "application/json": components["schemas"]["Error"];
104752
+ };
104753
+ };
104754
+ /** @description Not found */
104755
+ 404: {
104756
+ headers: {
104757
+ [name: string]: unknown;
104758
+ };
104759
+ content: {
104760
+ "application/json": components["schemas"]["Error"];
104761
+ };
104762
+ };
104763
+ /** @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. */
104764
+ 409: {
104765
+ headers: {
104766
+ [name: string]: unknown;
104767
+ };
104768
+ content: {
104769
+ /**
104770
+ * @example {
104771
+ * "error": {
104772
+ * "code": "ADS_KEY_NEEDS_REMINT",
104773
+ * "message": "Vitrina Ads is active but the delegated key has not finished rotating (key_kind: core)",
104774
+ * "details": {
104775
+ * "key_kind": "core"
104776
+ * }
104777
+ * }
104778
+ * }
104779
+ */
104780
+ "application/json": components["schemas"]["Error"];
104781
+ };
104782
+ };
104783
+ /** @description Rate limited */
104784
+ 429: {
104785
+ headers: {
104786
+ [name: string]: unknown;
104787
+ };
104788
+ content: {
104789
+ "application/json": components["schemas"]["Error"];
104790
+ };
104791
+ };
104792
+ };
104793
+ };
104794
+ put?: never;
104795
+ post?: never;
104796
+ delete?: never;
104797
+ options?: never;
104798
+ head?: never;
104799
+ patch?: never;
104800
+ trace?: never;
104801
+ };
104399
104802
  "/ads/health": {
104400
104803
  parameters: {
104401
104804
  query?: never;
@@ -130923,6 +131326,10 @@ interface components {
130923
131326
  cash: number | null;
130924
131327
  /** @description cash ÷ spend. `null` when no payment was recorded in the period (see `cash_recorded`) — the return is unknown then, never 0×. */
130925
131328
  return: number | null;
131329
+ /** @description The recorded value of the accepted presupuestos / closed sales of the conversations the entity opened (CLP) — pipeline, never cash. `null` = unknown. */
131330
+ accepted_value?: number | null;
131331
+ /** @description `accepted_value` ÷ spend («Retorno en presupuestos»). `null` = unknown or no spend. */
131332
+ accepted_return?: number | null;
130926
131333
  /** @description Meta’s OWN figures (its 7-day window, every sender) — never added to Vitrina’s. */
130927
131334
  meta: {
130928
131335
  conversations_started: number | null;
@@ -130983,6 +131390,10 @@ interface components {
130983
131390
  cash: number | null;
130984
131391
  /** @description cash ÷ spend. `null` when no payment was recorded in the period (see `cash_recorded`) — the return is unknown then, never 0×. */
130985
131392
  return: number | null;
131393
+ /** @description The recorded value of the accepted presupuestos / closed sales of the conversations the entity opened (CLP) — pipeline, never cash. `null` = unknown. */
131394
+ accepted_value?: number | null;
131395
+ /** @description `accepted_value` ÷ spend («Retorno en presupuestos»). `null` = unknown or no spend. */
131396
+ accepted_return?: number | null;
130986
131397
  /** @description Meta’s OWN figures (its 7-day window, every sender) — never added to Vitrina’s. */
130987
131398
  meta: {
130988
131399
  conversations_started: number | null;
@@ -131054,6 +131465,10 @@ interface components {
131054
131465
  cash: number | null;
131055
131466
  /** @description cash ÷ spend. `null` when no payment was recorded in the period (see `cash_recorded`) — the return is unknown then, never 0×. */
131056
131467
  return: number | null;
131468
+ /** @description The recorded value of the accepted presupuestos / closed sales of the conversations the entity opened (CLP) — pipeline, never cash. `null` = unknown. */
131469
+ accepted_value?: number | null;
131470
+ /** @description `accepted_value` ÷ spend («Retorno en presupuestos»). `null` = unknown or no spend. */
131471
+ accepted_return?: number | null;
131057
131472
  /** @description Meta’s OWN figures (its 7-day window, every sender) — never added to Vitrina’s. */
131058
131473
  meta: {
131059
131474
  conversations_started: number | null;
@@ -131362,6 +131777,102 @@ interface components {
131362
131777
  }[];
131363
131778
  coverage?: components["schemas"]["AdsCoverage"] & unknown;
131364
131779
  };
131780
+ AdsScorecard: {
131781
+ window: {
131782
+ from: string;
131783
+ to: string;
131784
+ days: number;
131785
+ };
131786
+ coverage: components["schemas"]["AdsCoverage"] & (Record<string, never> | null);
131787
+ /**
131788
+ * @description What the ranking sorts by first: the accepted-quote return, or cash once the window holds `cash_evidence.min_payments` payments.
131789
+ * @enum {string}
131790
+ */
131791
+ basis: "accepted" | "cash";
131792
+ cash_evidence: {
131793
+ payments: number;
131794
+ min_payments: number;
131795
+ used_for_ranking: boolean;
131796
+ };
131797
+ evidence: {
131798
+ thin: boolean;
131799
+ days: number;
131800
+ min_days: number;
131801
+ };
131802
+ rows: {
131803
+ ad_external_id: string;
131804
+ ad_name: string | null;
131805
+ /** @description The name to print: `ad_name`; an ad sharing its name with another is printed as «Campaña › Conjunto › Anuncio» (the id’s last digits follow only when even that path repeats). */
131806
+ display_name: string;
131807
+ ad_set_name: string | null;
131808
+ campaign_name: string | null;
131809
+ campaign_external_id: string | null;
131810
+ thumbnail_url: string | null;
131811
+ /** @description Spend over the covered window. */
131812
+ spend: number | null;
131813
+ /** @description Distinct people whose conversation the ad opened in the window. */
131814
+ people: number | null;
131815
+ booked: number | null;
131816
+ attended: number | null;
131817
+ /** @description Accepted presupuestos / closed sales — pipeline, never cash. */
131818
+ accepted: {
131819
+ count: number;
131820
+ value: number;
131821
+ } | null;
131822
+ cash: {
131823
+ first: number;
131824
+ recurring: number;
131825
+ total: number;
131826
+ payments: number;
131827
+ } | null;
131828
+ /**
131829
+ * @description The OBSERVED delivery state (`degraded` = se desgasta).
131830
+ * @enum {string|null}
131831
+ */
131832
+ fatigue: "active" | "paused" | "degraded" | null;
131833
+ ratios: {
131834
+ /** @description Accepted presupuestos / closed sales ÷ spend (×). */
131835
+ accepted_return: number | null;
131836
+ /** @description Cash (first + recurring payments) ÷ spend (×). */
131837
+ cash_return: number | null;
131838
+ /** @description First-payment cash ÷ spend (×). */
131839
+ first_payment_return: number | null;
131840
+ /** @description Spend ÷ people (CLP). */
131841
+ cost_per_person: number | null;
131842
+ };
131843
+ /** @description 1 = the best ad; null = not ranked (too little spend or people). */
131844
+ rank: number | null;
131845
+ /**
131846
+ * @description `best` rank 1 · `pays` returns ≥ 1× · `refresh` returns ≥ 1× but wears out · `pause` meets every pause rule · `thin` too little data · `watch` the rest. Never a probability.
131847
+ * @enum {string}
131848
+ */
131849
+ verdict: "best" | "pays" | "refresh" | "pause" | "watch" | "thin";
131850
+ }[];
131851
+ best_ad_external_id: string | null;
131852
+ };
131853
+ AdsPeopleFunnel: {
131854
+ window: {
131855
+ from: string;
131856
+ to: string;
131857
+ };
131858
+ steps: {
131859
+ /** @enum {string} */
131860
+ key: "contacted" | "booked" | "attended" | "quote_presented" | "accepted" | "paid";
131861
+ ads: number;
131862
+ other: number;
131863
+ total: number;
131864
+ /** @description total ÷ the previous step’s total (0–1). */
131865
+ conversion: number | null;
131866
+ }[];
131867
+ /** @description People whose first contact came BEFORE the window: their accepted plans and payments in it — outside the funnel. */
131868
+ earlier: {
131869
+ people: number;
131870
+ accepted_count: number;
131871
+ accepted_value: number;
131872
+ paid_value: number;
131873
+ };
131874
+ credit_known: boolean;
131875
+ };
131365
131876
  AdsSignalComponent: {
131366
131877
  /** @enum {string} */
131367
131878
  key: "meta" | "origin" | "site_tag";
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@vitrina/api",
3
- "version": "11.48.0",
3
+ "version": "11.49.0",
4
4
  "description": "Typed TypeScript SDK for the Vitrina API pública — generated from the committed openapi.public.json (ADR 0106).",
5
5
  "type": "module",
6
6
  "license": "MIT",