@isnap/sdk 0.0.0-next.3 → 1.1.0-next.38

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.
@@ -29,6 +29,33 @@ export interface paths {
29
29
  "application/json": components["schemas"]["HealthResponse"];
30
30
  };
31
31
  };
32
+ /** @description Bad request — validation failed */
33
+ 400: {
34
+ headers: {
35
+ [name: string]: unknown;
36
+ };
37
+ content: {
38
+ "application/json": components["schemas"]["ErrorEnvelope"];
39
+ };
40
+ };
41
+ /** @description Too many requests — rate limit exceeded */
42
+ 429: {
43
+ headers: {
44
+ [name: string]: unknown;
45
+ };
46
+ content: {
47
+ "application/json": components["schemas"]["ErrorEnvelope"];
48
+ };
49
+ };
50
+ /** @description Internal server error */
51
+ 500: {
52
+ headers: {
53
+ [name: string]: unknown;
54
+ };
55
+ content: {
56
+ "application/json": components["schemas"]["ErrorEnvelope"];
57
+ };
58
+ };
32
59
  /** @description Degraded */
33
60
  503: {
34
61
  headers: {
@@ -48,6 +75,68 @@ export interface paths {
48
75
  patch?: never;
49
76
  trace?: never;
50
77
  };
78
+ "/v1/version": {
79
+ parameters: {
80
+ query?: never;
81
+ header?: never;
82
+ path?: never;
83
+ cookie?: never;
84
+ };
85
+ get: {
86
+ parameters: {
87
+ query?: never;
88
+ header?: never;
89
+ path?: never;
90
+ cookie?: never;
91
+ };
92
+ requestBody?: never;
93
+ responses: {
94
+ /** @description API schema version */
95
+ 200: {
96
+ headers: {
97
+ [name: string]: unknown;
98
+ };
99
+ content: {
100
+ "application/json": components["schemas"]["VersionResponse"];
101
+ };
102
+ };
103
+ /** @description Bad request — validation failed */
104
+ 400: {
105
+ headers: {
106
+ [name: string]: unknown;
107
+ };
108
+ content: {
109
+ "application/json": components["schemas"]["ErrorEnvelope"];
110
+ };
111
+ };
112
+ /** @description Too many requests — rate limit exceeded */
113
+ 429: {
114
+ headers: {
115
+ [name: string]: unknown;
116
+ };
117
+ content: {
118
+ "application/json": components["schemas"]["ErrorEnvelope"];
119
+ };
120
+ };
121
+ /** @description Internal server error */
122
+ 500: {
123
+ headers: {
124
+ [name: string]: unknown;
125
+ };
126
+ content: {
127
+ "application/json": components["schemas"]["ErrorEnvelope"];
128
+ };
129
+ };
130
+ };
131
+ };
132
+ put?: never;
133
+ post?: never;
134
+ delete?: never;
135
+ options?: never;
136
+ head?: never;
137
+ patch?: never;
138
+ trace?: never;
139
+ };
51
140
  "/auth/signup": {
52
141
  parameters: {
53
142
  query?: never;
@@ -471,6 +560,10 @@ export interface paths {
471
560
  path?: never;
472
561
  cookie?: never;
473
562
  };
563
+ /**
564
+ * List public line pricing
565
+ * @description Returns the per-tier rental and BYOD price table in monthly / quarterly / annual cadences. Unauthenticated — partners and prospective customers consume this for marketplace and quote-tool displays.
566
+ */
474
567
  get: {
475
568
  parameters: {
476
569
  query?: never;
@@ -489,6 +582,33 @@ export interface paths {
489
582
  "application/json": components["schemas"]["Pricing"];
490
583
  };
491
584
  };
585
+ /** @description Bad request — validation failed */
586
+ 400: {
587
+ headers: {
588
+ [name: string]: unknown;
589
+ };
590
+ content: {
591
+ "application/json": components["schemas"]["ErrorEnvelope"];
592
+ };
593
+ };
594
+ /** @description Too many requests — rate limit exceeded */
595
+ 429: {
596
+ headers: {
597
+ [name: string]: unknown;
598
+ };
599
+ content: {
600
+ "application/json": components["schemas"]["ErrorEnvelope"];
601
+ };
602
+ };
603
+ /** @description Internal server error */
604
+ 500: {
605
+ headers: {
606
+ [name: string]: unknown;
607
+ };
608
+ content: {
609
+ "application/json": components["schemas"]["ErrorEnvelope"];
610
+ };
611
+ };
492
612
  };
493
613
  };
494
614
  put?: never;
@@ -1044,6 +1164,24 @@ export interface paths {
1044
1164
  "application/json": components["schemas"]["DeviceActivate"];
1045
1165
  };
1046
1166
  };
1167
+ /** @description Bad request — validation failed */
1168
+ 400: {
1169
+ headers: {
1170
+ [name: string]: unknown;
1171
+ };
1172
+ content: {
1173
+ "application/json": components["schemas"]["ErrorEnvelope"];
1174
+ };
1175
+ };
1176
+ /** @description Gone — a single-use resource has already been spent */
1177
+ 410: {
1178
+ headers: {
1179
+ [name: string]: unknown;
1180
+ };
1181
+ content: {
1182
+ "application/json": components["schemas"]["ErrorEnvelope"];
1183
+ };
1184
+ };
1047
1185
  };
1048
1186
  };
1049
1187
  delete?: never;
@@ -1156,7 +1294,7 @@ export interface paths {
1156
1294
  from: string;
1157
1295
  body: string;
1158
1296
  /** @enum {string} */
1159
- channel?: "imessage" | "sms" | "whatsapp";
1297
+ channel?: "imessage" | "sms";
1160
1298
  attachments?: unknown[];
1161
1299
  };
1162
1300
  };
