@atribu/node 0.1.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 (46) hide show
  1. package/CHANGELOG.md +27 -0
  2. package/LICENSE +21 -0
  3. package/README.md +423 -0
  4. package/dist/admin/index.cjs +326 -0
  5. package/dist/admin/index.cjs.map +1 -0
  6. package/dist/admin/index.d.cts +46 -0
  7. package/dist/admin/index.d.ts +46 -0
  8. package/dist/admin/index.js +323 -0
  9. package/dist/admin/index.js.map +1 -0
  10. package/dist/api.d-BXINTQo6.d.cts +3547 -0
  11. package/dist/api.d-BXINTQo6.d.ts +3547 -0
  12. package/dist/errors-D3ApBz8J.d.cts +86 -0
  13. package/dist/errors-D3ApBz8J.d.ts +86 -0
  14. package/dist/index.cjs +549 -0
  15. package/dist/index.cjs.map +1 -0
  16. package/dist/index.d.cts +198 -0
  17. package/dist/index.d.ts +198 -0
  18. package/dist/index.js +536 -0
  19. package/dist/index.js.map +1 -0
  20. package/dist/next/index.cjs +153 -0
  21. package/dist/next/index.cjs.map +1 -0
  22. package/dist/next/index.d.cts +43 -0
  23. package/dist/next/index.d.ts +43 -0
  24. package/dist/next/index.js +151 -0
  25. package/dist/next/index.js.map +1 -0
  26. package/dist/oauth/index.cjs +299 -0
  27. package/dist/oauth/index.cjs.map +1 -0
  28. package/dist/oauth/index.d.cts +117 -0
  29. package/dist/oauth/index.d.ts +117 -0
  30. package/dist/oauth/index.js +291 -0
  31. package/dist/oauth/index.js.map +1 -0
  32. package/dist/test/index.cjs +443 -0
  33. package/dist/test/index.cjs.map +1 -0
  34. package/dist/test/index.d.cts +321 -0
  35. package/dist/test/index.d.ts +321 -0
  36. package/dist/test/index.js +437 -0
  37. package/dist/test/index.js.map +1 -0
  38. package/dist/types-Dc6tIN_V.d.cts +101 -0
  39. package/dist/types-Dc6tIN_V.d.ts +101 -0
  40. package/dist/webhooks/index.cjs +97 -0
  41. package/dist/webhooks/index.cjs.map +1 -0
  42. package/dist/webhooks/index.d.cts +35 -0
  43. package/dist/webhooks/index.d.ts +35 -0
  44. package/dist/webhooks/index.js +94 -0
  45. package/dist/webhooks/index.js.map +1 -0
  46. package/package.json +101 -0
