@hubbyesim/sdk 2.1.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/CHANGELOG.md +79 -0
- package/LICENSE +21 -0
- package/README.md +346 -0
- package/dist/index.cjs +1656 -0
- package/dist/index.d.cts +1877 -0
- package/dist/index.d.ts +1877 -0
- package/dist/index.js +1622 -0
- package/llms.txt +80 -0
- package/package.json +72 -0
- package/signing-vectors.json +87 -0
package/dist/index.d.cts
ADDED
|
@@ -0,0 +1,1877 @@
|
|
|
1
|
+
type Fetch = (request: Request) => Promise<Response>;
|
|
2
|
+
type RetryOptions = {
|
|
3
|
+
/** Total attempts, the first included. Default 3. */
|
|
4
|
+
maxAttempts?: number;
|
|
5
|
+
/** The longest wait before a retry. A longer `Retry-After` is answered, not waited out. Default 30 000. */
|
|
6
|
+
maxDelayMs?: number;
|
|
7
|
+
/** The first wait after a network error or a 429 without `Retry-After`, doubled per attempt. Default 500. */
|
|
8
|
+
baseDelayMs?: number;
|
|
9
|
+
};
|
|
10
|
+
|
|
11
|
+
type SigningClientOptions = {
|
|
12
|
+
/** Your public key id, sent as `X-Api-Key`. */
|
|
13
|
+
apiKey: string;
|
|
14
|
+
/** Your secret. It signs requests and never leaves your server. */
|
|
15
|
+
apiSecret: string;
|
|
16
|
+
/** For example `https://core.hubbyesim.com/api`. */
|
|
17
|
+
baseUrl: string;
|
|
18
|
+
/** The `fetch` to send with. Default: the global `fetch`. */
|
|
19
|
+
fetch?: Fetch;
|
|
20
|
+
/** Epoch milliseconds. Default: `Date.now`. */
|
|
21
|
+
now?: () => number;
|
|
22
|
+
/** Waits between retries. Default: `setTimeout`. */
|
|
23
|
+
sleep?: (milliseconds: number) => Promise<void>;
|
|
24
|
+
/** Retry policy for 429s and network errors, or `false` to send each request once. */
|
|
25
|
+
retry?: RetryOptions | false;
|
|
26
|
+
};
|
|
27
|
+
|
|
28
|
+
/**
|
|
29
|
+
* AnalyticsActivation
|
|
30
|
+
*/
|
|
31
|
+
type AnalyticsActivation = {
|
|
32
|
+
/**
|
|
33
|
+
* Activated over claimed, as a rate.
|
|
34
|
+
*/
|
|
35
|
+
rate: AnalyticsRatio;
|
|
36
|
+
/**
|
|
37
|
+
* Booking codes first claimed in the judged part of the range.
|
|
38
|
+
*/
|
|
39
|
+
claimed: number;
|
|
40
|
+
/**
|
|
41
|
+
* Of those, how many had their eSIM package activated within the window.
|
|
42
|
+
*/
|
|
43
|
+
activated: number;
|
|
44
|
+
/**
|
|
45
|
+
* How long after the first claim an activation still counts, in days.
|
|
46
|
+
*/
|
|
47
|
+
window_days: number;
|
|
48
|
+
/**
|
|
49
|
+
* The part of the range old enough to judge, as UTC dates with both ends included; null when none of it is.
|
|
50
|
+
*/
|
|
51
|
+
judged_range: {
|
|
52
|
+
/**
|
|
53
|
+
* First judged day (UTC).
|
|
54
|
+
*/
|
|
55
|
+
from: string;
|
|
56
|
+
/**
|
|
57
|
+
* Last judged day (UTC).
|
|
58
|
+
*/
|
|
59
|
+
to: string;
|
|
60
|
+
} | null;
|
|
61
|
+
/**
|
|
62
|
+
* True when the whole range is too recent to judge, so no rate is given; read it as "too early to tell", not as a low rate.
|
|
63
|
+
*/
|
|
64
|
+
is_immature: boolean;
|
|
65
|
+
};
|
|
66
|
+
/**
|
|
67
|
+
* AnalyticsBreakdowns
|
|
68
|
+
*/
|
|
69
|
+
type AnalyticsBreakdowns = {
|
|
70
|
+
/**
|
|
71
|
+
* Codes issued in the range, by destination. Includes codes of bookings moved over from the previous platform.
|
|
72
|
+
*/
|
|
73
|
+
destinations: {
|
|
74
|
+
/**
|
|
75
|
+
* Codes issued in the range that have a destination. The `top` counts add up to it.
|
|
76
|
+
*/
|
|
77
|
+
codes: number;
|
|
78
|
+
/**
|
|
79
|
+
* Every destination with a code issued in the range, most codes first.
|
|
80
|
+
*/
|
|
81
|
+
top: Array<AnalyticsDestinationCount>;
|
|
82
|
+
};
|
|
83
|
+
/**
|
|
84
|
+
* Codes issued in the range, by bundle size. Includes codes of bookings moved over from the previous platform.
|
|
85
|
+
*/
|
|
86
|
+
bundle_sizes: {
|
|
87
|
+
/**
|
|
88
|
+
* Codes issued in the range. The `distribution` counts add up to it.
|
|
89
|
+
*/
|
|
90
|
+
codes: number;
|
|
91
|
+
/**
|
|
92
|
+
* One row per bundle size, most codes first.
|
|
93
|
+
*/
|
|
94
|
+
distribution: Array<AnalyticsBundleSizeCount>;
|
|
95
|
+
};
|
|
96
|
+
/**
|
|
97
|
+
* Discounts given on payments that went through in the range.
|
|
98
|
+
*/
|
|
99
|
+
discounts: {
|
|
100
|
+
/**
|
|
101
|
+
* Payments in the range that carried a discount of any kind: a discount code, a limited-time offer or an upgrade offer.
|
|
102
|
+
*/
|
|
103
|
+
discounted_payments: number;
|
|
104
|
+
/**
|
|
105
|
+
* The discount given through each discount code, per currency. A discount from an offer has no code, so it is counted in `discounted_payments` only.
|
|
106
|
+
*/
|
|
107
|
+
by_code: Array<AnalyticsDiscountCode>;
|
|
108
|
+
};
|
|
109
|
+
};
|
|
110
|
+
/**
|
|
111
|
+
* AnalyticsBundleSizeCount
|
|
112
|
+
*/
|
|
113
|
+
type AnalyticsBundleSizeCount = {
|
|
114
|
+
/**
|
|
115
|
+
* The bundle's data allowance in bytes. Null for an unlimited bundle.
|
|
116
|
+
*/
|
|
117
|
+
size_bytes: number | null;
|
|
118
|
+
/**
|
|
119
|
+
* The size as a reader would say it, in binary units (`5GB` is 5 × 1024³ bytes), or `Unlimited`.
|
|
120
|
+
*/
|
|
121
|
+
label: string;
|
|
122
|
+
/**
|
|
123
|
+
* Codes issued in the range with this bundle size.
|
|
124
|
+
*/
|
|
125
|
+
count: number;
|
|
126
|
+
};
|
|
127
|
+
/**
|
|
128
|
+
* AnalyticsDestinationCount
|
|
129
|
+
*/
|
|
130
|
+
type AnalyticsDestinationCount = {
|
|
131
|
+
/**
|
|
132
|
+
* The destination's id. A destination withdrawn since keeps its row and its name.
|
|
133
|
+
*/
|
|
134
|
+
id: string;
|
|
135
|
+
/**
|
|
136
|
+
* The destination's name.
|
|
137
|
+
*/
|
|
138
|
+
name: string;
|
|
139
|
+
/**
|
|
140
|
+
* Codes issued in the range for this destination.
|
|
141
|
+
*/
|
|
142
|
+
count: number;
|
|
143
|
+
};
|
|
144
|
+
/**
|
|
145
|
+
* AnalyticsDiscountCode
|
|
146
|
+
*/
|
|
147
|
+
type AnalyticsDiscountCode = {
|
|
148
|
+
/**
|
|
149
|
+
* The discount code as travellers enter it.
|
|
150
|
+
*/
|
|
151
|
+
code: string;
|
|
152
|
+
/**
|
|
153
|
+
* The discount given through this code in the range, per ISO 4217 currency code, in integer minor units. Currencies are never converted or added together.
|
|
154
|
+
*/
|
|
155
|
+
discount: {
|
|
156
|
+
[key: string]: number;
|
|
157
|
+
};
|
|
158
|
+
};
|
|
159
|
+
/**
|
|
160
|
+
* AnalyticsFunnel
|
|
161
|
+
*/
|
|
162
|
+
type AnalyticsFunnel = {
|
|
163
|
+
/**
|
|
164
|
+
* Always `new`: the funnel covers bookings made on this platform only. Bookings moved over from the previous platform are left out, so `cohort.codes` can differ from the summary's `bookings.total`, which includes them.
|
|
165
|
+
*/
|
|
166
|
+
population: string;
|
|
167
|
+
/**
|
|
168
|
+
* The codes the funnel follows.
|
|
169
|
+
*/
|
|
170
|
+
cohort: {
|
|
171
|
+
/**
|
|
172
|
+
* Booking codes (one per traveller) of the new bookings created in the range: the funnel's first step.
|
|
173
|
+
*/
|
|
174
|
+
codes: number;
|
|
175
|
+
/**
|
|
176
|
+
* The new bookings those codes belong to.
|
|
177
|
+
*/
|
|
178
|
+
bookings: number;
|
|
179
|
+
/**
|
|
180
|
+
* Codes of bookings moved over from the previous platform, left out of the funnel.
|
|
181
|
+
*/
|
|
182
|
+
moved_over_codes_excluded: number;
|
|
183
|
+
/**
|
|
184
|
+
* Codes of test bookings, left out of the funnel.
|
|
185
|
+
*/
|
|
186
|
+
test_codes_excluded: number;
|
|
187
|
+
};
|
|
188
|
+
/**
|
|
189
|
+
* True when the range ended within the last 14 days and has codes: travellers are still claiming, installing and activating, so later steps are still climbing. Read low rates as "too early to tell".
|
|
190
|
+
*/
|
|
191
|
+
is_immature: boolean;
|
|
192
|
+
/**
|
|
193
|
+
* The steps, in order: `codes_issued`, `claimed`, `paid`, `esim_installed`, `package_activated`, `used_data`. Empty when no new booking was created in the range.
|
|
194
|
+
*/
|
|
195
|
+
steps: Array<AnalyticsFunnelStep>;
|
|
196
|
+
/**
|
|
197
|
+
* The `dimension` the funnel is broken down by, as requested; null when none was.
|
|
198
|
+
*/
|
|
199
|
+
dimension: string | null;
|
|
200
|
+
/**
|
|
201
|
+
* The funnel split by `dimension`, one group per value, whose codes and step counts add up to the funnel above. Null when no `dimension` was requested or no new booking was created in the range.
|
|
202
|
+
*/
|
|
203
|
+
breakdown: Array<AnalyticsFunnelGroup> | null;
|
|
204
|
+
};
|
|
205
|
+
/**
|
|
206
|
+
* AnalyticsFunnelGroup
|
|
207
|
+
*/
|
|
208
|
+
type AnalyticsFunnelGroup = {
|
|
209
|
+
/**
|
|
210
|
+
* The dimension's value: a destination id, a bundle size in bytes, a sales channel, a booking source or a transaction type. Null for the codes that have none: an unlimited bundle has no size, and a code not sold in the app has no sales channel or transaction type.
|
|
211
|
+
*/
|
|
212
|
+
value: string | null;
|
|
213
|
+
/**
|
|
214
|
+
* A readable name for the value: the destination's name or the bundle size (for example "5GB"), otherwise the value itself. Null when the value is null.
|
|
215
|
+
*/
|
|
216
|
+
label: string | null;
|
|
217
|
+
/**
|
|
218
|
+
* This group's part of `cohort.codes`.
|
|
219
|
+
*/
|
|
220
|
+
codes: number;
|
|
221
|
+
/**
|
|
222
|
+
* This group's funnel, with the same steps as the whole funnel.
|
|
223
|
+
*/
|
|
224
|
+
steps: Array<AnalyticsFunnelStep>;
|
|
225
|
+
};
|
|
226
|
+
/**
|
|
227
|
+
* AnalyticsFunnelStep
|
|
228
|
+
*/
|
|
229
|
+
type AnalyticsFunnelStep = {
|
|
230
|
+
/**
|
|
231
|
+
* Which step: `codes_issued` (every booking code of the bookings created in the range), `claimed` (the traveller claimed the code), `paid` (the code was paid for in the app; only codes sold in the app can be), `esim_installed` (the eSIM carrying the code's package was installed), `package_activated` (the package went live on the network, at any time after the booking was created, with no 14-day window) or `used_data` (the package carried its first byte of data). Always in this order.
|
|
232
|
+
*/
|
|
233
|
+
step: string;
|
|
234
|
+
/**
|
|
235
|
+
* `recorded` when the step is counted; `not_recorded` when no code in the funnel has a record of it, so it cannot be counted and is skipped as the previous step of the next one; `not_applicable` when it cannot happen to any code in the funnel (`paid`, when no code was sold in the app).
|
|
236
|
+
*/
|
|
237
|
+
status: string;
|
|
238
|
+
/**
|
|
239
|
+
* How many codes reached this step, whenever that happened. For `paid`, out of the codes sold in the app only. Null when the step is not recorded or not applicable.
|
|
240
|
+
*/
|
|
241
|
+
count: number | null;
|
|
242
|
+
rate: AnalyticsRatio | null;
|
|
243
|
+
share_of_codes: AnalyticsRatio | null;
|
|
244
|
+
};
|
|
245
|
+
/**
|
|
246
|
+
* AnalyticsMeta
|
|
247
|
+
*/
|
|
248
|
+
type AnalyticsMeta = {
|
|
249
|
+
/**
|
|
250
|
+
* The range the figures cover, as UTC dates with both ends included.
|
|
251
|
+
*/
|
|
252
|
+
range: {
|
|
253
|
+
/**
|
|
254
|
+
* First day (UTC).
|
|
255
|
+
*/
|
|
256
|
+
from: string;
|
|
257
|
+
/**
|
|
258
|
+
* Last day (UTC).
|
|
259
|
+
*/
|
|
260
|
+
to: string;
|
|
261
|
+
};
|
|
262
|
+
/**
|
|
263
|
+
* Days are UTC days, always: a day runs from 00:00:00 to 23:59:59 UTC.
|
|
264
|
+
*/
|
|
265
|
+
timezone: 'UTC';
|
|
266
|
+
/**
|
|
267
|
+
* When these figures were computed. A repeated request within 15 minutes is answered from the same computation, so this can be up to 15 minutes ago.
|
|
268
|
+
*/
|
|
269
|
+
computed_at: string;
|
|
270
|
+
/**
|
|
271
|
+
* The Partners whose figures are included: your own and, with key inheritance, your descendants that are included.
|
|
272
|
+
*/
|
|
273
|
+
partner_ids: Array<string>;
|
|
274
|
+
/**
|
|
275
|
+
* Descendants left out of every figure because they have not moved to this platform yet, with their names. Empty for a key without key inheritance.
|
|
276
|
+
*/
|
|
277
|
+
excluded_partners: Array<{
|
|
278
|
+
id: string;
|
|
279
|
+
name: string;
|
|
280
|
+
}>;
|
|
281
|
+
/**
|
|
282
|
+
* Present when the range starts before the Partner moved to this platform: activity before that day is on the previous platform and is not in these figures. Null otherwise.
|
|
283
|
+
*/
|
|
284
|
+
cut_over_note: string | null;
|
|
285
|
+
};
|
|
286
|
+
/**
|
|
287
|
+
* AnalyticsPartnerContribution
|
|
288
|
+
*/
|
|
289
|
+
type AnalyticsPartnerContribution = {
|
|
290
|
+
/**
|
|
291
|
+
* The Partner these figures are for, one of `meta.partner_ids`.
|
|
292
|
+
*/
|
|
293
|
+
partner_id: string;
|
|
294
|
+
/**
|
|
295
|
+
* The Partner's name, to label the row with.
|
|
296
|
+
*/
|
|
297
|
+
name: string;
|
|
298
|
+
/**
|
|
299
|
+
* This Partner's part of `bookings.total`.
|
|
300
|
+
*/
|
|
301
|
+
bookings: number;
|
|
302
|
+
/**
|
|
303
|
+
* This Partner's part of `customers.total`.
|
|
304
|
+
*/
|
|
305
|
+
customers: number;
|
|
306
|
+
/**
|
|
307
|
+
* This Partner's part of `revenue_net`, per ISO 4217 currency code, in integer minor units. Empty when there was none.
|
|
308
|
+
*/
|
|
309
|
+
revenue_net: {
|
|
310
|
+
[key: string]: number;
|
|
311
|
+
};
|
|
312
|
+
/**
|
|
313
|
+
* This Partner's part of `data_consumed_bytes`, in bytes.
|
|
314
|
+
*/
|
|
315
|
+
data_consumed_bytes: number;
|
|
316
|
+
};
|
|
317
|
+
/**
|
|
318
|
+
* AnalyticsRatio
|
|
319
|
+
*/
|
|
320
|
+
type AnalyticsRatio = {
|
|
321
|
+
/**
|
|
322
|
+
* The rate as a percentage from 0 to 100, rounded to two decimals; null when suppressed.
|
|
323
|
+
*/
|
|
324
|
+
value: number | null;
|
|
325
|
+
/**
|
|
326
|
+
* True when the denominator is below 30 records, too few for the rate to mean anything.
|
|
327
|
+
*/
|
|
328
|
+
suppressed: boolean;
|
|
329
|
+
/**
|
|
330
|
+
* How many records met the condition.
|
|
331
|
+
*/
|
|
332
|
+
numerator: number;
|
|
333
|
+
/**
|
|
334
|
+
* How many records the rate is out of.
|
|
335
|
+
*/
|
|
336
|
+
denominator: number;
|
|
337
|
+
};
|
|
338
|
+
/**
|
|
339
|
+
* AnalyticsSummary
|
|
340
|
+
*/
|
|
341
|
+
type AnalyticsSummary = {
|
|
342
|
+
/**
|
|
343
|
+
* Bookings created in the range, test bookings left out. Includes bookings moved over from the previous platform, created here on the day they moved.
|
|
344
|
+
*/
|
|
345
|
+
bookings: {
|
|
346
|
+
/**
|
|
347
|
+
* New plus moved over.
|
|
348
|
+
*/
|
|
349
|
+
total: number;
|
|
350
|
+
/**
|
|
351
|
+
* Bookings made on this platform.
|
|
352
|
+
*/
|
|
353
|
+
new: number;
|
|
354
|
+
/**
|
|
355
|
+
* Bookings moved over from the previous platform.
|
|
356
|
+
*/
|
|
357
|
+
moved_over: number;
|
|
358
|
+
/**
|
|
359
|
+
* Test bookings created in the range and left out of every figure.
|
|
360
|
+
*/
|
|
361
|
+
tests_excluded: number;
|
|
362
|
+
};
|
|
363
|
+
/**
|
|
364
|
+
* Customers (travellers) gained in the range.
|
|
365
|
+
*/
|
|
366
|
+
customers: {
|
|
367
|
+
/**
|
|
368
|
+
* New plus moved over.
|
|
369
|
+
*/
|
|
370
|
+
total: number;
|
|
371
|
+
/**
|
|
372
|
+
* Customers who first appeared on this platform.
|
|
373
|
+
*/
|
|
374
|
+
new: number;
|
|
375
|
+
/**
|
|
376
|
+
* Customers moved over from the previous platform.
|
|
377
|
+
*/
|
|
378
|
+
moved_over: number;
|
|
379
|
+
};
|
|
380
|
+
/**
|
|
381
|
+
* Bookings departing from today onwards, whatever the range.
|
|
382
|
+
*/
|
|
383
|
+
departing_from_today: {
|
|
384
|
+
/**
|
|
385
|
+
* Departing between today and 30 days from today (UTC).
|
|
386
|
+
*/
|
|
387
|
+
next_30d: number;
|
|
388
|
+
/**
|
|
389
|
+
* Departing between today and 60 days from today (UTC).
|
|
390
|
+
*/
|
|
391
|
+
next_60d: number;
|
|
392
|
+
/**
|
|
393
|
+
* Departing between today and 90 days from today (UTC).
|
|
394
|
+
*/
|
|
395
|
+
next_90d: number;
|
|
396
|
+
};
|
|
397
|
+
/**
|
|
398
|
+
* The 14-day claim-to-activation rate for codes claimed in the range.
|
|
399
|
+
*/
|
|
400
|
+
activation: AnalyticsActivation;
|
|
401
|
+
/**
|
|
402
|
+
* Net revenue in the range: purchases minus refunds, per ISO 4217 currency code, in integer minor units. Currencies are never converted or added together. Empty when there was none.
|
|
403
|
+
*/
|
|
404
|
+
revenue_net: {
|
|
405
|
+
[key: string]: number;
|
|
406
|
+
};
|
|
407
|
+
/**
|
|
408
|
+
* Mobile data your travellers used in the range on packages sold through this platform, in bytes.
|
|
409
|
+
*/
|
|
410
|
+
data_consumed_bytes: number;
|
|
411
|
+
/**
|
|
412
|
+
* Packages sold through this platform that started using data in the range.
|
|
413
|
+
*/
|
|
414
|
+
used_data_packages: number;
|
|
415
|
+
/**
|
|
416
|
+
* Each Partner in `meta.partner_ids`, with its part of bookings, customers, net revenue and data consumed. The rows add up to the totals above. One row when the figures are for your own Partner alone.
|
|
417
|
+
*/
|
|
418
|
+
by_partner: Array<AnalyticsPartnerContribution>;
|
|
419
|
+
/**
|
|
420
|
+
* The same headline figures for the preceding period of equal length, when `compare` was set. Null otherwise.
|
|
421
|
+
*/
|
|
422
|
+
comparison: {
|
|
423
|
+
/**
|
|
424
|
+
* The preceding period, as UTC dates with both ends included.
|
|
425
|
+
*/
|
|
426
|
+
range: {
|
|
427
|
+
/**
|
|
428
|
+
* First day (UTC).
|
|
429
|
+
*/
|
|
430
|
+
from: string;
|
|
431
|
+
/**
|
|
432
|
+
* Last day (UTC).
|
|
433
|
+
*/
|
|
434
|
+
to: string;
|
|
435
|
+
};
|
|
436
|
+
/**
|
|
437
|
+
* Bookings created in the preceding period, counted as `bookings.total` is.
|
|
438
|
+
*/
|
|
439
|
+
bookings: number;
|
|
440
|
+
/**
|
|
441
|
+
* Net revenue in the preceding period, per currency, in integer minor units.
|
|
442
|
+
*/
|
|
443
|
+
revenue_net: {
|
|
444
|
+
[key: string]: number;
|
|
445
|
+
};
|
|
446
|
+
/**
|
|
447
|
+
* Data used in the preceding period on packages sold through this platform, in bytes.
|
|
448
|
+
*/
|
|
449
|
+
data_consumed_bytes: number;
|
|
450
|
+
/**
|
|
451
|
+
* The activation rate for codes claimed in the preceding period.
|
|
452
|
+
*/
|
|
453
|
+
activation: AnalyticsActivation;
|
|
454
|
+
/**
|
|
455
|
+
* Packages that started using data in the preceding period.
|
|
456
|
+
*/
|
|
457
|
+
used_data_packages: number;
|
|
458
|
+
} | null;
|
|
459
|
+
};
|
|
460
|
+
/**
|
|
461
|
+
* AnalyticsTimeseries
|
|
462
|
+
*/
|
|
463
|
+
type AnalyticsTimeseries = {
|
|
464
|
+
/**
|
|
465
|
+
* The bucket every row covers: `day`, `week` (ISO weeks, Monday to Sunday) or `month`.
|
|
466
|
+
*/
|
|
467
|
+
bucket: string;
|
|
468
|
+
/**
|
|
469
|
+
* One row per bucket, oldest first, from the bucket holding `meta.range.from` to the bucket holding `meta.range.to`.
|
|
470
|
+
*/
|
|
471
|
+
series: Array<AnalyticsTimeseriesBucket>;
|
|
472
|
+
};
|
|
473
|
+
/**
|
|
474
|
+
* AnalyticsTimeseriesBucket
|
|
475
|
+
*/
|
|
476
|
+
type AnalyticsTimeseriesBucket = {
|
|
477
|
+
/**
|
|
478
|
+
* The bucket's first day (UTC): the day itself, the Monday of the week, or the first of the month. A week or month bucket at either end of the range can start before or end after it; only the days inside the range are counted.
|
|
479
|
+
*/
|
|
480
|
+
date: string;
|
|
481
|
+
/**
|
|
482
|
+
* Bookings created in the bucket, test bookings left out. Includes bookings moved over from the previous platform, created here on the day they moved.
|
|
483
|
+
*/
|
|
484
|
+
bookings_created: number;
|
|
485
|
+
/**
|
|
486
|
+
* Bookings whose departure date falls in the bucket, test bookings left out, moved-over bookings included. This follows the requested range, unlike the summary's `departing_from_today`, which always looks forward from today.
|
|
487
|
+
*/
|
|
488
|
+
bookings_departing: number;
|
|
489
|
+
/**
|
|
490
|
+
* Bookings cancelled in the bucket, test bookings left out, moved-over bookings included.
|
|
491
|
+
*/
|
|
492
|
+
bookings_cancelled: number;
|
|
493
|
+
/**
|
|
494
|
+
* Customers (travellers) gained in the bucket.
|
|
495
|
+
*/
|
|
496
|
+
customers: number;
|
|
497
|
+
/**
|
|
498
|
+
* Net revenue in the bucket: purchases minus refunds, per ISO 4217 currency code, in integer minor units. Currencies are never converted or added together. Empty when there was none.
|
|
499
|
+
*/
|
|
500
|
+
revenue_net: {
|
|
501
|
+
[key: string]: number;
|
|
502
|
+
};
|
|
503
|
+
/**
|
|
504
|
+
* Mobile data your travellers used in the bucket on packages sold through this platform, in bytes.
|
|
505
|
+
*/
|
|
506
|
+
data_consumed_bytes: number;
|
|
507
|
+
};
|
|
508
|
+
/**
|
|
509
|
+
* Booking
|
|
510
|
+
*/
|
|
511
|
+
type Booking = {
|
|
512
|
+
id: string;
|
|
513
|
+
partner_id: string;
|
|
514
|
+
visual_identity_id: string | null;
|
|
515
|
+
external_reference: string | null;
|
|
516
|
+
external_reference_secondary: string | null;
|
|
517
|
+
source: BookingSource;
|
|
518
|
+
depart_at: string | null;
|
|
519
|
+
return_at: string | null;
|
|
520
|
+
locale: string | null;
|
|
521
|
+
email: string | null;
|
|
522
|
+
phone: string | null;
|
|
523
|
+
first_name: string | null;
|
|
524
|
+
last_name: string | null;
|
|
525
|
+
full_name: string | null;
|
|
526
|
+
title: string | null;
|
|
527
|
+
gender: string | null;
|
|
528
|
+
date_of_birth: string | null;
|
|
529
|
+
pax: number | null;
|
|
530
|
+
flight_number: string | null;
|
|
531
|
+
departure_location: string | null;
|
|
532
|
+
/**
|
|
533
|
+
* The partner `data` blob is write-only: a resource field named
|
|
534
|
+
* `data` would collide with the response's `data` wrapper (Laravel
|
|
535
|
+
* skips wrapping when the key already exists).
|
|
536
|
+
*/
|
|
537
|
+
communication_options: {
|
|
538
|
+
should_send_message?: boolean;
|
|
539
|
+
channels?: Array<string>;
|
|
540
|
+
} | null;
|
|
541
|
+
cancelled_at: string | null;
|
|
542
|
+
/**
|
|
543
|
+
* Whether `DELETE /v1/bookings/{id}` would cancel this booking now. False once it is cancelled, after `depart_at`, while any item is issued, or while a traveller's money sits on an item. Read it before offering a cancel button.
|
|
544
|
+
*/
|
|
545
|
+
is_cancellable: boolean;
|
|
546
|
+
is_pseudonymized: boolean;
|
|
547
|
+
/**
|
|
548
|
+
* The booking's items, one per package specification. Each item's `id` is the `{item}` you issue, read and terminate its package with.
|
|
549
|
+
*/
|
|
550
|
+
items?: Array<BookingItem & {
|
|
551
|
+
[key: string]: unknown;
|
|
552
|
+
}>;
|
|
553
|
+
created_at: string | null;
|
|
554
|
+
updated_at: string | null;
|
|
555
|
+
};
|
|
556
|
+
/**
|
|
557
|
+
* BookingItem
|
|
558
|
+
*/
|
|
559
|
+
type BookingItem = {
|
|
560
|
+
id: string;
|
|
561
|
+
/**
|
|
562
|
+
* The human-typeable redemption code for this package, twelve
|
|
563
|
+
* characters from an unambiguous alphabet. It is a bearer
|
|
564
|
+
* credential: whoever redeems it is bound to the package, so treat
|
|
565
|
+
* it like a voucher and do not put it anywhere public.
|
|
566
|
+
* Absent when your End-customer channel is `partner_app`.
|
|
567
|
+
*/
|
|
568
|
+
code?: string | null;
|
|
569
|
+
/**
|
|
570
|
+
* The key of this item's upgrade-offer page, where the traveller
|
|
571
|
+
* can buy a larger package before redeeming. Distinct from `id`:
|
|
572
|
+
* `id` is what the outbound webhooks send as `package_queue_uuid`,
|
|
573
|
+
* this is the page's own token, and the two are never
|
|
574
|
+
* interchangeable. Use it only if you build the link yourself —
|
|
575
|
+
* `upgrade_url` is already the whole link.
|
|
576
|
+
* Absent when your End-customer channel is `partner_app`.
|
|
577
|
+
*/
|
|
578
|
+
offer_uuid?: string | null;
|
|
579
|
+
/**
|
|
580
|
+
* The traveller's upgrade-offer link for this item, ready to send.
|
|
581
|
+
* It is a bearer capability URL — whoever opens it can buy an
|
|
582
|
+
* upgrade for this package — so treat it like `code` and keep it
|
|
583
|
+
* out of anywhere public. Null only on an environment with no
|
|
584
|
+
* public-pages deployment configured.
|
|
585
|
+
* Absent when your End-customer channel is `partner_app`.
|
|
586
|
+
*/
|
|
587
|
+
upgrade_url?: string | null;
|
|
588
|
+
/**
|
|
589
|
+
* A universal link that opens the Hubby app and applies this
|
|
590
|
+
* item's `code` automatically, so a traveller never types it. On
|
|
591
|
+
* a device without the app it leads to the store instead; on
|
|
592
|
+
* desktop, to a download page — it is a mobile CTA, not a general
|
|
593
|
+
* redemption URL. Send it as given rather than rebuilding it.
|
|
594
|
+
* Null for an item carrying no code.
|
|
595
|
+
* Absent when your End-customer channel is `partner_app`.
|
|
596
|
+
*/
|
|
597
|
+
deep_link_url?: string | null;
|
|
598
|
+
external_user_id?: string | null;
|
|
599
|
+
email?: string | null;
|
|
600
|
+
customer_id: string | null;
|
|
601
|
+
/**
|
|
602
|
+
* iso2 for countries, iso3 for regions (which carry only one of the two).
|
|
603
|
+
*/
|
|
604
|
+
destination?: string | null;
|
|
605
|
+
package_type: PackageType | null;
|
|
606
|
+
size_bytes: number | null;
|
|
607
|
+
duration_seconds: number | null;
|
|
608
|
+
start_at: string | null;
|
|
609
|
+
end_at: string | null;
|
|
610
|
+
status: PackageQueueStatus;
|
|
611
|
+
/**
|
|
612
|
+
* The bundle this item books: the one named by `bundle_id` at booking, or, once issued, the bundle the closest match chose. Null while an item specified by dimensions is not issued yet.
|
|
613
|
+
*/
|
|
614
|
+
bundle_id: string | null;
|
|
615
|
+
/**
|
|
616
|
+
* Where this item is in its lifecycle. Read it instead of `status`: `queued` (reserved, not issued yet; you can issue it), `unavailable` (cannot be issued now: no bundle answers its specification, or a payment is still pending; cancel the booking or book again), `redeemed` (issued, install material available), `installed` (the eSIM is on a phone), `activated` (live on the network, validity running), `expired` (validity elapsed or consumed), `terminated` (ended before activation), `cancelled` (the booking was cancelled).
|
|
617
|
+
*/
|
|
618
|
+
state: PackageLifecycleState;
|
|
619
|
+
package: IssuedPackage | null;
|
|
620
|
+
};
|
|
621
|
+
/**
|
|
622
|
+
* BookingSource
|
|
623
|
+
*/
|
|
624
|
+
type BookingSource = 'api' | 'platform' | 'manual' | 'synthetic' | 'migrated' | 'free_esim' | 'import' | 'membership';
|
|
625
|
+
/**
|
|
626
|
+
* Bundle
|
|
627
|
+
*/
|
|
628
|
+
type Bundle = {
|
|
629
|
+
/**
|
|
630
|
+
* The bundle's id. Stable: name it as `bundle_id` to book exactly this bundle.
|
|
631
|
+
*/
|
|
632
|
+
id: string;
|
|
633
|
+
/**
|
|
634
|
+
* The destination the bundle is sold for. `iso2` and `iso3` are null on a region.
|
|
635
|
+
*/
|
|
636
|
+
destination: {
|
|
637
|
+
id: string;
|
|
638
|
+
iso2: string | null;
|
|
639
|
+
iso3: string | null;
|
|
640
|
+
};
|
|
641
|
+
/**
|
|
642
|
+
* `data_limited`, `starter` or `unlimited`.
|
|
643
|
+
*/
|
|
644
|
+
type: string;
|
|
645
|
+
label: string;
|
|
646
|
+
provider: string;
|
|
647
|
+
size_bytes: number | null;
|
|
648
|
+
duration_seconds: number | null;
|
|
649
|
+
/**
|
|
650
|
+
* The validity in whole days, counted from first use. The same value as `duration_seconds`. Unlimited bundles are listed once for every day count from 1 to 30 that has a price.
|
|
651
|
+
*/
|
|
652
|
+
duration_days: number | null;
|
|
653
|
+
package_template: {
|
|
654
|
+
id: string;
|
|
655
|
+
name: string;
|
|
656
|
+
};
|
|
657
|
+
partner: {
|
|
658
|
+
id: string;
|
|
659
|
+
name: string;
|
|
660
|
+
} | null;
|
|
661
|
+
traffic_policy: {
|
|
662
|
+
description: string | null;
|
|
663
|
+
} | null;
|
|
664
|
+
fair_use_throttle: FairUseThrottle | null;
|
|
665
|
+
is_active: boolean;
|
|
666
|
+
is_visible: boolean;
|
|
667
|
+
priority: number;
|
|
668
|
+
created_at: string | null;
|
|
669
|
+
/**
|
|
670
|
+
* When anything on the bundle last changed. A price change does not move it: compare `prices` too, or watch the catalog `ETag`.
|
|
671
|
+
*/
|
|
672
|
+
updated_at: string | null;
|
|
673
|
+
deleted_at: string | null;
|
|
674
|
+
created_by: string | null;
|
|
675
|
+
updated_by: string | null;
|
|
676
|
+
/**
|
|
677
|
+
* The recommended retail price in EUR major units. Kept for older integrations; read `prices` instead.
|
|
678
|
+
*/
|
|
679
|
+
pricing_info: {
|
|
680
|
+
final_price: number;
|
|
681
|
+
original_price: number;
|
|
682
|
+
currency: string;
|
|
683
|
+
currency_symbol: string;
|
|
684
|
+
discount_applied: boolean;
|
|
685
|
+
discount_percentage: number;
|
|
686
|
+
};
|
|
687
|
+
/**
|
|
688
|
+
* Both prices of the bundle, in EUR cents.
|
|
689
|
+
*/
|
|
690
|
+
prices: {
|
|
691
|
+
/**
|
|
692
|
+
* The recommended retail price: what a traveller pays in Hubby's own shop.
|
|
693
|
+
*/
|
|
694
|
+
retail: {
|
|
695
|
+
amount: number;
|
|
696
|
+
currency: 'EUR';
|
|
697
|
+
};
|
|
698
|
+
/**
|
|
699
|
+
* Your price under your agreement: the amount Hubby invoices you. Null when your agreement sets no price for this bundle.
|
|
700
|
+
*/
|
|
701
|
+
net: {
|
|
702
|
+
amount: number;
|
|
703
|
+
currency: 'EUR';
|
|
704
|
+
} | null;
|
|
705
|
+
};
|
|
706
|
+
};
|
|
707
|
+
/**
|
|
708
|
+
* CheckDeviceCompatibilityData
|
|
709
|
+
*
|
|
710
|
+
* Device-compatibility check input. No real device dataset exists (see
|
|
711
|
+
* {@see DeviceCompatibilityController}), so both fields are required
|
|
712
|
+
* presence-only — there is nothing to validate the values against.
|
|
713
|
+
*/
|
|
714
|
+
type CheckDeviceCompatibilityData = {
|
|
715
|
+
phone_brand: string;
|
|
716
|
+
phone_model: string;
|
|
717
|
+
};
|
|
718
|
+
/**
|
|
719
|
+
* CommunicationChannel
|
|
720
|
+
*
|
|
721
|
+
* Channels a partner may name in a booking's communication_options. Backed by the exact wire values of the legacy API so stored payloads and validation share one source of truth. Core stores the choice; acting on it belongs to the (future) messaging domain.
|
|
722
|
+
*
|
|
723
|
+
*/
|
|
724
|
+
type CommunicationChannel = 'EMAIL' | 'WHATSAPP' | 'PUSH_NOTIFICATION' | 'SMS';
|
|
725
|
+
/**
|
|
726
|
+
* CreateBookingRequest
|
|
727
|
+
*
|
|
728
|
+
* A new booking: your reference, the trip, and one package specification per eSIM to issue. Travel dates are `depart_at` and `return_at` and branding is `visual_identity_id`, the names the booking response uses; the legacy spellings `departure_date`, `return_date` and `custom_branding` are refused.
|
|
729
|
+
*/
|
|
730
|
+
type CreateBookingRequest = {
|
|
731
|
+
external_reference: string;
|
|
732
|
+
external_reference_secondary?: string | null;
|
|
733
|
+
visual_identity_id?: string | null;
|
|
734
|
+
depart_at?: string | null;
|
|
735
|
+
return_at?: string | null;
|
|
736
|
+
locale?: string | null;
|
|
737
|
+
email?: string | null;
|
|
738
|
+
phone?: string | null;
|
|
739
|
+
first_name?: string | null;
|
|
740
|
+
last_name?: string | null;
|
|
741
|
+
full_name?: string | null;
|
|
742
|
+
title?: string | null;
|
|
743
|
+
gender?: string | null;
|
|
744
|
+
date_of_birth?: string | null;
|
|
745
|
+
/**
|
|
746
|
+
* The storage bound (int4), so an overflowing value 422s instead
|
|
747
|
+
* of 500ing on insert.
|
|
748
|
+
*/
|
|
749
|
+
pax?: number | null;
|
|
750
|
+
flight_number?: string | null;
|
|
751
|
+
departure_location?: string | null;
|
|
752
|
+
data?: Array<string> | null;
|
|
753
|
+
communication_options?: {
|
|
754
|
+
should_send_message: boolean;
|
|
755
|
+
channels: Array<CommunicationChannel> | null;
|
|
756
|
+
};
|
|
757
|
+
/**
|
|
758
|
+
* The package specifications to fulfil, one per traveller. When `GET /v1/me` reports a `package_strategy`, `package_type` may be omitted and `size` and `package_duration` are not required by the type: the strategy overwrites all three on every specification you create, whether or not you send them. Each specification must carry `email` or `external_user_id` when `GET /v1/me` reports `end_customer_channel: webapp`; otherwise both are optional and a specification naming neither is claimed by its code.
|
|
759
|
+
*/
|
|
760
|
+
package_specifications: Array<{
|
|
761
|
+
external_user_id?: string | null;
|
|
762
|
+
email?: string | null;
|
|
763
|
+
/**
|
|
764
|
+
* Required unless `bundle_id` is sent. The country or region the package is for: an ISO 3166-1 alpha-2 or alpha-3 code, or a destination name. May also be omitted when `GET /v1/me` reports `force_destinationless: true`; a sent one is then ignored.
|
|
765
|
+
*/
|
|
766
|
+
destination?: string;
|
|
767
|
+
/**
|
|
768
|
+
* Required unless `bundle_id` is sent. `data-limited` (or `data_limited`), `starter` or `unlimited`. Both spellings are accepted; answers always spell it `data_limited`. May also be omitted when `GET /v1/me` reports a `package_strategy`, which sets it for you.
|
|
769
|
+
*/
|
|
770
|
+
package_type?: string;
|
|
771
|
+
size?: string | null;
|
|
772
|
+
package_duration?: number | null;
|
|
773
|
+
start_at?: string | null;
|
|
774
|
+
end_at?: string | null;
|
|
775
|
+
/**
|
|
776
|
+
* A bundle `id` from the catalogue (`GET /v1/bundles`). Books exactly that bundle: its destination, type, size and duration are read from it, so `destination`, `package_type`, `size` and `package_duration` may be omitted and are ignored when sent. A bundle outside your catalogue answers 422. Omit it to specify by dimensions instead, which books the closest bundle. Refused with 422 when `GET /v1/me` reports a `package_strategy`, or when your bookings are made without a destination: those settings choose the bundle for you.
|
|
777
|
+
*/
|
|
778
|
+
bundle_id?: string | null;
|
|
779
|
+
esim_type?: string;
|
|
780
|
+
expires_at?: string;
|
|
781
|
+
}>;
|
|
782
|
+
/**
|
|
783
|
+
* Create this booking for one of your descendant partners instead of your own account, naming it by its `slug` (the value `GET /v1/me` reports). Optional: omit it and the booking is yours, exactly as before. No setting on your API key is needed — every account may do this. The named partner must be an active partner below you in the hierarchy, at any depth rather than only a direct child, and every partner between you and it must be active too. Naming anything else — a partner that is not yours, an inactive one, or a slug that does not exist — answers 422. The whole booking is then the named partner's: its catalog and price list, its visual identities, its Package strategy, and its customers.
|
|
784
|
+
*/
|
|
785
|
+
partner?: string | null;
|
|
786
|
+
/**
|
|
787
|
+
* Legacy wire spellings and retired fields: reject rather than
|
|
788
|
+
* silently drop, so a payload copied from a legacy integration
|
|
789
|
+
* fails loudly instead of storing null dates or losing branding.
|
|
790
|
+
* Channel hardening, not row semantics — so it lives here, not in
|
|
791
|
+
* the domain groups. The legacy shim maps/relaxes these before
|
|
792
|
+
* validation. Exception (decided 2026-07-24): per-item package_id
|
|
793
|
+
* is accepted and ignored — it maps to nothing, so dropping it
|
|
794
|
+
* loses nothing.
|
|
795
|
+
*/
|
|
796
|
+
departure_date?: string;
|
|
797
|
+
return_date?: string;
|
|
798
|
+
custom_branding?: string;
|
|
799
|
+
};
|
|
800
|
+
/**
|
|
801
|
+
* CreateRedirectTokenData
|
|
802
|
+
*
|
|
803
|
+
* Identifies the customer a redirect token should be minted for. The
|
|
804
|
+
* authenticated partner (never client input) scopes which customer can be
|
|
805
|
+
* resolved — see ResolveCustomerFromExternalId.
|
|
806
|
+
*/
|
|
807
|
+
type CreateRedirectTokenData = {
|
|
808
|
+
external_user_id: string;
|
|
809
|
+
};
|
|
810
|
+
/**
|
|
811
|
+
* Destination
|
|
812
|
+
*/
|
|
813
|
+
type Destination = {
|
|
814
|
+
id: string;
|
|
815
|
+
name: string | null;
|
|
816
|
+
type: string;
|
|
817
|
+
iso3s: Array<string>;
|
|
818
|
+
i18n_name: {
|
|
819
|
+
[key: string]: string;
|
|
820
|
+
};
|
|
821
|
+
iso2: string | null;
|
|
822
|
+
iso3: string | null;
|
|
823
|
+
} | {
|
|
824
|
+
id: string;
|
|
825
|
+
name: string | null;
|
|
826
|
+
type: string;
|
|
827
|
+
iso2: string | null;
|
|
828
|
+
iso3: string | null;
|
|
829
|
+
iso3s: Array<unknown>;
|
|
830
|
+
/**
|
|
831
|
+
* A region's name token in template names is its uppercased slug,
|
|
832
|
+
* not its iso2/iso3 (those are independently optional short codes
|
|
833
|
+
* on a region, not derived from the slug) — the client name
|
|
834
|
+
* preview needs it.
|
|
835
|
+
*/
|
|
836
|
+
slug: string | null;
|
|
837
|
+
i18n_name: {
|
|
838
|
+
[key: string]: string;
|
|
839
|
+
};
|
|
840
|
+
country_names: {
|
|
841
|
+
[key: string]: string;
|
|
842
|
+
};
|
|
843
|
+
};
|
|
844
|
+
/**
|
|
845
|
+
* DestinationResource
|
|
846
|
+
*/
|
|
847
|
+
type DestinationResource = {
|
|
848
|
+
id: string;
|
|
849
|
+
type: string;
|
|
850
|
+
tier: null;
|
|
851
|
+
iso3s: Array<string>;
|
|
852
|
+
name: string | null;
|
|
853
|
+
i18n_name: {
|
|
854
|
+
[key: string]: string;
|
|
855
|
+
};
|
|
856
|
+
is_active: boolean;
|
|
857
|
+
sort_order: number;
|
|
858
|
+
click_count: number;
|
|
859
|
+
created_at: string | null;
|
|
860
|
+
updated_at: string | null;
|
|
861
|
+
created_by: string | null;
|
|
862
|
+
updated_by: string | null;
|
|
863
|
+
bundles: Array<Bundle>;
|
|
864
|
+
};
|
|
865
|
+
/**
|
|
866
|
+
* DeviceCompatibility
|
|
867
|
+
*/
|
|
868
|
+
type DeviceCompatibility = {
|
|
869
|
+
phone_brand: string;
|
|
870
|
+
phone_model: string;
|
|
871
|
+
is_compatible: boolean;
|
|
872
|
+
};
|
|
873
|
+
/**
|
|
874
|
+
* DeviceCompatibilityList
|
|
875
|
+
*/
|
|
876
|
+
type DeviceCompatibilityList = {
|
|
877
|
+
devices: Array<unknown>;
|
|
878
|
+
};
|
|
879
|
+
/**
|
|
880
|
+
* EndCustomerChannel
|
|
881
|
+
*/
|
|
882
|
+
type EndCustomerChannel = 'webapp' | 'native_app' | 'partner_app';
|
|
883
|
+
/**
|
|
884
|
+
* Esim
|
|
885
|
+
*/
|
|
886
|
+
type Esim = {
|
|
887
|
+
/**
|
|
888
|
+
* The eSIM's ICCID.
|
|
889
|
+
*/
|
|
890
|
+
iccid: string;
|
|
891
|
+
/**
|
|
892
|
+
* Your own identifier for the traveller holding this eSIM.
|
|
893
|
+
*/
|
|
894
|
+
external_user_id: string | null;
|
|
895
|
+
/**
|
|
896
|
+
* When the eSIM was first installed on a phone. Null until then.
|
|
897
|
+
*/
|
|
898
|
+
installed_at: string | null;
|
|
899
|
+
/**
|
|
900
|
+
* Every package on this eSIM, oldest first, ended ones included.
|
|
901
|
+
*/
|
|
902
|
+
packages: Array<EsimPackage>;
|
|
903
|
+
/**
|
|
904
|
+
* When the usage figures were last read from the network. Null when they never were. Send `refresh=true` to read them now.
|
|
905
|
+
*/
|
|
906
|
+
refreshed_at: string | null;
|
|
907
|
+
};
|
|
908
|
+
/**
|
|
909
|
+
* EsimInstallMaterial
|
|
910
|
+
*/
|
|
911
|
+
type EsimInstallMaterial = {
|
|
912
|
+
iccid: string;
|
|
913
|
+
/**
|
|
914
|
+
* When this eSIM was first installed on a phone, whichever package it was installed for. Set for a repeat traveller: the eSIM is already on their phone, so skip the install screen and show that the new package is ready. Null until the eSIM is installed.
|
|
915
|
+
*/
|
|
916
|
+
installed_at: string | null;
|
|
917
|
+
/**
|
|
918
|
+
* The activation string. Render it as a QR code for "install on another device".
|
|
919
|
+
*/
|
|
920
|
+
lpa: string | null;
|
|
921
|
+
/**
|
|
922
|
+
* The SM-DP+ address from `lpa`, for manual entry in the phone's settings.
|
|
923
|
+
*/
|
|
924
|
+
smdp_address: string | null;
|
|
925
|
+
/**
|
|
926
|
+
* The matching id (activation code) from `lpa`, for manual entry in the phone's settings.
|
|
927
|
+
*/
|
|
928
|
+
matching_id: string | null;
|
|
929
|
+
/**
|
|
930
|
+
* One-tap install links. Open the one for the phone that will hold the eSIM; its own installer opens. Each is null when the activation string is not in the standard `LPA:1$…` form.
|
|
931
|
+
*/
|
|
932
|
+
install_links: {
|
|
933
|
+
ios: string | null;
|
|
934
|
+
android: string | null;
|
|
935
|
+
};
|
|
936
|
+
};
|
|
937
|
+
/**
|
|
938
|
+
* EsimPackage
|
|
939
|
+
*/
|
|
940
|
+
type EsimPackage = {
|
|
941
|
+
id: string;
|
|
942
|
+
/**
|
|
943
|
+
* The booking this package was issued from. Null for a package the traveller bought in the Hubby app.
|
|
944
|
+
*/
|
|
945
|
+
booking_id: string | null;
|
|
946
|
+
/**
|
|
947
|
+
* Where this package is in its lifecycle, the same `state` its booking item carries: `redeemed`, `installed`, `activated`, `expired` or `terminated`.
|
|
948
|
+
*/
|
|
949
|
+
state: PackageLifecycleState;
|
|
950
|
+
bundle_id: string;
|
|
951
|
+
/**
|
|
952
|
+
* When the package first attached on the network and its validity started. Null before.
|
|
953
|
+
*/
|
|
954
|
+
activated_at: string | null;
|
|
955
|
+
/**
|
|
956
|
+
* The latest moment this package can still be activated: the deadline the connectivity provider sets when the package is issued, after which an unused package can no longer be started. It is **not** when the package's validity ends: a package with a few days of validity is typically still activatable for about a year. Use `valid_until` for when the package stops working.
|
|
957
|
+
*/
|
|
958
|
+
expires_at: string | null;
|
|
959
|
+
/**
|
|
960
|
+
* When this package's validity ends and its data stops working: the moment it activated plus its time allowance. Null until the package activates, because the clock starts at activation, not at issue. Also null for a package that carries no time allowance.
|
|
961
|
+
*/
|
|
962
|
+
valid_until: string | null;
|
|
963
|
+
/**
|
|
964
|
+
* Data used so far, in bytes. Reported on unlimited packages too, where it is the position against the fair-use threshold.
|
|
965
|
+
*/
|
|
966
|
+
data_used_bytes: number;
|
|
967
|
+
/**
|
|
968
|
+
* Data left, in bytes. `0` once the package has ended (`state` is `expired` or `terminated`), whatever was unused: an ended package has no data the traveller can still use. Null on an unlimited package.
|
|
969
|
+
*/
|
|
970
|
+
data_remaining_bytes: number | null;
|
|
971
|
+
};
|
|
972
|
+
/**
|
|
973
|
+
* FairUseThrottle
|
|
974
|
+
*/
|
|
975
|
+
type FairUseThrottle = {
|
|
976
|
+
/**
|
|
977
|
+
* The daily threshold, in bytes: the data a traveller can use in one day at full speed. The threshold applies per day, not to the whole package.
|
|
978
|
+
*/
|
|
979
|
+
throttle_after_bytes: number;
|
|
980
|
+
/**
|
|
981
|
+
* The speed after the daily threshold is passed, in kbps (decimal: 1 Mbps is 1000 kbps). It applies until the threshold resets.
|
|
982
|
+
*/
|
|
983
|
+
throttled_kbps: number;
|
|
984
|
+
/**
|
|
985
|
+
* When the threshold resets and the full speed comes back.
|
|
986
|
+
* | |
|
|
987
|
+
* |---|
|
|
988
|
+
* | `daily` <br/> Each day: the threshold applies to the data used in one day. |
|
|
989
|
+
*/
|
|
990
|
+
resets: FairUseThrottleReset;
|
|
991
|
+
};
|
|
992
|
+
/**
|
|
993
|
+
* FairUseThrottleReset
|
|
994
|
+
*
|
|
995
|
+
* When the Fair-use throttle's threshold starts again: after it, the data used counts from zero and the full speed comes back.
|
|
996
|
+
* | |
|
|
997
|
+
* |---|
|
|
998
|
+
* | `daily` <br/> Each day: the threshold applies to the data used in one day. |
|
|
999
|
+
*/
|
|
1000
|
+
type FairUseThrottleReset = 'daily';
|
|
1001
|
+
/**
|
|
1002
|
+
* InstallInstructionSection
|
|
1003
|
+
*/
|
|
1004
|
+
type InstallInstructionSection = {
|
|
1005
|
+
/**
|
|
1006
|
+
* What the section does, in this order: `rename` the line, `turn_on` the line, enable `roaming`, pick the line for `mobile_data`.
|
|
1007
|
+
*/
|
|
1008
|
+
id: string | null;
|
|
1009
|
+
/**
|
|
1010
|
+
* The section's title, localized.
|
|
1011
|
+
*/
|
|
1012
|
+
title: string;
|
|
1013
|
+
/**
|
|
1014
|
+
* A short screen recording of the whole section on this phone family, in this language. Null when none exists.
|
|
1015
|
+
*/
|
|
1016
|
+
clip_url: string | null;
|
|
1017
|
+
/**
|
|
1018
|
+
* The steps, in order.
|
|
1019
|
+
*/
|
|
1020
|
+
steps: Array<InstallInstructionStep>;
|
|
1021
|
+
};
|
|
1022
|
+
/**
|
|
1023
|
+
* InstallInstructionSet
|
|
1024
|
+
*/
|
|
1025
|
+
type InstallInstructionSet = {
|
|
1026
|
+
/**
|
|
1027
|
+
* The phone family: `iphone` on iOS; `samsung`, `pixel` or `xiaomi` on Android. For an Android phone you cannot place, use `samsung`.
|
|
1028
|
+
*/
|
|
1029
|
+
family: string;
|
|
1030
|
+
/**
|
|
1031
|
+
* The lowest OS version these instructions apply to.
|
|
1032
|
+
*/
|
|
1033
|
+
min_os_version: string;
|
|
1034
|
+
/**
|
|
1035
|
+
* Install on the phone itself: open `install_link` on that phone, then follow the steps the OS asks.
|
|
1036
|
+
*/
|
|
1037
|
+
one_tap: {
|
|
1038
|
+
title: string;
|
|
1039
|
+
/**
|
|
1040
|
+
* The OS's own one-tap install link for this eSIM. Null when the eSIM's activation string is not in the standard `LPA:1$…` form.
|
|
1041
|
+
*/
|
|
1042
|
+
install_link: string | null;
|
|
1043
|
+
clip_url: string | null;
|
|
1044
|
+
steps: Array<InstallInstructionStep>;
|
|
1045
|
+
};
|
|
1046
|
+
/**
|
|
1047
|
+
* Install from a second screen: render `lpa` as a QR code and scan it with the phone.
|
|
1048
|
+
*/
|
|
1049
|
+
qr_code: {
|
|
1050
|
+
title: string;
|
|
1051
|
+
/**
|
|
1052
|
+
* The eSIM's activation string, to render as a QR code.
|
|
1053
|
+
*/
|
|
1054
|
+
lpa: string | null;
|
|
1055
|
+
clip_url: string | null;
|
|
1056
|
+
steps: Array<InstallInstructionStep>;
|
|
1057
|
+
};
|
|
1058
|
+
/**
|
|
1059
|
+
* Install by typing the SM-DP+ address and the matching id in the phone's settings.
|
|
1060
|
+
*/
|
|
1061
|
+
manual: {
|
|
1062
|
+
title: string;
|
|
1063
|
+
/**
|
|
1064
|
+
* The SM-DP+ address from the activation string. Null when the string is not in the standard form.
|
|
1065
|
+
*/
|
|
1066
|
+
smdp_address: string | null;
|
|
1067
|
+
/**
|
|
1068
|
+
* The matching id (activation code) from the activation string. Null when the string is not in the standard form.
|
|
1069
|
+
*/
|
|
1070
|
+
matching_id: string | null;
|
|
1071
|
+
clip_url: string | null;
|
|
1072
|
+
steps: Array<InstallInstructionStep>;
|
|
1073
|
+
};
|
|
1074
|
+
/**
|
|
1075
|
+
* What to do on arrival, in order: rename the line, turn it on, enable roaming, pick it for mobile data.
|
|
1076
|
+
*/
|
|
1077
|
+
on_arrival: Array<InstallInstructionSection>;
|
|
1078
|
+
};
|
|
1079
|
+
/**
|
|
1080
|
+
* InstallInstructionStep
|
|
1081
|
+
*/
|
|
1082
|
+
type InstallInstructionStep = {
|
|
1083
|
+
/**
|
|
1084
|
+
* The step, localized. Tap targets are marked with markdown bold, `**Activate**`, and nothing else; render or strip it.
|
|
1085
|
+
*/
|
|
1086
|
+
text: string;
|
|
1087
|
+
/**
|
|
1088
|
+
* An image of the screen for this step, in this language. Null when none exists.
|
|
1089
|
+
*/
|
|
1090
|
+
screenshot_url: string | null;
|
|
1091
|
+
};
|
|
1092
|
+
/**
|
|
1093
|
+
* InstallInstructions
|
|
1094
|
+
*/
|
|
1095
|
+
type InstallInstructions = {
|
|
1096
|
+
/**
|
|
1097
|
+
* The eSIM's ICCID.
|
|
1098
|
+
*/
|
|
1099
|
+
iccid: string;
|
|
1100
|
+
/**
|
|
1101
|
+
* The locale the instructions were asked in: `locale` from the query, else the locale of the booking that issued the eSIM, else `en-US`. Copy without a translation in that language is English.
|
|
1102
|
+
*/
|
|
1103
|
+
locale: string;
|
|
1104
|
+
/**
|
|
1105
|
+
* The name the eSIM carries in your branding, already filled in wherever a step names the line. From the Visual identity of the booking that issued the eSIM, else your default one, else `Hubby eSIM`.
|
|
1106
|
+
*/
|
|
1107
|
+
esim_label: string;
|
|
1108
|
+
/**
|
|
1109
|
+
* One entry per iOS phone family: `iphone`.
|
|
1110
|
+
*/
|
|
1111
|
+
ios: Array<InstallInstructionSet>;
|
|
1112
|
+
/**
|
|
1113
|
+
* One entry per Android phone family: `samsung`, `pixel`, `xiaomi`.
|
|
1114
|
+
*/
|
|
1115
|
+
android: Array<InstallInstructionSet>;
|
|
1116
|
+
};
|
|
1117
|
+
/**
|
|
1118
|
+
* IssuePackageRequest
|
|
1119
|
+
*
|
|
1120
|
+
* The body of an issue call. Send it empty unless the item names no traveller yet.
|
|
1121
|
+
*/
|
|
1122
|
+
type IssuePackageRequest = {
|
|
1123
|
+
/**
|
|
1124
|
+
* Your id for the traveller who receives this package. Required when the item does not name a traveller yet; the traveller is then bound to the item exactly as at booking. When the item already names one, send the same id or leave it out.
|
|
1125
|
+
*/
|
|
1126
|
+
external_user_id?: string | null;
|
|
1127
|
+
};
|
|
1128
|
+
/**
|
|
1129
|
+
* IssuedPackage
|
|
1130
|
+
*/
|
|
1131
|
+
type IssuedPackage = {
|
|
1132
|
+
id: string;
|
|
1133
|
+
/**
|
|
1134
|
+
* Where this package is in its lifecycle: `redeemed` (issued, install material available), `installed` (the eSIM is on a phone), `activated` (live on the network, validity running), `expired` (validity elapsed or consumed), `terminated` (ended before activation).
|
|
1135
|
+
*/
|
|
1136
|
+
state: PackageLifecycleState;
|
|
1137
|
+
/**
|
|
1138
|
+
* The bundle this package was issued from.
|
|
1139
|
+
*/
|
|
1140
|
+
bundle_id: string;
|
|
1141
|
+
/**
|
|
1142
|
+
* When the package was issued.
|
|
1143
|
+
*/
|
|
1144
|
+
issued_at: string | null;
|
|
1145
|
+
/**
|
|
1146
|
+
* When this package became installable on a phone: the eSIM's install, or the issue itself when the eSIM was already installed. Null until the eSIM is on a phone.
|
|
1147
|
+
*/
|
|
1148
|
+
installed_at: string | null;
|
|
1149
|
+
/**
|
|
1150
|
+
* When the package attached to the network at the destination (Package activation) and its validity started. Null until then.
|
|
1151
|
+
*/
|
|
1152
|
+
activated_at: string | null;
|
|
1153
|
+
/**
|
|
1154
|
+
* The latest moment this package can still be activated: the deadline the connectivity provider sets when the package is issued, after which an unused package can no longer be started. It is **not** when the package's validity ends: a package with a few days of validity is typically still activatable for about a year. Use `valid_until` for when the package stops working.
|
|
1155
|
+
*/
|
|
1156
|
+
expires_at: string | null;
|
|
1157
|
+
/**
|
|
1158
|
+
* When this package's validity ends and its data stops working: the moment it activated plus its time allowance. Null until the package activates, because the clock starts at activation, not at issue. Also null for a package that carries no time allowance.
|
|
1159
|
+
*/
|
|
1160
|
+
valid_until: string | null;
|
|
1161
|
+
/**
|
|
1162
|
+
* When the package was ended before it activated. Null otherwise.
|
|
1163
|
+
*/
|
|
1164
|
+
terminated_at: string | null;
|
|
1165
|
+
esim: EsimInstallMaterial;
|
|
1166
|
+
};
|
|
1167
|
+
/**
|
|
1168
|
+
* PackageLifecycleState
|
|
1169
|
+
*
|
|
1170
|
+
* The lifecycle state a Partner reads on a booking item and on the package issued from it (partner v1 `state`), so it never interprets the internal `status`. Derived, never stored: from the item's status until a package is issued, then from the package's own timestamps and its eSIM's install.
|
|
1171
|
+
*
|
|
1172
|
+
*/
|
|
1173
|
+
type PackageLifecycleState = 'queued' | 'unavailable' | 'redeemed' | 'installed' | 'activated' | 'expired' | 'terminated' | 'cancelled';
|
|
1174
|
+
/**
|
|
1175
|
+
* PackageQueueStatus
|
|
1176
|
+
*/
|
|
1177
|
+
type PackageQueueStatus = 'queued' | 'pending_payment' | 'paid' | 'activated' | 'cancelled' | 'reverted' | 'unresolved';
|
|
1178
|
+
/**
|
|
1179
|
+
* PackageType
|
|
1180
|
+
*/
|
|
1181
|
+
type PackageType = 'data_limited' | 'starter' | 'unlimited';
|
|
1182
|
+
/**
|
|
1183
|
+
* Partner
|
|
1184
|
+
*/
|
|
1185
|
+
type Partner = {
|
|
1186
|
+
id: string;
|
|
1187
|
+
slug: string;
|
|
1188
|
+
name: string;
|
|
1189
|
+
is_active: boolean;
|
|
1190
|
+
parent_id: string | null;
|
|
1191
|
+
end_customer_channel: EndCustomerChannel | null;
|
|
1192
|
+
price_list_id: string | null;
|
|
1193
|
+
/**
|
|
1194
|
+
* The fixed package dimensions applied to every booking you create
|
|
1195
|
+
* through this API. When present, the `package_type`, `size` and
|
|
1196
|
+
* `package_duration` on every package specification you send are
|
|
1197
|
+
* replaced before the booking is stored — your destination, travel
|
|
1198
|
+
* dates and traveller identities are never changed. The sizes here are canonical units, not the units you send:
|
|
1199
|
+
* `size_bytes` is what `size` (`"1GB"`, `"512MB"`) becomes, and
|
|
1200
|
+
* `duration_seconds` is what `package_duration` (whole days)
|
|
1201
|
+
* becomes. A null on either means that dimension does not apply to
|
|
1202
|
+
* the type — an unlimited package carries no size, a data-limited
|
|
1203
|
+
* one no duration.
|
|
1204
|
+
*
|
|
1205
|
+
* This may be set on your account or inherited from a parent
|
|
1206
|
+
* account; either way it is what governs your bookings. `null`
|
|
1207
|
+
* means no strategy applies: you specify packages freely.
|
|
1208
|
+
*/
|
|
1209
|
+
package_strategy: {
|
|
1210
|
+
package_type: string;
|
|
1211
|
+
size_bytes: number | null;
|
|
1212
|
+
duration_seconds: number | null;
|
|
1213
|
+
} | null;
|
|
1214
|
+
/**
|
|
1215
|
+
* Whether every booking you create through this API is stored without a destination, whatever destination you send. When `true`, the `destination` on each package specification is optional and is discarded if you send one — nothing is rejected for naming a destination, and your travel dates, package dimensions and traveller identities are untouched. Each traveller picks their destination when they redeem, from the destinations available to your account.
|
|
1216
|
+
*
|
|
1217
|
+
* This may be set on your account or inherited from a parent account; either way it is what governs your bookings. `false` means your bookings keep the destination you send, which is the normal case.
|
|
1218
|
+
*/
|
|
1219
|
+
force_destinationless: boolean;
|
|
1220
|
+
/**
|
|
1221
|
+
* The language bookings you create through this API are recorded in when you send no `locale` — for example `nl-NL`. Only ever fills a blank. A `locale` you send on a booking is always kept, whatever this says, and a booking you send without one is recorded in this language instead of none. `null` means no default is set on your account: a booking with no `locale` keeps none, exactly as before.
|
|
1222
|
+
*
|
|
1223
|
+
* It applies to the booking itself. Travellers are not switched to this language — a traveller keeps whichever language they have chosen, and one who has chosen none keeps none until they do.
|
|
1224
|
+
*
|
|
1225
|
+
* This is set on your account. Unlike `package_strategy` and `force_destinationless`, it is NOT inherited from a parent account.
|
|
1226
|
+
*/
|
|
1227
|
+
default_locale: string | null;
|
|
1228
|
+
created_at: string | null;
|
|
1229
|
+
updated_at: string | null;
|
|
1230
|
+
};
|
|
1231
|
+
/**
|
|
1232
|
+
* PartnerTerminateReason
|
|
1233
|
+
*
|
|
1234
|
+
* Why you terminated a package you issued.
|
|
1235
|
+
*
|
|
1236
|
+
*/
|
|
1237
|
+
type PartnerTerminateReason = 'changed_plans' | 'installation_failed' | 'not_received' | 'other';
|
|
1238
|
+
/**
|
|
1239
|
+
* PresignBookingUploadData
|
|
1240
|
+
*
|
|
1241
|
+
* Input for POST /v1/bookings/imports/presign-upload — the HMAC-authenticated
|
|
1242
|
+
* partner-v1 equivalent of the legacy-parity bucket-upload-url contract, for
|
|
1243
|
+
* partners who onboard directly against core. No partnerId field: the
|
|
1244
|
+
* partner is the authenticated principal ($request->partner()), never a
|
|
1245
|
+
* client-supplied value.
|
|
1246
|
+
*/
|
|
1247
|
+
type PresignBookingUploadData = {
|
|
1248
|
+
date: string;
|
|
1249
|
+
dataset?: string;
|
|
1250
|
+
overwrite?: boolean;
|
|
1251
|
+
};
|
|
1252
|
+
/**
|
|
1253
|
+
* RedirectToken
|
|
1254
|
+
*/
|
|
1255
|
+
type RedirectToken = {
|
|
1256
|
+
redirect_token: string;
|
|
1257
|
+
/**
|
|
1258
|
+
* Lifetime of the redirect token in seconds.
|
|
1259
|
+
*/
|
|
1260
|
+
expires_in: number;
|
|
1261
|
+
};
|
|
1262
|
+
/**
|
|
1263
|
+
* SupportedLocale
|
|
1264
|
+
*
|
|
1265
|
+
* Locales the platform supports for customer-facing content (e.g. the booking form's locale picker). Values are BCP-47 language-region tags; human-readable names are derived via ext-intl so there is no display map to maintain.
|
|
1266
|
+
*
|
|
1267
|
+
*/
|
|
1268
|
+
type SupportedLocale = 'en-US' | 'en-EU' | 'en-GB' | 'en-CA' | 'nl-NL' | 'de-DE' | 'fr-FR' | 'fr-CA' | 'it-IT' | 'es-ES' | 'cs-CZ' | 'pl-PL' | 'pt-PT' | 'fr-BE' | 'nl-BE' | 'de-AT' | 'de-CH' | 'fr-CH' | 'it-CH' | 'sv-SE' | 'sk-SK' | 'de-BE' | 'en-AU' | 'da-DK' | 'ko-KR' | 'hu-HU' | 'no-NO' | 'pt-BR' | 'en-NZ' | 'zh-CN' | 'ru-RU' | 'ro-RO';
|
|
1269
|
+
/**
|
|
1270
|
+
* UpdateBookingRequest
|
|
1271
|
+
*
|
|
1272
|
+
* The booking fields to change. Every field is optional: an omitted field is left as it is, and an explicit `null` clears it.
|
|
1273
|
+
*/
|
|
1274
|
+
type UpdateBookingRequest = {
|
|
1275
|
+
external_reference?: string | null;
|
|
1276
|
+
external_reference_secondary?: string | null;
|
|
1277
|
+
visual_identity_id?: string | null;
|
|
1278
|
+
/**
|
|
1279
|
+
* The trip's departure day. Changing it reschedules the booking: the traveller's pre-departure emails follow the new day. Compared by calendar day, so resending the day the booking already has changes nothing. Answers 422 when the booking has already departed, when the day is before today, when it is `null` for a booking that has a departure, or when the booking is cancelled.
|
|
1280
|
+
*/
|
|
1281
|
+
depart_at?: string | null;
|
|
1282
|
+
/**
|
|
1283
|
+
* The trip's return day, on or after the departure. Changing it reschedules the booking, and may still be done once the trip is under way. Answers 422 for a cancelled booking.
|
|
1284
|
+
*/
|
|
1285
|
+
return_at?: string | null;
|
|
1286
|
+
locale?: string | null;
|
|
1287
|
+
email?: string | null;
|
|
1288
|
+
phone?: string | null;
|
|
1289
|
+
first_name?: string | null;
|
|
1290
|
+
last_name?: string | null;
|
|
1291
|
+
full_name?: string | null;
|
|
1292
|
+
title?: string | null;
|
|
1293
|
+
gender?: string | null;
|
|
1294
|
+
date_of_birth?: string | null;
|
|
1295
|
+
/**
|
|
1296
|
+
* The storage bound (int4), so an overflowing value 422s instead
|
|
1297
|
+
* of 500ing on insert.
|
|
1298
|
+
*/
|
|
1299
|
+
pax?: number | null;
|
|
1300
|
+
flight_number?: string | null;
|
|
1301
|
+
departure_location?: string | null;
|
|
1302
|
+
communication_options?: {
|
|
1303
|
+
should_send_message: boolean;
|
|
1304
|
+
channels: Array<CommunicationChannel> | null;
|
|
1305
|
+
};
|
|
1306
|
+
};
|
|
1307
|
+
/**
|
|
1308
|
+
* UpdatePackageSpecificationRequest
|
|
1309
|
+
*
|
|
1310
|
+
* The new specification for a booking's package items. The same body updates one item (its id in the path) or every item of the booking (no id in the path). Send only the fields you change.
|
|
1311
|
+
*/
|
|
1312
|
+
type UpdatePackageSpecificationRequest = {
|
|
1313
|
+
destination?: string | null;
|
|
1314
|
+
/**
|
|
1315
|
+
* `data-limited` (or `data_limited`), `starter` or `unlimited`. Both spellings are accepted; answers always spell it `data_limited`.
|
|
1316
|
+
*/
|
|
1317
|
+
package_type?: string | null;
|
|
1318
|
+
size?: string | null;
|
|
1319
|
+
package_duration?: number | null;
|
|
1320
|
+
/**
|
|
1321
|
+
* A bundle `id` from the catalogue (`GET /v1/bundles`). The item takes that bundle's destination, type, size and duration, and is provisioned with exactly that bundle; `destination`, `package_type`, `size` and `package_duration` are ignored when sent with it. A bundle outside your catalogue answers 422. Omit it to re-specify by dimensions, which lets go of any bundle named before. Refused with 422 when `GET /v1/me` reports a `package_strategy`, or when your bookings are made without a destination: those settings choose the bundle for you. Also refused with 422 on an item Hubby support granted, whose bundle support chose.
|
|
1322
|
+
*/
|
|
1323
|
+
bundle_id?: string | null;
|
|
1324
|
+
};
|
|
1325
|
+
type PartnerApiV1AnalyticsSummaryData = {
|
|
1326
|
+
body?: never;
|
|
1327
|
+
path?: never;
|
|
1328
|
+
query?: {
|
|
1329
|
+
from?: string | null;
|
|
1330
|
+
to?: string | null;
|
|
1331
|
+
'partner_ids[]'?: Array<string>;
|
|
1332
|
+
include_self?: boolean;
|
|
1333
|
+
/**
|
|
1334
|
+
* Set to `1` (or `true`) to add `comparison`: the same totals for the preceding period of the same length, ending the day before `from`. Any value that is not a boolean is refused with 422.
|
|
1335
|
+
*/
|
|
1336
|
+
compare?: boolean;
|
|
1337
|
+
};
|
|
1338
|
+
url: '/v1/analytics/summary';
|
|
1339
|
+
};
|
|
1340
|
+
type PartnerApiV1AnalyticsSummaryResponses = {
|
|
1341
|
+
/**
|
|
1342
|
+
* `AnalyticsSummary`
|
|
1343
|
+
*/
|
|
1344
|
+
200: {
|
|
1345
|
+
data: AnalyticsSummary;
|
|
1346
|
+
/**
|
|
1347
|
+
* What the figures cover.
|
|
1348
|
+
*/
|
|
1349
|
+
meta: AnalyticsMeta;
|
|
1350
|
+
};
|
|
1351
|
+
};
|
|
1352
|
+
type PartnerApiV1AnalyticsSummaryResponse = PartnerApiV1AnalyticsSummaryResponses[keyof PartnerApiV1AnalyticsSummaryResponses];
|
|
1353
|
+
type PartnerApiV1AnalyticsFunnelData = {
|
|
1354
|
+
body?: never;
|
|
1355
|
+
path?: never;
|
|
1356
|
+
query?: {
|
|
1357
|
+
from?: string | null;
|
|
1358
|
+
to?: string | null;
|
|
1359
|
+
'partner_ids[]'?: Array<string>;
|
|
1360
|
+
include_self?: boolean;
|
|
1361
|
+
/**
|
|
1362
|
+
* Break the funnel down by this dimension: `destination`, `bundle_size`, `sales_channel`, `booking_source` or `transaction_type`. Any other value is refused with 422. Leave it out for no breakdown.
|
|
1363
|
+
*/
|
|
1364
|
+
dimension?: 'destination' | 'bundle_size' | 'sales_channel' | 'booking_source' | 'transaction_type';
|
|
1365
|
+
};
|
|
1366
|
+
url: '/v1/analytics/funnel';
|
|
1367
|
+
};
|
|
1368
|
+
type PartnerApiV1AnalyticsFunnelResponses = {
|
|
1369
|
+
/**
|
|
1370
|
+
* `AnalyticsFunnel`
|
|
1371
|
+
*/
|
|
1372
|
+
200: {
|
|
1373
|
+
data: AnalyticsFunnel;
|
|
1374
|
+
/**
|
|
1375
|
+
* What the figures cover.
|
|
1376
|
+
*/
|
|
1377
|
+
meta: AnalyticsMeta;
|
|
1378
|
+
};
|
|
1379
|
+
};
|
|
1380
|
+
type PartnerApiV1AnalyticsFunnelResponse = PartnerApiV1AnalyticsFunnelResponses[keyof PartnerApiV1AnalyticsFunnelResponses];
|
|
1381
|
+
type PartnerApiV1AnalyticsTimeseriesData = {
|
|
1382
|
+
body?: never;
|
|
1383
|
+
path?: never;
|
|
1384
|
+
query?: {
|
|
1385
|
+
from?: string | null;
|
|
1386
|
+
to?: string | null;
|
|
1387
|
+
'partner_ids[]'?: Array<string>;
|
|
1388
|
+
include_self?: boolean;
|
|
1389
|
+
/**
|
|
1390
|
+
* The length of each row: `day` (the default), `week` (ISO weeks, starting Monday) or `month`, all in UTC. Any other value is refused with 422.
|
|
1391
|
+
*/
|
|
1392
|
+
bucket?: 'day' | 'week' | 'month';
|
|
1393
|
+
};
|
|
1394
|
+
url: '/v1/analytics/timeseries';
|
|
1395
|
+
};
|
|
1396
|
+
type PartnerApiV1AnalyticsTimeseriesResponses = {
|
|
1397
|
+
/**
|
|
1398
|
+
* `AnalyticsTimeseries`
|
|
1399
|
+
*/
|
|
1400
|
+
200: {
|
|
1401
|
+
data: AnalyticsTimeseries;
|
|
1402
|
+
/**
|
|
1403
|
+
* What the figures cover.
|
|
1404
|
+
*/
|
|
1405
|
+
meta: AnalyticsMeta;
|
|
1406
|
+
};
|
|
1407
|
+
};
|
|
1408
|
+
type PartnerApiV1AnalyticsTimeseriesResponse = PartnerApiV1AnalyticsTimeseriesResponses[keyof PartnerApiV1AnalyticsTimeseriesResponses];
|
|
1409
|
+
type PartnerApiV1AnalyticsBreakdownsData = {
|
|
1410
|
+
body?: never;
|
|
1411
|
+
path?: never;
|
|
1412
|
+
query?: {
|
|
1413
|
+
from?: string | null;
|
|
1414
|
+
to?: string | null;
|
|
1415
|
+
'partner_ids[]'?: Array<string>;
|
|
1416
|
+
include_self?: boolean;
|
|
1417
|
+
};
|
|
1418
|
+
url: '/v1/analytics/breakdowns';
|
|
1419
|
+
};
|
|
1420
|
+
type PartnerApiV1AnalyticsBreakdownsResponses = {
|
|
1421
|
+
/**
|
|
1422
|
+
* `AnalyticsBreakdowns`
|
|
1423
|
+
*/
|
|
1424
|
+
200: {
|
|
1425
|
+
data: AnalyticsBreakdowns;
|
|
1426
|
+
/**
|
|
1427
|
+
* What the figures cover.
|
|
1428
|
+
*/
|
|
1429
|
+
meta: AnalyticsMeta;
|
|
1430
|
+
};
|
|
1431
|
+
};
|
|
1432
|
+
type PartnerApiV1AnalyticsBreakdownsResponse = PartnerApiV1AnalyticsBreakdownsResponses[keyof PartnerApiV1AnalyticsBreakdownsResponses];
|
|
1433
|
+
type PartnerApiV1BookingsIndexData = {
|
|
1434
|
+
body?: never;
|
|
1435
|
+
path?: never;
|
|
1436
|
+
query?: {
|
|
1437
|
+
per_page?: number;
|
|
1438
|
+
/**
|
|
1439
|
+
* The page to read: a `pagination.nextCursor` or `pagination.prevCursor` from the previous page, sent back unchanged. Omit it for the first page.
|
|
1440
|
+
*/
|
|
1441
|
+
cursor?: string | null;
|
|
1442
|
+
email?: string | null;
|
|
1443
|
+
external_reference?: string | null;
|
|
1444
|
+
depart_at?: string | null;
|
|
1445
|
+
created_at?: string | null;
|
|
1446
|
+
promo_code?: string | null;
|
|
1447
|
+
destination?: string | null;
|
|
1448
|
+
sort?: 'created_at' | 'depart_at' | 'external_reference';
|
|
1449
|
+
order?: 'asc' | 'desc';
|
|
1450
|
+
format?: 'csv' | null;
|
|
1451
|
+
departure_from?: string | null;
|
|
1452
|
+
departure_to?: string | null;
|
|
1453
|
+
};
|
|
1454
|
+
url: '/v1/bookings';
|
|
1455
|
+
};
|
|
1456
|
+
type PartnerApiV1BookingsIndexResponses = {
|
|
1457
|
+
200: {
|
|
1458
|
+
data: Array<Booking>;
|
|
1459
|
+
pagination: {
|
|
1460
|
+
perPage: number;
|
|
1461
|
+
nextCursor: string | null;
|
|
1462
|
+
prevCursor: string | null;
|
|
1463
|
+
hasNextPage: boolean;
|
|
1464
|
+
hasPrevPage: boolean;
|
|
1465
|
+
};
|
|
1466
|
+
} | {
|
|
1467
|
+
data: Array<Booking>;
|
|
1468
|
+
pagination: {
|
|
1469
|
+
hasNextPage: boolean;
|
|
1470
|
+
};
|
|
1471
|
+
};
|
|
1472
|
+
};
|
|
1473
|
+
type PartnerApiV1BookingsIndexResponse = PartnerApiV1BookingsIndexResponses[keyof PartnerApiV1BookingsIndexResponses];
|
|
1474
|
+
type PartnerApiV1BookingsImportsPresignUploadResponses = {
|
|
1475
|
+
200: {
|
|
1476
|
+
bucket: string;
|
|
1477
|
+
object_path: string;
|
|
1478
|
+
upload_url: string;
|
|
1479
|
+
expires_at: string;
|
|
1480
|
+
required_headers: {
|
|
1481
|
+
[key: string]: string;
|
|
1482
|
+
};
|
|
1483
|
+
};
|
|
1484
|
+
};
|
|
1485
|
+
type PartnerApiV1BookingsImportsPresignUploadResponse = PartnerApiV1BookingsImportsPresignUploadResponses[keyof PartnerApiV1BookingsImportsPresignUploadResponses];
|
|
1486
|
+
type PartnerApiV1BookingsUpdatePackageSpecificationsResponses = {
|
|
1487
|
+
200: {
|
|
1488
|
+
updated_count: number;
|
|
1489
|
+
skipped_count: number;
|
|
1490
|
+
} | {
|
|
1491
|
+
updated_count: 1;
|
|
1492
|
+
};
|
|
1493
|
+
};
|
|
1494
|
+
type PartnerApiV1BookingsUpdatePackageSpecificationsResponse = PartnerApiV1BookingsUpdatePackageSpecificationsResponses[keyof PartnerApiV1BookingsUpdatePackageSpecificationsResponses];
|
|
1495
|
+
type PartnerApiV1BookingsShowResponses = {
|
|
1496
|
+
200: {
|
|
1497
|
+
data: Booking;
|
|
1498
|
+
};
|
|
1499
|
+
};
|
|
1500
|
+
type PartnerApiV1BookingsShowResponse = PartnerApiV1BookingsShowResponses[keyof PartnerApiV1BookingsShowResponses];
|
|
1501
|
+
type PartnerApiV1BookingsItemsPackageShowResponses = {
|
|
1502
|
+
200: {
|
|
1503
|
+
data: IssuedPackage;
|
|
1504
|
+
};
|
|
1505
|
+
};
|
|
1506
|
+
type PartnerApiV1BookingsItemsPackageShowResponse = PartnerApiV1BookingsItemsPackageShowResponses[keyof PartnerApiV1BookingsItemsPackageShowResponses];
|
|
1507
|
+
type PartnerApiV1BundlesIndexResponses = {
|
|
1508
|
+
/**
|
|
1509
|
+
* Array of `Bundle`
|
|
1510
|
+
*/
|
|
1511
|
+
200: {
|
|
1512
|
+
data: Array<Bundle>;
|
|
1513
|
+
};
|
|
1514
|
+
};
|
|
1515
|
+
type PartnerApiV1BundlesIndexResponse = PartnerApiV1BundlesIndexResponses[keyof PartnerApiV1BundlesIndexResponses];
|
|
1516
|
+
type PartnerApiV1MeResponses = {
|
|
1517
|
+
/**
|
|
1518
|
+
* `Partner`
|
|
1519
|
+
*/
|
|
1520
|
+
200: {
|
|
1521
|
+
data: Partner;
|
|
1522
|
+
};
|
|
1523
|
+
};
|
|
1524
|
+
type PartnerApiV1MeResponse = PartnerApiV1MeResponses[keyof PartnerApiV1MeResponses];
|
|
1525
|
+
type PartnerApiV1DestinationsData = {
|
|
1526
|
+
body?: never;
|
|
1527
|
+
path?: never;
|
|
1528
|
+
query?: {
|
|
1529
|
+
iso3?: string | null;
|
|
1530
|
+
};
|
|
1531
|
+
url: '/v1/destinations';
|
|
1532
|
+
};
|
|
1533
|
+
type PartnerApiV1DestinationsResponses = {
|
|
1534
|
+
200: {
|
|
1535
|
+
countries: Array<Destination>;
|
|
1536
|
+
regions: Array<Destination>;
|
|
1537
|
+
};
|
|
1538
|
+
};
|
|
1539
|
+
type PartnerApiV1DestinationsResponse = PartnerApiV1DestinationsResponses[keyof PartnerApiV1DestinationsResponses];
|
|
1540
|
+
type PartnerApiV1DestinationsShowResponses = {
|
|
1541
|
+
/**
|
|
1542
|
+
* `DestinationResource`
|
|
1543
|
+
*/
|
|
1544
|
+
200: {
|
|
1545
|
+
data: DestinationResource;
|
|
1546
|
+
};
|
|
1547
|
+
};
|
|
1548
|
+
type PartnerApiV1DestinationsShowResponse = PartnerApiV1DestinationsShowResponses[keyof PartnerApiV1DestinationsShowResponses];
|
|
1549
|
+
type PartnerApiV1DeviceCompatibilityIndexResponses = {
|
|
1550
|
+
/**
|
|
1551
|
+
* `DeviceCompatibilityList`
|
|
1552
|
+
*/
|
|
1553
|
+
200: {
|
|
1554
|
+
data: DeviceCompatibilityList;
|
|
1555
|
+
};
|
|
1556
|
+
};
|
|
1557
|
+
type PartnerApiV1DeviceCompatibilityIndexResponse = PartnerApiV1DeviceCompatibilityIndexResponses[keyof PartnerApiV1DeviceCompatibilityIndexResponses];
|
|
1558
|
+
type PartnerApiV1DeviceCompatibilityCheckResponses = {
|
|
1559
|
+
/**
|
|
1560
|
+
* `DeviceCompatibility`
|
|
1561
|
+
*/
|
|
1562
|
+
200: {
|
|
1563
|
+
data: DeviceCompatibility;
|
|
1564
|
+
};
|
|
1565
|
+
};
|
|
1566
|
+
type PartnerApiV1DeviceCompatibilityCheckResponse = PartnerApiV1DeviceCompatibilityCheckResponses[keyof PartnerApiV1DeviceCompatibilityCheckResponses];
|
|
1567
|
+
type PartnerApiV1EsimsShowResponses = {
|
|
1568
|
+
/**
|
|
1569
|
+
* `Esim`
|
|
1570
|
+
*/
|
|
1571
|
+
200: {
|
|
1572
|
+
data: Esim;
|
|
1573
|
+
};
|
|
1574
|
+
};
|
|
1575
|
+
type PartnerApiV1EsimsShowResponse = PartnerApiV1EsimsShowResponses[keyof PartnerApiV1EsimsShowResponses];
|
|
1576
|
+
type PartnerApiV1EsimsInstructionsResponses = {
|
|
1577
|
+
/**
|
|
1578
|
+
* `InstallInstructions`
|
|
1579
|
+
*/
|
|
1580
|
+
200: {
|
|
1581
|
+
data: InstallInstructions;
|
|
1582
|
+
};
|
|
1583
|
+
};
|
|
1584
|
+
type PartnerApiV1EsimsInstructionsResponse = PartnerApiV1EsimsInstructionsResponses[keyof PartnerApiV1EsimsInstructionsResponses];
|
|
1585
|
+
type PartnerApiV1RedirectTokensCreateResponses = {
|
|
1586
|
+
/**
|
|
1587
|
+
* `RedirectToken`
|
|
1588
|
+
*/
|
|
1589
|
+
200: {
|
|
1590
|
+
data: RedirectToken;
|
|
1591
|
+
};
|
|
1592
|
+
};
|
|
1593
|
+
type PartnerApiV1RedirectTokensCreateResponse = PartnerApiV1RedirectTokensCreateResponses[keyof PartnerApiV1RedirectTokensCreateResponses];
|
|
1594
|
+
|
|
1595
|
+
/**
|
|
1596
|
+
* The types a Partner names: a readable alias for each method's input and
|
|
1597
|
+
* response, over the generated operation types, and the resource types under
|
|
1598
|
+
* their schema names. Every name is listed, never a wildcard (ADR 0058).
|
|
1599
|
+
*/
|
|
1600
|
+
|
|
1601
|
+
/** `createBooking(input)`. */
|
|
1602
|
+
type CreateBookingInput = CreateBookingRequest;
|
|
1603
|
+
/** `updateBooking(id, input)`. */
|
|
1604
|
+
type UpdateBookingInput = UpdateBookingRequest;
|
|
1605
|
+
/** `getBookings(filters?)`. */
|
|
1606
|
+
type BookingListFilters = NonNullable<PartnerApiV1BookingsIndexData['query']>;
|
|
1607
|
+
/** `getDestinations(filters?)`. */
|
|
1608
|
+
type DestinationListFilters = NonNullable<PartnerApiV1DestinationsData['query']>;
|
|
1609
|
+
/** `updatePackageSpecification(bookingId, uuid, input)`: one item's package specification. */
|
|
1610
|
+
type PackageSpecificationInput = UpdatePackageSpecificationRequest;
|
|
1611
|
+
/** `updatePackageSpecifications(bookingId, input)`: every item not yet issued. */
|
|
1612
|
+
type PackageSpecificationsInput = UpdatePackageSpecificationRequest;
|
|
1613
|
+
/** `presignBookingImport(input)`. */
|
|
1614
|
+
type PresignBookingImportInput = PresignBookingUploadData;
|
|
1615
|
+
/** `issuePackage(booking, item, input)`; how to create `idempotencyKey` is on `Hubby.issuePackage`. */
|
|
1616
|
+
type IssuePackageInput = IssuePackageRequest & {
|
|
1617
|
+
idempotencyKey: string;
|
|
1618
|
+
};
|
|
1619
|
+
/** `terminatePackage(booking, item, input?)`. */
|
|
1620
|
+
type TerminatePackageInput = {
|
|
1621
|
+
reason?: PartnerTerminateReason;
|
|
1622
|
+
};
|
|
1623
|
+
/** `getEsim(iccid, input?)`. `refresh: true` reads the eSIM from the network now. */
|
|
1624
|
+
type EsimReadOptions = {
|
|
1625
|
+
refresh?: boolean;
|
|
1626
|
+
};
|
|
1627
|
+
/** `getEsimInstructions(iccid, input?)`. */
|
|
1628
|
+
type EsimInstructionsOptions = {
|
|
1629
|
+
locale?: SupportedLocale;
|
|
1630
|
+
};
|
|
1631
|
+
/** `checkDeviceCompatibility(input)`. */
|
|
1632
|
+
type DeviceCompatibilityInput = CheckDeviceCompatibilityData;
|
|
1633
|
+
/** `createRedirectToken(input)`. */
|
|
1634
|
+
type RedirectTokenInput = CreateRedirectTokenData;
|
|
1635
|
+
/** `getAnalyticsBreakdowns(query?)`: the date range and filters every analytics read takes. */
|
|
1636
|
+
type AnalyticsQuery = NonNullable<PartnerApiV1AnalyticsBreakdownsData['query']>;
|
|
1637
|
+
/** `getAnalyticsSummary(query?)`. */
|
|
1638
|
+
type AnalyticsSummaryQuery = NonNullable<PartnerApiV1AnalyticsSummaryData['query']>;
|
|
1639
|
+
/** `getAnalyticsFunnel(query?)`. */
|
|
1640
|
+
type AnalyticsFunnelQuery = NonNullable<PartnerApiV1AnalyticsFunnelData['query']>;
|
|
1641
|
+
/** `getAnalyticsTimeseries(query?)`. */
|
|
1642
|
+
type AnalyticsTimeseriesQuery = NonNullable<PartnerApiV1AnalyticsTimeseriesData['query']>;
|
|
1643
|
+
/** `getPartner()`. */
|
|
1644
|
+
type PartnerResponse = PartnerApiV1MeResponse;
|
|
1645
|
+
/** `getBundles()` and `getDestinationBundles(code)`. */
|
|
1646
|
+
type BundleListResponse = PartnerApiV1BundlesIndexResponse;
|
|
1647
|
+
/** `getDestinations(filters?)`: countries and regions. */
|
|
1648
|
+
type DestinationListResponse = PartnerApiV1DestinationsResponse;
|
|
1649
|
+
/** `getDestination(code)`. */
|
|
1650
|
+
type DestinationResponse = PartnerApiV1DestinationsShowResponse;
|
|
1651
|
+
/** `createBooking`, `getBooking` and `updateBooking`. */
|
|
1652
|
+
type BookingResponse = PartnerApiV1BookingsShowResponse;
|
|
1653
|
+
/** `getBookings(filters?)`: a page of bookings and its cursors. */
|
|
1654
|
+
type BookingListResponse = PartnerApiV1BookingsIndexResponse;
|
|
1655
|
+
/** `updatePackageSpecification` and `updatePackageSpecifications`. */
|
|
1656
|
+
type PackageSpecificationUpdateResponse = PartnerApiV1BookingsUpdatePackageSpecificationsResponse;
|
|
1657
|
+
/** `presignBookingImport(input)`: where to upload the import file, and how. */
|
|
1658
|
+
type BookingImportPresignResponse = PartnerApiV1BookingsImportsPresignUploadResponse;
|
|
1659
|
+
/** `issuePackage` and `getPackage`. */
|
|
1660
|
+
type PackageResponse = PartnerApiV1BookingsItemsPackageShowResponse;
|
|
1661
|
+
/** `getEsim(iccid, input?)`. */
|
|
1662
|
+
type EsimResponse = PartnerApiV1EsimsShowResponse;
|
|
1663
|
+
/** `getEsimInstructions(iccid, input?)`. */
|
|
1664
|
+
type EsimInstructionsResponse = PartnerApiV1EsimsInstructionsResponse;
|
|
1665
|
+
/** `getCompatibleDevices()`. */
|
|
1666
|
+
type DeviceCompatibilityListResponse = PartnerApiV1DeviceCompatibilityIndexResponse;
|
|
1667
|
+
/** `checkDeviceCompatibility(input)`. */
|
|
1668
|
+
type DeviceCompatibilityResponse = PartnerApiV1DeviceCompatibilityCheckResponse;
|
|
1669
|
+
/** `createRedirectToken(input)`. */
|
|
1670
|
+
type RedirectTokenResponse = PartnerApiV1RedirectTokensCreateResponse;
|
|
1671
|
+
/** `getAnalyticsSummary(query?)`. */
|
|
1672
|
+
type AnalyticsSummaryResponse = PartnerApiV1AnalyticsSummaryResponse;
|
|
1673
|
+
/** `getAnalyticsFunnel(query?)`. */
|
|
1674
|
+
type AnalyticsFunnelResponse = PartnerApiV1AnalyticsFunnelResponse;
|
|
1675
|
+
/** `getAnalyticsTimeseries(query?)`. */
|
|
1676
|
+
type AnalyticsTimeseriesResponse = PartnerApiV1AnalyticsTimeseriesResponse;
|
|
1677
|
+
/** `getAnalyticsBreakdowns(query?)`. */
|
|
1678
|
+
type AnalyticsBreakdownsResponse = PartnerApiV1AnalyticsBreakdownsResponse;
|
|
1679
|
+
|
|
1680
|
+
type HubbyOptions = Omit<SigningClientOptions, 'baseUrl'> & {
|
|
1681
|
+
/** Default `https://core.hubbyesim.com/api`; staging is `https://core-staging.hubbyesim.com/api`. */
|
|
1682
|
+
baseUrl?: string;
|
|
1683
|
+
};
|
|
1684
|
+
/** Options every method takes last. */
|
|
1685
|
+
type RequestOptions = {
|
|
1686
|
+
/** Aborts the call, a retry wait included; the call rejects with the signal's reason. */
|
|
1687
|
+
signal?: AbortSignal;
|
|
1688
|
+
/** Extra headers sent with the call. A `User-Agent` here replaces the SDK's. */
|
|
1689
|
+
headers?: Record<string, string>;
|
|
1690
|
+
};
|
|
1691
|
+
/**
|
|
1692
|
+
* The Partner API v1 client: one method per operation, each returning the
|
|
1693
|
+
* response body as the Partner guide documents it. Every request is signed.
|
|
1694
|
+
*/
|
|
1695
|
+
declare class Hubby {
|
|
1696
|
+
#private;
|
|
1697
|
+
constructor(options: HubbyOptions);
|
|
1698
|
+
/** `GET /v1/me`: the Partner the API key belongs to, and its settings. */
|
|
1699
|
+
getPartner(options?: RequestOptions): Promise<PartnerResponse>;
|
|
1700
|
+
/** `GET /v1/bundles`: the Bundles you sell. */
|
|
1701
|
+
getBundles(options?: RequestOptions): Promise<BundleListResponse>;
|
|
1702
|
+
/**
|
|
1703
|
+
* `POST /v1/bookings`: creates a booking. The SDK gives the call an
|
|
1704
|
+
* `Idempotency-Key` and keeps it across its retries.
|
|
1705
|
+
*/
|
|
1706
|
+
createBooking(input: CreateBookingInput, options?: RequestOptions): Promise<BookingResponse>;
|
|
1707
|
+
/**
|
|
1708
|
+
* `POST /v1/bookings/{booking}/items/{item}/package`: issues the item's
|
|
1709
|
+
* package. Create `idempotencyKey` once per issue attempt and store it with
|
|
1710
|
+
* your own purchase record before the call, so a retry after a crash
|
|
1711
|
+
* replays rather than issues again. After a terminate, the next issue of
|
|
1712
|
+
* the item needs a new key.
|
|
1713
|
+
*/
|
|
1714
|
+
issuePackage(booking: string, item: string, input: IssuePackageInput, options?: RequestOptions): Promise<PackageResponse>;
|
|
1715
|
+
/** `GET /v1/bookings/{booking}/items/{item}/package`: the package issued for the item. */
|
|
1716
|
+
getPackage(booking: string, item: string, options?: RequestOptions): Promise<PackageResponse>;
|
|
1717
|
+
/**
|
|
1718
|
+
* `DELETE /v1/bookings/{booking}/items/{item}/package`: terminates the
|
|
1719
|
+
* item's package. Resolves once the Partner API answers `204`. Not retried
|
|
1720
|
+
* after a network error: read the package to learn whether it ended.
|
|
1721
|
+
*/
|
|
1722
|
+
terminatePackage(booking: string, item: string, input?: TerminatePackageInput, options?: RequestOptions): Promise<void>;
|
|
1723
|
+
/**
|
|
1724
|
+
* `GET /v1/esims/{iccid}`: the eSIM and its packages. `refresh: true` reads
|
|
1725
|
+
* it from the network now instead of answering the last readout; it is
|
|
1726
|
+
* rate-limited per Partner.
|
|
1727
|
+
*/
|
|
1728
|
+
getEsim(iccid: string, input?: EsimReadOptions, options?: RequestOptions): Promise<EsimResponse>;
|
|
1729
|
+
/** `GET /v1/destinations`: the destinations, filtered by `iso3` when given. */
|
|
1730
|
+
getDestinations(filters?: DestinationListFilters, options?: RequestOptions): Promise<DestinationListResponse>;
|
|
1731
|
+
/**
|
|
1732
|
+
* `GET /v1/destinations/{destination}`: one destination.
|
|
1733
|
+
*
|
|
1734
|
+
* @param destination a ULID, an ISO alpha-2 or alpha-3 code, or a name
|
|
1735
|
+
* (English, exact, any letter case).
|
|
1736
|
+
*/
|
|
1737
|
+
getDestination(destination: string, options?: RequestOptions): Promise<DestinationResponse>;
|
|
1738
|
+
/**
|
|
1739
|
+
* `GET /v1/destinations/{destination}/bundles`: the Bundles you sell for one destination.
|
|
1740
|
+
*
|
|
1741
|
+
* @param destination a ULID, an ISO alpha-2 or alpha-3 code, or a name
|
|
1742
|
+
* (English, exact, any letter case).
|
|
1743
|
+
*/
|
|
1744
|
+
getDestinationBundles(destination: string, options?: RequestOptions): Promise<BundleListResponse>;
|
|
1745
|
+
/** `GET /v1/bookings`: a page of your bookings, filtered and sorted. Pass `pagination.nextCursor` back as `cursor` for the next page. */
|
|
1746
|
+
getBookings(filters?: BookingListFilters, options?: RequestOptions): Promise<BookingListResponse>;
|
|
1747
|
+
/** `GET /v1/bookings/{id}`: one booking, by any identifier the guide lists. */
|
|
1748
|
+
getBooking(id: string, options?: RequestOptions): Promise<BookingResponse>;
|
|
1749
|
+
/** `PATCH /v1/bookings/{id}`: changes a booking. Not retried after a network error. */
|
|
1750
|
+
updateBooking(id: string, input: UpdateBookingInput, options?: RequestOptions): Promise<BookingResponse>;
|
|
1751
|
+
/**
|
|
1752
|
+
* `DELETE /v1/bookings/{id}`: cancels the booking (a Booking cancellation).
|
|
1753
|
+
* Resolves once the Partner API accepts it. Not retried after a network
|
|
1754
|
+
* error: read the booking to learn whether it was cancelled.
|
|
1755
|
+
*/
|
|
1756
|
+
cancelBooking(id: string, options?: RequestOptions): Promise<void>;
|
|
1757
|
+
/**
|
|
1758
|
+
* `PATCH /v1/bookings/{booking_id}/package-specifications/{uuid}`: changes
|
|
1759
|
+
* the package specification of one item, by its package queue `uuid`.
|
|
1760
|
+
*/
|
|
1761
|
+
updatePackageSpecification(bookingId: string, uuid: string, input: PackageSpecificationInput, options?: RequestOptions): Promise<PackageSpecificationUpdateResponse>;
|
|
1762
|
+
/**
|
|
1763
|
+
* `PATCH /v1/bookings/{booking_id}/package-specifications`: changes the
|
|
1764
|
+
* package specification of every item of the booking not yet issued.
|
|
1765
|
+
*/
|
|
1766
|
+
updatePackageSpecifications(bookingId: string, input: PackageSpecificationsInput, options?: RequestOptions): Promise<PackageSpecificationUpdateResponse>;
|
|
1767
|
+
/** `POST /v1/bookings/imports/presign-upload`: a URL to upload a booking import file to. */
|
|
1768
|
+
presignBookingImport(input: PresignBookingImportInput, options?: RequestOptions): Promise<BookingImportPresignResponse>;
|
|
1769
|
+
/**
|
|
1770
|
+
* `GET /v1/esims/{iccid}/instructions`: how to install the eSIM, in `locale`
|
|
1771
|
+
* when given, else in the locale of the booking that issued it.
|
|
1772
|
+
*/
|
|
1773
|
+
getEsimInstructions(iccid: string, input?: EsimInstructionsOptions, options?: RequestOptions): Promise<EsimInstructionsResponse>;
|
|
1774
|
+
/** `GET /v1/device-compatibility`: the devices that take an eSIM. */
|
|
1775
|
+
getCompatibleDevices(options?: RequestOptions): Promise<DeviceCompatibilityListResponse>;
|
|
1776
|
+
/** `POST /v1/device-compatibility`: whether one device takes an eSIM. */
|
|
1777
|
+
checkDeviceCompatibility(input: DeviceCompatibilityInput, options?: RequestOptions): Promise<DeviceCompatibilityResponse>;
|
|
1778
|
+
/** `POST /v1/redirect-tokens`: a redirect token that signs one of your travellers in, creating their Customer on first use. */
|
|
1779
|
+
createRedirectToken(input: RedirectTokenInput, options?: RequestOptions): Promise<RedirectTokenResponse>;
|
|
1780
|
+
/** `GET /v1/analytics/summary`: the totals for a date range, with the preceding period when `compare` is set. */
|
|
1781
|
+
getAnalyticsSummary(query?: AnalyticsSummaryQuery, options?: RequestOptions): Promise<AnalyticsSummaryResponse>;
|
|
1782
|
+
/** `GET /v1/analytics/funnel`: booking codes issued through to first data used, split by `dimension` when given. */
|
|
1783
|
+
getAnalyticsFunnel(query?: AnalyticsFunnelQuery, options?: RequestOptions): Promise<AnalyticsFunnelResponse>;
|
|
1784
|
+
/** `GET /v1/analytics/timeseries`: the totals per `bucket` (day, week or month). */
|
|
1785
|
+
getAnalyticsTimeseries(query?: AnalyticsTimeseriesQuery, options?: RequestOptions): Promise<AnalyticsTimeseriesResponse>;
|
|
1786
|
+
/** `GET /v1/analytics/breakdowns`: the totals split by each dimension. */
|
|
1787
|
+
getAnalyticsBreakdowns(query?: AnalyticsQuery, options?: RequestOptions): Promise<AnalyticsBreakdownsResponse>;
|
|
1788
|
+
}
|
|
1789
|
+
|
|
1790
|
+
/**
|
|
1791
|
+
* A non-2xx answer from the Partner API. Branch on `status` and `code` (the
|
|
1792
|
+
* refusal code the Partner guide lists); `errors` holds a `422`'s field errors.
|
|
1793
|
+
* A failure with no answer (a network error once the retries run out, or an
|
|
1794
|
+
* abort) is not a `HubbyApiError`: it rejects with the underlying error.
|
|
1795
|
+
*/
|
|
1796
|
+
declare class HubbyApiError extends Error {
|
|
1797
|
+
readonly status: number;
|
|
1798
|
+
/** The refusal code, when the body has one, for example `idempotency_key_in_use`. */
|
|
1799
|
+
readonly code: string | undefined;
|
|
1800
|
+
/** The field errors of a `422`, keyed by field; absent when the body's `errors` has another shape. */
|
|
1801
|
+
readonly errors: Record<string, string[]> | undefined;
|
|
1802
|
+
/** The parsed error body: JSON when it parses, else the text. */
|
|
1803
|
+
readonly body: unknown;
|
|
1804
|
+
readonly response: Response;
|
|
1805
|
+
constructor(response: Response, body: unknown);
|
|
1806
|
+
}
|
|
1807
|
+
|
|
1808
|
+
/** The version tag every Partner API v1 signature binds. */
|
|
1809
|
+
declare const SIGNATURE_VERSION = "HUBBY-HMAC-SHA256-v1";
|
|
1810
|
+
type SignableRequest = {
|
|
1811
|
+
method: string;
|
|
1812
|
+
/** The absolute URL the request goes to. */
|
|
1813
|
+
url: string;
|
|
1814
|
+
/** Unix time in seconds. */
|
|
1815
|
+
timestamp: number;
|
|
1816
|
+
/** The exact bytes sent; empty for a request without a body. */
|
|
1817
|
+
body: Uint8Array;
|
|
1818
|
+
};
|
|
1819
|
+
/**
|
|
1820
|
+
* The lowercase hex `X-Signature` for a request.
|
|
1821
|
+
*
|
|
1822
|
+
* The canonical string is six lines: the version tag, the method, the host, the
|
|
1823
|
+
* request URI as sent (path plus query string), the timestamp and the SHA-256 of
|
|
1824
|
+
* the body. The WHATWG URL already lowercases the host and drops a default port,
|
|
1825
|
+
* which is how core reads the host back.
|
|
1826
|
+
*/
|
|
1827
|
+
declare function signRequest(secret: string, request: SignableRequest): Promise<string>;
|
|
1828
|
+
|
|
1829
|
+
/** The envelope of every webhook delivery. `data` is the event body. */
|
|
1830
|
+
type WebhookEvent<TData = Record<string, unknown>> = {
|
|
1831
|
+
event: string;
|
|
1832
|
+
timestamp: string;
|
|
1833
|
+
data: TData;
|
|
1834
|
+
/** Deduplicate on this: a retried delivery repeats it. */
|
|
1835
|
+
event_id: string;
|
|
1836
|
+
delivery_id: string;
|
|
1837
|
+
};
|
|
1838
|
+
type WebhookVerificationFailure = 'missing_signature' | 'missing_timestamp' | 'stale_timestamp' | 'invalid_signature' | 'invalid_body';
|
|
1839
|
+
declare class WebhookVerificationError extends Error {
|
|
1840
|
+
readonly reason: WebhookVerificationFailure;
|
|
1841
|
+
constructor(reason: WebhookVerificationFailure, message: string);
|
|
1842
|
+
}
|
|
1843
|
+
/** A `Headers`, or a plain object such as Node's `IncomingMessage.headers`. */
|
|
1844
|
+
type WebhookHeaders = Headers | Record<string, string | string[] | undefined>;
|
|
1845
|
+
type VerifyWebhookOptions = {
|
|
1846
|
+
/** The signing secret configured for your endpoint. */
|
|
1847
|
+
secret: string;
|
|
1848
|
+
/** The raw request body, exactly as received. Not a parsed object. */
|
|
1849
|
+
body: string | Uint8Array;
|
|
1850
|
+
headers: WebhookHeaders;
|
|
1851
|
+
/** How far `x-hubby-timestamp` may be from now, either way. Default 300. */
|
|
1852
|
+
toleranceSeconds?: number;
|
|
1853
|
+
/** Epoch milliseconds. Default: `Date.now`. */
|
|
1854
|
+
now?: () => number;
|
|
1855
|
+
};
|
|
1856
|
+
declare const DEFAULT_WEBHOOK_TOLERANCE_SECONDS = 300;
|
|
1857
|
+
/**
|
|
1858
|
+
* Verifies a webhook delivery and returns its parsed envelope, or throws a
|
|
1859
|
+
* `WebhookVerificationError` naming why it was refused.
|
|
1860
|
+
*
|
|
1861
|
+
* `x-hubby-signature` is a comma-separated list of `sha256=` plus the hex
|
|
1862
|
+
* HMAC-SHA256 of `{x-hubby-timestamp}.{raw body}`; any one matching entry is
|
|
1863
|
+
* enough, so a secret can rotate without dropping deliveries. Every entry is
|
|
1864
|
+
* compared in constant time.
|
|
1865
|
+
*/
|
|
1866
|
+
declare function verifyWebhook<TData = Record<string, unknown>>(options: VerifyWebhookOptions): Promise<WebhookEvent<TData>>;
|
|
1867
|
+
|
|
1868
|
+
/**
|
|
1869
|
+
* The Partner API version this SDK release is generated from and tested
|
|
1870
|
+
* against. The SDK has its own semver; this names the API it speaks.
|
|
1871
|
+
*
|
|
1872
|
+
* scripts/check-api-version.mjs reads this line and fails CI when the exported
|
|
1873
|
+
* Partner document's `info.version` differs, so keep it a single-quoted literal.
|
|
1874
|
+
*/
|
|
1875
|
+
declare const SUPPORTED_API_VERSION = "5.13.0";
|
|
1876
|
+
|
|
1877
|
+
export { type AnalyticsActivation, type AnalyticsBreakdowns, type AnalyticsBreakdownsResponse, type AnalyticsBundleSizeCount, type AnalyticsDestinationCount, type AnalyticsDiscountCode, type AnalyticsFunnel, type AnalyticsFunnelGroup, type AnalyticsFunnelQuery, type AnalyticsFunnelResponse, type AnalyticsFunnelStep, type AnalyticsMeta, type AnalyticsPartnerContribution, type AnalyticsQuery, type AnalyticsRatio, type AnalyticsSummary, type AnalyticsSummaryQuery, type AnalyticsSummaryResponse, type AnalyticsTimeseries, type AnalyticsTimeseriesBucket, type AnalyticsTimeseriesQuery, type AnalyticsTimeseriesResponse, type Booking, type BookingImportPresignResponse, type BookingItem, type BookingListFilters, type BookingListResponse, type BookingResponse, type BookingSource, type Bundle, type BundleListResponse, type CommunicationChannel, type CreateBookingInput, DEFAULT_WEBHOOK_TOLERANCE_SECONDS, type Destination, type DestinationListFilters, type DestinationListResponse, type DestinationResource, type DestinationResponse, type DeviceCompatibility, type DeviceCompatibilityInput, type DeviceCompatibilityList, type DeviceCompatibilityListResponse, type DeviceCompatibilityResponse, type EndCustomerChannel, type Esim, type EsimInstallMaterial, type EsimInstructionsOptions, type EsimInstructionsResponse, type EsimPackage, type EsimReadOptions, type EsimResponse, type FairUseThrottle, type FairUseThrottleReset, Hubby, HubbyApiError, type HubbyOptions, type InstallInstructionSection, type InstallInstructionSet, type InstallInstructionStep, type InstallInstructions, type IssuePackageInput, type IssuedPackage, type PackageLifecycleState, type PackageQueueStatus, type PackageResponse, type PackageSpecificationInput, type PackageSpecificationUpdateResponse, type PackageSpecificationsInput, type PackageType, type Partner, type PartnerResponse, type PartnerTerminateReason, type PresignBookingImportInput, type RedirectToken, type RedirectTokenInput, type RedirectTokenResponse, type RequestOptions, type RetryOptions, SIGNATURE_VERSION, SUPPORTED_API_VERSION, type SignableRequest, type SupportedLocale, type TerminatePackageInput, type UpdateBookingInput, type VerifyWebhookOptions, type WebhookEvent, type WebhookHeaders, WebhookVerificationError, type WebhookVerificationFailure, signRequest, verifyWebhook };
|