@@ -2623,7 +2761,7 @@ export interface paths {
2623
2761
  get: {
2624
2762
  parameters: {
2625
2763
  query?: {
2626
- billing_tier?: string;
2764
+ billing_tier?: "rental_iphone" | "rental_android" | "byod_imessage" | "byod_android" | "shared_pool";
2627
2765
  status?: string;
2628
2766
  assigned?: boolean | null;
2629
2767
  fulfillment?: "pending" | "fulfilled";
@@ -2665,7 +2803,7 @@ export interface paths {
2665
2803
  query?: {
2666
2804
  page?: number;
2667
2805
  limit?: number;
2668
- billing_tier?: string;
2806
+ billing_tier?: "rental_iphone" | "rental_android" | "byod_imessage" | "byod_android" | "shared_pool";
2669
2807
  };
2670
2808
  header?: never;
2671
2809
  path?: never;
@@ -3080,7 +3218,7 @@ export interface paths {
3080
3218
  };
3081
3219
  requestBody?: never;
3082
3220
  responses: {
3083
- /** @description Per-tier system defaults (5 rows) */
3221
+ /** @description Per-platform system defaults (2 rows: imessage, android) */
3084
3222
  200: {
3085
3223
  headers: {
3086
3224
  [name: string]: unknown;
@@ -3099,7 +3237,7 @@ export interface paths {
3099
3237
  patch?: never;
3100
3238
  trace?: never;
3101
3239
  };
3102
- "/admin/system-defaults/{billing_tier}": {
3240
+ "/admin/system-defaults/{platform}": {
3103
3241
  parameters: {
3104
3242
  query?: never;
3105
3243
  header?: never;
@@ -3117,7 +3255,7 @@ export interface paths {
3117
3255
  query?: never;
3118
3256
  header?: never;
3119
3257
  path: {
3120
- billing_tier: "rental_iphone" | "rental_android" | "byod_imessage" | "byod_android" | "shared_pool";
3258
+ platform: "imessage" | "android";
3121
3259
  };
3122
3260
  cookie?: never;
3123
3261
  };
@@ -3127,7 +3265,7 @@ export interface paths {
3127
3265
  };
3128
3266
  };
3129
3267
  responses: {
3130
- /** @description Updated tier defaults + clamp counts */
3268
+ /** @description Updated platform defaults + clamp counts */
3131
3269
  200: {
3132
3270
  headers: {
3133
3271
  [name: string]: unknown;
@@ -3957,6 +4095,10 @@ export interface paths {
3957
4095
  path?: never;
3958
4096
  cookie?: never;
3959
4097
  };
4098
+ /**
4099
+ * List API keys
4100
+ * @description Return every non-revoked API key for the authenticated user. Includes the key prefix, scope, line allowlist, and last-used timestamp — never the plaintext (which is only emitted once at create time).
4101
+ */
3960
4102
  get: {
3961
4103
  parameters: {
3962
4104
  query?: never;
@@ -3975,9 +4117,49 @@ export interface paths {
3975
4117
  "application/json": components["schemas"]["ApiKeyList"];
3976
4118
  };
3977
4119
  };
4120
+ /** @description Bad request — validation failed */
4121
+ 400: {
4122
+ headers: {
4123
+ [name: string]: unknown;
4124
+ };
4125
+ content: {
4126
+ "application/json": components["schemas"]["ErrorEnvelope"];
4127
+ };
4128
+ };
4129
+ /** @description Unauthenticated — missing or invalid bearer token */
4130
+ 401: {
4131
+ headers: {
4132
+ [name: string]: unknown;
4133
+ };
4134
+ content: {
4135
+ "application/json": components["schemas"]["ErrorEnvelope"];
4136
+ };
4137
+ };
4138
+ /** @description Too many requests — rate limit exceeded */
4139
+ 429: {
4140
+ headers: {
4141
+ [name: string]: unknown;
4142
+ };
4143
+ content: {
4144
+ "application/json": components["schemas"]["ErrorEnvelope"];
4145
+ };
4146
+ };
4147
+ /** @description Internal server error */
4148
+ 500: {
4149
+ headers: {
4150
+ [name: string]: unknown;
4151
+ };
4152
+ content: {
4153
+ "application/json": components["schemas"]["ErrorEnvelope"];
4154
+ };
4155
+ };
3978
4156
  };
3979
4157
  };
3980
4158
  put?: never;
4159
+ /**
4160
+ * Create an API key
4161
+ * @description Mint a new API key for the authenticated user. The plaintext key is returned ONCE in this response — store it; the server only keeps a hash. Optional `line_ids` array scopes the key to specific lines; omit or pass `[]` for account-wide access.
4162
+ */
3981
4163
  post: {
3982
4164
  parameters: {
3983
4165
  query?: never;
@@ -4008,6 +4190,42 @@ export interface paths {
4008
4190
  "application/json": components["schemas"]["ApiKeyCreate"];
4009
4191
  };
4010
4192
  };
4193
+ /** @description Bad request — validation failed */
4194
+ 400: {
4195
+ headers: {
4196
+ [name: string]: unknown;
4197
+ };
4198
+ content: {
4199
+ "application/json": components["schemas"]["ErrorEnvelope"];
4200
+ };
4201
+ };
4202
+ /** @description Unauthenticated — missing or invalid bearer token */
4203
+ 401: {
4204
+ headers: {
4205
+ [name: string]: unknown;
4206
+ };
4207
+ content: {
4208
+ "application/json": components["schemas"]["ErrorEnvelope"];
4209
+ };
4210
+ };
4211
+ /** @description Too many requests — rate limit exceeded */
4212
+ 429: {
4213
+ headers: {
4214
+ [name: string]: unknown;
4215
+ };
4216
+ content: {
4217
+ "application/json": components["schemas"]["ErrorEnvelope"];
4218
+ };
4219
+ };
4220
+ /** @description Internal server error */
4221
+ 500: {
4222
+ headers: {
4223
+ [name: string]: unknown;
4224
+ };
4225
+ content: {
4226
+ "application/json": components["schemas"]["ErrorEnvelope"];
4227
+ };
4228
+ };
4011
4229
  };
4012
4230
  };
4013
4231
  delete?: never;
@@ -4026,6 +4244,10 @@ export interface paths {
4026
4244
  get?: never;
4027
4245
  put?: never;
4028
4246
  post?: never;
4247
+ /**
4248
+ * Revoke an API key
4249
+ * @description Mark the API key as revoked. Subsequent requests presenting this key receive 401. Revocation is irreversible — issue a fresh key via `POST /v1/api-keys` to regain access.
4250
+ */
4029
4251
  delete: {
4030
4252
  parameters: {
4031
4253
  query?: never;
@@ -4046,6 +4268,60 @@ export interface paths {
4046
4268
  "application/json": components["schemas"]["ApiKeyRevoke"];
4047
4269
  };
4048
4270
  };
4271
+ /** @description Bad request — validation failed */
4272
+ 400: {
4273
+ headers: {
4274
+ [name: string]: unknown;
4275
+ };
4276
+ content: {
4277
+ "application/json": components["schemas"]["ErrorEnvelope"];
4278
+ };
4279
+ };
4280
+ /** @description Unauthenticated — missing or invalid bearer token */
4281
+ 401: {
4282
+ headers: {
4283
+ [name: string]: unknown;
4284
+ };
4285
+ content: {
4286
+ "application/json": components["schemas"]["ErrorEnvelope"];
4287
+ };
4288
+ };
4289
+ /** @description Forbidden — caller authenticated but not allowed */
4290
+ 403: {
4291
+ headers: {
4292
+ [name: string]: unknown;
4293
+ };
4294
+ content: {
4295
+ "application/json": components["schemas"]["ErrorEnvelope"];
4296
+ };
4297
+ };
4298
+ /** @description Not found */
4299
+ 404: {
4300
+ headers: {
4301
+ [name: string]: unknown;
4302
+ };
4303
+ content: {
4304
+ "application/json": components["schemas"]["ErrorEnvelope"];
4305
+ };
4306
+ };
4307
+ /** @description Too many requests — rate limit exceeded */
4308
+ 429: {
4309
+ headers: {
4310
+ [name: string]: unknown;
4311
+ };
4312
+ content: {
4313
+ "application/json": components["schemas"]["ErrorEnvelope"];
4314
+ };
4315
+ };
4316
+ /** @description Internal server error */
4317
+ 500: {
4318
+ headers: {
4319
+ [name: string]: unknown;
4320
+ };
4321
+ content: {
4322
+ "application/json": components["schemas"]["ErrorEnvelope"];
4323
+ };
4324
+ };
4049
4325
  };
4050
4326
  };
4051
4327
  options?: never;
@@ -4060,12 +4336,16 @@ export interface paths {
4060
4336
  path?: never;
4061
4337
  cookie?: never;
4062
4338
  };
4339
+ /**
4340
+ * List available lines (public marketplace)
4341
+ * @description Browse the marketplace inventory of unassigned lines. Filter by billing tier, area code, country code, status. Returns only `status: available` and never the iSnap-internal `shared_pool` tier. Unauthenticated — partners use this in prospecting / quote flows.
4342
+ */
4063
4343
  get: {
4064
4344
  parameters: {
4065
4345
  query?: {
4066
4346
  billing_tier?: "rental_iphone" | "rental_android" | "byod_imessage" | "byod_android" | "shared_pool";
4067
4347
  area_code?: string;
4068
- region?: string;
4348
+ country_code?: string;
4069
4349
  status?: string;
4070
4350
  page?: number;
4071
4351
  limit?: number;
@@ -4085,6 +4365,33 @@ export interface paths {
4085
4365
  "application/json": components["schemas"]["LineList"];
4086
4366
  };
4087
4367
  };
4368
+ /** @description Bad request — validation failed */
4369
+ 400: {
4370
+ headers: {
4371
+ [name: string]: unknown;
4372
+ };
4373
+ content: {
4374
+ "application/json": components["schemas"]["ErrorEnvelope"];
4375
+ };
4376
+ };
4377
+ /** @description Too many requests — rate limit exceeded */
4378
+ 429: {
4379
+ headers: {
4380
+ [name: string]: unknown;
4381
+ };
4382
+ content: {
4383
+ "application/json": components["schemas"]["ErrorEnvelope"];
4384
+ };
4385
+ };
4386
+ /** @description Internal server error */
4387
+ 500: {
4388
+ headers: {
4389
+ [name: string]: unknown;
4390
+ };
4391
+ content: {
4392
+ "application/json": components["schemas"]["ErrorEnvelope"];
4393
+ };
4394
+ };
4088
4395
  };
4089
4396
  };
4090
4397
  put?: never;
@@ -4102,6 +4409,10 @@ export interface paths {
4102
4409
  path?: never;
4103
4410
  cookie?: never;
4104
4411
  };
4412
+ /**
4413
+ * List the caller's own lines
4414
+ * @description Return every line owned by the authenticated user that's in `active` or `reserved` status. Includes a `fulfillment_status` hint for lines whose hardware is still being procured.
4415
+ */
4105
4416
  get: {
4106
4417
  parameters: {
4107
4418
  query?: never;
@@ -4120,6 +4431,42 @@ export interface paths {
4120
4431
  "application/json": components["schemas"]["MyLines"];
4121
4432
  };
4122
4433
  };
4434
+ /** @description Bad request — validation failed */
4435
+ 400: {
4436
+ headers: {
4437
+ [name: string]: unknown;
4438
+ };
4439
+ content: {
4440
+ "application/json": components["schemas"]["ErrorEnvelope"];
4441
+ };
4442
+ };
4443
+ /** @description Unauthenticated — missing or invalid bearer token */
4444
+ 401: {
4445
+ headers: {
4446
+ [name: string]: unknown;
4447
+ };
4448
+ content: {
4449
+ "application/json": components["schemas"]["ErrorEnvelope"];
4450
+ };
4451
+ };
4452
+ /** @description Too many requests — rate limit exceeded */
4453
+ 429: {
4454
+ headers: {
4455
+ [name: string]: unknown;
4456
+ };
4457
+ content: {
4458
+ "application/json": components["schemas"]["ErrorEnvelope"];
4459
+ };
4460
+ };
4461
+ /** @description Internal server error */
4462
+ 500: {
4463
+ headers: {
4464
+ [name: string]: unknown;
4465
+ };
4466
+ content: {
4467
+ "application/json": components["schemas"]["ErrorEnvelope"];
4468
+ };
4469
+ };
4123
4470
  };
4124
4471
  };
4125
4472
  put?: never;
@@ -4137,6 +4484,10 @@ export interface paths {
4137
4484
  path?: never;
4138
4485
  cookie?: never;
4139
4486
  };
4487
+ /**
4488
+ * Get line details (public marketplace)
4489
+ * @description Fetch a single line by its `line_<base62>` id. Available unauthenticated for the marketplace browsing flow; partner-private metadata still requires API key access via `GET /v1/lines/my`.
4490
+ */
4140
4491
  get: {
4141
4492
  parameters: {
4142
4493
  query?: never;
@@ -4157,6 +4508,42 @@ export interface paths {
4157
4508
  "application/json": components["schemas"]["Line"];
4158
4509
  };
4159
4510
  };
4511
+ /** @description Bad request — validation failed */
4512
+ 400: {
4513
+ headers: {
4514
+ [name: string]: unknown;
4515
+ };
4516
+ content: {
4517
+ "application/json": components["schemas"]["ErrorEnvelope"];
4518
+ };
4519
+ };
4520
+ /** @description Not found */
4521
+ 404: {
4522
+ headers: {
4523
+ [name: string]: unknown;
4524
+ };
4525
+ content: {
4526
+ "application/json": components["schemas"]["ErrorEnvelope"];
4527
+ };
4528
+ };
4529
+ /** @description Too many requests — rate limit exceeded */
4530
+ 429: {
4531
+ headers: {
4532
+ [name: string]: unknown;
4533
+ };
4534
+ content: {
4535
+ "application/json": components["schemas"]["ErrorEnvelope"];
4536
+ };
4537
+ };
4538
+ /** @description Internal server error */
4539
+ 500: {
4540
+ headers: {
4541
+ [name: string]: unknown;
4542
+ };
4543
+ content: {
4544
+ "application/json": components["schemas"]["ErrorEnvelope"];
4545
+ };
4546
+ };
4160
4547
  };
4161
4548
  };
4162
4549
  put?: never;
@@ -4164,6 +4551,10 @@ export interface paths {
4164
4551
  delete?: never;
4165
4552
  options?: never;
4166
4553
  head?: never;
4554
+ /**
4555
+ * Update line metadata
4556
+ * @description Merge-patch the line's free-form `metadata` tag object. Pass `null` for a key to delete it; pass a new value to overwrite. Metadata is echoed on every `line.*` webhook so partners can attribute events back to their own customer IDs.
4557
+ */
4167
4558
  patch: {
4168
4559
  parameters: {
4169
4560
  query?: never;
@@ -4188,12 +4579,66 @@ export interface paths {
4188
4579
  "application/json": components["schemas"]["Line"];
4189
4580
  };
4190
4581
  };
4191
- };
4192
- };
4193
- trace?: never;
4194
- };
4195
- "/v1/lines/assign": {
4196
- parameters: {
4582
+ /** @description Bad request — validation failed */
4583
+ 400: {
4584
+ headers: {
4585
+ [name: string]: unknown;
4586
+ };
4587
+ content: {
4588
+ "application/json": components["schemas"]["ErrorEnvelope"];
4589
+ };
4590
+ };
4591
+ /** @description Unauthenticated — missing or invalid bearer token */
4592
+ 401: {
4593
+ headers: {
4594
+ [name: string]: unknown;
4595
+ };
4596
+ content: {
4597
+ "application/json": components["schemas"]["ErrorEnvelope"];
4598
+ };
4599
+ };
4600
+ /** @description Forbidden — caller authenticated but not allowed */
4601
+ 403: {
4602
+ headers: {
4603
+ [name: string]: unknown;
4604
+ };
4605
+ content: {
4606
+ "application/json": components["schemas"]["ErrorEnvelope"];
4607
+ };
4608
+ };
4609
+ /** @description Not found */
4610
+ 404: {
4611
+ headers: {
4612
+ [name: string]: unknown;
4613
+ };
4614
+ content: {
4615
+ "application/json": components["schemas"]["ErrorEnvelope"];
4616
+ };
4617
+ };
4618
+ /** @description Too many requests — rate limit exceeded */
4619
+ 429: {
4620
+ headers: {
4621
+ [name: string]: unknown;
4622
+ };
4623
+ content: {
4624
+ "application/json": components["schemas"]["ErrorEnvelope"];
4625
+ };
4626
+ };
4627
+ /** @description Internal server error */
4628
+ 500: {
4629
+ headers: {
4630
+ [name: string]: unknown;
4631
+ };
4632
+ content: {
4633
+ "application/json": components["schemas"]["ErrorEnvelope"];
4634
+ };
4635
+ };
4636
+ };
4637
+ };
4638
+ trace?: never;
4639
+ };
4640
+ "/v1/lines/assign": {
4641
+ parameters: {
4197
4642
  query?: never;
4198
4643
  header?: never;
4199
4644
  path?: never;
@@ -4201,6 +4646,10 @@ export interface paths {
4201
4646
  };
4202
4647
  get?: never;
4203
4648
  put?: never;
4649
+ /**
4650
+ * Atomically reserve + activate a line
4651
+ * @description Find an available line matching `billing_tier` (and optional `area_code`), reserve it, and activate it in a single round-trip. Useful when the partner doesn't care which specific number they get — saves the reserve→checkout→activate dance. Scoped API keys are rejected (cannot assign lines outside their allowlist).
4652
+ */
4204
4653
  post: {
4205
4654
  parameters: {
4206
4655
  query?: never;
@@ -4223,6 +4672,69 @@ export interface paths {
4223
4672
  "application/json": components["schemas"]["Line"];
4224
4673
  };
4225
4674
  };
4675
+ /** @description Bad request — validation failed */
4676
+ 400: {
4677
+ headers: {
4678
+ [name: string]: unknown;
4679
+ };
4680
+ content: {
4681
+ "application/json": components["schemas"]["ErrorEnvelope"];
4682
+ };
4683
+ };
4684
+ /** @description Unauthenticated — missing or invalid bearer token */
4685
+ 401: {
4686
+ headers: {
4687
+ [name: string]: unknown;
4688
+ };
4689
+ content: {
4690
+ "application/json": components["schemas"]["ErrorEnvelope"];
4691
+ };
4692
+ };
4693
+ /** @description Forbidden — caller authenticated but not allowed */
4694
+ 403: {
4695
+ headers: {
4696
+ [name: string]: unknown;
4697
+ };
4698
+ content: {
4699
+ "application/json": components["schemas"]["ErrorEnvelope"];
4700
+ };
4701
+ };
4702
+ /** @description Not found */
4703
+ 404: {
4704
+ headers: {
4705
+ [name: string]: unknown;
4706
+ };
4707
+ content: {
4708
+ "application/json": components["schemas"]["ErrorEnvelope"];
4709
+ };
4710
+ };
4711
+ /** @description Conflict — concurrent or terminal state */
4712
+ 409: {
4713
+ headers: {
4714
+ [name: string]: unknown;
4715
+ };
4716
+ content: {
4717
+ "application/json": components["schemas"]["ErrorEnvelope"];
4718
+ };
4719
+ };
4720
+ /** @description Too many requests — rate limit exceeded */
4721
+ 429: {
4722
+ headers: {
4723
+ [name: string]: unknown;
4724
+ };
4725
+ content: {
4726
+ "application/json": components["schemas"]["ErrorEnvelope"];
4727
+ };
4728
+ };
4729
+ /** @description Internal server error */
4730
+ 500: {
4731
+ headers: {
4732
+ [name: string]: unknown;
4733
+ };
4734
+ content: {
4735
+ "application/json": components["schemas"]["ErrorEnvelope"];
4736
+ };
4737
+ };
4226
4738
  };
4227
4739
  };
4228
4740
  delete?: never;
@@ -4240,6 +4752,10 @@ export interface paths {
4240
4752
  };
4241
4753
  get?: never;
4242
4754
  put?: never;
4755
+ /**
4756
+ * Reserve an available line
4757
+ * @description Move a specific line from `available` to `reserved` for 15 minutes. After that window a background worker auto-releases the reservation. Call `POST /v1/billing/checkout` next to convert the reservation into an active subscription.
4758
+ */
4243
4759
  post: {
4244
4760
  parameters: {
4245
4761
  query?: never;
@@ -4260,6 +4776,69 @@ export interface paths {
4260
4776
  "application/json": components["schemas"]["Line"];
4261
4777
  };
4262
4778
  };
4779
+ /** @description Bad request — validation failed */
4780
+ 400: {
4781
+ headers: {
4782
+ [name: string]: unknown;
4783
+ };
4784
+ content: {
4785
+ "application/json": components["schemas"]["ErrorEnvelope"];
4786
+ };
4787
+ };
4788
+ /** @description Unauthenticated — missing or invalid bearer token */
4789
+ 401: {
4790
+ headers: {
4791
+ [name: string]: unknown;
4792
+ };
4793
+ content: {
4794
+ "application/json": components["schemas"]["ErrorEnvelope"];
4795
+ };
4796
+ };
4797
+ /** @description Forbidden — caller authenticated but not allowed */
4798
+ 403: {
4799
+ headers: {
4800
+ [name: string]: unknown;
4801
+ };
4802
+ content: {
4803
+ "application/json": components["schemas"]["ErrorEnvelope"];
4804
+ };
4805
+ };
4806
+ /** @description Not found */
4807
+ 404: {
4808
+ headers: {
4809
+ [name: string]: unknown;
4810
+ };
4811
+ content: {
4812
+ "application/json": components["schemas"]["ErrorEnvelope"];
4813
+ };
4814
+ };
4815
+ /** @description Conflict — concurrent or terminal state */
4816
+ 409: {
4817
+ headers: {
4818
+ [name: string]: unknown;
4819
+ };
4820
+ content: {
4821
+ "application/json": components["schemas"]["ErrorEnvelope"];
4822
+ };
4823
+ };
4824
+ /** @description Too many requests — rate limit exceeded */
4825
+ 429: {
4826
+ headers: {
4827
+ [name: string]: unknown;
4828
+ };
4829
+ content: {
4830
+ "application/json": components["schemas"]["ErrorEnvelope"];
4831
+ };
4832
+ };
4833
+ /** @description Internal server error */
4834
+ 500: {
4835
+ headers: {
4836
+ [name: string]: unknown;
4837
+ };
4838
+ content: {
4839
+ "application/json": components["schemas"]["ErrorEnvelope"];
4840
+ };
4841
+ };
4263
4842
  };
4264
4843
  };
4265
4844
  delete?: never;
@@ -4277,6 +4856,10 @@ export interface paths {
4277
4856
  };
4278
4857
  get?: never;
4279
4858
  put?: never;
4859
+ /**
4860
+ * Activate a reserved line (test/dev)
4861
+ * @description Move a reserved line to `active` with a mock Stripe subscription id. Test-environment shortcut so partners can drive an end-to-end flow without going through real Stripe checkout. Production activation happens via the Stripe webhook on `checkout.session.completed`.
4862
+ */
4280
4863
  post: {
4281
4864
  parameters: {
4282
4865
  query?: never;
@@ -4297,6 +4880,69 @@ export interface paths {
4297
4880
  "application/json": components["schemas"]["Line"];
4298
4881
  };
4299
4882
  };
4883
+ /** @description Bad request — validation failed */
4884
+ 400: {
4885
+ headers: {
4886
+ [name: string]: unknown;
4887
+ };
4888
+ content: {
4889
+ "application/json": components["schemas"]["ErrorEnvelope"];
4890
+ };
4891
+ };
4892
+ /** @description Unauthenticated — missing or invalid bearer token */
4893
+ 401: {
4894
+ headers: {
4895
+ [name: string]: unknown;
4896
+ };
4897
+ content: {
4898
+ "application/json": components["schemas"]["ErrorEnvelope"];
4899
+ };
4900
+ };
4901
+ /** @description Forbidden — caller authenticated but not allowed */
4902
+ 403: {
4903
+ headers: {
4904
+ [name: string]: unknown;
4905
+ };
4906
+ content: {
4907
+ "application/json": components["schemas"]["ErrorEnvelope"];
4908
+ };
4909
+ };
4910
+ /** @description Not found */
4911
+ 404: {
4912
+ headers: {
4913
+ [name: string]: unknown;
4914
+ };
4915
+ content: {
4916
+ "application/json": components["schemas"]["ErrorEnvelope"];
4917
+ };
4918
+ };
4919
+ /** @description Conflict — concurrent or terminal state */
4920
+ 409: {
4921
+ headers: {
4922
+ [name: string]: unknown;
4923
+ };
4924
+ content: {
4925
+ "application/json": components["schemas"]["ErrorEnvelope"];
4926
+ };
4927
+ };
4928
+ /** @description Too many requests — rate limit exceeded */
4929
+ 429: {
4930
+ headers: {
4931
+ [name: string]: unknown;
4932
+ };
4933
+ content: {
4934
+ "application/json": components["schemas"]["ErrorEnvelope"];
4935
+ };
4936
+ };
4937
+ /** @description Internal server error */
4938
+ 500: {
4939
+ headers: {
4940
+ [name: string]: unknown;
4941
+ };
4942
+ content: {
4943
+ "application/json": components["schemas"]["ErrorEnvelope"];
4944
+ };
4945
+ };
4300
4946
  };
4301
4947
  };
4302
4948
  delete?: never;
@@ -4314,6 +4960,10 @@ export interface paths {
4314
4960
  };
4315
4961
  get?: never;
4316
4962
  put?: never;
4963
+ /**
4964
+ * Transfer a line to another iSnap user
4965
+ * @description Move ownership of a line to a different iSnap user. By default the paired device session stays attached so messaging continues uninterrupted; pass `preserve_device_session: false` to force the new owner to re-pair. See `/concepts/billing` for how the cutover handles the in-flight Stripe subscription.
4966
+ */
4317
4967
  post: {
4318
4968
  parameters: {
4319
4969
  query?: never;
@@ -4338,6 +4988,69 @@ export interface paths {
4338
4988
  "application/json": components["schemas"]["Line"];
4339
4989
  };
4340
4990
  };
4991
+ /** @description Bad request — validation failed */
4992
+ 400: {
4993
+ headers: {
4994
+ [name: string]: unknown;
4995
+ };
4996
+ content: {
4997
+ "application/json": components["schemas"]["ErrorEnvelope"];
4998
+ };
4999
+ };
5000
+ /** @description Unauthenticated — missing or invalid bearer token */
5001
+ 401: {
5002
+ headers: {
5003
+ [name: string]: unknown;
5004
+ };
5005
+ content: {
5006
+ "application/json": components["schemas"]["ErrorEnvelope"];
5007
+ };
5008
+ };
5009
+ /** @description Forbidden — caller authenticated but not allowed */
5010
+ 403: {
5011
+ headers: {
5012
+ [name: string]: unknown;
5013
+ };
5014
+ content: {
5015
+ "application/json": components["schemas"]["ErrorEnvelope"];
5016
+ };
5017
+ };
5018
+ /** @description Not found */
5019
+ 404: {
5020
+ headers: {
5021
+ [name: string]: unknown;
5022
+ };
5023
+ content: {
5024
+ "application/json": components["schemas"]["ErrorEnvelope"];
5025
+ };
5026
+ };
5027
+ /** @description Conflict — concurrent or terminal state */
5028
+ 409: {
5029
+ headers: {
5030
+ [name: string]: unknown;
5031
+ };
5032
+ content: {
5033
+ "application/json": components["schemas"]["ErrorEnvelope"];
5034
+ };
5035
+ };
5036
+ /** @description Too many requests — rate limit exceeded */
5037
+ 429: {
5038
+ headers: {
5039
+ [name: string]: unknown;
5040
+ };
5041
+ content: {
5042
+ "application/json": components["schemas"]["ErrorEnvelope"];
5043
+ };
5044
+ };
5045
+ /** @description Internal server error */
5046
+ 500: {
5047
+ headers: {
5048
+ [name: string]: unknown;
5049
+ };
5050
+ content: {
5051
+ "application/json": components["schemas"]["ErrorEnvelope"];
5052
+ };
5053
+ };
4341
5054
  };
4342
5055
  };
4343
5056
  delete?: never;
@@ -4355,6 +5068,10 @@ export interface paths {
4355
5068
  };
4356
5069
  get?: never;
4357
5070
  put?: never;
5071
+ /**
5072
+ * Release a line back to the marketplace
5073
+ * @description Cancel the line's ownership and return it to `available`. Cancels the underlying Stripe subscription at period end. The caller must own the line. See `/concepts/billing` for the proration rules.
5074
+ */
4358
5075
  post: {
4359
5076
  parameters: {
4360
5077
  query?: never;
@@ -4375,6 +5092,60 @@ export interface paths {
4375
5092
  "application/json": components["schemas"]["Line"];
4376
5093
  };
4377
5094
  };
5095
+ /** @description Bad request — validation failed */
5096
+ 400: {
5097
+ headers: {
5098
+ [name: string]: unknown;
5099
+ };
5100
+ content: {
5101
+ "application/json": components["schemas"]["ErrorEnvelope"];
5102
+ };
5103
+ };
5104
+ /** @description Unauthenticated — missing or invalid bearer token */
5105
+ 401: {
5106
+ headers: {
5107
+ [name: string]: unknown;
5108
+ };
5109
+ content: {
5110
+ "application/json": components["schemas"]["ErrorEnvelope"];
5111
+ };
5112
+ };
5113
+ /** @description Forbidden — caller authenticated but not allowed */
5114
+ 403: {
5115
+ headers: {
5116
+ [name: string]: unknown;
5117
+ };
5118
+ content: {
5119
+ "application/json": components["schemas"]["ErrorEnvelope"];
5120
+ };
5121
+ };
5122
+ /** @description Not found */
5123
+ 404: {
5124
+ headers: {
5125
+ [name: string]: unknown;
5126
+ };
5127
+ content: {
5128
+ "application/json": components["schemas"]["ErrorEnvelope"];
5129
+ };
5130
+ };
5131
+ /** @description Too many requests — rate limit exceeded */
5132
+ 429: {
5133
+ headers: {
5134
+ [name: string]: unknown;
5135
+ };
5136
+ content: {
5137
+ "application/json": components["schemas"]["ErrorEnvelope"];
5138
+ };
5139
+ };
5140
+ /** @description Internal server error */
5141
+ 500: {
5142
+ headers: {
5143
+ [name: string]: unknown;
5144
+ };
5145
+ content: {
5146
+ "application/json": components["schemas"]["ErrorEnvelope"];
5147
+ };
5148
+ };
4378
5149
  };
4379
5150
  };
4380
5151
  delete?: never;
@@ -4390,6 +5161,10 @@ export interface paths {
4390
5161
  path?: never;
4391
5162
  cookie?: never;
4392
5163
  };
5164
+ /**
5165
+ * Get a line's quota snapshot
5166
+ * @description Five-bucket quota snapshot: new-contacts, known-contacts, total daily messages, hourly, and minute counters with their effective limits plus 80%-warning flags. Drives the dashboard usage panel and partner self-service throttle decisions.
5167
+ */
4393
5168
  get: {
4394
5169
  parameters: {
4395
5170
  query?: never;
@@ -4410,16 +5185,70 @@ export interface paths {
4410
5185
  "application/json": components["schemas"]["QuotaEnvelope"];
4411
5186
  };
4412
5187
  };
4413
- };
4414
- };
4415
- put?: never;
4416
- post?: never;
4417
- delete?: never;
4418
- options?: never;
4419
- head?: never;
4420
- patch?: never;
4421
- trace?: never;
4422
- };
5188
+ /** @description Bad request — validation failed */
5189
+ 400: {
5190
+ headers: {
5191
+ [name: string]: unknown;
5192
+ };
5193
+ content: {
5194
+ "application/json": components["schemas"]["ErrorEnvelope"];
5195
+ };
5196
+ };
5197
+ /** @description Unauthenticated — missing or invalid bearer token */
5198
+ 401: {
5199
+ headers: {
5200
+ [name: string]: unknown;
5201
+ };
5202
+ content: {
5203
+ "application/json": components["schemas"]["ErrorEnvelope"];
5204
+ };
5205
+ };
5206
+ /** @description Forbidden — caller authenticated but not allowed */
5207
+ 403: {
5208
+ headers: {
5209
+ [name: string]: unknown;
5210
+ };
5211
+ content: {
5212
+ "application/json": components["schemas"]["ErrorEnvelope"];
5213
+ };
5214
+ };
5215
+ /** @description Not found */
5216
+ 404: {
5217
+ headers: {
5218
+ [name: string]: unknown;
5219
+ };
5220
+ content: {
5221
+ "application/json": components["schemas"]["ErrorEnvelope"];
5222
+ };
5223
+ };
5224
+ /** @description Too many requests — rate limit exceeded */
5225
+ 429: {
5226
+ headers: {
5227
+ [name: string]: unknown;
5228
+ };
5229
+ content: {
5230
+ "application/json": components["schemas"]["ErrorEnvelope"];
5231
+ };
5232
+ };
5233
+ /** @description Internal server error */
5234
+ 500: {
5235
+ headers: {
5236
+ [name: string]: unknown;
5237
+ };
5238
+ content: {
5239
+ "application/json": components["schemas"]["ErrorEnvelope"];
5240
+ };
5241
+ };
5242
+ };
5243
+ };
5244
+ put?: never;
5245
+ post?: never;
5246
+ delete?: never;
5247
+ options?: never;
5248
+ head?: never;
5249
+ patch?: never;
5250
+ trace?: never;
5251
+ };
4423
5252
  "/v1/lines/{id}/queue": {
4424
5253
  parameters: {
4425
5254
  query?: never;
@@ -4427,6 +5256,10 @@ export interface paths {
4427
5256
  path?: never;
4428
5257
  cookie?: never;
4429
5258
  };
5259
+ /**
5260
+ * Inspect a line's queued and scheduled messages
5261
+ * @description Cursor-paginated queue snapshot: per-row `to` / `body` / `status` (`queued` / `scheduled` / `delivered_to_device`) + the schedule reason and the activity-curve hour. Companion to `GET /v1/lines/{id}/quota` for partners debugging delivery delays.
5262
+ */
4430
5263
  get: {
4431
5264
  parameters: {
4432
5265
  query?: {
@@ -4451,6 +5284,60 @@ export interface paths {
4451
5284
  "application/json": components["schemas"]["QueueEnvelope"];
4452
5285
  };
4453
5286
  };
5287
+ /** @description Bad request — validation failed */
5288
+ 400: {
5289
+ headers: {
5290
+ [name: string]: unknown;
5291
+ };
5292
+ content: {
5293
+ "application/json": components["schemas"]["ErrorEnvelope"];
5294
+ };
5295
+ };
5296
+ /** @description Unauthenticated — missing or invalid bearer token */
5297
+ 401: {
5298
+ headers: {
5299
+ [name: string]: unknown;
5300
+ };
5301
+ content: {
5302
+ "application/json": components["schemas"]["ErrorEnvelope"];
5303
+ };
5304
+ };
5305
+ /** @description Forbidden — caller authenticated but not allowed */
5306
+ 403: {
5307
+ headers: {
5308
+ [name: string]: unknown;
5309
+ };
5310
+ content: {
5311
+ "application/json": components["schemas"]["ErrorEnvelope"];
5312
+ };
5313
+ };
5314
+ /** @description Not found */
5315
+ 404: {
5316
+ headers: {
5317
+ [name: string]: unknown;
5318
+ };
5319
+ content: {
5320
+ "application/json": components["schemas"]["ErrorEnvelope"];
5321
+ };
5322
+ };
5323
+ /** @description Too many requests — rate limit exceeded */
5324
+ 429: {
5325
+ headers: {
5326
+ [name: string]: unknown;
5327
+ };
5328
+ content: {
5329
+ "application/json": components["schemas"]["ErrorEnvelope"];
5330
+ };
5331
+ };
5332
+ /** @description Internal server error */
5333
+ 500: {
5334
+ headers: {
5335
+ [name: string]: unknown;
5336
+ };
5337
+ content: {
5338
+ "application/json": components["schemas"]["ErrorEnvelope"];
5339
+ };
5340
+ };
4454
5341
  };
4455
5342
  };
4456
5343
  put?: never;
@@ -4468,6 +5355,10 @@ export interface paths {
4468
5355
  path?: never;
4469
5356
  cookie?: never;
4470
5357
  };
5358
+ /**
5359
+ * Get a BYOD line's health snapshot
5360
+ * @description BYOD-only health rollup: device-session state (`active` / `degraded` / `offline`), last heartbeat timestamp, daily quota headroom, Apple-ID-flagged flag, last-error string, bridge version. Rental tiers receive 403 `rental_health_not_exposed` — they don't own the hardware and surfacing transient state creates support-ticket noise.
5361
+ */
4471
5362
  get: {
4472
5363
  parameters: {
4473
5364
  query?: never;
@@ -4488,6 +5379,60 @@ export interface paths {
4488
5379
  "application/json": components["schemas"]["LineHealthEnvelope"];
4489
5380
  };
4490
5381
  };
5382
+ /** @description Bad request — validation failed */
5383
+ 400: {
5384
+ headers: {
5385
+ [name: string]: unknown;
5386
+ };
5387
+ content: {
5388
+ "application/json": components["schemas"]["ErrorEnvelope"];
5389
+ };
5390
+ };
5391
+ /** @description Unauthenticated — missing or invalid bearer token */
5392
+ 401: {
5393
+ headers: {
5394
+ [name: string]: unknown;
5395
+ };
5396
+ content: {
5397
+ "application/json": components["schemas"]["ErrorEnvelope"];
5398
+ };
5399
+ };
5400
+ /** @description Forbidden — caller authenticated but not allowed */
5401
+ 403: {
5402
+ headers: {
5403
+ [name: string]: unknown;
5404
+ };
5405
+ content: {
5406
+ "application/json": components["schemas"]["ErrorEnvelope"];
5407
+ };
5408
+ };
5409
+ /** @description Not found */
5410
+ 404: {
5411
+ headers: {
5412
+ [name: string]: unknown;
5413
+ };
5414
+ content: {
5415
+ "application/json": components["schemas"]["ErrorEnvelope"];
5416
+ };
5417
+ };
5418
+ /** @description Too many requests — rate limit exceeded */
5419
+ 429: {
5420
+ headers: {
5421
+ [name: string]: unknown;
5422
+ };
5423
+ content: {
5424
+ "application/json": components["schemas"]["ErrorEnvelope"];
5425
+ };
5426
+ };
5427
+ /** @description Internal server error */
5428
+ 500: {
5429
+ headers: {
5430
+ [name: string]: unknown;
5431
+ };
5432
+ content: {
5433
+ "application/json": components["schemas"]["ErrorEnvelope"];
5434
+ };
5435
+ };
4491
5436
  };
4492
5437
  };
4493
5438
  put?: never;
@@ -4505,6 +5450,10 @@ export interface paths {
4505
5450
  path?: never;
4506
5451
  cookie?: never;
4507
5452
  };
5453
+ /**
5454
+ * Get a line's effective send configuration
5455
+ * @description Return the resolved send configuration for this line — tier defaults merged with per-line overrides. Surfaces effective quota caps, timezone, activity-curve target hour, and the `overridden_keys` list so partners can see which fields they've customised.
5456
+ */
4508
5457
  get: {
4509
5458
  parameters: {
4510
5459
  query?: never;
@@ -4525,6 +5474,60 @@ export interface paths {
4525
5474
  "application/json": components["schemas"]["LineConfigEnvelope"];
4526
5475
  };
4527
5476
  };
5477
+ /** @description Bad request — validation failed */
5478
+ 400: {
5479
+ headers: {
5480
+ [name: string]: unknown;
5481
+ };
5482
+ content: {
5483
+ "application/json": components["schemas"]["ErrorEnvelope"];
5484
+ };
5485
+ };
5486
+ /** @description Unauthenticated — missing or invalid bearer token */
5487
+ 401: {
5488
+ headers: {
5489
+ [name: string]: unknown;
5490
+ };
5491
+ content: {
5492
+ "application/json": components["schemas"]["ErrorEnvelope"];
5493
+ };
5494
+ };
5495
+ /** @description Forbidden — caller authenticated but not allowed */
5496
+ 403: {
5497
+ headers: {
5498
+ [name: string]: unknown;
5499
+ };
5500
+ content: {
5501
+ "application/json": components["schemas"]["ErrorEnvelope"];
5502
+ };
5503
+ };
5504
+ /** @description Not found */
5505
+ 404: {
5506
+ headers: {
5507
+ [name: string]: unknown;
5508
+ };
5509
+ content: {
5510
+ "application/json": components["schemas"]["ErrorEnvelope"];
5511
+ };
5512
+ };
5513
+ /** @description Too many requests — rate limit exceeded */
5514
+ 429: {
5515
+ headers: {
5516
+ [name: string]: unknown;
5517
+ };
5518
+ content: {
5519
+ "application/json": components["schemas"]["ErrorEnvelope"];
5520
+ };
5521
+ };
5522
+ /** @description Internal server error */
5523
+ 500: {
5524
+ headers: {
5525
+ [name: string]: unknown;
5526
+ };
5527
+ content: {
5528
+ "application/json": components["schemas"]["ErrorEnvelope"];
5529
+ };
5530
+ };
4528
5531
  };
4529
5532
  };