@@ -0,0 +1,3547 @@
1
+ /**
2
+ * HTTP request layer.
3
+ *
4
+ * Single entry point for every API call: handles auth headers, timeout via
5
+ * AbortController, idempotency-key generation, error envelope parsing, and
6
+ * RetryHint derivation. Resources call `request()` and parse `data` from the
7
+ * envelope.
8
+ */
9
+
10
+ interface RequestOptions {
11
+ method: "GET" | "POST" | "PATCH" | "DELETE" | "PUT";
12
+ path: string;
13
+ query?: Record<string, string | number | boolean | undefined | null>;
14
+ body?: unknown;
15
+ /** Form-urlencoded body (used by /oauth/token, /oauth/revoke). */
16
+ form?: Record<string, string>;
17
+ /** Override the Authorization header (used by /oauth/* with client-credentials). */
18
+ authOverride?: string;
19
+ idempotencyKey?: string;
20
+ signal?: AbortSignal;
21
+ /** When true, parse 200-body as RFC 6749/7009 OAuth response shape. */
22
+ oauthErrorShape?: boolean;
23
+ /** When true, return raw Response without JSON parse (used by 204 / RFC 7009 empty 200). */
24
+ expectEmpty?: boolean;
25
+ /** Extra headers to merge. */
26
+ headers?: Record<string, string>;
27
+ }
28
+ /**
29
+ * Minimum surface a transport needs to be usable by resources. Lets us
30
+ * stack RetryingHttpClient on top of HttpClient without inheritance.
31
+ */
32
+ interface HttpClientLike {
33
+ request<T>(opts: RequestOptions): Promise<T>;
34
+ }
35
+
36
+ /**
37
+ * This file was auto-generated by openapi-typescript.
38
+ * Do not make direct changes to the file.
39
+ */
40
+
41
+ interface paths {
42
+ "/api/v1/overview": {
43
+ parameters: {
44
+ query?: never;
45
+ header?: never;
46
+ path?: never;
47
+ cookie?: never;
48
+ };
49
+ /**
50
+ * Get dashboard overview
51
+ * @description Returns KPIs (spend, revenue, ROAS, CAC), visitor metrics, and comparison with the previous period of equal length.
52
+ */
53
+ get: {
54
+ parameters: {
55
+ query: {
56
+ date_from: string;
57
+ date_to: string;
58
+ model?: string;
59
+ };
60
+ header?: never;
61
+ path?: never;
62
+ cookie?: never;
63
+ };
64
+ requestBody?: never;
65
+ responses: {
66
+ /** @description Overview data */
67
+ 200: {
68
+ headers: {
69
+ [name: string]: unknown;
70
+ };
71
+ content: {
72
+ "application/json": components["schemas"]["OverviewResponse"];
73
+ };
74
+ };
75
+ /** @description Unauthorized */
76
+ 401: {
77
+ headers: {
78
+ [name: string]: unknown;
79
+ };
80
+ content: {
81
+ "application/json": components["schemas"]["ErrorResponse"];
82
+ };
83
+ };
84
+ /** @description Rate limited */
85
+ 429: {
86
+ headers: {
87
+ [name: string]: unknown;
88
+ };
89
+ content: {
90
+ "application/json": components["schemas"]["ErrorResponse"];
91
+ };
92
+ };
93
+ };
94
+ };
95
+ put?: never;
96
+ post?: never;
97
+ delete?: never;
98
+ options?: never;
99
+ head?: never;
100
+ patch?: never;
101
+ trace?: never;
102
+ };
103
+ "/api/v1/timeseries": {
104
+ parameters: {
105
+ query?: never;
106
+ header?: never;
107
+ path?: never;
108
+ cookie?: never;
109
+ };
110
+ /**
111
+ * Get daily timeseries data
112
+ * @description Returns daily visitors, pageviews, bounces, revenue, and spend.
113
+ */
114
+ get: {
115
+ parameters: {
116
+ query: {
117
+ date_from: string;
118
+ date_to: string;
119
+ };
120
+ header?: never;
121
+ path?: never;
122
+ cookie?: never;
123
+ };
124
+ requestBody?: never;
125
+ responses: {
126
+ /** @description Timeseries data */
127
+ 200: {
128
+ headers: {
129
+ [name: string]: unknown;
130
+ };
131
+ content: {
132
+ "application/json": {
133
+ data: {
134
+ date: string;
135
+ visitors: number;
136
+ pageviews: number;
137
+ bounces: number;
138
+ cash_revenue: number;
139
+ spend: number;
140
+ }[];
141
+ meta: components["schemas"]["Meta"];
142
+ };
143
+ };
144
+ };
145
+ };
146
+ };
147
+ put?: never;
148
+ post?: never;
149
+ delete?: never;
150
+ options?: never;
151
+ head?: never;
152
+ patch?: never;
153
+ trace?: never;
154
+ };
155
+ "/api/v1/realtime": {
156
+ parameters: {
157
+ query?: never;
158
+ header?: never;
159
+ path?: never;
160
+ cookie?: never;
161
+ };
162
+ /**
163
+ * Get live visitor count
164
+ * @description Returns the number of visitors currently online (active in last 5 minutes).
165
+ */
166
+ get: {
167
+ parameters: {
168
+ query?: never;
169
+ header?: never;
170
+ path?: never;
171
+ cookie?: never;
172
+ };
173
+ requestBody?: never;
174
+ responses: {
175
+ /** @description Realtime data */
176
+ 200: {
177
+ headers: {
178
+ [name: string]: unknown;
179
+ };
180
+ content: {
181
+ "application/json": {
182
+ data: {
183
+ visitors_online: number;
184
+ };
185
+ meta: components["schemas"]["Meta"];
186
+ };
187
+ };
188
+ };
189
+ };
190
+ };
191
+ put?: never;
192
+ post?: never;
193
+ delete?: never;
194
+ options?: never;
195
+ head?: never;
196
+ patch?: never;
197
+ trace?: never;
198
+ };
199
+ "/api/v1/channels": {
200
+ parameters: {
201
+ query?: never;
202
+ header?: never;
203
+ path?: never;
204
+ cookie?: never;
205
+ };
206
+ /**
207
+ * Get traffic source breakdown
208
+ * @description Returns channel breakdown with visitors, sessions, pageviews, bounce rate, conversions, and revenue.
209
+ */
210
+ get: {
211
+ parameters: {
212
+ query: {
213
+ date_from: string;
214
+ date_to: string;
215
+ limit?: string;
216
+ };
217
+ header?: never;
218
+ path?: never;
219
+ cookie?: never;
220
+ };
221
+ requestBody?: never;
222
+ responses: {
223
+ /** @description Breakdown data */
224
+ 200: {
225
+ headers: {
226
+ [name: string]: unknown;
227
+ };
228
+ content: {
229
+ "application/json": {
230
+ data: {
231
+ value: string;
232
+ visitors: number;
233
+ visits: number;
234
+ pageviews: number;
235
+ bounce_rate: number;
236
+ conversions: number;
237
+ conversion_rate: number;
238
+ revenue: number;
239
+ }[];
240
+ meta: components["schemas"]["Meta"];
241
+ };
242
+ };
243
+ };
244
+ };
245
+ };
246
+ put?: never;
247
+ post?: never;
248
+ delete?: never;
249
+ options?: never;
250
+ head?: never;
251
+ patch?: never;
252
+ trace?: never;
253
+ };
254
+ "/api/v1/pages": {
255
+ parameters: {
256
+ query?: never;
257
+ header?: never;
258
+ path?: never;
259
+ cookie?: never;
260
+ };
261
+ /**
262
+ * Get page performance breakdown
263
+ * @description Returns page breakdown with visitors, sessions, pageviews, bounce rate, conversions, and revenue.
264
+ */
265
+ get: {
266
+ parameters: {
267
+ query: {
268
+ date_from: string;
269
+ date_to: string;
270
+ limit?: string;
271
+ };
272
+ header?: never;
273
+ path?: never;
274
+ cookie?: never;
275
+ };
276
+ requestBody?: never;
277
+ responses: {
278
+ /** @description Breakdown data */
279
+ 200: {
280
+ headers: {
281
+ [name: string]: unknown;
282
+ };
283
+ content: {
284
+ "application/json": {
285
+ data: {
286
+ value: string;
287
+ visitors: number;
288
+ visits: number;
289
+ pageviews: number;
290
+ bounce_rate: number;
291
+ conversions: number;
292
+ conversion_rate: number;
293
+ revenue: number;
294
+ }[];
295
+ meta: components["schemas"]["Meta"];
296
+ };
297
+ };
298
+ };
299
+ };
300
+ };
301
+ put?: never;
302
+ post?: never;
303
+ delete?: never;
304
+ options?: never;
305
+ head?: never;
306
+ patch?: never;
307
+ trace?: never;
308
+ };
309
+ "/api/v1/countries": {
310
+ parameters: {
311
+ query?: never;
312
+ header?: never;
313
+ path?: never;
314
+ cookie?: never;
315
+ };
316
+ /**
317
+ * Get country breakdown
318
+ * @description Returns country breakdown with visitors, sessions, pageviews, bounce rate, conversions, and revenue.
319
+ */
320
+ get: {
321
+ parameters: {
322
+ query: {
323
+ date_from: string;
324
+ date_to: string;
325
+ limit?: string;
326
+ };
327
+ header?: never;
328
+ path?: never;
329
+ cookie?: never;
330
+ };
331
+ requestBody?: never;
332
+ responses: {
333
+ /** @description Breakdown data */
334
+ 200: {
335
+ headers: {
336
+ [name: string]: unknown;
337
+ };
338
+ content: {
339
+ "application/json": {
340
+ data: {
341
+ value: string;
342
+ visitors: number;
343
+ visits: number;
344
+ pageviews: number;
345
+ bounce_rate: number;
346
+ conversions: number;
347
+ conversion_rate: number;
348
+ revenue: number;
349
+ }[];
350
+ meta: components["schemas"]["Meta"];
351
+ };
352
+ };
353
+ };
354
+ };
355
+ };
356
+ put?: never;
357
+ post?: never;
358
+ delete?: never;
359
+ options?: never;
360
+ head?: never;
361
+ patch?: never;
362
+ trace?: never;
363
+ };
364
+ "/api/v1/devices": {
365
+ parameters: {
366
+ query?: never;
367
+ header?: never;
368
+ path?: never;
369
+ cookie?: never;
370
+ };
371
+ /**
372
+ * Get device type breakdown
373
+ * @description Returns device breakdown with visitors, sessions, pageviews, bounce rate, conversions, and revenue.
374
+ */
375
+ get: {
376
+ parameters: {
377
+ query: {
378
+ date_from: string;
379
+ date_to: string;
380
+ limit?: string;
381
+ };
382
+ header?: never;
383
+ path?: never;
384
+ cookie?: never;
385
+ };
386
+ requestBody?: never;
387
+ responses: {
388
+ /** @description Breakdown data */
389
+ 200: {
390
+ headers: {
391
+ [name: string]: unknown;
392
+ };
393
+ content: {
394
+ "application/json": {
395
+ data: {
396
+ value: string;
397
+ visitors: number;
398
+ visits: number;
399
+ pageviews: number;
400
+ bounce_rate: number;
401
+ conversions: number;
402
+ conversion_rate: number;
403
+ revenue: number;
404
+ }[];
405
+ meta: components["schemas"]["Meta"];
406
+ };
407
+ };
408
+ };
409
+ };
410
+ };
411
+ put?: never;
412
+ post?: never;
413
+ delete?: never;
414
+ options?: never;
415
+ head?: never;
416
+ patch?: never;
417
+ trace?: never;
418
+ };
419
+ "/api/v1/browsers": {
420
+ parameters: {
421
+ query?: never;
422
+ header?: never;
423
+ path?: never;
424
+ cookie?: never;
425
+ };
426
+ /**
427
+ * Get browser breakdown
428
+ * @description Returns browser breakdown with visitors, sessions, pageviews, bounce rate, conversions, and revenue.
429
+ */
430
+ get: {
431
+ parameters: {
432
+ query: {
433
+ date_from: string;
434
+ date_to: string;
435
+ limit?: string;
436
+ };
437
+ header?: never;
438
+ path?: never;
439
+ cookie?: never;
440
+ };
441
+ requestBody?: never;
442
+ responses: {
443
+ /** @description Breakdown data */
444
+ 200: {
445
+ headers: {
446
+ [name: string]: unknown;
447
+ };
448
+ content: {
449
+ "application/json": {
450
+ data: {
451
+ value: string;
452
+ visitors: number;
453
+ visits: number;
454
+ pageviews: number;
455
+ bounce_rate: number;
456
+ conversions: number;
457
+ conversion_rate: number;
458
+ revenue: number;
459
+ }[];
460
+ meta: components["schemas"]["Meta"];
461
+ };
462
+ };
463
+ };
464
+ };
465
+ };
466
+ put?: never;
467
+ post?: never;
468
+ delete?: never;
469
+ options?: never;
470
+ head?: never;
471
+ patch?: never;
472
+ trace?: never;
473
+ };
474
+ "/api/v1/os": {
475
+ parameters: {
476
+ query?: never;
477
+ header?: never;
478
+ path?: never;
479
+ cookie?: never;
480
+ };
481
+ /**
482
+ * Get operating system breakdown
483
+ * @description Returns os breakdown with visitors, sessions, pageviews, bounce rate, conversions, and revenue.
484
+ */
485
+ get: {
486
+ parameters: {
487
+ query: {
488
+ date_from: string;
489
+ date_to: string;
490
+ limit?: string;
491
+ };
492
+ header?: never;
493
+ path?: never;
494
+ cookie?: never;
495
+ };
496
+ requestBody?: never;
497
+ responses: {
498
+ /** @description Breakdown data */
499
+ 200: {
500
+ headers: {
501
+ [name: string]: unknown;
502
+ };
503
+ content: {
504
+ "application/json": {
505
+ data: {
506
+ value: string;
507
+ visitors: number;
508
+ visits: number;
509
+ pageviews: number;
510
+ bounce_rate: number;
511
+ conversions: number;
512
+ conversion_rate: number;
513
+ revenue: number;
514
+ }[];
515
+ meta: components["schemas"]["Meta"];
516
+ };
517
+ };
518
+ };
519
+ };
520
+ };
521
+ put?: never;
522
+ post?: never;
523
+ delete?: never;
524
+ options?: never;
525
+ head?: never;
526
+ patch?: never;
527
+ trace?: never;
528
+ };
529
+ "/api/v1/referrers": {
530
+ parameters: {
531
+ query?: never;
532
+ header?: never;
533
+ path?: never;
534
+ cookie?: never;
535
+ };
536
+ /**
537
+ * Get referrer breakdown
538
+ * @description Returns referrer breakdown with visitors, sessions, pageviews, bounce rate, conversions, and revenue.
539
+ */
540
+ get: {
541
+ parameters: {
542
+ query: {
543
+ date_from: string;
544
+ date_to: string;
545
+ limit?: string;
546
+ };
547
+ header?: never;
548
+ path?: never;
549
+ cookie?: never;
550
+ };
551
+ requestBody?: never;
552
+ responses: {
553
+ /** @description Breakdown data */
554
+ 200: {
555
+ headers: {
556
+ [name: string]: unknown;
557
+ };
558
+ content: {
559
+ "application/json": {
560
+ data: {
561
+ value: string;
562
+ visitors: number;
563
+ visits: number;
564
+ pageviews: number;
565
+ bounce_rate: number;
566
+ conversions: number;
567
+ conversion_rate: number;
568
+ revenue: number;
569
+ }[];
570
+ meta: components["schemas"]["Meta"];
571
+ };
572
+ };
573
+ };
574
+ };
575
+ };
576
+ put?: never;
577
+ post?: never;
578
+ delete?: never;
579
+ options?: never;
580
+ head?: never;
581
+ patch?: never;
582
+ trace?: never;
583
+ };
584
+ "/api/v1/campaigns": {
585
+ parameters: {
586
+ query?: never;
587
+ header?: never;
588
+ path?: never;
589
+ cookie?: never;
590
+ };
591
+ /**
592
+ * Get campaign performance
593
+ * @description Returns top campaigns with ROAS and attribution data. Add `level=ad_set` or `level=ad` for granular breakdowns.
594
+ */
595
+ get: {
596
+ parameters: {
597
+ query: {
598
+ date_from: string;
599
+ date_to: string;
600
+ model?: string;
601
+ limit?: string;
602
+ level?: string;
603
+ };
604
+ header?: never;
605
+ path?: never;
606
+ cookie?: never;
607
+ };
608
+ requestBody?: never;
609
+ responses: {
610
+ /** @description Campaign data */
611
+ 200: {
612
+ headers: {
613
+ [name: string]: unknown;
614
+ };
615
+ content: {
616
+ "application/json": {
617
+ data: {
618
+ campaign_id: string;
619
+ campaign_name: string;
620
+ spend: number;
621
+ outcome_count: number;
622
+ outcome_value: number;
623
+ roas: number;
624
+ }[];
625
+ meta: components["schemas"]["Meta"];
626
+ };
627
+ };
628
+ };
629
+ };
630
+ };
631
+ put?: never;
632
+ post?: never;
633
+ delete?: never;
634
+ options?: never;
635
+ head?: never;
636
+ patch?: never;
637
+ trace?: never;
638
+ };
639
+ "/api/v1/campaigns/trend": {
640
+ parameters: {
641
+ query?: never;
642
+ header?: never;
643
+ path?: never;
644
+ cookie?: never;
645
+ };
646
+ /**
647
+ * Get daily campaign trend
648
+ * @description Returns daily spend, impressions, and clicks for specific campaigns/ad sets/ads.
649
+ */
650
+ get: {
651
+ parameters: {
652
+ query: {
653
+ date_from: string;
654
+ date_to: string;
655
+ entity_ids: string;
656
+ level?: string;
657
+ };
658
+ header?: never;
659
+ path?: never;
660
+ cookie?: never;
661
+ };
662
+ requestBody?: never;
663
+ responses: {
664
+ /** @description Trend data */
665
+ 200: {
666
+ headers: {
667
+ [name: string]: unknown;
668
+ };
669
+ content: {
670
+ "application/json": {
671
+ data: {
672
+ entity_id: string;
673
+ date: string;
674
+ spend: number;
675
+ impressions: number;
676
+ clicks: number;
677
+ }[];
678
+ meta: components["schemas"]["Meta"];
679
+ };
680
+ };
681
+ };
682
+ };
683
+ };
684
+ put?: never;
685
+ post?: never;
686
+ delete?: never;
687
+ options?: never;
688
+ head?: never;
689
+ patch?: never;
690
+ trace?: never;
691
+ };
692
+ "/api/v1/top-performers": {
693
+ parameters: {
694
+ query?: never;
695
+ header?: never;
696
+ path?: never;
697
+ cookie?: never;
698
+ };
699
+ /**
700
+ * Get the profile's top-performing ads (cohort-normalized creative scoring)
701
+ * @description Best ads scored against *comparable* creative (a cohort = channel × format × objective × audience warmth × geo × placement): cohort-normalized, empirical-Bayes-smoothed (small-sample ads shrink toward the cohort mean), and maturity-staged. Each ad carries THREE distinct measures — present them separately, never merge: `composite_score` (0–100, a transparent rule blend), `top_performer_likelihood` (0–1, a probability — a *likelihood, not a guarantee*; the calibrated ML-ranker output when `score_source='model'` with `model_version` set, else a monotone function of `composite_score`; never ROAS), and `attributed_revenue`/`roas` (real cash attribution, present when `truth_grade='attributed'`). `maturity_stage` (cold→early→mature→calibrated) says how settled the score is; `reason_codes` explain which funnel layer is strong/weak with a sample-confidence band. Scores refresh on a daily cadence. `window` is a rolling lookback (`7d`/`14d`/`28d`/`lifetime`), not a custom date range. The workspace-wide cross-profile view is exposed via the Atribu MCP server's `top_workspace_performers` tool.
702
+ */
703
+ get: {
704
+ parameters: {
705
+ query?: {
706
+ window?: "7d" | "14d" | "28d" | "lifetime";
707
+ limit?: string;
708
+ min_spend?: string;
709
+ objectives?: string;
710
+ truth_grades?: string;
711
+ formats?: string;
712
+ has_video?: "true" | "false";
713
+ };
714
+ header?: never;
715
+ path?: never;
716
+ cookie?: never;
717
+ };
718
+ requestBody?: never;
719
+ responses: {
720
+ /** @description Top performers */
721
+ 200: {
722
+ headers: {
723
+ [name: string]: unknown;
724
+ };
725
+ content: {
726
+ "application/json": {
727
+ data: {
728
+ ad_external_id: string;
729
+ ad_name: string | null;
730
+ campaign_name: string | null;
731
+ ad_set_name: string | null;
732
+ creative_thumbnail_url: string | null;
733
+ video_id: string | null;
734
+ score_window: string;
735
+ composite_score: number | null;
736
+ top_performer_likelihood: number | null;
737
+ model_version: number | null;
738
+ /** @enum {string} */
739
+ score_source: "model" | "rules";
740
+ maturity_stage: string;
741
+ truth_grade: string;
742
+ primary_outcome_kind: string;
743
+ cohort_key: string | null;
744
+ cohort_objective: string | null;
745
+ cohort_format: string | null;
746
+ cohort_audience_warmth: string | null;
747
+ cohort_n_ads: number;
748
+ hook_type: string | null;
749
+ creative_format: string | null;
750
+ cta_type: string | null;
751
+ primary_angle: string | null;
752
+ offers: string[];
753
+ spend: number;
754
+ impressions: number;
755
+ ctr: number;
756
+ cpc: number | null;
757
+ attributed_cash_outcomes: number;
758
+ attributed_revenue: number;
759
+ roas: number | null;
760
+ cac: number | null;
761
+ attributed_outcomes_total: number;
762
+ attributed_pipeline_outcomes: number;
763
+ attributed_pipeline_value: number;
764
+ meta_reported_conversions: number;
765
+ meta_reported_conversion_value: number;
766
+ cost_per_conversation: number | null;
767
+ messaging_conversations_started: number;
768
+ first_reply_rate: number | null;
769
+ avg_engagement_score: number | null;
770
+ reason_codes: {
771
+ layer: string;
772
+ /** @enum {string} */
773
+ polarity: "strength" | "weakness" | "forecast" | "fatigue";
774
+ percentile: number | null;
775
+ /** @enum {string} */
776
+ sample_confidence: "low" | "medium" | "high";
777
+ code?: string;
778
+ metric_value?: number | null;
779
+ }[];
780
+ forecast_outcomes_7d: number | null;
781
+ forecast_outcomes_7d_low: number | null;
782
+ forecast_outcomes_7d_high: number | null;
783
+ /** @enum {string|null} */
784
+ forecast_confidence: "low" | "medium" | "high" | null;
785
+ hazard_30d_pause: number | null;
786
+ hazard_30d_degradation: number | null;
787
+ /** @enum {string|null} */
788
+ fatigue_state: "active" | "paused" | "degraded" | null;
789
+ /** @enum {string|null} */
790
+ fatigue_risk_tier: "low" | "medium" | "high" | "critical" | null;
791
+ expected_lifespan_days: number | null;
792
+ }[];
793
+ meta: components["schemas"]["Meta"];
794
+ };
795
+ };
796
+ };
797
+ };
798
+ };
799
+ put?: never;
800
+ post?: never;
801
+ delete?: never;
802
+ options?: never;
803
+ head?: never;
804
+ patch?: never;
805
+ trace?: never;
806
+ };
807
+ "/api/v1/creative-patterns": {
808
+ parameters: {
809
+ query?: never;
810
+ header?: never;
811
+ path?: never;
812
+ cookie?: never;
813
+ };
814
+ /**
815
+ * Workspace creative pattern miner (Phase 2.7)
816
+ * @description Which structural creative patterns (archetype cluster, narrative arc, dominant-third role combo, role presence signature, social-proof duration bucket, hook×claim×cta) win MORE than the workspace baseline. One row per (pattern_dim, pattern_value) with sample_n, winner_n, win_rate, workspace_baseline_win_rate, lift_vs_workspace, Wilson 95% CI bounds, and the top-5 exemplar ads embodying the pattern. Filtered to the API key's profile via the workspace RPC's profile_ids filter. Pair with /top-performers for cash impact per ad.
817
+ */
818
+ get: {
819
+ parameters: {
820
+ query?: {
821
+ window?: "7d" | "14d" | "28d" | "lifetime";
822
+ min_cluster_size?: string;
823
+ };
824
+ header?: never;
825
+ path?: never;
826
+ cookie?: never;
827
+ };
828
+ requestBody?: never;
829
+ responses: {
830
+ /** @description Creative patterns */
831
+ 200: {
832
+ headers: {
833
+ [name: string]: unknown;
834
+ };
835
+ content: {
836
+ "application/json": {
837
+ data: {
838
+ patterns: {
839
+ pattern_dim: string;
840
+ pattern_value: string | null;
841
+ pattern_label: string | null;
842
+ pattern_description: string | null;
843
+ pattern_winning_signal: string | null;
844
+ sample_n: number;
845
+ winner_n: number;
846
+ win_rate: number | null;
847
+ workspace_baseline_win_rate: number | null;
848
+ lift_vs_workspace: number | null;
849
+ confidence_interval_low: number | null;
850
+ confidence_interval_high: number | null;
851
+ exemplar_ad_external_ids: string[];
852
+ }[];
853
+ score_window: string;
854
+ min_cluster_size: number;
855
+ };
856
+ meta: components["schemas"]["Meta"];
857
+ };
858
+ };
859
+ };
860
+ };
861
+ };
862
+ put?: never;
863
+ post?: never;
864
+ delete?: never;
865
+ options?: never;
866
+ head?: never;
867
+ patch?: never;
868
+ trace?: never;
869
+ };
870
+ "/api/v1/archetypes": {
871
+ parameters: {
872
+ query?: never;
873
+ header?: never;
874
+ path?: never;
875
+ cookie?: never;
876
+ };
877
+ /**
878
+ * Workspace creative archetype summary (Phase 2.7)
879
+ * @description Workspace-level archetype headline: 'these are your creative clusters, named and ranked by lift.' One row per archetype_cluster with LLM-generated label/description/winning_signal, win-rate vs workspace baseline, Wilson 95% CI bounds, and top-5 exemplars. Archetypes are workspace-grain (cross-profile cohort percentiles); the response is NOT profile-scoped.
880
+ */
881
+ get: {
882
+ parameters: {
883
+ query?: {
884
+ window?: "7d" | "14d" | "28d" | "lifetime";
885
+ };
886
+ header?: never;
887
+ path?: never;
888
+ cookie?: never;
889
+ };
890
+ requestBody?: never;
891
+ responses: {
892
+ /** @description Archetype summary */
893
+ 200: {
894
+ headers: {
895
+ [name: string]: unknown;
896
+ };
897
+ content: {
898
+ "application/json": {
899
+ data: {
900
+ archetypes: {
901
+ archetype_cluster: number;
902
+ label: string | null;
903
+ description: string | null;
904
+ winning_signal: string | null;
905
+ n_ads: number;
906
+ n_winners: number;
907
+ win_rate: number | null;
908
+ workspace_baseline_win_rate: number | null;
909
+ lift_vs_workspace: number | null;
910
+ confidence_interval_low: number | null;
911
+ confidence_interval_high: number | null;
912
+ exemplar_ad_external_ids: string[];
913
+ }[];
914
+ score_window: string;
915
+ };
916
+ meta: components["schemas"]["Meta"];
917
+ };
918
+ };
919
+ };
920
+ };
921
+ };
922
+ put?: never;
923
+ post?: never;
924
+ delete?: never;
925
+ options?: never;
926
+ head?: never;
927
+ patch?: never;
928
+ trace?: never;
929
+ };
930
+ "/api/v1/ads/funnel-diagnosis": {
931
+ parameters: {
932
+ query?: never;
933
+ header?: never;
934
+ path?: never;
935
+ cookie?: never;
936
+ };
937
+ /**
938
+ * Per-ad funnel diagnosis (Phase 2.8)
939
+ * @description Per-ad funnel-layer percentile breakdown — delivery, attention, retention, click_intent, postclick_messaging, attributed_revenue, platform_diagnostics. Each layer carries the ad's percentile within its cohort, the smoothed metric, sample_n, weakest-layer flag, diagnostic codes (e.g. retention_below_p25_at_mature_stage), and a recommended_priority — one of: fix_offer_or_audience, fix_landing_or_offer, fix_hook, improve_creative_clarity, increase_spend, rework_offer_or_landing, maintain. Cold-maturity ads with spend < $50 return 'increase_spend' (the 'spend_below_learning_phase' code). When the ad has no per-layer percentiles yet but at least one diagnostic_code applies, the response contains a single layer='no_data' row carrying the codes + recommended_priority. Scope: campaigns:read.
940
+ */
941
+ get: {
942
+ parameters: {
943
+ query: {
944
+ ad_external_id: string;
945
+ window?: "7d" | "14d" | "28d" | "lifetime";
946
+ };
947
+ header?: never;
948
+ path?: never;
949
+ cookie?: never;
950
+ };
951
+ requestBody?: never;
952
+ responses: {
953
+ /** @description Funnel diagnosis */
954
+ 200: {
955
+ headers: {
956
+ [name: string]: unknown;
957
+ };
958
+ content: {
959
+ "application/json": {
960
+ data: {
961
+ ad_external_id: string;
962
+ score_window: string;
963
+ weakest_layer: string | null;
964
+ recommended_priority: string;
965
+ layers: {
966
+ layer: string;
967
+ percentile: number | null;
968
+ smoothed_metric: number | null;
969
+ sample_n: number | null;
970
+ is_weakest_layer: boolean;
971
+ diagnostic_codes: string[];
972
+ recommended_priority: string;
973
+ maturity_stage: string | null;
974
+ truth_grade: string | null;
975
+ }[];
976
+ };
977
+ meta: components["schemas"]["Meta"];
978
+ };
979
+ };
980
+ };
981
+ };
982
+ };
983
+ put?: never;
984
+ post?: never;
985
+ delete?: never;
986
+ options?: never;
987
+ head?: never;
988
+ patch?: never;
989
+ trace?: never;
990
+ };
991
+ "/api/v1/ads/compare": {
992
+ parameters: {
993
+ query?: never;
994
+ header?: never;
995
+ path?: never;
996
+ cookie?: never;
997
+ };
998
+ /**
999
+ * Compare two ads by feature contributions (Phase 2.8)
1000
+ * @description Returns the top-N features most responsible for the gap between two ads' rankings, sorted by |model_contribution_a − model_contribution_b|. Each row has the feature name, raw values for A and B, the numeric delta, and per-ad model contributions sourced from `model_feature_contributions`.
1001
+ */
1002
+ get: {
1003
+ parameters: {
1004
+ query: {
1005
+ ad_a: string;
1006
+ ad_b: string;
1007
+ window?: "7d" | "14d" | "28d" | "lifetime";
1008
+ top_n?: string;
1009
+ };
1010
+ header?: never;
1011
+ path?: never;
1012
+ cookie?: never;
1013
+ };
1014
+ requestBody?: never;
1015
+ responses: {
1016
+ /** @description Feature comparison */
1017
+ 200: {
1018
+ headers: {
1019
+ [name: string]: unknown;
1020
+ };
1021
+ content: {
1022
+ "application/json": {
1023
+ data: {
1024
+ ad_external_id_a: string;
1025
+ ad_external_id_b: string;
1026
+ score_window: string;
1027
+ features: {
1028
+ feature_name: string;
1029
+ value_a: string | null;
1030
+ value_b: string | null;
1031
+ delta: number | null;
1032
+ model_contribution_a: number | null;
1033
+ model_contribution_b: number | null;
1034
+ contribution_delta_abs: number | null;
1035
+ }[];
1036
+ };
1037
+ meta: components["schemas"]["Meta"];
1038
+ };
1039
+ };
1040
+ };
1041
+ };
1042
+ };
1043
+ put?: never;
1044
+ post?: never;
1045
+ delete?: never;
1046
+ options?: never;
1047
+ head?: never;
1048
+ patch?: never;
1049
+ trace?: never;
1050
+ };
1051
+ "/api/v1/ads/trajectory": {
1052
+ parameters: {
1053
+ query?: never;
1054
+ header?: never;
1055
+ path?: never;
1056
+ cookie?: never;
1057
+ };
1058
+ /**
1059
+ * Per-ad daily history trajectory (Phase 2.8)
1060
+ * @description Daily snapshot rows for one ad from `creative_feature_store_history`. Each snapshot carries spend, smoothed funnel-layer percentiles, composite_score, maturity_stage, truth_grade, and delta_composite_vs_prev. Backs charts of how an ad's performance evolves over time. Default 60 days back, max 365.
1061
+ */
1062
+ get: {
1063
+ parameters: {
1064
+ query: {
1065
+ ad_external_id: string;
1066
+ window?: "7d" | "14d" | "28d" | "lifetime";
1067
+ days_back?: string;
1068
+ };
1069
+ header?: never;
1070
+ path?: never;
1071
+ cookie?: never;
1072
+ };
1073
+ requestBody?: never;
1074
+ responses: {
1075
+ /** @description Ad trajectory */
1076
+ 200: {
1077
+ headers: {
1078
+ [name: string]: unknown;
1079
+ };
1080
+ content: {
1081
+ "application/json": {
1082
+ data: {
1083
+ ad_external_id: string;
1084
+ score_window: string;
1085
+ days_back: number;
1086
+ points: {
1087
+ snapshot_date: string;
1088
+ spend: number | null;
1089
+ impressions: number | null;
1090
+ clicks: number | null;
1091
+ ctr: number | null;
1092
+ smoothed_hook_rate: number | null;
1093
+ smoothed_retention_rate: number | null;
1094
+ smoothed_ctr: number | null;
1095
+ smoothed_roas: number | null;
1096
+ pct_delivery: number | null;
1097
+ pct_attention: number | null;
1098
+ pct_retention: number | null;
1099
+ pct_click_intent: number | null;
1100
+ pct_attributed_revenue: number | null;
1101
+ attributed_revenue: number | null;
1102
+ attributed_outcomes_total: number | null;
1103
+ messaging_conversations_started: number | null;
1104
+ refund_rate: number | null;
1105
+ composite_score: number | null;
1106
+ maturity_stage: string | null;
1107
+ truth_grade: string | null;
1108
+ primary_outcome_kind: string | null;
1109
+ delta_composite_vs_prev: number | null;
1110
+ }[];
1111
+ };
1112
+ meta: components["schemas"]["Meta"];
1113
+ };
1114
+ };
1115
+ };
1116
+ };
1117
+ };
1118
+ put?: never;
1119
+ post?: never;
1120
+ delete?: never;
1121
+ options?: never;
1122
+ head?: never;
1123
+ patch?: never;
1124
+ trace?: never;
1125
+ };
1126
+ "/api/v1/ads/fatigue-risk": {
1127
+ parameters: {
1128
+ query?: never;
1129
+ header?: never;
1130
+ path?: never;
1131
+ cookie?: never;
1132
+ };
1133
+ /**
1134
+ * Workspace fatigue risk ranking (Phase 4)
1135
+ * @description Returns ads at predicted fatigue risk (high/critical tier only, fatigue_state='active') ranked by `hazard_30d_pause × spend` — the projected budget at risk if each ad pauses within 30 days. The Cox cause-specific 30-day pause probability is a *likelihood, not a guarantee*. Excludes already paused/degraded ads (those are observed states surfaced separately). Each row carries `fatigue_risk_tier`, `hazard_30d_pause`, `hazard_30d_degradation` (when the degradation cause has trained, else null), `expected_lifespan_days` (trapezoidal E[T] from the survival curve), and `risk_rank_score`. Models retrain weekly.
1136
+ */
1137
+ get: {
1138
+ parameters: {
1139
+ query?: {
1140
+ /** @description Default '28d' */
1141
+ score_window?: "7d" | "14d" | "28d" | "lifetime";
1142
+ /** @description Top N ads (default 20, max 50) */
1143
+ top?: string;
1144
+ /** @description Minimum spend filter (default 100; pass 0 to include all) */
1145
+ min_spend?: string;
1146
+ };
1147
+ header?: never;
1148
+ path?: never;
1149
+ cookie?: never;
1150
+ };
1151
+ requestBody?: never;
1152
+ responses: {
1153
+ /** @description Workspace fatigue risk ranking */
1154
+ 200: {
1155
+ headers: {
1156
+ [name: string]: unknown;
1157
+ };
1158
+ content: {
1159
+ "application/json": {
1160
+ data: {
1161
+ score_window: string;
1162
+ top_n: number;
1163
+ min_spend: number;
1164
+ ads: {
1165
+ [key: string]: unknown;
1166
+ }[];
1167
+ };
1168
+ meta: components["schemas"]["Meta"];
1169
+ };
1170
+ };
1171
+ };
1172
+ };
1173
+ };
1174
+ put?: never;
1175
+ post?: never;
1176
+ delete?: never;
1177
+ options?: never;
1178
+ head?: never;
1179
+ patch?: never;
1180
+ trace?: never;
1181
+ };
1182
+ "/api/v1/forecast-outlook": {
1183
+ parameters: {
1184
+ query?: never;
1185
+ header?: never;
1186
+ path?: never;
1187
+ cookie?: never;
1188
+ };
1189
+ /**
1190
+ * Workspace portfolio forecast outlook (Phase 4)
1191
+ * @description Portfolio-grain forecast for the next 7 days. Returns one document with: projected total impressions + attributed outcomes (with 80% prediction-interval bands from split-conformal calibration — calibrated coverage bands, not Gaussian σ), projected average cost-per-outcome, the counts of `n_emerging_top_performers` (climbing ads with strong forecasts) and `n_at_risk_top_performers` (currently top-tier ads in high/critical fatigue), per-tier fatigue histograms, and `projected_budget_at_risk` (total spend across high+critical fatigue ads). Use as the first 'what's the week ahead' lookup.
1192
+ */
1193
+ get: {
1194
+ parameters: {
1195
+ query?: {
1196
+ /** @description Default '28d' */
1197
+ score_window?: "7d" | "14d" | "28d" | "lifetime";
1198
+ };
1199
+ header?: never;
1200
+ path?: never;
1201
+ cookie?: never;
1202
+ };
1203
+ requestBody?: never;
1204
+ responses: {
1205
+ /** @description Portfolio outlook (single document) */
1206
+ 200: {
1207
+ headers: {
1208
+ [name: string]: unknown;
1209
+ };
1210
+ content: {
1211
+ "application/json": {
1212
+ data: {
1213
+ [key: string]: unknown;
1214
+ };
1215
+ meta: components["schemas"]["Meta"];
1216
+ };
1217
+ };
1218
+ };
1219
+ };
1220
+ };
1221
+ put?: never;
1222
+ post?: never;
1223
+ delete?: never;
1224
+ options?: never;
1225
+ head?: never;
1226
+ patch?: never;
1227
+ trace?: never;
1228
+ };
1229
+ "/api/v1/ads/forecast": {
1230
+ parameters: {
1231
+ query?: never;
1232
+ header?: never;
1233
+ path?: never;
1234
+ cookie?: never;
1235
+ };
1236
+ /**
1237
+ * Per-ad forecast + fatigue + 14d trajectory (Phase 4 / F-3)
1238
+ * @description Returns one creative_feature_store row for the (workspace, profile, ad_external_id) tuple plus the last 14 days of daily delivery and any lifecycle events. The `cfs` object carries the Phase-4 forecast cols (forecast_outcomes_7d/_low/_high, forecast_confidence) and the fatigue cols (hazard_30d_pause, hazard_30d_degradation, expected_lifespan_days, fatigue_state, fatigue_risk_tier). All Phase-4 cols are NULL when the prediction-pass cron hasn't scored the ad (cold-start, paused, ML_FORECAST_AND_FATIGUE_ENABLED off). Query-param convention (audit B-7).
1239
+ */
1240
+ get: {
1241
+ parameters: {
1242
+ query: {
1243
+ /** @description The ad's external id (Meta ad id / Google ads id) */
1244
+ ad_external_id: string;
1245
+ /** @description Default '28d' */
1246
+ score_window?: "7d" | "14d" | "28d" | "lifetime";
1247
+ };
1248
+ header?: never;
1249
+ path?: never;
1250
+ cookie?: never;
1251
+ };
1252
+ requestBody?: never;
1253
+ responses: {
1254
+ /** @description Ad forecast detail */
1255
+ 200: {
1256
+ headers: {
1257
+ [name: string]: unknown;
1258
+ };
1259
+ content: {
1260
+ "application/json": {
1261
+ data: {
1262
+ ad_external_id: string;
1263
+ score_window: string;
1264
+ cfs: {
1265
+ [key: string]: unknown;
1266
+ } | null;
1267
+ trajectory_last_14d: {
1268
+ day: string;
1269
+ spend: number;
1270
+ impressions: number;
1271
+ clicks: number;
1272
+ }[];
1273
+ lifecycle_history: {
1274
+ event_date: string;
1275
+ event_type: string;
1276
+ lifecycle_seq: number;
1277
+ }[];
1278
+ };
1279
+ meta: components["schemas"]["Meta"];
1280
+ };
1281
+ };
1282
+ };
1283
+ };
1284
+ };
1285
+ put?: never;
1286
+ post?: never;
1287
+ delete?: never;
1288
+ options?: never;
1289
+ head?: never;
1290
+ patch?: never;
1291
+ trace?: never;
1292
+ };
1293
+ "/api/v1/ads/forecast/scenarios": {
1294
+ parameters: {
1295
+ query?: never;
1296
+ header?: never;
1297
+ path?: never;
1298
+ cookie?: never;
1299
+ };
1300
+ get?: never;
1301
+ put?: never;
1302
+ /**
1303
+ * Per-ad what-if forecast scenarios (Phase 4 / F-3)
1304
+ * @description Feeds modified spend / frequency overrides back through the active outcomes-head forecaster and returns the projected 7-day outcomes count per scenario, with 80% conformal PI bands. The `out_of_range` flag goes true when a scenario's spend is > 2x or < 0.5x the ad's current trailing-7d spend — the model is extrapolating beyond its training distribution; treat the result as directional only. Up to 5 scenarios per call. Returns base=null + per-scenario `gated_reason` when the ad is cold-start / paused / has no active forecaster model.
1305
+ */
1306
+ post: {
1307
+ parameters: {
1308
+ query?: never;
1309
+ header?: never;
1310
+ path?: never;
1311
+ cookie?: never;
1312
+ };
1313
+ requestBody?: {
1314
+ content: {
1315
+ "application/json": {
1316
+ ad_external_id: string;
1317
+ /** @enum {string} */
1318
+ score_window?: "7d" | "14d" | "28d" | "lifetime";
1319
+ scenarios: {
1320
+ name: string;
1321
+ spend_7d_override?: number;
1322
+ frequency_override?: number;
1323
+ }[];
1324
+ };
1325
+ };
1326
+ };
1327
+ responses: {
1328
+ /** @description Per-scenario projection */
1329
+ 200: {
1330
+ headers: {
1331
+ [name: string]: unknown;
1332
+ };
1333
+ content: {
1334
+ "application/json": {
1335
+ data: {
1336
+ ad_external_id: string;
1337
+ score_window: string | null;
1338
+ cohort_variant?: string;
1339
+ base_trailing_7d_spend?: number;
1340
+ base: {
1341
+ point: number;
1342
+ low: number;
1343
+ high: number;
1344
+ /** @enum {string} */
1345
+ confidence: "low" | "medium" | "high";
1346
+ } | null;
1347
+ scenarios: {
1348
+ name: string;
1349
+ point: number | null;
1350
+ low: number | null;
1351
+ high: number | null;
1352
+ /** @enum {string} */
1353
+ confidence: "low" | "medium" | "high";
1354
+ delta_from_base: number;
1355
+ out_of_range: boolean;
1356
+ gated_reason?: string;
1357
+ }[];
1358
+ };
1359
+ meta: components["schemas"]["Meta"];
1360
+ };
1361
+ };
1362
+ };
1363
+ };
1364
+ };
1365
+ delete?: never;
1366
+ options?: never;
1367
+ head?: never;
1368
+ patch?: never;
1369
+ trace?: never;
1370
+ };
1371
+ "/api/v1/conversions": {
1372
+ parameters: {
1373
+ query?: never;
1374
+ header?: never;
1375
+ path?: never;
1376
+ cookie?: never;
1377
+ };
1378
+ /**
1379
+ * Get conversion counts by type
1380
+ * @description Returns counts of each conversion type (lead_created, payment_received, etc.).
1381
+ */
1382
+ get: {
1383
+ parameters: {
1384
+ query: {
1385
+ date_from: string;
1386
+ date_to: string;
1387
+ };
1388
+ header?: never;
1389
+ path?: never;
1390
+ cookie?: never;
1391
+ };
1392
+ requestBody?: never;
1393
+ responses: {
1394
+ /** @description Conversion data */
1395
+ 200: {
1396
+ headers: {
1397
+ [name: string]: unknown;
1398
+ };
1399
+ content: {
1400
+ "application/json": {
1401
+ data: {
1402
+ event_type: string;
1403
+ count: number;
1404
+ }[];
1405
+ meta: components["schemas"]["Meta"];
1406
+ };
1407
+ };
1408
+ };
1409
+ };
1410
+ };
1411
+ put?: never;
1412
+ post?: never;
1413
+ delete?: never;
1414
+ options?: never;
1415
+ head?: never;
1416
+ patch?: never;
1417
+ trace?: never;
1418
+ };
1419
+ "/api/v1/conversions/timeseries": {
1420
+ parameters: {
1421
+ query?: never;
1422
+ header?: never;
1423
+ path?: never;
1424
+ cookie?: never;
1425
+ };
1426
+ /**
1427
+ * Get daily conversion counts
1428
+ * @description Returns daily conversion counts broken down by event type.
1429
+ */
1430
+ get: {
1431
+ parameters: {
1432
+ query: {
1433
+ date_from: string;
1434
+ date_to: string;
1435
+ };
1436
+ header?: never;
1437
+ path?: never;
1438
+ cookie?: never;
1439
+ };
1440
+ requestBody?: never;
1441
+ responses: {
1442
+ /** @description Conversion timeseries */
1443
+ 200: {
1444
+ headers: {
1445
+ [name: string]: unknown;
1446
+ };
1447
+ content: {
1448
+ "application/json": {
1449
+ data: {
1450
+ date: string;
1451
+ event_type: string;
1452
+ count: number;
1453
+ }[];
1454
+ meta: components["schemas"]["Meta"];
1455
+ };
1456
+ };
1457
+ };
1458
+ };
1459
+ };
1460
+ put?: never;
1461
+ post?: never;
1462
+ delete?: never;
1463
+ options?: never;
1464
+ head?: never;
1465
+ patch?: never;
1466
+ trace?: never;
1467
+ };
1468
+ "/api/v1/revenue": {
1469
+ parameters: {
1470
+ query?: never;
1471
+ header?: never;
1472
+ path?: never;
1473
+ cookie?: never;
1474
+ };
1475
+ /**
1476
+ * Get daily revenue and spend
1477
+ * @description Returns attributed revenue (cash only) and ad spend per day.
1478
+ */
1479
+ get: {
1480
+ parameters: {
1481
+ query: {
1482
+ date_from: string;
1483
+ date_to: string;
1484
+ model?: string;
1485
+ };
1486
+ header?: never;
1487
+ path?: never;
1488
+ cookie?: never;
1489
+ };
1490
+ requestBody?: never;
1491
+ responses: {
1492
+ /** @description Revenue data */
1493
+ 200: {
1494
+ headers: {
1495
+ [name: string]: unknown;
1496
+ };
1497
+ content: {
1498
+ "application/json": {
1499
+ data: {
1500
+ date: string;
1501
+ revenue: number;
1502
+ spend: number;
1503
+ }[];
1504
+ meta: components["schemas"]["Meta"];
1505
+ };
1506
+ };
1507
+ };
1508
+ };
1509
+ };
1510
+ put?: never;
1511
+ post?: never;
1512
+ delete?: never;
1513
+ options?: never;
1514
+ head?: never;
1515
+ patch?: never;
1516
+ trace?: never;
1517
+ };
1518
+ "/api/v1/revenue/cash": {
1519
+ parameters: {
1520
+ query?: never;
1521
+ header?: never;
1522
+ path?: never;
1523
+ cookie?: never;
1524
+ };
1525
+ /**
1526
+ * Get cash collected by source
1527
+ * @description Returns total cash payments grouped by payment source (Stripe, MercadoPago) and currency.
1528
+ */
1529
+ get: {
1530
+ parameters: {
1531
+ query: {
1532
+ date_from: string;
1533
+ date_to: string;
1534
+ };
1535
+ header?: never;
1536
+ path?: never;
1537
+ cookie?: never;
1538
+ };
1539
+ requestBody?: never;
1540
+ responses: {
1541
+ /** @description Cash data */
1542
+ 200: {
1543
+ headers: {
1544
+ [name: string]: unknown;
1545
+ };
1546
+ content: {
1547
+ "application/json": {
1548
+ data: {
1549
+ source: string;
1550
+ currency: string;
1551
+ total: number;
1552
+ count: number;
1553
+ }[];
1554
+ meta: components["schemas"]["Meta"];
1555
+ };
1556
+ };
1557
+ };
1558
+ };
1559
+ };
1560
+ put?: never;
1561
+ post?: never;
1562
+ delete?: never;
1563
+ options?: never;
1564
+ head?: never;
1565
+ patch?: never;
1566
+ trace?: never;
1567
+ };
1568
+ "/api/v1/quality": {
1569
+ parameters: {
1570
+ query?: never;
1571
+ header?: never;
1572
+ path?: never;
1573
+ cookie?: never;
1574
+ };
1575
+ /**
1576
+ * Get attribution data quality
1577
+ * @description Returns metrics on UTM tracking coverage and attribution quality.
1578
+ */
1579
+ get: {
1580
+ parameters: {
1581
+ query: {
1582
+ date_from: string;
1583
+ date_to: string;
1584
+ };
1585
+ header?: never;
1586
+ path?: never;
1587
+ cookie?: never;
1588
+ };
1589
+ requestBody?: never;
1590
+ responses: {
1591
+ /** @description Quality data */
1592
+ 200: {
1593
+ headers: {
1594
+ [name: string]: unknown;
1595
+ };
1596
+ content: {
1597
+ "application/json": {
1598
+ data: {
1599
+ total_events: number;
1600
+ with_full_utms: number;
1601
+ with_fbclid_only: number;
1602
+ with_no_tracking: number;
1603
+ coverage_percent: number;
1604
+ };
1605
+ meta: components["schemas"]["Meta"];
1606
+ };
1607
+ };
1608
+ };
1609
+ };
1610
+ };
1611
+ put?: never;
1612
+ post?: never;
1613
+ delete?: never;
1614
+ options?: never;
1615
+ head?: never;
1616
+ patch?: never;
1617
+ trace?: never;
1618
+ };
1619
+ "/api/v1/customers": {
1620
+ parameters: {
1621
+ query?: never;
1622
+ header?: never;
1623
+ path?: never;
1624
+ cookie?: never;
1625
+ };
1626
+ /**
1627
+ * Get customer conversions
1628
+ * @description Paginated list of customers who achieved a goal. Requires `customers:read` scope. Returns PII (name, email).
1629
+ */
1630
+ get: {
1631
+ parameters: {
1632
+ query: {
1633
+ date_from: string;
1634
+ date_to: string;
1635
+ goal: string;
1636
+ search?: string;
1637
+ limit?: string;
1638
+ cursor_time?: string;
1639
+ cursor_id?: string;
1640
+ };
1641
+ header?: never;
1642
+ path?: never;
1643
+ cookie?: never;
1644
+ };
1645
+ requestBody?: never;
1646
+ responses: {
1647
+ /** @description Customer list */
1648
+ 200: {
1649
+ headers: {
1650
+ [name: string]: unknown;
1651
+ };
1652
+ content: {
1653
+ "application/json": {
1654
+ data: {
1655
+ conversion_id: string;
1656
+ customer_profile_id: string | null;
1657
+ name: string | null;
1658
+ email: string | null;
1659
+ country: string | null;
1660
+ device: string | null;
1661
+ channel: string | null;
1662
+ source: string | null;
1663
+ revenue: number;
1664
+ revenue_type: string;
1665
+ conversion_time: string;
1666
+ time_to_complete_seconds: number;
1667
+ touch_count: number;
1668
+ touch_channels: string[];
1669
+ conversion_count: number;
1670
+ total_revenue: number;
1671
+ }[];
1672
+ pagination: components["schemas"]["Pagination"];
1673
+ meta: components["schemas"]["Meta"];
1674
+ };
1675
+ };
1676
+ };
1677
+ };
1678
+ };
1679
+ put?: never;
1680
+ post?: never;
1681
+ delete?: never;
1682
+ options?: never;
1683
+ head?: never;
1684
+ patch?: never;
1685
+ trace?: never;
1686
+ };
1687
+ "/api/v1/customers/{id}/journey": {
1688
+ parameters: {
1689
+ query?: never;
1690
+ header?: never;
1691
+ path?: never;
1692
+ cookie?: never;
1693
+ };
1694
+ /**
1695
+ * Get customer journey timeline
1696
+ * @description Full event timeline for a single customer (page views, form fills, payments, etc.). Returns empty data if the customer does not belong to this profile. Requires `customers:read` scope.
1697
+ */
1698
+ get: {
1699
+ parameters: {
1700
+ query?: {
1701
+ cursor?: string;
1702
+ limit?: string;
1703
+ };
1704
+ header?: never;
1705
+ path: {
1706
+ id: string;
1707
+ };
1708
+ cookie?: never;
1709
+ };
1710
+ requestBody?: never;
1711
+ responses: {
1712
+ /** @description Journey data */
1713
+ 200: {
1714
+ headers: {
1715
+ [name: string]: unknown;
1716
+ };
1717
+ content: {
1718
+ "application/json": {
1719
+ data: {
1720
+ event_type: string;
1721
+ event_name: string;
1722
+ event_time: string;
1723
+ url: string | null;
1724
+ path: string | null;
1725
+ channel: string | null;
1726
+ source: string | null;
1727
+ medium: string | null;
1728
+ campaign: string | null;
1729
+ value_amount: number | null;
1730
+ currency: string | null;
1731
+ device: string | null;
1732
+ browser: string | null;
1733
+ os: string | null;
1734
+ country: string | null;
1735
+ city: string | null;
1736
+ is_synthetic: boolean;
1737
+ }[];
1738
+ pagination: components["schemas"]["Pagination"];
1739
+ meta: components["schemas"]["Meta"];
1740
+ };
1741
+ };
1742
+ };
1743
+ };
1744
+ };
1745
+ put?: never;
1746
+ post?: never;
1747
+ delete?: never;
1748
+ options?: never;
1749
+ head?: never;
1750
+ patch?: never;
1751
+ trace?: never;
1752
+ };
1753
+ "/api/v1/visitors": {
1754
+ parameters: {
1755
+ query?: never;
1756
+ header?: never;
1757
+ path?: never;
1758
+ cookie?: never;
1759
+ };
1760
+ /**
1761
+ * Get visitor list
1762
+ * @description Paginated list of all visitors (identified and anonymous). Requires `visitors:read` scope.
1763
+ */
1764
+ get: {
1765
+ parameters: {
1766
+ query: {
1767
+ date_from: string;
1768
+ date_to: string;
1769
+ search?: string;
1770
+ limit?: string;
1771
+ cursor_time?: string;
1772
+ cursor_id?: string;
1773
+ };
1774
+ header?: never;
1775
+ path?: never;
1776
+ cookie?: never;
1777
+ };
1778
+ requestBody?: never;
1779
+ responses: {
1780
+ /** @description Visitor list */
1781
+ 200: {
1782
+ headers: {
1783
+ [name: string]: unknown;
1784
+ };
1785
+ content: {
1786
+ "application/json": {
1787
+ data: {
1788
+ visitor_id: string;
1789
+ customer_profile_id: string | null;
1790
+ name: string | null;
1791
+ email: string | null;
1792
+ country: string | null;
1793
+ device: string | null;
1794
+ browser: string | null;
1795
+ os: string | null;
1796
+ channel: string | null;
1797
+ source: string | null;
1798
+ total_revenue: number;
1799
+ last_seen_at: string;
1800
+ session_count: number;
1801
+ total_pageviews: number;
1802
+ touch_channels: string[];
1803
+ }[];
1804
+ pagination: components["schemas"]["Pagination"];
1805
+ meta: components["schemas"]["Meta"];
1806
+ };
1807
+ };
1808
+ };
1809
+ };
1810
+ };
1811
+ put?: never;
1812
+ post?: never;
1813
+ delete?: never;
1814
+ options?: never;
1815
+ head?: never;
1816
+ patch?: never;
1817
+ trace?: never;
1818
+ };
1819
+ "/api/v1/keywords": {
1820
+ parameters: {
1821
+ query?: never;
1822
+ header?: never;
1823
+ path?: never;
1824
+ cookie?: never;
1825
+ };
1826
+ /**
1827
+ * Get search keywords
1828
+ * @description Returns Google Search Console keyword data (impressions, clicks, CTR, position).
1829
+ */
1830
+ get: {
1831
+ parameters: {
1832
+ query: {
1833
+ date_from: string;
1834
+ date_to: string;
1835
+ limit?: string;
1836
+ };
1837
+ header?: never;
1838
+ path?: never;
1839
+ cookie?: never;
1840
+ };
1841
+ requestBody?: never;
1842
+ responses: {
1843
+ /** @description Keyword data */
1844
+ 200: {
1845
+ headers: {
1846
+ [name: string]: unknown;
1847
+ };
1848
+ content: {
1849
+ "application/json": {
1850
+ data: {
1851
+ keyword: string;
1852
+ impressions: number;
1853
+ clicks: number;
1854
+ ctr: number;
1855
+ avg_position: number;
1856
+ }[];
1857
+ meta: components["schemas"]["Meta"];
1858
+ };
1859
+ };
1860
+ };
1861
+ };
1862
+ };
1863
+ put?: never;
1864
+ post?: never;
1865
+ delete?: never;
1866
+ options?: never;
1867
+ head?: never;
1868
+ patch?: never;
1869
+ trace?: never;
1870
+ };
1871
+ "/api/v1/events": {
1872
+ parameters: {
1873
+ query?: never;
1874
+ header?: never;
1875
+ path?: never;
1876
+ cookie?: never;
1877
+ };
1878
+ get?: never;
1879
+ put?: never;
1880
+ /**
1881
+ * Ingest a custom event
1882
+ * @description Submit a custom event for tracking. Use the `Idempotency-Key` header or `idempotency_key` field to prevent duplicates. Returns 202 Accepted.
1883
+ */
1884
+ post: {
1885
+ parameters: {
1886
+ query?: never;
1887
+ header?: never;
1888
+ path?: never;
1889
+ cookie?: never;
1890
+ };
1891
+ requestBody?: {
1892
+ content: {
1893
+ "application/json": {
1894
+ /** @example custom_signup */
1895
+ event_name: string;
1896
+ anonymous_id?: string;
1897
+ session_id?: string;
1898
+ /** @example 2026-03-25T10:00:00Z */
1899
+ timestamp?: string;
1900
+ properties?: {
1901
+ [key: string]: unknown;
1902
+ };
1903
+ user_traits?: {
1904
+ email?: string;
1905
+ phone?: string;
1906
+ first_name?: string;
1907
+ last_name?: string;
1908
+ };
1909
+ utm?: {
1910
+ source?: string;
1911
+ medium?: string;
1912
+ campaign?: string;
1913
+ content?: string;
1914
+ term?: string;
1915
+ };
1916
+ idempotency_key?: string;
1917
+ };
1918
+ };
1919
+ };
1920
+ responses: {
1921
+ /** @description Event accepted */
1922
+ 202: {
1923
+ headers: {
1924
+ [name: string]: unknown;
1925
+ };
1926
+ content: {
1927
+ "application/json": {
1928
+ data: {
1929
+ event_id: string;
1930
+ status: string;
1931
+ };
1932
+ meta: components["schemas"]["Meta"];
1933
+ };
1934
+ };
1935
+ };
1936
+ };
1937
+ };
1938
+ delete?: never;
1939
+ options?: never;
1940
+ head?: never;
1941
+ patch?: never;
1942
+ trace?: never;
1943
+ };
1944
+ "/api/v1/goals": {
1945
+ parameters: {
1946
+ query?: never;
1947
+ header?: never;
1948
+ path?: never;
1949
+ cookie?: never;
1950
+ };
1951
+ /**
1952
+ * List conversion goals
1953
+ * @description Returns all conversion definitions for this profile.
1954
+ */
1955
+ get: {
1956
+ parameters: {
1957
+ query?: never;
1958
+ header?: never;
1959
+ path?: never;
1960
+ cookie?: never;
1961
+ };
1962
+ requestBody?: never;
1963
+ responses: {
1964
+ /** @description Goal list */
1965
+ 200: {
1966
+ headers: {
1967
+ [name: string]: unknown;
1968
+ };
1969
+ content: {
1970
+ "application/json": {
1971
+ data: {
1972
+ id: string;
1973
+ display_name: string;
1974
+ conversion_key: string;
1975
+ source_event_names: string[];
1976
+ revenue_type: string;
1977
+ attribution_eligible: boolean;
1978
+ }[];
1979
+ meta: components["schemas"]["Meta"];
1980
+ };
1981
+ };
1982
+ };
1983
+ };
1984
+ };
1985
+ put?: never;
1986
+ /**
1987
+ * Create a conversion goal
1988
+ * @description Creates a new conversion definition that maps event types to conversion metrics.
1989
+ */
1990
+ post: {
1991
+ parameters: {
1992
+ query?: never;
1993
+ header?: never;
1994
+ path?: never;
1995
+ cookie?: never;
1996
+ };
1997
+ requestBody?: {
1998
+ content: {
1999
+ "application/json": {
2000
+ /** @example Trial Signup */
2001
+ name: string;
2002
+ /**
2003
+ * @example [
2004
+ * "trial_started"
2005
+ * ]
2006
+ */
2007
+ source_event_names: string[];
2008
+ /** @enum {string} */
2009
+ revenue_type: "cash" | "pipeline" | "gross";
2010
+ attribution_eligible?: boolean;
2011
+ };
2012
+ };
2013
+ };
2014
+ responses: {
2015
+ /** @description Goal created */
2016
+ 200: {
2017
+ headers: {
2018
+ [name: string]: unknown;
2019
+ };
2020
+ content: {
2021
+ "application/json": {
2022
+ data: {
2023
+ id: string;
2024
+ display_name: string;
2025
+ conversion_key: string;
2026
+ };
2027
+ meta: components["schemas"]["Meta"];
2028
+ };
2029
+ };
2030
+ };
2031
+ };
2032
+ };
2033
+ /**
2034
+ * Delete a conversion goal
2035
+ * @description Deletes a conversion definition by ID. Pass `id` as a query parameter.
2036
+ */
2037
+ delete: {
2038
+ parameters: {
2039
+ query: {
2040
+ id: string;
2041
+ };
2042
+ header?: never;
2043
+ path?: never;
2044
+ cookie?: never;
2045
+ };
2046
+ requestBody?: never;
2047
+ responses: {
2048
+ /** @description Goal deleted */
2049
+ 200: {
2050
+ headers: {
2051
+ [name: string]: unknown;
2052
+ };
2053
+ content: {
2054
+ "application/json": {
2055
+ data: {
2056
+ deleted: boolean;
2057
+ };
2058
+ meta: components["schemas"]["Meta"];
2059
+ };
2060
+ };
2061
+ };
2062
+ };
2063
+ };
2064
+ options?: never;
2065
+ head?: never;
2066
+ patch?: never;
2067
+ trace?: never;
2068
+ };
2069
+ "/api/v1/attribution/recompute": {
2070
+ parameters: {
2071
+ query?: never;
2072
+ header?: never;
2073
+ path?: never;
2074
+ cookie?: never;
2075
+ };
2076
+ get?: never;
2077
+ put?: never;
2078
+ /**
2079
+ * Trigger attribution recompute
2080
+ * @description Queues a full attribution recompute for this profile. Returns 202 Accepted. Heavy endpoint — rate limited to prevent abuse.
2081
+ */
2082
+ post: {
2083
+ parameters: {
2084
+ query?: never;
2085
+ header?: never;
2086
+ path?: never;
2087
+ cookie?: never;
2088
+ };
2089
+ requestBody?: never;
2090
+ responses: {
2091
+ /** @description Recompute queued */
2092
+ 202: {
2093
+ headers: {
2094
+ [name: string]: unknown;
2095
+ };
2096
+ content: {
2097
+ "application/json": {
2098
+ data: {
2099
+ status: string;
2100
+ message: string;
2101
+ };
2102
+ meta: components["schemas"]["Meta"];
2103
+ };
2104
+ };
2105
+ };
2106
+ };
2107
+ };
2108
+ delete?: never;
2109
+ options?: never;
2110
+ head?: never;
2111
+ patch?: never;
2112
+ trace?: never;
2113
+ };
2114
+ "/api/v1/messages": {
2115
+ parameters: {
2116
+ query?: never;
2117
+ header?: never;
2118
+ path?: never;
2119
+ cookie?: never;
2120
+ };
2121
+ get?: never;
2122
+ put?: never;
2123
+ /**
2124
+ * Send a channel-agnostic message
2125
+ * @description Sends a WhatsApp or Instagram message via a connected `data_connection`. Requires the `whatsapp` or `instagram` scope on the API key (matching the `channel`). For keys minted through the OAuth provider flow, an active `oauth_app_authorizations` row must also exist for the (app, profile, data_connection).
2126
+ *
2127
+ * **WhatsApp media (image/video/audio/document)** accepts either `media.media_id` (pre-uploaded via Meta's `/media` endpoint, 30-day cache) or `media.link` (public HTTPS URL Meta fetches once per send — no caching, size caps enforced). High-fanout sends should pre-upload.
2128
+ *
2129
+ * **Instagram image** accepts `image_url` directly (Meta downloads the URL). Quick replies are IG-only.
2130
+ */
2131
+ post: {
2132
+ parameters: {
2133
+ query?: never;
2134
+ header?: never;
2135
+ path?: never;
2136
+ cookie?: never;
2137
+ };
2138
+ requestBody?: {
2139
+ content: {
2140
+ "application/json": {
2141
+ /** Format: uuid */
2142
+ connection_id: string;
2143
+ /** @enum {string} */
2144
+ channel: "whatsapp" | "instagram";
2145
+ /** @description E.164 phone for WhatsApp; IGSID for Instagram. */
2146
+ to: string;
2147
+ content: {
2148
+ /** @enum {string} */
2149
+ type: "text";
2150
+ /** @description Up to 4096 chars. */
2151
+ text: string;
2152
+ } | {
2153
+ /** @enum {string} */
2154
+ type: "template";
2155
+ template_name: string;
2156
+ language_code: string;
2157
+ components?: {
2158
+ [key: string]: unknown;
2159
+ }[];
2160
+ } | {
2161
+ /** @enum {string} */
2162
+ type: "image";
2163
+ /**
2164
+ * Format: uri
2165
+ * @description Instagram path.
2166
+ */
2167
+ image_url?: string;
2168
+ /** @description WhatsApp path — either media_id or link. */
2169
+ media?: {
2170
+ /** @description Pre-uploaded handle from POST /{phone-number-id}/media. Valid 30 days. Meta-cached. */
2171
+ media_id?: string;
2172
+ /**
2173
+ * Format: uri
2174
+ * @description Publicly accessible HTTPS URL. Meta fetches at send-time; no auth, no caching, size caps enforced server-side.
2175
+ */
2176
+ link?: string;
2177
+ };
2178
+ caption?: string;
2179
+ } | {
2180
+ /** @enum {string} */
2181
+ type: "video";
2182
+ media: {
2183
+ /** @description Pre-uploaded handle from POST /{phone-number-id}/media. Valid 30 days. Meta-cached. */
2184
+ media_id?: string;
2185
+ /**
2186
+ * Format: uri
2187
+ * @description Publicly accessible HTTPS URL. Meta fetches at send-time; no auth, no caching, size caps enforced server-side.
2188
+ */
2189
+ link?: string;
2190
+ };
2191
+ caption?: string;
2192
+ } | {
2193
+ /** @enum {string} */
2194
+ type: "audio";
2195
+ media: {
2196
+ /** @description Pre-uploaded handle from POST /{phone-number-id}/media. Valid 30 days. Meta-cached. */
2197
+ media_id?: string;
2198
+ /**
2199
+ * Format: uri
2200
+ * @description Publicly accessible HTTPS URL. Meta fetches at send-time; no auth, no caching, size caps enforced server-side.
2201
+ */
2202
+ link?: string;
2203
+ };
2204
+ } | {
2205
+ /** @enum {string} */
2206
+ type: "document";
2207
+ media: {
2208
+ /** @description Pre-uploaded handle from POST /{phone-number-id}/media. Valid 30 days. Meta-cached. */
2209
+ media_id?: string;
2210
+ /**
2211
+ * Format: uri
2212
+ * @description Publicly accessible HTTPS URL. Meta fetches at send-time; no auth, no caching, size caps enforced server-side.
2213
+ */
2214
+ link?: string;
2215
+ };
2216
+ filename: string;
2217
+ caption?: string;
2218
+ } | {
2219
+ /** @enum {string} */
2220
+ type: "quick_replies";
2221
+ text: string;
2222
+ quick_replies: {
2223
+ title: string;
2224
+ payload: string;
2225
+ }[];
2226
+ };
2227
+ };
2228
+ };
2229
+ };
2230
+ responses: {
2231
+ /** @description Message sent */
2232
+ 200: {
2233
+ headers: {
2234
+ [name: string]: unknown;
2235
+ };
2236
+ content: {
2237
+ "application/json": {
2238
+ data: {
2239
+ /** Format: uuid */
2240
+ connection_id: string;
2241
+ /** @enum {string} */
2242
+ channel: "whatsapp" | "instagram";
2243
+ to: string;
2244
+ provider_message_id: string;
2245
+ sent_at: string;
2246
+ };
2247
+ meta: components["schemas"]["Meta"];
2248
+ };
2249
+ };
2250
+ };
2251
+ /** @description Missing scope or OAuth-app not authorized for this connection */
2252
+ 403: {
2253
+ headers: {
2254
+ [name: string]: unknown;
2255
+ };
2256
+ content: {
2257
+ "application/json": components["schemas"]["ErrorResponse"];
2258
+ };
2259
+ };
2260
+ /** @description Connection not found */
2261
+ 404: {
2262
+ headers: {
2263
+ [name: string]: unknown;
2264
+ };
2265
+ content: {
2266
+ "application/json": components["schemas"]["ErrorResponse"];
2267
+ };
2268
+ };
2269
+ /** @description Connection not ready (status != connected) */
2270
+ 409: {
2271
+ headers: {
2272
+ [name: string]: unknown;
2273
+ };
2274
+ content: {
2275
+ "application/json": components["schemas"]["ErrorResponse"];
2276
+ };
2277
+ };
2278
+ /** @description Validation error (content shape unsupported for this channel) */
2279
+ 422: {
2280
+ headers: {
2281
+ [name: string]: unknown;
2282
+ };
2283
+ content: {
2284
+ "application/json": components["schemas"]["ErrorResponse"];
2285
+ };
2286
+ };
2287
+ /** @description Upstream Meta send failed */
2288
+ 502: {
2289
+ headers: {
2290
+ [name: string]: unknown;
2291
+ };
2292
+ content: {
2293
+ "application/json": components["schemas"]["ErrorResponse"];
2294
+ };
2295
+ };
2296
+ };
2297
+ };
2298
+ delete?: never;
2299
+ options?: never;
2300
+ head?: never;
2301
+ patch?: never;
2302
+ trace?: never;
2303
+ };
2304
+ "/api/v1/comments/{comment_id}/private-reply": {
2305
+ parameters: {
2306
+ query?: never;
2307
+ header?: never;
2308
+ path?: never;
2309
+ cookie?: never;
2310
+ };
2311
+ get?: never;
2312
+ put?: never;
2313
+ /**
2314
+ * Send a DM to the user who left an IG comment
2315
+ * @description Targets Meta's `recipient.comment_id` send path — the message lands as a DM in the comment-to-DM thread. Requires `instagram` scope.
2316
+ */
2317
+ post: {
2318
+ parameters: {
2319
+ query?: never;
2320
+ header?: never;
2321
+ path: {
2322
+ comment_id: string;
2323
+ };
2324
+ cookie?: never;
2325
+ };
2326
+ requestBody?: {
2327
+ content: {
2328
+ "application/json": {
2329
+ /** Format: uuid */
2330
+ connection_id: string;
2331
+ text: string;
2332
+ };
2333
+ };
2334
+ };
2335
+ responses: {
2336
+ /** @description Private reply sent */
2337
+ 200: {
2338
+ headers: {
2339
+ [name: string]: unknown;
2340
+ };
2341
+ content: {
2342
+ "application/json": {
2343
+ data: {
2344
+ comment_id: string;
2345
+ /** @enum {string} */
2346
+ kind: "private_reply" | "public_reply";
2347
+ /** Format: uuid */
2348
+ connection_id: string;
2349
+ provider_message_id: string;
2350
+ sent_at: string;
2351
+ };
2352
+ meta: components["schemas"]["Meta"];
2353
+ };
2354
+ };
2355
+ };
2356
+ /** @description Missing scope or unauthorized connection */
2357
+ 403: {
2358
+ headers: {
2359
+ [name: string]: unknown;
2360
+ };
2361
+ content: {
2362
+ "application/json": components["schemas"]["ErrorResponse"];
2363
+ };
2364
+ };
2365
+ /** @description Connection not found */
2366
+ 404: {
2367
+ headers: {
2368
+ [name: string]: unknown;
2369
+ };
2370
+ content: {
2371
+ "application/json": components["schemas"]["ErrorResponse"];
2372
+ };
2373
+ };
2374
+ };
2375
+ };
2376
+ delete?: never;
2377
+ options?: never;
2378
+ head?: never;
2379
+ patch?: never;
2380
+ trace?: never;
2381
+ };
2382
+ "/api/v1/comments/{comment_id}/reply": {
2383
+ parameters: {
2384
+ query?: never;
2385
+ header?: never;
2386
+ path?: never;
2387
+ cookie?: never;
2388
+ };
2389
+ get?: never;
2390
+ put?: never;
2391
+ /**
2392
+ * Post a public reply on an IG comment thread
2393
+ * @description Posts directly to `/<comment-id>/replies` — visible to everyone, not a DM. Requires `instagram` scope.
2394
+ */
2395
+ post: {
2396
+ parameters: {
2397
+ query?: never;
2398
+ header?: never;
2399
+ path: {
2400
+ comment_id: string;
2401
+ };
2402
+ cookie?: never;
2403
+ };
2404
+ requestBody?: {
2405
+ content: {
2406
+ "application/json": {
2407
+ /** Format: uuid */
2408
+ connection_id: string;
2409
+ text: string;
2410
+ };
2411
+ };
2412
+ };
2413
+ responses: {
2414
+ /** @description Public reply posted */
2415
+ 200: {
2416
+ headers: {
2417
+ [name: string]: unknown;
2418
+ };
2419
+ content: {
2420
+ "application/json": {
2421
+ data: {
2422
+ comment_id: string;
2423
+ /** @enum {string} */
2424
+ kind: "private_reply" | "public_reply";
2425
+ /** Format: uuid */
2426
+ connection_id: string;
2427
+ provider_message_id: string;
2428
+ sent_at: string;
2429
+ };
2430
+ meta: components["schemas"]["Meta"];
2431
+ };
2432
+ };
2433
+ };
2434
+ /** @description Missing scope or unauthorized connection */
2435
+ 403: {
2436
+ headers: {
2437
+ [name: string]: unknown;
2438
+ };
2439
+ content: {
2440
+ "application/json": components["schemas"]["ErrorResponse"];
2441
+ };
2442
+ };
2443
+ /** @description Connection not found */
2444
+ 404: {
2445
+ headers: {
2446
+ [name: string]: unknown;
2447
+ };
2448
+ content: {
2449
+ "application/json": components["schemas"]["ErrorResponse"];
2450
+ };
2451
+ };
2452
+ };
2453
+ };
2454
+ delete?: never;
2455
+ options?: never;
2456
+ head?: never;
2457
+ patch?: never;
2458
+ trace?: never;
2459
+ };
2460
+ "/api/v1/webhooks/subscriptions": {
2461
+ parameters: {
2462
+ query?: never;
2463
+ header?: never;
2464
+ path?: never;
2465
+ cookie?: never;
2466
+ };
2467
+ /**
2468
+ * List webhook subscriptions
2469
+ * @description Returns the subscriptions owned by the calling OAuth app for the calling profile. At most one subscription per (app, profile) today.
2470
+ */
2471
+ get: {
2472
+ parameters: {
2473
+ query?: never;
2474
+ header?: never;
2475
+ path?: never;
2476
+ cookie?: never;
2477
+ };
2478
+ requestBody?: never;
2479
+ responses: {
2480
+ /** @description Subscriptions list */
2481
+ 200: {
2482
+ headers: {
2483
+ [name: string]: unknown;
2484
+ };
2485
+ content: {
2486
+ "application/json": {
2487
+ data: {
2488
+ /** Format: uuid */
2489
+ id: string;
2490
+ /** Format: uuid */
2491
+ app_id: string;
2492
+ /** Format: uuid */
2493
+ profile_id: string;
2494
+ /** Format: uri */
2495
+ url: string;
2496
+ events: string[];
2497
+ providers: string[];
2498
+ /** @enum {string} */
2499
+ status: "active" | "paused" | "failed";
2500
+ last_delivery_at: string | null;
2501
+ consecutive_failures: number;
2502
+ previous_secret_expires_at: string | null;
2503
+ created_at: string;
2504
+ updated_at: string;
2505
+ }[];
2506
+ meta: components["schemas"]["Meta"];
2507
+ };
2508
+ };
2509
+ };
2510
+ /** @description Endpoint is only available to OAuth-flow-minted keys */
2511
+ 403: {
2512
+ headers: {
2513
+ [name: string]: unknown;
2514
+ };
2515
+ content: {
2516
+ "application/json": components["schemas"]["ErrorResponse"];
2517
+ };
2518
+ };
2519
+ };
2520
+ };
2521
+ put?: never;
2522
+ /**
2523
+ * Create a webhook subscription
2524
+ * @description Creates a webhook subscription. The HMAC `secret` is returned ONCE in the response body and never again — persist it on your side. Atribu signs every outbound event as `X-Atribu-Signature: t=<unix>,v1=<hex_hmac_sha256>` over `<ts>.<body>`.
2525
+ */
2526
+ post: {
2527
+ parameters: {
2528
+ query?: never;
2529
+ header?: never;
2530
+ path?: never;
2531
+ cookie?: never;
2532
+ };
2533
+ requestBody?: {
2534
+ content: {
2535
+ "application/json": {
2536
+ /**
2537
+ * Format: uri
2538
+ * @description HTTPS URL where Atribu will POST signed events.
2539
+ */
2540
+ url: string;
2541
+ events: ("message.received" | "message.delivery" | "conversation.started")[];
2542
+ providers: ("whatsapp" | "instagram")[];
2543
+ };
2544
+ };
2545
+ };
2546
+ responses: {
2547
+ /** @description Subscription created; `secret` field shown once */
2548
+ 201: {
2549
+ headers: {
2550
+ [name: string]: unknown;
2551
+ };
2552
+ content: {
2553
+ "application/json": {
2554
+ data: {
2555
+ /** Format: uuid */
2556
+ id: string;
2557
+ /** Format: uuid */
2558
+ app_id: string;
2559
+ /** Format: uuid */
2560
+ profile_id: string;
2561
+ /** Format: uri */
2562
+ url: string;
2563
+ events: string[];
2564
+ providers: string[];
2565
+ /** @enum {string} */
2566
+ status: "active" | "paused" | "failed";
2567
+ last_delivery_at: string | null;
2568
+ consecutive_failures: number;
2569
+ previous_secret_expires_at: string | null;
2570
+ created_at: string;
2571
+ updated_at: string;
2572
+ secret: string;
2573
+ };
2574
+ };
2575
+ };
2576
+ };
2577
+ /** @description A subscription already exists for this (app, profile) */
2578
+ 409: {
2579
+ headers: {
2580
+ [name: string]: unknown;
2581
+ };
2582
+ content: {
2583
+ "application/json": components["schemas"]["ErrorResponse"];
2584
+ };
2585
+ };
2586
+ };
2587
+ };
2588
+ delete?: never;
2589
+ options?: never;
2590
+ head?: never;
2591
+ patch?: never;
2592
+ trace?: never;
2593
+ };
2594
+ "/api/v1/webhooks/subscriptions/{id}": {
2595
+ parameters: {
2596
+ query?: never;
2597
+ header?: never;
2598
+ path?: never;
2599
+ cookie?: never;
2600
+ };
2601
+ get?: never;
2602
+ put?: never;
2603
+ post?: never;
2604
+ /**
2605
+ * Delete a webhook subscription
2606
+ * @description Hard-deletes the subscription. Existing `webhook_deliveries` audit rows cascade via FK ON DELETE CASCADE.
2607
+ */
2608
+ delete: {
2609
+ parameters: {
2610
+ query?: never;
2611
+ header?: never;
2612
+ path: {
2613
+ id: string;
2614
+ };
2615
+ cookie?: never;
2616
+ };
2617
+ requestBody?: never;
2618
+ responses: {
2619
+ /** @description Subscription deleted */
2620
+ 204: {
2621
+ headers: {
2622
+ [name: string]: unknown;
2623
+ };
2624
+ content?: never;
2625
+ };
2626
+ /** @description Subscription not found */
2627
+ 404: {
2628
+ headers: {
2629
+ [name: string]: unknown;
2630
+ };
2631
+ content: {
2632
+ "application/json": components["schemas"]["ErrorResponse"];
2633
+ };
2634
+ };
2635
+ };
2636
+ };
2637
+ options?: never;
2638
+ head?: never;
2639
+ /**
2640
+ * Update a webhook subscription
2641
+ * @description Update `url`, `events`, `providers`, or `status` (active/paused). At least one field is required.
2642
+ */
2643
+ patch: {
2644
+ parameters: {
2645
+ query?: never;
2646
+ header?: never;
2647
+ path: {
2648
+ id: string;
2649
+ };
2650
+ cookie?: never;
2651
+ };
2652
+ requestBody?: {
2653
+ content: {
2654
+ "application/json": {
2655
+ /** Format: uri */
2656
+ url?: string;
2657
+ events?: string[];
2658
+ providers?: string[];
2659
+ /** @enum {string} */
2660
+ status?: "active" | "paused";
2661
+ };
2662
+ };
2663
+ };
2664
+ responses: {
2665
+ /** @description Subscription updated */
2666
+ 200: {
2667
+ headers: {
2668
+ [name: string]: unknown;
2669
+ };
2670
+ content: {
2671
+ "application/json": {
2672
+ data: {
2673
+ /** Format: uuid */
2674
+ id: string;
2675
+ /** Format: uuid */
2676
+ app_id: string;
2677
+ /** Format: uuid */
2678
+ profile_id: string;
2679
+ /** Format: uri */
2680
+ url: string;
2681
+ events: string[];
2682
+ providers: string[];
2683
+ /** @enum {string} */
2684
+ status: "active" | "paused" | "failed";
2685
+ last_delivery_at: string | null;
2686
+ consecutive_failures: number;
2687
+ previous_secret_expires_at: string | null;
2688
+ created_at: string;
2689
+ updated_at: string;
2690
+ };
2691
+ meta: components["schemas"]["Meta"];
2692
+ };
2693
+ };
2694
+ };
2695
+ /** @description Subscription not found */
2696
+ 404: {
2697
+ headers: {
2698
+ [name: string]: unknown;
2699
+ };
2700
+ content: {
2701
+ "application/json": components["schemas"]["ErrorResponse"];
2702
+ };
2703
+ };
2704
+ };
2705
+ };
2706
+ trace?: never;
2707
+ };
2708
+ "/api/v1/webhooks/subscriptions/{id}/rotate-secret": {
2709
+ parameters: {
2710
+ query?: never;
2711
+ header?: never;
2712
+ path?: never;
2713
+ cookie?: never;
2714
+ };
2715
+ get?: never;
2716
+ put?: never;
2717
+ /**
2718
+ * Rotate a subscription's HMAC secret
2719
+ * @description Generates a fresh HMAC secret and atomically rolls current→previous with a grace window (default 7d, max 90d). **Important: deploy dual-verify on your side BEFORE calling this** — Atribu starts signing with the new secret immediately. The previous secret stays in DB only so subscribers can dual-verify during their deploy.
2720
+ */
2721
+ post: {
2722
+ parameters: {
2723
+ query?: never;
2724
+ header?: never;
2725
+ path: {
2726
+ id: string;
2727
+ };
2728
+ cookie?: never;
2729
+ };
2730
+ requestBody?: {
2731
+ content: {
2732
+ "application/json": {
2733
+ grace_days?: number;
2734
+ };
2735
+ };
2736
+ };
2737
+ responses: {
2738
+ /** @description New secret returned once */
2739
+ 200: {
2740
+ headers: {
2741
+ [name: string]: unknown;
2742
+ };
2743
+ content: {
2744
+ "application/json": {
2745
+ data: {
2746
+ /** Format: uuid */
2747
+ subscription_id: string;
2748
+ secret: string;
2749
+ grace_days: number;
2750
+ previous_secret_expires_at: string;
2751
+ };
2752
+ meta: components["schemas"]["Meta"];
2753
+ };
2754
+ };
2755
+ };
2756
+ };
2757
+ };
2758
+ delete?: never;
2759
+ options?: never;
2760
+ head?: never;
2761
+ patch?: never;
2762
+ trace?: never;
2763
+ };
2764
+ "/api/v1/webhooks/test/{id}": {
2765
+ parameters: {
2766
+ query?: never;
2767
+ header?: never;
2768
+ path?: never;
2769
+ cookie?: never;
2770
+ };
2771
+ get?: never;
2772
+ put?: never;
2773
+ /**
2774
+ * Fire a synthetic test event
2775
+ * @description Enqueues a synthetic `message.received` event onto the outbound queue for the subscription. Subscriber receives a fully-signed POST so signature + payload handling can be verified before the first real inbound event.
2776
+ */
2777
+ post: {
2778
+ parameters: {
2779
+ query?: never;
2780
+ header?: never;
2781
+ path: {
2782
+ id: string;
2783
+ };
2784
+ cookie?: never;
2785
+ };
2786
+ requestBody?: never;
2787
+ responses: {
2788
+ /** @description Synthetic event enqueued */
2789
+ 200: {
2790
+ headers: {
2791
+ [name: string]: unknown;
2792
+ };
2793
+ content: {
2794
+ "application/json": {
2795
+ data: {
2796
+ enqueued: boolean;
2797
+ /** Format: uuid */
2798
+ event_id: string;
2799
+ /** Format: uuid */
2800
+ subscription_id: string;
2801
+ };
2802
+ meta: components["schemas"]["Meta"];
2803
+ };
2804
+ };
2805
+ };
2806
+ };
2807
+ };
2808
+ delete?: never;
2809
+ options?: never;
2810
+ head?: never;
2811
+ patch?: never;
2812
+ trace?: never;
2813
+ };
2814
+ "/api/v1/webhooks/deliveries/{id}/replay": {
2815
+ parameters: {
2816
+ query?: never;
2817
+ header?: never;
2818
+ path?: never;
2819
+ cookie?: never;
2820
+ };
2821
+ get?: never;
2822
+ put?: never;
2823
+ /**
2824
+ * Replay a webhook delivery
2825
+ * @description Re-enqueues the payload from an existing `webhook_deliveries` row. The original `event.id` is preserved so subscribers can de-dup the replay. Only the OAuth app that owns the subscription can replay.
2826
+ */
2827
+ post: {
2828
+ parameters: {
2829
+ query?: never;
2830
+ header?: never;
2831
+ path: {
2832
+ id: string;
2833
+ };
2834
+ cookie?: never;
2835
+ };
2836
+ requestBody?: never;
2837
+ responses: {
2838
+ /** @description Replay queued */
2839
+ 200: {
2840
+ headers: {
2841
+ [name: string]: unknown;
2842
+ };
2843
+ content: {
2844
+ "application/json": {
2845
+ data: {
2846
+ enqueued: boolean;
2847
+ /** Format: uuid */
2848
+ delivery_id: string;
2849
+ /** Format: uuid */
2850
+ event_id: string;
2851
+ /** Format: uuid */
2852
+ subscription_id: string;
2853
+ };
2854
+ meta: components["schemas"]["Meta"];
2855
+ };
2856
+ };
2857
+ };
2858
+ /** @description Delivery or subscription not found */
2859
+ 404: {
2860
+ headers: {
2861
+ [name: string]: unknown;
2862
+ };
2863
+ content: {
2864
+ "application/json": components["schemas"]["ErrorResponse"];
2865
+ };
2866
+ };
2867
+ };
2868
+ };
2869
+ delete?: never;
2870
+ options?: never;
2871
+ head?: never;
2872
+ patch?: never;
2873
+ trace?: never;
2874
+ };
2875
+ "/oauth/token": {
2876
+ parameters: {
2877
+ query?: never;
2878
+ header?: never;
2879
+ path?: never;
2880
+ cookie?: never;
2881
+ };
2882
+ get?: never;
2883
+ put?: never;
2884
+ /**
2885
+ * OAuth 2.0 authorization_code grant exchange
2886
+ * @description RFC 6749 §4.1.3 token endpoint. Exchanges a single-use `code` (issued at `/oauth/authorize` consent) for an Atribu API key. Accepts both `application/x-www-form-urlencoded` (spec-default) and `application/json` bodies. Client authentication: `client_secret_basic` (`Authorization: Basic <base64(id:secret)>`) OR `client_secret_post` (`client_id` + `client_secret` in body).
2887
+ *
2888
+ * Returns `Cache-Control: no-store` per RFC.
2889
+ */
2890
+ post: {
2891
+ parameters: {
2892
+ query?: never;
2893
+ header?: never;
2894
+ path?: never;
2895
+ cookie?: never;
2896
+ };
2897
+ requestBody?: {
2898
+ content: {
2899
+ "application/x-www-form-urlencoded": {
2900
+ /** @enum {string} */
2901
+ grant_type: "authorization_code";
2902
+ code: string;
2903
+ /** Format: uri */
2904
+ redirect_uri: string;
2905
+ /** @description Required when not using `Authorization: Basic`. */
2906
+ client_id?: string;
2907
+ /** @description Required when not using `Authorization: Basic`. */
2908
+ client_secret?: string;
2909
+ /** @description PKCE verifier (RFC 7636). Required when the authorize step sent a `code_challenge`. */
2910
+ code_verifier?: string;
2911
+ };
2912
+ "application/json": {
2913
+ /** @enum {string} */
2914
+ grant_type: "authorization_code";
2915
+ code: string;
2916
+ /** Format: uri */
2917
+ redirect_uri: string;
2918
+ /** @description Required when not using `Authorization: Basic`. */
2919
+ client_id?: string;
2920
+ /** @description Required when not using `Authorization: Basic`. */
2921
+ client_secret?: string;
2922
+ /** @description PKCE verifier (RFC 7636). Required when the authorize step sent a `code_challenge`. */
2923
+ code_verifier?: string;
2924
+ };
2925
+ };
2926
+ };
2927
+ responses: {
2928
+ /** @description Code exchanged successfully */
2929
+ 200: {
2930
+ headers: {
2931
+ [name: string]: unknown;
2932
+ };
2933
+ content: {
2934
+ "application/json": {
2935
+ /** @description The minted Atribu API key (`atb_live_...`). Use as `Authorization: Bearer <token>` on `/api/v1/*` calls. */
2936
+ access_token: string;
2937
+ /** @enum {string} */
2938
+ token_type: "bearer";
2939
+ /** @description Space-separated scopes. Subset of `whatsapp instagram` today. */
2940
+ scope: string;
2941
+ /**
2942
+ * Format: uuid
2943
+ * @description UUID of the `data_connections` row the user authorized. Pass on `POST /api/v1/messages`.
2944
+ */
2945
+ connection_id?: string;
2946
+ /** Format: uuid */
2947
+ profile_id: string;
2948
+ /** Format: uuid */
2949
+ workspace_id: string;
2950
+ };
2951
+ };
2952
+ };
2953
+ /** @description `invalid_grant` / `invalid_request` / `unsupported_grant_type` */
2954
+ 400: {
2955
+ headers: {
2956
+ [name: string]: unknown;
2957
+ };
2958
+ content: {
2959
+ "application/json": {
2960
+ /** @description RFC 6749 §5.2 / RFC 7009 §2.2.1 error code. */
2961
+ error: string;
2962
+ error_description?: string;
2963
+ };
2964
+ };
2965
+ };
2966
+ /** @description `invalid_client` */
2967
+ 401: {
2968
+ headers: {
2969
+ [name: string]: unknown;
2970
+ };
2971
+ content: {
2972
+ "application/json": {
2973
+ /** @description RFC 6749 §5.2 / RFC 7009 §2.2.1 error code. */
2974
+ error: string;
2975
+ error_description?: string;
2976
+ };
2977
+ };
2978
+ };
2979
+ /** @description `server_error` */
2980
+ 500: {
2981
+ headers: {
2982
+ [name: string]: unknown;
2983
+ };
2984
+ content: {
2985
+ "application/json": {
2986
+ /** @description RFC 6749 §5.2 / RFC 7009 §2.2.1 error code. */
2987
+ error: string;
2988
+ error_description?: string;
2989
+ };
2990
+ };
2991
+ };
2992
+ };
2993
+ };
2994
+ delete?: never;
2995
+ options?: never;
2996
+ head?: never;
2997
+ patch?: never;
2998
+ trace?: never;
2999
+ };
3000
+ "/oauth/revoke": {
3001
+ parameters: {
3002
+ query?: never;
3003
+ header?: never;
3004
+ path?: never;
3005
+ cookie?: never;
3006
+ };
3007
+ get?: never;
3008
+ put?: never;
3009
+ /**
3010
+ * RFC 7009 token revocation
3011
+ * @description Revokes an access token minted via `/oauth/token`. Returns 200 regardless of whether the token existed (RFC §2.2 — no enumeration). Idempotent. Client authentication identical to `/oauth/token`. The `token_type_hint` is accepted (`access_token`) but ignored — only `access_token` is supported.
3012
+ */
3013
+ post: {
3014
+ parameters: {
3015
+ query?: never;
3016
+ header?: never;
3017
+ path?: never;
3018
+ cookie?: never;
3019
+ };
3020
+ requestBody?: {
3021
+ content: {
3022
+ "application/x-www-form-urlencoded": {
3023
+ token: string;
3024
+ /** @enum {string} */
3025
+ token_type_hint?: "access_token";
3026
+ client_id?: string;
3027
+ client_secret?: string;
3028
+ };
3029
+ "application/json": {
3030
+ token: string;
3031
+ /** @enum {string} */
3032
+ token_type_hint?: "access_token";
3033
+ client_id?: string;
3034
+ client_secret?: string;
3035
+ };
3036
+ };
3037
+ };
3038
+ responses: {
3039
+ /** @description Empty 200 (RFC 7009) */
3040
+ 200: {
3041
+ headers: {
3042
+ [name: string]: unknown;
3043
+ };
3044
+ content?: never;
3045
+ };
3046
+ /** @description `invalid_request` */
3047
+ 400: {
3048
+ headers: {
3049
+ [name: string]: unknown;
3050
+ };
3051
+ content: {
3052
+ "application/json": {
3053
+ /** @description RFC 6749 §5.2 / RFC 7009 §2.2.1 error code. */
3054
+ error: string;
3055
+ error_description?: string;
3056
+ };
3057
+ };
3058
+ };
3059
+ /** @description `invalid_client` */
3060
+ 401: {
3061
+ headers: {
3062
+ [name: string]: unknown;
3063
+ };
3064
+ content: {
3065
+ "application/json": {
3066
+ /** @description RFC 6749 §5.2 / RFC 7009 §2.2.1 error code. */
3067
+ error: string;
3068
+ error_description?: string;
3069
+ };
3070
+ };
3071
+ };
3072
+ };
3073
+ };
3074
+ delete?: never;
3075
+ options?: never;
3076
+ head?: never;
3077
+ patch?: never;
3078
+ trace?: never;
3079
+ };
3080
+ "/api/v1/admin/oauth-apps": {
3081
+ parameters: {
3082
+ query?: never;
3083
+ header?: never;
3084
+ path?: never;
3085
+ cookie?: never;
3086
+ };
3087
+ get?: never;
3088
+ put?: never;
3089
+ /**
3090
+ * Create a consumer OAuth app
3091
+ * @description Creates a new consumer OAuth app (e.g. "vitrina"). Generates fresh `client_secret` + `jwt_signing_secret` server-side — both returned **once** in the 201 response and never readable again. Store them safely; rotate via the dedicated endpoints.
3092
+ */
3093
+ post: {
3094
+ parameters: {
3095
+ query?: never;
3096
+ header?: never;
3097
+ path?: never;
3098
+ cookie?: never;
3099
+ };
3100
+ requestBody?: {
3101
+ content: {
3102
+ "application/json": {
3103
+ client_id: string;
3104
+ name: string;
3105
+ description?: string;
3106
+ /** Format: uri */
3107
+ logo_url?: string;
3108
+ redirect_uris: string[];
3109
+ allowed_scopes: ("whatsapp" | "instagram")[];
3110
+ /** Format: uuid */
3111
+ created_by: string;
3112
+ };
3113
+ };
3114
+ };
3115
+ responses: {
3116
+ /** @description App created; secrets shown once */
3117
+ 201: {
3118
+ headers: {
3119
+ [name: string]: unknown;
3120
+ };
3121
+ content: {
3122
+ "application/json": {
3123
+ data: {
3124
+ /** Format: uuid */
3125
+ id: string;
3126
+ client_id: string;
3127
+ name: string;
3128
+ description: string | null;
3129
+ logo_url: string | null;
3130
+ redirect_uris: string[];
3131
+ allowed_scopes: ("whatsapp" | "instagram")[];
3132
+ /** @enum {string} */
3133
+ status: "active" | "suspended";
3134
+ created_at: string;
3135
+ client_secret: string;
3136
+ jwt_signing_secret: string;
3137
+ };
3138
+ };
3139
+ };
3140
+ };
3141
+ /** @description Invalid request (e.g. unknown `created_by` user) */
3142
+ 400: {
3143
+ headers: {
3144
+ [name: string]: unknown;
3145
+ };
3146
+ content: {
3147
+ "application/json": components["schemas"]["ErrorResponse"];
3148
+ };
3149
+ };
3150
+ /** @description `client_id` already exists */
3151
+ 409: {
3152
+ headers: {
3153
+ [name: string]: unknown;
3154
+ };
3155
+ content: {
3156
+ "application/json": components["schemas"]["ErrorResponse"];
3157
+ };
3158
+ };
3159
+ /** @description Validation error */
3160
+ 422: {
3161
+ headers: {
3162
+ [name: string]: unknown;
3163
+ };
3164
+ content: {
3165
+ "application/json": components["schemas"]["ErrorResponse"];
3166
+ };
3167
+ };
3168
+ };
3169
+ };
3170
+ delete?: never;
3171
+ options?: never;
3172
+ head?: never;
3173
+ patch?: never;
3174
+ trace?: never;
3175
+ };
3176
+ "/api/v1/admin/oauth-apps/{id}": {
3177
+ parameters: {
3178
+ query?: never;
3179
+ header?: never;
3180
+ path?: never;
3181
+ cookie?: never;
3182
+ };
3183
+ get?: never;
3184
+ put?: never;
3185
+ post?: never;
3186
+ /**
3187
+ * Suspend a consumer OAuth app (kill-switch)
3188
+ * @description Flips `status='suspended'` AND atomically revokes every `api_key` minted via this app. Idempotent — re-running on an already-suspended app returns `keys_revoked=0`. After suspension, in-flight consumer keys stop working immediately; the app reappears (with the same id) only if re-activated via PATCH.
3189
+ */
3190
+ delete: {
3191
+ parameters: {
3192
+ query?: never;
3193
+ header?: never;
3194
+ path: {
3195
+ id: string;
3196
+ };
3197
+ cookie?: never;
3198
+ };
3199
+ requestBody?: never;
3200
+ responses: {
3201
+ /** @description App suspended; api_keys cascaded */
3202
+ 200: {
3203
+ headers: {
3204
+ [name: string]: unknown;
3205
+ };
3206
+ content: {
3207
+ "application/json": {
3208
+ data: {
3209
+ /** Format: uuid */
3210
+ id: string;
3211
+ /** @enum {string} */
3212
+ status: "suspended";
3213
+ keys_revoked: number;
3214
+ };
3215
+ };
3216
+ };
3217
+ };
3218
+ /** @description App not found */
3219
+ 404: {
3220
+ headers: {
3221
+ [name: string]: unknown;
3222
+ };
3223
+ content: {
3224
+ "application/json": components["schemas"]["ErrorResponse"];
3225
+ };
3226
+ };
3227
+ };
3228
+ };
3229
+ options?: never;
3230
+ head?: never;
3231
+ /**
3232
+ * Update a consumer OAuth app
3233
+ * @description Update name, description, logo, redirect URIs, scopes, or status. At least one field is required.
3234
+ */
3235
+ patch: {
3236
+ parameters: {
3237
+ query?: never;
3238
+ header?: never;
3239
+ path: {
3240
+ id: string;
3241
+ };
3242
+ cookie?: never;
3243
+ };
3244
+ requestBody?: {
3245
+ content: {
3246
+ "application/json": {
3247
+ name?: string;
3248
+ description?: string | null;
3249
+ /** Format: uri */
3250
+ logo_url?: string | null;
3251
+ redirect_uris?: string[];
3252
+ allowed_scopes?: ("whatsapp" | "instagram")[];
3253
+ /** @enum {string} */
3254
+ status?: "active" | "suspended";
3255
+ };
3256
+ };
3257
+ };
3258
+ responses: {
3259
+ /** @description App updated */
3260
+ 200: {
3261
+ headers: {
3262
+ [name: string]: unknown;
3263
+ };
3264
+ content: {
3265
+ "application/json": {
3266
+ data: {
3267
+ /** Format: uuid */
3268
+ id: string;
3269
+ client_id: string;
3270
+ name: string;
3271
+ description: string | null;
3272
+ logo_url: string | null;
3273
+ redirect_uris: string[];
3274
+ allowed_scopes: ("whatsapp" | "instagram")[];
3275
+ /** @enum {string} */
3276
+ status: "active" | "suspended";
3277
+ created_at: string;
3278
+ };
3279
+ };
3280
+ };
3281
+ };
3282
+ /** @description App not found */
3283
+ 404: {
3284
+ headers: {
3285
+ [name: string]: unknown;
3286
+ };
3287
+ content: {
3288
+ "application/json": components["schemas"]["ErrorResponse"];
3289
+ };
3290
+ };
3291
+ /** @description Validation error */
3292
+ 422: {
3293
+ headers: {
3294
+ [name: string]: unknown;
3295
+ };
3296
+ content: {
3297
+ "application/json": components["schemas"]["ErrorResponse"];
3298
+ };
3299
+ };
3300
+ };
3301
+ };
3302
+ trace?: never;
3303
+ };
3304
+ "/api/v1/admin/oauth-apps/{id}/rotate-client-secret": {
3305
+ parameters: {
3306
+ query?: never;
3307
+ header?: never;
3308
+ path?: never;
3309
+ cookie?: never;
3310
+ };
3311
+ get?: never;
3312
+ put?: never;
3313
+ /**
3314
+ * Rotate the OAuth app's `client_secret`
3315
+ * @description Atomically rolls `client_secret_hash` → `previous_client_secret_hash` with a grace window (default 7 days, max 90). The new plaintext secret is returned **once**. In-flight `/oauth/token` calls authenticated with the old secret continue to succeed until the grace window expires.
3316
+ */
3317
+ post: {
3318
+ parameters: {
3319
+ query?: never;
3320
+ header?: never;
3321
+ path: {
3322
+ id: string;
3323
+ };
3324
+ cookie?: never;
3325
+ };
3326
+ requestBody?: {
3327
+ content: {
3328
+ "application/json": {
3329
+ grace_days?: number;
3330
+ };
3331
+ };
3332
+ };
3333
+ responses: {
3334
+ /** @description New secret returned once */
3335
+ 200: {
3336
+ headers: {
3337
+ [name: string]: unknown;
3338
+ };
3339
+ content: {
3340
+ "application/json": {
3341
+ data: {
3342
+ /** Format: uuid */
3343
+ oauth_app_id: string;
3344
+ client_secret: string;
3345
+ grace_days: number;
3346
+ previous_client_secret_expires_at: string;
3347
+ };
3348
+ };
3349
+ };
3350
+ };
3351
+ /** @description App not found */
3352
+ 404: {
3353
+ headers: {
3354
+ [name: string]: unknown;
3355
+ };
3356
+ content: {
3357
+ "application/json": components["schemas"]["ErrorResponse"];
3358
+ };
3359
+ };
3360
+ /** @description `grace_days` out of range */
3361
+ 422: {
3362
+ headers: {
3363
+ [name: string]: unknown;
3364
+ };
3365
+ content: {
3366
+ "application/json": components["schemas"]["ErrorResponse"];
3367
+ };
3368
+ };
3369
+ };
3370
+ };
3371
+ delete?: never;
3372
+ options?: never;
3373
+ head?: never;
3374
+ patch?: never;
3375
+ trace?: never;
3376
+ };
3377
+ "/api/v1/admin/oauth-apps/{id}/rotate-jwt-secret": {
3378
+ parameters: {
3379
+ query?: never;
3380
+ header?: never;
3381
+ path?: never;
3382
+ cookie?: never;
3383
+ };
3384
+ get?: never;
3385
+ put?: never;
3386
+ /**
3387
+ * Rotate the OAuth app's `id_token_hint` HS256 signing secret
3388
+ * @description Atomically rolls `jwt_signing_secret` → `previous_jwt_signing_secret` with a grace window (default 7 days, max 90). Atribu's `id_token_hint` verifier accepts both during the window so in-flight authorize flows don't break mid-deploy.
3389
+ */
3390
+ post: {
3391
+ parameters: {
3392
+ query?: never;
3393
+ header?: never;
3394
+ path: {
3395
+ id: string;
3396
+ };
3397
+ cookie?: never;
3398
+ };
3399
+ requestBody?: {
3400
+ content: {
3401
+ "application/json": {
3402
+ grace_days?: number;
3403
+ };
3404
+ };
3405
+ };
3406
+ responses: {
3407
+ /** @description New secret returned once */
3408
+ 200: {
3409
+ headers: {
3410
+ [name: string]: unknown;
3411
+ };
3412
+ content: {
3413
+ "application/json": {
3414
+ data: {
3415
+ /** Format: uuid */
3416
+ oauth_app_id: string;
3417
+ jwt_signing_secret: string;
3418
+ grace_days: number;
3419
+ previous_jwt_signing_secret_expires_at: string;
3420
+ };
3421
+ };
3422
+ };
3423
+ };
3424
+ /** @description App not found */
3425
+ 404: {
3426
+ headers: {
3427
+ [name: string]: unknown;
3428
+ };
3429
+ content: {
3430
+ "application/json": components["schemas"]["ErrorResponse"];
3431
+ };
3432
+ };
3433
+ /** @description `grace_days` out of range */
3434
+ 422: {
3435
+ headers: {
3436
+ [name: string]: unknown;
3437
+ };
3438
+ content: {
3439
+ "application/json": components["schemas"]["ErrorResponse"];
3440
+ };
3441
+ };
3442
+ };
3443
+ };
3444
+ delete?: never;
3445
+ options?: never;
3446
+ head?: never;
3447
+ patch?: never;
3448
+ trace?: never;
3449
+ };
3450
+ }
3451
+ interface components {
3452
+ schemas: {
3453
+ ErrorResponse: {
3454
+ error: {
3455
+ /** @example invalid_parameter */
3456
+ code: string;
3457
+ /** @example date_from is required */
3458
+ message: string;
3459
+ /** @example 400 */
3460
+ status: number;
3461
+ /** @example req_a1b2c3d4 */
3462
+ request_id: string;
3463
+ };
3464
+ };
3465
+ Meta: {
3466
+ /** @example 2026-03-01 */
3467
+ date_from?: string;
3468
+ /** @example 2026-03-25 */
3469
+ date_to?: string;
3470
+ /** @example uuid */
3471
+ profile_id: string;
3472
+ };
3473
+ Pagination: {
3474
+ has_next: boolean;
3475
+ cursor?: string;
3476
+ };
3477
+ /**
3478
+ * @description Start date (YYYY-MM-DD, inclusive)
3479
+ * @example 2026-03-01
3480
+ */
3481
+ date_from: string;
3482
+ /**
3483
+ * @description End date (YYYY-MM-DD, inclusive). Max range: 366 days.
3484
+ * @example 2026-03-25
3485
+ */
3486
+ date_to: string;
3487
+ /**
3488
+ * @description Max results to return (default 10, max 100)
3489
+ * @example 10
3490
+ */
3491
+ limit: string;
3492
+ /**
3493
+ * @description Attribution model. One of: last_touch, first_touch, split_50_50, linear, position_based, time_decay, last_non_direct, custom_weighted
3494
+ * @example last_touch
3495
+ */
3496
+ model: string;
3497
+ OverviewResponse: {
3498
+ data: {
3499
+ current: {
3500
+ spend: number;
3501
+ revenue: number;
3502
+ roas: number;
3503
+ outcomes: number;
3504
+ attributed_outcomes: number;
3505
+ coverage_percent: number;
3506
+ visitors: number;
3507
+ pageviews: number;
3508
+ bounce_rate: number;
3509
+ avg_engaged_seconds: number;
3510
+ cash_revenue: number;
3511
+ cash_payments: number;
3512
+ };
3513
+ previous: {
3514
+ spend: number;
3515
+ revenue: number;
3516
+ roas: number;
3517
+ outcomes: number;
3518
+ attributed_outcomes: number;
3519
+ coverage_percent: number;
3520
+ visitors: number;
3521
+ pageviews: number;
3522
+ bounce_rate: number;
3523
+ avg_engaged_seconds: number;
3524
+ cash_revenue: number;
3525
+ cash_payments: number;
3526
+ };
3527
+ };
3528
+ meta: components["schemas"]["Meta"];
3529
+ };
3530
+ };
3531
+ responses: never;
3532
+ parameters: {
3533
+ /** @description Start date (YYYY-MM-DD, inclusive) */
3534
+ date_from: components["schemas"]["date_from"];
3535
+ /** @description End date (YYYY-MM-DD, inclusive). Max range: 366 days. */
3536
+ date_to: components["schemas"]["date_to"];
3537
+ /** @description Max results to return (default 10, max 100) */
3538
+ limit: components["schemas"]["limit"];
3539
+ /** @description Attribution model. One of: last_touch, first_touch, split_50_50, linear, position_based, time_decay, last_non_direct, custom_weighted */
3540
+ model: components["schemas"]["model"];
3541
+ };
3542
+ requestBodies: never;
3543
+ headers: never;
3544
+ pathItems: never;
3545
+ }
3546
+
3547
+ export type { HttpClientLike as H, RequestOptions as R, paths as p };