@isnap/sdk 1.3.0-next.17 → 1.3.0-next.170
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 +3 -0
- package/README.md +1 -1
- package/dist/client.d.ts +2 -0
- package/dist/client.d.ts.map +1 -1
- package/dist/client.js +3 -0
- package/dist/client.js.map +1 -1
- package/dist/generated/openapi.d.ts +1968 -898
- package/dist/index.d.ts +5 -3
- package/dist/index.d.ts.map +1 -1
- package/dist/index.js +2 -1
- package/dist/index.js.map +1 -1
- package/dist/resources/apps.d.ts +11 -4
- package/dist/resources/apps.d.ts.map +1 -1
- package/dist/resources/apps.js +11 -4
- package/dist/resources/apps.js.map +1 -1
- package/dist/resources/lines.d.ts +94 -4
- package/dist/resources/lines.d.ts.map +1 -1
- package/dist/resources/lines.js +100 -4
- package/dist/resources/lines.js.map +1 -1
- package/dist/resources/macos-sessions.d.ts +48 -0
- package/dist/resources/macos-sessions.d.ts.map +1 -0
- package/dist/resources/macos-sessions.js +51 -0
- package/dist/resources/macos-sessions.js.map +1 -0
- package/dist/resources/preorders.d.ts +19 -7
- package/dist/resources/preorders.d.ts.map +1 -1
- package/dist/resources/preorders.js +19 -7
- package/dist/resources/preorders.js.map +1 -1
- package/dist/version.d.ts +1 -1
- package/dist/version.d.ts.map +1 -1
- package/dist/version.js +12 -4
- package/dist/version.js.map +1 -1
- package/dist/webhooks/types.d.ts +34 -3
- package/dist/webhooks/types.d.ts.map +1 -1
- package/dist/webhooks/types.js +3 -0
- package/dist/webhooks/types.js.map +1 -1
- package/package.json +1 -1
|
@@ -387,7 +387,7 @@ export interface paths {
|
|
|
387
387
|
};
|
|
388
388
|
/**
|
|
389
389
|
* List available lines (public marketplace)
|
|
390
|
-
* @description Browse the marketplace inventory of unassigned lines. Filter by billing tier, area code, country code,
|
|
390
|
+
* @description Browse the marketplace inventory of unassigned lines. Filter by billing tier, area code, country code, state, country. Returns only `status: available` and never the iSnap-internal `shared_pool` tier — `?status=` therefore accepts `available` alone and refuses any other status with a 400, rather than answering with a list you did not ask for (WHA-2777). Unauthenticated — partners use this in prospecting / quote flows.
|
|
391
391
|
*/
|
|
392
392
|
get: {
|
|
393
393
|
parameters: {
|
|
@@ -399,6 +399,7 @@ export interface paths {
|
|
|
399
399
|
state?: string;
|
|
400
400
|
/** @description Country filter — ISO alpha-2 code or country name. */
|
|
401
401
|
country?: string;
|
|
402
|
+
/** @description Comma-separated set of statuses to filter on. Every member must be one of: available — anything else is a 400, never an empty list. Omitted or blank means no status filter. */
|
|
402
403
|
status?: string;
|
|
403
404
|
page?: number;
|
|
404
405
|
limit?: number;
|
|
@@ -551,7 +552,7 @@ export interface paths {
|
|
|
551
552
|
};
|
|
552
553
|
/**
|
|
553
554
|
* Get line details (public marketplace)
|
|
554
|
-
* @description Fetch a single line by its `line_<base62>` id. Available unauthenticated for the marketplace browsing flow
|
|
555
|
+
* @description Fetch a single line by its `line_<base62>` id. Available unauthenticated for the marketplace browsing flow, where the `phone_number` is masked so the inventory cannot be scraped. Authenticate with your API key (or dashboard JWT) and, when you own the line, the `phone_number` comes back unmasked — the same full number `GET /v1/lines/my` returns (WHA-3030). A credential that does not own the line, or none at all, still gets the masked number.
|
|
555
556
|
*/
|
|
556
557
|
get: {
|
|
557
558
|
parameters: {
|
|
@@ -1059,7 +1060,7 @@ export interface paths {
|
|
|
1059
1060
|
put?: never;
|
|
1060
1061
|
/**
|
|
1061
1062
|
* Activate a reserved line
|
|
1062
|
-
* @description Commit a `reserved` line to `active`. Wholesale partners (no Stripe checkout surface)
|
|
1063
|
+
* @description Commit a `reserved` line to `active`. **Wholesale partners only** (no Stripe checkout surface): this is the second phase of reserve→activate — they reserve, bill their own end-user, then activate within the 15-minute window with no per-line Stripe sub (EOM-metered), and may pick the INBOUND product via `inbound_only` (a line that cannot initiate — the contact must message first, after which the exchange is unrestricted; not receive-only). Direct customers get `402 checkout_required`: their line is activated by the `checkout.session.completed` webhook once `POST /v1/billing/checkout` is paid, which is what mints the Stripe subscription that bills them (§2.5 Flow A). `inbound_only` is meaningless for them — theirs comes from the checkout price.
|
|
1063
1064
|
*/
|
|
1064
1065
|
post: {
|
|
1065
1066
|
parameters: {
|
|
@@ -1109,6 +1110,15 @@ export interface paths {
|
|
|
1109
1110
|
"application/json": components["schemas"]["ErrorEnvelope"];
|
|
1110
1111
|
};
|
|
1111
1112
|
};
|
|
1113
|
+
/** @description Payment required — no billing relationship entitles this call */
|
|
1114
|
+
402: {
|
|
1115
|
+
headers: {
|
|
1116
|
+
[name: string]: unknown;
|
|
1117
|
+
};
|
|
1118
|
+
content: {
|
|
1119
|
+
"application/json": components["schemas"]["ErrorEnvelope"];
|
|
1120
|
+
};
|
|
1121
|
+
};
|
|
1112
1122
|
/** @description Forbidden — caller authenticated but not allowed */
|
|
1113
1123
|
403: {
|
|
1114
1124
|
headers: {
|
|
@@ -1496,7 +1506,7 @@ export interface paths {
|
|
|
1496
1506
|
patch?: never;
|
|
1497
1507
|
trace?: never;
|
|
1498
1508
|
};
|
|
1499
|
-
"/v1/lines/{id}/
|
|
1509
|
+
"/v1/lines/{id}/terminate": {
|
|
1500
1510
|
parameters: {
|
|
1501
1511
|
query?: never;
|
|
1502
1512
|
header?: never;
|
|
@@ -1506,8 +1516,8 @@ export interface paths {
|
|
|
1506
1516
|
get?: never;
|
|
1507
1517
|
put?: never;
|
|
1508
1518
|
/**
|
|
1509
|
-
*
|
|
1510
|
-
* @description
|
|
1519
|
+
* Terminate a line you own
|
|
1520
|
+
* @description Permanently END an active line the caller owns — the self-serve counterpart to the admin terminate. Use this when your own customer cancels: `/release` only returns a *reserved* marketplace line to the shelf, while this ends a live `rental` line or a virtual `shared` line for good. The line flips to the terminal `cancelled` status and keeps its owner (who held it when it died is history, not a shelf return); queued messages fail with `carrier_terminated`, shared-fleet bindings are released (`binding.released`), device sessions are revoked, and `line.disconnected` fires with `reason: customer_initiated`. Billing stops in both shapes: a per-line Stripe subscription is cancelled immediately (not at period end), and a wholesale partner's end-of-month active-line count drops the line in the same breath. Dedicated hardware goes back to iSnap stock — the eSIM and Apple ID are recycled, never scrapped, because a customer ending a rental says nothing about whether the carrier plan is still good. **Idempotent**: terminating an already-terminated line returns 200 with the line unchanged and fires nothing a second time. Only an `active` or `suspended` line — the ones you are actually being billed for — is terminable: a merely `reserved` line is a 15-minute hold you give back with `/release`, and a `provisioning` pre-order line is cancelled through `/v1/pre-orders/{id}/cancel`. BYOD lines are refused (400) — that hardware is yours and is billed per device slot by `/v1/byod/*`; owned test lines are refused (403) until converted back with `/convert-from-test`.
|
|
1511
1521
|
*/
|
|
1512
1522
|
post: {
|
|
1513
1523
|
parameters: {
|
|
@@ -1518,9 +1528,13 @@ export interface paths {
|
|
|
1518
1528
|
};
|
|
1519
1529
|
cookie?: never;
|
|
1520
1530
|
};
|
|
1521
|
-
requestBody?:
|
|
1531
|
+
requestBody?: {
|
|
1532
|
+
content: {
|
|
1533
|
+
"application/json": components["schemas"]["TerminateLine"];
|
|
1534
|
+
};
|
|
1535
|
+
};
|
|
1522
1536
|
responses: {
|
|
1523
|
-
/** @description Line
|
|
1537
|
+
/** @description Line terminated (or already terminated — the call is idempotent). Returns the line at its terminal `cancelled` status. */
|
|
1524
1538
|
200: {
|
|
1525
1539
|
headers: {
|
|
1526
1540
|
[name: string]: unknown;
|
|
@@ -1571,6 +1585,15 @@ export interface paths {
|
|
|
1571
1585
|
"application/json": components["schemas"]["ErrorEnvelope"];
|
|
1572
1586
|
};
|
|
1573
1587
|
};
|
|
1588
|
+
/** @description Conflict — concurrent or terminal state */
|
|
1589
|
+
409: {
|
|
1590
|
+
headers: {
|
|
1591
|
+
[name: string]: unknown;
|
|
1592
|
+
};
|
|
1593
|
+
content: {
|
|
1594
|
+
"application/json": components["schemas"]["ErrorEnvelope"];
|
|
1595
|
+
};
|
|
1596
|
+
};
|
|
1574
1597
|
/** @description Too many requests — rate limit exceeded */
|
|
1575
1598
|
429: {
|
|
1576
1599
|
headers: {
|
|
@@ -1597,18 +1620,20 @@ export interface paths {
|
|
|
1597
1620
|
patch?: never;
|
|
1598
1621
|
trace?: never;
|
|
1599
1622
|
};
|
|
1600
|
-
"/v1/lines/{id}/
|
|
1623
|
+
"/v1/lines/{id}/cancel": {
|
|
1601
1624
|
parameters: {
|
|
1602
1625
|
query?: never;
|
|
1603
1626
|
header?: never;
|
|
1604
1627
|
path?: never;
|
|
1605
1628
|
cookie?: never;
|
|
1606
1629
|
};
|
|
1630
|
+
get?: never;
|
|
1631
|
+
put?: never;
|
|
1607
1632
|
/**
|
|
1608
|
-
*
|
|
1609
|
-
* @description
|
|
1633
|
+
* Cancel a line at its next billing anniversary
|
|
1634
|
+
* @description Schedule the END of a line you own for its next billing anniversary, and keep using it until then. This is the verb for "my own customer cancelled": the month is already paid for and iSnap never prorates, so terminating on the spot would destroy days you have bought. The line stays fully `active` — it sends, receives and bills exactly as before — and iSnap terminates it itself when `cancel_at` arrives, firing `line.terminated` with `origin: scheduled_cancellation`. The date is the next occurrence of `anniversary_at` strictly after now, clamped to the last day of a shorter month (a line taken on the 31st renews on the 28th in February and on the 31st again in March — the clamp never sticks). **Idempotent**: cancelling an already-cancelled line returns the SAME `cancel_at`, never a recomputed one, so a retry that happens to cross the anniversary cannot push your own cancellation a month into the future. Undo it with `/uncancel` any time before the date. Refused with 409 `line_has_no_anniversary` on a line that has none — state it with `/anniversary`, or end the line now with `/terminate`.
|
|
1610
1635
|
*/
|
|
1611
|
-
|
|
1636
|
+
post: {
|
|
1612
1637
|
parameters: {
|
|
1613
1638
|
query?: never;
|
|
1614
1639
|
header?: never;
|
|
@@ -1619,13 +1644,19 @@ export interface paths {
|
|
|
1619
1644
|
};
|
|
1620
1645
|
requestBody?: never;
|
|
1621
1646
|
responses: {
|
|
1622
|
-
/** @description
|
|
1647
|
+
/** @description Cancellation scheduled (or already scheduled — the call is idempotent). Returns the line, still `active`, with `cancel_at` set. */
|
|
1623
1648
|
200: {
|
|
1624
1649
|
headers: {
|
|
1625
1650
|
[name: string]: unknown;
|
|
1626
1651
|
};
|
|
1627
1652
|
content: {
|
|
1628
|
-
"application/json":
|
|
1653
|
+
"application/json": {
|
|
1654
|
+
/** @enum {boolean} */
|
|
1655
|
+
success: true;
|
|
1656
|
+
data: components["schemas"]["Line"];
|
|
1657
|
+
trace_id: string;
|
|
1658
|
+
request_id: string;
|
|
1659
|
+
};
|
|
1629
1660
|
};
|
|
1630
1661
|
};
|
|
1631
1662
|
/** @description Bad request — validation failed */
|
|
@@ -1664,6 +1695,15 @@ export interface paths {
|
|
|
1664
1695
|
"application/json": components["schemas"]["ErrorEnvelope"];
|
|
1665
1696
|
};
|
|
1666
1697
|
};
|
|
1698
|
+
/** @description Conflict — concurrent or terminal state */
|
|
1699
|
+
409: {
|
|
1700
|
+
headers: {
|
|
1701
|
+
[name: string]: unknown;
|
|
1702
|
+
};
|
|
1703
|
+
content: {
|
|
1704
|
+
"application/json": components["schemas"]["ErrorEnvelope"];
|
|
1705
|
+
};
|
|
1706
|
+
};
|
|
1667
1707
|
/** @description Too many requests — rate limit exceeded */
|
|
1668
1708
|
429: {
|
|
1669
1709
|
headers: {
|
|
@@ -1684,32 +1724,28 @@ export interface paths {
|
|
|
1684
1724
|
};
|
|
1685
1725
|
};
|
|
1686
1726
|
};
|
|
1687
|
-
put?: never;
|
|
1688
|
-
post?: never;
|
|
1689
1727
|
delete?: never;
|
|
1690
1728
|
options?: never;
|
|
1691
1729
|
head?: never;
|
|
1692
1730
|
patch?: never;
|
|
1693
1731
|
trace?: never;
|
|
1694
1732
|
};
|
|
1695
|
-
"/v1/lines/{id}/
|
|
1733
|
+
"/v1/lines/{id}/uncancel": {
|
|
1696
1734
|
parameters: {
|
|
1697
1735
|
query?: never;
|
|
1698
1736
|
header?: never;
|
|
1699
1737
|
path?: never;
|
|
1700
1738
|
cookie?: never;
|
|
1701
1739
|
};
|
|
1740
|
+
get?: never;
|
|
1741
|
+
put?: never;
|
|
1702
1742
|
/**
|
|
1703
|
-
*
|
|
1704
|
-
* @description
|
|
1743
|
+
* Undo a scheduled cancellation
|
|
1744
|
+
* @description Clear a pending cancellation: `cancel_at` goes back to `null` and the line resumes renewing at its anniversary like any other. Nothing about the line changed while it was cancelled — it never stopped working — so there is nothing to restore. **A no-op on a line that is not cancelled**: 200 with the line and `cancel_at: null`, which is the honest answer to "make sure this line is not cancelled" and lets a reconciliation loop run without treating its own success as an error. Refused with 409 `line_already_terminated` once the anniversary has passed and iSnap has ended the line — that cannot be undone; order a new line instead.
|
|
1705
1745
|
*/
|
|
1706
|
-
|
|
1746
|
+
post: {
|
|
1707
1747
|
parameters: {
|
|
1708
|
-
query?:
|
|
1709
|
-
limit?: number;
|
|
1710
|
-
cursor?: string;
|
|
1711
|
-
status?: "queued" | "scheduled" | "delivered_to_device";
|
|
1712
|
-
};
|
|
1748
|
+
query?: never;
|
|
1713
1749
|
header?: never;
|
|
1714
1750
|
path: {
|
|
1715
1751
|
id: string;
|
|
@@ -1718,13 +1754,19 @@ export interface paths {
|
|
|
1718
1754
|
};
|
|
1719
1755
|
requestBody?: never;
|
|
1720
1756
|
responses: {
|
|
1721
|
-
/** @description
|
|
1757
|
+
/** @description Cancellation cleared, or the line was not cancelled. Returns the line with `cancel_at: null`. */
|
|
1722
1758
|
200: {
|
|
1723
1759
|
headers: {
|
|
1724
1760
|
[name: string]: unknown;
|
|
1725
1761
|
};
|
|
1726
1762
|
content: {
|
|
1727
|
-
"application/json":
|
|
1763
|
+
"application/json": {
|
|
1764
|
+
/** @enum {boolean} */
|
|
1765
|
+
success: true;
|
|
1766
|
+
data: components["schemas"]["Line"];
|
|
1767
|
+
trace_id: string;
|
|
1768
|
+
request_id: string;
|
|
1769
|
+
};
|
|
1728
1770
|
};
|
|
1729
1771
|
};
|
|
1730
1772
|
/** @description Bad request — validation failed */
|
|
@@ -1763,6 +1805,15 @@ export interface paths {
|
|
|
1763
1805
|
"application/json": components["schemas"]["ErrorEnvelope"];
|
|
1764
1806
|
};
|
|
1765
1807
|
};
|
|
1808
|
+
/** @description Conflict — concurrent or terminal state */
|
|
1809
|
+
409: {
|
|
1810
|
+
headers: {
|
|
1811
|
+
[name: string]: unknown;
|
|
1812
|
+
};
|
|
1813
|
+
content: {
|
|
1814
|
+
"application/json": components["schemas"]["ErrorEnvelope"];
|
|
1815
|
+
};
|
|
1816
|
+
};
|
|
1766
1817
|
/** @description Too many requests — rate limit exceeded */
|
|
1767
1818
|
429: {
|
|
1768
1819
|
headers: {
|
|
@@ -1783,26 +1834,26 @@ export interface paths {
|
|
|
1783
1834
|
};
|
|
1784
1835
|
};
|
|
1785
1836
|
};
|
|
1786
|
-
put?: never;
|
|
1787
|
-
post?: never;
|
|
1788
1837
|
delete?: never;
|
|
1789
1838
|
options?: never;
|
|
1790
1839
|
head?: never;
|
|
1791
1840
|
patch?: never;
|
|
1792
1841
|
trace?: never;
|
|
1793
1842
|
};
|
|
1794
|
-
"/v1/lines/{id}/
|
|
1843
|
+
"/v1/lines/{id}/anniversary": {
|
|
1795
1844
|
parameters: {
|
|
1796
1845
|
query?: never;
|
|
1797
1846
|
header?: never;
|
|
1798
1847
|
path?: never;
|
|
1799
1848
|
cookie?: never;
|
|
1800
1849
|
};
|
|
1850
|
+
get?: never;
|
|
1851
|
+
put?: never;
|
|
1801
1852
|
/**
|
|
1802
|
-
*
|
|
1803
|
-
* @description
|
|
1853
|
+
* State the day you took this line
|
|
1854
|
+
* @description Record the instant you took this line, which becomes the day of the month it renews on and the date `/cancel` waits for. **This is for lines migrated from your own system**, whose real start date iSnap cannot know: a line taken through the iSnap API is stamped automatically at activation and needs no call. A BYOD line is accepted here even though `/cancel` refuses it: it is on the same monthly meter and carries an anniversary, iSnap simply has no way to end it for you at that date yet. Overwrites an existing anniversary — a date somebody states beats a date iSnap inferred — but is refused with 409 `line_cancellation_pending` while a cancellation is scheduled, because that `cancel_at` was computed from the anniversary you are replacing and would otherwise end the line on a day nothing explains: uncancel, set the date, cancel again. Audited as `line.anniversary_set` with the previous value.
|
|
1804
1855
|
*/
|
|
1805
|
-
|
|
1856
|
+
post: {
|
|
1806
1857
|
parameters: {
|
|
1807
1858
|
query?: never;
|
|
1808
1859
|
header?: never;
|
|
@@ -1811,15 +1862,25 @@ export interface paths {
|
|
|
1811
1862
|
};
|
|
1812
1863
|
cookie?: never;
|
|
1813
1864
|
};
|
|
1814
|
-
requestBody?:
|
|
1865
|
+
requestBody?: {
|
|
1866
|
+
content: {
|
|
1867
|
+
"application/json": components["schemas"]["SetLineAnniversary"];
|
|
1868
|
+
};
|
|
1869
|
+
};
|
|
1815
1870
|
responses: {
|
|
1816
|
-
/** @description
|
|
1871
|
+
/** @description Anniversary recorded. Returns the line with the new `anniversary_at`. */
|
|
1817
1872
|
200: {
|
|
1818
1873
|
headers: {
|
|
1819
1874
|
[name: string]: unknown;
|
|
1820
1875
|
};
|
|
1821
1876
|
content: {
|
|
1822
|
-
"application/json":
|
|
1877
|
+
"application/json": {
|
|
1878
|
+
/** @enum {boolean} */
|
|
1879
|
+
success: true;
|
|
1880
|
+
data: components["schemas"]["Line"];
|
|
1881
|
+
trace_id: string;
|
|
1882
|
+
request_id: string;
|
|
1883
|
+
};
|
|
1823
1884
|
};
|
|
1824
1885
|
};
|
|
1825
1886
|
/** @description Bad request — validation failed */
|
|
@@ -1858,6 +1919,15 @@ export interface paths {
|
|
|
1858
1919
|
"application/json": components["schemas"]["ErrorEnvelope"];
|
|
1859
1920
|
};
|
|
1860
1921
|
};
|
|
1922
|
+
/** @description Conflict — concurrent or terminal state */
|
|
1923
|
+
409: {
|
|
1924
|
+
headers: {
|
|
1925
|
+
[name: string]: unknown;
|
|
1926
|
+
};
|
|
1927
|
+
content: {
|
|
1928
|
+
"application/json": components["schemas"]["ErrorEnvelope"];
|
|
1929
|
+
};
|
|
1930
|
+
};
|
|
1861
1931
|
/** @description Too many requests — rate limit exceeded */
|
|
1862
1932
|
429: {
|
|
1863
1933
|
headers: {
|
|
@@ -1878,26 +1948,26 @@ export interface paths {
|
|
|
1878
1948
|
};
|
|
1879
1949
|
};
|
|
1880
1950
|
};
|
|
1881
|
-
put?: never;
|
|
1882
|
-
post?: never;
|
|
1883
1951
|
delete?: never;
|
|
1884
1952
|
options?: never;
|
|
1885
1953
|
head?: never;
|
|
1886
1954
|
patch?: never;
|
|
1887
1955
|
trace?: never;
|
|
1888
1956
|
};
|
|
1889
|
-
"/v1/lines/{id}/
|
|
1957
|
+
"/v1/lines/{id}/release": {
|
|
1890
1958
|
parameters: {
|
|
1891
1959
|
query?: never;
|
|
1892
1960
|
header?: never;
|
|
1893
1961
|
path?: never;
|
|
1894
1962
|
cookie?: never;
|
|
1895
1963
|
};
|
|
1964
|
+
get?: never;
|
|
1965
|
+
put?: never;
|
|
1896
1966
|
/**
|
|
1897
|
-
*
|
|
1898
|
-
* @description
|
|
1967
|
+
* Release a line back to the marketplace
|
|
1968
|
+
* @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.
|
|
1899
1969
|
*/
|
|
1900
|
-
|
|
1970
|
+
post: {
|
|
1901
1971
|
parameters: {
|
|
1902
1972
|
query?: never;
|
|
1903
1973
|
header?: never;
|
|
@@ -1908,13 +1978,19 @@ export interface paths {
|
|
|
1908
1978
|
};
|
|
1909
1979
|
requestBody?: never;
|
|
1910
1980
|
responses: {
|
|
1911
|
-
/** @description
|
|
1981
|
+
/** @description Line released */
|
|
1912
1982
|
200: {
|
|
1913
1983
|
headers: {
|
|
1914
1984
|
[name: string]: unknown;
|
|
1915
1985
|
};
|
|
1916
1986
|
content: {
|
|
1917
|
-
"application/json":
|
|
1987
|
+
"application/json": {
|
|
1988
|
+
/** @enum {boolean} */
|
|
1989
|
+
success: true;
|
|
1990
|
+
data: components["schemas"]["Line"];
|
|
1991
|
+
trace_id: string;
|
|
1992
|
+
request_id: string;
|
|
1993
|
+
};
|
|
1918
1994
|
};
|
|
1919
1995
|
};
|
|
1920
1996
|
/** @description Bad request — validation failed */
|
|
@@ -1973,16 +2049,24 @@ export interface paths {
|
|
|
1973
2049
|
};
|
|
1974
2050
|
};
|
|
1975
2051
|
};
|
|
1976
|
-
put?: never;
|
|
1977
|
-
post?: never;
|
|
1978
2052
|
delete?: never;
|
|
1979
2053
|
options?: never;
|
|
1980
2054
|
head?: never;
|
|
2055
|
+
patch?: never;
|
|
2056
|
+
trace?: never;
|
|
2057
|
+
};
|
|
2058
|
+
"/v1/lines/{id}/quota": {
|
|
2059
|
+
parameters: {
|
|
2060
|
+
query?: never;
|
|
2061
|
+
header?: never;
|
|
2062
|
+
path?: never;
|
|
2063
|
+
cookie?: never;
|
|
2064
|
+
};
|
|
1981
2065
|
/**
|
|
1982
|
-
*
|
|
1983
|
-
* @description
|
|
2066
|
+
* Get a line's quota snapshot
|
|
2067
|
+
* @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.
|
|
1984
2068
|
*/
|
|
1985
|
-
|
|
2069
|
+
get: {
|
|
1986
2070
|
parameters: {
|
|
1987
2071
|
query?: never;
|
|
1988
2072
|
header?: never;
|
|
@@ -1991,19 +2075,15 @@ export interface paths {
|
|
|
1991
2075
|
};
|
|
1992
2076
|
cookie?: never;
|
|
1993
2077
|
};
|
|
1994
|
-
requestBody?:
|
|
1995
|
-
content: {
|
|
1996
|
-
"application/json": components["schemas"]["LineConfigPatch"];
|
|
1997
|
-
};
|
|
1998
|
-
};
|
|
2078
|
+
requestBody?: never;
|
|
1999
2079
|
responses: {
|
|
2000
|
-
/** @description
|
|
2080
|
+
/** @description 5-bucket quota snapshot */
|
|
2001
2081
|
200: {
|
|
2002
2082
|
headers: {
|
|
2003
2083
|
[name: string]: unknown;
|
|
2004
2084
|
};
|
|
2005
2085
|
content: {
|
|
2006
|
-
"application/json": components["schemas"]["
|
|
2086
|
+
"application/json": components["schemas"]["QuotaEnvelope"];
|
|
2007
2087
|
};
|
|
2008
2088
|
};
|
|
2009
2089
|
/** @description Bad request — validation failed */
|
|
@@ -2062,9 +2142,15 @@ export interface paths {
|
|
|
2062
2142
|
};
|
|
2063
2143
|
};
|
|
2064
2144
|
};
|
|
2145
|
+
put?: never;
|
|
2146
|
+
post?: never;
|
|
2147
|
+
delete?: never;
|
|
2148
|
+
options?: never;
|
|
2149
|
+
head?: never;
|
|
2150
|
+
patch?: never;
|
|
2065
2151
|
trace?: never;
|
|
2066
2152
|
};
|
|
2067
|
-
"/v1/
|
|
2153
|
+
"/v1/lines/{id}/queue": {
|
|
2068
2154
|
parameters: {
|
|
2069
2155
|
query?: never;
|
|
2070
2156
|
header?: never;
|
|
@@ -2072,29 +2158,31 @@ export interface paths {
|
|
|
2072
2158
|
cookie?: never;
|
|
2073
2159
|
};
|
|
2074
2160
|
/**
|
|
2075
|
-
*
|
|
2076
|
-
* @description Cursor-paginated
|
|
2161
|
+
* Inspect a line's queued and scheduled messages
|
|
2162
|
+
* @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.
|
|
2077
2163
|
*/
|
|
2078
2164
|
get: {
|
|
2079
2165
|
parameters: {
|
|
2080
2166
|
query?: {
|
|
2081
|
-
status?: "draft" | "pending" | "provisioning" | "ready" | "fulfilled" | "cancelled" | "refunded";
|
|
2082
|
-
cursor?: string;
|
|
2083
2167
|
limit?: number;
|
|
2168
|
+
cursor?: string;
|
|
2169
|
+
status?: "queued" | "scheduled" | "delivered_to_device";
|
|
2084
2170
|
};
|
|
2085
2171
|
header?: never;
|
|
2086
|
-
path
|
|
2172
|
+
path: {
|
|
2173
|
+
id: string;
|
|
2174
|
+
};
|
|
2087
2175
|
cookie?: never;
|
|
2088
2176
|
};
|
|
2089
2177
|
requestBody?: never;
|
|
2090
2178
|
responses: {
|
|
2091
|
-
/** @description
|
|
2179
|
+
/** @description Queue inspection — summary + paginated items */
|
|
2092
2180
|
200: {
|
|
2093
2181
|
headers: {
|
|
2094
2182
|
[name: string]: unknown;
|
|
2095
2183
|
};
|
|
2096
2184
|
content: {
|
|
2097
|
-
"application/json": components["schemas"]["
|
|
2185
|
+
"application/json": components["schemas"]["QueueEnvelope"];
|
|
2098
2186
|
};
|
|
2099
2187
|
};
|
|
2100
2188
|
/** @description Bad request — validation failed */
|
|
@@ -2115,6 +2203,24 @@ export interface paths {
|
|
|
2115
2203
|
"application/json": components["schemas"]["ErrorEnvelope"];
|
|
2116
2204
|
};
|
|
2117
2205
|
};
|
|
2206
|
+
/** @description Forbidden — caller authenticated but not allowed */
|
|
2207
|
+
403: {
|
|
2208
|
+
headers: {
|
|
2209
|
+
[name: string]: unknown;
|
|
2210
|
+
};
|
|
2211
|
+
content: {
|
|
2212
|
+
"application/json": components["schemas"]["ErrorEnvelope"];
|
|
2213
|
+
};
|
|
2214
|
+
};
|
|
2215
|
+
/** @description Not found */
|
|
2216
|
+
404: {
|
|
2217
|
+
headers: {
|
|
2218
|
+
[name: string]: unknown;
|
|
2219
|
+
};
|
|
2220
|
+
content: {
|
|
2221
|
+
"application/json": components["schemas"]["ErrorEnvelope"];
|
|
2222
|
+
};
|
|
2223
|
+
};
|
|
2118
2224
|
/** @description Too many requests — rate limit exceeded */
|
|
2119
2225
|
429: {
|
|
2120
2226
|
headers: {
|
|
@@ -2136,43 +2242,42 @@ export interface paths {
|
|
|
2136
2242
|
};
|
|
2137
2243
|
};
|
|
2138
2244
|
put?: never;
|
|
2245
|
+
post?: never;
|
|
2246
|
+
delete?: never;
|
|
2247
|
+
options?: never;
|
|
2248
|
+
head?: never;
|
|
2249
|
+
patch?: never;
|
|
2250
|
+
trace?: never;
|
|
2251
|
+
};
|
|
2252
|
+
"/v1/lines/{id}/health": {
|
|
2253
|
+
parameters: {
|
|
2254
|
+
query?: never;
|
|
2255
|
+
header?: never;
|
|
2256
|
+
path?: never;
|
|
2257
|
+
cookie?: never;
|
|
2258
|
+
};
|
|
2139
2259
|
/**
|
|
2140
|
-
*
|
|
2141
|
-
* @description
|
|
2260
|
+
* Get a BYOD line's health snapshot
|
|
2261
|
+
* @description BYOD-only health rollup. `state` (`active` / `degraded` / `offline`) is derived from the device's fundamental capabilities — min(send_text, imessage) — with offline (no heartbeat) taking precedence. Also returns `runtime_capabilities` (the per-key tri-valued descriptor the device last reported), 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.
|
|
2142
2262
|
*/
|
|
2143
|
-
|
|
2263
|
+
get: {
|
|
2144
2264
|
parameters: {
|
|
2145
2265
|
query?: never;
|
|
2146
2266
|
header?: never;
|
|
2147
|
-
path
|
|
2148
|
-
|
|
2149
|
-
};
|
|
2150
|
-
requestBody?: {
|
|
2151
|
-
content: {
|
|
2152
|
-
"application/json": {
|
|
2153
|
-
/** @enum {string} */
|
|
2154
|
-
billing_tier: "rental_iphone" | "rental_android";
|
|
2155
|
-
/** @default [] */
|
|
2156
|
-
preferred_area_codes?: string[];
|
|
2157
|
-
/** @default false */
|
|
2158
|
-
inbound_only?: boolean;
|
|
2159
|
-
};
|
|
2267
|
+
path: {
|
|
2268
|
+
id: string;
|
|
2160
2269
|
};
|
|
2270
|
+
cookie?: never;
|
|
2161
2271
|
};
|
|
2272
|
+
requestBody?: never;
|
|
2162
2273
|
responses: {
|
|
2163
|
-
/** @description
|
|
2164
|
-
|
|
2274
|
+
/** @description BYOD line health snapshot */
|
|
2275
|
+
200: {
|
|
2165
2276
|
headers: {
|
|
2166
2277
|
[name: string]: unknown;
|
|
2167
2278
|
};
|
|
2168
2279
|
content: {
|
|
2169
|
-
"application/json":
|
|
2170
|
-
/** @enum {boolean} */
|
|
2171
|
-
success: true;
|
|
2172
|
-
data: components["schemas"]["PreOrder"];
|
|
2173
|
-
trace_id: string;
|
|
2174
|
-
request_id: string;
|
|
2175
|
-
};
|
|
2280
|
+
"application/json": components["schemas"]["LineHealthEnvelope"];
|
|
2176
2281
|
};
|
|
2177
2282
|
};
|
|
2178
2283
|
/** @description Bad request — validation failed */
|
|
@@ -2193,8 +2298,26 @@ export interface paths {
|
|
|
2193
2298
|
"application/json": components["schemas"]["ErrorEnvelope"];
|
|
2194
2299
|
};
|
|
2195
2300
|
};
|
|
2196
|
-
/** @description
|
|
2197
|
-
|
|
2301
|
+
/** @description Forbidden — caller authenticated but not allowed */
|
|
2302
|
+
403: {
|
|
2303
|
+
headers: {
|
|
2304
|
+
[name: string]: unknown;
|
|
2305
|
+
};
|
|
2306
|
+
content: {
|
|
2307
|
+
"application/json": components["schemas"]["ErrorEnvelope"];
|
|
2308
|
+
};
|
|
2309
|
+
};
|
|
2310
|
+
/** @description Not found */
|
|
2311
|
+
404: {
|
|
2312
|
+
headers: {
|
|
2313
|
+
[name: string]: unknown;
|
|
2314
|
+
};
|
|
2315
|
+
content: {
|
|
2316
|
+
"application/json": components["schemas"]["ErrorEnvelope"];
|
|
2317
|
+
};
|
|
2318
|
+
};
|
|
2319
|
+
/** @description Too many requests — rate limit exceeded */
|
|
2320
|
+
429: {
|
|
2198
2321
|
headers: {
|
|
2199
2322
|
[name: string]: unknown;
|
|
2200
2323
|
};
|
|
@@ -2213,26 +2336,26 @@ export interface paths {
|
|
|
2213
2336
|
};
|
|
2214
2337
|
};
|
|
2215
2338
|
};
|
|
2339
|
+
put?: never;
|
|
2340
|
+
post?: never;
|
|
2216
2341
|
delete?: never;
|
|
2217
2342
|
options?: never;
|
|
2218
2343
|
head?: never;
|
|
2219
2344
|
patch?: never;
|
|
2220
2345
|
trace?: never;
|
|
2221
2346
|
};
|
|
2222
|
-
"/v1/
|
|
2347
|
+
"/v1/lines/{id}/config": {
|
|
2223
2348
|
parameters: {
|
|
2224
2349
|
query?: never;
|
|
2225
2350
|
header?: never;
|
|
2226
2351
|
path?: never;
|
|
2227
2352
|
cookie?: never;
|
|
2228
2353
|
};
|
|
2229
|
-
get?: never;
|
|
2230
|
-
put?: never;
|
|
2231
2354
|
/**
|
|
2232
|
-
*
|
|
2233
|
-
* @description
|
|
2355
|
+
* Get a line's effective send configuration
|
|
2356
|
+
* @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.
|
|
2234
2357
|
*/
|
|
2235
|
-
|
|
2358
|
+
get: {
|
|
2236
2359
|
parameters: {
|
|
2237
2360
|
query?: never;
|
|
2238
2361
|
header?: never;
|
|
@@ -2243,19 +2366,13 @@ export interface paths {
|
|
|
2243
2366
|
};
|
|
2244
2367
|
requestBody?: never;
|
|
2245
2368
|
responses: {
|
|
2246
|
-
/** @description
|
|
2369
|
+
/** @description Effective config (tier defaults + per-line overrides) */
|
|
2247
2370
|
200: {
|
|
2248
2371
|
headers: {
|
|
2249
2372
|
[name: string]: unknown;
|
|
2250
2373
|
};
|
|
2251
2374
|
content: {
|
|
2252
|
-
"application/json":
|
|
2253
|
-
/** @enum {boolean} */
|
|
2254
|
-
success: true;
|
|
2255
|
-
data: components["schemas"]["PreOrder"];
|
|
2256
|
-
trace_id: string;
|
|
2257
|
-
request_id: string;
|
|
2258
|
-
};
|
|
2375
|
+
"application/json": components["schemas"]["LineConfigEnvelope"];
|
|
2259
2376
|
};
|
|
2260
2377
|
};
|
|
2261
2378
|
/** @description Bad request — validation failed */
|
|
@@ -2276,6 +2393,15 @@ export interface paths {
|
|
|
2276
2393
|
"application/json": components["schemas"]["ErrorEnvelope"];
|
|
2277
2394
|
};
|
|
2278
2395
|
};
|
|
2396
|
+
/** @description Forbidden — caller authenticated but not allowed */
|
|
2397
|
+
403: {
|
|
2398
|
+
headers: {
|
|
2399
|
+
[name: string]: unknown;
|
|
2400
|
+
};
|
|
2401
|
+
content: {
|
|
2402
|
+
"application/json": components["schemas"]["ErrorEnvelope"];
|
|
2403
|
+
};
|
|
2404
|
+
};
|
|
2279
2405
|
/** @description Not found */
|
|
2280
2406
|
404: {
|
|
2281
2407
|
headers: {
|
|
@@ -2305,24 +2431,16 @@ export interface paths {
|
|
|
2305
2431
|
};
|
|
2306
2432
|
};
|
|
2307
2433
|
};
|
|
2434
|
+
put?: never;
|
|
2435
|
+
post?: never;
|
|
2308
2436
|
delete?: never;
|
|
2309
2437
|
options?: never;
|
|
2310
2438
|
head?: never;
|
|
2311
|
-
patch?: never;
|
|
2312
|
-
trace?: never;
|
|
2313
|
-
};
|
|
2314
|
-
"/v1/pre-orders/{id}": {
|
|
2315
|
-
parameters: {
|
|
2316
|
-
query?: never;
|
|
2317
|
-
header?: never;
|
|
2318
|
-
path?: never;
|
|
2319
|
-
cookie?: never;
|
|
2320
|
-
};
|
|
2321
2439
|
/**
|
|
2322
|
-
*
|
|
2323
|
-
* @description
|
|
2440
|
+
* Update a line's send configuration
|
|
2441
|
+
* @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.
|
|
2324
2442
|
*/
|
|
2325
|
-
|
|
2443
|
+
patch: {
|
|
2326
2444
|
parameters: {
|
|
2327
2445
|
query?: never;
|
|
2328
2446
|
header?: never;
|
|
@@ -2331,21 +2449,19 @@ export interface paths {
|
|
|
2331
2449
|
};
|
|
2332
2450
|
cookie?: never;
|
|
2333
2451
|
};
|
|
2334
|
-
requestBody?:
|
|
2452
|
+
requestBody?: {
|
|
2453
|
+
content: {
|
|
2454
|
+
"application/json": components["schemas"]["LineConfigPatch"];
|
|
2455
|
+
};
|
|
2456
|
+
};
|
|
2335
2457
|
responses: {
|
|
2336
|
-
/** @description
|
|
2458
|
+
/** @description Updated effective config (merged) + overridden_keys */
|
|
2337
2459
|
200: {
|
|
2338
2460
|
headers: {
|
|
2339
2461
|
[name: string]: unknown;
|
|
2340
2462
|
};
|
|
2341
2463
|
content: {
|
|
2342
|
-
"application/json":
|
|
2343
|
-
/** @enum {boolean} */
|
|
2344
|
-
success: true;
|
|
2345
|
-
data: components["schemas"]["PreOrder"];
|
|
2346
|
-
trace_id: string;
|
|
2347
|
-
request_id: string;
|
|
2348
|
-
};
|
|
2464
|
+
"application/json": components["schemas"]["LineConfigEnvelope"];
|
|
2349
2465
|
};
|
|
2350
2466
|
};
|
|
2351
2467
|
/** @description Bad request — validation failed */
|
|
@@ -2366,6 +2482,15 @@ export interface paths {
|
|
|
2366
2482
|
"application/json": components["schemas"]["ErrorEnvelope"];
|
|
2367
2483
|
};
|
|
2368
2484
|
};
|
|
2485
|
+
/** @description Forbidden — caller authenticated but not allowed */
|
|
2486
|
+
403: {
|
|
2487
|
+
headers: {
|
|
2488
|
+
[name: string]: unknown;
|
|
2489
|
+
};
|
|
2490
|
+
content: {
|
|
2491
|
+
"application/json": components["schemas"]["ErrorEnvelope"];
|
|
2492
|
+
};
|
|
2493
|
+
};
|
|
2369
2494
|
/** @description Not found */
|
|
2370
2495
|
404: {
|
|
2371
2496
|
headers: {
|
|
@@ -2395,51 +2520,39 @@ export interface paths {
|
|
|
2395
2520
|
};
|
|
2396
2521
|
};
|
|
2397
2522
|
};
|
|
2398
|
-
put?: never;
|
|
2399
|
-
post?: never;
|
|
2400
|
-
delete?: never;
|
|
2401
|
-
options?: never;
|
|
2402
|
-
head?: never;
|
|
2403
|
-
patch?: never;
|
|
2404
2523
|
trace?: never;
|
|
2405
2524
|
};
|
|
2406
|
-
"/v1/pre-orders
|
|
2525
|
+
"/v1/pre-orders": {
|
|
2407
2526
|
parameters: {
|
|
2408
2527
|
query?: never;
|
|
2409
2528
|
header?: never;
|
|
2410
2529
|
path?: never;
|
|
2411
2530
|
cookie?: never;
|
|
2412
2531
|
};
|
|
2413
|
-
get?: never;
|
|
2414
|
-
put?: never;
|
|
2415
2532
|
/**
|
|
2416
|
-
*
|
|
2417
|
-
* @description
|
|
2533
|
+
* List pre-orders
|
|
2534
|
+
* @description Cursor-paginated list of the caller's pre-orders. Filter by status (`draft`, `provisioning`, `fulfilled`, `cancelled`) to surface only the ones the dashboard needs.
|
|
2418
2535
|
*/
|
|
2419
|
-
|
|
2536
|
+
get: {
|
|
2420
2537
|
parameters: {
|
|
2421
|
-
query?:
|
|
2422
|
-
|
|
2423
|
-
|
|
2424
|
-
|
|
2538
|
+
query?: {
|
|
2539
|
+
status?: "draft" | "provisioning" | "fulfilled" | "cancelled";
|
|
2540
|
+
cursor?: string;
|
|
2541
|
+
limit?: number;
|
|
2425
2542
|
};
|
|
2543
|
+
header?: never;
|
|
2544
|
+
path?: never;
|
|
2426
2545
|
cookie?: never;
|
|
2427
2546
|
};
|
|
2428
2547
|
requestBody?: never;
|
|
2429
2548
|
responses: {
|
|
2430
|
-
/** @description Pre-order
|
|
2549
|
+
/** @description Pre-order list */
|
|
2431
2550
|
200: {
|
|
2432
2551
|
headers: {
|
|
2433
2552
|
[name: string]: unknown;
|
|
2434
2553
|
};
|
|
2435
2554
|
content: {
|
|
2436
|
-
"application/json":
|
|
2437
|
-
/** @enum {boolean} */
|
|
2438
|
-
success: true;
|
|
2439
|
-
data: components["schemas"]["PreOrder"];
|
|
2440
|
-
trace_id: string;
|
|
2441
|
-
request_id: string;
|
|
2442
|
-
};
|
|
2555
|
+
"application/json": components["schemas"]["PreOrderList"];
|
|
2443
2556
|
};
|
|
2444
2557
|
};
|
|
2445
2558
|
/** @description Bad request — validation failed */
|
|
@@ -2460,24 +2573,6 @@ export interface paths {
|
|
|
2460
2573
|
"application/json": components["schemas"]["ErrorEnvelope"];
|
|
2461
2574
|
};
|
|
2462
2575
|
};
|
|
2463
|
-
/** @description Not found */
|
|
2464
|
-
404: {
|
|
2465
|
-
headers: {
|
|
2466
|
-
[name: string]: unknown;
|
|
2467
|
-
};
|
|
2468
|
-
content: {
|
|
2469
|
-
"application/json": components["schemas"]["ErrorEnvelope"];
|
|
2470
|
-
};
|
|
2471
|
-
};
|
|
2472
|
-
/** @description Conflict — concurrent or terminal state */
|
|
2473
|
-
409: {
|
|
2474
|
-
headers: {
|
|
2475
|
-
[name: string]: unknown;
|
|
2476
|
-
};
|
|
2477
|
-
content: {
|
|
2478
|
-
"application/json": components["schemas"]["ErrorEnvelope"];
|
|
2479
|
-
};
|
|
2480
|
-
};
|
|
2481
2576
|
/** @description Too many requests — rate limit exceeded */
|
|
2482
2577
|
429: {
|
|
2483
2578
|
headers: {
|
|
@@ -2498,24 +2593,10 @@ export interface paths {
|
|
|
2498
2593
|
};
|
|
2499
2594
|
};
|
|
2500
2595
|
};
|
|
2501
|
-
delete?: never;
|
|
2502
|
-
options?: never;
|
|
2503
|
-
head?: never;
|
|
2504
|
-
patch?: never;
|
|
2505
|
-
trace?: never;
|
|
2506
|
-
};
|
|
2507
|
-
"/v1/billing/checkout": {
|
|
2508
|
-
parameters: {
|
|
2509
|
-
query?: never;
|
|
2510
|
-
header?: never;
|
|
2511
|
-
path?: never;
|
|
2512
|
-
cookie?: never;
|
|
2513
|
-
};
|
|
2514
|
-
get?: never;
|
|
2515
2596
|
put?: never;
|
|
2516
2597
|
/**
|
|
2517
|
-
*
|
|
2518
|
-
* @description
|
|
2598
|
+
* Create a pre-order (draft)
|
|
2599
|
+
* @description Place a pre-order as a `draft` (WHA-1155). A draft has NO side effects — no provisioning line, no procurement, no Stripe charge — so the partner can hold intent / bill its own end-user first. Call `POST /v1/pre-orders/{id}/confirm` to engage the month and start procurement. A pre-order carries the area codes you would accept, in order of preference, the plan (`inbound_only`), which is remembered for confirm and read back on every response, and optionally the SKU (`billing_tier`). The tier and the plan are ORTHOGONAL — `rental_iphone` covers both the outbound and the inbound product, which is what `inbound_only` selects — so naming both is never a contradiction. `billing_tier` is optional because a pre-order that omits it is still `rental_iphone`, the only tier this flow mints; when named it is ANSWERED, never discarded: `rental_android` is `400 android_rental_not_purchasable` (no Android product exists in the Stripe catalogue, WHA-2474) and a tier no pre-order can procure — BYOD, virtual shared, pool — is `400 tier_not_pre_orderable`, naming the endpoint to call instead (WHA-2949). The body is otherwise STRICT (WHA-2644) — any other property is a `400`, including `quantity` and `metadata`, which earlier revisions of this contract documented and the server silently discarded.
|
|
2519
2600
|
*/
|
|
2520
2601
|
post: {
|
|
2521
2602
|
parameters: {
|
|
@@ -2527,27 +2608,29 @@ export interface paths {
|
|
|
2527
2608
|
requestBody?: {
|
|
2528
2609
|
content: {
|
|
2529
2610
|
"application/json": {
|
|
2530
|
-
/**
|
|
2531
|
-
|
|
2532
|
-
|
|
2533
|
-
*/
|
|
2534
|
-
line_id: string;
|
|
2535
|
-
/**
|
|
2536
|
-
* @description Pick the inbound-only rental price variant (WHA-1153). Rental tiers only; the chosen Stripe price is the source of truth — `lines.inbound_only` is re-derived from its lookup_key on `customer.subscription.created/updated`.
|
|
2537
|
-
* @default false
|
|
2538
|
-
*/
|
|
2611
|
+
/** @default [] */
|
|
2612
|
+
preferred_area_codes?: string[];
|
|
2613
|
+
/** @default false */
|
|
2539
2614
|
inbound_only?: boolean;
|
|
2615
|
+
/** @enum {string} */
|
|
2616
|
+
billing_tier?: "rental_iphone" | "rental_android" | "byod_imessage" | "byod_android" | "shared_pool" | "shared_imessage";
|
|
2540
2617
|
};
|
|
2541
2618
|
};
|
|
2542
2619
|
};
|
|
2543
2620
|
responses: {
|
|
2544
|
-
/** @description
|
|
2545
|
-
|
|
2621
|
+
/** @description Pre-order draft created */
|
|
2622
|
+
201: {
|
|
2546
2623
|
headers: {
|
|
2547
2624
|
[name: string]: unknown;
|
|
2548
2625
|
};
|
|
2549
2626
|
content: {
|
|
2550
|
-
"application/json":
|
|
2627
|
+
"application/json": {
|
|
2628
|
+
/** @enum {boolean} */
|
|
2629
|
+
success: true;
|
|
2630
|
+
data: components["schemas"]["PreOrder"];
|
|
2631
|
+
trace_id: string;
|
|
2632
|
+
request_id: string;
|
|
2633
|
+
};
|
|
2551
2634
|
};
|
|
2552
2635
|
};
|
|
2553
2636
|
/** @description Bad request — validation failed */
|
|
@@ -2568,15 +2651,6 @@ export interface paths {
|
|
|
2568
2651
|
"application/json": components["schemas"]["ErrorEnvelope"];
|
|
2569
2652
|
};
|
|
2570
2653
|
};
|
|
2571
|
-
/** @description Not found */
|
|
2572
|
-
404: {
|
|
2573
|
-
headers: {
|
|
2574
|
-
[name: string]: unknown;
|
|
2575
|
-
};
|
|
2576
|
-
content: {
|
|
2577
|
-
"application/json": components["schemas"]["ErrorEnvelope"];
|
|
2578
|
-
};
|
|
2579
|
-
};
|
|
2580
2654
|
/** @description Too many requests — rate limit exceeded */
|
|
2581
2655
|
429: {
|
|
2582
2656
|
headers: {
|
|
@@ -2603,7 +2677,7 @@ export interface paths {
|
|
|
2603
2677
|
patch?: never;
|
|
2604
2678
|
trace?: never;
|
|
2605
2679
|
};
|
|
2606
|
-
"/v1/
|
|
2680
|
+
"/v1/pre-orders/{id}/confirm": {
|
|
2607
2681
|
parameters: {
|
|
2608
2682
|
query?: never;
|
|
2609
2683
|
header?: never;
|
|
@@ -2613,29 +2687,33 @@ export interface paths {
|
|
|
2613
2687
|
get?: never;
|
|
2614
2688
|
put?: never;
|
|
2615
2689
|
/**
|
|
2616
|
-
*
|
|
2617
|
-
* @description
|
|
2690
|
+
* Confirm a pre-order draft
|
|
2691
|
+
* @description Confirm a `draft` pre-order (WHA-1155). The binding step: engages the one-month commitment (full month, no proration) and triggers procurement — mints the `provisioning` line + fulfillment task, notifies ops, and (for direct customers) creates the first-month Stripe payment intent, returned as `stripe_client_secret`. Only a draft can be confirmed.
|
|
2618
2692
|
*/
|
|
2619
2693
|
post: {
|
|
2620
2694
|
parameters: {
|
|
2621
2695
|
query?: never;
|
|
2622
2696
|
header?: never;
|
|
2623
|
-
path
|
|
2624
|
-
|
|
2625
|
-
};
|
|
2626
|
-
requestBody?: {
|
|
2627
|
-
content: {
|
|
2628
|
-
"application/json": components["schemas"]["ByodCheckoutBody"];
|
|
2697
|
+
path: {
|
|
2698
|
+
id: string;
|
|
2629
2699
|
};
|
|
2700
|
+
cookie?: never;
|
|
2630
2701
|
};
|
|
2702
|
+
requestBody?: never;
|
|
2631
2703
|
responses: {
|
|
2632
|
-
/** @description
|
|
2704
|
+
/** @description Pre-order confirmed (now provisioning) */
|
|
2633
2705
|
200: {
|
|
2634
2706
|
headers: {
|
|
2635
2707
|
[name: string]: unknown;
|
|
2636
2708
|
};
|
|
2637
2709
|
content: {
|
|
2638
|
-
"application/json":
|
|
2710
|
+
"application/json": {
|
|
2711
|
+
/** @enum {boolean} */
|
|
2712
|
+
success: true;
|
|
2713
|
+
data: components["schemas"]["PreOrder"];
|
|
2714
|
+
trace_id: string;
|
|
2715
|
+
request_id: string;
|
|
2716
|
+
};
|
|
2639
2717
|
};
|
|
2640
2718
|
};
|
|
2641
2719
|
/** @description Bad request — validation failed */
|
|
@@ -2656,6 +2734,15 @@ export interface paths {
|
|
|
2656
2734
|
"application/json": components["schemas"]["ErrorEnvelope"];
|
|
2657
2735
|
};
|
|
2658
2736
|
};
|
|
2737
|
+
/** @description Not found */
|
|
2738
|
+
404: {
|
|
2739
|
+
headers: {
|
|
2740
|
+
[name: string]: unknown;
|
|
2741
|
+
};
|
|
2742
|
+
content: {
|
|
2743
|
+
"application/json": components["schemas"]["ErrorEnvelope"];
|
|
2744
|
+
};
|
|
2745
|
+
};
|
|
2659
2746
|
/** @description Too many requests — rate limit exceeded */
|
|
2660
2747
|
429: {
|
|
2661
2748
|
headers: {
|
|
@@ -2682,7 +2769,7 @@ export interface paths {
|
|
|
2682
2769
|
patch?: never;
|
|
2683
2770
|
trace?: never;
|
|
2684
2771
|
};
|
|
2685
|
-
"/v1/
|
|
2772
|
+
"/v1/pre-orders/{id}": {
|
|
2686
2773
|
parameters: {
|
|
2687
2774
|
query?: never;
|
|
2688
2775
|
header?: never;
|
|
@@ -2690,25 +2777,33 @@ export interface paths {
|
|
|
2690
2777
|
cookie?: never;
|
|
2691
2778
|
};
|
|
2692
2779
|
/**
|
|
2693
|
-
*
|
|
2694
|
-
* @description
|
|
2780
|
+
* Get a pre-order
|
|
2781
|
+
* @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.
|
|
2695
2782
|
*/
|
|
2696
2783
|
get: {
|
|
2697
2784
|
parameters: {
|
|
2698
2785
|
query?: never;
|
|
2699
2786
|
header?: never;
|
|
2700
|
-
path
|
|
2787
|
+
path: {
|
|
2788
|
+
id: string;
|
|
2789
|
+
};
|
|
2701
2790
|
cookie?: never;
|
|
2702
2791
|
};
|
|
2703
2792
|
requestBody?: never;
|
|
2704
2793
|
responses: {
|
|
2705
|
-
/** @description
|
|
2794
|
+
/** @description Pre-order */
|
|
2706
2795
|
200: {
|
|
2707
2796
|
headers: {
|
|
2708
2797
|
[name: string]: unknown;
|
|
2709
2798
|
};
|
|
2710
2799
|
content: {
|
|
2711
|
-
"application/json":
|
|
2800
|
+
"application/json": {
|
|
2801
|
+
/** @enum {boolean} */
|
|
2802
|
+
success: true;
|
|
2803
|
+
data: components["schemas"]["PreOrder"];
|
|
2804
|
+
trace_id: string;
|
|
2805
|
+
request_id: string;
|
|
2806
|
+
};
|
|
2712
2807
|
};
|
|
2713
2808
|
};
|
|
2714
2809
|
/** @description Bad request — validation failed */
|
|
@@ -2729,8 +2824,8 @@ export interface paths {
|
|
|
2729
2824
|
"application/json": components["schemas"]["ErrorEnvelope"];
|
|
2730
2825
|
};
|
|
2731
2826
|
};
|
|
2732
|
-
/** @description
|
|
2733
|
-
|
|
2827
|
+
/** @description Not found */
|
|
2828
|
+
404: {
|
|
2734
2829
|
headers: {
|
|
2735
2830
|
[name: string]: unknown;
|
|
2736
2831
|
};
|
|
@@ -2738,8 +2833,17 @@ export interface paths {
|
|
|
2738
2833
|
"application/json": components["schemas"]["ErrorEnvelope"];
|
|
2739
2834
|
};
|
|
2740
2835
|
};
|
|
2741
|
-
/** @description
|
|
2742
|
-
|
|
2836
|
+
/** @description Too many requests — rate limit exceeded */
|
|
2837
|
+
429: {
|
|
2838
|
+
headers: {
|
|
2839
|
+
[name: string]: unknown;
|
|
2840
|
+
};
|
|
2841
|
+
content: {
|
|
2842
|
+
"application/json": components["schemas"]["ErrorEnvelope"];
|
|
2843
|
+
};
|
|
2844
|
+
};
|
|
2845
|
+
/** @description Internal server error */
|
|
2846
|
+
500: {
|
|
2743
2847
|
headers: {
|
|
2744
2848
|
[name: string]: unknown;
|
|
2745
2849
|
};
|
|
@@ -2757,33 +2861,43 @@ export interface paths {
|
|
|
2757
2861
|
patch?: never;
|
|
2758
2862
|
trace?: never;
|
|
2759
2863
|
};
|
|
2760
|
-
"/v1/
|
|
2864
|
+
"/v1/pre-orders/{id}/cancel": {
|
|
2761
2865
|
parameters: {
|
|
2762
2866
|
query?: never;
|
|
2763
2867
|
header?: never;
|
|
2764
2868
|
path?: never;
|
|
2765
2869
|
cookie?: never;
|
|
2766
2870
|
};
|
|
2871
|
+
get?: never;
|
|
2872
|
+
put?: never;
|
|
2767
2873
|
/**
|
|
2768
|
-
*
|
|
2769
|
-
* @description
|
|
2874
|
+
* Cancel a pre-order draft
|
|
2875
|
+
* @description Cancel an unconfirmed `draft` pre-order (WHA-1155) — free, nothing was provisioned or charged. A CONFIRMED pre-order cannot be cancelled here (the month is committed, full month no proration); release its provisioned line through the standard line endpoint `POST /v1/lines/{id}/release` instead.
|
|
2770
2876
|
*/
|
|
2771
|
-
|
|
2877
|
+
post: {
|
|
2772
2878
|
parameters: {
|
|
2773
2879
|
query?: never;
|
|
2774
2880
|
header?: never;
|
|
2775
|
-
path
|
|
2881
|
+
path: {
|
|
2882
|
+
id: string;
|
|
2883
|
+
};
|
|
2776
2884
|
cookie?: never;
|
|
2777
2885
|
};
|
|
2778
2886
|
requestBody?: never;
|
|
2779
2887
|
responses: {
|
|
2780
|
-
/** @description
|
|
2888
|
+
/** @description Pre-order cancelled */
|
|
2781
2889
|
200: {
|
|
2782
2890
|
headers: {
|
|
2783
2891
|
[name: string]: unknown;
|
|
2784
2892
|
};
|
|
2785
2893
|
content: {
|
|
2786
|
-
"application/json":
|
|
2894
|
+
"application/json": {
|
|
2895
|
+
/** @enum {boolean} */
|
|
2896
|
+
success: true;
|
|
2897
|
+
data: components["schemas"]["PreOrder"];
|
|
2898
|
+
trace_id: string;
|
|
2899
|
+
request_id: string;
|
|
2900
|
+
};
|
|
2787
2901
|
};
|
|
2788
2902
|
};
|
|
2789
2903
|
/** @description Bad request — validation failed */
|
|
@@ -2804,6 +2918,24 @@ export interface paths {
|
|
|
2804
2918
|
"application/json": components["schemas"]["ErrorEnvelope"];
|
|
2805
2919
|
};
|
|
2806
2920
|
};
|
|
2921
|
+
/** @description Not found */
|
|
2922
|
+
404: {
|
|
2923
|
+
headers: {
|
|
2924
|
+
[name: string]: unknown;
|
|
2925
|
+
};
|
|
2926
|
+
content: {
|
|
2927
|
+
"application/json": components["schemas"]["ErrorEnvelope"];
|
|
2928
|
+
};
|
|
2929
|
+
};
|
|
2930
|
+
/** @description Conflict — concurrent or terminal state */
|
|
2931
|
+
409: {
|
|
2932
|
+
headers: {
|
|
2933
|
+
[name: string]: unknown;
|
|
2934
|
+
};
|
|
2935
|
+
content: {
|
|
2936
|
+
"application/json": components["schemas"]["ErrorEnvelope"];
|
|
2937
|
+
};
|
|
2938
|
+
};
|
|
2807
2939
|
/** @description Too many requests — rate limit exceeded */
|
|
2808
2940
|
429: {
|
|
2809
2941
|
headers: {
|
|
@@ -2824,15 +2956,13 @@ export interface paths {
|
|
|
2824
2956
|
};
|
|
2825
2957
|
};
|
|
2826
2958
|
};
|
|
2827
|
-
put?: never;
|
|
2828
|
-
post?: never;
|
|
2829
2959
|
delete?: never;
|
|
2830
2960
|
options?: never;
|
|
2831
2961
|
head?: never;
|
|
2832
2962
|
patch?: never;
|
|
2833
2963
|
trace?: never;
|
|
2834
2964
|
};
|
|
2835
|
-
"/v1/billing/
|
|
2965
|
+
"/v1/billing/checkout": {
|
|
2836
2966
|
parameters: {
|
|
2837
2967
|
query?: never;
|
|
2838
2968
|
header?: never;
|
|
@@ -2841,29 +2971,41 @@ export interface paths {
|
|
|
2841
2971
|
};
|
|
2842
2972
|
get?: never;
|
|
2843
2973
|
put?: never;
|
|
2844
|
-
post?: never;
|
|
2845
2974
|
/**
|
|
2846
|
-
*
|
|
2847
|
-
* @description
|
|
2975
|
+
* Start a Stripe Checkout for a reserved line
|
|
2976
|
+
* @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.
|
|
2848
2977
|
*/
|
|
2849
|
-
|
|
2978
|
+
post: {
|
|
2850
2979
|
parameters: {
|
|
2851
2980
|
query?: never;
|
|
2852
2981
|
header?: never;
|
|
2853
|
-
path
|
|
2854
|
-
id: string;
|
|
2855
|
-
};
|
|
2982
|
+
path?: never;
|
|
2856
2983
|
cookie?: never;
|
|
2857
2984
|
};
|
|
2858
|
-
requestBody?:
|
|
2985
|
+
requestBody?: {
|
|
2986
|
+
content: {
|
|
2987
|
+
"application/json": {
|
|
2988
|
+
/**
|
|
2989
|
+
* @description Line to check out. Send the `line_<base62>` public ID returned by `POST /v1/lines/{id}/reserve`; the internal UUID is also accepted for backward compatibility. Must be status `reserved`.
|
|
2990
|
+
* @example line_2k9Qp7RtY4mNb8VcXs3Wd6Lf1
|
|
2991
|
+
*/
|
|
2992
|
+
line_id: string;
|
|
2993
|
+
/**
|
|
2994
|
+
* @description Buy the INBOUND rental product instead of the outbound one. An inbound line cannot INITIATE a conversation — the contact must message first, after which the exchange is unrestricted; it is NOT receive-only. Rental tiers only. The chosen Stripe price is the source of truth: `lines.inbound_only` is re-derived from its lookup_key on `customer.subscription.created/updated`.
|
|
2995
|
+
* @default false
|
|
2996
|
+
*/
|
|
2997
|
+
inbound_only?: boolean;
|
|
2998
|
+
};
|
|
2999
|
+
};
|
|
3000
|
+
};
|
|
2859
3001
|
responses: {
|
|
2860
|
-
/** @description
|
|
3002
|
+
/** @description Checkout session */
|
|
2861
3003
|
200: {
|
|
2862
3004
|
headers: {
|
|
2863
3005
|
[name: string]: unknown;
|
|
2864
3006
|
};
|
|
2865
3007
|
content: {
|
|
2866
|
-
"application/json": components["schemas"]["
|
|
3008
|
+
"application/json": components["schemas"]["Checkout"];
|
|
2867
3009
|
};
|
|
2868
3010
|
};
|
|
2869
3011
|
/** @description Bad request — validation failed */
|
|
@@ -2893,15 +3035,6 @@ export interface paths {
|
|
|
2893
3035
|
"application/json": components["schemas"]["ErrorEnvelope"];
|
|
2894
3036
|
};
|
|
2895
3037
|
};
|
|
2896
|
-
/** @description Conflict — concurrent or terminal state */
|
|
2897
|
-
409: {
|
|
2898
|
-
headers: {
|
|
2899
|
-
[name: string]: unknown;
|
|
2900
|
-
};
|
|
2901
|
-
content: {
|
|
2902
|
-
"application/json": components["schemas"]["ErrorEnvelope"];
|
|
2903
|
-
};
|
|
2904
|
-
};
|
|
2905
3038
|
/** @description Too many requests — rate limit exceeded */
|
|
2906
3039
|
429: {
|
|
2907
3040
|
headers: {
|
|
@@ -2922,38 +3055,45 @@ export interface paths {
|
|
|
2922
3055
|
};
|
|
2923
3056
|
};
|
|
2924
3057
|
};
|
|
3058
|
+
delete?: never;
|
|
2925
3059
|
options?: never;
|
|
2926
3060
|
head?: never;
|
|
2927
3061
|
patch?: never;
|
|
2928
3062
|
trace?: never;
|
|
2929
3063
|
};
|
|
2930
|
-
"/v1/billing/
|
|
3064
|
+
"/v1/billing/byod-checkout": {
|
|
2931
3065
|
parameters: {
|
|
2932
3066
|
query?: never;
|
|
2933
3067
|
header?: never;
|
|
2934
3068
|
path?: never;
|
|
2935
3069
|
cookie?: never;
|
|
2936
3070
|
};
|
|
3071
|
+
get?: never;
|
|
3072
|
+
put?: never;
|
|
2937
3073
|
/**
|
|
2938
|
-
*
|
|
2939
|
-
* @description
|
|
3074
|
+
* Start a Stripe Checkout for BYOD slots
|
|
3075
|
+
* @description Create a Stripe Checkout Session for the BYOD subscription product (`$15/mo`, `$40.50/quarter` or `$150/yr` per slot, `device_count` slots). All three cadences the BYOP catalogue carries are sellable — `GET /pricing` publishes the amount of each. The completed session writes a `byod_subscriptions` row that `POST /v1/byod/pair` reads to enforce slot capacity.
|
|
2940
3076
|
*/
|
|
2941
|
-
|
|
3077
|
+
post: {
|
|
2942
3078
|
parameters: {
|
|
2943
3079
|
query?: never;
|
|
2944
3080
|
header?: never;
|
|
2945
3081
|
path?: never;
|
|
2946
3082
|
cookie?: never;
|
|
2947
3083
|
};
|
|
2948
|
-
requestBody?:
|
|
3084
|
+
requestBody?: {
|
|
3085
|
+
content: {
|
|
3086
|
+
"application/json": components["schemas"]["ByodCheckoutBody"];
|
|
3087
|
+
};
|
|
3088
|
+
};
|
|
2949
3089
|
responses: {
|
|
2950
|
-
/** @description
|
|
3090
|
+
/** @description BYOD checkout session */
|
|
2951
3091
|
200: {
|
|
2952
3092
|
headers: {
|
|
2953
3093
|
[name: string]: unknown;
|
|
2954
3094
|
};
|
|
2955
3095
|
content: {
|
|
2956
|
-
"application/json": components["schemas"]["
|
|
3096
|
+
"application/json": components["schemas"]["ByodCheckoutEnvelope"];
|
|
2957
3097
|
};
|
|
2958
3098
|
};
|
|
2959
3099
|
/** @description Bad request — validation failed */
|
|
@@ -2994,10 +3134,24 @@ export interface paths {
|
|
|
2994
3134
|
};
|
|
2995
3135
|
};
|
|
2996
3136
|
};
|
|
3137
|
+
delete?: never;
|
|
3138
|
+
options?: never;
|
|
3139
|
+
head?: never;
|
|
3140
|
+
patch?: never;
|
|
3141
|
+
trace?: never;
|
|
3142
|
+
};
|
|
3143
|
+
"/v1/billing/mac-checkout": {
|
|
3144
|
+
parameters: {
|
|
3145
|
+
query?: never;
|
|
3146
|
+
header?: never;
|
|
3147
|
+
path?: never;
|
|
3148
|
+
cookie?: never;
|
|
3149
|
+
};
|
|
3150
|
+
get?: never;
|
|
2997
3151
|
put?: never;
|
|
2998
3152
|
/**
|
|
2999
|
-
* Start
|
|
3000
|
-
* @description Create a Stripe
|
|
3153
|
+
* Start a Stripe Checkout for hosted macOS sessions
|
|
3154
|
+
* @description Create a Stripe Checkout Session for `quantity` rented macOS sessions, priced on a graduated ladder ($35/$30/$25/$20 per session across the 1–10 / 11–30 / 31–50 / 51+ bands). Two rules are enforced here and nowhere else: the quantity must be a whole number of packs at or above the one-pack minimum (`422 mac_quantity_not_a_pack`, the divisor echoed as `issues[0].min`), and a rented session hosts the bridge for one BYOP iPhone so sessions may not exceed the account’s BYOP lines (`422 mac_sessions_exceed_byop_lines`). Stripe’s hosted UI cannot change the quantity afterwards — use `PATCH /v1/billing/subscriptions/{id}`, which applies the same two rules.
|
|
3001
3155
|
*/
|
|
3002
3156
|
post: {
|
|
3003
3157
|
parameters: {
|
|
@@ -3006,15 +3160,19 @@ export interface paths {
|
|
|
3006
3160
|
path?: never;
|
|
3007
3161
|
cookie?: never;
|
|
3008
3162
|
};
|
|
3009
|
-
requestBody?:
|
|
3163
|
+
requestBody?: {
|
|
3164
|
+
content: {
|
|
3165
|
+
"application/json": components["schemas"]["MacCheckoutBody"];
|
|
3166
|
+
};
|
|
3167
|
+
};
|
|
3010
3168
|
responses: {
|
|
3011
|
-
/** @description
|
|
3169
|
+
/** @description macOS session checkout */
|
|
3012
3170
|
200: {
|
|
3013
3171
|
headers: {
|
|
3014
3172
|
[name: string]: unknown;
|
|
3015
3173
|
};
|
|
3016
3174
|
content: {
|
|
3017
|
-
"application/json": components["schemas"]["
|
|
3175
|
+
"application/json": components["schemas"]["MacCheckoutEnvelope"];
|
|
3018
3176
|
};
|
|
3019
3177
|
};
|
|
3020
3178
|
/** @description Bad request — validation failed */
|
|
@@ -3035,6 +3193,24 @@ export interface paths {
|
|
|
3035
3193
|
"application/json": components["schemas"]["ErrorEnvelope"];
|
|
3036
3194
|
};
|
|
3037
3195
|
};
|
|
3196
|
+
/** @description Not found */
|
|
3197
|
+
404: {
|
|
3198
|
+
headers: {
|
|
3199
|
+
[name: string]: unknown;
|
|
3200
|
+
};
|
|
3201
|
+
content: {
|
|
3202
|
+
"application/json": components["schemas"]["ErrorEnvelope"];
|
|
3203
|
+
};
|
|
3204
|
+
};
|
|
3205
|
+
/** @description Unprocessable — domain rule violation */
|
|
3206
|
+
422: {
|
|
3207
|
+
headers: {
|
|
3208
|
+
[name: string]: unknown;
|
|
3209
|
+
};
|
|
3210
|
+
content: {
|
|
3211
|
+
"application/json": components["schemas"]["ErrorEnvelope"];
|
|
3212
|
+
};
|
|
3213
|
+
};
|
|
3038
3214
|
/** @description Too many requests — rate limit exceeded */
|
|
3039
3215
|
429: {
|
|
3040
3216
|
headers: {
|
|
@@ -3061,7 +3237,7 @@ export interface paths {
|
|
|
3061
3237
|
patch?: never;
|
|
3062
3238
|
trace?: never;
|
|
3063
3239
|
};
|
|
3064
|
-
"/v1/billing/
|
|
3240
|
+
"/v1/billing/subscriptions/{id}": {
|
|
3065
3241
|
parameters: {
|
|
3066
3242
|
query?: never;
|
|
3067
3243
|
header?: never;
|
|
@@ -3072,8 +3248,8 @@ export interface paths {
|
|
|
3072
3248
|
put?: never;
|
|
3073
3249
|
post?: never;
|
|
3074
3250
|
/**
|
|
3075
|
-
*
|
|
3076
|
-
* @description
|
|
3251
|
+
* Cancel a subscription
|
|
3252
|
+
* @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.
|
|
3077
3253
|
*/
|
|
3078
3254
|
delete: {
|
|
3079
3255
|
parameters: {
|
|
@@ -3086,7 +3262,7 @@ export interface paths {
|
|
|
3086
3262
|
};
|
|
3087
3263
|
requestBody?: never;
|
|
3088
3264
|
responses: {
|
|
3089
|
-
/** @description
|
|
3265
|
+
/** @description Subscription cancelled */
|
|
3090
3266
|
200: {
|
|
3091
3267
|
headers: {
|
|
3092
3268
|
[name: string]: unknown;
|
|
@@ -3122,6 +3298,15 @@ export interface paths {
|
|
|
3122
3298
|
"application/json": components["schemas"]["ErrorEnvelope"];
|
|
3123
3299
|
};
|
|
3124
3300
|
};
|
|
3301
|
+
/** @description Conflict — concurrent or terminal state */
|
|
3302
|
+
409: {
|
|
3303
|
+
headers: {
|
|
3304
|
+
[name: string]: unknown;
|
|
3305
|
+
};
|
|
3306
|
+
content: {
|
|
3307
|
+
"application/json": components["schemas"]["ErrorEnvelope"];
|
|
3308
|
+
};
|
|
3309
|
+
};
|
|
3125
3310
|
/** @description Too many requests — rate limit exceeded */
|
|
3126
3311
|
429: {
|
|
3127
3312
|
headers: {
|
|
@@ -3144,23 +3329,11 @@ export interface paths {
|
|
|
3144
3329
|
};
|
|
3145
3330
|
options?: never;
|
|
3146
3331
|
head?: never;
|
|
3147
|
-
patch?: never;
|
|
3148
|
-
trace?: never;
|
|
3149
|
-
};
|
|
3150
|
-
"/v1/billing/payment-methods/{id}/default": {
|
|
3151
|
-
parameters: {
|
|
3152
|
-
query?: never;
|
|
3153
|
-
header?: never;
|
|
3154
|
-
path?: never;
|
|
3155
|
-
cookie?: never;
|
|
3156
|
-
};
|
|
3157
|
-
get?: never;
|
|
3158
|
-
put?: never;
|
|
3159
3332
|
/**
|
|
3160
|
-
*
|
|
3161
|
-
* @description
|
|
3333
|
+
* Change a subscription’s quantity
|
|
3334
|
+
* @description Set the quantity on the subscription’s single quantity-adjustable item — hosted macOS sessions, or BYOP slots. Both directions of the 1:1 rule are enforced: raising sessions above the account’s BYOP lines is `422 mac_sessions_exceed_byop_lines`, and lowering BYOP below the macOS sessions already rented is `422 byop_reduction_strands_mac_sessions`. A macOS quantity must additionally be a whole pack (`422 mac_quantity_not_a_pack`). A subscription that does not carry exactly one adjustable item — a per-line rental, or a wholesale master subscription whose quantities are pushed by metering — is refused `409 subscription_not_quantity_adjustable`.
|
|
3162
3335
|
*/
|
|
3163
|
-
|
|
3336
|
+
patch: {
|
|
3164
3337
|
parameters: {
|
|
3165
3338
|
query?: never;
|
|
3166
3339
|
header?: never;
|
|
@@ -3169,15 +3342,19 @@ export interface paths {
|
|
|
3169
3342
|
};
|
|
3170
3343
|
cookie?: never;
|
|
3171
3344
|
};
|
|
3172
|
-
requestBody?:
|
|
3345
|
+
requestBody?: {
|
|
3346
|
+
content: {
|
|
3347
|
+
"application/json": components["schemas"]["SubscriptionQuantityBody"];
|
|
3348
|
+
};
|
|
3349
|
+
};
|
|
3173
3350
|
responses: {
|
|
3174
|
-
/** @description
|
|
3351
|
+
/** @description Quantity updated */
|
|
3175
3352
|
200: {
|
|
3176
3353
|
headers: {
|
|
3177
3354
|
[name: string]: unknown;
|
|
3178
3355
|
};
|
|
3179
3356
|
content: {
|
|
3180
|
-
"application/json": components["schemas"]["
|
|
3357
|
+
"application/json": components["schemas"]["SubscriptionQuantityEnvelope"];
|
|
3181
3358
|
};
|
|
3182
3359
|
};
|
|
3183
3360
|
/** @description Bad request — validation failed */
|
|
@@ -3198,6 +3375,15 @@ export interface paths {
|
|
|
3198
3375
|
"application/json": components["schemas"]["ErrorEnvelope"];
|
|
3199
3376
|
};
|
|
3200
3377
|
};
|
|
3378
|
+
/** @description Forbidden — caller authenticated but not allowed */
|
|
3379
|
+
403: {
|
|
3380
|
+
headers: {
|
|
3381
|
+
[name: string]: unknown;
|
|
3382
|
+
};
|
|
3383
|
+
content: {
|
|
3384
|
+
"application/json": components["schemas"]["ErrorEnvelope"];
|
|
3385
|
+
};
|
|
3386
|
+
};
|
|
3201
3387
|
/** @description Not found */
|
|
3202
3388
|
404: {
|
|
3203
3389
|
headers: {
|
|
@@ -3207,6 +3393,24 @@ export interface paths {
|
|
|
3207
3393
|
"application/json": components["schemas"]["ErrorEnvelope"];
|
|
3208
3394
|
};
|
|
3209
3395
|
};
|
|
3396
|
+
/** @description Conflict — concurrent or terminal state */
|
|
3397
|
+
409: {
|
|
3398
|
+
headers: {
|
|
3399
|
+
[name: string]: unknown;
|
|
3400
|
+
};
|
|
3401
|
+
content: {
|
|
3402
|
+
"application/json": components["schemas"]["ErrorEnvelope"];
|
|
3403
|
+
};
|
|
3404
|
+
};
|
|
3405
|
+
/** @description Unprocessable — domain rule violation */
|
|
3406
|
+
422: {
|
|
3407
|
+
headers: {
|
|
3408
|
+
[name: string]: unknown;
|
|
3409
|
+
};
|
|
3410
|
+
content: {
|
|
3411
|
+
"application/json": components["schemas"]["ErrorEnvelope"];
|
|
3412
|
+
};
|
|
3413
|
+
};
|
|
3210
3414
|
/** @description Too many requests — rate limit exceeded */
|
|
3211
3415
|
429: {
|
|
3212
3416
|
headers: {
|
|
@@ -3227,13 +3431,9 @@ export interface paths {
|
|
|
3227
3431
|
};
|
|
3228
3432
|
};
|
|
3229
3433
|
};
|
|
3230
|
-
delete?: never;
|
|
3231
|
-
options?: never;
|
|
3232
|
-
head?: never;
|
|
3233
|
-
patch?: never;
|
|
3234
3434
|
trace?: never;
|
|
3235
3435
|
};
|
|
3236
|
-
"/v1/
|
|
3436
|
+
"/v1/billing/subscriptions": {
|
|
3237
3437
|
parameters: {
|
|
3238
3438
|
query?: never;
|
|
3239
3439
|
header?: never;
|
|
@@ -3241,32 +3441,25 @@ export interface paths {
|
|
|
3241
3441
|
cookie?: never;
|
|
3242
3442
|
};
|
|
3243
3443
|
/**
|
|
3244
|
-
* List
|
|
3245
|
-
* @description
|
|
3444
|
+
* List Stripe subscriptions
|
|
3445
|
+
* @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.
|
|
3246
3446
|
*/
|
|
3247
3447
|
get: {
|
|
3248
3448
|
parameters: {
|
|
3249
|
-
query?:
|
|
3250
|
-
line_id?: string;
|
|
3251
|
-
status?: "queued" | "sent" | "delivered" | "read" | "failed";
|
|
3252
|
-
direction?: "outbound" | "inbound";
|
|
3253
|
-
kind?: "message" | "voice" | "reaction";
|
|
3254
|
-
cursor?: string;
|
|
3255
|
-
limit?: number;
|
|
3256
|
-
};
|
|
3449
|
+
query?: never;
|
|
3257
3450
|
header?: never;
|
|
3258
3451
|
path?: never;
|
|
3259
3452
|
cookie?: never;
|
|
3260
3453
|
};
|
|
3261
3454
|
requestBody?: never;
|
|
3262
3455
|
responses: {
|
|
3263
|
-
/** @description
|
|
3456
|
+
/** @description Subscription list */
|
|
3264
3457
|
200: {
|
|
3265
3458
|
headers: {
|
|
3266
3459
|
[name: string]: unknown;
|
|
3267
3460
|
};
|
|
3268
3461
|
content: {
|
|
3269
|
-
"application/json": components["schemas"]["
|
|
3462
|
+
"application/json": components["schemas"]["SubscriptionListEnvelope"];
|
|
3270
3463
|
};
|
|
3271
3464
|
};
|
|
3272
3465
|
/** @description Bad request — validation failed */
|
|
@@ -3308,15 +3501,478 @@ export interface paths {
|
|
|
3308
3501
|
};
|
|
3309
3502
|
};
|
|
3310
3503
|
put?: never;
|
|
3311
|
-
|
|
3312
|
-
|
|
3313
|
-
|
|
3314
|
-
|
|
3315
|
-
|
|
3316
|
-
|
|
3317
|
-
|
|
3318
|
-
|
|
3319
|
-
|
|
3504
|
+
post?: never;
|
|
3505
|
+
delete?: never;
|
|
3506
|
+
options?: never;
|
|
3507
|
+
head?: never;
|
|
3508
|
+
patch?: never;
|
|
3509
|
+
trace?: never;
|
|
3510
|
+
};
|
|
3511
|
+
"/v1/billing/invoices": {
|
|
3512
|
+
parameters: {
|
|
3513
|
+
query?: never;
|
|
3514
|
+
header?: never;
|
|
3515
|
+
path?: never;
|
|
3516
|
+
cookie?: never;
|
|
3517
|
+
};
|
|
3518
|
+
/**
|
|
3519
|
+
* List Stripe invoices
|
|
3520
|
+
* @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.
|
|
3521
|
+
*/
|
|
3522
|
+
get: {
|
|
3523
|
+
parameters: {
|
|
3524
|
+
query?: never;
|
|
3525
|
+
header?: never;
|
|
3526
|
+
path?: never;
|
|
3527
|
+
cookie?: never;
|
|
3528
|
+
};
|
|
3529
|
+
requestBody?: never;
|
|
3530
|
+
responses: {
|
|
3531
|
+
/** @description Invoice list */
|
|
3532
|
+
200: {
|
|
3533
|
+
headers: {
|
|
3534
|
+
[name: string]: unknown;
|
|
3535
|
+
};
|
|
3536
|
+
content: {
|
|
3537
|
+
"application/json": components["schemas"]["InvoiceListEnvelope"];
|
|
3538
|
+
};
|
|
3539
|
+
};
|
|
3540
|
+
/** @description Bad request — validation failed */
|
|
3541
|
+
400: {
|
|
3542
|
+
headers: {
|
|
3543
|
+
[name: string]: unknown;
|
|
3544
|
+
};
|
|
3545
|
+
content: {
|
|
3546
|
+
"application/json": components["schemas"]["ErrorEnvelope"];
|
|
3547
|
+
};
|
|
3548
|
+
};
|
|
3549
|
+
/** @description Unauthenticated — missing or invalid bearer token */
|
|
3550
|
+
401: {
|
|
3551
|
+
headers: {
|
|
3552
|
+
[name: string]: unknown;
|
|
3553
|
+
};
|
|
3554
|
+
content: {
|
|
3555
|
+
"application/json": components["schemas"]["ErrorEnvelope"];
|
|
3556
|
+
};
|
|
3557
|
+
};
|
|
3558
|
+
/** @description Too many requests — rate limit exceeded */
|
|
3559
|
+
429: {
|
|
3560
|
+
headers: {
|
|
3561
|
+
[name: string]: unknown;
|
|
3562
|
+
};
|
|
3563
|
+
content: {
|
|
3564
|
+
"application/json": components["schemas"]["ErrorEnvelope"];
|
|
3565
|
+
};
|
|
3566
|
+
};
|
|
3567
|
+
/** @description Internal server error */
|
|
3568
|
+
500: {
|
|
3569
|
+
headers: {
|
|
3570
|
+
[name: string]: unknown;
|
|
3571
|
+
};
|
|
3572
|
+
content: {
|
|
3573
|
+
"application/json": components["schemas"]["ErrorEnvelope"];
|
|
3574
|
+
};
|
|
3575
|
+
};
|
|
3576
|
+
};
|
|
3577
|
+
};
|
|
3578
|
+
put?: never;
|
|
3579
|
+
post?: never;
|
|
3580
|
+
delete?: never;
|
|
3581
|
+
options?: never;
|
|
3582
|
+
head?: never;
|
|
3583
|
+
patch?: never;
|
|
3584
|
+
trace?: never;
|
|
3585
|
+
};
|
|
3586
|
+
"/v1/billing/payment-methods": {
|
|
3587
|
+
parameters: {
|
|
3588
|
+
query?: never;
|
|
3589
|
+
header?: never;
|
|
3590
|
+
path?: never;
|
|
3591
|
+
cookie?: never;
|
|
3592
|
+
};
|
|
3593
|
+
/**
|
|
3594
|
+
* List payment methods
|
|
3595
|
+
* @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.
|
|
3596
|
+
*/
|
|
3597
|
+
get: {
|
|
3598
|
+
parameters: {
|
|
3599
|
+
query?: never;
|
|
3600
|
+
header?: never;
|
|
3601
|
+
path?: never;
|
|
3602
|
+
cookie?: never;
|
|
3603
|
+
};
|
|
3604
|
+
requestBody?: never;
|
|
3605
|
+
responses: {
|
|
3606
|
+
/** @description Payment methods */
|
|
3607
|
+
200: {
|
|
3608
|
+
headers: {
|
|
3609
|
+
[name: string]: unknown;
|
|
3610
|
+
};
|
|
3611
|
+
content: {
|
|
3612
|
+
"application/json": components["schemas"]["PaymentMethodListEnvelope"];
|
|
3613
|
+
};
|
|
3614
|
+
};
|
|
3615
|
+
/** @description Bad request — validation failed */
|
|
3616
|
+
400: {
|
|
3617
|
+
headers: {
|
|
3618
|
+
[name: string]: unknown;
|
|
3619
|
+
};
|
|
3620
|
+
content: {
|
|
3621
|
+
"application/json": components["schemas"]["ErrorEnvelope"];
|
|
3622
|
+
};
|
|
3623
|
+
};
|
|
3624
|
+
/** @description Unauthenticated — missing or invalid bearer token */
|
|
3625
|
+
401: {
|
|
3626
|
+
headers: {
|
|
3627
|
+
[name: string]: unknown;
|
|
3628
|
+
};
|
|
3629
|
+
content: {
|
|
3630
|
+
"application/json": components["schemas"]["ErrorEnvelope"];
|
|
3631
|
+
};
|
|
3632
|
+
};
|
|
3633
|
+
/** @description Too many requests — rate limit exceeded */
|
|
3634
|
+
429: {
|
|
3635
|
+
headers: {
|
|
3636
|
+
[name: string]: unknown;
|
|
3637
|
+
};
|
|
3638
|
+
content: {
|
|
3639
|
+
"application/json": components["schemas"]["ErrorEnvelope"];
|
|
3640
|
+
};
|
|
3641
|
+
};
|
|
3642
|
+
/** @description Internal server error */
|
|
3643
|
+
500: {
|
|
3644
|
+
headers: {
|
|
3645
|
+
[name: string]: unknown;
|
|
3646
|
+
};
|
|
3647
|
+
content: {
|
|
3648
|
+
"application/json": components["schemas"]["ErrorEnvelope"];
|
|
3649
|
+
};
|
|
3650
|
+
};
|
|
3651
|
+
};
|
|
3652
|
+
};
|
|
3653
|
+
put?: never;
|
|
3654
|
+
/**
|
|
3655
|
+
* Start adding a payment method
|
|
3656
|
+
* @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.
|
|
3657
|
+
*/
|
|
3658
|
+
post: {
|
|
3659
|
+
parameters: {
|
|
3660
|
+
query?: never;
|
|
3661
|
+
header?: never;
|
|
3662
|
+
path?: never;
|
|
3663
|
+
cookie?: never;
|
|
3664
|
+
};
|
|
3665
|
+
requestBody?: never;
|
|
3666
|
+
responses: {
|
|
3667
|
+
/** @description Setup intent */
|
|
3668
|
+
200: {
|
|
3669
|
+
headers: {
|
|
3670
|
+
[name: string]: unknown;
|
|
3671
|
+
};
|
|
3672
|
+
content: {
|
|
3673
|
+
"application/json": components["schemas"]["SetupIntent"];
|
|
3674
|
+
};
|
|
3675
|
+
};
|
|
3676
|
+
/** @description Bad request — validation failed */
|
|
3677
|
+
400: {
|
|
3678
|
+
headers: {
|
|
3679
|
+
[name: string]: unknown;
|
|
3680
|
+
};
|
|
3681
|
+
content: {
|
|
3682
|
+
"application/json": components["schemas"]["ErrorEnvelope"];
|
|
3683
|
+
};
|
|
3684
|
+
};
|
|
3685
|
+
/** @description Unauthenticated — missing or invalid bearer token */
|
|
3686
|
+
401: {
|
|
3687
|
+
headers: {
|
|
3688
|
+
[name: string]: unknown;
|
|
3689
|
+
};
|
|
3690
|
+
content: {
|
|
3691
|
+
"application/json": components["schemas"]["ErrorEnvelope"];
|
|
3692
|
+
};
|
|
3693
|
+
};
|
|
3694
|
+
/** @description Too many requests — rate limit exceeded */
|
|
3695
|
+
429: {
|
|
3696
|
+
headers: {
|
|
3697
|
+
[name: string]: unknown;
|
|
3698
|
+
};
|
|
3699
|
+
content: {
|
|
3700
|
+
"application/json": components["schemas"]["ErrorEnvelope"];
|
|
3701
|
+
};
|
|
3702
|
+
};
|
|
3703
|
+
/** @description Internal server error */
|
|
3704
|
+
500: {
|
|
3705
|
+
headers: {
|
|
3706
|
+
[name: string]: unknown;
|
|
3707
|
+
};
|
|
3708
|
+
content: {
|
|
3709
|
+
"application/json": components["schemas"]["ErrorEnvelope"];
|
|
3710
|
+
};
|
|
3711
|
+
};
|
|
3712
|
+
};
|
|
3713
|
+
};
|
|
3714
|
+
delete?: never;
|
|
3715
|
+
options?: never;
|
|
3716
|
+
head?: never;
|
|
3717
|
+
patch?: never;
|
|
3718
|
+
trace?: never;
|
|
3719
|
+
};
|
|
3720
|
+
"/v1/billing/payment-methods/{id}": {
|
|
3721
|
+
parameters: {
|
|
3722
|
+
query?: never;
|
|
3723
|
+
header?: never;
|
|
3724
|
+
path?: never;
|
|
3725
|
+
cookie?: never;
|
|
3726
|
+
};
|
|
3727
|
+
get?: never;
|
|
3728
|
+
put?: never;
|
|
3729
|
+
post?: never;
|
|
3730
|
+
/**
|
|
3731
|
+
* Remove a payment method
|
|
3732
|
+
* @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.
|
|
3733
|
+
*/
|
|
3734
|
+
delete: {
|
|
3735
|
+
parameters: {
|
|
3736
|
+
query?: never;
|
|
3737
|
+
header?: never;
|
|
3738
|
+
path: {
|
|
3739
|
+
id: string;
|
|
3740
|
+
};
|
|
3741
|
+
cookie?: never;
|
|
3742
|
+
};
|
|
3743
|
+
requestBody?: never;
|
|
3744
|
+
responses: {
|
|
3745
|
+
/** @description Payment method removed */
|
|
3746
|
+
200: {
|
|
3747
|
+
headers: {
|
|
3748
|
+
[name: string]: unknown;
|
|
3749
|
+
};
|
|
3750
|
+
content: {
|
|
3751
|
+
"application/json": components["schemas"]["BillingMessage"];
|
|
3752
|
+
};
|
|
3753
|
+
};
|
|
3754
|
+
/** @description Bad request — validation failed */
|
|
3755
|
+
400: {
|
|
3756
|
+
headers: {
|
|
3757
|
+
[name: string]: unknown;
|
|
3758
|
+
};
|
|
3759
|
+
content: {
|
|
3760
|
+
"application/json": components["schemas"]["ErrorEnvelope"];
|
|
3761
|
+
};
|
|
3762
|
+
};
|
|
3763
|
+
/** @description Unauthenticated — missing or invalid bearer token */
|
|
3764
|
+
401: {
|
|
3765
|
+
headers: {
|
|
3766
|
+
[name: string]: unknown;
|
|
3767
|
+
};
|
|
3768
|
+
content: {
|
|
3769
|
+
"application/json": components["schemas"]["ErrorEnvelope"];
|
|
3770
|
+
};
|
|
3771
|
+
};
|
|
3772
|
+
/** @description Not found */
|
|
3773
|
+
404: {
|
|
3774
|
+
headers: {
|
|
3775
|
+
[name: string]: unknown;
|
|
3776
|
+
};
|
|
3777
|
+
content: {
|
|
3778
|
+
"application/json": components["schemas"]["ErrorEnvelope"];
|
|
3779
|
+
};
|
|
3780
|
+
};
|
|
3781
|
+
/** @description Too many requests — rate limit exceeded */
|
|
3782
|
+
429: {
|
|
3783
|
+
headers: {
|
|
3784
|
+
[name: string]: unknown;
|
|
3785
|
+
};
|
|
3786
|
+
content: {
|
|
3787
|
+
"application/json": components["schemas"]["ErrorEnvelope"];
|
|
3788
|
+
};
|
|
3789
|
+
};
|
|
3790
|
+
/** @description Internal server error */
|
|
3791
|
+
500: {
|
|
3792
|
+
headers: {
|
|
3793
|
+
[name: string]: unknown;
|
|
3794
|
+
};
|
|
3795
|
+
content: {
|
|
3796
|
+
"application/json": components["schemas"]["ErrorEnvelope"];
|
|
3797
|
+
};
|
|
3798
|
+
};
|
|
3799
|
+
};
|
|
3800
|
+
};
|
|
3801
|
+
options?: never;
|
|
3802
|
+
head?: never;
|
|
3803
|
+
patch?: never;
|
|
3804
|
+
trace?: never;
|
|
3805
|
+
};
|
|
3806
|
+
"/v1/billing/payment-methods/{id}/default": {
|
|
3807
|
+
parameters: {
|
|
3808
|
+
query?: never;
|
|
3809
|
+
header?: never;
|
|
3810
|
+
path?: never;
|
|
3811
|
+
cookie?: never;
|
|
3812
|
+
};
|
|
3813
|
+
get?: never;
|
|
3814
|
+
put?: never;
|
|
3815
|
+
/**
|
|
3816
|
+
* Set default payment method
|
|
3817
|
+
* @description Mark the payment method as the default for invoice charges. Future invoices on existing subscriptions automatically draw from this card.
|
|
3818
|
+
*/
|
|
3819
|
+
post: {
|
|
3820
|
+
parameters: {
|
|
3821
|
+
query?: never;
|
|
3822
|
+
header?: never;
|
|
3823
|
+
path: {
|
|
3824
|
+
id: string;
|
|
3825
|
+
};
|
|
3826
|
+
cookie?: never;
|
|
3827
|
+
};
|
|
3828
|
+
requestBody?: never;
|
|
3829
|
+
responses: {
|
|
3830
|
+
/** @description Default payment method updated */
|
|
3831
|
+
200: {
|
|
3832
|
+
headers: {
|
|
3833
|
+
[name: string]: unknown;
|
|
3834
|
+
};
|
|
3835
|
+
content: {
|
|
3836
|
+
"application/json": components["schemas"]["BillingMessage"];
|
|
3837
|
+
};
|
|
3838
|
+
};
|
|
3839
|
+
/** @description Bad request — validation failed */
|
|
3840
|
+
400: {
|
|
3841
|
+
headers: {
|
|
3842
|
+
[name: string]: unknown;
|
|
3843
|
+
};
|
|
3844
|
+
content: {
|
|
3845
|
+
"application/json": components["schemas"]["ErrorEnvelope"];
|
|
3846
|
+
};
|
|
3847
|
+
};
|
|
3848
|
+
/** @description Unauthenticated — missing or invalid bearer token */
|
|
3849
|
+
401: {
|
|
3850
|
+
headers: {
|
|
3851
|
+
[name: string]: unknown;
|
|
3852
|
+
};
|
|
3853
|
+
content: {
|
|
3854
|
+
"application/json": components["schemas"]["ErrorEnvelope"];
|
|
3855
|
+
};
|
|
3856
|
+
};
|
|
3857
|
+
/** @description Not found */
|
|
3858
|
+
404: {
|
|
3859
|
+
headers: {
|
|
3860
|
+
[name: string]: unknown;
|
|
3861
|
+
};
|
|
3862
|
+
content: {
|
|
3863
|
+
"application/json": components["schemas"]["ErrorEnvelope"];
|
|
3864
|
+
};
|
|
3865
|
+
};
|
|
3866
|
+
/** @description Too many requests — rate limit exceeded */
|
|
3867
|
+
429: {
|
|
3868
|
+
headers: {
|
|
3869
|
+
[name: string]: unknown;
|
|
3870
|
+
};
|
|
3871
|
+
content: {
|
|
3872
|
+
"application/json": components["schemas"]["ErrorEnvelope"];
|
|
3873
|
+
};
|
|
3874
|
+
};
|
|
3875
|
+
/** @description Internal server error */
|
|
3876
|
+
500: {
|
|
3877
|
+
headers: {
|
|
3878
|
+
[name: string]: unknown;
|
|
3879
|
+
};
|
|
3880
|
+
content: {
|
|
3881
|
+
"application/json": components["schemas"]["ErrorEnvelope"];
|
|
3882
|
+
};
|
|
3883
|
+
};
|
|
3884
|
+
};
|
|
3885
|
+
};
|
|
3886
|
+
delete?: never;
|
|
3887
|
+
options?: never;
|
|
3888
|
+
head?: never;
|
|
3889
|
+
patch?: never;
|
|
3890
|
+
trace?: never;
|
|
3891
|
+
};
|
|
3892
|
+
"/v1/messages": {
|
|
3893
|
+
parameters: {
|
|
3894
|
+
query?: never;
|
|
3895
|
+
header?: never;
|
|
3896
|
+
path?: never;
|
|
3897
|
+
cookie?: never;
|
|
3898
|
+
};
|
|
3899
|
+
/**
|
|
3900
|
+
* List messages
|
|
3901
|
+
* @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`, `direction`, or `kind` (`message` drops the separate reaction/voice rows for a clean feed; `reaction`/`voice` fetch only those; omit for all kinds); pass an opaque `cursor` from the previous page's `next_cursor` to advance.
|
|
3902
|
+
*/
|
|
3903
|
+
get: {
|
|
3904
|
+
parameters: {
|
|
3905
|
+
query?: {
|
|
3906
|
+
line_id?: string;
|
|
3907
|
+
status?: "queued" | "sent" | "delivered" | "read" | "failed";
|
|
3908
|
+
direction?: "outbound" | "inbound";
|
|
3909
|
+
kind?: "message" | "voice" | "reaction";
|
|
3910
|
+
cursor?: string;
|
|
3911
|
+
limit?: number;
|
|
3912
|
+
};
|
|
3913
|
+
header?: never;
|
|
3914
|
+
path?: never;
|
|
3915
|
+
cookie?: never;
|
|
3916
|
+
};
|
|
3917
|
+
requestBody?: never;
|
|
3918
|
+
responses: {
|
|
3919
|
+
/** @description Cursored message list */
|
|
3920
|
+
200: {
|
|
3921
|
+
headers: {
|
|
3922
|
+
[name: string]: unknown;
|
|
3923
|
+
};
|
|
3924
|
+
content: {
|
|
3925
|
+
"application/json": components["schemas"]["CursoredMessagesEnvelope"];
|
|
3926
|
+
};
|
|
3927
|
+
};
|
|
3928
|
+
/** @description Bad request — validation failed */
|
|
3929
|
+
400: {
|
|
3930
|
+
headers: {
|
|
3931
|
+
[name: string]: unknown;
|
|
3932
|
+
};
|
|
3933
|
+
content: {
|
|
3934
|
+
"application/json": components["schemas"]["ErrorEnvelope"];
|
|
3935
|
+
};
|
|
3936
|
+
};
|
|
3937
|
+
/** @description Unauthenticated — missing or invalid bearer token */
|
|
3938
|
+
401: {
|
|
3939
|
+
headers: {
|
|
3940
|
+
[name: string]: unknown;
|
|
3941
|
+
};
|
|
3942
|
+
content: {
|
|
3943
|
+
"application/json": components["schemas"]["ErrorEnvelope"];
|
|
3944
|
+
};
|
|
3945
|
+
};
|
|
3946
|
+
/** @description Too many requests — rate limit exceeded */
|
|
3947
|
+
429: {
|
|
3948
|
+
headers: {
|
|
3949
|
+
[name: string]: unknown;
|
|
3950
|
+
};
|
|
3951
|
+
content: {
|
|
3952
|
+
"application/json": components["schemas"]["ErrorEnvelope"];
|
|
3953
|
+
};
|
|
3954
|
+
};
|
|
3955
|
+
/** @description Internal server error */
|
|
3956
|
+
500: {
|
|
3957
|
+
headers: {
|
|
3958
|
+
[name: string]: unknown;
|
|
3959
|
+
};
|
|
3960
|
+
content: {
|
|
3961
|
+
"application/json": components["schemas"]["ErrorEnvelope"];
|
|
3962
|
+
};
|
|
3963
|
+
};
|
|
3964
|
+
};
|
|
3965
|
+
};
|
|
3966
|
+
put?: never;
|
|
3967
|
+
/**
|
|
3968
|
+
* Send a message
|
|
3969
|
+
* @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`.
|
|
3970
|
+
*/
|
|
3971
|
+
post: {
|
|
3972
|
+
parameters: {
|
|
3973
|
+
query?: never;
|
|
3974
|
+
header?: never;
|
|
3975
|
+
path?: never;
|
|
3320
3976
|
cookie?: never;
|
|
3321
3977
|
};
|
|
3322
3978
|
requestBody?: {
|
|
@@ -3392,8 +4048,196 @@ export interface paths {
|
|
|
3392
4048
|
"application/json": components["schemas"]["ErrorEnvelope"];
|
|
3393
4049
|
};
|
|
3394
4050
|
};
|
|
3395
|
-
/** @description Not found */
|
|
3396
|
-
404: {
|
|
4051
|
+
/** @description Not found */
|
|
4052
|
+
404: {
|
|
4053
|
+
headers: {
|
|
4054
|
+
[name: string]: unknown;
|
|
4055
|
+
};
|
|
4056
|
+
content: {
|
|
4057
|
+
"application/json": components["schemas"]["ErrorEnvelope"];
|
|
4058
|
+
};
|
|
4059
|
+
};
|
|
4060
|
+
/** @description Conflict — concurrent or terminal state */
|
|
4061
|
+
409: {
|
|
4062
|
+
headers: {
|
|
4063
|
+
[name: string]: unknown;
|
|
4064
|
+
};
|
|
4065
|
+
content: {
|
|
4066
|
+
"application/json": components["schemas"]["ErrorEnvelope"];
|
|
4067
|
+
};
|
|
4068
|
+
};
|
|
4069
|
+
/** @description Unprocessable — domain rule violation */
|
|
4070
|
+
422: {
|
|
4071
|
+
headers: {
|
|
4072
|
+
[name: string]: unknown;
|
|
4073
|
+
};
|
|
4074
|
+
content: {
|
|
4075
|
+
"application/json": components["schemas"]["ErrorEnvelope"];
|
|
4076
|
+
};
|
|
4077
|
+
};
|
|
4078
|
+
/** @description Too many requests — rate limit exceeded */
|
|
4079
|
+
429: {
|
|
4080
|
+
headers: {
|
|
4081
|
+
[name: string]: unknown;
|
|
4082
|
+
};
|
|
4083
|
+
content: {
|
|
4084
|
+
"application/json": components["schemas"]["ErrorEnvelope"];
|
|
4085
|
+
};
|
|
4086
|
+
};
|
|
4087
|
+
/** @description Internal server error */
|
|
4088
|
+
500: {
|
|
4089
|
+
headers: {
|
|
4090
|
+
[name: string]: unknown;
|
|
4091
|
+
};
|
|
4092
|
+
content: {
|
|
4093
|
+
"application/json": components["schemas"]["ErrorEnvelope"];
|
|
4094
|
+
};
|
|
4095
|
+
};
|
|
4096
|
+
};
|
|
4097
|
+
};
|
|
4098
|
+
delete?: never;
|
|
4099
|
+
options?: never;
|
|
4100
|
+
head?: never;
|
|
4101
|
+
patch?: never;
|
|
4102
|
+
trace?: never;
|
|
4103
|
+
};
|
|
4104
|
+
"/v1/messages/{id}/reactions": {
|
|
4105
|
+
parameters: {
|
|
4106
|
+
query?: never;
|
|
4107
|
+
header?: never;
|
|
4108
|
+
path?: never;
|
|
4109
|
+
cookie?: never;
|
|
4110
|
+
};
|
|
4111
|
+
get?: never;
|
|
4112
|
+
put?: never;
|
|
4113
|
+
/**
|
|
4114
|
+
* Add or replace a tapback
|
|
4115
|
+
* @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.
|
|
4116
|
+
*/
|
|
4117
|
+
post: {
|
|
4118
|
+
parameters: {
|
|
4119
|
+
query?: never;
|
|
4120
|
+
header?: never;
|
|
4121
|
+
path: {
|
|
4122
|
+
id: string;
|
|
4123
|
+
};
|
|
4124
|
+
cookie?: never;
|
|
4125
|
+
};
|
|
4126
|
+
requestBody?: {
|
|
4127
|
+
content: {
|
|
4128
|
+
"application/json": components["schemas"]["SendReactionRequest"];
|
|
4129
|
+
};
|
|
4130
|
+
};
|
|
4131
|
+
responses: {
|
|
4132
|
+
/** @description Reaction queued (added or replaced) */
|
|
4133
|
+
202: {
|
|
4134
|
+
headers: {
|
|
4135
|
+
[name: string]: unknown;
|
|
4136
|
+
};
|
|
4137
|
+
content: {
|
|
4138
|
+
"application/json": components["schemas"]["ReactionEnvelope"];
|
|
4139
|
+
};
|
|
4140
|
+
};
|
|
4141
|
+
/** @description Bad request — validation failed */
|
|
4142
|
+
400: {
|
|
4143
|
+
headers: {
|
|
4144
|
+
[name: string]: unknown;
|
|
4145
|
+
};
|
|
4146
|
+
content: {
|
|
4147
|
+
"application/json": components["schemas"]["ErrorEnvelope"];
|
|
4148
|
+
};
|
|
4149
|
+
};
|
|
4150
|
+
/** @description Unauthenticated — missing or invalid bearer token */
|
|
4151
|
+
401: {
|
|
4152
|
+
headers: {
|
|
4153
|
+
[name: string]: unknown;
|
|
4154
|
+
};
|
|
4155
|
+
content: {
|
|
4156
|
+
"application/json": components["schemas"]["ErrorEnvelope"];
|
|
4157
|
+
};
|
|
4158
|
+
};
|
|
4159
|
+
/** @description Forbidden — caller authenticated but not allowed */
|
|
4160
|
+
403: {
|
|
4161
|
+
headers: {
|
|
4162
|
+
[name: string]: unknown;
|
|
4163
|
+
};
|
|
4164
|
+
content: {
|
|
4165
|
+
"application/json": components["schemas"]["ErrorEnvelope"];
|
|
4166
|
+
};
|
|
4167
|
+
};
|
|
4168
|
+
/** @description Not found */
|
|
4169
|
+
404: {
|
|
4170
|
+
headers: {
|
|
4171
|
+
[name: string]: unknown;
|
|
4172
|
+
};
|
|
4173
|
+
content: {
|
|
4174
|
+
"application/json": components["schemas"]["ErrorEnvelope"];
|
|
4175
|
+
};
|
|
4176
|
+
};
|
|
4177
|
+
/** @description Unprocessable — domain rule violation */
|
|
4178
|
+
422: {
|
|
4179
|
+
headers: {
|
|
4180
|
+
[name: string]: unknown;
|
|
4181
|
+
};
|
|
4182
|
+
content: {
|
|
4183
|
+
"application/json": components["schemas"]["ErrorEnvelope"];
|
|
4184
|
+
};
|
|
4185
|
+
};
|
|
4186
|
+
/** @description Too many requests — rate limit exceeded */
|
|
4187
|
+
429: {
|
|
4188
|
+
headers: {
|
|
4189
|
+
[name: string]: unknown;
|
|
4190
|
+
};
|
|
4191
|
+
content: {
|
|
4192
|
+
"application/json": components["schemas"]["ErrorEnvelope"];
|
|
4193
|
+
};
|
|
4194
|
+
};
|
|
4195
|
+
/** @description Internal server error */
|
|
4196
|
+
500: {
|
|
4197
|
+
headers: {
|
|
4198
|
+
[name: string]: unknown;
|
|
4199
|
+
};
|
|
4200
|
+
content: {
|
|
4201
|
+
"application/json": components["schemas"]["ErrorEnvelope"];
|
|
4202
|
+
};
|
|
4203
|
+
};
|
|
4204
|
+
};
|
|
4205
|
+
};
|
|
4206
|
+
/**
|
|
4207
|
+
* Remove a tapback
|
|
4208
|
+
* @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.
|
|
4209
|
+
*/
|
|
4210
|
+
delete: {
|
|
4211
|
+
parameters: {
|
|
4212
|
+
query?: never;
|
|
4213
|
+
header?: never;
|
|
4214
|
+
path: {
|
|
4215
|
+
id: string;
|
|
4216
|
+
};
|
|
4217
|
+
cookie?: never;
|
|
4218
|
+
};
|
|
4219
|
+
requestBody?: never;
|
|
4220
|
+
responses: {
|
|
4221
|
+
/** @description Reaction removed (idempotent — no-op when nothing to remove) */
|
|
4222
|
+
200: {
|
|
4223
|
+
headers: {
|
|
4224
|
+
[name: string]: unknown;
|
|
4225
|
+
};
|
|
4226
|
+
content: {
|
|
4227
|
+
"application/json": components["schemas"]["ReactionRemovalEnvelope"];
|
|
4228
|
+
};
|
|
4229
|
+
};
|
|
4230
|
+
/** @description Bad request — validation failed */
|
|
4231
|
+
400: {
|
|
4232
|
+
headers: {
|
|
4233
|
+
[name: string]: unknown;
|
|
4234
|
+
};
|
|
4235
|
+
content: {
|
|
4236
|
+
"application/json": components["schemas"]["ErrorEnvelope"];
|
|
4237
|
+
};
|
|
4238
|
+
};
|
|
4239
|
+
/** @description Unauthenticated — missing or invalid bearer token */
|
|
4240
|
+
401: {
|
|
3397
4241
|
headers: {
|
|
3398
4242
|
[name: string]: unknown;
|
|
3399
4243
|
};
|
|
@@ -3401,8 +4245,8 @@ export interface paths {
|
|
|
3401
4245
|
"application/json": components["schemas"]["ErrorEnvelope"];
|
|
3402
4246
|
};
|
|
3403
4247
|
};
|
|
3404
|
-
/** @description
|
|
3405
|
-
|
|
4248
|
+
/** @description Forbidden — caller authenticated but not allowed */
|
|
4249
|
+
403: {
|
|
3406
4250
|
headers: {
|
|
3407
4251
|
[name: string]: unknown;
|
|
3408
4252
|
};
|
|
@@ -3410,8 +4254,8 @@ export interface paths {
|
|
|
3410
4254
|
"application/json": components["schemas"]["ErrorEnvelope"];
|
|
3411
4255
|
};
|
|
3412
4256
|
};
|
|
3413
|
-
/** @description
|
|
3414
|
-
|
|
4257
|
+
/** @description Not found */
|
|
4258
|
+
404: {
|
|
3415
4259
|
headers: {
|
|
3416
4260
|
[name: string]: unknown;
|
|
3417
4261
|
};
|
|
@@ -3439,26 +4283,23 @@ export interface paths {
|
|
|
3439
4283
|
};
|
|
3440
4284
|
};
|
|
3441
4285
|
};
|
|
3442
|
-
delete?: never;
|
|
3443
4286
|
options?: never;
|
|
3444
4287
|
head?: never;
|
|
3445
4288
|
patch?: never;
|
|
3446
4289
|
trace?: never;
|
|
3447
4290
|
};
|
|
3448
|
-
"/v1/messages/{id}
|
|
4291
|
+
"/v1/messages/{id}": {
|
|
3449
4292
|
parameters: {
|
|
3450
4293
|
query?: never;
|
|
3451
4294
|
header?: never;
|
|
3452
4295
|
path?: never;
|
|
3453
4296
|
cookie?: never;
|
|
3454
4297
|
};
|
|
3455
|
-
get?: never;
|
|
3456
|
-
put?: never;
|
|
3457
4298
|
/**
|
|
3458
|
-
*
|
|
3459
|
-
* @description
|
|
4299
|
+
* Get a message
|
|
4300
|
+
* @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.
|
|
3460
4301
|
*/
|
|
3461
|
-
|
|
4302
|
+
get: {
|
|
3462
4303
|
parameters: {
|
|
3463
4304
|
query?: never;
|
|
3464
4305
|
header?: never;
|
|
@@ -3467,19 +4308,15 @@ export interface paths {
|
|
|
3467
4308
|
};
|
|
3468
4309
|
cookie?: never;
|
|
3469
4310
|
};
|
|
3470
|
-
requestBody?:
|
|
3471
|
-
content: {
|
|
3472
|
-
"application/json": components["schemas"]["SendReactionRequest"];
|
|
3473
|
-
};
|
|
3474
|
-
};
|
|
4311
|
+
requestBody?: never;
|
|
3475
4312
|
responses: {
|
|
3476
|
-
/** @description
|
|
3477
|
-
|
|
4313
|
+
/** @description Message */
|
|
4314
|
+
200: {
|
|
3478
4315
|
headers: {
|
|
3479
4316
|
[name: string]: unknown;
|
|
3480
4317
|
};
|
|
3481
4318
|
content: {
|
|
3482
|
-
"application/json": components["schemas"]["
|
|
4319
|
+
"application/json": components["schemas"]["MessageV1Envelope"];
|
|
3483
4320
|
};
|
|
3484
4321
|
};
|
|
3485
4322
|
/** @description Bad request — validation failed */
|
|
@@ -3518,15 +4355,6 @@ export interface paths {
|
|
|
3518
4355
|
"application/json": components["schemas"]["ErrorEnvelope"];
|
|
3519
4356
|
};
|
|
3520
4357
|
};
|
|
3521
|
-
/** @description Unprocessable — domain rule violation */
|
|
3522
|
-
422: {
|
|
3523
|
-
headers: {
|
|
3524
|
-
[name: string]: unknown;
|
|
3525
|
-
};
|
|
3526
|
-
content: {
|
|
3527
|
-
"application/json": components["schemas"]["ErrorEnvelope"];
|
|
3528
|
-
};
|
|
3529
|
-
};
|
|
3530
4358
|
/** @description Too many requests — rate limit exceeded */
|
|
3531
4359
|
429: {
|
|
3532
4360
|
headers: {
|
|
@@ -3547,9 +4375,11 @@ export interface paths {
|
|
|
3547
4375
|
};
|
|
3548
4376
|
};
|
|
3549
4377
|
};
|
|
4378
|
+
put?: never;
|
|
4379
|
+
post?: never;
|
|
3550
4380
|
/**
|
|
3551
|
-
*
|
|
3552
|
-
* @description
|
|
4381
|
+
* Cancel a queued or scheduled message
|
|
4382
|
+
* @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.
|
|
3553
4383
|
*/
|
|
3554
4384
|
delete: {
|
|
3555
4385
|
parameters: {
|
|
@@ -3562,13 +4392,13 @@ export interface paths {
|
|
|
3562
4392
|
};
|
|
3563
4393
|
requestBody?: never;
|
|
3564
4394
|
responses: {
|
|
3565
|
-
/** @description
|
|
4395
|
+
/** @description Message cancelled */
|
|
3566
4396
|
200: {
|
|
3567
4397
|
headers: {
|
|
3568
4398
|
[name: string]: unknown;
|
|
3569
4399
|
};
|
|
3570
4400
|
content: {
|
|
3571
|
-
"application/json": components["schemas"]["
|
|
4401
|
+
"application/json": components["schemas"]["MessageV1Envelope"];
|
|
3572
4402
|
};
|
|
3573
4403
|
};
|
|
3574
4404
|
/** @description Bad request — validation failed */
|
|
@@ -3607,6 +4437,15 @@ export interface paths {
|
|
|
3607
4437
|
"application/json": components["schemas"]["ErrorEnvelope"];
|
|
3608
4438
|
};
|
|
3609
4439
|
};
|
|
4440
|
+
/** @description Conflict — concurrent or terminal state */
|
|
4441
|
+
409: {
|
|
4442
|
+
headers: {
|
|
4443
|
+
[name: string]: unknown;
|
|
4444
|
+
};
|
|
4445
|
+
content: {
|
|
4446
|
+
"application/json": components["schemas"]["ErrorEnvelope"];
|
|
4447
|
+
};
|
|
4448
|
+
};
|
|
3610
4449
|
/** @description Too many requests — rate limit exceeded */
|
|
3611
4450
|
429: {
|
|
3612
4451
|
headers: {
|
|
@@ -3632,7 +4471,7 @@ export interface paths {
|
|
|
3632
4471
|
patch?: never;
|
|
3633
4472
|
trace?: never;
|
|
3634
4473
|
};
|
|
3635
|
-
"/v1/
|
|
4474
|
+
"/v1/webhooks": {
|
|
3636
4475
|
parameters: {
|
|
3637
4476
|
query?: never;
|
|
3638
4477
|
header?: never;
|
|
@@ -3640,27 +4479,31 @@ export interface paths {
|
|
|
3640
4479
|
cookie?: never;
|
|
3641
4480
|
};
|
|
3642
4481
|
/**
|
|
3643
|
-
*
|
|
3644
|
-
* @description
|
|
4482
|
+
* List webhook subscriptions
|
|
4483
|
+
* @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. Accepts an API key (`isnap_*`) or a dashboard JWT.
|
|
3645
4484
|
*/
|
|
3646
4485
|
get: {
|
|
3647
4486
|
parameters: {
|
|
3648
4487
|
query?: never;
|
|
3649
4488
|
header?: never;
|
|
3650
|
-
path
|
|
3651
|
-
id: string;
|
|
3652
|
-
};
|
|
4489
|
+
path?: never;
|
|
3653
4490
|
cookie?: never;
|
|
3654
4491
|
};
|
|
3655
4492
|
requestBody?: never;
|
|
3656
4493
|
responses: {
|
|
3657
|
-
/** @description
|
|
4494
|
+
/** @description Webhook list */
|
|
3658
4495
|
200: {
|
|
3659
4496
|
headers: {
|
|
3660
4497
|
[name: string]: unknown;
|
|
3661
4498
|
};
|
|
3662
4499
|
content: {
|
|
3663
|
-
"application/json":
|
|
4500
|
+
"application/json": {
|
|
4501
|
+
/** @enum {boolean} */
|
|
4502
|
+
success: true;
|
|
4503
|
+
data: components["schemas"]["WebhookList"];
|
|
4504
|
+
trace_id: string;
|
|
4505
|
+
request_id: string;
|
|
4506
|
+
};
|
|
3664
4507
|
};
|
|
3665
4508
|
};
|
|
3666
4509
|
/** @description Bad request — validation failed */
|
|
@@ -3681,8 +4524,8 @@ export interface paths {
|
|
|
3681
4524
|
"application/json": components["schemas"]["ErrorEnvelope"];
|
|
3682
4525
|
};
|
|
3683
4526
|
};
|
|
3684
|
-
/** @description
|
|
3685
|
-
|
|
4527
|
+
/** @description Too many requests — rate limit exceeded */
|
|
4528
|
+
429: {
|
|
3686
4529
|
headers: {
|
|
3687
4530
|
[name: string]: unknown;
|
|
3688
4531
|
};
|
|
@@ -3690,8 +4533,66 @@ export interface paths {
|
|
|
3690
4533
|
"application/json": components["schemas"]["ErrorEnvelope"];
|
|
3691
4534
|
};
|
|
3692
4535
|
};
|
|
3693
|
-
/** @description
|
|
3694
|
-
|
|
4536
|
+
/** @description Internal server error */
|
|
4537
|
+
500: {
|
|
4538
|
+
headers: {
|
|
4539
|
+
[name: string]: unknown;
|
|
4540
|
+
};
|
|
4541
|
+
content: {
|
|
4542
|
+
"application/json": components["schemas"]["ErrorEnvelope"];
|
|
4543
|
+
};
|
|
4544
|
+
};
|
|
4545
|
+
};
|
|
4546
|
+
};
|
|
4547
|
+
put?: never;
|
|
4548
|
+
/**
|
|
4549
|
+
* Register a webhook subscription
|
|
4550
|
+
* @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. Accepts an API key (`isnap_*`) or a dashboard JWT.
|
|
4551
|
+
*/
|
|
4552
|
+
post: {
|
|
4553
|
+
parameters: {
|
|
4554
|
+
query?: never;
|
|
4555
|
+
header?: never;
|
|
4556
|
+
path?: never;
|
|
4557
|
+
cookie?: never;
|
|
4558
|
+
};
|
|
4559
|
+
requestBody?: {
|
|
4560
|
+
content: {
|
|
4561
|
+
"application/json": {
|
|
4562
|
+
/** Format: uri */
|
|
4563
|
+
url: string;
|
|
4564
|
+
events: components["schemas"]["WebhookEventName"][];
|
|
4565
|
+
line_ids?: string[];
|
|
4566
|
+
};
|
|
4567
|
+
};
|
|
4568
|
+
};
|
|
4569
|
+
responses: {
|
|
4570
|
+
/** @description Webhook created */
|
|
4571
|
+
201: {
|
|
4572
|
+
headers: {
|
|
4573
|
+
[name: string]: unknown;
|
|
4574
|
+
};
|
|
4575
|
+
content: {
|
|
4576
|
+
"application/json": {
|
|
4577
|
+
/** @enum {boolean} */
|
|
4578
|
+
success: true;
|
|
4579
|
+
data: components["schemas"]["Webhook"];
|
|
4580
|
+
trace_id: string;
|
|
4581
|
+
request_id: string;
|
|
4582
|
+
};
|
|
4583
|
+
};
|
|
4584
|
+
};
|
|
4585
|
+
/** @description Bad request — validation failed */
|
|
4586
|
+
400: {
|
|
4587
|
+
headers: {
|
|
4588
|
+
[name: string]: unknown;
|
|
4589
|
+
};
|
|
4590
|
+
content: {
|
|
4591
|
+
"application/json": components["schemas"]["ErrorEnvelope"];
|
|
4592
|
+
};
|
|
4593
|
+
};
|
|
4594
|
+
/** @description Unauthenticated — missing or invalid bearer token */
|
|
4595
|
+
401: {
|
|
3695
4596
|
headers: {
|
|
3696
4597
|
[name: string]: unknown;
|
|
3697
4598
|
};
|
|
@@ -3719,13 +4620,24 @@ export interface paths {
|
|
|
3719
4620
|
};
|
|
3720
4621
|
};
|
|
3721
4622
|
};
|
|
3722
|
-
|
|
3723
|
-
|
|
4623
|
+
delete?: never;
|
|
4624
|
+
options?: never;
|
|
4625
|
+
head?: never;
|
|
4626
|
+
patch?: never;
|
|
4627
|
+
trace?: never;
|
|
4628
|
+
};
|
|
4629
|
+
"/v1/webhooks/{id}": {
|
|
4630
|
+
parameters: {
|
|
4631
|
+
query?: never;
|
|
4632
|
+
header?: never;
|
|
4633
|
+
path?: never;
|
|
4634
|
+
cookie?: never;
|
|
4635
|
+
};
|
|
3724
4636
|
/**
|
|
3725
|
-
*
|
|
3726
|
-
* @description
|
|
4637
|
+
* Get a webhook subscription
|
|
4638
|
+
* @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).
|
|
3727
4639
|
*/
|
|
3728
|
-
|
|
4640
|
+
get: {
|
|
3729
4641
|
parameters: {
|
|
3730
4642
|
query?: never;
|
|
3731
4643
|
header?: never;
|
|
@@ -3736,13 +4648,13 @@ export interface paths {
|
|
|
3736
4648
|
};
|
|
3737
4649
|
requestBody?: never;
|
|
3738
4650
|
responses: {
|
|
3739
|
-
/** @description
|
|
4651
|
+
/** @description Webhook */
|
|
3740
4652
|
200: {
|
|
3741
4653
|
headers: {
|
|
3742
4654
|
[name: string]: unknown;
|
|
3743
4655
|
};
|
|
3744
4656
|
content: {
|
|
3745
|
-
"application/json": components["schemas"]["
|
|
4657
|
+
"application/json": components["schemas"]["WebhookV1Envelope"];
|
|
3746
4658
|
};
|
|
3747
4659
|
};
|
|
3748
4660
|
/** @description Bad request — validation failed */
|
|
@@ -3763,8 +4675,8 @@ export interface paths {
|
|
|
3763
4675
|
"application/json": components["schemas"]["ErrorEnvelope"];
|
|
3764
4676
|
};
|
|
3765
4677
|
};
|
|
3766
|
-
/** @description
|
|
3767
|
-
|
|
4678
|
+
/** @description Not found */
|
|
4679
|
+
404: {
|
|
3768
4680
|
headers: {
|
|
3769
4681
|
[name: string]: unknown;
|
|
3770
4682
|
};
|
|
@@ -3772,8 +4684,8 @@ export interface paths {
|
|
|
3772
4684
|
"application/json": components["schemas"]["ErrorEnvelope"];
|
|
3773
4685
|
};
|
|
3774
4686
|
};
|
|
3775
|
-
/** @description
|
|
3776
|
-
|
|
4687
|
+
/** @description Too many requests — rate limit exceeded */
|
|
4688
|
+
429: {
|
|
3777
4689
|
headers: {
|
|
3778
4690
|
[name: string]: unknown;
|
|
3779
4691
|
};
|
|
@@ -3781,8 +4693,8 @@ export interface paths {
|
|
|
3781
4693
|
"application/json": components["schemas"]["ErrorEnvelope"];
|
|
3782
4694
|
};
|
|
3783
4695
|
};
|
|
3784
|
-
/** @description
|
|
3785
|
-
|
|
4696
|
+
/** @description Internal server error */
|
|
4697
|
+
500: {
|
|
3786
4698
|
headers: {
|
|
3787
4699
|
[name: string]: unknown;
|
|
3788
4700
|
};
|
|
@@ -3790,8 +4702,34 @@ export interface paths {
|
|
|
3790
4702
|
"application/json": components["schemas"]["ErrorEnvelope"];
|
|
3791
4703
|
};
|
|
3792
4704
|
};
|
|
3793
|
-
|
|
3794
|
-
|
|
4705
|
+
};
|
|
4706
|
+
};
|
|
4707
|
+
put?: never;
|
|
4708
|
+
post?: never;
|
|
4709
|
+
/**
|
|
4710
|
+
* Delete a webhook subscription
|
|
4711
|
+
* @description Permanently delete the webhook subscription. In-flight deliveries already enqueued will still attempt — the deletion only stops new event matching. Accepts an API key (`isnap_*`) or a dashboard JWT.
|
|
4712
|
+
*/
|
|
4713
|
+
delete: {
|
|
4714
|
+
parameters: {
|
|
4715
|
+
query?: never;
|
|
4716
|
+
header?: never;
|
|
4717
|
+
path: {
|
|
4718
|
+
id: string;
|
|
4719
|
+
};
|
|
4720
|
+
cookie?: never;
|
|
4721
|
+
};
|
|
4722
|
+
requestBody?: never;
|
|
4723
|
+
responses: {
|
|
4724
|
+
/** @description Webhook deleted */
|
|
4725
|
+
204: {
|
|
4726
|
+
headers: {
|
|
4727
|
+
[name: string]: unknown;
|
|
4728
|
+
};
|
|
4729
|
+
content?: never;
|
|
4730
|
+
};
|
|
4731
|
+
/** @description Bad request — validation failed */
|
|
4732
|
+
400: {
|
|
3795
4733
|
headers: {
|
|
3796
4734
|
[name: string]: unknown;
|
|
3797
4735
|
};
|
|
@@ -3799,8 +4737,8 @@ export interface paths {
|
|
|
3799
4737
|
"application/json": components["schemas"]["ErrorEnvelope"];
|
|
3800
4738
|
};
|
|
3801
4739
|
};
|
|
3802
|
-
/** @description
|
|
3803
|
-
|
|
4740
|
+
/** @description Unauthenticated — missing or invalid bearer token */
|
|
4741
|
+
401: {
|
|
3804
4742
|
headers: {
|
|
3805
4743
|
[name: string]: unknown;
|
|
3806
4744
|
};
|
|
@@ -3808,46 +4746,70 @@ export interface paths {
|
|
|
3808
4746
|
"application/json": components["schemas"]["ErrorEnvelope"];
|
|
3809
4747
|
};
|
|
3810
4748
|
};
|
|
3811
|
-
|
|
3812
|
-
|
|
3813
|
-
|
|
3814
|
-
|
|
3815
|
-
|
|
3816
|
-
|
|
3817
|
-
|
|
3818
|
-
|
|
3819
|
-
|
|
3820
|
-
|
|
3821
|
-
|
|
3822
|
-
|
|
3823
|
-
|
|
4749
|
+
/** @description Not found */
|
|
4750
|
+
404: {
|
|
4751
|
+
headers: {
|
|
4752
|
+
[name: string]: unknown;
|
|
4753
|
+
};
|
|
4754
|
+
content: {
|
|
4755
|
+
"application/json": components["schemas"]["ErrorEnvelope"];
|
|
4756
|
+
};
|
|
4757
|
+
};
|
|
4758
|
+
/** @description Too many requests — rate limit exceeded */
|
|
4759
|
+
429: {
|
|
4760
|
+
headers: {
|
|
4761
|
+
[name: string]: unknown;
|
|
4762
|
+
};
|
|
4763
|
+
content: {
|
|
4764
|
+
"application/json": components["schemas"]["ErrorEnvelope"];
|
|
4765
|
+
};
|
|
4766
|
+
};
|
|
4767
|
+
/** @description Internal server error */
|
|
4768
|
+
500: {
|
|
4769
|
+
headers: {
|
|
4770
|
+
[name: string]: unknown;
|
|
4771
|
+
};
|
|
4772
|
+
content: {
|
|
4773
|
+
"application/json": components["schemas"]["ErrorEnvelope"];
|
|
4774
|
+
};
|
|
4775
|
+
};
|
|
4776
|
+
};
|
|
3824
4777
|
};
|
|
4778
|
+
options?: never;
|
|
4779
|
+
head?: never;
|
|
3825
4780
|
/**
|
|
3826
|
-
*
|
|
3827
|
-
* @description
|
|
4781
|
+
* Update a webhook subscription
|
|
4782
|
+
* @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.
|
|
3828
4783
|
*/
|
|
3829
|
-
|
|
4784
|
+
patch: {
|
|
3830
4785
|
parameters: {
|
|
3831
4786
|
query?: never;
|
|
3832
4787
|
header?: never;
|
|
3833
|
-
path
|
|
4788
|
+
path: {
|
|
4789
|
+
id: string;
|
|
4790
|
+
};
|
|
3834
4791
|
cookie?: never;
|
|
3835
4792
|
};
|
|
3836
|
-
requestBody?:
|
|
4793
|
+
requestBody?: {
|
|
4794
|
+
content: {
|
|
4795
|
+
"application/json": {
|
|
4796
|
+
/** Format: uri */
|
|
4797
|
+
url?: string;
|
|
4798
|
+
events?: components["schemas"]["WebhookEventName"][];
|
|
4799
|
+
line_ids?: string[] | null;
|
|
4800
|
+
description?: string | null;
|
|
4801
|
+
active?: boolean;
|
|
4802
|
+
};
|
|
4803
|
+
};
|
|
4804
|
+
};
|
|
3837
4805
|
responses: {
|
|
3838
|
-
/** @description Webhook
|
|
4806
|
+
/** @description Webhook updated */
|
|
3839
4807
|
200: {
|
|
3840
4808
|
headers: {
|
|
3841
4809
|
[name: string]: unknown;
|
|
3842
4810
|
};
|
|
3843
4811
|
content: {
|
|
3844
|
-
"application/json":
|
|
3845
|
-
/** @enum {boolean} */
|
|
3846
|
-
success: true;
|
|
3847
|
-
data: components["schemas"]["WebhookList"];
|
|
3848
|
-
trace_id: string;
|
|
3849
|
-
request_id: string;
|
|
3850
|
-
};
|
|
4812
|
+
"application/json": components["schemas"]["WebhookV1Envelope"];
|
|
3851
4813
|
};
|
|
3852
4814
|
};
|
|
3853
4815
|
/** @description Bad request — validation failed */
|
|
@@ -3868,6 +4830,15 @@ export interface paths {
|
|
|
3868
4830
|
"application/json": components["schemas"]["ErrorEnvelope"];
|
|
3869
4831
|
};
|
|
3870
4832
|
};
|
|
4833
|
+
/** @description Not found */
|
|
4834
|
+
404: {
|
|
4835
|
+
headers: {
|
|
4836
|
+
[name: string]: unknown;
|
|
4837
|
+
};
|
|
4838
|
+
content: {
|
|
4839
|
+
"application/json": components["schemas"]["ErrorEnvelope"];
|
|
4840
|
+
};
|
|
4841
|
+
};
|
|
3871
4842
|
/** @description Too many requests — rate limit exceeded */
|
|
3872
4843
|
429: {
|
|
3873
4844
|
headers: {
|
|
@@ -3888,42 +4859,43 @@ export interface paths {
|
|
|
3888
4859
|
};
|
|
3889
4860
|
};
|
|
3890
4861
|
};
|
|
3891
|
-
|
|
4862
|
+
trace?: never;
|
|
4863
|
+
};
|
|
4864
|
+
"/v1/webhooks/events": {
|
|
4865
|
+
parameters: {
|
|
4866
|
+
query?: never;
|
|
4867
|
+
header?: never;
|
|
4868
|
+
path?: never;
|
|
4869
|
+
cookie?: never;
|
|
4870
|
+
};
|
|
3892
4871
|
/**
|
|
3893
|
-
*
|
|
3894
|
-
* @description
|
|
4872
|
+
* Replay webhook events within the retention window
|
|
4873
|
+
* @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`.
|
|
3895
4874
|
*/
|
|
3896
|
-
|
|
4875
|
+
get: {
|
|
3897
4876
|
parameters: {
|
|
3898
|
-
query
|
|
4877
|
+
query: {
|
|
4878
|
+
since: string;
|
|
4879
|
+
until?: string;
|
|
4880
|
+
/** @description A concrete event type (e.g. `message.received`), a family wildcard (`line.*`), or the catch-all `*`. */
|
|
4881
|
+
event?: components["schemas"]["WebhookEventName"];
|
|
4882
|
+
line_id?: string;
|
|
4883
|
+
limit?: number;
|
|
4884
|
+
cursor?: string;
|
|
4885
|
+
};
|
|
3899
4886
|
header?: never;
|
|
3900
4887
|
path?: never;
|
|
3901
4888
|
cookie?: never;
|
|
3902
4889
|
};
|
|
3903
|
-
requestBody?:
|
|
3904
|
-
content: {
|
|
3905
|
-
"application/json": {
|
|
3906
|
-
/** Format: uri */
|
|
3907
|
-
url: string;
|
|
3908
|
-
events: components["schemas"]["WebhookEventName"][];
|
|
3909
|
-
line_ids?: string[];
|
|
3910
|
-
};
|
|
3911
|
-
};
|
|
3912
|
-
};
|
|
4890
|
+
requestBody?: never;
|
|
3913
4891
|
responses: {
|
|
3914
|
-
/** @description Webhook
|
|
3915
|
-
|
|
4892
|
+
/** @description Webhook events (paginated, §4.1 envelope items) */
|
|
4893
|
+
200: {
|
|
3916
4894
|
headers: {
|
|
3917
4895
|
[name: string]: unknown;
|
|
3918
4896
|
};
|
|
3919
4897
|
content: {
|
|
3920
|
-
"application/json":
|
|
3921
|
-
/** @enum {boolean} */
|
|
3922
|
-
success: true;
|
|
3923
|
-
data: components["schemas"]["Webhook"];
|
|
3924
|
-
trace_id: string;
|
|
3925
|
-
request_id: string;
|
|
3926
|
-
};
|
|
4898
|
+
"application/json": components["schemas"]["WebhookEventsEnvelope"];
|
|
3927
4899
|
};
|
|
3928
4900
|
};
|
|
3929
4901
|
/** @description Bad request — validation failed */
|
|
@@ -3964,24 +4936,28 @@ export interface paths {
|
|
|
3964
4936
|
};
|
|
3965
4937
|
};
|
|
3966
4938
|
};
|
|
4939
|
+
put?: never;
|
|
4940
|
+
post?: never;
|
|
3967
4941
|
delete?: never;
|
|
3968
4942
|
options?: never;
|
|
3969
4943
|
head?: never;
|
|
3970
4944
|
patch?: never;
|
|
3971
4945
|
trace?: never;
|
|
3972
4946
|
};
|
|
3973
|
-
"/v1/webhooks/{id}": {
|
|
4947
|
+
"/v1/webhooks/{id}/rotate-secret": {
|
|
3974
4948
|
parameters: {
|
|
3975
4949
|
query?: never;
|
|
3976
4950
|
header?: never;
|
|
3977
4951
|
path?: never;
|
|
3978
4952
|
cookie?: never;
|
|
3979
4953
|
};
|
|
4954
|
+
get?: never;
|
|
4955
|
+
put?: never;
|
|
3980
4956
|
/**
|
|
3981
|
-
*
|
|
3982
|
-
* @description
|
|
4957
|
+
* Rotate the signing secret
|
|
4958
|
+
* @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.
|
|
3983
4959
|
*/
|
|
3984
|
-
|
|
4960
|
+
post: {
|
|
3985
4961
|
parameters: {
|
|
3986
4962
|
query?: never;
|
|
3987
4963
|
header?: never;
|
|
@@ -3992,13 +4968,13 @@ export interface paths {
|
|
|
3992
4968
|
};
|
|
3993
4969
|
requestBody?: never;
|
|
3994
4970
|
responses: {
|
|
3995
|
-
/** @description
|
|
4971
|
+
/** @description Secret rotated — plaintext shown once */
|
|
3996
4972
|
200: {
|
|
3997
4973
|
headers: {
|
|
3998
4974
|
[name: string]: unknown;
|
|
3999
4975
|
};
|
|
4000
4976
|
content: {
|
|
4001
|
-
"application/json": components["schemas"]["
|
|
4977
|
+
"application/json": components["schemas"]["WebhookRotateSecretEnvelope"];
|
|
4002
4978
|
};
|
|
4003
4979
|
};
|
|
4004
4980
|
/** @description Bad request — validation failed */
|
|
@@ -4048,15 +5024,33 @@ export interface paths {
|
|
|
4048
5024
|
};
|
|
4049
5025
|
};
|
|
4050
5026
|
};
|
|
4051
|
-
|
|
4052
|
-
|
|
5027
|
+
delete?: never;
|
|
5028
|
+
options?: never;
|
|
5029
|
+
head?: never;
|
|
5030
|
+
patch?: never;
|
|
5031
|
+
trace?: never;
|
|
5032
|
+
};
|
|
5033
|
+
"/v1/webhooks/{id}/deliveries": {
|
|
5034
|
+
parameters: {
|
|
5035
|
+
query?: never;
|
|
5036
|
+
header?: never;
|
|
5037
|
+
path?: never;
|
|
5038
|
+
cookie?: never;
|
|
5039
|
+
};
|
|
4053
5040
|
/**
|
|
4054
|
-
*
|
|
4055
|
-
* @description
|
|
5041
|
+
* List delivery attempts for a webhook
|
|
5042
|
+
* @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.
|
|
4056
5043
|
*/
|
|
4057
|
-
|
|
5044
|
+
get: {
|
|
4058
5045
|
parameters: {
|
|
4059
|
-
query?:
|
|
5046
|
+
query?: {
|
|
5047
|
+
limit?: number;
|
|
5048
|
+
cursor?: string;
|
|
5049
|
+
status?: "pending" | "success" | "failed";
|
|
5050
|
+
event?: string;
|
|
5051
|
+
since?: string;
|
|
5052
|
+
until?: string;
|
|
5053
|
+
};
|
|
4060
5054
|
header?: never;
|
|
4061
5055
|
path: {
|
|
4062
5056
|
id: string;
|
|
@@ -4065,12 +5059,14 @@ export interface paths {
|
|
|
4065
5059
|
};
|
|
4066
5060
|
requestBody?: never;
|
|
4067
5061
|
responses: {
|
|
4068
|
-
/** @description
|
|
4069
|
-
|
|
5062
|
+
/** @description Delivery list (cursor paginated) */
|
|
5063
|
+
200: {
|
|
4070
5064
|
headers: {
|
|
4071
5065
|
[name: string]: unknown;
|
|
4072
5066
|
};
|
|
4073
|
-
content
|
|
5067
|
+
content: {
|
|
5068
|
+
"application/json": components["schemas"]["WebhookDeliveryListEnvelope"];
|
|
5069
|
+
};
|
|
4074
5070
|
};
|
|
4075
5071
|
/** @description Bad request — validation failed */
|
|
4076
5072
|
400: {
|
|
@@ -4119,41 +5115,46 @@ export interface paths {
|
|
|
4119
5115
|
};
|
|
4120
5116
|
};
|
|
4121
5117
|
};
|
|
5118
|
+
put?: never;
|
|
5119
|
+
post?: never;
|
|
5120
|
+
delete?: never;
|
|
4122
5121
|
options?: never;
|
|
4123
5122
|
head?: never;
|
|
5123
|
+
patch?: never;
|
|
5124
|
+
trace?: never;
|
|
5125
|
+
};
|
|
5126
|
+
"/v1/webhooks/{id}/deliveries/{delivery_id}/replay": {
|
|
5127
|
+
parameters: {
|
|
5128
|
+
query?: never;
|
|
5129
|
+
header?: never;
|
|
5130
|
+
path?: never;
|
|
5131
|
+
cookie?: never;
|
|
5132
|
+
};
|
|
5133
|
+
get?: never;
|
|
5134
|
+
put?: never;
|
|
4124
5135
|
/**
|
|
4125
|
-
*
|
|
4126
|
-
* @description
|
|
5136
|
+
* Replay a delivery attempt
|
|
5137
|
+
* @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.
|
|
4127
5138
|
*/
|
|
4128
|
-
|
|
5139
|
+
post: {
|
|
4129
5140
|
parameters: {
|
|
4130
5141
|
query?: never;
|
|
4131
5142
|
header?: never;
|
|
4132
5143
|
path: {
|
|
4133
5144
|
id: string;
|
|
5145
|
+
delivery_id: string;
|
|
4134
5146
|
};
|
|
4135
5147
|
cookie?: never;
|
|
4136
5148
|
};
|
|
4137
|
-
requestBody?:
|
|
4138
|
-
content: {
|
|
4139
|
-
"application/json": {
|
|
4140
|
-
/** Format: uri */
|
|
4141
|
-
url?: string;
|
|
4142
|
-
events?: components["schemas"]["WebhookEventName"][];
|
|
4143
|
-
line_ids?: string[] | null;
|
|
4144
|
-
description?: string | null;
|
|
4145
|
-
active?: boolean;
|
|
4146
|
-
};
|
|
4147
|
-
};
|
|
4148
|
-
};
|
|
5149
|
+
requestBody?: never;
|
|
4149
5150
|
responses: {
|
|
4150
|
-
/** @description
|
|
4151
|
-
|
|
5151
|
+
/** @description Replay queued */
|
|
5152
|
+
202: {
|
|
4152
5153
|
headers: {
|
|
4153
5154
|
[name: string]: unknown;
|
|
4154
5155
|
};
|
|
4155
5156
|
content: {
|
|
4156
|
-
"application/json": components["schemas"]["
|
|
5157
|
+
"application/json": components["schemas"]["WebhookDeliveryReplayEnvelope"];
|
|
4157
5158
|
};
|
|
4158
5159
|
};
|
|
4159
5160
|
/** @description Bad request — validation failed */
|
|
@@ -4203,43 +5204,51 @@ export interface paths {
|
|
|
4203
5204
|
};
|
|
4204
5205
|
};
|
|
4205
5206
|
};
|
|
5207
|
+
delete?: never;
|
|
5208
|
+
options?: never;
|
|
5209
|
+
head?: never;
|
|
5210
|
+
patch?: never;
|
|
4206
5211
|
trace?: never;
|
|
4207
5212
|
};
|
|
4208
|
-
"/v1/
|
|
5213
|
+
"/v1/attachments": {
|
|
4209
5214
|
parameters: {
|
|
4210
5215
|
query?: never;
|
|
4211
5216
|
header?: never;
|
|
4212
5217
|
path?: never;
|
|
4213
5218
|
cookie?: never;
|
|
4214
5219
|
};
|
|
5220
|
+
get?: never;
|
|
5221
|
+
put?: never;
|
|
4215
5222
|
/**
|
|
4216
|
-
*
|
|
4217
|
-
* @description
|
|
5223
|
+
* Create an attachment + receive a signed upload URL
|
|
5224
|
+
* @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.
|
|
4218
5225
|
*/
|
|
4219
|
-
|
|
5226
|
+
post: {
|
|
4220
5227
|
parameters: {
|
|
4221
|
-
query
|
|
4222
|
-
since: string;
|
|
4223
|
-
until?: string;
|
|
4224
|
-
/** @description A concrete event type (e.g. `message.received`), a family wildcard (`line.*`), or the catch-all `*`. */
|
|
4225
|
-
event?: components["schemas"]["WebhookEventName"];
|
|
4226
|
-
line_id?: string;
|
|
4227
|
-
limit?: number;
|
|
4228
|
-
cursor?: string;
|
|
4229
|
-
};
|
|
5228
|
+
query?: never;
|
|
4230
5229
|
header?: never;
|
|
4231
5230
|
path?: never;
|
|
4232
5231
|
cookie?: never;
|
|
4233
5232
|
};
|
|
4234
|
-
requestBody?:
|
|
5233
|
+
requestBody?: {
|
|
5234
|
+
content: {
|
|
5235
|
+
"application/json": components["schemas"]["CreateAttachment"];
|
|
5236
|
+
};
|
|
5237
|
+
};
|
|
4235
5238
|
responses: {
|
|
4236
|
-
/** @description
|
|
4237
|
-
|
|
5239
|
+
/** @description Attachment row created, upload pending */
|
|
5240
|
+
201: {
|
|
4238
5241
|
headers: {
|
|
4239
5242
|
[name: string]: unknown;
|
|
4240
5243
|
};
|
|
4241
5244
|
content: {
|
|
4242
|
-
"application/json":
|
|
5245
|
+
"application/json": {
|
|
5246
|
+
/** @enum {boolean} */
|
|
5247
|
+
success: true;
|
|
5248
|
+
data: components["schemas"]["CreateAttachmentResponse"];
|
|
5249
|
+
trace_id: string;
|
|
5250
|
+
request_id: string;
|
|
5251
|
+
};
|
|
4243
5252
|
};
|
|
4244
5253
|
};
|
|
4245
5254
|
/** @description Bad request — validation failed */
|
|
@@ -4280,28 +5289,24 @@ export interface paths {
|
|
|
4280
5289
|
};
|
|
4281
5290
|
};
|
|
4282
5291
|
};
|
|
4283
|
-
put?: never;
|
|
4284
|
-
post?: never;
|
|
4285
5292
|
delete?: never;
|
|
4286
5293
|
options?: never;
|
|
4287
5294
|
head?: never;
|
|
4288
5295
|
patch?: never;
|
|
4289
5296
|
trace?: never;
|
|
4290
5297
|
};
|
|
4291
|
-
"/v1/
|
|
5298
|
+
"/v1/attachments/{id}": {
|
|
4292
5299
|
parameters: {
|
|
4293
5300
|
query?: never;
|
|
4294
5301
|
header?: never;
|
|
4295
5302
|
path?: never;
|
|
4296
5303
|
cookie?: never;
|
|
4297
5304
|
};
|
|
4298
|
-
get?: never;
|
|
4299
|
-
put?: never;
|
|
4300
5305
|
/**
|
|
4301
|
-
*
|
|
4302
|
-
* @description
|
|
5306
|
+
* Get an attachment + signed download URL
|
|
5307
|
+
* @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.
|
|
4303
5308
|
*/
|
|
4304
|
-
|
|
5309
|
+
get: {
|
|
4305
5310
|
parameters: {
|
|
4306
5311
|
query?: never;
|
|
4307
5312
|
header?: never;
|
|
@@ -4312,13 +5317,19 @@ export interface paths {
|
|
|
4312
5317
|
};
|
|
4313
5318
|
requestBody?: never;
|
|
4314
5319
|
responses: {
|
|
4315
|
-
/** @description
|
|
5320
|
+
/** @description Attachment record + fresh signed download URL */
|
|
4316
5321
|
200: {
|
|
4317
5322
|
headers: {
|
|
4318
5323
|
[name: string]: unknown;
|
|
4319
5324
|
};
|
|
4320
5325
|
content: {
|
|
4321
|
-
"application/json":
|
|
5326
|
+
"application/json": {
|
|
5327
|
+
/** @enum {boolean} */
|
|
5328
|
+
success: true;
|
|
5329
|
+
data: components["schemas"]["Attachment"];
|
|
5330
|
+
trace_id: string;
|
|
5331
|
+
request_id: string;
|
|
5332
|
+
};
|
|
4322
5333
|
};
|
|
4323
5334
|
};
|
|
4324
5335
|
/** @description Bad request — validation failed */
|
|
@@ -4368,61 +5379,60 @@ export interface paths {
|
|
|
4368
5379
|
};
|
|
4369
5380
|
};
|
|
4370
5381
|
};
|
|
5382
|
+
put?: never;
|
|
5383
|
+
post?: never;
|
|
4371
5384
|
delete?: never;
|
|
4372
5385
|
options?: never;
|
|
4373
5386
|
head?: never;
|
|
4374
5387
|
patch?: never;
|
|
4375
5388
|
trace?: never;
|
|
4376
5389
|
};
|
|
4377
|
-
"/v1/
|
|
5390
|
+
"/v1/lookup": {
|
|
4378
5391
|
parameters: {
|
|
4379
5392
|
query?: never;
|
|
4380
5393
|
header?: never;
|
|
4381
5394
|
path?: never;
|
|
4382
5395
|
cookie?: never;
|
|
4383
5396
|
};
|
|
5397
|
+
get?: never;
|
|
5398
|
+
put?: never;
|
|
4384
5399
|
/**
|
|
4385
|
-
*
|
|
4386
|
-
* @description
|
|
5400
|
+
* Look up a recipient capability
|
|
5401
|
+
* @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.
|
|
4387
5402
|
*/
|
|
4388
|
-
|
|
5403
|
+
post: {
|
|
4389
5404
|
parameters: {
|
|
4390
|
-
query?:
|
|
4391
|
-
limit?: number;
|
|
4392
|
-
cursor?: string;
|
|
4393
|
-
status?: "pending" | "success" | "failed";
|
|
4394
|
-
event?: string;
|
|
4395
|
-
since?: string;
|
|
4396
|
-
until?: string;
|
|
4397
|
-
};
|
|
5405
|
+
query?: never;
|
|
4398
5406
|
header?: never;
|
|
4399
|
-
path
|
|
4400
|
-
id: string;
|
|
4401
|
-
};
|
|
5407
|
+
path?: never;
|
|
4402
5408
|
cookie?: never;
|
|
4403
5409
|
};
|
|
4404
|
-
requestBody?:
|
|
5410
|
+
requestBody?: {
|
|
5411
|
+
content: {
|
|
5412
|
+
"application/json": components["schemas"]["LookupRequest"];
|
|
5413
|
+
};
|
|
5414
|
+
};
|
|
4405
5415
|
responses: {
|
|
4406
|
-
/** @description
|
|
5416
|
+
/** @description Lookup result — cache hit, fast probe, or an un-probed miss */
|
|
4407
5417
|
200: {
|
|
4408
5418
|
headers: {
|
|
4409
5419
|
[name: string]: unknown;
|
|
4410
5420
|
};
|
|
4411
5421
|
content: {
|
|
4412
|
-
"application/json": components["schemas"]["
|
|
5422
|
+
"application/json": components["schemas"]["LookupEnvelope"];
|
|
4413
5423
|
};
|
|
4414
5424
|
};
|
|
4415
|
-
/** @description
|
|
4416
|
-
|
|
5425
|
+
/** @description Lookup pending — a device probe was dispatched but had not answered within the wait budget; re-poll the same request after `retry_after` seconds */
|
|
5426
|
+
202: {
|
|
4417
5427
|
headers: {
|
|
4418
5428
|
[name: string]: unknown;
|
|
4419
5429
|
};
|
|
4420
5430
|
content: {
|
|
4421
|
-
"application/json": components["schemas"]["
|
|
5431
|
+
"application/json": components["schemas"]["LookupEnvelope"];
|
|
4422
5432
|
};
|
|
4423
5433
|
};
|
|
4424
|
-
/** @description
|
|
4425
|
-
|
|
5434
|
+
/** @description Bad request — validation failed */
|
|
5435
|
+
400: {
|
|
4426
5436
|
headers: {
|
|
4427
5437
|
[name: string]: unknown;
|
|
4428
5438
|
};
|
|
@@ -4430,8 +5440,8 @@ export interface paths {
|
|
|
4430
5440
|
"application/json": components["schemas"]["ErrorEnvelope"];
|
|
4431
5441
|
};
|
|
4432
5442
|
};
|
|
4433
|
-
/** @description
|
|
4434
|
-
|
|
5443
|
+
/** @description Unauthenticated — missing or invalid bearer token */
|
|
5444
|
+
401: {
|
|
4435
5445
|
headers: {
|
|
4436
5446
|
[name: string]: unknown;
|
|
4437
5447
|
};
|
|
@@ -4459,46 +5469,42 @@ export interface paths {
|
|
|
4459
5469
|
};
|
|
4460
5470
|
};
|
|
4461
5471
|
};
|
|
4462
|
-
put?: never;
|
|
4463
|
-
post?: never;
|
|
4464
5472
|
delete?: never;
|
|
4465
5473
|
options?: never;
|
|
4466
5474
|
head?: never;
|
|
4467
5475
|
patch?: never;
|
|
4468
5476
|
trace?: never;
|
|
4469
5477
|
};
|
|
4470
|
-
"/v1/
|
|
5478
|
+
"/v1/area-codes": {
|
|
4471
5479
|
parameters: {
|
|
4472
5480
|
query?: never;
|
|
4473
5481
|
header?: never;
|
|
4474
5482
|
path?: never;
|
|
4475
5483
|
cookie?: never;
|
|
4476
5484
|
};
|
|
4477
|
-
get?: never;
|
|
4478
|
-
put?: never;
|
|
4479
5485
|
/**
|
|
4480
|
-
*
|
|
4481
|
-
* @description
|
|
5486
|
+
* List selectable area codes (public)
|
|
5487
|
+
* @description Enumerate the area codes a customer can request as `preferred_area_codes` on `POST /v1/pre-orders`, for rendering a pre-order area-code picker. Optional `?country=US` filters the list. Also returns the selectable countries so the same response can drive a country dropdown. Unauthenticated — mirrors `GET /v1/lines` and `GET /pricing`. The list is the *selectable* set (a curated subset of NANP), not a guarantee of immediate inventory: pre-orders are precisely for tiers with no in-stock line.
|
|
4482
5488
|
*/
|
|
4483
|
-
|
|
5489
|
+
get: {
|
|
4484
5490
|
parameters: {
|
|
4485
|
-
query?:
|
|
4486
|
-
|
|
4487
|
-
|
|
4488
|
-
id: string;
|
|
4489
|
-
delivery_id: string;
|
|
5491
|
+
query?: {
|
|
5492
|
+
/** @description ISO 3166-1 alpha-2 country filter (case-insensitive). Omit for all countries. */
|
|
5493
|
+
country?: string;
|
|
4490
5494
|
};
|
|
5495
|
+
header?: never;
|
|
5496
|
+
path?: never;
|
|
4491
5497
|
cookie?: never;
|
|
4492
5498
|
};
|
|
4493
5499
|
requestBody?: never;
|
|
4494
5500
|
responses: {
|
|
4495
|
-
/** @description
|
|
4496
|
-
|
|
5501
|
+
/** @description Selectable area codes + countries */
|
|
5502
|
+
200: {
|
|
4497
5503
|
headers: {
|
|
4498
5504
|
[name: string]: unknown;
|
|
4499
5505
|
};
|
|
4500
5506
|
content: {
|
|
4501
|
-
"application/json": components["schemas"]["
|
|
5507
|
+
"application/json": components["schemas"]["AreaCodesEnvelope"];
|
|
4502
5508
|
};
|
|
4503
5509
|
};
|
|
4504
5510
|
/** @description Bad request — validation failed */
|
|
@@ -4510,24 +5516,6 @@ export interface paths {
|
|
|
4510
5516
|
"application/json": components["schemas"]["ErrorEnvelope"];
|
|
4511
5517
|
};
|
|
4512
5518
|
};
|
|
4513
|
-
/** @description Unauthenticated — missing or invalid bearer token */
|
|
4514
|
-
401: {
|
|
4515
|
-
headers: {
|
|
4516
|
-
[name: string]: unknown;
|
|
4517
|
-
};
|
|
4518
|
-
content: {
|
|
4519
|
-
"application/json": components["schemas"]["ErrorEnvelope"];
|
|
4520
|
-
};
|
|
4521
|
-
};
|
|
4522
|
-
/** @description Not found */
|
|
4523
|
-
404: {
|
|
4524
|
-
headers: {
|
|
4525
|
-
[name: string]: unknown;
|
|
4526
|
-
};
|
|
4527
|
-
content: {
|
|
4528
|
-
"application/json": components["schemas"]["ErrorEnvelope"];
|
|
4529
|
-
};
|
|
4530
|
-
};
|
|
4531
5519
|
/** @description Too many requests — rate limit exceeded */
|
|
4532
5520
|
429: {
|
|
4533
5521
|
headers: {
|
|
@@ -4548,51 +5536,47 @@ export interface paths {
|
|
|
4548
5536
|
};
|
|
4549
5537
|
};
|
|
4550
5538
|
};
|
|
5539
|
+
put?: never;
|
|
5540
|
+
post?: never;
|
|
4551
5541
|
delete?: never;
|
|
4552
5542
|
options?: never;
|
|
4553
5543
|
head?: never;
|
|
4554
5544
|
patch?: never;
|
|
4555
5545
|
trace?: never;
|
|
4556
5546
|
};
|
|
4557
|
-
"/v1/
|
|
5547
|
+
"/v1/chats": {
|
|
4558
5548
|
parameters: {
|
|
4559
5549
|
query?: never;
|
|
4560
5550
|
header?: never;
|
|
4561
5551
|
path?: never;
|
|
4562
5552
|
cookie?: never;
|
|
4563
5553
|
};
|
|
4564
|
-
get?: never;
|
|
4565
|
-
put?: never;
|
|
4566
5554
|
/**
|
|
4567
|
-
*
|
|
4568
|
-
* @description
|
|
5555
|
+
* List chats
|
|
5556
|
+
* @description Cursor-paginated list of the caller's conversations, newest activity first. Filter by `line_id`. On shared-plan (virtual) lines each chat carries `outbound_number` — the physical number currently serving that contact (null once the binding is released; the next outbound is assigned a fresh number). Non-shared lines always carry `outbound_number: null`. Accepts an API key (`isnap_*`) or a dashboard JWT; line-scoped API keys only see chats of the lines in their allowlist.
|
|
4569
5557
|
*/
|
|
4570
|
-
|
|
5558
|
+
get: {
|
|
4571
5559
|
parameters: {
|
|
4572
|
-
query?:
|
|
5560
|
+
query?: {
|
|
5561
|
+
line_id?: string;
|
|
5562
|
+
limit?: number;
|
|
5563
|
+
cursor?: string;
|
|
5564
|
+
since?: string;
|
|
5565
|
+
until?: string;
|
|
5566
|
+
};
|
|
4573
5567
|
header?: never;
|
|
4574
5568
|
path?: never;
|
|
4575
5569
|
cookie?: never;
|
|
4576
5570
|
};
|
|
4577
|
-
requestBody?:
|
|
4578
|
-
content: {
|
|
4579
|
-
"application/json": components["schemas"]["CreateAttachment"];
|
|
4580
|
-
};
|
|
4581
|
-
};
|
|
5571
|
+
requestBody?: never;
|
|
4582
5572
|
responses: {
|
|
4583
|
-
/** @description
|
|
4584
|
-
|
|
5573
|
+
/** @description Chat list */
|
|
5574
|
+
200: {
|
|
4585
5575
|
headers: {
|
|
4586
5576
|
[name: string]: unknown;
|
|
4587
5577
|
};
|
|
4588
5578
|
content: {
|
|
4589
|
-
"application/json":
|
|
4590
|
-
/** @enum {boolean} */
|
|
4591
|
-
success: true;
|
|
4592
|
-
data: components["schemas"]["CreateAttachmentResponse"];
|
|
4593
|
-
trace_id: string;
|
|
4594
|
-
request_id: string;
|
|
4595
|
-
};
|
|
5579
|
+
"application/json": components["schemas"]["ChatListEnvelope"];
|
|
4596
5580
|
};
|
|
4597
5581
|
};
|
|
4598
5582
|
/** @description Bad request — validation failed */
|
|
@@ -4633,13 +5617,15 @@ export interface paths {
|
|
|
4633
5617
|
};
|
|
4634
5618
|
};
|
|
4635
5619
|
};
|
|
5620
|
+
put?: never;
|
|
5621
|
+
post?: never;
|
|
4636
5622
|
delete?: never;
|
|
4637
5623
|
options?: never;
|
|
4638
5624
|
head?: never;
|
|
4639
5625
|
patch?: never;
|
|
4640
5626
|
trace?: never;
|
|
4641
5627
|
};
|
|
4642
|
-
"/v1/
|
|
5628
|
+
"/v1/chats/{chat_id}": {
|
|
4643
5629
|
parameters: {
|
|
4644
5630
|
query?: never;
|
|
4645
5631
|
header?: never;
|
|
@@ -4647,33 +5633,27 @@ export interface paths {
|
|
|
4647
5633
|
cookie?: never;
|
|
4648
5634
|
};
|
|
4649
5635
|
/**
|
|
4650
|
-
* Get
|
|
4651
|
-
* @description Fetch
|
|
5636
|
+
* Get a chat
|
|
5637
|
+
* @description Fetch a single conversation by its `chat_<base62>` id. Same shape as the list items, including `outbound_number` for shared-plan lines. Cross-account and out-of-scope ids resolve 404 (no existence leak).
|
|
4652
5638
|
*/
|
|
4653
5639
|
get: {
|
|
4654
5640
|
parameters: {
|
|
4655
5641
|
query?: never;
|
|
4656
5642
|
header?: never;
|
|
4657
5643
|
path: {
|
|
4658
|
-
|
|
5644
|
+
chat_id: string;
|
|
4659
5645
|
};
|
|
4660
5646
|
cookie?: never;
|
|
4661
5647
|
};
|
|
4662
5648
|
requestBody?: never;
|
|
4663
5649
|
responses: {
|
|
4664
|
-
/** @description
|
|
5650
|
+
/** @description Chat */
|
|
4665
5651
|
200: {
|
|
4666
5652
|
headers: {
|
|
4667
5653
|
[name: string]: unknown;
|
|
4668
5654
|
};
|
|
4669
5655
|
content: {
|
|
4670
|
-
"application/json":
|
|
4671
|
-
/** @enum {boolean} */
|
|
4672
|
-
success: true;
|
|
4673
|
-
data: components["schemas"]["Attachment"];
|
|
4674
|
-
trace_id: string;
|
|
4675
|
-
request_id: string;
|
|
4676
|
-
};
|
|
5656
|
+
"application/json": components["schemas"]["ChatEnvelope"];
|
|
4677
5657
|
};
|
|
4678
5658
|
};
|
|
4679
5659
|
/** @description Bad request — validation failed */
|
|
@@ -4731,7 +5711,7 @@ export interface paths {
|
|
|
4731
5711
|
patch?: never;
|
|
4732
5712
|
trace?: never;
|
|
4733
5713
|
};
|
|
4734
|
-
"/v1/
|
|
5714
|
+
"/v1/chats/{chat_id}/share-contact-card": {
|
|
4735
5715
|
parameters: {
|
|
4736
5716
|
query?: never;
|
|
4737
5717
|
header?: never;
|
|
@@ -4740,43 +5720,50 @@ export interface paths {
|
|
|
4740
5720
|
};
|
|
4741
5721
|
get?: never;
|
|
4742
5722
|
put?: never;
|
|
4743
|
-
/**
|
|
4744
|
-
* Look up a recipient capability
|
|
4745
|
-
* @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.
|
|
4746
|
-
*/
|
|
4747
5723
|
post: {
|
|
4748
5724
|
parameters: {
|
|
4749
5725
|
query?: never;
|
|
4750
5726
|
header?: never;
|
|
4751
|
-
path
|
|
5727
|
+
path: {
|
|
5728
|
+
chat_id: string;
|
|
5729
|
+
};
|
|
4752
5730
|
cookie?: never;
|
|
4753
5731
|
};
|
|
4754
5732
|
requestBody?: {
|
|
4755
5733
|
content: {
|
|
4756
|
-
"application/json":
|
|
5734
|
+
"application/json": {
|
|
5735
|
+
first_name: string;
|
|
5736
|
+
last_name?: string;
|
|
5737
|
+
/** Format: uri */
|
|
5738
|
+
avatar_url?: string;
|
|
5739
|
+
phone_numbers?: string[];
|
|
5740
|
+
emails?: string[];
|
|
5741
|
+
organization?: string;
|
|
5742
|
+
note?: string;
|
|
5743
|
+
};
|
|
4757
5744
|
};
|
|
4758
5745
|
};
|
|
4759
5746
|
responses: {
|
|
4760
|
-
/** @description
|
|
4761
|
-
|
|
5747
|
+
/** @description Contact card queued */
|
|
5748
|
+
202: {
|
|
4762
5749
|
headers: {
|
|
4763
5750
|
[name: string]: unknown;
|
|
4764
5751
|
};
|
|
4765
5752
|
content: {
|
|
4766
|
-
"application/json": components["schemas"]["
|
|
5753
|
+
"application/json": components["schemas"]["ShareContactCardEnvelope"];
|
|
4767
5754
|
};
|
|
4768
5755
|
};
|
|
4769
|
-
/** @description
|
|
4770
|
-
|
|
5756
|
+
/** @description Bad request — validation failed */
|
|
5757
|
+
400: {
|
|
4771
5758
|
headers: {
|
|
4772
5759
|
[name: string]: unknown;
|
|
4773
5760
|
};
|
|
4774
5761
|
content: {
|
|
4775
|
-
"application/json": components["schemas"]["
|
|
5762
|
+
"application/json": components["schemas"]["ErrorEnvelope"];
|
|
4776
5763
|
};
|
|
4777
5764
|
};
|
|
4778
|
-
/** @description
|
|
4779
|
-
|
|
5765
|
+
/** @description Unauthenticated — missing or invalid bearer token */
|
|
5766
|
+
401: {
|
|
4780
5767
|
headers: {
|
|
4781
5768
|
[name: string]: unknown;
|
|
4782
5769
|
};
|
|
@@ -4784,8 +5771,26 @@ export interface paths {
|
|
|
4784
5771
|
"application/json": components["schemas"]["ErrorEnvelope"];
|
|
4785
5772
|
};
|
|
4786
5773
|
};
|
|
4787
|
-
/** @description
|
|
4788
|
-
|
|
5774
|
+
/** @description Forbidden — caller authenticated but not allowed */
|
|
5775
|
+
403: {
|
|
5776
|
+
headers: {
|
|
5777
|
+
[name: string]: unknown;
|
|
5778
|
+
};
|
|
5779
|
+
content: {
|
|
5780
|
+
"application/json": components["schemas"]["ErrorEnvelope"];
|
|
5781
|
+
};
|
|
5782
|
+
};
|
|
5783
|
+
/** @description Not found */
|
|
5784
|
+
404: {
|
|
5785
|
+
headers: {
|
|
5786
|
+
[name: string]: unknown;
|
|
5787
|
+
};
|
|
5788
|
+
content: {
|
|
5789
|
+
"application/json": components["schemas"]["ErrorEnvelope"];
|
|
5790
|
+
};
|
|
5791
|
+
};
|
|
5792
|
+
/** @description Unprocessable — domain rule violation */
|
|
5793
|
+
422: {
|
|
4789
5794
|
headers: {
|
|
4790
5795
|
[name: string]: unknown;
|
|
4791
5796
|
};
|
|
@@ -4819,49 +5824,41 @@ export interface paths {
|
|
|
4819
5824
|
patch?: never;
|
|
4820
5825
|
trace?: never;
|
|
4821
5826
|
};
|
|
4822
|
-
"/v1/
|
|
5827
|
+
"/v1/chats/{chat_id}/typing": {
|
|
4823
5828
|
parameters: {
|
|
4824
5829
|
query?: never;
|
|
4825
5830
|
header?: never;
|
|
4826
5831
|
path?: never;
|
|
4827
5832
|
cookie?: never;
|
|
4828
5833
|
};
|
|
4829
|
-
|
|
4830
|
-
|
|
4831
|
-
|
|
4832
|
-
*/
|
|
4833
|
-
get: {
|
|
5834
|
+
get?: never;
|
|
5835
|
+
put?: never;
|
|
5836
|
+
post: {
|
|
4834
5837
|
parameters: {
|
|
4835
|
-
query?:
|
|
4836
|
-
/** @description ISO 3166-1 alpha-2 country filter (case-insensitive). Omit for all countries. */
|
|
4837
|
-
country?: string;
|
|
4838
|
-
};
|
|
5838
|
+
query?: never;
|
|
4839
5839
|
header?: never;
|
|
4840
|
-
path
|
|
5840
|
+
path: {
|
|
5841
|
+
chat_id: string;
|
|
5842
|
+
};
|
|
4841
5843
|
cookie?: never;
|
|
4842
5844
|
};
|
|
4843
|
-
requestBody?:
|
|
4844
|
-
|
|
4845
|
-
|
|
4846
|
-
200: {
|
|
4847
|
-
headers: {
|
|
4848
|
-
[name: string]: unknown;
|
|
4849
|
-
};
|
|
4850
|
-
content: {
|
|
4851
|
-
"application/json": components["schemas"]["AreaCodesEnvelope"];
|
|
4852
|
-
};
|
|
5845
|
+
requestBody?: {
|
|
5846
|
+
content: {
|
|
5847
|
+
"application/json": Record<string, never>;
|
|
4853
5848
|
};
|
|
4854
|
-
|
|
4855
|
-
|
|
5849
|
+
};
|
|
5850
|
+
responses: {
|
|
5851
|
+
/** @description Typing indicator started */
|
|
5852
|
+
202: {
|
|
4856
5853
|
headers: {
|
|
4857
5854
|
[name: string]: unknown;
|
|
4858
5855
|
};
|
|
4859
5856
|
content: {
|
|
4860
|
-
"application/json": components["schemas"]["
|
|
5857
|
+
"application/json": components["schemas"]["ChatTypingStartEnvelope"];
|
|
4861
5858
|
};
|
|
4862
|
-
};
|
|
4863
|
-
/** @description
|
|
4864
|
-
|
|
5859
|
+
};
|
|
5860
|
+
/** @description Bad request — validation failed */
|
|
5861
|
+
400: {
|
|
4865
5862
|
headers: {
|
|
4866
5863
|
[name: string]: unknown;
|
|
4867
5864
|
};
|
|
@@ -4869,8 +5866,8 @@ export interface paths {
|
|
|
4869
5866
|
"application/json": components["schemas"]["ErrorEnvelope"];
|
|
4870
5867
|
};
|
|
4871
5868
|
};
|
|
4872
|
-
/** @description
|
|
4873
|
-
|
|
5869
|
+
/** @description Unauthenticated — missing or invalid bearer token */
|
|
5870
|
+
401: {
|
|
4874
5871
|
headers: {
|
|
4875
5872
|
[name: string]: unknown;
|
|
4876
5873
|
};
|
|
@@ -4878,53 +5875,17 @@ export interface paths {
|
|
|
4878
5875
|
"application/json": components["schemas"]["ErrorEnvelope"];
|
|
4879
5876
|
};
|
|
4880
5877
|
};
|
|
4881
|
-
|
|
4882
|
-
|
|
4883
|
-
put?: never;
|
|
4884
|
-
post?: never;
|
|
4885
|
-
delete?: never;
|
|
4886
|
-
options?: never;
|
|
4887
|
-
head?: never;
|
|
4888
|
-
patch?: never;
|
|
4889
|
-
trace?: never;
|
|
4890
|
-
};
|
|
4891
|
-
"/v1/chats": {
|
|
4892
|
-
parameters: {
|
|
4893
|
-
query?: never;
|
|
4894
|
-
header?: never;
|
|
4895
|
-
path?: never;
|
|
4896
|
-
cookie?: never;
|
|
4897
|
-
};
|
|
4898
|
-
/**
|
|
4899
|
-
* List chats
|
|
4900
|
-
* @description Cursor-paginated list of the caller's conversations, newest activity first. Filter by `line_id`. On shared-plan (virtual) lines each chat carries `outbound_number` — the physical number currently serving that contact (null once the binding is released; the next outbound is assigned a fresh number). Non-shared lines always carry `outbound_number: null`. Accepts an API key (`isnap_*`) or a dashboard JWT; line-scoped API keys only see chats of the lines in their allowlist.
|
|
4901
|
-
*/
|
|
4902
|
-
get: {
|
|
4903
|
-
parameters: {
|
|
4904
|
-
query?: {
|
|
4905
|
-
line_id?: string;
|
|
4906
|
-
limit?: number;
|
|
4907
|
-
cursor?: string;
|
|
4908
|
-
since?: string;
|
|
4909
|
-
until?: string;
|
|
4910
|
-
};
|
|
4911
|
-
header?: never;
|
|
4912
|
-
path?: never;
|
|
4913
|
-
cookie?: never;
|
|
4914
|
-
};
|
|
4915
|
-
requestBody?: never;
|
|
4916
|
-
responses: {
|
|
4917
|
-
/** @description Chat list */
|
|
4918
|
-
200: {
|
|
5878
|
+
/** @description Forbidden — caller authenticated but not allowed */
|
|
5879
|
+
403: {
|
|
4919
5880
|
headers: {
|
|
4920
5881
|
[name: string]: unknown;
|
|
4921
5882
|
};
|
|
4922
5883
|
content: {
|
|
4923
|
-
"application/json": components["schemas"]["
|
|
5884
|
+
"application/json": components["schemas"]["ErrorEnvelope"];
|
|
4924
5885
|
};
|
|
4925
5886
|
};
|
|
4926
|
-
/** @description
|
|
4927
|
-
|
|
5887
|
+
/** @description Not found */
|
|
5888
|
+
404: {
|
|
4928
5889
|
headers: {
|
|
4929
5890
|
[name: string]: unknown;
|
|
4930
5891
|
};
|
|
@@ -4932,8 +5893,8 @@ export interface paths {
|
|
|
4932
5893
|
"application/json": components["schemas"]["ErrorEnvelope"];
|
|
4933
5894
|
};
|
|
4934
5895
|
};
|
|
4935
|
-
/** @description
|
|
4936
|
-
|
|
5896
|
+
/** @description Unprocessable — domain rule violation */
|
|
5897
|
+
422: {
|
|
4937
5898
|
headers: {
|
|
4938
5899
|
[name: string]: unknown;
|
|
4939
5900
|
};
|
|
@@ -4961,26 +5922,7 @@ export interface paths {
|
|
|
4961
5922
|
};
|
|
4962
5923
|
};
|
|
4963
5924
|
};
|
|
4964
|
-
|
|
4965
|
-
post?: never;
|
|
4966
|
-
delete?: never;
|
|
4967
|
-
options?: never;
|
|
4968
|
-
head?: never;
|
|
4969
|
-
patch?: never;
|
|
4970
|
-
trace?: never;
|
|
4971
|
-
};
|
|
4972
|
-
"/v1/chats/{chat_id}": {
|
|
4973
|
-
parameters: {
|
|
4974
|
-
query?: never;
|
|
4975
|
-
header?: never;
|
|
4976
|
-
path?: never;
|
|
4977
|
-
cookie?: never;
|
|
4978
|
-
};
|
|
4979
|
-
/**
|
|
4980
|
-
* Get a chat
|
|
4981
|
-
* @description Fetch a single conversation by its `chat_<base62>` id. Same shape as the list items, including `outbound_number` for shared-plan lines. Cross-account and out-of-scope ids resolve 404 (no existence leak).
|
|
4982
|
-
*/
|
|
4983
|
-
get: {
|
|
5925
|
+
delete: {
|
|
4984
5926
|
parameters: {
|
|
4985
5927
|
query?: never;
|
|
4986
5928
|
header?: never;
|
|
@@ -4991,13 +5933,13 @@ export interface paths {
|
|
|
4991
5933
|
};
|
|
4992
5934
|
requestBody?: never;
|
|
4993
5935
|
responses: {
|
|
4994
|
-
/** @description
|
|
5936
|
+
/** @description Typing indicator stopped */
|
|
4995
5937
|
200: {
|
|
4996
5938
|
headers: {
|
|
4997
5939
|
[name: string]: unknown;
|
|
4998
5940
|
};
|
|
4999
5941
|
content: {
|
|
5000
|
-
"application/json": components["schemas"]["
|
|
5942
|
+
"application/json": components["schemas"]["ChatTypingStopEnvelope"];
|
|
5001
5943
|
};
|
|
5002
5944
|
};
|
|
5003
5945
|
/** @description Bad request — validation failed */
|
|
@@ -5018,6 +5960,15 @@ export interface paths {
|
|
|
5018
5960
|
"application/json": components["schemas"]["ErrorEnvelope"];
|
|
5019
5961
|
};
|
|
5020
5962
|
};
|
|
5963
|
+
/** @description Forbidden — caller authenticated but not allowed */
|
|
5964
|
+
403: {
|
|
5965
|
+
headers: {
|
|
5966
|
+
[name: string]: unknown;
|
|
5967
|
+
};
|
|
5968
|
+
content: {
|
|
5969
|
+
"application/json": components["schemas"]["ErrorEnvelope"];
|
|
5970
|
+
};
|
|
5971
|
+
};
|
|
5021
5972
|
/** @description Not found */
|
|
5022
5973
|
404: {
|
|
5023
5974
|
headers: {
|
|
@@ -5047,15 +5998,12 @@ export interface paths {
|
|
|
5047
5998
|
};
|
|
5048
5999
|
};
|
|
5049
6000
|
};
|
|
5050
|
-
put?: never;
|
|
5051
|
-
post?: never;
|
|
5052
|
-
delete?: never;
|
|
5053
6001
|
options?: never;
|
|
5054
6002
|
head?: never;
|
|
5055
6003
|
patch?: never;
|
|
5056
6004
|
trace?: never;
|
|
5057
6005
|
};
|
|
5058
|
-
"/v1/chats/{chat_id}/
|
|
6006
|
+
"/v1/chats/{chat_id}/read": {
|
|
5059
6007
|
parameters: {
|
|
5060
6008
|
query?: never;
|
|
5061
6009
|
header?: never;
|
|
@@ -5075,26 +6023,17 @@ export interface paths {
|
|
|
5075
6023
|
};
|
|
5076
6024
|
requestBody?: {
|
|
5077
6025
|
content: {
|
|
5078
|
-
"application/json":
|
|
5079
|
-
first_name: string;
|
|
5080
|
-
last_name?: string;
|
|
5081
|
-
/** Format: uri */
|
|
5082
|
-
avatar_url?: string;
|
|
5083
|
-
phone_numbers?: string[];
|
|
5084
|
-
emails?: string[];
|
|
5085
|
-
organization?: string;
|
|
5086
|
-
note?: string;
|
|
5087
|
-
};
|
|
6026
|
+
"application/json": Record<string, never>;
|
|
5088
6027
|
};
|
|
5089
6028
|
};
|
|
5090
6029
|
responses: {
|
|
5091
|
-
/** @description
|
|
5092
|
-
|
|
6030
|
+
/** @description Chat marked read */
|
|
6031
|
+
200: {
|
|
5093
6032
|
headers: {
|
|
5094
6033
|
[name: string]: unknown;
|
|
5095
6034
|
};
|
|
5096
6035
|
content: {
|
|
5097
|
-
"application/json": components["schemas"]["
|
|
6036
|
+
"application/json": components["schemas"]["ChatMarkReadEnvelope"];
|
|
5098
6037
|
};
|
|
5099
6038
|
};
|
|
5100
6039
|
/** @description Bad request — validation failed */
|
|
@@ -5133,15 +6072,6 @@ export interface paths {
|
|
|
5133
6072
|
"application/json": components["schemas"]["ErrorEnvelope"];
|
|
5134
6073
|
};
|
|
5135
6074
|
};
|
|
5136
|
-
/** @description Unprocessable — domain rule violation */
|
|
5137
|
-
422: {
|
|
5138
|
-
headers: {
|
|
5139
|
-
[name: string]: unknown;
|
|
5140
|
-
};
|
|
5141
|
-
content: {
|
|
5142
|
-
"application/json": components["schemas"]["ErrorEnvelope"];
|
|
5143
|
-
};
|
|
5144
|
-
};
|
|
5145
6075
|
/** @description Too many requests — rate limit exceeded */
|
|
5146
6076
|
429: {
|
|
5147
6077
|
headers: {
|
|
@@ -5168,7 +6098,7 @@ export interface paths {
|
|
|
5168
6098
|
patch?: never;
|
|
5169
6099
|
trace?: never;
|
|
5170
6100
|
};
|
|
5171
|
-
"/v1/
|
|
6101
|
+
"/v1/trial/init": {
|
|
5172
6102
|
parameters: {
|
|
5173
6103
|
query?: never;
|
|
5174
6104
|
header?: never;
|
|
@@ -5177,28 +6107,30 @@ export interface paths {
|
|
|
5177
6107
|
};
|
|
5178
6108
|
get?: never;
|
|
5179
6109
|
put?: never;
|
|
6110
|
+
/**
|
|
6111
|
+
* Start a trial session
|
|
6112
|
+
* @description Create a pairing-pending trial session owned by the caller (dashboard JWT for direct self-serve, or an API key for wholesale/SDK). 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 pool line. Direct accounts may hold only one live trial at a time.
|
|
6113
|
+
*/
|
|
5180
6114
|
post: {
|
|
5181
6115
|
parameters: {
|
|
5182
6116
|
query?: never;
|
|
5183
6117
|
header?: never;
|
|
5184
|
-
path
|
|
5185
|
-
chat_id: string;
|
|
5186
|
-
};
|
|
6118
|
+
path?: never;
|
|
5187
6119
|
cookie?: never;
|
|
5188
6120
|
};
|
|
5189
6121
|
requestBody?: {
|
|
5190
6122
|
content: {
|
|
5191
|
-
"application/json":
|
|
6123
|
+
"application/json": components["schemas"]["TrialInitBody"];
|
|
5192
6124
|
};
|
|
5193
6125
|
};
|
|
5194
6126
|
responses: {
|
|
5195
|
-
/** @description
|
|
5196
|
-
|
|
6127
|
+
/** @description Trial session created — pairing pending */
|
|
6128
|
+
201: {
|
|
5197
6129
|
headers: {
|
|
5198
6130
|
[name: string]: unknown;
|
|
5199
6131
|
};
|
|
5200
6132
|
content: {
|
|
5201
|
-
"application/json": components["schemas"]["
|
|
6133
|
+
"application/json": components["schemas"]["TrialInitEnvelope"];
|
|
5202
6134
|
};
|
|
5203
6135
|
};
|
|
5204
6136
|
/** @description Bad request — validation failed */
|
|
@@ -5219,26 +6151,8 @@ export interface paths {
|
|
|
5219
6151
|
"application/json": components["schemas"]["ErrorEnvelope"];
|
|
5220
6152
|
};
|
|
5221
6153
|
};
|
|
5222
|
-
/** @description
|
|
5223
|
-
|
|
5224
|
-
headers: {
|
|
5225
|
-
[name: string]: unknown;
|
|
5226
|
-
};
|
|
5227
|
-
content: {
|
|
5228
|
-
"application/json": components["schemas"]["ErrorEnvelope"];
|
|
5229
|
-
};
|
|
5230
|
-
};
|
|
5231
|
-
/** @description Not found */
|
|
5232
|
-
404: {
|
|
5233
|
-
headers: {
|
|
5234
|
-
[name: string]: unknown;
|
|
5235
|
-
};
|
|
5236
|
-
content: {
|
|
5237
|
-
"application/json": components["schemas"]["ErrorEnvelope"];
|
|
5238
|
-
};
|
|
5239
|
-
};
|
|
5240
|
-
/** @description Unprocessable — domain rule violation */
|
|
5241
|
-
422: {
|
|
6154
|
+
/** @description Conflict — concurrent or terminal state */
|
|
6155
|
+
409: {
|
|
5242
6156
|
headers: {
|
|
5243
6157
|
[name: string]: unknown;
|
|
5244
6158
|
};
|
|
@@ -5266,24 +6180,41 @@ export interface paths {
|
|
|
5266
6180
|
};
|
|
5267
6181
|
};
|
|
5268
6182
|
};
|
|
5269
|
-
delete
|
|
6183
|
+
delete?: never;
|
|
6184
|
+
options?: never;
|
|
6185
|
+
head?: never;
|
|
6186
|
+
patch?: never;
|
|
6187
|
+
trace?: never;
|
|
6188
|
+
};
|
|
6189
|
+
"/v1/trial/status": {
|
|
6190
|
+
parameters: {
|
|
6191
|
+
query?: never;
|
|
6192
|
+
header?: never;
|
|
6193
|
+
path?: never;
|
|
6194
|
+
cookie?: never;
|
|
6195
|
+
};
|
|
6196
|
+
/**
|
|
6197
|
+
* Check trial pairing status
|
|
6198
|
+
* @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.
|
|
6199
|
+
*/
|
|
6200
|
+
get: {
|
|
5270
6201
|
parameters: {
|
|
5271
|
-
query
|
|
5272
|
-
|
|
5273
|
-
path: {
|
|
5274
|
-
chat_id: string;
|
|
6202
|
+
query: {
|
|
6203
|
+
token: string;
|
|
5275
6204
|
};
|
|
6205
|
+
header?: never;
|
|
6206
|
+
path?: never;
|
|
5276
6207
|
cookie?: never;
|
|
5277
6208
|
};
|
|
5278
6209
|
requestBody?: never;
|
|
5279
6210
|
responses: {
|
|
5280
|
-
/** @description
|
|
6211
|
+
/** @description Current trial status */
|
|
5281
6212
|
200: {
|
|
5282
6213
|
headers: {
|
|
5283
6214
|
[name: string]: unknown;
|
|
5284
6215
|
};
|
|
5285
6216
|
content: {
|
|
5286
|
-
"application/json": components["schemas"]["
|
|
6217
|
+
"application/json": components["schemas"]["TrialStatusEnvelope"];
|
|
5287
6218
|
};
|
|
5288
6219
|
};
|
|
5289
6220
|
/** @description Bad request — validation failed */
|
|
@@ -5295,8 +6226,8 @@ export interface paths {
|
|
|
5295
6226
|
"application/json": components["schemas"]["ErrorEnvelope"];
|
|
5296
6227
|
};
|
|
5297
6228
|
};
|
|
5298
|
-
/** @description
|
|
5299
|
-
|
|
6229
|
+
/** @description Not found */
|
|
6230
|
+
404: {
|
|
5300
6231
|
headers: {
|
|
5301
6232
|
[name: string]: unknown;
|
|
5302
6233
|
};
|
|
@@ -5304,8 +6235,65 @@ export interface paths {
|
|
|
5304
6235
|
"application/json": components["schemas"]["ErrorEnvelope"];
|
|
5305
6236
|
};
|
|
5306
6237
|
};
|
|
5307
|
-
/** @description
|
|
5308
|
-
|
|
6238
|
+
/** @description Too many requests — rate limit exceeded */
|
|
6239
|
+
429: {
|
|
6240
|
+
headers: {
|
|
6241
|
+
[name: string]: unknown;
|
|
6242
|
+
};
|
|
6243
|
+
content: {
|
|
6244
|
+
"application/json": components["schemas"]["ErrorEnvelope"];
|
|
6245
|
+
};
|
|
6246
|
+
};
|
|
6247
|
+
/** @description Internal server error */
|
|
6248
|
+
500: {
|
|
6249
|
+
headers: {
|
|
6250
|
+
[name: string]: unknown;
|
|
6251
|
+
};
|
|
6252
|
+
content: {
|
|
6253
|
+
"application/json": components["schemas"]["ErrorEnvelope"];
|
|
6254
|
+
};
|
|
6255
|
+
};
|
|
6256
|
+
};
|
|
6257
|
+
};
|
|
6258
|
+
put?: never;
|
|
6259
|
+
post?: never;
|
|
6260
|
+
delete?: never;
|
|
6261
|
+
options?: never;
|
|
6262
|
+
head?: never;
|
|
6263
|
+
patch?: never;
|
|
6264
|
+
trace?: never;
|
|
6265
|
+
};
|
|
6266
|
+
"/v1/trial/activity": {
|
|
6267
|
+
parameters: {
|
|
6268
|
+
query?: never;
|
|
6269
|
+
header?: never;
|
|
6270
|
+
path?: never;
|
|
6271
|
+
cookie?: never;
|
|
6272
|
+
};
|
|
6273
|
+
/**
|
|
6274
|
+
* Get trial activity counters
|
|
6275
|
+
* @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).
|
|
6276
|
+
*/
|
|
6277
|
+
get: {
|
|
6278
|
+
parameters: {
|
|
6279
|
+
query?: never;
|
|
6280
|
+
header?: never;
|
|
6281
|
+
path?: never;
|
|
6282
|
+
cookie?: never;
|
|
6283
|
+
};
|
|
6284
|
+
requestBody?: never;
|
|
6285
|
+
responses: {
|
|
6286
|
+
/** @description Trial activity snapshot */
|
|
6287
|
+
200: {
|
|
6288
|
+
headers: {
|
|
6289
|
+
[name: string]: unknown;
|
|
6290
|
+
};
|
|
6291
|
+
content: {
|
|
6292
|
+
"application/json": components["schemas"]["TrialActivityEnvelope"];
|
|
6293
|
+
};
|
|
6294
|
+
};
|
|
6295
|
+
/** @description Bad request — validation failed */
|
|
6296
|
+
400: {
|
|
5309
6297
|
headers: {
|
|
5310
6298
|
[name: string]: unknown;
|
|
5311
6299
|
};
|
|
@@ -5313,8 +6301,8 @@ export interface paths {
|
|
|
5313
6301
|
"application/json": components["schemas"]["ErrorEnvelope"];
|
|
5314
6302
|
};
|
|
5315
6303
|
};
|
|
5316
|
-
/** @description
|
|
5317
|
-
|
|
6304
|
+
/** @description Unauthenticated — missing or invalid bearer token */
|
|
6305
|
+
401: {
|
|
5318
6306
|
headers: {
|
|
5319
6307
|
[name: string]: unknown;
|
|
5320
6308
|
};
|
|
@@ -5342,12 +6330,15 @@ export interface paths {
|
|
|
5342
6330
|
};
|
|
5343
6331
|
};
|
|
5344
6332
|
};
|
|
6333
|
+
put?: never;
|
|
6334
|
+
post?: never;
|
|
6335
|
+
delete?: never;
|
|
5345
6336
|
options?: never;
|
|
5346
6337
|
head?: never;
|
|
5347
6338
|
patch?: never;
|
|
5348
6339
|
trace?: never;
|
|
5349
6340
|
};
|
|
5350
|
-
"/v1/
|
|
6341
|
+
"/v1/trial/{trial_id}/revoke": {
|
|
5351
6342
|
parameters: {
|
|
5352
6343
|
query?: never;
|
|
5353
6344
|
header?: never;
|
|
@@ -5356,28 +6347,33 @@ export interface paths {
|
|
|
5356
6347
|
};
|
|
5357
6348
|
get?: never;
|
|
5358
6349
|
put?: never;
|
|
6350
|
+
/**
|
|
6351
|
+
* Revoke a trial session
|
|
6352
|
+
* @description Terminate a trial owned by the caller, freeing its pool-line slot (the same handle can immediately start a fresh trial) and invalidating its trial API key. Idempotent — revoking an already-revoked trial returns `already_revoked: true` with a 200. A trial the caller does not own returns 404 (no existence leak). Per-partner rebind policy (WHA-1642) applies ONLY to `reason: rebind` (`partner`/`admin` always pass): a partner with rebind disabled gets 403 `rebind_not_allowed`, and one over its daily rebind cap gets 429 `rebind_cap_reached` carrying `retry_at`.
|
|
6353
|
+
*/
|
|
5359
6354
|
post: {
|
|
5360
6355
|
parameters: {
|
|
5361
6356
|
query?: never;
|
|
5362
6357
|
header?: never;
|
|
5363
6358
|
path: {
|
|
5364
|
-
|
|
6359
|
+
/** @description The trl_<base62> public id returned by POST /v1/trial/init. */
|
|
6360
|
+
trial_id: string;
|
|
5365
6361
|
};
|
|
5366
6362
|
cookie?: never;
|
|
5367
6363
|
};
|
|
5368
6364
|
requestBody?: {
|
|
5369
6365
|
content: {
|
|
5370
|
-
"application/json":
|
|
6366
|
+
"application/json": components["schemas"]["TrialRevokeBody"];
|
|
5371
6367
|
};
|
|
5372
6368
|
};
|
|
5373
6369
|
responses: {
|
|
5374
|
-
/** @description
|
|
6370
|
+
/** @description Trial revoked (idempotent) */
|
|
5375
6371
|
200: {
|
|
5376
6372
|
headers: {
|
|
5377
6373
|
[name: string]: unknown;
|
|
5378
6374
|
};
|
|
5379
6375
|
content: {
|
|
5380
|
-
"application/json": components["schemas"]["
|
|
6376
|
+
"application/json": components["schemas"]["TrialRevokeEnvelope"];
|
|
5381
6377
|
};
|
|
5382
6378
|
};
|
|
5383
6379
|
/** @description Bad request — validation failed */
|
|
@@ -5416,6 +6412,15 @@ export interface paths {
|
|
|
5416
6412
|
"application/json": components["schemas"]["ErrorEnvelope"];
|
|
5417
6413
|
};
|
|
5418
6414
|
};
|
|
6415
|
+
/** @description Unprocessable — domain rule violation */
|
|
6416
|
+
422: {
|
|
6417
|
+
headers: {
|
|
6418
|
+
[name: string]: unknown;
|
|
6419
|
+
};
|
|
6420
|
+
content: {
|
|
6421
|
+
"application/json": components["schemas"]["ErrorEnvelope"];
|
|
6422
|
+
};
|
|
6423
|
+
};
|
|
5419
6424
|
/** @description Too many requests — rate limit exceeded */
|
|
5420
6425
|
429: {
|
|
5421
6426
|
headers: {
|
|
@@ -5442,7 +6447,7 @@ export interface paths {
|
|
|
5442
6447
|
patch?: never;
|
|
5443
6448
|
trace?: never;
|
|
5444
6449
|
};
|
|
5445
|
-
"/v1/
|
|
6450
|
+
"/v1/byod/pair": {
|
|
5446
6451
|
parameters: {
|
|
5447
6452
|
query?: never;
|
|
5448
6453
|
header?: never;
|
|
@@ -5452,8 +6457,8 @@ export interface paths {
|
|
|
5452
6457
|
get?: never;
|
|
5453
6458
|
put?: never;
|
|
5454
6459
|
/**
|
|
5455
|
-
* Start a
|
|
5456
|
-
* @description
|
|
6460
|
+
* Start a BYOD pairing flow
|
|
6461
|
+
* @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.
|
|
5457
6462
|
*/
|
|
5458
6463
|
post: {
|
|
5459
6464
|
parameters: {
|
|
@@ -5464,17 +6469,17 @@ export interface paths {
|
|
|
5464
6469
|
};
|
|
5465
6470
|
requestBody?: {
|
|
5466
6471
|
content: {
|
|
5467
|
-
"application/json": components["schemas"]["
|
|
6472
|
+
"application/json": components["schemas"]["ByodPairBody"];
|
|
5468
6473
|
};
|
|
5469
6474
|
};
|
|
5470
6475
|
responses: {
|
|
5471
|
-
/** @description
|
|
6476
|
+
/** @description Activation code + bridge download URL */
|
|
5472
6477
|
201: {
|
|
5473
6478
|
headers: {
|
|
5474
6479
|
[name: string]: unknown;
|
|
5475
6480
|
};
|
|
5476
6481
|
content: {
|
|
5477
|
-
"application/json": components["schemas"]["
|
|
6482
|
+
"application/json": components["schemas"]["ByodPairEnvelope"];
|
|
5478
6483
|
};
|
|
5479
6484
|
};
|
|
5480
6485
|
/** @description Bad request — validation failed */
|
|
@@ -5495,8 +6500,8 @@ export interface paths {
|
|
|
5495
6500
|
"application/json": components["schemas"]["ErrorEnvelope"];
|
|
5496
6501
|
};
|
|
5497
6502
|
};
|
|
5498
|
-
/** @description
|
|
5499
|
-
|
|
6503
|
+
/** @description Not found */
|
|
6504
|
+
404: {
|
|
5500
6505
|
headers: {
|
|
5501
6506
|
[name: string]: unknown;
|
|
5502
6507
|
};
|
|
@@ -5530,35 +6535,35 @@ export interface paths {
|
|
|
5530
6535
|
patch?: never;
|
|
5531
6536
|
trace?: never;
|
|
5532
6537
|
};
|
|
5533
|
-
"/v1/
|
|
6538
|
+
"/v1/macos-sessions/rent": {
|
|
5534
6539
|
parameters: {
|
|
5535
6540
|
query?: never;
|
|
5536
6541
|
header?: never;
|
|
5537
6542
|
path?: never;
|
|
5538
6543
|
cookie?: never;
|
|
5539
6544
|
};
|
|
6545
|
+
get?: never;
|
|
6546
|
+
put?: never;
|
|
5540
6547
|
/**
|
|
5541
|
-
*
|
|
5542
|
-
* @description
|
|
6548
|
+
* Rent a hosted macOS session
|
|
6549
|
+
* @description Take one hosted macOS session out of iSnap stock on the calling wholesale partner’s account. The tenancy starts immediately and `anniversary_at` is stamped with the day it was taken — that day of the month is what the session bills on, clamped to the last day of shorter months. Returns `409 no_macos_session_in_stock` when no confirmed, unrented session sits on a delivered Mac; iSnap provisions one and attaches it, and no request needs to be repeated. Direct customers do not use this verb — they buy sessions through `POST /v1/billing/mac-checkout` and are refused here with `403 not_a_wholesale_partner`.
|
|
5543
6550
|
*/
|
|
5544
|
-
|
|
6551
|
+
post: {
|
|
5545
6552
|
parameters: {
|
|
5546
|
-
query
|
|
5547
|
-
token: string;
|
|
5548
|
-
};
|
|
6553
|
+
query?: never;
|
|
5549
6554
|
header?: never;
|
|
5550
6555
|
path?: never;
|
|
5551
6556
|
cookie?: never;
|
|
5552
6557
|
};
|
|
5553
6558
|
requestBody?: never;
|
|
5554
6559
|
responses: {
|
|
5555
|
-
/** @description
|
|
5556
|
-
|
|
6560
|
+
/** @description The rented session */
|
|
6561
|
+
201: {
|
|
5557
6562
|
headers: {
|
|
5558
6563
|
[name: string]: unknown;
|
|
5559
6564
|
};
|
|
5560
6565
|
content: {
|
|
5561
|
-
"application/json": components["schemas"]["
|
|
6566
|
+
"application/json": components["schemas"]["MacosSessionEnvelope"];
|
|
5562
6567
|
};
|
|
5563
6568
|
};
|
|
5564
6569
|
/** @description Bad request — validation failed */
|
|
@@ -5570,26 +6575,8 @@ export interface paths {
|
|
|
5570
6575
|
"application/json": components["schemas"]["ErrorEnvelope"];
|
|
5571
6576
|
};
|
|
5572
6577
|
};
|
|
5573
|
-
/** @description
|
|
5574
|
-
|
|
5575
|
-
headers: {
|
|
5576
|
-
[name: string]: unknown;
|
|
5577
|
-
};
|
|
5578
|
-
content: {
|
|
5579
|
-
"application/json": components["schemas"]["ErrorEnvelope"];
|
|
5580
|
-
};
|
|
5581
|
-
};
|
|
5582
|
-
/** @description Too many requests — rate limit exceeded */
|
|
5583
|
-
429: {
|
|
5584
|
-
headers: {
|
|
5585
|
-
[name: string]: unknown;
|
|
5586
|
-
};
|
|
5587
|
-
content: {
|
|
5588
|
-
"application/json": components["schemas"]["ErrorEnvelope"];
|
|
5589
|
-
};
|
|
5590
|
-
};
|
|
5591
|
-
/** @description Internal server error */
|
|
5592
|
-
500: {
|
|
6578
|
+
/** @description Unauthenticated — missing or invalid bearer token */
|
|
6579
|
+
401: {
|
|
5593
6580
|
headers: {
|
|
5594
6581
|
[name: string]: unknown;
|
|
5595
6582
|
};
|
|
@@ -5597,47 +6584,8 @@ export interface paths {
|
|
|
5597
6584
|
"application/json": components["schemas"]["ErrorEnvelope"];
|
|
5598
6585
|
};
|
|
5599
6586
|
};
|
|
5600
|
-
|
|
5601
|
-
|
|
5602
|
-
put?: never;
|
|
5603
|
-
post?: never;
|
|
5604
|
-
delete?: never;
|
|
5605
|
-
options?: never;
|
|
5606
|
-
head?: never;
|
|
5607
|
-
patch?: never;
|
|
5608
|
-
trace?: never;
|
|
5609
|
-
};
|
|
5610
|
-
"/v1/trial/activity": {
|
|
5611
|
-
parameters: {
|
|
5612
|
-
query?: never;
|
|
5613
|
-
header?: never;
|
|
5614
|
-
path?: never;
|
|
5615
|
-
cookie?: never;
|
|
5616
|
-
};
|
|
5617
|
-
/**
|
|
5618
|
-
* Get trial activity counters
|
|
5619
|
-
* @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).
|
|
5620
|
-
*/
|
|
5621
|
-
get: {
|
|
5622
|
-
parameters: {
|
|
5623
|
-
query?: never;
|
|
5624
|
-
header?: never;
|
|
5625
|
-
path?: never;
|
|
5626
|
-
cookie?: never;
|
|
5627
|
-
};
|
|
5628
|
-
requestBody?: never;
|
|
5629
|
-
responses: {
|
|
5630
|
-
/** @description Trial activity snapshot */
|
|
5631
|
-
200: {
|
|
5632
|
-
headers: {
|
|
5633
|
-
[name: string]: unknown;
|
|
5634
|
-
};
|
|
5635
|
-
content: {
|
|
5636
|
-
"application/json": components["schemas"]["TrialActivityEnvelope"];
|
|
5637
|
-
};
|
|
5638
|
-
};
|
|
5639
|
-
/** @description Bad request — validation failed */
|
|
5640
|
-
400: {
|
|
6587
|
+
/** @description Forbidden — caller authenticated but not allowed */
|
|
6588
|
+
403: {
|
|
5641
6589
|
headers: {
|
|
5642
6590
|
[name: string]: unknown;
|
|
5643
6591
|
};
|
|
@@ -5645,8 +6593,8 @@ export interface paths {
|
|
|
5645
6593
|
"application/json": components["schemas"]["ErrorEnvelope"];
|
|
5646
6594
|
};
|
|
5647
6595
|
};
|
|
5648
|
-
/** @description
|
|
5649
|
-
|
|
6596
|
+
/** @description Conflict — concurrent or terminal state */
|
|
6597
|
+
409: {
|
|
5650
6598
|
headers: {
|
|
5651
6599
|
[name: string]: unknown;
|
|
5652
6600
|
};
|
|
@@ -5674,15 +6622,13 @@ export interface paths {
|
|
|
5674
6622
|
};
|
|
5675
6623
|
};
|
|
5676
6624
|
};
|
|
5677
|
-
put?: never;
|
|
5678
|
-
post?: never;
|
|
5679
6625
|
delete?: never;
|
|
5680
6626
|
options?: never;
|
|
5681
6627
|
head?: never;
|
|
5682
6628
|
patch?: never;
|
|
5683
6629
|
trace?: never;
|
|
5684
6630
|
};
|
|
5685
|
-
"/v1/
|
|
6631
|
+
"/v1/macos-sessions/{id}/cancel": {
|
|
5686
6632
|
parameters: {
|
|
5687
6633
|
query?: never;
|
|
5688
6634
|
header?: never;
|
|
@@ -5692,32 +6638,27 @@ export interface paths {
|
|
|
5692
6638
|
get?: never;
|
|
5693
6639
|
put?: never;
|
|
5694
6640
|
/**
|
|
5695
|
-
*
|
|
5696
|
-
* @description
|
|
6641
|
+
* Cancel a rented macOS session
|
|
6642
|
+
* @description End the tenancy at its next anniversary. The session stays usable and keeps billing until `cancel_at`, which is the next occurrence of `anniversary_at` strictly after the cancellation — so cancelling ON the anniversary buys the month that starts that day, never zero days. Idempotent: a second call returns the `cancel_at` the first one set rather than pushing it a month further out. Only the renting partner may cancel; every other caller gets `404`.
|
|
5697
6643
|
*/
|
|
5698
6644
|
post: {
|
|
5699
6645
|
parameters: {
|
|
5700
6646
|
query?: never;
|
|
5701
6647
|
header?: never;
|
|
5702
6648
|
path: {
|
|
5703
|
-
|
|
5704
|
-
trial_id: string;
|
|
6649
|
+
id: string;
|
|
5705
6650
|
};
|
|
5706
6651
|
cookie?: never;
|
|
5707
6652
|
};
|
|
5708
|
-
requestBody?:
|
|
5709
|
-
content: {
|
|
5710
|
-
"application/json": components["schemas"]["TrialRevokeBody"];
|
|
5711
|
-
};
|
|
5712
|
-
};
|
|
6653
|
+
requestBody?: never;
|
|
5713
6654
|
responses: {
|
|
5714
|
-
/** @description
|
|
6655
|
+
/** @description The cancelled session */
|
|
5715
6656
|
200: {
|
|
5716
6657
|
headers: {
|
|
5717
6658
|
[name: string]: unknown;
|
|
5718
6659
|
};
|
|
5719
6660
|
content: {
|
|
5720
|
-
"application/json": components["schemas"]["
|
|
6661
|
+
"application/json": components["schemas"]["MacosSessionEnvelope"];
|
|
5721
6662
|
};
|
|
5722
6663
|
};
|
|
5723
6664
|
/** @description Bad request — validation failed */
|
|
@@ -5738,15 +6679,6 @@ export interface paths {
|
|
|
5738
6679
|
"application/json": components["schemas"]["ErrorEnvelope"];
|
|
5739
6680
|
};
|
|
5740
6681
|
};
|
|
5741
|
-
/** @description Forbidden — caller authenticated but not allowed */
|
|
5742
|
-
403: {
|
|
5743
|
-
headers: {
|
|
5744
|
-
[name: string]: unknown;
|
|
5745
|
-
};
|
|
5746
|
-
content: {
|
|
5747
|
-
"application/json": components["schemas"]["ErrorEnvelope"];
|
|
5748
|
-
};
|
|
5749
|
-
};
|
|
5750
6682
|
/** @description Not found */
|
|
5751
6683
|
404: {
|
|
5752
6684
|
headers: {
|
|
@@ -5756,8 +6688,8 @@ export interface paths {
|
|
|
5756
6688
|
"application/json": components["schemas"]["ErrorEnvelope"];
|
|
5757
6689
|
};
|
|
5758
6690
|
};
|
|
5759
|
-
/** @description
|
|
5760
|
-
|
|
6691
|
+
/** @description Conflict — concurrent or terminal state */
|
|
6692
|
+
409: {
|
|
5761
6693
|
headers: {
|
|
5762
6694
|
[name: string]: unknown;
|
|
5763
6695
|
};
|
|
@@ -5791,7 +6723,7 @@ export interface paths {
|
|
|
5791
6723
|
patch?: never;
|
|
5792
6724
|
trace?: never;
|
|
5793
6725
|
};
|
|
5794
|
-
"/v1/
|
|
6726
|
+
"/v1/macos-sessions/{id}/uncancel": {
|
|
5795
6727
|
parameters: {
|
|
5796
6728
|
query?: never;
|
|
5797
6729
|
header?: never;
|
|
@@ -5801,29 +6733,27 @@ export interface paths {
|
|
|
5801
6733
|
get?: never;
|
|
5802
6734
|
put?: never;
|
|
5803
6735
|
/**
|
|
5804
|
-
*
|
|
5805
|
-
* @description
|
|
6736
|
+
* Keep a cancelled macOS session
|
|
6737
|
+
* @description Withdraw a pending cancellation, clearing `cancel_at` and leaving `anniversary_at` untouched — the billing day does not move. Idempotent on a session that is not cancelled. Only possible before the release runs: once `cancel_at` has passed the paid month is over and this answers `409 macos_session_cancellation_already_due` — the release is hourly, so there is a window in which the date has passed and the session is still rented, and un-cancelling inside it would hold a seat the monthly tally has already stopped billing. After the release has run the tenancy is gone and this returns `404`; the session must be rented again.
|
|
5806
6738
|
*/
|
|
5807
6739
|
post: {
|
|
5808
6740
|
parameters: {
|
|
5809
6741
|
query?: never;
|
|
5810
6742
|
header?: never;
|
|
5811
|
-
path
|
|
5812
|
-
|
|
5813
|
-
};
|
|
5814
|
-
requestBody?: {
|
|
5815
|
-
content: {
|
|
5816
|
-
"application/json": components["schemas"]["ByodPairBody"];
|
|
6743
|
+
path: {
|
|
6744
|
+
id: string;
|
|
5817
6745
|
};
|
|
6746
|
+
cookie?: never;
|
|
5818
6747
|
};
|
|
6748
|
+
requestBody?: never;
|
|
5819
6749
|
responses: {
|
|
5820
|
-
/** @description
|
|
5821
|
-
|
|
6750
|
+
/** @description The session, no longer cancelled */
|
|
6751
|
+
200: {
|
|
5822
6752
|
headers: {
|
|
5823
6753
|
[name: string]: unknown;
|
|
5824
6754
|
};
|
|
5825
6755
|
content: {
|
|
5826
|
-
"application/json": components["schemas"]["
|
|
6756
|
+
"application/json": components["schemas"]["MacosSessionEnvelope"];
|
|
5827
6757
|
};
|
|
5828
6758
|
};
|
|
5829
6759
|
/** @description Bad request — validation failed */
|
|
@@ -5853,6 +6783,15 @@ export interface paths {
|
|
|
5853
6783
|
"application/json": components["schemas"]["ErrorEnvelope"];
|
|
5854
6784
|
};
|
|
5855
6785
|
};
|
|
6786
|
+
/** @description Conflict — concurrent or terminal state */
|
|
6787
|
+
409: {
|
|
6788
|
+
headers: {
|
|
6789
|
+
[name: string]: unknown;
|
|
6790
|
+
};
|
|
6791
|
+
content: {
|
|
6792
|
+
"application/json": components["schemas"]["ErrorEnvelope"];
|
|
6793
|
+
};
|
|
6794
|
+
};
|
|
5856
6795
|
/** @description Too many requests — rate limit exceeded */
|
|
5857
6796
|
429: {
|
|
5858
6797
|
headers: {
|
|
@@ -5888,7 +6827,7 @@ export interface paths {
|
|
|
5888
6827
|
};
|
|
5889
6828
|
/**
|
|
5890
6829
|
* Get the app/bridge download manifest (public)
|
|
5891
|
-
* @description Per-platform installer URL,
|
|
6830
|
+
* @description Per-platform installer URL, published version, and availability. Requires no pairing and no auth — use it for setup guides, "add a device" flows, reinstalls, and update prompts. The URLs are the same stable 302-redirect endpoints `POST /v1/byod/pair` returns in `download_urls`, built by one shared builder so they cannot drift. `version` is read from the release feed beside the artifact the redirect resolves to, and is `null` when that feed publishes nothing — never a configured placeholder.
|
|
5892
6831
|
*/
|
|
5893
6832
|
get: {
|
|
5894
6833
|
parameters: {
|
|
@@ -5996,9 +6935,9 @@ export interface components {
|
|
|
5996
6935
|
state_name: string | null;
|
|
5997
6936
|
/** @enum {string} */
|
|
5998
6937
|
billing_tier: "rental_iphone" | "rental_android" | "byod_imessage" | "byod_android" | "shared_pool" | "shared_imessage";
|
|
5999
|
-
/** @description True when the customer owns the underlying hardware (BYOD billing tiers). BYOD lines expose the full line-health surface
|
|
6938
|
+
/** @description True when the customer owns the underlying hardware (BYOD billing tiers). BYOD lines expose the full line-health surface: GET /v1/lines/{id}/health, the immediate line.offline/line.connected with their diagnostic fields, and the device-health-flux events line.degraded and line.capability_changed. Rental lines (false) are told about DURABLE connectivity changes only, and with NO diagnostic detail by design — line.disconnected always; line.offline once an outage has lasted ≥15 minutes (durable:true, carrying only line_id and detected_at — present it as "line temporarily unavailable, being resolved by the provider"); line.connected on hand-over and on recovery from a surfaced outage — never a transient blip, and never the BYOD-only device-health-flux events they cannot act on. */
|
|
6000
6939
|
byod: boolean;
|
|
6001
|
-
/** @description True when the line is
|
|
6940
|
+
/** @description True when the line cannot INITIATE a conversation: the contact must send the first message, after which the exchange is unrestricted in both directions. It is NOT receive-only — the line replies, reacts and sends attachments normally once contacted. Messaging a handle that has never contacted the line is rejected with 403 outbound_first_forbidden, per recipient and with no time limit once unlocked. Cheaper than the outbound tier; always false on BYOD/pool lines. */
|
|
6002
6941
|
inbound_only: boolean;
|
|
6003
6942
|
capabilities?: unknown;
|
|
6004
6943
|
status: string;
|
|
@@ -6010,6 +6949,10 @@ export interface components {
|
|
|
6010
6949
|
stripe_subscription_id: string | null;
|
|
6011
6950
|
activated_at: string | null;
|
|
6012
6951
|
expires_at: string | null;
|
|
6952
|
+
/** @description The day you took this line, and therefore the day of the month it renews on: billed once per month at this instant, never prorated. Stamped when the line becomes yours; `null` means the line has no per-line anniversary — a direct customer's line renews on its Stripe subscription's own anchor, and a pool line is billed to nobody. Set it explicitly with POST /v1/lines/{id}/anniversary for a line you migrated from your own system, whose real start date iSnap cannot know. */
|
|
6953
|
+
anniversary_at: string | null;
|
|
6954
|
+
/** @description The anniversary occurrence at which iSnap will END this line, set by POST /v1/lines/{id}/cancel and cleared by POST /v1/lines/{id}/uncancel. The line stays fully active and usable until this instant — the month is already paid for and is never prorated — and iSnap terminates it itself when the date arrives. `null` means the line is not cancelled. It survives the termination it schedules, so a `cancelled` line still says which date ended it. */
|
|
6955
|
+
cancel_at: string | null;
|
|
6013
6956
|
created_at: string;
|
|
6014
6957
|
metadata: {
|
|
6015
6958
|
[key: string]: unknown;
|
|
@@ -6020,8 +6963,30 @@ export interface components {
|
|
|
6020
6963
|
shared: boolean;
|
|
6021
6964
|
fulfillment_status?: string | null;
|
|
6022
6965
|
};
|
|
6023
|
-
|
|
6024
|
-
|
|
6966
|
+
MacosSession: {
|
|
6967
|
+
/** @example mcs_7Kd2Nq8Rb4Xw1Ty6Ue9Ao3Ph5 */
|
|
6968
|
+
id: string;
|
|
6969
|
+
/** @description Whether this session is currently rented by the calling partner. `false` once it has been released back to iSnap stock. */
|
|
6970
|
+
rented: boolean;
|
|
6971
|
+
/**
|
|
6972
|
+
* Format: date-time
|
|
6973
|
+
* @description The day the session was taken, and the day of the month it bills on. Null once the session is released. A day-of-month past the end of a shorter month bills on that month’s last day.
|
|
6974
|
+
* @example 2026-09-07T14:32:00.000Z
|
|
6975
|
+
*/
|
|
6976
|
+
anniversary_at: string | null;
|
|
6977
|
+
/**
|
|
6978
|
+
* Format: date-time
|
|
6979
|
+
* @description When the tenancy ends — always the next occurrence of `anniversary_at` after the cancellation. Null when the session is not cancelled. The session stays usable and keeps billing until this instant.
|
|
6980
|
+
* @example 2026-10-07T14:32:00.000Z
|
|
6981
|
+
*/
|
|
6982
|
+
cancel_at: string | null;
|
|
6983
|
+
/**
|
|
6984
|
+
* @description `pending_provisioning` while the Mac hosting the session has not been delivered yet; `created` once it has.
|
|
6985
|
+
* @enum {string}
|
|
6986
|
+
*/
|
|
6987
|
+
status: "created" | "pending_provisioning";
|
|
6988
|
+
/** Format: date-time */
|
|
6989
|
+
created_at: string;
|
|
6025
6990
|
};
|
|
6026
6991
|
ApiKey: {
|
|
6027
6992
|
/** Format: uuid */
|
|
@@ -6034,6 +6999,9 @@ export interface components {
|
|
|
6034
6999
|
created_at: string;
|
|
6035
7000
|
last_used_at: string | null;
|
|
6036
7001
|
};
|
|
7002
|
+
ApiKeyCreate: components["schemas"]["ApiKey"] & {
|
|
7003
|
+
key: string;
|
|
7004
|
+
};
|
|
6037
7005
|
ApiKeyList: {
|
|
6038
7006
|
api_keys: components["schemas"]["ApiKey"][];
|
|
6039
7007
|
};
|
|
@@ -6072,6 +7040,17 @@ export interface components {
|
|
|
6072
7040
|
to_user_id: string;
|
|
6073
7041
|
preserve_device_session?: boolean;
|
|
6074
7042
|
};
|
|
7043
|
+
TerminateLine: {
|
|
7044
|
+
reason?: string;
|
|
7045
|
+
};
|
|
7046
|
+
SetLineAnniversary: {
|
|
7047
|
+
/**
|
|
7048
|
+
* Format: date-time
|
|
7049
|
+
* @description The instant you took this line (ISO-8601, UTC). Its day of the month becomes the line’s renewal day and the date a cancellation waits for; the time of day is kept, because the anniversary is an instant and not a calendar day. Use this for a line migrated from your own system, whose real start date iSnap cannot know — for a line taken through the iSnap API it is stamped automatically and does not need stating. A BYOD line carries one too — it is on the same monthly meter — even though iSnap cannot end it for you at that date. Refused (409 `line_cancellation_pending`) while the line carries a `cancel_at`, which was computed from the anniversary you are replacing: uncancel first, set the date, cancel again.
|
|
7050
|
+
* @example 2026-07-02T09:15:00Z
|
|
7051
|
+
*/
|
|
7052
|
+
anniversary_at: string;
|
|
7053
|
+
};
|
|
6075
7054
|
PatchLine: {
|
|
6076
7055
|
metadata: {
|
|
6077
7056
|
[key: string]: unknown;
|
|
@@ -6241,20 +7220,17 @@ export interface components {
|
|
|
6241
7220
|
PreOrder: {
|
|
6242
7221
|
/** Format: uuid */
|
|
6243
7222
|
id: string;
|
|
6244
|
-
/** @enum {string} */
|
|
6245
|
-
billing_tier: "rental_iphone" | "rental_android";
|
|
6246
7223
|
preferred_area_codes: string[];
|
|
7224
|
+
inbound_only: boolean;
|
|
6247
7225
|
status: components["schemas"]["PreOrderStatus"];
|
|
6248
|
-
stripe_payment_intent_id: string | null;
|
|
6249
7226
|
stripe_client_secret: string | null;
|
|
6250
|
-
amount: number;
|
|
6251
7227
|
estimated_fulfillment: string | null;
|
|
6252
7228
|
device_status?: components["schemas"]["DeviceFulfillmentStatus"];
|
|
6253
7229
|
created_at: string;
|
|
6254
7230
|
updated_at: string;
|
|
6255
7231
|
};
|
|
6256
7232
|
/** @enum {string} */
|
|
6257
|
-
PreOrderStatus: "draft" | "
|
|
7233
|
+
PreOrderStatus: "draft" | "provisioning" | "fulfilled" | "cancelled";
|
|
6258
7234
|
/** @enum {string|null} */
|
|
6259
7235
|
DeviceFulfillmentStatus: "awaiting_hardware" | "received" | "setup_in_progress" | "ready" | "deployed" | null;
|
|
6260
7236
|
PreOrderList: {
|
|
@@ -6298,11 +7274,71 @@ export interface components {
|
|
|
6298
7274
|
*/
|
|
6299
7275
|
device_count: number;
|
|
6300
7276
|
/**
|
|
6301
|
-
* @description Stripe price cadence.
|
|
7277
|
+
* @description Stripe price cadence. Quarterly is 2.7x monthly (10% off) and annual is 10x monthly (2 months free).
|
|
7278
|
+
* @example monthly
|
|
7279
|
+
* @enum {string}
|
|
7280
|
+
*/
|
|
7281
|
+
billing_cycle: "monthly" | "quarterly" | "annual";
|
|
7282
|
+
};
|
|
7283
|
+
MacCheckoutEnvelope: {
|
|
7284
|
+
/** @enum {boolean} */
|
|
7285
|
+
success: true;
|
|
7286
|
+
data: components["schemas"]["MacCheckoutResponse"];
|
|
7287
|
+
trace_id: string;
|
|
7288
|
+
request_id: string;
|
|
7289
|
+
};
|
|
7290
|
+
MacCheckoutResponse: {
|
|
7291
|
+
/**
|
|
7292
|
+
* Format: uri
|
|
7293
|
+
* @description Hosted Stripe Checkout URL — redirect the customer here.
|
|
7294
|
+
*/
|
|
7295
|
+
checkout_url: string;
|
|
7296
|
+
/**
|
|
7297
|
+
* Format: date-time
|
|
7298
|
+
* @description Session expiry (ISO-8601). Stripe default is 24h.
|
|
7299
|
+
*/
|
|
7300
|
+
expires_at: string;
|
|
7301
|
+
/** @description Sessions ordered — echoed back as accepted. */
|
|
7302
|
+
quantity: number;
|
|
7303
|
+
/** @description The pack divisor in force, read from the Stripe Price’s `pack_size` metadata. Quantities must be whole multiples of it, at or above it. */
|
|
7304
|
+
pack_size: number;
|
|
7305
|
+
/** @description Recurring total per period in integer cents, from the Price’s graduated tier ladder. Excludes tax, proration and coupons. */
|
|
7306
|
+
estimated_total_cents: number;
|
|
7307
|
+
};
|
|
7308
|
+
MacCheckoutBody: {
|
|
7309
|
+
/**
|
|
7310
|
+
* @description Number of hosted macOS sessions to rent. Must be a whole number of packs at or above the one-pack minimum — the pack size is read from the Stripe Price and echoed as `pack_size` in the response and in the `422` error `issues[0].min`. A quantity that is not a whole pack is refused `422 mac_quantity_not_a_pack`.
|
|
7311
|
+
* @example 5
|
|
7312
|
+
*/
|
|
7313
|
+
quantity: number;
|
|
7314
|
+
/**
|
|
7315
|
+
* @description Stripe price cadence for the session subscription.
|
|
6302
7316
|
* @example monthly
|
|
6303
7317
|
* @enum {string}
|
|
6304
7318
|
*/
|
|
6305
|
-
billing_cycle: "monthly" | "annual";
|
|
7319
|
+
billing_cycle: "monthly" | "quarterly" | "annual";
|
|
7320
|
+
};
|
|
7321
|
+
SubscriptionQuantityEnvelope: {
|
|
7322
|
+
/** @enum {boolean} */
|
|
7323
|
+
success: true;
|
|
7324
|
+
data: components["schemas"]["SubscriptionQuantityResponse"];
|
|
7325
|
+
trace_id: string;
|
|
7326
|
+
request_id: string;
|
|
7327
|
+
};
|
|
7328
|
+
SubscriptionQuantityResponse: {
|
|
7329
|
+
/** @description The Stripe subscription ID (`sub_*`). */
|
|
7330
|
+
subscription_id: string;
|
|
7331
|
+
/** @description The quantity now set on the adjustable item. */
|
|
7332
|
+
quantity: number;
|
|
7333
|
+
/** @description Recurring total per period in integer cents. `null` when the item’s Price carries no computable per-period total. Excludes tax, proration and coupons. */
|
|
7334
|
+
estimated_total_cents: number | null;
|
|
7335
|
+
};
|
|
7336
|
+
SubscriptionQuantityBody: {
|
|
7337
|
+
/**
|
|
7338
|
+
* @description New quantity for the subscription’s single adjustable item — macOS sessions, or BYOP slots. Both products are subject to the 1:1 rule (see the `422` codes), and the macOS product additionally to the pack rule.
|
|
7339
|
+
* @example 10
|
|
7340
|
+
*/
|
|
7341
|
+
quantity: number;
|
|
6306
7342
|
};
|
|
6307
7343
|
SubscriptionListEnvelope: {
|
|
6308
7344
|
/** @enum {boolean} */
|
|
@@ -6515,7 +7551,7 @@ export interface components {
|
|
|
6515
7551
|
* @description A concrete event type (e.g. `message.received`), a family wildcard (`line.*`), or the catch-all `*`.
|
|
6516
7552
|
* @enum {string}
|
|
6517
7553
|
*/
|
|
6518
|
-
WebhookEventName: "message.queued" | "message.sent" | "message.delivered" | "message.read" | "message.failed" | "message.received" | "message.scheduled" | "message.cancelled" | "message.fallback_triggered" | "reaction.added" | "reaction.received" | "reaction.removed" | "line.connected" | "line.disconnected" | "line.offline" | "line.degraded" | "line.apple_id_flagged" | "line.quota_warning" | "line.quota_exceeded" | "line.capability_changed" | "typing_indicator.started" | "typing_indicator.stopped" | "trial.linked" | "trial.dormant" | "trial.reactivated" | "trial.bind_conflict" | "trial.revoked" | "binding.released" | "pre_order.fulfilled" | "pre_order.cancelled" | "
|
|
7554
|
+
WebhookEventName: "message.queued" | "message.sent" | "message.delivered" | "message.read" | "message.failed" | "message.received" | "message.scheduled" | "message.cancelled" | "message.fallback_triggered" | "reaction.added" | "reaction.received" | "reaction.removed" | "line.connected" | "line.disconnected" | "line.offline" | "line.degraded" | "line.apple_id_flagged" | "line.quota_warning" | "line.quota_exceeded" | "line.capability_changed" | "line.terminated" | "typing_indicator.started" | "typing_indicator.stopped" | "trial.linked" | "trial.dormant" | "trial.reactivated" | "trial.bind_conflict" | "trial.revoked" | "binding.released" | "pre_order.fulfilled" | "pre_order.cancelled" | "macos_session.rented" | "macos_session.released" | "webhook.test" | "*" | "message.*" | "reaction.*" | "line.*" | "typing_indicator.*" | "trial.*" | "binding.*" | "pre_order.*" | "macos_session.*" | "webhook.*";
|
|
6519
7555
|
WebhookList: {
|
|
6520
7556
|
webhooks: components["schemas"]["Webhook"][];
|
|
6521
7557
|
};
|
|
@@ -6681,6 +7717,27 @@ export interface components {
|
|
|
6681
7717
|
region: string;
|
|
6682
7718
|
/** @example US */
|
|
6683
7719
|
country_code: string;
|
|
7720
|
+
/**
|
|
7721
|
+
* @description A ZIP code whose geography this area code serves — the postal address to use at purchase, and the address most likely to have the carrier assign this area code. `null` when no ZIP is on record for this code: choosing the address is then a judgement call for the operator, and this catalogue may not know of an overlay covering the code either, so no regional address can be assumed to yield it.
|
|
7722
|
+
* @example 10019
|
|
7723
|
+
*/
|
|
7724
|
+
purchase_zip: string | null;
|
|
7725
|
+
/**
|
|
7726
|
+
* @description Fallback ZIPs in the same geography, to retry with if the carrier rejects the primary. Empty when no ZIP is on record.
|
|
7727
|
+
* @example [
|
|
7728
|
+
* "10021",
|
|
7729
|
+
* "10023"
|
|
7730
|
+
* ]
|
|
7731
|
+
*/
|
|
7732
|
+
alt_zips: string[];
|
|
7733
|
+
/**
|
|
7734
|
+
* @description Other area codes IN THIS CATALOGUE that overlay the same geography. Non-empty means NO address can guarantee this specific code — the carrier may assign any code in the complex. An empty list is NOT the converse guarantee: it says only that no code this endpoint can offer is known to overlay this one, and an overlay outside the catalogue may still take the number.
|
|
7735
|
+
* @example [
|
|
7736
|
+
* "646",
|
|
7737
|
+
* "917"
|
|
7738
|
+
* ]
|
|
7739
|
+
*/
|
|
7740
|
+
shared_with: string[];
|
|
6684
7741
|
};
|
|
6685
7742
|
Country: {
|
|
6686
7743
|
/** @example US */
|
|
@@ -6907,6 +7964,13 @@ export interface components {
|
|
|
6907
7964
|
[key: string]: unknown;
|
|
6908
7965
|
};
|
|
6909
7966
|
};
|
|
7967
|
+
MacosSessionEnvelope: {
|
|
7968
|
+
/** @enum {boolean} */
|
|
7969
|
+
success: true;
|
|
7970
|
+
data: components["schemas"]["MacosSession"];
|
|
7971
|
+
trace_id: string;
|
|
7972
|
+
request_id: string;
|
|
7973
|
+
};
|
|
6910
7974
|
AppManifestEnvelope: {
|
|
6911
7975
|
/** @enum {boolean} */
|
|
6912
7976
|
success: true;
|
|
@@ -6926,10 +7990,16 @@ export interface components {
|
|
|
6926
7990
|
*/
|
|
6927
7991
|
url: string;
|
|
6928
7992
|
/**
|
|
6929
|
-
* @description
|
|
6930
|
-
* @example
|
|
7993
|
+
* @description Version currently published for this platform, read from the release feed that sits beside the artifact `url` resolves to — so the number announced and the file served cannot name different releases. `null` when that feed publishes nothing or could not be read; `version_status` says which. Never a configured placeholder: a fabricated version makes a failed install and an uninformed console indistinguishable to whoever is checking. Compare it against an installed version to offer an update.
|
|
7994
|
+
* @example 0.0.211
|
|
7995
|
+
*/
|
|
7996
|
+
version: string | null;
|
|
7997
|
+
/**
|
|
7998
|
+
* @description Why `version` holds what it holds. `version` is non-null if and only if this is `published`, so a null is never ambiguous (WHA-2765). `none_published` — the feed answered and publishes no version (a 404, or a feed with no readable item): a real fact about the channel, render "version not published". `unreachable` — the feed could not be read (timeout, DNS failure, a body past the size cap): OUR fault or the update host's, and nobody knows what this channel publishes, so do not tell an operator the version is missing. `misconfigured` — an artifact URL is configured for the platform and no feed URL can be derived from it; someone must fix the deployment. `not_configured` — this deployment ships no artifact for the platform, which is the same fact `available: false` carries. Before this field the last three and the first were one indistinguishable `null`, so a broken appcast URL and a healthy pre-release channel rendered identically.
|
|
7999
|
+
* @example published
|
|
8000
|
+
* @enum {string}
|
|
6931
8001
|
*/
|
|
6932
|
-
|
|
8002
|
+
version_status: "published" | "none_published" | "unreachable" | "misconfigured" | "not_configured";
|
|
6933
8003
|
/**
|
|
6934
8004
|
* @description False when this deployment has no artifact configured for the platform. The entry is still returned, so a consumer can hide the affordance instead of surfacing a link that 404s on click.
|
|
6935
8005
|
* @example true
|