4530
5533
  put?: never;
@@ -4532,6 +5535,10 @@ export interface paths {
4532
5535
  delete?: never;
4533
5536
  options?: never;
4534
5537
  head?: never;
5538
+ /**
5539
+ * Update a line's send configuration
5540
+ * @description Merge-patch the line's per-line config overrides (quota caps, timezone, activity curve). Pass `null` for a key to revert it to the tier default. Validates the activity curve sums to 1.0 and rejects an unknown timezone with 400.
5541
+ */
4535
5542
  patch: {
4536
5543
  parameters: {
4537
5544
  query?: never;
@@ -4556,6 +5563,60 @@ export interface paths {
4556
5563
  "application/json": components["schemas"]["LineConfigEnvelope"];
4557
5564
  };
4558
5565
  };
5566
+ /** @description Bad request — validation failed */
5567
+ 400: {
5568
+ headers: {
5569
+ [name: string]: unknown;
5570
+ };
5571
+ content: {
5572
+ "application/json": components["schemas"]["ErrorEnvelope"];
5573
+ };
5574
+ };
5575
+ /** @description Unauthenticated — missing or invalid bearer token */
5576
+ 401: {
5577
+ headers: {
5578
+ [name: string]: unknown;
5579
+ };
5580
+ content: {
5581
+ "application/json": components["schemas"]["ErrorEnvelope"];
5582
+ };
5583
+ };
5584
+ /** @description Forbidden — caller authenticated but not allowed */
5585
+ 403: {
5586
+ headers: {
5587
+ [name: string]: unknown;
5588
+ };
5589
+ content: {
5590
+ "application/json": components["schemas"]["ErrorEnvelope"];
5591
+ };
5592
+ };
5593
+ /** @description Not found */
5594
+ 404: {
5595
+ headers: {
5596
+ [name: string]: unknown;
5597
+ };
5598
+ content: {
5599
+ "application/json": components["schemas"]["ErrorEnvelope"];
5600
+ };
5601
+ };
5602
+ /** @description Too many requests — rate limit exceeded */
5603
+ 429: {
5604
+ headers: {
5605
+ [name: string]: unknown;
5606
+ };
5607
+ content: {
5608
+ "application/json": components["schemas"]["ErrorEnvelope"];
5609
+ };
5610
+ };
5611
+ /** @description Internal server error */
5612
+ 500: {
5613
+ headers: {
5614
+ [name: string]: unknown;
5615
+ };
5616
+ content: {
5617
+ "application/json": components["schemas"]["ErrorEnvelope"];
5618
+ };
5619
+ };
4559
5620
  };
4560
5621
  };
4561
5622
  trace?: never;
@@ -4567,6 +5628,10 @@ export interface paths {
4567
5628
  path?: never;
4568
5629
  cookie?: never;
4569
5630
  };
5631
+ /**
5632
+ * List pre-orders
5633
+ * @description Cursor-paginated list of the caller's pre-orders. Filter by status (`pending`, `provisioning`, `ready`, `fulfilled`, `cancelled`, `refunded`) to surface only the ones the dashboard needs.
5634
+ */
4570
5635
  get: {
4571
5636
  parameters: {
4572
5637
  query?: {
@@ -4589,9 +5654,49 @@ export interface paths {
4589
5654
  "application/json": components["schemas"]["PreOrderList"];
4590
5655
  };
4591
5656
  };
5657
+ /** @description Bad request — validation failed */
5658
+ 400: {
5659
+ headers: {
5660
+ [name: string]: unknown;
5661
+ };
5662
+ content: {
5663
+ "application/json": components["schemas"]["ErrorEnvelope"];
5664
+ };
5665
+ };
5666
+ /** @description Unauthenticated — missing or invalid bearer token */
5667
+ 401: {
5668
+ headers: {
5669
+ [name: string]: unknown;
5670
+ };
5671
+ content: {
5672
+ "application/json": components["schemas"]["ErrorEnvelope"];
5673
+ };
5674
+ };
5675
+ /** @description Too many requests — rate limit exceeded */
5676
+ 429: {
5677
+ headers: {
5678
+ [name: string]: unknown;
5679
+ };
5680
+ content: {
5681
+ "application/json": components["schemas"]["ErrorEnvelope"];
5682
+ };
5683
+ };
5684
+ /** @description Internal server error */
5685
+ 500: {
5686
+ headers: {
5687
+ [name: string]: unknown;
5688
+ };
5689
+ content: {
5690
+ "application/json": components["schemas"]["ErrorEnvelope"];
5691
+ };
5692
+ };
4592
5693
  };
4593
5694
  };
4594
5695
  put?: never;
5696
+ /**
5697
+ * Create a pre-order
5698
+ * @description Place a pre-order for a line tier that has no inventory in stock. Returns a `provisioning` pre-order with a Stripe payment intent; ops picks it up to procure hardware, and the partner is notified via the `pre_order.fulfilled` webhook when a matching line is ready.
5699
+ */
4595
5700
  post: {
4596
5701
  parameters: {
4597
5702
  query?: never;
@@ -4606,6 +5711,8 @@ export interface paths {
4606
5711
  billing_tier: "rental_iphone" | "rental_android";
4607
5712
  /** @default [] */
4608
5713
  preferred_area_codes?: string[];
5714
+ /** @default false */
5715
+ inbound_only?: boolean;
4609
5716
  };
4610
5717
  };
4611
5718
  };
@@ -4619,6 +5726,42 @@ export interface paths {
4619
5726
  "application/json": components["schemas"]["PreOrder"];
4620
5727
  };
4621
5728
  };
5729
+ /** @description Bad request — validation failed */
5730
+ 400: {
5731
+ headers: {
5732
+ [name: string]: unknown;
5733
+ };
5734
+ content: {
5735
+ "application/json": components["schemas"]["ErrorEnvelope"];
5736
+ };
5737
+ };
5738
+ /** @description Unauthenticated — missing or invalid bearer token */
5739
+ 401: {
5740
+ headers: {
5741
+ [name: string]: unknown;
5742
+ };
5743
+ content: {
5744
+ "application/json": components["schemas"]["ErrorEnvelope"];
5745
+ };
5746
+ };
5747
+ /** @description Too many requests — rate limit exceeded */
5748
+ 429: {
5749
+ headers: {
5750
+ [name: string]: unknown;
5751
+ };
5752
+ content: {
5753
+ "application/json": components["schemas"]["ErrorEnvelope"];
5754
+ };
5755
+ };
5756
+ /** @description Internal server error */
5757
+ 500: {
5758
+ headers: {
5759
+ [name: string]: unknown;
5760
+ };
5761
+ content: {
5762
+ "application/json": components["schemas"]["ErrorEnvelope"];
5763
+ };
5764
+ };
4622
5765
  };
4623
5766
  };
4624
5767
  delete?: never;
@@ -4634,6 +5777,10 @@ export interface paths {
4634
5777
  path?: never;
4635
5778
  cookie?: never;
4636
5779
  };
5780
+ /**
5781
+ * Get a pre-order
5782
+ * @description Fetch a single pre-order, including its current status, the linked Stripe payment intent, and the fulfilled-line reference if the procurement has completed.
5783
+ */
4637
5784
  get: {
4638
5785
  parameters: {
4639
5786
  query?: never;
@@ -4654,25 +5801,74 @@ export interface paths {
4654
5801
  "application/json": components["schemas"]["PreOrder"];
4655
5802
  };
4656
5803
  };
4657
- };
4658
- };
4659
- put?: never;
4660
- post?: never;
4661
- delete?: never;
4662
- options?: never;
4663
- head?: never;
4664
- patch?: never;
4665
- trace?: never;
4666
- };
4667
- "/v1/pre-orders/{id}/cancel": {
4668
- parameters: {
4669
- query?: never;
4670
- header?: never;
4671
- path?: never;
4672
- cookie?: never;
4673
- };
4674
- get?: never;
5804
+ /** @description Bad request — validation failed */
5805
+ 400: {
5806
+ headers: {
5807
+ [name: string]: unknown;
5808
+ };
5809
+ content: {
5810
+ "application/json": components["schemas"]["ErrorEnvelope"];
5811
+ };
5812
+ };
5813
+ /** @description Unauthenticated — missing or invalid bearer token */
5814
+ 401: {
5815
+ headers: {
5816
+ [name: string]: unknown;
5817
+ };
5818
+ content: {
5819
+ "application/json": components["schemas"]["ErrorEnvelope"];
5820
+ };
5821
+ };
5822
+ /** @description Not found */
5823
+ 404: {
5824
+ headers: {
5825
+ [name: string]: unknown;
5826
+ };
5827
+ content: {
5828
+ "application/json": components["schemas"]["ErrorEnvelope"];
5829
+ };
5830
+ };
5831
+ /** @description Too many requests — rate limit exceeded */
5832
+ 429: {
5833
+ headers: {
5834
+ [name: string]: unknown;
5835
+ };
5836
+ content: {
5837
+ "application/json": components["schemas"]["ErrorEnvelope"];
5838
+ };
5839
+ };
5840
+ /** @description Internal server error */
5841
+ 500: {
5842
+ headers: {
5843
+ [name: string]: unknown;
5844
+ };
5845
+ content: {
5846
+ "application/json": components["schemas"]["ErrorEnvelope"];
5847
+ };
5848
+ };
5849
+ };
5850
+ };
4675
5851
  put?: never;
5852
+ post?: never;
5853
+ delete?: never;
5854
+ options?: never;
5855
+ head?: never;
5856
+ patch?: never;
5857
+ trace?: never;
5858
+ };
5859
+ "/v1/pre-orders/{id}/cancel": {
5860
+ parameters: {
5861
+ query?: never;
5862
+ header?: never;
5863
+ path?: never;
5864
+ cookie?: never;
5865
+ };
5866
+ get?: never;
5867
+ put?: never;
5868
+ /**
5869
+ * Cancel a pre-order
5870
+ * @description Cancel a pre-order before it is fulfilled. Refunds the Stripe payment intent (if charged) and releases the procurement task. No-op on already-cancelled or fulfilled pre-orders.
5871
+ */
4676
5872
  post: {
4677
5873
  parameters: {
4678
5874
  query?: never;
@@ -4693,6 +5889,60 @@ export interface paths {
4693
5889
  "application/json": components["schemas"]["PreOrder"];
4694
5890
  };
4695
5891
  };
5892
+ /** @description Bad request — validation failed */
5893
+ 400: {
5894
+ headers: {
5895
+ [name: string]: unknown;
5896
+ };
5897
+ content: {
5898
+ "application/json": components["schemas"]["ErrorEnvelope"];
5899
+ };
5900
+ };
5901
+ /** @description Unauthenticated — missing or invalid bearer token */
5902
+ 401: {
5903
+ headers: {
5904
+ [name: string]: unknown;
5905
+ };
5906
+ content: {
5907
+ "application/json": components["schemas"]["ErrorEnvelope"];
5908
+ };
5909
+ };
5910
+ /** @description Not found */
5911
+ 404: {
5912
+ headers: {
5913
+ [name: string]: unknown;
5914
+ };
5915
+ content: {
5916
+ "application/json": components["schemas"]["ErrorEnvelope"];
5917
+ };
5918
+ };
5919
+ /** @description Conflict — concurrent or terminal state */
5920
+ 409: {
5921
+ headers: {
5922
+ [name: string]: unknown;
5923
+ };
5924
+ content: {
5925
+ "application/json": components["schemas"]["ErrorEnvelope"];
5926
+ };
5927
+ };
5928
+ /** @description Too many requests — rate limit exceeded */
5929
+ 429: {
5930
+ headers: {
5931
+ [name: string]: unknown;
5932
+ };
5933
+ content: {
5934
+ "application/json": components["schemas"]["ErrorEnvelope"];
5935
+ };
5936
+ };
5937
+ /** @description Internal server error */
5938
+ 500: {
5939
+ headers: {
5940
+ [name: string]: unknown;
5941
+ };
5942
+ content: {
5943
+ "application/json": components["schemas"]["ErrorEnvelope"];
5944
+ };
5945
+ };
4696
5946
  };
4697
5947
  };
4698
5948
  delete?: never;
@@ -4710,6 +5960,10 @@ export interface paths {
4710
5960
  };
4711
5961
  get?: never;
4712
5962
  put?: never;
5963
+ /**
5964
+ * Start a Stripe Checkout for a reserved line
5965
+ * @description Create a Stripe Checkout Session for the line previously reserved by `POST /v1/lines/{id}/reserve`. Returns the hosted checkout URL — redirect the customer there. The webhook handler activates the line once the session completes.
5966
+ */
4713
5967
  post: {
4714
5968
  parameters: {
4715
5969
  query?: never;
@@ -4735,6 +5989,51 @@ export interface paths {
4735
5989
  "application/json": components["schemas"]["Checkout"];
4736
5990
  };
4737
5991
  };
5992
+ /** @description Bad request — validation failed */
5993
+ 400: {
5994
+ headers: {
5995
+ [name: string]: unknown;
5996
+ };
5997
+ content: {
5998
+ "application/json": components["schemas"]["ErrorEnvelope"];
5999
+ };
6000
+ };
6001
+ /** @description Unauthenticated — missing or invalid bearer token */
6002
+ 401: {
6003
+ headers: {
6004
+ [name: string]: unknown;
6005
+ };
6006
+ content: {
6007
+ "application/json": components["schemas"]["ErrorEnvelope"];
6008
+ };
6009
+ };
6010
+ /** @description Not found */
6011
+ 404: {
6012
+ headers: {
6013
+ [name: string]: unknown;
6014
+ };
6015
+ content: {
6016
+ "application/json": components["schemas"]["ErrorEnvelope"];
6017
+ };
6018
+ };
6019
+ /** @description Too many requests — rate limit exceeded */
6020
+ 429: {
6021
+ headers: {
6022
+ [name: string]: unknown;
6023
+ };
6024
+ content: {
6025
+ "application/json": components["schemas"]["ErrorEnvelope"];
6026
+ };
6027
+ };
6028
+ /** @description Internal server error */
6029
+ 500: {
6030
+ headers: {
6031
+ [name: string]: unknown;
6032
+ };
6033
+ content: {
6034
+ "application/json": components["schemas"]["ErrorEnvelope"];
6035
+ };
6036
+ };
4738
6037
  };
4739
6038
  };
4740
6039
  delete?: never;
@@ -4752,6 +6051,10 @@ export interface paths {
4752
6051
  };
4753
6052
  get?: never;
4754
6053
  put?: never;
