xapi-to 0.1.21 → 0.1.22
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/README.md +123 -1
- package/dist/{chunk-UEQCIJ7T.js → chunk-2YRWNREY.js} +2 -2
- package/dist/index.js +475 -33
- package/dist/openai-sandbox-client.js +1 -1
- package/examples/openai-gpt-live-text.mjs +128 -0
- package/examples/provider/openapi.json +34 -0
- package/package.json +1 -1
- package/skills/xapi/SKILL.md +42 -193
- package/skills/xapi/guides/binance_web3.md +210 -0
- package/skills/xapi/guides/blockpi.md +112 -0
- package/skills/xapi/guides/domains.md +189 -0
- package/skills/xapi/guides/provider.md +30 -0
- package/skills/xapi/guides/ws_gateway.md +64 -4
- package/src/client.ts +6 -2
|
@@ -0,0 +1,210 @@
|
|
|
1
|
+
# Binance Web3 API Guide
|
|
2
|
+
|
|
3
|
+
The official `Binance Web3 API` service uses the action prefix
|
|
4
|
+
`binance-web3-api.` and currently exposes 58 Crypto actions for market data,
|
|
5
|
+
address analytics, RWA data, DEX aggregation, wallet balances, transaction
|
|
6
|
+
data/building/broadcast, and DeFi data and transaction building.
|
|
7
|
+
|
|
8
|
+
Do not confuse it with `binance-web3.` (Binance Web3 Intelligence) or
|
|
9
|
+
`binance-spot.` (Binance Spot). They are separate services with different
|
|
10
|
+
actions, schemas, and upstream behavior.
|
|
11
|
+
|
|
12
|
+
## Discovery and shared limit
|
|
13
|
+
|
|
14
|
+
Discover the service ID instead of persisting a database UUID in automation:
|
|
15
|
+
|
|
16
|
+
```bash
|
|
17
|
+
npx xapi-to services --category Crypto --page-size 100
|
|
18
|
+
npx xapi-to list --source api \
|
|
19
|
+
--service-id <binance-web3-api-service-id> --page-size 100
|
|
20
|
+
npx xapi-to get binance-web3-api.api_v1_dex_market_token_search
|
|
21
|
+
```
|
|
22
|
+
|
|
23
|
+
The live catalog currently declares a service-level limit of **10 requests per
|
|
24
|
+
second per user**, shared across every API key and all 58 endpoints. Pace the
|
|
25
|
+
combined workload, not each action independently. The current fixed listed
|
|
26
|
+
price is `$0/call`; re-check `get` because limits and pricing can change.
|
|
27
|
+
|
|
28
|
+
GET actions take `{"method":"GET","params":{...}}` (plus `pathParams` when
|
|
29
|
+
the schema requires them). Chain identifiers are Binance IDs such as `"1"`
|
|
30
|
+
for Ethereum, `"56"` for BSC, and `"CT_501"` for Solana. They are not the
|
|
31
|
+
BlockPI network names or the built-in `crypto.*` chain enum.
|
|
32
|
+
|
|
33
|
+
## Safe read examples
|
|
34
|
+
|
|
35
|
+
Discover the current chain list before relying on remembered IDs:
|
|
36
|
+
|
|
37
|
+
```bash
|
|
38
|
+
npx xapi-to call binance-web3-api.api_v1_dex_market_supported_chain \
|
|
39
|
+
--input '{"method":"GET"}'
|
|
40
|
+
```
|
|
41
|
+
|
|
42
|
+
Search by symbol/address, then use the returned contract and chain ID:
|
|
43
|
+
|
|
44
|
+
```bash
|
|
45
|
+
npx xapi-to call binance-web3-api.api_v1_dex_market_token_search --input '{
|
|
46
|
+
"method":"GET","params":{"chains":"1,56,CT_501","search":"USDT"}
|
|
47
|
+
}'
|
|
48
|
+
|
|
49
|
+
npx xapi-to call binance-web3-api.api_v1_dex_market_candles --input '{
|
|
50
|
+
"method":"GET","params":{
|
|
51
|
+
"binanceChainId":"1",
|
|
52
|
+
"tokenContractAddress":"0xdac17f958d2ee523a2206206994597c13d831ec7",
|
|
53
|
+
"bar":"1h","limit":100
|
|
54
|
+
}
|
|
55
|
+
}'
|
|
56
|
+
```
|
|
57
|
+
|
|
58
|
+
`candles.limit` is currently 1–300. `before` and `after` are exclusive Unix
|
|
59
|
+
millisecond bounds. Read each endpoint's enum independently; for example,
|
|
60
|
+
portfolio `timeFrame` values differ from leaderboard values.
|
|
61
|
+
|
|
62
|
+
RWA search supports ticker, company name, or contract address:
|
|
63
|
+
|
|
64
|
+
```bash
|
|
65
|
+
npx xapi-to call binance-web3-api.api_v1_dex_market_rwa_search --input '{
|
|
66
|
+
"method":"GET","params":{"keyword":"NVDA","platformId":"ondo"}
|
|
67
|
+
}'
|
|
68
|
+
```
|
|
69
|
+
|
|
70
|
+
`platformId` currently accepts `ondo` or `bstock` and is optional.
|
|
71
|
+
|
|
72
|
+
## Quote and transaction boundary
|
|
73
|
+
|
|
74
|
+
Aggregator quote amounts are positive integer strings in the sell token's
|
|
75
|
+
smallest unit. A quote is not a swap and does not authorize signing:
|
|
76
|
+
|
|
77
|
+
```bash
|
|
78
|
+
npx xapi-to call binance-web3-api.api_v1_dex_aggregator_quote --input '{
|
|
79
|
+
"method":"GET","params":{
|
|
80
|
+
"amount":"1000000","binanceChainId":"56",
|
|
81
|
+
"fromTokenAddress":"0x55d398326f99059fF775485246999027B3197955",
|
|
82
|
+
"toTokenAddress":"0x8AC76a51cc950d9822D68b83fE1Ad97B32Cd580d"
|
|
83
|
+
}
|
|
84
|
+
}'
|
|
85
|
+
```
|
|
86
|
+
|
|
87
|
+
The normal flow is `quote` → choose a returned route/`quoteId` (about 30-second
|
|
88
|
+
TTL) → `swap` to build transaction data. `quote-and-swap` combines the first
|
|
89
|
+
two steps when a vendor is selected. EVM approvals and swaps, Solana compiled
|
|
90
|
+
transactions/instructions, RFQ typed data, and DeFi transaction endpoints
|
|
91
|
+
return data for the caller to inspect, sign, and submit. They do not authorize
|
|
92
|
+
xAPI or an agent to sign on the user's behalf.
|
|
93
|
+
|
|
94
|
+
Before any sign or broadcast step, obtain explicit approval for the selected
|
|
95
|
+
chain, wallet, token addresses, exact amounts, route/vendor, slippage, fees,
|
|
96
|
+
approval allowance, recipient, gas policy, and expected transaction effects.
|
|
97
|
+
Never pass a private key or seed phrase to xAPI.
|
|
98
|
+
|
|
99
|
+
## Current POST schema gap
|
|
100
|
+
|
|
101
|
+
At the time this guide was verified, the serving XAPI action catalog omitted
|
|
102
|
+
the `body` from all 18 body-bearing POST operations even though the provider's
|
|
103
|
+
current import payload contained those schemas. The nineteenth POST operation,
|
|
104
|
+
`token_basic-info`, is intentionally query-only and exposes required `params`
|
|
105
|
+
(`binanceChainId` and `tokenContractAddress`). This mismatch is serving-contract
|
|
106
|
+
drift, not evidence that the official operations take no input.
|
|
107
|
+
|
|
108
|
+
Do not copy a Binance-native request body or invent a `body`. For an action that
|
|
109
|
+
needs request content, wait until `npx xapi-to get <action-id>` exposes it and
|
|
110
|
+
report the service-schema gap instead. The query-only token basic-info action
|
|
111
|
+
may be called exactly as its live `params` schema declares. Once fixed, the
|
|
112
|
+
live xAPI schema—not this snapshot—is authoritative.
|
|
113
|
+
|
|
114
|
+
## Provider errors
|
|
115
|
+
|
|
116
|
+
Binance may return a successful HTTP response with a nonzero business code.
|
|
117
|
+
Treat `code: 0` as success and preserve the upstream code/message on failure.
|
|
118
|
+
In particular:
|
|
119
|
+
|
|
120
|
+
- `40304` means a regional compliance restriction; changing parameters or
|
|
121
|
+
retrying cannot bypass it.
|
|
122
|
+
- `40104` means the configured upstream API key lacks permission for that
|
|
123
|
+
product; DeFi access requires explicit enablement.
|
|
124
|
+
|
|
125
|
+
Do not automatically retry either error or misreport it as an xAPI-key failure.
|
|
126
|
+
|
|
127
|
+
## Current action catalog (58)
|
|
128
|
+
|
|
129
|
+
### General Data (13)
|
|
130
|
+
|
|
131
|
+
- `binance-web3-api.api_v1_dex_market_candles`
|
|
132
|
+
- `binance-web3-api.api_v1_dex_market_memepump_tokenDevInfo`
|
|
133
|
+
- `binance-web3-api.api_v1_dex_market_price`
|
|
134
|
+
- `binance-web3-api.api_v1_dex_market_price-info`
|
|
135
|
+
- `binance-web3-api.api_v1_dex_market_supported_chain`
|
|
136
|
+
- `binance-web3-api.api_v1_dex_market_token_advanced-info`
|
|
137
|
+
- `binance-web3-api.api_v1_dex_market_token_basic-info`
|
|
138
|
+
- `binance-web3-api.api_v1_dex_market_token_holder`
|
|
139
|
+
- `binance-web3-api.api_v1_dex_market_token_hot-token`
|
|
140
|
+
- `binance-web3-api.api_v1_dex_market_token_search`
|
|
141
|
+
- `binance-web3-api.api_v1_dex_market_token_top-liquidity`
|
|
142
|
+
- `binance-web3-api.api_v1_dex_market_token_top-trader`
|
|
143
|
+
- `binance-web3-api.api_v1_dex_market_trades`
|
|
144
|
+
|
|
145
|
+
### Address Portfolio (7)
|
|
146
|
+
|
|
147
|
+
- `binance-web3-api.api_v1_dex_market_address-tracker_trades`
|
|
148
|
+
- `binance-web3-api.api_v1_dex_market_leaderboard_list`
|
|
149
|
+
- `binance-web3-api.api_v1_dex_market_portfolio_dex-history`
|
|
150
|
+
- `binance-web3-api.api_v1_dex_market_portfolio_overview`
|
|
151
|
+
- `binance-web3-api.api_v1_dex_market_portfolio_recent-pnl`
|
|
152
|
+
- `binance-web3-api.api_v1_dex_market_portfolio_supported_chain`
|
|
153
|
+
- `binance-web3-api.api_v1_dex_market_portfolio_token_latest-pnl`
|
|
154
|
+
|
|
155
|
+
### RWA Data (6)
|
|
156
|
+
|
|
157
|
+
- `binance-web3-api.api_v1_dex_market_rwa_platforms`
|
|
158
|
+
- `binance-web3-api.api_v1_dex_market_rwa_price`
|
|
159
|
+
- `binance-web3-api.api_v1_dex_market_rwa_search`
|
|
160
|
+
- `binance-web3-api.api_v1_dex_market_rwa_tokens`
|
|
161
|
+
- `binance-web3-api.api_v1_dex_market_rwa_underlying-market`
|
|
162
|
+
- `binance-web3-api.api_v1_dex_market_rwa_underlying-profile`
|
|
163
|
+
|
|
164
|
+
### Trading API (9)
|
|
165
|
+
|
|
166
|
+
- `binance-web3-api.api_v1_dex_aggregator_approve-transaction`
|
|
167
|
+
- `binance-web3-api.api_v1_dex_aggregator_history`
|
|
168
|
+
- `binance-web3-api.api_v1_dex_aggregator_order_{orderId}`
|
|
169
|
+
- `binance-web3-api.api_v1_dex_aggregator_quote`
|
|
170
|
+
- `binance-web3-api.api_v1_dex_aggregator_quote-and-swap`
|
|
171
|
+
- `binance-web3-api.api_v1_dex_aggregator_supported_chain`
|
|
172
|
+
- `binance-web3-api.api_v1_dex_aggregator_swap`
|
|
173
|
+
- `binance-web3-api.api_v1_dex_aggregator_swap-instruction`
|
|
174
|
+
- `binance-web3-api.api_v1_dex_aggregator_order_submit`
|
|
175
|
+
|
|
176
|
+
### Transaction API (7)
|
|
177
|
+
|
|
178
|
+
- `binance-web3-api.api_v1_dex_post-transaction_orders`
|
|
179
|
+
- `binance-web3-api.api_v1_dex_pre-transaction_block-height`
|
|
180
|
+
- `binance-web3-api.api_v1_dex_pre-transaction_broadcast-transaction`
|
|
181
|
+
- `binance-web3-api.api_v1_dex_pre-transaction_gas-limit`
|
|
182
|
+
- `binance-web3-api.api_v1_dex_pre-transaction_gas-price`
|
|
183
|
+
- `binance-web3-api.api_v1_dex_pre-transaction_simulate`
|
|
184
|
+
- `binance-web3-api.api_v1_dex_pre-transaction_supported_chain`
|
|
185
|
+
|
|
186
|
+
### Wallet API (5)
|
|
187
|
+
|
|
188
|
+
- `binance-web3-api.api_v1_dex_balance_all-token-balances-by-address`
|
|
189
|
+
- `binance-web3-api.api_v1_dex_balance_supported_chain`
|
|
190
|
+
- `binance-web3-api.api_v1_dex_balance_token-balances-by-address`
|
|
191
|
+
- `binance-web3-api.api_v1_dex_post-transaction_transaction-detail-by-txhash`
|
|
192
|
+
- `binance-web3-api.api_v1_dex_post-transaction_transactions-by-address`
|
|
193
|
+
|
|
194
|
+
### DeFi Data and Transaction (11)
|
|
195
|
+
|
|
196
|
+
- `binance-web3-api.api_v1_defi_data_investment_detail`
|
|
197
|
+
- `binance-web3-api.api_v1_defi_data_investment_list`
|
|
198
|
+
- `binance-web3-api.api_v1_defi_data_position_list`
|
|
199
|
+
- `binance-web3-api.api_v1_defi_data_protocol_detail`
|
|
200
|
+
- `binance-web3-api.api_v1_defi_data_protocol_list`
|
|
201
|
+
- `binance-web3-api.api_v1_defi_transaction_claim`
|
|
202
|
+
- `binance-web3-api.api_v1_defi_transaction_deposit`
|
|
203
|
+
- `binance-web3-api.api_v1_defi_transaction_lp-add`
|
|
204
|
+
- `binance-web3-api.api_v1_defi_transaction_lp-add_calculate`
|
|
205
|
+
- `binance-web3-api.api_v1_defi_transaction_lp-remove`
|
|
206
|
+
- `binance-web3-api.api_v1_defi_transaction_redeem`
|
|
207
|
+
|
|
208
|
+
Use `list --service-id` to detect additions/removals and `get` immediately
|
|
209
|
+
before each call. Do not infer that similarly named endpoints share parameters,
|
|
210
|
+
enum values, pagination, or response shapes.
|
|
@@ -0,0 +1,112 @@
|
|
|
1
|
+
# BlockPI RPC Guide
|
|
2
|
+
|
|
3
|
+
The `rpc` third-party service exposes EVM JSON-RPC through BlockPI. The current
|
|
4
|
+
catalog has one generic action and 12 legacy convenience actions over 60
|
|
5
|
+
explicitly registered mainnets and testnets. The server supplies the BlockPI
|
|
6
|
+
partner credential; callers send only their xAPI key to xAPI and must never ask for, expose, or forward the upstream credential.
|
|
7
|
+
|
|
8
|
+
Always inspect the live schema and price before calling:
|
|
9
|
+
|
|
10
|
+
```bash
|
|
11
|
+
npx xapi-to get rpc.network
|
|
12
|
+
npx xapi-to search "BlockPI RPC" --source api --page-size 100
|
|
13
|
+
```
|
|
14
|
+
|
|
15
|
+
The catalog currently lists each action at `$0.000003/call`; treat `get` as the
|
|
16
|
+
authority because pricing and supported networks may change.
|
|
17
|
+
|
|
18
|
+
## Generic JSON-RPC
|
|
19
|
+
|
|
20
|
+
Prefer `rpc.network` for arbitrary EVM methods. It accepts exactly one JSON-RPC
|
|
21
|
+
request object, not a batch. Keep the HTTP method and JSON-RPC method separate:
|
|
22
|
+
|
|
23
|
+
```bash
|
|
24
|
+
npx xapi-to call rpc.network --input '{
|
|
25
|
+
"method":"POST",
|
|
26
|
+
"pathParams":{"network":"ethereum"},
|
|
27
|
+
"body":{"jsonrpc":"2.0","id":1,"method":"eth_blockNumber","params":[]}
|
|
28
|
+
}'
|
|
29
|
+
```
|
|
30
|
+
|
|
31
|
+
The required outer fields are `method`, `pathParams`, and `body`.
|
|
32
|
+
`pathParams.network` selects the registered BlockPI network. The body requires
|
|
33
|
+
`jsonrpc: "2.0"` and the JSON-RPC `method`; `id` and `params` are optional.
|
|
34
|
+
|
|
35
|
+
The generic route fails closed with HTTP 503 when the server-side partner key
|
|
36
|
+
is unavailable; it never silently sends a raw RPC call without that credential.
|
|
37
|
+
The legacy convenience routes have a different availability contract and may
|
|
38
|
+
fall back to their configured public RPC endpoints. Diagnose the two route
|
|
39
|
+
families separately instead of treating every BlockPI 503 as a bad request.
|
|
40
|
+
|
|
41
|
+
For example, read an address balance without exposing any provider key:
|
|
42
|
+
|
|
43
|
+
```bash
|
|
44
|
+
npx xapi-to call rpc.network --input '{
|
|
45
|
+
"method":"POST",
|
|
46
|
+
"pathParams":{"network":"base"},
|
|
47
|
+
"body":{"jsonrpc":"2.0","id":"balance-1","method":"eth_getBalance",
|
|
48
|
+
"params":["0x0000000000000000000000000000000000000000","latest"]}
|
|
49
|
+
}'
|
|
50
|
+
```
|
|
51
|
+
|
|
52
|
+
## Registered networks
|
|
53
|
+
|
|
54
|
+
The current `rpc.network` enum contains 60 values:
|
|
55
|
+
|
|
56
|
+
```text
|
|
57
|
+
abstract, arbitrum, arbitrum-nova, arbitrum-sepolia, arc-testnet,
|
|
58
|
+
avalanche, avalanche-fuji, base, base-sepolia, berachain, blast, bsc,
|
|
59
|
+
bsc-testnet, celo, celo-sepolia, conflux-espace, cronos, ethereum,
|
|
60
|
+
ethereum-hoodi, ethereum-sepolia, etherlink, fantom, gnosis, hemi,
|
|
61
|
+
hyperliquid, ink, kaia, kaia-kairos, linea, linea-sepolia, mantle, merlin,
|
|
62
|
+
merlin-testnet, meter, metis, monad, monad-testnet, optimism,
|
|
63
|
+
optimism-sepolia, plasma, plume, polygon, polygon-amoy, robinhood, scroll,
|
|
64
|
+
scroll-sepolia, sei-evm, sei-testnet-evm, sonic, stable, story, taiko,
|
|
65
|
+
unichain, unichain-sepolia, viction, xlayer, zetachain-athens-evm,
|
|
66
|
+
zetachain-evm, zksync-era, zksync-era-sepolia
|
|
67
|
+
```
|
|
68
|
+
|
|
69
|
+
Do not normalize or invent aliases. Re-run `get rpc.network` and use its exact
|
|
70
|
+
enum when a network is absent or when the task depends on current support.
|
|
71
|
+
|
|
72
|
+
## Legacy convenience actions
|
|
73
|
+
|
|
74
|
+
These actions translate simple REST-shaped inputs to common EVM methods:
|
|
75
|
+
|
|
76
|
+
- `rpc.network` — arbitrary single JSON-RPC request
|
|
77
|
+
- `rpc.chain_blockNumber` — latest block number
|
|
78
|
+
- `rpc.chain_call` — `eth_call`
|
|
79
|
+
- `rpc.chain_chainId` — chain ID
|
|
80
|
+
- `rpc.chain_gasPrice` — gas price
|
|
81
|
+
- `rpc.chain_getBalance` — native balance
|
|
82
|
+
- `rpc.chain_getBlockByHash` — block by hash
|
|
83
|
+
- `rpc.chain_getBlockByNumber` — block by number/tag
|
|
84
|
+
- `rpc.chain_getCode` — contract bytecode
|
|
85
|
+
- `rpc.chain_getLogs` — event logs
|
|
86
|
+
- `rpc.chain_getTransactionByHash` — transaction by hash
|
|
87
|
+
- `rpc.chain_getTransactionCount` — address nonce
|
|
88
|
+
- `rpc.chain_getTransactionReceipt` — transaction receipt
|
|
89
|
+
|
|
90
|
+
Legacy actions use `pathParams.chain` plus action-specific query `params`.
|
|
91
|
+
Never infer those parameters from the raw JSON-RPC signature; inspect the exact
|
|
92
|
+
action first:
|
|
93
|
+
|
|
94
|
+
```bash
|
|
95
|
+
npx xapi-to get rpc.chain_getBalance
|
|
96
|
+
npx xapi-to call rpc.chain_getBalance --input '{
|
|
97
|
+
"method":"POST",
|
|
98
|
+
"pathParams":{"chain":"ethereum"},
|
|
99
|
+
"params":{"address":"0x0000000000000000000000000000000000000000",
|
|
100
|
+
"block":"latest"}
|
|
101
|
+
}'
|
|
102
|
+
```
|
|
103
|
+
|
|
104
|
+
## Transaction safety
|
|
105
|
+
|
|
106
|
+
Reads such as block, balance, code, logs, and receipt queries are non-mutating.
|
|
107
|
+
Methods such as `eth_sendRawTransaction` can create irreversible on-chain
|
|
108
|
+
effects even though they use the same generic action. Before submitting a
|
|
109
|
+
signed transaction, obtain explicit approval for the chain, sender, recipient,
|
|
110
|
+
value, calldata, gas policy, and transaction hash workflow. Do not send private
|
|
111
|
+
keys or seed phrases through xAPI, and do not automatically retry an ambiguous
|
|
112
|
+
broadcast. Check the transaction hash or sender nonce first.
|
|
@@ -0,0 +1,189 @@
|
|
|
1
|
+
# Domains and DNS Guide
|
|
2
|
+
|
|
3
|
+
Use the built-in `domain.*` and `dns.*` capabilities to search, price, register,
|
|
4
|
+
list, and inspect domains, then manage their DNS records. These are capability
|
|
5
|
+
actions, not third-party API actions, so discover them with
|
|
6
|
+
`--source capability` and pass a flat JSON object to `--input`.
|
|
7
|
+
|
|
8
|
+
Domain registration is a real, non-refundable purchase. DNS changes alter live
|
|
9
|
+
traffic. Read the current schema, show the user the exact target and price or
|
|
10
|
+
record change, and obtain explicit approval before either mutation.
|
|
11
|
+
|
|
12
|
+
## Current actions
|
|
13
|
+
|
|
14
|
+
| Action | Purpose | Mutation |
|
|
15
|
+
|---|---|---|
|
|
16
|
+
| `domain.search` | Registrar suggestions and one-year estimated prices | No |
|
|
17
|
+
| `domain.check` | Check exact-domain availability | No |
|
|
18
|
+
| `domain.price` | Read the current USD registration price | No |
|
|
19
|
+
| `domain.register` | Register a domain | **Purchase** |
|
|
20
|
+
| `domain.registration.get` | Read an asynchronous registration task | No |
|
|
21
|
+
| `domain.list` | List domains owned through xAPI | No |
|
|
22
|
+
| `domain.get` | Inspect one domain by `domain_id` | No |
|
|
23
|
+
| `dns.list` | List a domain's DNS records | No |
|
|
24
|
+
| `dns.upsert` | Create or update a DNS record | **Write** |
|
|
25
|
+
| `dns.delete` | Delete a DNS record | **Write** |
|
|
26
|
+
| `dns.dnssec.get` | Read desired, effective, and provider DNSSEC state | No |
|
|
27
|
+
| `dns.dnssec.set` | Enable or disable Cloudflare DNSSEC | **Write** |
|
|
28
|
+
|
|
29
|
+
Fetch the live schemas before use:
|
|
30
|
+
|
|
31
|
+
```bash
|
|
32
|
+
npx xapi-to get-batch domain.search domain.check domain.price domain.register \
|
|
33
|
+
domain.registration.get domain.list domain.get dns.list dns.upsert dns.delete \
|
|
34
|
+
dns.dnssec.get dns.dnssec.set
|
|
35
|
+
```
|
|
36
|
+
|
|
37
|
+
## Search, check, and price
|
|
38
|
+
|
|
39
|
+
`domain.search` accepts a keyword and up to 20 optional TLDs. Its availability
|
|
40
|
+
and one-year prices are suggestions, not a purchase quote. Search first, then
|
|
41
|
+
check and price the exact fully qualified domain:
|
|
42
|
+
|
|
43
|
+
```bash
|
|
44
|
+
npx xapi-to call domain.search \
|
|
45
|
+
--input '{"keyword":"example","tlds":["com","dev","ai"]}'
|
|
46
|
+
|
|
47
|
+
npx xapi-to call domain.check --input '{"domain":"example.com"}'
|
|
48
|
+
npx xapi-to call domain.price --input '{"domain":"example.com","period":1}'
|
|
49
|
+
```
|
|
50
|
+
|
|
51
|
+
`domain.price` is the authoritative pre-registration price at call time. The
|
|
52
|
+
current USD billable price includes xAPI's fixed fee; non-USD registrar quotes
|
|
53
|
+
are unsupported. Re-price immediately before registration because availability
|
|
54
|
+
and upstream prices can change.
|
|
55
|
+
|
|
56
|
+
## Register a domain
|
|
57
|
+
|
|
58
|
+
Before calling `domain.register`:
|
|
59
|
+
|
|
60
|
+
1. Re-run `domain.check` and `domain.price` for the exact domain and period.
|
|
61
|
+
2. Show the exact domain, period, current USD price, and `max_price_usd` ceiling.
|
|
62
|
+
3. Confirm the registrant contact details and obtain explicit purchase approval.
|
|
63
|
+
4. Create one idempotency key for that exact request and reuse it only for retries.
|
|
64
|
+
|
|
65
|
+
The required contact fields are `first_name`, `last_name`, `address1`, `city`,
|
|
66
|
+
`state`, `postal_code`, `country`, `phone`, and `email`. `country` is a two-letter
|
|
67
|
+
ISO code. Phone numbers must use `+{country_code}.{number}`, for example
|
|
68
|
+
`+86.13800138000`. Do not log contact data or include it in task summaries.
|
|
69
|
+
|
|
70
|
+
```bash
|
|
71
|
+
npx xapi-to call domain.register --input '{
|
|
72
|
+
"domain":"example.com",
|
|
73
|
+
"period":1,
|
|
74
|
+
"max_price_usd":20,
|
|
75
|
+
"idempotency_key":"register-example-com-20260910",
|
|
76
|
+
"auto_renew":false,
|
|
77
|
+
"whois_privacy":true,
|
|
78
|
+
"contact":{
|
|
79
|
+
"first_name":"Given","last_name":"Family",
|
|
80
|
+
"address1":"Street address","city":"City","state":"Region",
|
|
81
|
+
"postal_code":"000000","country":"CN",
|
|
82
|
+
"phone":"+86.13800138000","email":"owner@example.com"
|
|
83
|
+
}
|
|
84
|
+
}'
|
|
85
|
+
```
|
|
86
|
+
|
|
87
|
+
`max_price_usd` is a hard final-charge ceiling, not the expected price.
|
|
88
|
+
`auto_renew` must currently remain `false`; renewal billing is not available.
|
|
89
|
+
Registration is non-refundable. A successful submission can return a `task_id`
|
|
90
|
+
before the registrar has finished. Poll that exact task rather than repeating the
|
|
91
|
+
purchase:
|
|
92
|
+
|
|
93
|
+
```bash
|
|
94
|
+
npx xapi-to call domain.registration.get \
|
|
95
|
+
--input '{"task_id":"<task-id-from-domain-register>"}'
|
|
96
|
+
```
|
|
97
|
+
|
|
98
|
+
Continue polling only while `status` is `pending` or `processing`. Treat
|
|
99
|
+
`succeeded`, `failed`, and `expired` as terminal. Preserve `phase`, `action`,
|
|
100
|
+
`error`, `final_cost`, and `confirmation_sent_to` when reporting the result;
|
|
101
|
+
some registrations can require external confirmation or manual review.
|
|
102
|
+
|
|
103
|
+
Do not retry with a new idempotency key after an ambiguous response. If a
|
|
104
|
+
`task_id` was returned, read it with `domain.registration.get`. Otherwise reuse
|
|
105
|
+
the original key only for the exact same request, then inspect `domain.list`
|
|
106
|
+
before deciding whether another purchase attempt is safe.
|
|
107
|
+
|
|
108
|
+
`domain.get` intentionally does not return the registrant contact. Treat that
|
|
109
|
+
privacy boundary as expected rather than assuming registration lost the data.
|
|
110
|
+
|
|
111
|
+
## DNS workflow
|
|
112
|
+
|
|
113
|
+
DNS actions use the xAPI `domain_id`, not the domain name. Resolve it with
|
|
114
|
+
`domain.list`, inspect the current records, and retain the stable `record_id`:
|
|
115
|
+
|
|
116
|
+
```bash
|
|
117
|
+
npx xapi-to call domain.list --input '{"limit":50,"offset":0}'
|
|
118
|
+
npx xapi-to call dns.list --input '{"domain_id":"<domain-id>"}'
|
|
119
|
+
```
|
|
120
|
+
|
|
121
|
+
Create a record by omitting both record identifiers:
|
|
122
|
+
|
|
123
|
+
```bash
|
|
124
|
+
npx xapi-to call dns.upsert --input '{
|
|
125
|
+
"domain_id":"<domain-id>",
|
|
126
|
+
"subdomain":"@","type":"A","value":"203.0.113.10",
|
|
127
|
+
"idempotency_key":"dns-create-root-a-20260910"
|
|
128
|
+
}'
|
|
129
|
+
```
|
|
130
|
+
|
|
131
|
+
Update an existing record with its stable `record_id`. `record_index` is a
|
|
132
|
+
legacy fallback whose meaning can change when the record set changes; use it
|
|
133
|
+
only when a live response lacks `record_id`.
|
|
134
|
+
|
|
135
|
+
```bash
|
|
136
|
+
npx xapi-to call dns.upsert --input '{
|
|
137
|
+
"domain_id":"<domain-id>","record_id":"<record-id>",
|
|
138
|
+
"subdomain":"www","type":"CNAME","value":"example.com.",
|
|
139
|
+
"idempotency_key":"dns-update-www-20260910"
|
|
140
|
+
}'
|
|
141
|
+
|
|
142
|
+
npx xapi-to call dns.delete --input '{
|
|
143
|
+
"domain_id":"<domain-id>","record_id":"<record-id>",
|
|
144
|
+
"idempotency_key":"dns-delete-record-20260910"
|
|
145
|
+
}'
|
|
146
|
+
```
|
|
147
|
+
|
|
148
|
+
For every write, confirm the domain, record type/name/value, and stable record
|
|
149
|
+
identifier. Reuse an idempotency key only for an identical retry; use a new key
|
|
150
|
+
when any requested value changes. After a successful write, call `dns.list`
|
|
151
|
+
again and verify the intended state instead of assuming propagation or success.
|
|
152
|
+
|
|
153
|
+
## DNSSEC lifecycle
|
|
154
|
+
|
|
155
|
+
DNSSEC is currently available only for domains whose authoritative provider is
|
|
156
|
+
Cloudflare. Read the current state before changing it:
|
|
157
|
+
|
|
158
|
+
```bash
|
|
159
|
+
npx xapi-to call dns.dnssec.get \
|
|
160
|
+
--input '{"domain_id":"<domain-id>"}'
|
|
161
|
+
```
|
|
162
|
+
|
|
163
|
+
After explicit approval, request the desired state with one stable idempotency
|
|
164
|
+
key. Reuse that key only when retrying this exact domain and `enabled` value:
|
|
165
|
+
|
|
166
|
+
```bash
|
|
167
|
+
npx xapi-to call dns.dnssec.set --input '{
|
|
168
|
+
"domain_id":"<domain-id>",
|
|
169
|
+
"enabled":true,
|
|
170
|
+
"idempotency_key":"dnssec-enable-example-20260917"
|
|
171
|
+
}'
|
|
172
|
+
```
|
|
173
|
+
|
|
174
|
+
The mutation can finish its request while Cloudflare or the parent registry is
|
|
175
|
+
still reconciling. Interpret the response fields together:
|
|
176
|
+
|
|
177
|
+
- `desired_enabled` is the requested target.
|
|
178
|
+
- `effective_enabled` is the state currently protecting DNS responses.
|
|
179
|
+
- `transition` is `enabling`, `disabling`, or `null` when settled.
|
|
180
|
+
- `provider_status` preserves the upstream lifecycle state.
|
|
181
|
+
- `action_required` means operator intervention is needed.
|
|
182
|
+
|
|
183
|
+
`pending` and `pending-disabled` are transitions, not success. Poll
|
|
184
|
+
`dns.dnssec.get` until the state settles, becomes `error`, or the user's
|
|
185
|
+
deadline is reached. Do not report DNSSEC as enabled until
|
|
186
|
+
`effective_enabled=true` with no transition, and do not report it as disabled
|
|
187
|
+
until `effective_enabled=false` with no transition. Preserve DS metadata when
|
|
188
|
+
the caller needs to inspect delegation, but never invent or manually publish a
|
|
189
|
+
DS record unless the live response explicitly says operator action is required.
|
|
@@ -55,6 +55,36 @@ Use `--clear-about` or `--clear-website` to clear a value. Provider metadata
|
|
|
55
55
|
updates cannot modify the version contract or upstream credentials; use the
|
|
56
56
|
version command for those fields.
|
|
57
57
|
|
|
58
|
+
## Configure a service request limit
|
|
59
|
+
|
|
60
|
+
Rate limits are optional service settings. Configure both values together when
|
|
61
|
+
creating a service or updating an existing one:
|
|
62
|
+
|
|
63
|
+
```bash
|
|
64
|
+
npx xapi-to provider create --file ./service.json \
|
|
65
|
+
--rate-limit-requests 100 \
|
|
66
|
+
--rate-limit-period-seconds 60
|
|
67
|
+
|
|
68
|
+
npx xapi-to provider update <service-id> \
|
|
69
|
+
--rate-limit-requests 100 \
|
|
70
|
+
--rate-limit-period-seconds 60
|
|
71
|
+
```
|
|
72
|
+
|
|
73
|
+
`requests` accepts 1 through 1,000,000 and `periodSeconds` accepts 1 through
|
|
74
|
+
86,400. The backend applies one quota to each User x Service pair, so all API keys
|
|
75
|
+
owned by the same user share that service quota. This setting is supported only
|
|
76
|
+
for `PROXY` services; the backend rejects a non-null limit for `DIRECT` services.
|
|
77
|
+
|
|
78
|
+
Disable the limit explicitly with:
|
|
79
|
+
|
|
80
|
+
```bash
|
|
81
|
+
npx xapi-to provider update <service-id> --clear-rate-limit
|
|
82
|
+
```
|
|
83
|
+
|
|
84
|
+
This sends `rateLimitConfig: null`. Omitting the rate-limit flags during an
|
|
85
|
+
update leaves the existing setting unchanged. A raw `rateLimitConfig` can also
|
|
86
|
+
be included in `service.json`; explicit CLI rate-limit flags override that field.
|
|
87
|
+
|
|
58
88
|
## Edit and publish a revision
|
|
59
89
|
|
|
60
90
|
```bash
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
# WebSocket Gateway Guide
|
|
2
2
|
|
|
3
|
-
Use xAPI's WebSocket Gateway for full-duplex, low-latency sessions such as OpenAI Realtime, streaming speech recognition, bidirectional text-to-speech, simultaneous interpretation, and podcast generation.
|
|
3
|
+
Use xAPI's WebSocket Gateway for full-duplex, low-latency sessions such as GPT Live, OpenAI Realtime, streaming speech recognition, bidirectional text-to-speech, simultaneous interpretation, and podcast generation.
|
|
4
4
|
|
|
5
5
|
The WebSocket Gateway shares the public `ai.xapi.to` host with the HTTP AI Gateway, but it is a separate protocol surface. An HTTP request continues to use the AI Gateway; a valid WebSocket Upgrade request is routed to the WebSocket Gateway.
|
|
6
6
|
|
|
@@ -9,6 +9,7 @@ The WebSocket Gateway shares the public `ai.xapi.to` host with the HTTP AI Gatew
|
|
|
9
9
|
- [Choose the right interface](#choose-the-right-interface)
|
|
10
10
|
- [Public URLs and routing](#public-urls-and-routing)
|
|
11
11
|
- [Authentication](#authentication)
|
|
12
|
+
- [GPT Live example](#gpt-live-example)
|
|
12
13
|
- [OpenAI Realtime example](#openai-realtime-example)
|
|
13
14
|
- [Browser connections](#browser-connections)
|
|
14
15
|
- [Native protocol endpoints](#native-protocol-endpoints)
|
|
@@ -39,6 +40,7 @@ Current curated production paths include:
|
|
|
39
40
|
|
|
40
41
|
| Path | Protocol | Typical use |
|
|
41
42
|
|---|---|---|
|
|
43
|
+
| `/v1/live/sessions` on the GPT Live service host | OpenAI Live Sessions JSON events | GPT-Live 1 voice with Client or managed Responses delegation |
|
|
42
44
|
| `/v1/realtime` | OpenAI Realtime GA JSON events | Realtime text and voice |
|
|
43
45
|
| `/v1/asr` | Volcengine ASR binary frames | Streaming speech recognition |
|
|
44
46
|
| `/v1/tts` | Doubao bidirectional TTS binary frames | Streaming text-to-speech |
|
|
@@ -57,6 +59,15 @@ wss://<service-slug>.p.xapi.to/<endpoint-path>
|
|
|
57
59
|
|
|
58
60
|
This avoids shared-path ambiguity and is required when the desired service uses a provider-native protocol that is not selected by the unified path. Console Try-It and review workflows can also address an endpoint exactly with `?endpoint=<endpoint-id>`.
|
|
59
61
|
|
|
62
|
+
GPT Live currently uses the service-specific URL:
|
|
63
|
+
|
|
64
|
+
```text
|
|
65
|
+
wss://openai-live.p.xapi.to/v1/live/sessions
|
|
66
|
+
```
|
|
67
|
+
|
|
68
|
+
Do not replace it with `/v1/realtime`. Live Sessions uses `session.start` and
|
|
69
|
+
`session.started`; Realtime uses a different session lifecycle and event model.
|
|
70
|
+
|
|
60
71
|
## Authentication
|
|
61
72
|
|
|
62
73
|
Use the same xAPI key as the CLI and HTTP Gateway. Server-side clients should send one of these handshake headers:
|
|
@@ -78,6 +89,43 @@ The Gateway also accepts `?token=<XAPI_KEY>` or `?xapi-key=<XAPI_KEY>` for clien
|
|
|
78
89
|
|
|
79
90
|
Authentication is checked before the WebSocket upgrade. Invalid handshakes therefore return an HTTP status instead of opening and immediately closing a socket.
|
|
80
91
|
|
|
92
|
+
## GPT Live example
|
|
93
|
+
|
|
94
|
+
GPT Live is a provider-native JSON event protocol, not an Action `call` and not
|
|
95
|
+
OpenAI Realtime. The first client frame must be `session.start`. The production
|
|
96
|
+
endpoint locks the Live model to `gpt-live-1`, disables storage, and lets the
|
|
97
|
+
caller choose `client` or `responses` delegation once per connection. In
|
|
98
|
+
`responses` mode, the managed Responses model and its limits remain
|
|
99
|
+
server-controlled.
|
|
100
|
+
|
|
101
|
+
The packaged `examples/openai-gpt-live-text.mjs` demonstrates the smallest
|
|
102
|
+
managed-Responses lifecycle: connect with a server-side xAPI key, send
|
|
103
|
+
`session.start`, wait for `session.started`, create a text item, request a
|
|
104
|
+
response, and finish with `session.close` after the nested response completes.
|
|
105
|
+
It intentionally omits microphone capture so the protocol boundary is clear.
|
|
106
|
+
|
|
107
|
+
```bash
|
|
108
|
+
# Install the example's WebSocket transport in your application directory.
|
|
109
|
+
npm install ws
|
|
110
|
+
|
|
111
|
+
# Supply XAPI_KEY through the process environment; never put it in source code
|
|
112
|
+
# or pass it as a command-line argument.
|
|
113
|
+
node examples/openai-gpt-live-text.mjs "Answer in one short sentence."
|
|
114
|
+
```
|
|
115
|
+
|
|
116
|
+
Voice clients use the same session lifecycle, then send base64 PCM chunks as
|
|
117
|
+
`session.input_audio.append` events and consume `session.output_audio.delta`.
|
|
118
|
+
Audio format, voice, interruption behavior, and the complete event schema must
|
|
119
|
+
follow the current Live Sessions contract. Do not copy Realtime
|
|
120
|
+
`conversation.item.create` or `input_audio_buffer.*` events into a Live session.
|
|
121
|
+
|
|
122
|
+
With `client` delegation, the application must handle
|
|
123
|
+
`session.delegation.created`, run its own text-model request, and return the
|
|
124
|
+
result with `session.commentary.append`, then wait for
|
|
125
|
+
`session.commentary.appended`. Selecting `client` does not make xAPI run a
|
|
126
|
+
model on the application's behalf. Use `responses` when the managed backend is
|
|
127
|
+
desired.
|
|
128
|
+
|
|
81
129
|
## OpenAI Realtime example
|
|
82
130
|
|
|
83
131
|
The unified `/v1/realtime` route speaks the OpenAI Realtime GA JSON event protocol. It is native passthrough: send the same events you would send to the upstream Realtime API, but authenticate with the xAPI key.
|
|
@@ -121,15 +169,26 @@ Do not send the retired `OpenAI-Beta: realtime=v1` header. Session settings, aud
|
|
|
121
169
|
The browser `WebSocket` API cannot set arbitrary handshake headers. The Gateway accepts an xAPI key or temporary token through a subprotocol entry:
|
|
122
170
|
|
|
123
171
|
```javascript
|
|
124
|
-
const
|
|
172
|
+
const credential = await getEndpointBoundCredentialFromYourBackend(endpointId);
|
|
173
|
+
if (Date.now() >= new Date(credential.latestStartAt).getTime()) {
|
|
174
|
+
throw new Error("refresh the credential before opening a full new session");
|
|
175
|
+
}
|
|
125
176
|
const ws = new WebSocket(
|
|
126
|
-
"wss://
|
|
127
|
-
[`xapi-key.${
|
|
177
|
+
"wss://openai-live.p.xapi.to/v1/live/sessions",
|
|
178
|
+
["xapi-ws-v1", `xapi-key.${credential.token}`],
|
|
128
179
|
);
|
|
129
180
|
```
|
|
130
181
|
|
|
131
182
|
Never embed a long-lived xAPI key in frontend JavaScript. Use the authenticated xAPI Console Try-It flow or your backend to obtain a short-lived token, then pass only that token to the browser. The Console's `POST /api/keys/ws-token` flow mints a temporary token for a WebSocket endpoint; it requires a logged-in entity account and an endpoint ID, and is not authenticated with a normal xAPI key.
|
|
132
183
|
|
|
184
|
+
The credential is endpoint-bound and returns `expiresAt`, `latestStartAt`, and
|
|
185
|
+
`maxDurationSec`. It may be reused for reconnects only while the new connection
|
|
186
|
+
starts before `latestStartAt`; after that boundary, mint a fresh credential so
|
|
187
|
+
the full advertised session and final `session.close` exchange fit inside its
|
|
188
|
+
lifetime. If an endpoint declares public subprotocols, retain them and append
|
|
189
|
+
the `xapi-key.*` entry; otherwise use the non-secret `xapi-ws-v1` marker shown
|
|
190
|
+
above. Never log the secret subprotocol value.
|
|
191
|
+
|
|
133
192
|
If a browser integration must use `?token=`, use only a short-lived token and avoid logging the complete URL.
|
|
134
193
|
|
|
135
194
|
## Native protocol endpoints
|
|
@@ -138,6 +197,7 @@ The Gateway forwards frames without translating the application protocol. The se
|
|
|
138
197
|
|
|
139
198
|
| Adapter | Client frames | Important client requirement |
|
|
140
199
|
|---|---|---|
|
|
200
|
+
| `openai-live` | UTF-8 JSON text | First frame is `session.start`; choose Client or managed Responses delegation once. |
|
|
141
201
|
| `openai-realtime` | UTF-8 JSON text | Use OpenAI Realtime GA events. |
|
|
142
202
|
| `volcengine-asr` | Binary | Send the Volcengine ASR header/config/audio frame sequence; PCM configuration must match the audio bytes. |
|
|
143
203
|
| `doubao-realtime` | Binary | Use the Doubao end-to-end realtime dialogue protocol through its service host or exact endpoint. |
|