6054
+ /**
6055
+ * Start a Stripe Checkout for BYOD slots
6056
+ * @description Create a Stripe Checkout Session for the BYOD subscription product (`$15/mo` or `$150/yr` per slot, `device_count` slots). The completed session writes a `byod_subscriptions` row that `POST /v1/byod/pair` reads to enforce slot capacity.
6057
+ */
4755
6058
  post: {
4756
6059
  parameters: {
4757
6060
  query?: never;
@@ -4774,6 +6077,42 @@ export interface paths {
4774
6077
  "application/json": components["schemas"]["ByodCheckoutEnvelope"];
4775
6078
  };
4776
6079
  };
6080
+ /** @description Bad request — validation failed */
6081
+ 400: {
6082
+ headers: {
6083
+ [name: string]: unknown;
6084
+ };
6085
+ content: {
6086
+ "application/json": components["schemas"]["ErrorEnvelope"];
6087
+ };
6088
+ };
6089
+ /** @description Unauthenticated — missing or invalid bearer token */
6090
+ 401: {
6091
+ headers: {
6092
+ [name: string]: unknown;
6093
+ };
6094
+ content: {
6095
+ "application/json": components["schemas"]["ErrorEnvelope"];
6096
+ };
6097
+ };
6098
+ /** @description Too many requests — rate limit exceeded */
6099
+ 429: {
6100
+ headers: {
6101
+ [name: string]: unknown;
6102
+ };
6103
+ content: {
6104
+ "application/json": components["schemas"]["ErrorEnvelope"];
6105
+ };
6106
+ };
6107
+ /** @description Internal server error */
6108
+ 500: {
6109
+ headers: {
6110
+ [name: string]: unknown;
6111
+ };
6112
+ content: {
6113
+ "application/json": components["schemas"]["ErrorEnvelope"];
6114
+ };
6115
+ };
4777
6116
  };
4778
6117
  };
4779
6118
  delete?: never;
@@ -4789,6 +6128,10 @@ export interface paths {
4789
6128
  path?: never;
4790
6129
  cookie?: never;
4791
6130
  };
6131
+ /**
6132
+ * List Stripe subscriptions
6133
+ * @description Return every active Stripe subscription on the authenticated user's customer record — both per-line rental subs and BYOD slot subs. Period boundaries, line link, price ID, and cancellation flag are surfaced verbatim from Stripe.
6134
+ */
4792
6135
  get: {
4793
6136
  parameters: {
4794
6137
  query?: never;
@@ -4804,7 +6147,43 @@ export interface paths {
4804
6147
  [name: string]: unknown;
4805
6148
  };
4806
6149
  content: {
4807
- "application/json": components["schemas"]["SubscriptionList"];
6150
+ "application/json": components["schemas"]["SubscriptionListEnvelope"];
6151
+ };
6152
+ };
6153
+ /** @description Bad request — validation failed */
6154
+ 400: {
6155
+ headers: {
6156
+ [name: string]: unknown;
6157
+ };
6158
+ content: {
6159
+ "application/json": components["schemas"]["ErrorEnvelope"];
6160
+ };
6161
+ };
6162
+ /** @description Unauthenticated — missing or invalid bearer token */
6163
+ 401: {
6164
+ headers: {
6165
+ [name: string]: unknown;
6166
+ };
6167
+ content: {
6168
+ "application/json": components["schemas"]["ErrorEnvelope"];
6169
+ };
6170
+ };
6171
+ /** @description Too many requests — rate limit exceeded */
6172
+ 429: {
6173
+ headers: {
6174
+ [name: string]: unknown;
6175
+ };
6176
+ content: {
6177
+ "application/json": components["schemas"]["ErrorEnvelope"];
6178
+ };
6179
+ };
6180
+ /** @description Internal server error */
6181
+ 500: {
6182
+ headers: {
6183
+ [name: string]: unknown;
6184
+ };
6185
+ content: {
6186
+ "application/json": components["schemas"]["ErrorEnvelope"];
4808
6187
  };
4809
6188
  };
4810
6189
  };
@@ -4824,6 +6203,10 @@ export interface paths {
4824
6203
  path?: never;
4825
6204
  cookie?: never;
4826
6205
  };
6206
+ /**
6207
+ * List Stripe invoices
6208
+ * @description List the authenticated user's Stripe invoices in reverse-chronological order. Each invoice exposes the period boundaries (unix seconds), the integer-cent amounts, the hosted invoice URL, and the PDF link.
6209
+ */
4827
6210
  get: {
4828
6211
  parameters: {
4829
6212
  query?: never;
@@ -4839,7 +6222,43 @@ export interface paths {
4839
6222
  [name: string]: unknown;
4840
6223
  };
4841
6224
  content: {
4842
- "application/json": components["schemas"]["InvoiceList"];
6225
+ "application/json": components["schemas"]["InvoiceListEnvelope"];
6226
+ };
6227
+ };
6228
+ /** @description Bad request — validation failed */
6229
+ 400: {
6230
+ headers: {
6231
+ [name: string]: unknown;
6232
+ };
6233
+ content: {
6234
+ "application/json": components["schemas"]["ErrorEnvelope"];
6235
+ };
6236
+ };
6237
+ /** @description Unauthenticated — missing or invalid bearer token */
6238
+ 401: {
6239
+ headers: {
6240
+ [name: string]: unknown;
6241
+ };
6242
+ content: {
6243
+ "application/json": components["schemas"]["ErrorEnvelope"];
6244
+ };
6245
+ };
6246
+ /** @description Too many requests — rate limit exceeded */
6247
+ 429: {
6248
+ headers: {
6249
+ [name: string]: unknown;
6250
+ };
6251
+ content: {
6252
+ "application/json": components["schemas"]["ErrorEnvelope"];
6253
+ };
6254
+ };
6255
+ /** @description Internal server error */
6256
+ 500: {
6257
+ headers: {
6258
+ [name: string]: unknown;
6259
+ };
6260
+ content: {
6261
+ "application/json": components["schemas"]["ErrorEnvelope"];
4843
6262
  };
4844
6263
  };
4845
6264
  };
@@ -4862,6 +6281,10 @@ export interface paths {
4862
6281
  get?: never;
4863
6282
  put?: never;
4864
6283
  post?: never;
6284
+ /**
6285
+ * Cancel a subscription
6286
+ * @description Schedule the subscription to cancel at the end of the current billing period. The line remains active until the period rolls over; the partner sees the `cancel_at_period_end: true` flag in `GET /v1/billing/subscriptions` until then.
6287
+ */
4865
6288
  delete: {
4866
6289
  parameters: {
4867
6290
  query?: never;
@@ -4882,6 +6305,60 @@ export interface paths {
4882
6305
  "application/json": components["schemas"]["BillingMessage"];
4883
6306
  };
4884
6307
  };
6308
+ /** @description Bad request — validation failed */
6309
+ 400: {
6310
+ headers: {
6311
+ [name: string]: unknown;
6312
+ };
6313
+ content: {
6314
+ "application/json": components["schemas"]["ErrorEnvelope"];
6315
+ };
6316
+ };
6317
+ /** @description Unauthenticated — missing or invalid bearer token */
6318
+ 401: {
6319
+ headers: {
6320
+ [name: string]: unknown;
6321
+ };
6322
+ content: {
6323
+ "application/json": components["schemas"]["ErrorEnvelope"];
6324
+ };
6325
+ };
6326
+ /** @description Not found */
6327
+ 404: {
6328
+ headers: {
6329
+ [name: string]: unknown;
6330
+ };
6331
+ content: {
6332
+ "application/json": components["schemas"]["ErrorEnvelope"];
6333
+ };
6334
+ };
6335
+ /** @description Conflict — concurrent or terminal state */
6336
+ 409: {
6337
+ headers: {
6338
+ [name: string]: unknown;
6339
+ };
6340
+ content: {
6341
+ "application/json": components["schemas"]["ErrorEnvelope"];
6342
+ };
6343
+ };
6344
+ /** @description Too many requests — rate limit exceeded */
6345
+ 429: {
6346
+ headers: {
6347
+ [name: string]: unknown;
6348
+ };
6349
+ content: {
6350
+ "application/json": components["schemas"]["ErrorEnvelope"];
6351
+ };
6352
+ };
6353
+ /** @description Internal server error */
6354
+ 500: {
6355
+ headers: {
6356
+ [name: string]: unknown;
6357
+ };
6358
+ content: {
6359
+ "application/json": components["schemas"]["ErrorEnvelope"];
6360
+ };
6361
+ };
4885
6362
  };
4886
6363
  };
4887
6364
  options?: never;
@@ -4896,6 +6373,10 @@ export interface paths {
4896
6373
  path?: never;
4897
6374
  cookie?: never;
4898
6375
  };
6376
+ /**
6377
+ * List payment methods
6378
+ * @description List the saved payment methods on the authenticated user's Stripe customer. Each entry exposes the brand (`visa`, `mastercard`, etc.), the last four digits, and the default-method flag — never the PAN.
6379
+ */
4899
6380
  get: {
4900
6381
  parameters: {
4901
6382
  query?: never;
@@ -4911,12 +6392,52 @@ export interface paths {
4911
6392
  [name: string]: unknown;
4912
6393
  };
4913
6394
  content: {
4914
- "application/json": components["schemas"]["PaymentMethodList"];
6395
+ "application/json": components["schemas"]["PaymentMethodListEnvelope"];
6396
+ };
6397
+ };
6398
+ /** @description Bad request — validation failed */
6399
+ 400: {
6400
+ headers: {
6401
+ [name: string]: unknown;
6402
+ };
6403
+ content: {
6404
+ "application/json": components["schemas"]["ErrorEnvelope"];
6405
+ };
6406
+ };
6407
+ /** @description Unauthenticated — missing or invalid bearer token */
6408
+ 401: {
6409
+ headers: {
6410
+ [name: string]: unknown;
6411
+ };
6412
+ content: {
6413
+ "application/json": components["schemas"]["ErrorEnvelope"];
6414
+ };
6415
+ };
6416
+ /** @description Too many requests — rate limit exceeded */
6417
+ 429: {
6418
+ headers: {
6419
+ [name: string]: unknown;
6420
+ };
6421
+ content: {
6422
+ "application/json": components["schemas"]["ErrorEnvelope"];
6423
+ };
6424
+ };
6425
+ /** @description Internal server error */
6426
+ 500: {
6427
+ headers: {
6428
+ [name: string]: unknown;
6429
+ };
6430
+ content: {
6431
+ "application/json": components["schemas"]["ErrorEnvelope"];
4915
6432
  };
4916
6433
  };
4917
6434
  };
4918
6435
  };
4919
6436
  put?: never;
6437
+ /**
6438
+ * Start adding a payment method
6439
+ * @description Create a Stripe SetupIntent so the customer can save a new card. The returned `client_secret` feeds directly into Stripe Elements / PaymentSheet on the partner UI; the resulting payment method is attached to the customer record on completion.
6440
+ */
4920
6441
  post: {
4921
6442
  parameters: {
4922
6443
  query?: never;
@@ -4935,16 +6456,52 @@ export interface paths {
4935
6456
  "application/json": components["schemas"]["SetupIntent"];
4936
6457
  };
4937
6458
  };
4938
- };
4939
- };
4940
- delete?: never;
4941
- options?: never;
4942
- head?: never;
4943
- patch?: never;
4944
- trace?: never;
4945
- };
4946
- "/v1/billing/payment-methods/{id}": {
4947
- parameters: {
6459
+ /** @description Bad request — validation failed */
6460
+ 400: {
6461
+ headers: {
6462
+ [name: string]: unknown;
6463
+ };
6464
+ content: {
6465
+ "application/json": components["schemas"]["ErrorEnvelope"];
6466
+ };
6467
+ };
6468
+ /** @description Unauthenticated — missing or invalid bearer token */
6469
+ 401: {
6470
+ headers: {
6471
+ [name: string]: unknown;
6472
+ };
6473
+ content: {
6474
+ "application/json": components["schemas"]["ErrorEnvelope"];
6475
+ };
6476
+ };
6477
+ /** @description Too many requests — rate limit exceeded */
6478
+ 429: {
6479
+ headers: {
6480
+ [name: string]: unknown;
6481
+ };
6482
+ content: {
6483
+ "application/json": components["schemas"]["ErrorEnvelope"];
6484
+ };
6485
+ };
6486
+ /** @description Internal server error */
6487
+ 500: {
6488
+ headers: {
6489
+ [name: string]: unknown;
6490
+ };
6491
+ content: {
6492
+ "application/json": components["schemas"]["ErrorEnvelope"];
6493
+ };
6494
+ };
6495
+ };
6496
+ };
6497
+ delete?: never;
6498
+ options?: never;
6499
+ head?: never;
6500
+ patch?: never;
6501
+ trace?: never;
6502
+ };
6503
+ "/v1/billing/payment-methods/{id}": {
6504
+ parameters: {
4948
6505
  query?: never;
4949
6506
  header?: never;
4950
6507
  path?: never;
@@ -4953,6 +6510,10 @@ export interface paths {
4953
6510
  get?: never;
4954
6511
  put?: never;
4955
6512
  post?: never;
6513
+ /**
6514
+ * Remove a payment method
6515
+ * @description Detach the payment method from the Stripe customer. Active subscriptions paying with this method will retry against the new default; ensure another method is set as default first.
6516
+ */
4956
6517
  delete: {
4957
6518
  parameters: {
4958
6519
  query?: never;
@@ -4973,6 +6534,51 @@ export interface paths {
4973
6534
  "application/json": components["schemas"]["BillingMessage"];
4974
6535
  };
4975
6536
  };
6537
+ /** @description Bad request — validation failed */
6538
+ 400: {
6539
+ headers: {
6540
+ [name: string]: unknown;
6541
+ };
6542
+ content: {
6543
+ "application/json": components["schemas"]["ErrorEnvelope"];
6544
+ };
6545
+ };
6546
+ /** @description Unauthenticated — missing or invalid bearer token */
6547
+ 401: {
6548
+ headers: {
6549
+ [name: string]: unknown;
6550
+ };
6551
+ content: {
6552
+ "application/json": components["schemas"]["ErrorEnvelope"];
6553
+ };
6554
+ };
6555
+ /** @description Not found */
6556
+ 404: {
6557
+ headers: {
6558
+ [name: string]: unknown;
6559
+ };
6560
+ content: {
6561
+ "application/json": components["schemas"]["ErrorEnvelope"];
6562
+ };
6563
+ };
6564
+ /** @description Too many requests — rate limit exceeded */
6565
+ 429: {
6566
+ headers: {
6567
+ [name: string]: unknown;
6568
+ };
6569
+ content: {
6570
+ "application/json": components["schemas"]["ErrorEnvelope"];
6571
+ };
6572
+ };
6573
+ /** @description Internal server error */
6574
+ 500: {
6575
+ headers: {
6576
+ [name: string]: unknown;
6577
+ };
6578
+ content: {
6579
+ "application/json": components["schemas"]["ErrorEnvelope"];
6580
+ };
6581
+ };
4976
6582
  };
4977
6583
  };
4978
6584
  options?: never;
@@ -4989,6 +6595,10 @@ export interface paths {
4989
6595
  };
4990
6596
  get?: never;
4991
6597
  put?: never;
6598
+ /**
6599
+ * Set default payment method
6600
+ * @description Mark the payment method as the default for invoice charges. Future invoices on existing subscriptions automatically draw from this card.
6601
+ */
4992
6602
  post: {
4993
6603
  parameters: {
4994
6604
  query?: never;
@@ -5009,6 +6619,51 @@ export interface paths {
5009
6619
  "application/json": components["schemas"]["BillingMessage"];
5010
6620
  };
5011
6621
  };
6622
+ /** @description Bad request — validation failed */
6623
+ 400: {
6624
+ headers: {
6625
+ [name: string]: unknown;
6626
+ };
6627
+ content: {
6628
+ "application/json": components["schemas"]["ErrorEnvelope"];
6629
+ };
6630
+ };
6631
+ /** @description Unauthenticated — missing or invalid bearer token */
6632
+ 401: {
6633
+ headers: {
6634
+ [name: string]: unknown;
6635
+ };
6636
+ content: {
6637
+ "application/json": components["schemas"]["ErrorEnvelope"];
6638
+ };
6639
+ };
6640
+ /** @description Not found */
6641
+ 404: {
6642
+ headers: {
6643
+ [name: string]: unknown;
6644
+ };
6645
+ content: {
6646
+ "application/json": components["schemas"]["ErrorEnvelope"];
6647
+ };
6648
+ };
6649
+ /** @description Too many requests — rate limit exceeded */
6650
+ 429: {
6651
+ headers: {
6652
+ [name: string]: unknown;
6653
+ };
6654
+ content: {
6655
+ "application/json": components["schemas"]["ErrorEnvelope"];
6656
+ };
6657
+ };
6658
+ /** @description Internal server error */
6659
+ 500: {
6660
+ headers: {
6661
+ [name: string]: unknown;
6662
+ };
6663
+ content: {
6664
+ "application/json": components["schemas"]["ErrorEnvelope"];
6665
+ };
6666
+ };
5012
6667
  };
5013
6668
  };
5014
6669
  delete?: never;
@@ -5024,6 +6679,10 @@ export interface paths {
5024
6679
  path?: never;
5025
6680
  cookie?: never;
5026
6681
  };
6682
+ /**
6683
+ * List messages
6684
+ * @description Cursor-paginated list of messages, newest first. Each item carries the full `MessageV1` shape — partners can write a uniform handler over both `GET /v1/messages` and `GET /v1/messages/{id}`. Filter by `line_id`, `status`, or `direction`; pass an opaque `cursor` from the previous page's `next_cursor` to advance.
6685
+ */
5027
6686
  get: {
5028
6687
  parameters: {
5029
6688
  query?: {
@@ -5048,9 +6707,49 @@ export interface paths {
5048
6707
  "application/json": components["schemas"]["CursoredMessagesEnvelope"];
5049
6708
  };
5050
6709
  };
6710
+ /** @description Bad request — validation failed */
6711
+ 400: {
6712
+ headers: {
6713
+ [name: string]: unknown;
6714
+ };
6715
+ content: {
6716
+ "application/json": components["schemas"]["ErrorEnvelope"];
6717
+ };
6718
+ };
6719
+ /** @description Unauthenticated — missing or invalid bearer token */
6720
+ 401: {
6721
+ headers: {
6722
+ [name: string]: unknown;
6723
+ };
6724
+ content: {
6725
+ "application/json": components["schemas"]["ErrorEnvelope"];
6726
+ };
6727
+ };
6728
+ /** @description Too many requests — rate limit exceeded */
6729
+ 429: {
6730
+ headers: {
6731
+ [name: string]: unknown;
6732
+ };
6733
+ content: {
6734
+ "application/json": components["schemas"]["ErrorEnvelope"];
6735
+ };
6736
+ };
6737
+ /** @description Internal server error */
6738
+ 500: {
6739
+ headers: {
6740
+ [name: string]: unknown;
6741
+ };
6742
+ content: {
6743
+ "application/json": components["schemas"]["ErrorEnvelope"];
6744
+ };
6745
+ };
5051
6746
  };
5052
6747
  };
5053
6748
  put?: never;
6749
+ /**
6750
+ * Send a message
6751
+ * @description Queue an outbound iMessage / SMS / RCS message on the specified line. The device picks the actual transport at delivery time (`channel: "auto"` is the only supported value in v1). Returns `202` with the queued message envelope; the message progresses through `queued → sent → delivered → read` (or `failed`) reflected via webhooks. Quota-deferred sends return `status: "scheduled"` with a future `scheduled_for`.
6752
+ */
5054
6753
  post: {
5055
6754
  parameters: {
5056
6755
  query?: never;
@@ -5068,8 +6767,11 @@ export interface paths {
5068
6767
  * @default auto
5069
6768
  * @enum {string}
5070
6769
  */
5071
- channel?: "auto" | "iMessage" | "SMS" | "RCS";
5072
- /** @default [] */
6770
+ channel?: "auto";
6771
+ /**
6772
+ * @description Ordered list of `att_<base62>` attachment publicIds. Mint each ID via `POST /v1/attachments` and upload the bytes to the returned signed URL before referencing the ID here. Up to 10 attachments per message and 100 MB per attachment. Per-channel total budgets at delivery time: iMessage ~100 MB, RCS ~10 MB, SMS ~1 MB — the device picks the transport at send time and degrades to a lower-cap channel only when iMessage is unavailable.
6773
+ * @default []
6774
+ */
5073
6775
  attachments?: string[];
5074
6776
  effect?: {
5075
6777
  /** @enum {string} */
@@ -5100,6 +6802,78 @@ export interface paths {
5100
6802
  "application/json": components["schemas"]["MessageV1Envelope"];
5101
6803
  };
5102
6804
  };
6805
+ /** @description Bad request — validation failed */
6806
+ 400: {
6807
+ headers: {
6808
+ [name: string]: unknown;
6809
+ };
6810
+ content: {
6811
+ "application/json": components["schemas"]["ErrorEnvelope"];
6812
+ };
6813
+ };
6814
+ /** @description Unauthenticated — missing or invalid bearer token */
6815
+ 401: {
6816
+ headers: {
6817
+ [name: string]: unknown;
6818
+ };
6819
+ content: {
6820
+ "application/json": components["schemas"]["ErrorEnvelope"];
6821
+ };
6822
+ };
6823
+ /** @description Forbidden — caller authenticated but not allowed */
6824
+ 403: {
6825
+ headers: {
6826
+ [name: string]: unknown;
6827
+ };
6828
+ content: {
6829
+ "application/json": components["schemas"]["ErrorEnvelope"];
6830
+ };
6831
+ };
6832
+ /** @description Not found */
6833
+ 404: {
6834
+ headers: {
6835
+ [name: string]: unknown;
6836
+ };
6837
+ content: {
6838
+ "application/json": components["schemas"]["ErrorEnvelope"];
6839
+ };
6840
+ };
6841
+ /** @description Conflict — concurrent or terminal state */
6842
+ 409: {
6843
+ headers: {
6844
+ [name: string]: unknown;
6845
+ };
6846
+ content: {
6847
+ "application/json": components["schemas"]["ErrorEnvelope"];
6848
+ };
6849
+ };
6850
+ /** @description Unprocessable — domain rule violation */
6851
+ 422: {
6852
+ headers: {
6853
+ [name: string]: unknown;
6854
+ };
6855
+ content: {
6856
+ "application/json": components["schemas"]["ErrorEnvelope"];
6857
+ };
6858
+ };
6859
+ /** @description Too many requests — rate limit exceeded */
6860
+ 429: {
6861
+ headers: {
6862
+ [name: string]: unknown;
6863
+ };
6864
+ content: {
6865
+ "application/json": components["schemas"]["ErrorEnvelope"];
6866
+ };
6867
+ };
6868
+ /** @description Internal server error */
6869
+ 500: {
6870
+ headers: {
6871
+ [name: string]: unknown;
6872
+ };
6873
+ content: {
6874
+ "application/json": components["schemas"]["ErrorEnvelope"];
6875
+ };
6876
+ };
5103
6877
  };
5104
6878
  };
5105
6879
  delete?: never;
@@ -5117,6 +6891,10 @@ export interface paths {
5117
6891
  };
5118
6892
  get?: never;
5119
6893
  put?: never;
6894
+ /**
6895
+ * Add or replace a tapback
6896
+ * @description Add an iMessage tapback (love / like / dislike / laugh / emphasize / question) on a prior message you sent. Replace-on-add semantics: posting a different `type` against the same parent updates the existing reaction in place — switching from `like` to `love` is a single POST, no DELETE-then-POST dance. Reactions require iMessage; SMS / RCS parents are rejected with 422.
6897
+ */
5120
6898
  post: {
5121
6899
  parameters: {
5122
6900
  query?: never;
@@ -5132,7 +6910,7 @@ export interface paths {
5132
6910
  };
5133
6911
  };
5134
6912
  responses: {
5135
- /** @description Reaction queued */
6913
+ /** @description Reaction queued (added or replaced) */
5136
6914
  202: {
5137
6915
  headers: {
5138
6916
  [name: string]: unknown;
@@ -5141,45 +6919,75 @@ export interface paths {
5141
6919
  "application/json": components["schemas"]["ReactionEnvelope"];
5142
6920
  };
5143
6921
  };
5144
- };
5145
- };
5146
- delete?: never;
5147
- options?: never;
5148
- head?: never;
5149
- patch?: never;
5150
- trace?: never;
5151
- };
5152
- "/v1/messages/{id}": {
5153
- parameters: {
5154
- query?: never;
5155
- header?: never;
5156
- path?: never;
5157
- cookie?: never;
5158
- };
5159
- get: {
5160
- parameters: {
5161
- query?: never;
5162
- header?: never;
5163
- path: {
5164
- id: string;
6922
+ /** @description Bad request — validation failed */
6923
+ 400: {
6924
+ headers: {
6925
+ [name: string]: unknown;
6926
+ };
6927
+ content: {
6928
+ "application/json": components["schemas"]["ErrorEnvelope"];
6929
+ };
5165
6930
  };
5166
- cookie?: never;
5167
- };
5168
- requestBody?: never;
5169
- responses: {
5170
- /** @description Message */
5171
- 200: {
6931
+ /** @description Unauthenticated — missing or invalid bearer token */
6932
+ 401: {
5172
6933
  headers: {
5173
6934
  [name: string]: unknown;
5174
6935
  };
5175
6936
  content: {
5176
- "application/json": components["schemas"]["MessageV1Envelope"];
6937
+ "application/json": components["schemas"]["ErrorEnvelope"];
6938
+ };
6939
+ };
6940
+ /** @description Forbidden — caller authenticated but not allowed */
6941
+ 403: {
6942
+ headers: {
6943
+ [name: string]: unknown;
6944
+ };
6945
+ content: {
6946
+ "application/json": components["schemas"]["ErrorEnvelope"];
6947
+ };
6948
+ };
6949
+ /** @description Not found */
6950
+ 404: {
6951
+ headers: {
6952
+ [name: string]: unknown;
6953
+ };
6954
+ content: {
6955
+ "application/json": components["schemas"]["ErrorEnvelope"];
6956
+ };
6957
+ };
6958
+ /** @description Unprocessable — domain rule violation */
6959
+ 422: {
6960
+ headers: {
6961
+ [name: string]: unknown;
6962
+ };
6963
+ content: {
6964
+ "application/json": components["schemas"]["ErrorEnvelope"];
6965
+ };
6966
+ };
6967
+ /** @description Too many requests — rate limit exceeded */
6968
+ 429: {
6969
+ headers: {
6970
+ [name: string]: unknown;
6971
+ };
6972
+ content: {
6973
+ "application/json": components["schemas"]["ErrorEnvelope"];
6974
+ };
6975
+ };
6976
+ /** @description Internal server error */
6977
+ 500: {
6978
+ headers: {
6979
+ [name: string]: unknown;
6980
+ };
6981
+ content: {
6982
+ "application/json": components["schemas"]["ErrorEnvelope"];
5177
6983
  };
5178
6984
  };
5179
6985
  };
5180
6986
  };
5181
- put?: never;
5182
- post?: never;
6987
+ /**
6988
+ * Remove a tapback
6989
+ * @description Remove the caller's tapback on a prior message. Idempotent — `removed: false` is a 200, not a 404, so partners can fire-and-forget without first checking whether a reaction was set. The response reports the type that was removed when applicable.
6990
+ */
5183
6991
  delete: {
5184
6992
  parameters: {
5185
6993
  query?: never;
@@ -5191,13 +6999,67 @@ export interface paths {
5191
6999
  };
5192
7000
  requestBody?: never;
5193
7001
  responses: {
5194
- /** @description Message cancelled */
7002
+ /** @description Reaction removed (idempotent — no-op when nothing to remove) */
5195
7003
  200: {
5196
7004
  headers: {
5197
7005
  [name: string]: unknown;
5198
7006
  };
5199
7007
  content: {
5200
- "application/json": components["schemas"]["MessageV1Envelope"];
7008
+ "application/json": components["schemas"]["ReactionRemovalEnvelope"];
7009
+ };
7010
+ };
7011
+ /** @description Bad request — validation failed */
7012
+ 400: {
7013
+ headers: {
7014
+ [name: string]: unknown;
7015
+ };
7016
+ content: {
7017
+ "application/json": components["schemas"]["ErrorEnvelope"];
7018
+ };
7019
+ };
7020
+ /** @description Unauthenticated — missing or invalid bearer token */
7021
+ 401: {
7022
+ headers: {
7023
+ [name: string]: unknown;
7024
+ };
7025
+ content: {
7026
+ "application/json": components["schemas"]["ErrorEnvelope"];
7027
+ };
7028
+ };
7029
+ /** @description Forbidden — caller authenticated but not allowed */
7030
+ 403: {
7031
+ headers: {
7032
+ [name: string]: unknown;
7033
+ };
7034
+ content: {
7035
+ "application/json": components["schemas"]["ErrorEnvelope"];
7036
+ };
7037
+ };
7038
+ /** @description Not found */
7039
+ 404: {
7040
+ headers: {
7041
+ [name: string]: unknown;
7042
+ };
7043
+ content: {
7044
+ "application/json": components["schemas"]["ErrorEnvelope"];
7045
+ };
7046
+ };
7047
+ /** @description Too many requests — rate limit exceeded */
7048
+ 429: {
7049
+ headers: {
7050
+ [name: string]: unknown;
7051
+ };
7052
+ content: {
7053
+ "application/json": components["schemas"]["ErrorEnvelope"];
7054
+ };
7055
+ };
7056
+ /** @description Internal server error */
7057
+ 500: {
7058
+ headers: {
7059
+ [name: string]: unknown;
7060
+ };
7061
+ content: {
7062
+ "application/json": components["schemas"]["ErrorEnvelope"];
5201
7063
  };
5202
7064
  };
5203
7065
  };
@@ -5207,62 +7069,100 @@ export interface paths {
5207
7069
  patch?: never;
5208
7070
  trace?: never;
5209
7071
  };
5210
- "/v1/messages/inbound": {
7072
+ "/v1/messages/{id}": {
5211
7073
  parameters: {
5212
7074
  query?: never;
5213
7075
  header?: never;
5214
7076
  path?: never;
5215
7077
  cookie?: never;
5216
7078
  };
5217
- get?: never;
5218
- put?: never;
5219
- post: {
7079
+ /**
7080
+ * Get a message
7081
+ * @description Retrieve a single message by its `msg_<base62>` publicId. Returns the full message envelope with the current lifecycle status (`queued | scheduled | sent | delivered | read | failed | cancelled | received`). The `queue_info` field is always `null` on GET reads — that snapshot is populated only on the POST response at send time.
7082
+ */
7083
+ get: {
5220
7084
  parameters: {
5221
7085
  query?: never;
5222
7086
  header?: never;
5223
- path?: never;
7087
+ path: {
7088
+ id: string;
7089
+ };
5224
7090
  cookie?: never;
5225
7091
  };
5226
- requestBody?: {
5227
- content: {
5228
- "application/json": {
5229
- line_id: string;
5230
- from: string;
5231
- body: string;
5232
- /** @enum {string} */
5233
- channel: "imessage" | "sms" | "whatsapp";
5234
- secret: string;
7092
+ requestBody?: never;
7093
+ responses: {
7094
+ /** @description Message */
7095
+ 200: {
7096
+ headers: {
7097
+ [name: string]: unknown;
7098
+ };
7099
+ content: {
7100
+ "application/json": components["schemas"]["MessageV1Envelope"];
5235
7101
  };
5236
7102
  };
5237
- };
5238
- responses: {
5239
- /** @description Inbound accepted */
5240
- 201: {
7103
+ /** @description Bad request — validation failed */
7104
+ 400: {
5241
7105
  headers: {
5242
7106
  [name: string]: unknown;
5243
7107
  };
5244
7108
  content: {
5245
- "application/json": components["schemas"]["Message"];
7109
+ "application/json": components["schemas"]["ErrorEnvelope"];
5246
7110
  };
5247
7111
  };
5248
- };
5249
- };
5250
- delete?: never;
5251
- options?: never;
5252
- head?: never;
5253
- patch?: never;
5254
- trace?: never;
5255
- };
5256
- "/v1/messages/{id}/status": {
5257
- parameters: {
5258
- query?: never;
5259
- header?: never;
5260
- path?: never;
5261
- cookie?: never;
7112
+ /** @description Unauthenticated — missing or invalid bearer token */
7113
+ 401: {
7114
+ headers: {
7115
+ [name: string]: unknown;
7116
+ };
7117
+ content: {
7118
+ "application/json": components["schemas"]["ErrorEnvelope"];
7119
+ };
7120
+ };
7121
+ /** @description Forbidden — caller authenticated but not allowed */
7122
+ 403: {
7123
+ headers: {
7124
+ [name: string]: unknown;
7125
+ };
7126
+ content: {
7127
+ "application/json": components["schemas"]["ErrorEnvelope"];
7128
+ };
7129
+ };
7130
+ /** @description Not found */
7131
+ 404: {
7132
+ headers: {
7133
+ [name: string]: unknown;
7134
+ };
7135
+ content: {
7136
+ "application/json": components["schemas"]["ErrorEnvelope"];
7137
+ };
7138
+ };
7139
+ /** @description Too many requests — rate limit exceeded */
7140
+ 429: {
7141
+ headers: {
7142
+ [name: string]: unknown;
7143
+ };
7144
+ content: {
7145
+ "application/json": components["schemas"]["ErrorEnvelope"];
7146
+ };
7147
+ };
7148
+ /** @description Internal server error */
7149
+ 500: {
7150
+ headers: {
7151
+ [name: string]: unknown;
7152
+ };
7153
+ content: {
7154
+ "application/json": components["schemas"]["ErrorEnvelope"];
7155
+ };
7156
+ };
7157
+ };
5262
7158
  };
5263
- get?: never;
5264
7159
  put?: never;
5265
- post: {
7160
+ post?: never;
7161
+ /**
7162
+ * Cancel a queued or scheduled message
7163
+ * @description Cancel a message before it leaves iSnap. Cancellable while the row is still `queued` or `scheduled` (and has not been pushed to a device); returns `409 too_late_to_cancel` once the device has picked it up. Decrements the daily quota when the row had been counted at send time.
7164
+ */
7165
+ delete: {
5266
7166
  parameters: {
5267
7167
  query?: never;
5268
7168
  header?: never;
@@ -5271,30 +7171,82 @@ export interface paths {
5271
7171
  };
5272
7172
  cookie?: never;
5273
7173
  };
5274
- requestBody?: {
5275
- content: {
5276
- "application/json": {
5277
- /** @enum {string} */
5278
- status: "sent" | "delivered" | "read" | "failed";
5279
- error_code?: string;
5280
- error_message?: string;
5281
- secret: string;
5282
- };
5283
- };
5284
- };
7174
+ requestBody?: never;
5285
7175
  responses: {
5286
- /** @description Status updated */
7176
+ /** @description Message cancelled */
5287
7177
  200: {
5288
7178
  headers: {
5289
7179
  [name: string]: unknown;
5290
7180
  };
5291
7181
  content: {
5292
- "application/json": components["schemas"]["StatusUpdate"];
7182
+ "application/json": components["schemas"]["MessageV1Envelope"];
7183
+ };
7184
+ };
7185
+ /** @description Bad request — validation failed */
7186
+ 400: {
7187
+ headers: {
7188
+ [name: string]: unknown;
7189
+ };
7190
+ content: {
7191
+ "application/json": components["schemas"]["ErrorEnvelope"];
7192
+ };
7193
+ };
7194
+ /** @description Unauthenticated — missing or invalid bearer token */
7195
+ 401: {
7196
+ headers: {
7197
+ [name: string]: unknown;
7198
+ };
7199
+ content: {
7200
+ "application/json": components["schemas"]["ErrorEnvelope"];
7201
+ };
7202
+ };
7203
+ /** @description Forbidden — caller authenticated but not allowed */
7204
+ 403: {
7205
+ headers: {
7206
+ [name: string]: unknown;
7207
+ };
7208
+ content: {
7209
+ "application/json": components["schemas"]["ErrorEnvelope"];
7210
+ };
7211
+ };
7212
+ /** @description Not found */
7213
+ 404: {
7214
+ headers: {
7215
+ [name: string]: unknown;
7216
+ };
7217
+ content: {
7218
+ "application/json": components["schemas"]["ErrorEnvelope"];
7219
+ };
7220
+ };
7221
+ /** @description Conflict — concurrent or terminal state */
7222
+ 409: {
7223
+ headers: {
7224
+ [name: string]: unknown;
7225
+ };
7226
+ content: {
7227
+ "application/json": components["schemas"]["ErrorEnvelope"];
7228
+ };
7229
+ };
7230
+ /** @description Too many requests — rate limit exceeded */
7231
+ 429: {
7232
+ headers: {
7233
+ [name: string]: unknown;
7234
+ };
7235
+ content: {
7236
+ "application/json": components["schemas"]["ErrorEnvelope"];
7237
+ };
7238
+ };
7239
+ /** @description Internal server error */
7240
+ 500: {
7241
+ headers: {
7242
+ [name: string]: unknown;
7243
+ };
7244
+ content: {
7245
+ "application/json": components["schemas"]["ErrorEnvelope"];
5293
7246
  };
5294
7247
  };
5295
7248
  };
5296
7249
  };
5297
- delete?: never;
5298
7250
  options?: never;
5299
7251
  head?: never;
5300
7252
  patch?: never;
@@ -5307,6 +7259,10 @@ export interface paths {
5307
7259
  path?: never;
5308
7260
  cookie?: never;
5309
7261
  };
7262
+ /**
7263
+ * List webhook subscriptions
7264
+ * @description Return every webhook subscription owned by the authenticated user. Each entry surfaces the URL, the subscribed event list, the line allowlist, the active flag, the failure counter, and the last success / failure timestamps.
7265
+ */
5310
7266
  get: {
5311
7267
  parameters: {
5312
7268
  query?: never;
@@ -5325,9 +7281,49 @@ export interface paths {
5325
7281
  "application/json": components["schemas"]["WebhookList"];
5326
7282
  };
5327
7283
  };
7284
+ /** @description Bad request — validation failed */
7285
+ 400: {
7286
+ headers: {
7287
+ [name: string]: unknown;
7288
+ };
7289
+ content: {
7290
+ "application/json": components["schemas"]["ErrorEnvelope"];
7291
+ };
7292
+ };
7293
+ /** @description Unauthenticated — missing or invalid bearer token */
7294
+ 401: {
7295
+ headers: {
7296
+ [name: string]: unknown;
7297
+ };
7298
+ content: {
7299
+ "application/json": components["schemas"]["ErrorEnvelope"];
7300
+ };
7301
+ };
7302
+ /** @description Too many requests — rate limit exceeded */
7303
+ 429: {
7304
+ headers: {
7305
+ [name: string]: unknown;
7306
+ };
7307
+ content: {
7308
+ "application/json": components["schemas"]["ErrorEnvelope"];
7309
+ };
7310
+ };
7311
+ /** @description Internal server error */
7312
+ 500: {
7313
+ headers: {
7314
+ [name: string]: unknown;
7315
+ };
7316
+ content: {
7317
+ "application/json": components["schemas"]["ErrorEnvelope"];
7318
+ };
7319
+ };
5328
7320
  };
5329
7321
  };
5330
7322
  put?: never;
7323
+ /**
7324
+ * Register a webhook subscription
7325
+ * @description Subscribe a URL to a list of event types and (optionally) a line allowlist. The server signs deliveries with an HMAC-SHA256 secret returned once here. Retries follow exponential backoff; 10 consecutive failures auto-disable the subscription.
7326
+ */
5331
7327
  post: {
5332
7328
  parameters: {
5333
7329
  query?: never;
@@ -5340,7 +7336,7 @@ export interface paths {
5340
7336
  "application/json": {
5341
7337
  /** Format: uri */
5342
7338
  url: string;
5343
- events: ("message.received" | "message.failed" | "line.disconnected" | "line.activated" | "line.suspended")[];
7339
+ events: components["schemas"]["WebhookEventName"][];
5344
7340
  line_ids?: string[];
5345
7341
  };
5346
7342
  };
@@ -5355,6 +7351,42 @@ export interface paths {
5355
7351
  "application/json": components["schemas"]["Webhook"];
5356
7352
  };
5357
7353
  };
7354
+ /** @description Bad request — validation failed */
7355
+ 400: {
7356
+ headers: {
7357
+ [name: string]: unknown;
7358
+ };
7359
+ content: {
7360
+ "application/json": components["schemas"]["ErrorEnvelope"];
7361
+ };
7362
+ };
7363
+ /** @description Unauthenticated — missing or invalid bearer token */
7364
+ 401: {
7365
+ headers: {
7366
+ [name: string]: unknown;
7367
+ };
7368
+ content: {
7369
+ "application/json": components["schemas"]["ErrorEnvelope"];
7370
+ };
7371
+ };
7372
+ /** @description Too many requests — rate limit exceeded */
7373
+ 429: {
7374
+ headers: {
7375
+ [name: string]: unknown;
7376
+ };
7377
+ content: {
7378
+ "application/json": components["schemas"]["ErrorEnvelope"];
7379
+ };
7380
+ };
7381
+ /** @description Internal server error */
7382
+ 500: {
7383
+ headers: {
7384
+ [name: string]: unknown;
7385
+ };
7386
+ content: {
7387
+ "application/json": components["schemas"]["ErrorEnvelope"];
7388
+ };
7389
+ };
5358
7390
  };
5359
7391
  };
5360
7392
  delete?: never;
@@ -5370,6 +7402,10 @@ export interface paths {
5370
7402
  path?: never;
5371
7403
  cookie?: never;
5372
7404
  };
7405
+ /**
7406
+ * Get a webhook subscription
7407
+ * @description Fetch a single webhook subscription by its `wh_<base62>` id. Returns the URL, the event list, the line allowlist, the active flag, and the metadata — never the secret (rotate via the dedicated endpoint to mint a new one).
7408
+ */
5373
7409
  get: {
5374
7410
  parameters: {
5375
7411
  query?: never;
@@ -5390,10 +7426,59 @@ export interface paths {
5390
7426
  "application/json": components["schemas"]["WebhookV1Envelope"];
5391
7427
  };
5392
7428
  };
7429
+ /** @description Bad request — validation failed */
7430
+ 400: {
7431
+ headers: {
7432
+ [name: string]: unknown;
7433
+ };
7434
+ content: {
7435
+ "application/json": components["schemas"]["ErrorEnvelope"];
7436
+ };
7437
+ };
7438
+ /** @description Unauthenticated — missing or invalid bearer token */
7439
+ 401: {
7440
+ headers: {
7441
+ [name: string]: unknown;
7442
+ };
7443
+ content: {
7444
+ "application/json": components["schemas"]["ErrorEnvelope"];
7445
+ };
7446
+ };
7447
+ /** @description Not found */
7448
+ 404: {
7449
+ headers: {
7450
+ [name: string]: unknown;
7451
+ };
7452
+ content: {
7453
+ "application/json": components["schemas"]["ErrorEnvelope"];
7454
+ };
7455
+ };
7456
+ /** @description Too many requests — rate limit exceeded */
7457
+ 429: {
7458
+ headers: {
7459
+ [name: string]: unknown;
7460
+ };
7461
+ content: {
7462
+ "application/json": components["schemas"]["ErrorEnvelope"];
7463
+ };
7464
+ };
7465
+ /** @description Internal server error */
7466
+ 500: {
7467
+ headers: {
7468
+ [name: string]: unknown;
7469
+ };
7470
+ content: {
7471
+ "application/json": components["schemas"]["ErrorEnvelope"];
7472
+ };
7473
+ };
5393
7474
  };
5394
7475
  };
5395
7476
  put?: never;
5396
7477
  post?: never;
7478
+ /**
7479
+ * Delete a webhook subscription
7480
+ * @description Permanently delete the webhook subscription. In-flight deliveries already enqueued will still attempt — the deletion only stops new event matching.
7481
+ */
5397
7482
  delete: {
5398
7483
  parameters: {
5399
7484
  query?: never;
@@ -5412,10 +7497,59 @@ export interface paths {
5412
7497
  };
5413
7498
  content?: never;
5414
7499
  };
7500
+ /** @description Bad request — validation failed */
7501
+ 400: {
7502
+ headers: {
7503
+ [name: string]: unknown;
7504
+ };
7505
+ content: {
7506
+ "application/json": components["schemas"]["ErrorEnvelope"];
7507
+ };
7508
+ };
7509
+ /** @description Unauthenticated — missing or invalid bearer token */
7510
+ 401: {
7511
+ headers: {
7512
+ [name: string]: unknown;
7513
+ };
7514
+ content: {
7515
+ "application/json": components["schemas"]["ErrorEnvelope"];
7516
+ };
7517
+ };
7518
+ /** @description Not found */
7519
+ 404: {
7520
+ headers: {
7521
+ [name: string]: unknown;
7522
+ };
7523
+ content: {
7524
+ "application/json": components["schemas"]["ErrorEnvelope"];
7525
+ };
7526
+ };
7527
+ /** @description Too many requests — rate limit exceeded */
7528
+ 429: {
7529
+ headers: {
7530
+ [name: string]: unknown;
7531
+ };
7532
+ content: {
7533
+ "application/json": components["schemas"]["ErrorEnvelope"];
7534
+ };
7535
+ };
7536
+ /** @description Internal server error */
7537
+ 500: {
7538
+ headers: {
7539
+ [name: string]: unknown;
7540
+ };
7541
+ content: {
7542
+ "application/json": components["schemas"]["ErrorEnvelope"];
7543
+ };
7544
+ };
5415
7545
  };
5416
7546
  };
5417
7547
  options?: never;
5418
7548
  head?: never;
7549
+ /**
7550
+ * Update a webhook subscription
7551
+ * @description Partial update of a webhook subscription. Any subset of `url`, `events`, `line_ids`, `description`, and `active` is accepted; at least one field is required. Event names are validated against the shared `WebhookEventName` enum so typos reject at 400.
7552
+ */
5419
7553
  patch: {
5420
7554
  parameters: {
5421
7555
  query?: never;
@@ -5430,7 +7564,7 @@ export interface paths {
5430
7564
  "application/json": {
5431
7565
  /** Format: uri */
5432
7566
  url?: string;
5433
- events?: string[];
7567
+ events?: components["schemas"]["WebhookEventName"][];
5434
7568
  line_ids?: string[] | null;
5435
7569
  description?: string | null;
5436
7570
  active?: boolean;
@@ -5447,6 +7581,51 @@ export interface paths {
5447
7581
  "application/json": components["schemas"]["WebhookV1Envelope"];
5448
7582
  };
5449
7583
  };
7584
+ /** @description Bad request — validation failed */
7585
+ 400: {
7586
+ headers: {
7587
+ [name: string]: unknown;
7588
+ };
7589
+ content: {
7590
+ "application/json": components["schemas"]["ErrorEnvelope"];
7591
+ };
7592
+ };
7593
+ /** @description Unauthenticated — missing or invalid bearer token */
7594
+ 401: {
7595
+ headers: {
7596
+ [name: string]: unknown;
7597
+ };
7598
+ content: {
7599
+ "application/json": components["schemas"]["ErrorEnvelope"];
7600
+ };
7601
+ };
7602
+ /** @description Not found */
7603
+ 404: {
7604
+ headers: {
7605
+ [name: string]: unknown;
7606
+ };
7607
+ content: {
7608
+ "application/json": components["schemas"]["ErrorEnvelope"];
7609
+ };
7610
+ };
7611
+ /** @description Too many requests — rate limit exceeded */
7612
+ 429: {
7613
+ headers: {
7614
+ [name: string]: unknown;
7615
+ };
7616
+ content: {
7617
+ "application/json": components["schemas"]["ErrorEnvelope"];
7618
+ };
7619
+ };
7620
+ /** @description Internal server error */
7621
+ 500: {
7622
+ headers: {
7623
+ [name: string]: unknown;
7624
+ };
7625
+ content: {
7626
+ "application/json": components["schemas"]["ErrorEnvelope"];
7627
+ };
7628
+ };
5450
7629
  };
5451
7630
  };
5452
7631
  trace?: never;
@@ -5458,12 +7637,17 @@ export interface paths {
5458
7637
  path?: never;
5459
7638
  cookie?: never;
5460
7639
  };
7640
+ /**
7641
+ * Replay webhook events within the retention window
7642
+ * @description Pull events fired in the last 72h (the retention window) so a partner whose receiver was down can reconcile. Cursor-paginated on `(created_at DESC, event_id DESC)`. Each item is the same `§4.1` envelope the live webhook delivery carried — partners deduplicate by `event_id`.
7643
+ */
5461
7644
  get: {
5462
7645
  parameters: {
5463
7646
  query: {
5464
7647
  since: string;
5465
7648
  until?: string;
5466
- event?: string;
7649
+ /** @description A concrete event type (e.g. `message.received`), a family wildcard (`line.*`), or the catch-all `*`. */
7650
+ event?: components["schemas"]["WebhookEventName"];
5467
7651
  line_id?: string;
5468
7652
  limit?: number;
5469
7653
  cursor?: string;
@@ -5483,6 +7667,42 @@ export interface paths {
5483
7667
  "application/json": components["schemas"]["WebhookEventsEnvelope"];
5484
7668
  };
5485
7669
  };
7670
+ /** @description Bad request — validation failed */
7671
+ 400: {
7672
+ headers: {
7673
+ [name: string]: unknown;
7674
+ };
7675
+ content: {
7676
+ "application/json": components["schemas"]["ErrorEnvelope"];
7677
+ };
7678
+ };
7679
+ /** @description Unauthenticated — missing or invalid bearer token */
7680
+ 401: {
7681
+ headers: {
7682
+ [name: string]: unknown;
7683
+ };
7684
+ content: {
7685
+ "application/json": components["schemas"]["ErrorEnvelope"];
7686
+ };
7687
+ };
7688
+ /** @description Too many requests — rate limit exceeded */
7689
+ 429: {
7690
+ headers: {
7691
+ [name: string]: unknown;
7692
+ };
7693
+ content: {
7694
+ "application/json": components["schemas"]["ErrorEnvelope"];
7695
+ };
7696
+ };
7697
+ /** @description Internal server error */
7698
+ 500: {
7699
+ headers: {
7700
+ [name: string]: unknown;
7701
+ };
7702
+ content: {
7703
+ "application/json": components["schemas"]["ErrorEnvelope"];
7704
+ };
7705
+ };
5486
7706
  };
5487
7707
  };
5488
7708
  put?: never;
@@ -5502,6 +7722,10 @@ export interface paths {
5502
7722
  };
5503
7723
  get?: never;
5504
7724
  put?: never;
7725
+ /**
7726
+ * Rotate the signing secret
7727
+ * @description Generate a new HMAC signing secret. The returned plaintext is shown once — update your verifier promptly. The old secret remains valid for a short grace window (`old_secret_expires_at`) so in-flight deliveries verify against either secret.
7728
+ */
5505
7729
  post: {
5506
7730
  parameters: {
5507
7731
  query?: never;
@@ -5519,7 +7743,52 @@ export interface paths {
5519
7743
  [name: string]: unknown;
5520
7744
  };
5521
7745
  content: {
5522
- "application/json": components["schemas"]["WebhookRotateSecretEnvelope"];
7746
+ "application/json": components["schemas"]["WebhookRotateSecretEnvelope"];
7747
+ };
7748
+ };
7749
+ /** @description Bad request — validation failed */
7750
+ 400: {
7751
+ headers: {
7752
+ [name: string]: unknown;
7753
+ };
7754
+ content: {
7755
+ "application/json": components["schemas"]["ErrorEnvelope"];
7756
+ };
7757
+ };
7758
+ /** @description Unauthenticated — missing or invalid bearer token */
7759
+ 401: {
7760
+ headers: {
7761
+ [name: string]: unknown;
7762
+ };
7763
+ content: {
7764
+ "application/json": components["schemas"]["ErrorEnvelope"];
7765
+ };
7766
+ };
7767
+ /** @description Not found */
7768
+ 404: {
7769
+ headers: {
7770
+ [name: string]: unknown;
7771
+ };
7772
+ content: {
7773
+ "application/json": components["schemas"]["ErrorEnvelope"];
7774
+ };
7775
+ };
7776
+ /** @description Too many requests — rate limit exceeded */
7777
+ 429: {
7778
+ headers: {
7779
+ [name: string]: unknown;
7780
+ };
7781
+ content: {
7782
+ "application/json": components["schemas"]["ErrorEnvelope"];
7783
+ };
7784
+ };
7785
+ /** @description Internal server error */
7786
+ 500: {
7787
+ headers: {
7788
+ [name: string]: unknown;
7789
+ };
7790
+ content: {
7791
+ "application/json": components["schemas"]["ErrorEnvelope"];
5523
7792
  };
5524
7793
  };
5525
7794
  };
@@ -5537,6 +7806,10 @@ export interface paths {
5537
7806
  path?: never;
5538
7807
  cookie?: never;
5539
7808
  };
7809
+ /**
7810
+ * List delivery attempts for a webhook
7811
+ * @description Inspect delivery attempts for a webhook subscription. Cursor-paginated on `(createdAt DESC, id DESC)`; filter by status (`pending` / `success` / `failed`), event type, or time window. Each row carries the request snippet, the response status + body snippet, and the next-retry timestamp.
7812
+ */
5540
7813
  get: {
5541
7814
  parameters: {
5542
7815
  query?: {
@@ -5564,6 +7837,51 @@ export interface paths {
5564
7837
  "application/json": components["schemas"]["WebhookDeliveryListEnvelope"];
5565
7838
  };
5566
7839
  };
7840
+ /** @description Bad request — validation failed */
7841
+ 400: {
7842
+ headers: {
7843
+ [name: string]: unknown;
7844
+ };
7845
+ content: {
7846
+ "application/json": components["schemas"]["ErrorEnvelope"];
7847
+ };
7848
+ };
7849
+ /** @description Unauthenticated — missing or invalid bearer token */
7850
+ 401: {
7851
+ headers: {
7852
+ [name: string]: unknown;
7853
+ };
7854
+ content: {
7855
+ "application/json": components["schemas"]["ErrorEnvelope"];
7856
+ };
7857
+ };
7858
+ /** @description Not found */
7859
+ 404: {
7860
+ headers: {
7861
+ [name: string]: unknown;
7862
+ };
7863
+ content: {
7864
+ "application/json": components["schemas"]["ErrorEnvelope"];
7865
+ };
7866
+ };
7867
+ /** @description Too many requests — rate limit exceeded */
7868
+ 429: {
7869
+ headers: {
7870
+ [name: string]: unknown;
7871
+ };
7872
+ content: {
7873
+ "application/json": components["schemas"]["ErrorEnvelope"];
7874
+ };
7875
+ };
7876
+ /** @description Internal server error */
7877
+ 500: {
7878
+ headers: {
7879
+ [name: string]: unknown;
7880
+ };
7881
+ content: {
7882
+ "application/json": components["schemas"]["ErrorEnvelope"];
7883
+ };
7884
+ };
5567
7885
  };
5568
7886
  };
5569
7887
  put?: never;
@@ -5583,6 +7901,10 @@ export interface paths {
5583
7901
  };
5584
7902
  get?: never;
5585
7903
  put?: never;
7904
+ /**
7905
+ * Replay a delivery attempt
7906
+ * @description Re-enqueue a prior delivery attempt. Mints a new `whd_` delivery row referencing the original via `replay_of` but keeps the same `event_id` so partner-side dedup collapses both into the same logical event.
7907
+ */
5586
7908
  post: {
5587
7909
  parameters: {
5588
7910
  query?: never;
@@ -5604,6 +7926,51 @@ export interface paths {
5604
7926
  "application/json": components["schemas"]["WebhookDeliveryReplayEnvelope"];
5605
7927
  };
5606
7928
  };
7929
+ /** @description Bad request — validation failed */
7930
+ 400: {
7931
+ headers: {
7932
+ [name: string]: unknown;
7933
+ };
7934
+ content: {
7935
+ "application/json": components["schemas"]["ErrorEnvelope"];
7936
+ };
7937
+ };
7938
+ /** @description Unauthenticated — missing or invalid bearer token */
7939
+ 401: {
7940
+ headers: {
7941
+ [name: string]: unknown;
7942
+ };
7943
+ content: {
7944
+ "application/json": components["schemas"]["ErrorEnvelope"];
7945
+ };
7946
+ };
7947
+ /** @description Not found */
7948
+ 404: {
7949
+ headers: {
7950
+ [name: string]: unknown;
7951
+ };
7952
+ content: {
7953
+ "application/json": components["schemas"]["ErrorEnvelope"];
7954
+ };
7955
+ };
7956
+ /** @description Too many requests — rate limit exceeded */
7957
+ 429: {
7958
+ headers: {
7959
+ [name: string]: unknown;
7960
+ };
7961
+ content: {
7962
+ "application/json": components["schemas"]["ErrorEnvelope"];
7963
+ };
7964
+ };
7965
+ /** @description Internal server error */
7966
+ 500: {
7967
+ headers: {
7968
+ [name: string]: unknown;
7969
+ };
7970
+ content: {
7971
+ "application/json": components["schemas"]["ErrorEnvelope"];
7972
+ };
7973
+ };
5607
7974
  };
5608
7975
  };
5609
7976
  delete?: never;
@@ -5621,6 +7988,10 @@ export interface paths {
5621
7988
  };
5622
7989
  get?: never;
5623
7990
  put?: never;
7991
+ /**
7992
+ * Create an attachment + receive a signed upload URL
7993
+ * @description Mint a new attachment record and receive a presigned R2 PUT URL valid for 15 minutes. The client uploads the bytes directly to R2 (the server never proxies them) and then references the returned `id` in the `attachment_ids` array on `POST /v1/messages`. Hard cap: 5 GB (R2 single-PUT ceiling). Attachments larger than 100 MB return a non-blocking `large_attachment_may_delay_delivery` warning.
7994
+ */
5624
7995
  post: {
5625
7996
  parameters: {
5626
7997
  query?: never;
@@ -5643,6 +8014,42 @@ export interface paths {
5643
8014
  "application/json": components["schemas"]["CreateAttachmentResponse"];
5644
8015
  };
5645
8016
  };
8017
+ /** @description Bad request — validation failed */
8018
+ 400: {
8019
+ headers: {
8020
+ [name: string]: unknown;
8021
+ };
8022
+ content: {
8023
+ "application/json": components["schemas"]["ErrorEnvelope"];
8024
+ };
8025
+ };
8026
+ /** @description Unauthenticated — missing or invalid bearer token */
8027
+ 401: {
8028
+ headers: {
8029
+ [name: string]: unknown;
8030
+ };
8031
+ content: {
8032
+ "application/json": components["schemas"]["ErrorEnvelope"];
8033
+ };
8034
+ };
8035
+ /** @description Too many requests — rate limit exceeded */
8036
+ 429: {
8037
+ headers: {
8038
+ [name: string]: unknown;
8039
+ };
8040
+ content: {
8041
+ "application/json": components["schemas"]["ErrorEnvelope"];
8042
+ };
8043
+ };
8044
+ /** @description Internal server error */
8045
+ 500: {
8046
+ headers: {
8047
+ [name: string]: unknown;
8048
+ };
8049
+ content: {
8050
+ "application/json": components["schemas"]["ErrorEnvelope"];
8051
+ };
8052
+ };
5646
8053
  };
5647
8054
  };
5648
8055
  delete?: never;
@@ -5658,6 +8065,10 @@ export interface paths {
5658
8065
  path?: never;
5659
8066
  cookie?: never;
5660
8067
  };
8068
+ /**
8069
+ * Get an attachment + signed download URL
8070
+ * @description Fetch an attachment record by its `att_<base62>` id. The response includes a short-TTL signed R2 download URL — re-call this endpoint to refresh the URL when the previous one expires.
8071
+ */
5661
8072
  get: {
5662
8073
  parameters: {
5663
8074
  query?: never;
@@ -5678,6 +8089,51 @@ export interface paths {
5678
8089
  "application/json": components["schemas"]["Attachment"];
5679
8090
  };
5680
8091
  };
8092
+ /** @description Bad request — validation failed */
8093
+ 400: {
8094
+ headers: {
8095
+ [name: string]: unknown;
8096
+ };
8097
+ content: {
8098
+ "application/json": components["schemas"]["ErrorEnvelope"];
8099
+ };
8100
+ };
8101
+ /** @description Unauthenticated — missing or invalid bearer token */
8102
+ 401: {
8103
+ headers: {
8104
+ [name: string]: unknown;
8105
+ };
8106
+ content: {
8107
+ "application/json": components["schemas"]["ErrorEnvelope"];
8108
+ };
8109
+ };
8110
+ /** @description Not found */
8111
+ 404: {
8112
+ headers: {
8113
+ [name: string]: unknown;
8114
+ };
8115
+ content: {
8116
+ "application/json": components["schemas"]["ErrorEnvelope"];
8117
+ };
8118
+ };
8119
+ /** @description Too many requests — rate limit exceeded */
8120
+ 429: {
8121
+ headers: {
8122
+ [name: string]: unknown;
8123
+ };
8124
+ content: {
8125
+ "application/json": components["schemas"]["ErrorEnvelope"];
8126
+ };
8127
+ };
8128
+ /** @description Internal server error */
8129
+ 500: {
8130
+ headers: {
8131
+ [name: string]: unknown;
8132
+ };
8133
+ content: {
8134
+ "application/json": components["schemas"]["ErrorEnvelope"];
8135
+ };
8136
+ };
5681
8137
  };
5682
8138
  };
5683
8139
  put?: never;
@@ -5697,6 +8153,10 @@ export interface paths {
5697
8153
  };
5698
8154
  get?: never;
5699
8155
  put?: never;
8156
+ /**
8157
+ * Look up a recipient capability
8158
+ * @description Check whether a phone number or email is iMessage-capable. Returns `imessage: true | false | null`; `null` means we have no cached probe result yet and the caller should fall back to SMS-safe behaviour. Rate-limited per line and per account.
8159
+ */
5700
8160
  post: {
5701
8161
  parameters: {
5702
8162
  query?: never;
@@ -5710,7 +8170,7 @@ export interface paths {
5710
8170
  };
5711
8171
  };
5712
8172
  responses: {
5713
- /** @description Lookup result (cached) */
8173
+ /** @description Lookup result */
5714
8174
  200: {
5715
8175
  headers: {
5716
8176
  [name: string]: unknown;
@@ -5719,13 +8179,40 @@ export interface paths {
5719
8179
  "application/json": components["schemas"]["LookupEnvelope"];
5720
8180
  };
5721
8181
  };
5722
- /** @description Lookup pendingretry after the indicated window */
5723
- 202: {
8182
+ /** @description Bad requestvalidation failed */
8183
+ 400: {
5724
8184
  headers: {
5725
8185
  [name: string]: unknown;
5726
8186
  };
5727
8187
  content: {
5728
- "application/json": components["schemas"]["LookupEnvelope"];
8188
+ "application/json": components["schemas"]["ErrorEnvelope"];
8189
+ };
8190
+ };
8191
+ /** @description Unauthenticated — missing or invalid bearer token */
8192
+ 401: {
8193
+ headers: {
8194
+ [name: string]: unknown;
8195
+ };
8196
+ content: {
8197
+ "application/json": components["schemas"]["ErrorEnvelope"];
8198
+ };
8199
+ };
8200
+ /** @description Too many requests — rate limit exceeded */
8201
+ 429: {
8202
+ headers: {
8203
+ [name: string]: unknown;
8204
+ };
8205
+ content: {
8206
+ "application/json": components["schemas"]["ErrorEnvelope"];
8207
+ };
8208
+ };
8209
+ /** @description Internal server error */
8210
+ 500: {
8211
+ headers: {
8212
+ [name: string]: unknown;
8213
+ };
8214
+ content: {
8215
+ "application/json": components["schemas"]["ErrorEnvelope"];
5729
8216
  };
5730
8217
  };
5731
8218
  };
@@ -5778,6 +8265,69 @@ export interface paths {
5778
8265
  "application/json": components["schemas"]["ShareContactCardEnvelope"];
5779
8266
  };
5780
8267
  };
8268
+ /** @description Bad request — validation failed */
8269
+ 400: {
8270
+ headers: {
8271
+ [name: string]: unknown;
8272
+ };
8273
+ content: {
8274
+ "application/json": components["schemas"]["ErrorEnvelope"];
8275
+ };
8276
+ };
8277
+ /** @description Unauthenticated — missing or invalid bearer token */
8278
+ 401: {
8279
+ headers: {
8280
+ [name: string]: unknown;
8281
+ };
8282
+ content: {
8283
+ "application/json": components["schemas"]["ErrorEnvelope"];
8284
+ };
8285
+ };
8286
+ /** @description Forbidden — caller authenticated but not allowed */
8287
+ 403: {
8288
+ headers: {
8289
+ [name: string]: unknown;
8290
+ };
8291
+ content: {
8292
+ "application/json": components["schemas"]["ErrorEnvelope"];
8293
+ };
8294
+ };
8295
+ /** @description Not found */
8296
+ 404: {
8297
+ headers: {
8298
+ [name: string]: unknown;
8299
+ };
8300
+ content: {
8301
+ "application/json": components["schemas"]["ErrorEnvelope"];
8302
+ };
8303
+ };
8304
+ /** @description Unprocessable — domain rule violation */
8305
+ 422: {
8306
+ headers: {
8307
+ [name: string]: unknown;
8308
+ };
8309
+ content: {
8310
+ "application/json": components["schemas"]["ErrorEnvelope"];
8311
+ };
8312
+ };
8313
+ /** @description Too many requests — rate limit exceeded */
8314
+ 429: {
8315
+ headers: {
8316
+ [name: string]: unknown;
8317
+ };
8318
+ content: {
8319
+ "application/json": components["schemas"]["ErrorEnvelope"];
8320
+ };
8321
+ };
8322
+ /** @description Internal server error */
8323
+ 500: {
8324
+ headers: {
8325
+ [name: string]: unknown;
8326
+ };
8327
+ content: {
8328
+ "application/json": components["schemas"]["ErrorEnvelope"];
8329
+ };
8330
+ };
5781
8331
  };
5782
8332
  };
5783
8333
  delete?: never;
@@ -5819,6 +8369,69 @@ export interface paths {
5819
8369
  "application/json": components["schemas"]["ChatTypingStartEnvelope"];
5820
8370
  };
5821
8371
  };
8372
+ /** @description Bad request — validation failed */
8373
+ 400: {
8374
+ headers: {
8375
+ [name: string]: unknown;
8376
+ };
8377
+ content: {
8378
+ "application/json": components["schemas"]["ErrorEnvelope"];
8379
+ };
8380
+ };
8381
+ /** @description Unauthenticated — missing or invalid bearer token */
8382
+ 401: {
8383
+ headers: {
8384
+ [name: string]: unknown;
8385
+ };
8386
+ content: {
8387
+ "application/json": components["schemas"]["ErrorEnvelope"];
8388
+ };
8389
+ };
8390
+ /** @description Forbidden — caller authenticated but not allowed */
8391
+ 403: {
8392
+ headers: {
8393
+ [name: string]: unknown;
8394
+ };
8395
+ content: {
8396
+ "application/json": components["schemas"]["ErrorEnvelope"];
8397
+ };
8398
+ };
8399
+ /** @description Not found */
8400
+ 404: {
8401
+ headers: {
8402
+ [name: string]: unknown;
8403
+ };
8404
+ content: {
8405
+ "application/json": components["schemas"]["ErrorEnvelope"];
8406
+ };
8407
+ };
8408
+ /** @description Unprocessable — domain rule violation */
8409
+ 422: {
8410
+ headers: {
8411
+ [name: string]: unknown;
8412
+ };
8413
+ content: {
8414
+ "application/json": components["schemas"]["ErrorEnvelope"];
8415
+ };
8416
+ };
8417
+ /** @description Too many requests — rate limit exceeded */
8418
+ 429: {
8419
+ headers: {
8420
+ [name: string]: unknown;
8421
+ };
8422
+ content: {
8423
+ "application/json": components["schemas"]["ErrorEnvelope"];
8424
+ };
8425
+ };
8426
+ /** @description Internal server error */
8427
+ 500: {
8428
+ headers: {
8429
+ [name: string]: unknown;
8430
+ };
8431
+ content: {
8432
+ "application/json": components["schemas"]["ErrorEnvelope"];
8433
+ };
8434
+ };
5822
8435
  };
5823
8436
  };
5824
8437
  delete: {
@@ -5838,7 +8451,61 @@ export interface paths {
5838
8451
  [name: string]: unknown;
5839
8452
  };
5840
8453
  content: {
5841
- "application/json": components["schemas"]["ChatTypingStopEnvelope"];
8454
+ "application/json": components["schemas"]["ChatTypingStopEnvelope"];
8455
+ };
8456
+ };
8457
+ /** @description Bad request — validation failed */
8458
+ 400: {
8459
+ headers: {
8460
+ [name: string]: unknown;
8461
+ };
8462
+ content: {
8463
+ "application/json": components["schemas"]["ErrorEnvelope"];
8464
+ };
8465
+ };
8466
+ /** @description Unauthenticated — missing or invalid bearer token */
8467
+ 401: {
8468
+ headers: {
8469
+ [name: string]: unknown;
8470
+ };
8471
+ content: {
8472
+ "application/json": components["schemas"]["ErrorEnvelope"];
8473
+ };
8474
+ };
8475
+ /** @description Forbidden — caller authenticated but not allowed */
8476
+ 403: {
8477
+ headers: {
8478
+ [name: string]: unknown;
8479
+ };
8480
+ content: {
8481
+ "application/json": components["schemas"]["ErrorEnvelope"];
8482
+ };
8483
+ };
8484
+ /** @description Not found */
8485
+ 404: {
8486
+ headers: {
8487
+ [name: string]: unknown;
8488
+ };
8489
+ content: {
8490
+ "application/json": components["schemas"]["ErrorEnvelope"];
8491
+ };
8492
+ };
8493
+ /** @description Too many requests — rate limit exceeded */
8494
+ 429: {
8495
+ headers: {
8496
+ [name: string]: unknown;
8497
+ };
8498
+ content: {
8499
+ "application/json": components["schemas"]["ErrorEnvelope"];
8500
+ };
8501
+ };
8502
+ /** @description Internal server error */
8503
+ 500: {
8504
+ headers: {
8505
+ [name: string]: unknown;
8506
+ };
8507
+ content: {
8508
+ "application/json": components["schemas"]["ErrorEnvelope"];
5842
8509
  };
5843
8510
  };
5844
8511
  };
@@ -5881,6 +8548,60 @@ export interface paths {
5881
8548
  "application/json": components["schemas"]["ChatMarkReadEnvelope"];
5882
8549
  };
5883
8550
  };
8551
+ /** @description Bad request — validation failed */
8552
+ 400: {
8553
+ headers: {
8554
+ [name: string]: unknown;
8555
+ };
8556
+ content: {
8557
+ "application/json": components["schemas"]["ErrorEnvelope"];
8558
+ };
8559
+ };
8560
+ /** @description Unauthenticated — missing or invalid bearer token */
8561
+ 401: {
8562
+ headers: {
8563
+ [name: string]: unknown;
8564
+ };
8565
+ content: {
8566
+ "application/json": components["schemas"]["ErrorEnvelope"];
8567
+ };
8568
+ };
8569
+ /** @description Forbidden — caller authenticated but not allowed */
8570
+ 403: {
8571
+ headers: {
8572
+ [name: string]: unknown;
8573
+ };
8574
+ content: {
8575
+ "application/json": components["schemas"]["ErrorEnvelope"];
8576
+ };
8577
+ };
8578
+ /** @description Not found */
8579
+ 404: {
8580
+ headers: {
8581
+ [name: string]: unknown;
8582
+ };
8583
+ content: {
8584
+ "application/json": components["schemas"]["ErrorEnvelope"];
8585
+ };
8586
+ };
8587
+ /** @description Too many requests — rate limit exceeded */
8588
+ 429: {
8589
+ headers: {
8590
+ [name: string]: unknown;
8591
+ };
8592
+ content: {
8593
+ "application/json": components["schemas"]["ErrorEnvelope"];
8594
+ };
8595
+ };
8596
+ /** @description Internal server error */
8597
+ 500: {
8598
+ headers: {
8599
+ [name: string]: unknown;
8600
+ };
8601
+ content: {
8602
+ "application/json": components["schemas"]["ErrorEnvelope"];
8603
+ };
8604
+ };
5884
8605
  };
5885
8606
  };
5886
8607
  delete?: never;
@@ -5898,6 +8619,10 @@ export interface paths {
5898
8619
  };
5899
8620
  get?: never;
5900
8621
  put?: never;
8622
+ /**
8623
+ * Start a trial session
8624
+ * @description Create a pairing-pending trial session against the caller's API key. Returns a one-time pairing token the partner embeds in their onboarding UI; the recipient claims it by sending an inbound message that links them to a shared-pool line.
8625
+ */
5901
8626
  post: {
5902
8627
  parameters: {
5903
8628
  query?: never;
@@ -5920,6 +8645,42 @@ export interface paths {
5920
8645
  "application/json": components["schemas"]["TrialInitEnvelope"];
5921
8646
  };
5922
8647
  };
8648
+ /** @description Bad request — validation failed */
8649
+ 400: {
8650
+ headers: {
8651
+ [name: string]: unknown;
8652
+ };
8653
+ content: {
8654
+ "application/json": components["schemas"]["ErrorEnvelope"];
8655
+ };
8656
+ };
8657
+ /** @description Unauthenticated — missing or invalid bearer token */
8658
+ 401: {
8659
+ headers: {
8660
+ [name: string]: unknown;
8661
+ };
8662
+ content: {
8663
+ "application/json": components["schemas"]["ErrorEnvelope"];
8664
+ };
8665
+ };
8666
+ /** @description Too many requests — rate limit exceeded */
8667
+ 429: {
8668
+ headers: {
8669
+ [name: string]: unknown;
8670
+ };
8671
+ content: {
8672
+ "application/json": components["schemas"]["ErrorEnvelope"];
8673
+ };
8674
+ };
8675
+ /** @description Internal server error */
8676
+ 500: {
8677
+ headers: {
8678
+ [name: string]: unknown;
8679
+ };
8680
+ content: {
8681
+ "application/json": components["schemas"]["ErrorEnvelope"];
8682
+ };
8683
+ };
5923
8684
  };
5924
8685
  };
5925
8686
  delete?: never;
@@ -5935,6 +8696,10 @@ export interface paths {
5935
8696
  path?: never;
5936
8697
  cookie?: never;
5937
8698
  };
8699
+ /**
8700
+ * Check trial pairing status
8701
+ * @description Token-keyed public lookup. Returns the current trial state — `pairing_pending` while waiting for the recipient's first inbound, `paired` once linked, `expired` after the pairing window. On first poll after `paired` the response also reveals the `trial_api_key` (`isnap_test_*`) for the partner to embed.
8702
+ */
5938
8703
  get: {
5939
8704
  parameters: {
5940
8705
  query: {
@@ -5955,6 +8720,42 @@ export interface paths {
5955
8720
  "application/json": components["schemas"]["TrialStatusEnvelope"];
5956
8721
  };
5957
8722
  };
8723
+ /** @description Bad request — validation failed */
8724
+ 400: {
8725
+ headers: {
8726
+ [name: string]: unknown;
8727
+ };
8728
+ content: {
8729
+ "application/json": components["schemas"]["ErrorEnvelope"];
8730
+ };
8731
+ };
8732
+ /** @description Not found */
8733
+ 404: {
8734
+ headers: {
8735
+ [name: string]: unknown;
8736
+ };
8737
+ content: {
8738
+ "application/json": components["schemas"]["ErrorEnvelope"];
8739
+ };
8740
+ };
8741
+ /** @description Too many requests — rate limit exceeded */
8742
+ 429: {
8743
+ headers: {
8744
+ [name: string]: unknown;
8745
+ };
8746
+ content: {
8747
+ "application/json": components["schemas"]["ErrorEnvelope"];
8748
+ };
8749
+ };
8750
+ /** @description Internal server error */
8751
+ 500: {
8752
+ headers: {
8753
+ [name: string]: unknown;
8754
+ };
8755
+ content: {
8756
+ "application/json": components["schemas"]["ErrorEnvelope"];
8757
+ };
8758
+ };
5958
8759
  };
5959
8760
  };
5960
8761
  put?: never;
@@ -5972,6 +8773,10 @@ export interface paths {
5972
8773
  path?: never;
5973
8774
  cookie?: never;
5974
8775
  };
8776
+ /**
8777
+ * Get trial activity counters
8778
+ * @description Trial-key-only snapshot of the dormancy and outbound-without-inbound counters. Partner dashboards poll this to render the trial's live state ("3/10 sends since last inbound", dormancy timer remaining).
8779
+ */
5975
8780
  get: {
5976
8781
  parameters: {
5977
8782
  query?: never;
@@ -5990,6 +8795,42 @@ export interface paths {
5990
8795
  "application/json": components["schemas"]["TrialActivityEnvelope"];
5991
8796
  };
5992
8797
  };
8798
+ /** @description Bad request — validation failed */
8799
+ 400: {
8800
+ headers: {
8801
+ [name: string]: unknown;
8802
+ };
8803
+ content: {
8804
+ "application/json": components["schemas"]["ErrorEnvelope"];
8805
+ };
8806
+ };
8807
+ /** @description Unauthenticated — missing or invalid bearer token */
8808
+ 401: {
8809
+ headers: {
8810
+ [name: string]: unknown;
8811
+ };
8812
+ content: {
8813
+ "application/json": components["schemas"]["ErrorEnvelope"];
8814
+ };
8815
+ };
8816
+ /** @description Too many requests — rate limit exceeded */
8817
+ 429: {
8818
+ headers: {
8819
+ [name: string]: unknown;
8820
+ };
8821
+ content: {
8822
+ "application/json": components["schemas"]["ErrorEnvelope"];
8823
+ };
8824
+ };
8825
+ /** @description Internal server error */
8826
+ 500: {
8827
+ headers: {
8828
+ [name: string]: unknown;
8829
+ };
8830
+ content: {
8831
+ "application/json": components["schemas"]["ErrorEnvelope"];
8832
+ };
8833
+ };
5993
8834
  };
5994
8835
  };
5995
8836
  put?: never;
@@ -6009,6 +8850,10 @@ export interface paths {
6009
8850
  };
6010
8851
  get?: never;
6011
8852
  put?: never;
8853
+ /**
8854
+ * Start a BYOD pairing flow
8855
+ * @description Mint a one-time activation code plus the stable per-platform bridge-installer download links for a customer-owned Mac+iPhone or Android device. The customer runs the bridge, enters the code, and the device-side `POST /device/activate` consumes it to mint a `byod_imessage` or `byod_android` line — the platform is derived there from what the bridge reports.
8856
+ */
6012
8857
  post: {
6013
8858
  parameters: {
6014
8859
  query?: never;
@@ -6031,6 +8876,51 @@ export interface paths {
6031
8876
  "application/json": components["schemas"]["ByodPairEnvelope"];
6032
8877
  };
6033
8878
  };
8879
+ /** @description Bad request — validation failed */
8880
+ 400: {
8881
+ headers: {
8882
+ [name: string]: unknown;
8883
+ };
8884
+ content: {
8885
+ "application/json": components["schemas"]["ErrorEnvelope"];
8886
+ };
8887
+ };
8888
+ /** @description Unauthenticated — missing or invalid bearer token */
8889
+ 401: {
8890
+ headers: {
8891
+ [name: string]: unknown;
8892
+ };
8893
+ content: {
8894
+ "application/json": components["schemas"]["ErrorEnvelope"];
8895
+ };
8896
+ };
8897
+ /** @description Not found */
8898
+ 404: {
8899
+ headers: {
8900
+ [name: string]: unknown;
8901
+ };
8902
+ content: {
8903
+ "application/json": components["schemas"]["ErrorEnvelope"];
8904
+ };
8905
+ };
8906
+ /** @description Too many requests — rate limit exceeded */
8907
+ 429: {
8908
+ headers: {
8909
+ [name: string]: unknown;
8910
+ };
8911
+ content: {
8912
+ "application/json": components["schemas"]["ErrorEnvelope"];
8913
+ };
8914
+ };
8915
+ /** @description Internal server error */
8916
+ 500: {
8917
+ headers: {
8918
+ [name: string]: unknown;
8919
+ };
8920
+ content: {
8921
+ "application/json": components["schemas"]["ErrorEnvelope"];
8922
+ };
8923
+ };
6034
8924
  };
6035
8925
  };
6036
8926
  delete?: never;
@@ -6289,6 +9179,33 @@ export interface components {
6289
9179
  [key: string]: string;
6290
9180
  };
6291
9181
  };
9182
+ ErrorEnvelope: {
9183
+ /** @enum {boolean} */
9184
+ success: false;
9185
+ data: unknown;
9186
+ error: {
9187
+ status: number;
9188
+ code: string;
9189
+ message: string;
9190
+ retry_after: number | null;
9191
+ issues: {
9192
+ path: (string | number)[];
9193
+ message: string;
9194
+ code: string;
9195
+ }[] | null;
9196
+ };
9197
+ trace_id: string;
9198
+ request_id: string;
9199
+ };
9200
+ VersionResponse: {
9201
+ /** @enum {boolean} */
9202
+ success: true;
9203
+ data: {
9204
+ version: string;
9205
+ };
9206
+ trace_id: string;
9207
+ request_id: string;
9208
+ };
6292
9209
  AuthResponse: {
6293
9210
  user: components["schemas"]["UserResponse"];
6294
9211
  accessToken: string;
@@ -6421,6 +9338,10 @@ export interface components {
6421
9338
  /** Format: uuid */
6422
9339
  sessionId: string;
6423
9340
  apiKey: string;
9341
+ linePublicId: string | null;
9342
+ metadata: {
9343
+ [key: string]: unknown;
9344
+ } | null;
6424
9345
  };
6425
9346
  Heartbeat: {
6426
9347
  ok: boolean;
@@ -6561,7 +9482,6 @@ export interface components {
6561
9482
  lastHeartbeatAt: string | null;
6562
9483
  /** @enum {string} */
6563
9484
  heartbeatHealth: "green" | "yellow" | "red" | "gray";
6564
- dailySendCount: number;
6565
9485
  lastMessageAt: string | null;
6566
9486
  clientName: string | null;
6567
9487
  clientEmail: string | null;
@@ -6667,12 +9587,9 @@ export interface components {
6667
9587
  capabilities?: unknown;
6668
9588
  status: string;
6669
9589
  health?: unknown;
6670
- dailySendCount: number;
6671
9590
  lastHeartbeatAt: string | null;
6672
9591
  activeSessionCount: number;
6673
9592
  /** Format: uuid */
6674
- preOrderId: string | null;
6675
- /** Format: uuid */
6676
9593
  vaId: string | null;
6677
9594
  /** Format: uuid */
6678
9595
  operatorId: string | null;
@@ -6700,7 +9617,6 @@ export interface components {
6700
9617
  capabilities?: unknown;
6701
9618
  status: string;
6702
9619
  health?: unknown;
6703
- dailySendCount: number;
6704
9620
  provisioningData?: unknown;
6705
9621
  createdAt: string;
6706
9622
  updatedAt: string;
@@ -6723,7 +9639,7 @@ export interface components {
6723
9639
  /** Format: uuid */
6724
9640
  id: string;
6725
9641
  phoneNumber: string;
6726
- areaCode: string;
9642
+ areaCode: string | null;
6727
9643
  billingTier: string;
6728
9644
  status: string;
6729
9645
  monthlyPrice: number;
@@ -6758,11 +9674,8 @@ export interface components {
6758
9674
  capabilities?: unknown;
6759
9675
  status: string;
6760
9676
  health?: unknown;
6761
- dailySendCount: number;
6762
9677
  provisioningData?: unknown;
6763
9678
  /** Format: uuid */
6764
- preOrderId: string | null;
6765
- /** Format: uuid */
6766
9679
  vaId: string | null;
6767
9680
  /** Format: uuid */
6768
9681
  operatorId: string | null;
@@ -6787,7 +9700,7 @@ export interface components {
6787
9700
  /** Format: uuid */
6788
9701
  userId: string | null;
6789
9702
  phoneNumber: string;
6790
- areaCode: string;
9703
+ areaCode: string | null;
6791
9704
  billingTier: string;
6792
9705
  capabilities?: unknown;
6793
9706
  status: string;
@@ -6815,7 +9728,7 @@ export interface components {
6815
9728
  /** Format: uuid */
6816
9729
  id: string;
6817
9730
  phone_number: string;
6818
- area_code: string;
9731
+ area_code: string | null;
6819
9732
  billing_tier: string;
6820
9733
  status: string;
6821
9734
  /** Format: uuid */
@@ -6891,7 +9804,7 @@ export interface components {
6891
9804
  };
6892
9805
  SystemDefaultsRow: {
6893
9806
  /** @enum {string} */
6894
- billing_tier: "rental_iphone" | "rental_android" | "byod_imessage" | "byod_android" | "shared_pool";
9807
+ platform: "imessage" | "android";
6895
9808
  daily_new_contact_limit: number;
6896
9809
  daily_known_contact_limit: number;
6897
9810
  daily_total_message_limit: number;
@@ -7024,7 +9937,7 @@ export interface components {
7024
9937
  /** Format: uuid */
7025
9938
  id: string;
7026
9939
  phoneNumber: string;
7027
- areaCode: string;
9940
+ areaCode: string | null;
7028
9941
  carrier: string | null;
7029
9942
  iccid: string | null;
7030
9943
  status: string;
@@ -7138,7 +10051,7 @@ export interface components {
7138
10051
  name: string | null;
7139
10052
  prefix: string;
7140
10053
  scope: string;
7141
- line_ids?: unknown;
10054
+ line_ids: string[];
7142
10055
  rate_limit: number;
7143
10056
  created_at: string;
7144
10057
  last_used_at: string | null;
@@ -7158,9 +10071,14 @@ export interface components {
7158
10071
  Line: {
7159
10072
  id: string;
7160
10073
  phone_number: string;
7161
- area_code: string;
10074
+ area_code: string | null;
10075
+ country_code: string | null;
7162
10076
  /** @enum {string} */
7163
10077
  billing_tier: "rental_iphone" | "rental_android" | "byod_imessage" | "byod_android" | "shared_pool";
10078
+ /** @description True when the customer owns the underlying hardware (BYOD billing tiers). BYOD lines expose the full line-health surface (offline/degraded events, GET /v1/lines/{id}/health). Rental lines (false) only emit durable, actionable events to keep customers out of transient infrastructure noise they cannot act on. */
10079
+ byod: boolean;
10080
+ /** @description True when the line is inbound-only: it may only message a handle that has messaged it first (a recipient who has never contacted the line is rejected with 403 outbound_first_forbidden). Inbound-only is a cheaper rental-tier variant (Bloo parity); always false on BYOD/pool lines. */
10081
+ inbound_only: boolean;
7164
10082
  capabilities?: unknown;
7165
10083
  status: string;
7166
10084
  monthly_price: number;
@@ -7341,16 +10259,19 @@ export interface components {
7341
10259
  /** @enum {string} */
7342
10260
  billing_tier: "rental_iphone" | "rental_android";
7343
10261
  preferred_area_codes: string[];
7344
- status: string;
10262
+ status: components["schemas"]["PreOrderStatus"];
7345
10263
  stripe_payment_intent_id: string | null;
10264
+ stripe_client_secret: string | null;
7346
10265
  amount: number;
7347
10266
  estimated_fulfillment: string | null;
7348
- /** Format: uuid */
7349
- fulfilled_line_id: string | null;
7350
- device_status?: string | null;
10267
+ device_status?: components["schemas"]["DeviceFulfillmentStatus"];
7351
10268
  created_at: string;
7352
10269
  updated_at: string;
7353
10270
  };
10271
+ /** @enum {string} */
10272
+ PreOrderStatus: "pending" | "provisioning" | "ready" | "fulfilled" | "cancelled" | "refunded";
10273
+ /** @enum {string|null} */
10274
+ DeviceFulfillmentStatus: "awaiting_hardware" | "received" | "setup_in_progress" | "ready" | "deployed" | null;
7354
10275
  PreOrderList: {
7355
10276
  /** @enum {boolean} */
7356
10277
  success: true;
@@ -7398,36 +10319,54 @@ export interface components {
7398
10319
  */
7399
10320
  billing_cycle: "monthly" | "annual";
7400
10321
  };
7401
- SubscriptionList: components["schemas"]["Subscription"][];
10322
+ SubscriptionListEnvelope: {
10323
+ /** @enum {boolean} */
10324
+ success: true;
10325
+ data: components["schemas"]["Subscription"][];
10326
+ trace_id: string;
10327
+ request_id: string;
10328
+ };
7402
10329
  Subscription: {
7403
10330
  id: string;
7404
10331
  status: string;
7405
- currentPeriodStart: number;
7406
- currentPeriodEnd: number;
7407
- cancelAtPeriodEnd: boolean;
7408
- lineId: string | null;
7409
- priceId: string | null;
10332
+ current_period_start: number;
10333
+ current_period_end: number;
10334
+ cancel_at_period_end: boolean;
10335
+ line_id: string | null;
10336
+ price_id: string | null;
7410
10337
  amount: number | null;
7411
10338
  currency: string | null;
7412
- createdAt: number;
10339
+ created_at: number;
10340
+ };
10341
+ InvoiceListEnvelope: {
10342
+ /** @enum {boolean} */
10343
+ success: true;
10344
+ data: components["schemas"]["Invoice"][];
10345
+ trace_id: string;
10346
+ request_id: string;
7413
10347
  };
7414
- InvoiceList: components["schemas"]["Invoice"][];
7415
10348
  Invoice: {
7416
10349
  id: string;
7417
10350
  status: string | null;
7418
- amountDue: number;
7419
- amountPaid: number;
10351
+ amount_due: number;
10352
+ amount_paid: number;
7420
10353
  currency: string;
7421
- invoicePdf: string | null;
7422
- hostedInvoiceUrl: string | null;
7423
- periodStart: number;
7424
- periodEnd: number;
7425
- createdAt: number;
10354
+ invoice_pdf: string | null;
10355
+ hosted_invoice_url: string | null;
10356
+ period_start: number;
10357
+ period_end: number;
10358
+ created_at: number;
7426
10359
  };
7427
10360
  BillingMessage: {
7428
10361
  message: string;
7429
10362
  };
7430
- PaymentMethodList: components["schemas"]["PaymentMethod"][];
10363
+ PaymentMethodListEnvelope: {
10364
+ /** @enum {boolean} */
10365
+ success: true;
10366
+ data: components["schemas"]["PaymentMethod"][];
10367
+ trace_id: string;
10368
+ request_id: string;
10369
+ };
7431
10370
  PaymentMethod: {
7432
10371
  id: string;
7433
10372
  brand: string;
@@ -7449,13 +10388,13 @@ export interface components {
7449
10388
  MessageV1: {
7450
10389
  id: string;
7451
10390
  line_id: string;
7452
- direction: string;
10391
+ direction: components["schemas"]["MessageDirection"];
7453
10392
  to: string;
7454
10393
  from: string;
7455
10394
  body: string | null;
7456
- channel: string;
7457
- service: string | null;
7458
- status: string;
10395
+ channel: components["schemas"]["MessageChannel"];
10396
+ service: components["schemas"]["MessageService"];
10397
+ status: components["schemas"]["MessageStatus"];
7459
10398
  effect: {
7460
10399
  /** @enum {string} */
7461
10400
  type: "bubble";
@@ -7473,7 +10412,7 @@ export interface components {
7473
10412
  [key: string]: unknown;
7474
10413
  } | null;
7475
10414
  attachments: string[];
7476
- scheduled_for: string;
10415
+ scheduled_for: string | null;
7477
10416
  schedule_reason: string | null;
7478
10417
  queue_info: {
7479
10418
  queue_position: number;
@@ -7493,13 +10432,21 @@ export interface components {
7493
10432
  jitter_applied_seconds?: number;
7494
10433
  } | null;
7495
10434
  created_at: string;
7496
- queued_at: string;
10435
+ queued_at: string | null;
7497
10436
  sent_at: string | null;
7498
10437
  delivered_at: string | null;
7499
10438
  read_at: string | null;
7500
10439
  failed_at: string | null;
7501
10440
  cancelled_at: string | null;
7502
10441
  };
10442
+ /** @enum {string} */
10443
+ MessageDirection: "outbound" | "inbound";
10444
+ /** @enum {string} */
10445
+ MessageChannel: "auto" | "iMessage" | "SMS" | "RCS";
10446
+ /** @enum {string|null} */
10447
+ MessageService: "iMessage" | "SMS" | "RCS" | null;
10448
+ /** @enum {string} */
10449
+ MessageStatus: "queued" | "scheduled" | "sent" | "delivered" | "read" | "failed" | "cancelled";
7503
10450
  ReactionEnvelope: {
7504
10451
  /** @enum {boolean} */
7505
10452
  success: true;
@@ -7511,8 +10458,6 @@ export interface components {
7511
10458
  id: string;
7512
10459
  parent_message_id: string;
7513
10460
  /** @enum {string} */
7514
- operation: "add" | "remove";
7515
- /** @enum {string} */
7516
10461
  type: "love" | "like" | "dislike" | "laugh" | "emphasize" | "question";
7517
10462
  /** @enum {string} */
7518
10463
  direction: "outbound" | "inbound";
@@ -7520,11 +10465,22 @@ export interface components {
7520
10465
  created_at: string;
7521
10466
  };
7522
10467
  SendReactionRequest: {
7523
- /** @enum {string} */
7524
- operation: "add" | "remove";
7525
10468
  /** @enum {string} */
7526
10469
  type: "love" | "like" | "dislike" | "laugh" | "emphasize" | "question";
7527
10470
  };
10471
+ ReactionRemovalEnvelope: {
10472
+ /** @enum {boolean} */
10473
+ success: true;
10474
+ data: components["schemas"]["ReactionRemoval"];
10475
+ trace_id: string;
10476
+ request_id: string;
10477
+ };
10478
+ ReactionRemoval: {
10479
+ parent_message_id: string;
10480
+ removed: boolean;
10481
+ /** @enum {string|null} */
10482
+ type: "love" | "like" | "dislike" | "laugh" | "emphasize" | "question" | null;
10483
+ };
7528
10484
  CursoredMessagesEnvelope: {
7529
10485
  /** @enum {boolean} */
7530
10486
  success: true;
@@ -7533,33 +10489,10 @@ export interface components {
7533
10489
  request_id: string;
7534
10490
  };
7535
10491
  CursoredMessages: {
7536
- items: components["schemas"]["Message"][];
10492
+ items: components["schemas"]["MessageV1"][];
7537
10493
  has_more: boolean;
7538
10494
  next_cursor: string | null;
7539
10495
  };
7540
- Message: {
7541
- /** Format: uuid */
7542
- id: string;
7543
- line_id: string;
7544
- direction: string;
7545
- from_number: string;
7546
- to_number: string;
7547
- body: string;
7548
- channel: string;
7549
- status: string;
7550
- error_code: string | null;
7551
- error_message: string | null;
7552
- metadata?: unknown;
7553
- queued_at: string;
7554
- sent_at: string | null;
7555
- delivered_at: string | null;
7556
- read_at: string | null;
7557
- failed_at: string | null;
7558
- created_at: string;
7559
- };
7560
- StatusUpdate: {
7561
- ok: boolean;
7562
- };
7563
10496
  Webhook: {
7564
10497
  /** Format: uuid */
7565
10498
  id: string;
@@ -7573,6 +10506,11 @@ export interface components {
7573
10506
  created_at: string;
7574
10507
  secret?: string;
7575
10508
  };
10509
+ /**
10510
+ * @description A concrete event type (e.g. `message.received`), a family wildcard (`line.*`), or the catch-all `*`.
10511
+ * @enum {string}
10512
+ */
10513
+ WebhookEventName: "message.queued" | "message.sent" | "message.delivered" | "message.read" | "message.failed" | "message.received" | "message.scheduled" | "message.cancelled" | "reaction.added" | "reaction.received" | "reaction.removed" | "line.connected" | "line.disconnected" | "line.offline" | "line.degraded" | "line.apple_id_flagged" | "line.quota_warning" | "line.quota_exceeded" | "typing_indicator.started" | "typing_indicator.stopped" | "trial.linked" | "trial.dormant" | "trial.reactivated" | "pre_order.fulfilled" | "pre_order.cancelled" | "pre_order.refunded" | "webhook.test" | "*" | "message.*" | "reaction.*" | "line.*" | "typing_indicator.*" | "trial.*" | "webhook.*";
7576
10514
  WebhookList: {
7577
10515
  webhooks: components["schemas"]["Webhook"][];
7578
10516
  };
@@ -7684,6 +10622,7 @@ export interface components {
7684
10622
  CreateAttachment: {
7685
10623
  filename: string;
7686
10624
  content_type: string;
10625
+ /** @description Attachment size in bytes. Hard cap 5 GB (R2 single-PUT ceiling); oversize requests are rejected with HTTP 413 `attachment_exceeds_storage_limit`. Sizes above 100 MB succeed but carry a `large_attachment_may_delay_delivery` warning. */
7687
10626
  size_bytes: number;
7688
10627
  };
7689
10628
  Attachment: {
@@ -7711,13 +10650,6 @@ export interface components {
7711
10650
  Lookup: {
7712
10651
  handle: string;
7713
10652
  imessage: boolean | null;
7714
- facetime: boolean | null;
7715
- line_type: string | null;
7716
- carrier: string | null;
7717
- checked_at: string;
7718
- cached: boolean;
7719
- pending?: boolean;
7720
- retry_after?: number;
7721
10653
  };
7722
10654
  LookupRequest: {
7723
10655
  handle: string;
@@ -7789,6 +10721,7 @@ export interface components {
7789
10721
  };
7790
10722
  TrialInitBody: {
7791
10723
  max_outbound_without_inbound?: number;
10724
+ welcome_message?: string;
7792
10725
  };
7793
10726
  TrialStatusEnvelope: {
7794
10727
  /** @enum {boolean} */
@@ -7850,31 +10783,32 @@ export interface components {
7850
10783
  * @description Activation code expiry — 5 minutes from issue.
7851
10784
  */
7852
10785
  expires_at: string;
10786
+ download_urls: components["schemas"]["ByodDownloadUrls"];
10787
+ /** @example 2.0.1 */
10788
+ bridge_version: string;
10789
+ };
10790
+ ByodDownloadUrls: {
7853
10791
  /**
7854
10792
  * Format: uri
7855
- * @description Presigned R2 GET for the bridge installer (.dmg or .apk). 5-minute TTL.
10793
+ * @example https://api.isnap.ai/device/apps/download/android
7856
10794
  */
7857
- bridge_download_url: string;
7858
- /** @example 2.0.1 */
7859
- bridge_version: string;
10795
+ android: string;
7860
10796
  /**
7861
10797
  * Format: uri
7862
- * @description Deep link to the platform-specific BYOD setup docs.
10798
+ * @example https://api.isnap.ai/device/apps/download/macos
7863
10799
  */
7864
- setup_instructions_url: string;
10800
+ macos: string;
7865
10801
  };
7866
10802
  ByodPairBody: {
7867
10803
  /**
7868
- * @description BYOD device platform. macos_byod runs the iMessage bridge on a customer-owned Mac; android_byod runs the Android bridge on a customer-owned phone.
7869
- * @example macos_byod
7870
- * @enum {string}
7871
- */
7872
- device_type: "macos_byod" | "android_byod";
7873
- /**
7874
- * @description Customer-chosen friendly name surfaced in the dashboard.
7875
- * @example My Mac Mini
10804
+ * @description Opaque consumer metadata, stored verbatim and echoed back at activation. iSnap never interprets the keys.
10805
+ * @example {
10806
+ * "whatsnap_client_id": "cust_a1b2"
10807
+ * }
7876
10808
  */
7877
- device_name: string;
10809
+ metadata?: {
10810
+ [key: string]: unknown;
10811
+ };
7878
10812
  };
7879
10813
  MessageList: {
7880
10814
  messages: components["schemas"]["Message"][];
@@ -7882,6 +10816,26 @@ export interface components {
7882
10816
  page: number;
7883
10817
  limit: number;
7884
10818
  };
10819
+ Message: {
10820
+ /** Format: uuid */
10821
+ id: string;
10822
+ line_id: string;
10823
+ direction: string;
10824
+ from_number: string;
10825
+ to_number: string;
10826
+ body: string;
10827
+ channel: string;
10828
+ status: string;
10829
+ error_code: string | null;
10830
+ error_message: string | null;
10831
+ metadata?: unknown;
10832
+ queued_at: string | null;
10833
+ sent_at: string | null;
10834
+ delivered_at: string | null;
10835
+ read_at: string | null;
10836
+ failed_at: string | null;
10837
+ created_at: string;
10838
+ };
7885
10839
  ConversationList: {
7886
10840
  conversations: components["schemas"]["Conversation"][];
7887
10841
  total: number;
@@ -7895,6 +10849,7 @@ export interface components {
7895
10849
  contact_number: string;
7896
10850
  last_message_at: string;
7897
10851
  message_count: number;
10852
+ unread_count: number;
7898
10853
  created_at: string;
7899
10854
  };
7900
10855
  ConversationThread: {
@@ -7926,13 +10881,15 @@ export interface components {
7926
10881
  device_session_id: string;
7927
10882
  /** Format: uuid */
7928
10883
  line_id: string | null;
10884
+ line_public_id: string | null;
7929
10885
  created: boolean;
7930
10886
  };
7931
10887
  ImportDeviceSession: {
7932
10888
  legacy_api_key: string;
7933
- phone_number: string;
10889
+ phone_number?: string | null;
7934
10890
  device_type: string;
7935
10891
  device_name?: string;
10892
+ migration_ref?: string;
7936
10893
  metadata?: {
7937
10894
  [key: string]: unknown;
7938
10895
  };
@@ -7940,14 +10897,18 @@ export interface components {
7940
10897
  ImportLineResponse: {
7941
10898
  /** Format: uuid */
7942
10899
  line_id: string;
10900
+ line_public_id: string;
7943
10901
  created: boolean;
7944
10902
  };
7945
10903
  ImportLine: {
7946
- phone_number: string;
7947
- area_code: string;
10904
+ migration_ref: string;
10905
+ phone_number?: string | null;
10906
+ area_code?: string;
7948
10907
  /** @enum {string} */
7949
10908
  billing_tier: "rental_iphone" | "rental_android" | "byod_imessage" | "byod_android" | "shared_pool";
7950
10909
  monthly_price_cents: number;
10910
+ /** Format: uuid */
10911
+ owner_user_id?: string;
7951
10912
  metadata?: {
7952
10913
  [key: string]: unknown;
7953
10914
  };