xapi-to 0.1.18 → 0.1.19
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/LICENSE +21 -0
- package/README.md +51 -10
- package/dist/index.js +384 -46
- package/package.json +9 -2
- package/skills/xapi/SKILL.md +485 -0
- package/skills/xapi/guides/ai.md +200 -0
- package/skills/xapi/guides/ai_gateway.md +263 -0
- package/skills/xapi/guides/crypto.md +197 -0
- package/skills/xapi/guides/douyin.md +297 -0
- package/skills/xapi/guides/google_search.md +194 -0
- package/skills/xapi/guides/linkedin.md +198 -0
- package/skills/xapi/guides/reddit.md +312 -0
- package/skills/xapi/guides/sms.md +186 -0
- package/skills/xapi/guides/tiktok.md +322 -0
- package/skills/xapi/guides/twitter.md +276 -0
- package/skills/xapi/guides/weibo.md +301 -0
- package/skills/xapi/guides/ws_gateway.md +206 -0
- package/skills/xapi/guides/xiaohongshu.md +315 -0
- package/skills/xapi/scripts/download_tweet_videos.sh +125 -0
|
@@ -0,0 +1,200 @@
|
|
|
1
|
+
# AI Guide
|
|
2
|
+
|
|
3
|
+
Complete guide for AI capabilities via xAPI — text chat, summarize/rewrite, embeddings, asynchronous image/video generation, text-to-speech, and speech-to-text.
|
|
4
|
+
|
|
5
|
+
All AI endpoints are **built-in capabilities** (`--source capability`). Pass parameters with `--input` as a JSON object.
|
|
6
|
+
|
|
7
|
+
This guide covers CLI capabilities. For Claude Code, Anthropic/OpenAI SDKs, streaming HTTP APIs, and Gateway routing, read `guides/ai_gateway.md`. For full-duplex OpenAI Realtime or provider-native streaming ASR/TTS, read `guides/ws_gateway.md`.
|
|
8
|
+
|
|
9
|
+
## Contents
|
|
10
|
+
|
|
11
|
+
- [Text](#text-synchronous-or-sse-streaming)
|
|
12
|
+
- [Image generation](#image-generation)
|
|
13
|
+
- [Video generation](#video-generation)
|
|
14
|
+
- [Speech generation](#speech-generation)
|
|
15
|
+
- [Speech transcription](#speech-transcription)
|
|
16
|
+
- [Error handling](#error-handling)
|
|
17
|
+
|
|
18
|
+
## Text (synchronous or SSE streaming)
|
|
19
|
+
|
|
20
|
+
### Chat completions
|
|
21
|
+
|
|
22
|
+
```bash
|
|
23
|
+
# Fast — low latency, good for simple tasks
|
|
24
|
+
npx xapi-to call ai.text.chat.fast \
|
|
25
|
+
--input '{"messages":[{"role":"user","content":"Explain quantum computing in one sentence"}]}'
|
|
26
|
+
|
|
27
|
+
# Reasoning — slower, more thorough for analysis
|
|
28
|
+
npx xapi-to call ai.text.chat.reasoning \
|
|
29
|
+
--input '{"messages":[{"role":"user","content":"Analyze the pros and cons of microservices"}]}'
|
|
30
|
+
|
|
31
|
+
# Auto — you name the model; the gateway auto-routes to the best upstream with fallback
|
|
32
|
+
npx xapi-to call ai.text.chat.auto \
|
|
33
|
+
--input '{"model":"deepseek-v4-pro","messages":[{"role":"user","content":"Hello"}]}'
|
|
34
|
+
```
|
|
35
|
+
|
|
36
|
+
- `messages` follows the standard `[{role, content}]` chat format. `fast` and `reasoning` accept `system` | `user` | `assistant`; `auto` documents `user` | `assistant`.
|
|
37
|
+
- **When to choose which:** `fast` for quick/cheap replies, `reasoning` for multi-step analysis, `auto` when you want to specify a particular model and let the gateway pick the healthiest provider that serves it (defaults to `deepseek-v4-pro` if `model` is omitted).
|
|
38
|
+
- `ai.text.chat.auto.priority` accepts `default`, `cost`, `speed`, or `quality`. `cost` affects candidate ranking; `speed` and `quality` are accepted routing labels but currently have no dedicated rankers, so do not promise a distinct latency or quality outcome. See `guides/ai_gateway.md` for routing details.
|
|
39
|
+
- Add `--stream` to `ai.text.chat.fast`, `ai.text.chat.reasoning`, `ai.text.chat.auto`, `ai.text.summarize`, or `ai.text.rewrite` to forward the backend HTTP SSE frames unchanged. This is not WebSocket transport. Do not combine it with `--output` or `--code`.
|
|
40
|
+
|
|
41
|
+
### Summarize & rewrite
|
|
42
|
+
|
|
43
|
+
```bash
|
|
44
|
+
npx xapi-to call ai.text.summarize --input '{"text":"<long text here>"}'
|
|
45
|
+
|
|
46
|
+
npx xapi-to call ai.text.rewrite --input '{"text":"<text>","mode":"formalize"}'
|
|
47
|
+
```
|
|
48
|
+
|
|
49
|
+
`mode` values: `improve`, `simplify`, `formalize`, `casual`, `creative`, `professional`, `academic`.
|
|
50
|
+
|
|
51
|
+
- Summarization controls that affect execution: `model`, `max_length` (target words), `style` (`concise`, `detailed`, `bullet_points`, or `executive`), `language` (`auto` keeps the input language), `focus`, and `temperature`.
|
|
52
|
+
- Rewrite controls that affect execution: `model`, `mode`, `tone`, `target_audience`, `length_preference` (`shorter`, `similar`, or `longer`), and `temperature`.
|
|
53
|
+
- Always run `get` before using newly advertised fields. Do not assume every declared compatibility field changes current backend behavior.
|
|
54
|
+
|
|
55
|
+
### Embeddings
|
|
56
|
+
|
|
57
|
+
```bash
|
|
58
|
+
npx xapi-to call ai.embedding.generate --input '{"input":"hello world"}'
|
|
59
|
+
```
|
|
60
|
+
|
|
61
|
+
Returns a vector for one input string; use it for semantic search or similarity. Optional fields are `model`, `encoding_format` (`float` or `base64`), model-dependent `dimensions`, `user`, and provider-routing options in the `provider` object. The current declared schema accepts a string, so do not send a batch array until `get` reports array support.
|
|
62
|
+
|
|
63
|
+
## Image generation
|
|
64
|
+
|
|
65
|
+
Image generation is asynchronous and returns a task to wait for.
|
|
66
|
+
|
|
67
|
+
```bash
|
|
68
|
+
npx xapi-to call ai.image.generate \
|
|
69
|
+
--input '{"prompt":"A serene mountain landscape at sunset, digital art","model":"gpt-image-2"}'
|
|
70
|
+
```
|
|
71
|
+
|
|
72
|
+
- `prompt` (required) — the text description.
|
|
73
|
+
- `provider` (optional) — upstream, hard-pinned (no fallback). Defaults to `gpt88`.
|
|
74
|
+
- `model` (optional) — **must be compatible with the provider**:
|
|
75
|
+
- `gpt88` (default provider) serves `gpt-image-2` (default model).
|
|
76
|
+
- `skyimage` serves `gpt-image-1` and `dall-e-*` (`dall-e-3`, `dall-e-2`).
|
|
77
|
+
- ⚠️ Picking e.g. `dall-e-3` without also setting `provider: "skyimage"` will fail — the default `gpt88` provider only serves `gpt-image-2`.
|
|
78
|
+
- `n` (optional) — number of images (default `1`); `size` (optional, e.g. `1024x1024`).
|
|
79
|
+
- Other optional controls include `aspect_ratio`, `quality`, `background`, `moderation`, `style`, `image` (reference-image array), and `user`. Support depends on the selected model.
|
|
80
|
+
- Returns an async task handle, not the image itself. Wait for it with `task wait` as described below.
|
|
81
|
+
|
|
82
|
+
## Video generation
|
|
83
|
+
|
|
84
|
+
Video generation does **not** return the video immediately. It returns a task handle you must poll.
|
|
85
|
+
|
|
86
|
+
### Step 1: Submit the generation request
|
|
87
|
+
|
|
88
|
+
```bash
|
|
89
|
+
npx xapi-to call ai.video.generate \
|
|
90
|
+
--input '{"prompt":"A cat playing piano in a jazz bar, cinematic"}'
|
|
91
|
+
```
|
|
92
|
+
|
|
93
|
+
Optional inputs:
|
|
94
|
+
- `model` — any OpenRouter video model accepted upstream, e.g. `bytedance/seedance-2.0-fast`, `bytedance/seedance-2.0`, `google/veo-3.1`, or `openai/sora-2-pro`. Defaults to `bytedance/seedance-2.0-fast`.
|
|
95
|
+
- `provider` — only `openrouter` is currently supported; it is the default and is hard-pinned with no fallback.
|
|
96
|
+
- `image` — a single reference image URL (first frame).
|
|
97
|
+
- `images` — multiple reference image URLs.
|
|
98
|
+
- `input_reference` — OpenAI Videos-style reference material.
|
|
99
|
+
- `size` — frame size or aspect ratio, e.g. `1280x720`, `16:9`, or `9:16`.
|
|
100
|
+
- `duration` / `seconds` — requested duration; accepted values depend on the model.
|
|
101
|
+
- `seed` — random seed.
|
|
102
|
+
- `metadata` — provider-specific options such as roles, resolution, audio, watermark, or ratio.
|
|
103
|
+
|
|
104
|
+
The response is a **202-style async task**:
|
|
105
|
+
|
|
106
|
+
```json
|
|
107
|
+
{ "task_id": "…", "status": "pending", "poll_url": "…", "expires_at": "…" }
|
|
108
|
+
```
|
|
109
|
+
|
|
110
|
+
### Step 2: Wait until terminal
|
|
111
|
+
|
|
112
|
+
```bash
|
|
113
|
+
npx xapi-to task wait <task_id-from-step-1> --interval 2s --timeout 10m
|
|
114
|
+
```
|
|
115
|
+
|
|
116
|
+
Status values: `pending` | `processing` | `succeeded` | `failed` | `expired`.
|
|
117
|
+
|
|
118
|
+
- `task wait` polls every few seconds until the status is **terminal** (`succeeded` / `failed` / `expired`).
|
|
119
|
+
- On `succeeded`, the result payload (video URL/data) is included.
|
|
120
|
+
- On `failed` / `expired`, the error payload is printed and the command exits nonzero.
|
|
121
|
+
|
|
122
|
+
Use `npx xapi-to task poll <task_id>` for one status read when another scheduler controls the loop. Add `--max-attempts <n>` when an attempt bound is more useful than a time bound. Duration values accept `ms`, `s`, `m`, and `h`.
|
|
123
|
+
|
|
124
|
+
**Agent-controlled polling loop (pseudocode):**
|
|
125
|
+
|
|
126
|
+
```
|
|
127
|
+
submit → get task_id
|
|
128
|
+
loop:
|
|
129
|
+
result = run("npx xapi-to task poll " + task_id)
|
|
130
|
+
if result.status in {succeeded, failed, expired}: break
|
|
131
|
+
wait a few seconds
|
|
132
|
+
handle result
|
|
133
|
+
```
|
|
134
|
+
|
|
135
|
+
Do not busy-loop with zero delay — space polls a few seconds apart. If the task `expires`, resubmit.
|
|
136
|
+
|
|
137
|
+
## Speech generation
|
|
138
|
+
|
|
139
|
+
Text-to-speech calls are synchronous.
|
|
140
|
+
|
|
141
|
+
```bash
|
|
142
|
+
npx xapi-to call ai.audio.generate \
|
|
143
|
+
--input '{"text":"Hello world, this is a test.","model":"hexgrad/kokoro-82m","voice":"af_bella","format":"mp3"}'
|
|
144
|
+
```
|
|
145
|
+
|
|
146
|
+
Required inputs:
|
|
147
|
+
|
|
148
|
+
- `text` — text to convert into speech.
|
|
149
|
+
- `model` — OpenRouter TTS model ID.
|
|
150
|
+
- `voice` — a voice supported by the selected model.
|
|
151
|
+
|
|
152
|
+
Optional inputs:
|
|
153
|
+
|
|
154
|
+
- `format` — `mp3` (default) or `pcm`.
|
|
155
|
+
- `speed` — playback-speed multiplier when supported by the model.
|
|
156
|
+
- `provider` — OpenRouter provider-routing options as an object, not a provider name string.
|
|
157
|
+
|
|
158
|
+
The response is a lossless binary envelope:
|
|
159
|
+
|
|
160
|
+
```json
|
|
161
|
+
{
|
|
162
|
+
"success": true,
|
|
163
|
+
"data": {
|
|
164
|
+
"type": "binary",
|
|
165
|
+
"encoding": "base64",
|
|
166
|
+
"content_type": "audio/mpeg",
|
|
167
|
+
"content_length": 12345,
|
|
168
|
+
"content": "<base64-audio>"
|
|
169
|
+
}
|
|
170
|
+
}
|
|
171
|
+
```
|
|
172
|
+
|
|
173
|
+
Decode `data.content` from base64 to save or play the audio. `data.content_disposition` may also be present when supplied upstream.
|
|
174
|
+
|
|
175
|
+
## Speech transcription
|
|
176
|
+
|
|
177
|
+
Speech-to-text calls are synchronous.
|
|
178
|
+
|
|
179
|
+
```bash
|
|
180
|
+
npx xapi-to call ai.audio.transcribe \
|
|
181
|
+
--input '{"audio":{"data":"<base64-audio>","format":"wav"},"model":"openai/whisper-large-v3","language":"en"}'
|
|
182
|
+
```
|
|
183
|
+
|
|
184
|
+
- `audio` (required) — object containing raw base64 `data` without a data URI prefix and a file `format` such as `wav`, `mp3`, `flac`, `m4a`, `ogg`, `webm`, or `aac`.
|
|
185
|
+
- `model` (required) — OpenRouter speech-recognition model ID.
|
|
186
|
+
- `language` (optional) — ISO-639-1 code; omit it for automatic detection.
|
|
187
|
+
- `temperature` (optional) — transcription sampling temperature.
|
|
188
|
+
- `provider` (optional) — OpenRouter provider-routing options as an object.
|
|
189
|
+
|
|
190
|
+
Returns the transcribed `text` and optional OpenRouter `usage` information.
|
|
191
|
+
|
|
192
|
+
## Error handling
|
|
193
|
+
|
|
194
|
+
- **Missing `prompt`** → `prompt` is required for both `ai.image.generate` and `ai.video.generate`.
|
|
195
|
+
- **Unknown image model** → use a model compatible with the chosen image provider; omit both fields to use `gpt88` + `gpt-image-2`.
|
|
196
|
+
- **Unknown video provider/model** → provider must be `openrouter`; omit `model` to use `bytedance/seedance-2.0-fast`.
|
|
197
|
+
- **Image/video result never ready** → keep polling until a terminal status; on `expired`, resubmit the request.
|
|
198
|
+
- **Missing speech fields** → TTS requires `text`, `model`, and `voice`; transcription requires `audio.data`, `audio.format`, and `model`.
|
|
199
|
+
- **Invalid audio input** → pass raw base64 bytes without a `data:audio/...;base64,` prefix and set the matching file format.
|
|
200
|
+
- **Insufficient balance** → run `npx xapi-to topup --method stripe --amount 10` (AI media and speech calls consume credits).
|
|
@@ -0,0 +1,263 @@
|
|
|
1
|
+
# AI Gateway Guide
|
|
2
|
+
|
|
3
|
+
Use xAPI's public AI Gateway when a tool or application expects an Anthropic- or OpenAI-compatible HTTP API. For one-off agent calls from the terminal, prefer the `ai.*` CLI capabilities documented in `guides/ai.md`. For full-duplex OpenAI Realtime, streaming ASR/TTS, simultaneous interpretation, or other WebSocket sessions, read `guides/ws_gateway.md`.
|
|
4
|
+
|
|
5
|
+
## Contents
|
|
6
|
+
|
|
7
|
+
- [Choose CLI capabilities or the Gateway](#choose-cli-capabilities-or-the-gateway)
|
|
8
|
+
- [Base URLs and authentication](#base-urls-and-authentication)
|
|
9
|
+
- [Claude Code and Anthropic setup](#claude-code-and-anthropic-setup)
|
|
10
|
+
- [OpenAI-compatible setup](#openai-compatible-setup)
|
|
11
|
+
- [Select a model in the URL](#select-a-model-in-the-url)
|
|
12
|
+
- [Supported endpoints](#supported-endpoints)
|
|
13
|
+
- [Routing strategies](#routing-strategies)
|
|
14
|
+
- [Provider affinity](#provider-affinity)
|
|
15
|
+
- [Streaming and protocol translation](#streaming-and-protocol-translation)
|
|
16
|
+
- [Routing and billing headers](#routing-and-billing-headers)
|
|
17
|
+
- [Image, video, and rerank endpoints](#image-video-and-rerank-endpoints)
|
|
18
|
+
- [Known limitations](#known-limitations)
|
|
19
|
+
- [Error handling and security](#error-handling-and-security)
|
|
20
|
+
|
|
21
|
+
## Choose CLI capabilities or the Gateway
|
|
22
|
+
|
|
23
|
+
Use CLI capabilities when an agent needs to make a small number of direct calls and consume JSON:
|
|
24
|
+
|
|
25
|
+
```bash
|
|
26
|
+
npx xapi-to call ai.text.chat.auto \
|
|
27
|
+
--input '{"model":"deepseek-v4-pro","messages":[{"role":"user","content":"Hello"}]}'
|
|
28
|
+
```
|
|
29
|
+
|
|
30
|
+
Use the AI Gateway when:
|
|
31
|
+
|
|
32
|
+
- configuring Claude Code, an Anthropic SDK, an OpenAI SDK, or another compatible client;
|
|
33
|
+
- an existing application already calls `/v1/messages`, `/v1/chat/completions`, `/v1/responses`, or `/v1/embeddings`;
|
|
34
|
+
- the caller needs streaming SSE responses;
|
|
35
|
+
- the caller should use model normalization, protocol translation, provider health checks, and fallback without selecting an upstream manually.
|
|
36
|
+
|
|
37
|
+
The Gateway is a separate HTTP interface. Do not wrap Gateway request bodies in the xAPI action format (`action_id` / `input`). Send the native Anthropic or OpenAI request body directly.
|
|
38
|
+
|
|
39
|
+
## Base URLs and authentication
|
|
40
|
+
|
|
41
|
+
Public host: `https://ai.xapi.to`
|
|
42
|
+
|
|
43
|
+
Strategy-prefixed base URLs:
|
|
44
|
+
|
|
45
|
+
| Protocol | Base URL |
|
|
46
|
+
|---|---|
|
|
47
|
+
| Anthropic | `https://ai.xapi.to/<strategy>` |
|
|
48
|
+
| OpenAI | `https://ai.xapi.to/<strategy>/v1` |
|
|
49
|
+
|
|
50
|
+
Omit `<strategy>` to use the default routes directly under `/v1`.
|
|
51
|
+
|
|
52
|
+
The Gateway accepts the xAPI key through any of these headers:
|
|
53
|
+
|
|
54
|
+
```text
|
|
55
|
+
XAPI-Key: <XAPI_KEY>
|
|
56
|
+
Authorization: Bearer <XAPI_KEY>
|
|
57
|
+
x-api-key: <XAPI_KEY>
|
|
58
|
+
```
|
|
59
|
+
|
|
60
|
+
Use the header expected by the client library: Anthropic clients normally use `x-api-key`; OpenAI clients normally use `Authorization: Bearer`.
|
|
61
|
+
|
|
62
|
+
If no key is configured, register or set one with the CLI before proceeding:
|
|
63
|
+
|
|
64
|
+
```bash
|
|
65
|
+
npx xapi-to register
|
|
66
|
+
npx xapi-to config set apiKey=<your-key>
|
|
67
|
+
```
|
|
68
|
+
|
|
69
|
+
## Claude Code and Anthropic setup
|
|
70
|
+
|
|
71
|
+
Configure Claude Code or another Anthropic-compatible client with an xAPI key and a strategy base URL:
|
|
72
|
+
|
|
73
|
+
```bash
|
|
74
|
+
export ANTHROPIC_BASE_URL="https://ai.xapi.to/quality"
|
|
75
|
+
export ANTHROPIC_API_KEY="<XAPI_KEY>"
|
|
76
|
+
```
|
|
77
|
+
|
|
78
|
+
Direct Anthropic Messages request:
|
|
79
|
+
|
|
80
|
+
```bash
|
|
81
|
+
curl https://ai.xapi.to/default/v1/messages \
|
|
82
|
+
-H 'content-type: application/json' \
|
|
83
|
+
-H 'anthropic-version: 2023-06-01' \
|
|
84
|
+
-H 'x-api-key: <XAPI_KEY>' \
|
|
85
|
+
-d '{
|
|
86
|
+
"model":"deepseek-v4-pro",
|
|
87
|
+
"max_tokens":1024,
|
|
88
|
+
"messages":[{"role":"user","content":"Explain xAPI in one sentence."}]
|
|
89
|
+
}'
|
|
90
|
+
```
|
|
91
|
+
|
|
92
|
+
Anthropic fields such as top-level `system`, content blocks, `thinking`, `tools`, `tool_choice`, `temperature`, `top_p`, `top_k`, `stop_sequences`, and `metadata` are accepted and routed with the request. Support at the selected upstream still depends on the model.
|
|
93
|
+
|
|
94
|
+
## OpenAI-compatible setup
|
|
95
|
+
|
|
96
|
+
For clients that honor the standard OpenAI environment variables:
|
|
97
|
+
|
|
98
|
+
```bash
|
|
99
|
+
export OPENAI_BASE_URL="https://ai.xapi.to/default/v1"
|
|
100
|
+
export OPENAI_API_KEY="<XAPI_KEY>"
|
|
101
|
+
```
|
|
102
|
+
|
|
103
|
+
Direct Chat Completions request:
|
|
104
|
+
|
|
105
|
+
```bash
|
|
106
|
+
curl https://ai.xapi.to/cost/v1/chat/completions \
|
|
107
|
+
-H 'content-type: application/json' \
|
|
108
|
+
-H 'authorization: Bearer <XAPI_KEY>' \
|
|
109
|
+
-d '{
|
|
110
|
+
"model":"deepseek-v4-flash",
|
|
111
|
+
"messages":[{"role":"user","content":"Hello"}]
|
|
112
|
+
}'
|
|
113
|
+
```
|
|
114
|
+
|
|
115
|
+
List currently routable canonical models:
|
|
116
|
+
|
|
117
|
+
```bash
|
|
118
|
+
curl https://ai.xapi.to/v1/models
|
|
119
|
+
```
|
|
120
|
+
|
|
121
|
+
Use the returned model ID in subsequent requests. A model can only be routed when an active provider exposes a compatible endpoint and input modality.
|
|
122
|
+
|
|
123
|
+
## Select a model in the URL
|
|
124
|
+
|
|
125
|
+
For strategy-aware endpoints, the segment before `/v1` can be either a routing strategy or a model ID. When it is not one of the reserved strategies `default`, `cost`, `speed`, or `quality`, the Gateway treats it as the model, overwrites any `model` value in the request body, and uses the default strategy.
|
|
126
|
+
|
|
127
|
+
```bash
|
|
128
|
+
curl https://ai.xapi.to/gpt-4o/v1/chat/completions \
|
|
129
|
+
-H 'authorization: Bearer <XAPI_KEY>' \
|
|
130
|
+
-H 'content-type: application/json' \
|
|
131
|
+
-d '{"model":"ignored","messages":[{"role":"user","content":"Hello"}]}'
|
|
132
|
+
```
|
|
133
|
+
|
|
134
|
+
This also works for Anthropic Messages, OpenAI Responses, and embeddings. Use it only for model IDs that fit in one URL path segment. For IDs containing `/`, keep the model in the JSON body and use a strategy-prefixed or unprefixed `/v1` route.
|
|
135
|
+
|
|
136
|
+
## Supported endpoints
|
|
137
|
+
|
|
138
|
+
| Interface | Method and path | Strategy prefix |
|
|
139
|
+
|---|---|---|
|
|
140
|
+
| Anthropic Messages | `POST /v1/messages` | Optional |
|
|
141
|
+
| OpenAI Chat Completions | `POST /v1/chat/completions` | Optional |
|
|
142
|
+
| OpenAI Responses | `POST /v1/responses` | Optional |
|
|
143
|
+
| Embeddings | `POST /v1/embeddings` | Optional |
|
|
144
|
+
| Model discovery | `GET /v1/models` | Optional |
|
|
145
|
+
| Image generation | `POST /v1/images/generations` | No |
|
|
146
|
+
| Video generation | `POST /v1/videos` | No |
|
|
147
|
+
| Rerank | `POST /v1/rerank` | No |
|
|
148
|
+
|
|
149
|
+
For strategy-aware endpoints, insert a strategy before `/v1`, for example `/cost/v1/responses`. Without a prefix, the Gateway uses `default`.
|
|
150
|
+
|
|
151
|
+
## Routing strategies
|
|
152
|
+
|
|
153
|
+
Accepted strategies:
|
|
154
|
+
|
|
155
|
+
| Strategy | Current behavior |
|
|
156
|
+
|---|---|
|
|
157
|
+
| `default` | Prefer protocol-compatible zero-translation candidates, then configured provider priority and weighted distribution. |
|
|
158
|
+
| `cost` | Prefer the lowest effective cost, adjusted by recent provider success rate; near-equal candidates fall back to default ordering. |
|
|
159
|
+
| `speed` | Accepted, but currently uses the same candidate ordering as `default`. |
|
|
160
|
+
| `quality` | Accepted, but currently uses the same candidate ordering as `default`. |
|
|
161
|
+
|
|
162
|
+
All strategies apply the active-provider gate, model and modality compatibility checks, provider health checks, circuit breaking, and eligible-provider fallback. Do not promise distinct latency or quality optimization for `speed` or `quality` until their dedicated rankers are implemented.
|
|
163
|
+
|
|
164
|
+
## Provider affinity
|
|
165
|
+
|
|
166
|
+
After a successful request, the Gateway remembers the serving provider for one hour and promotes it for later requests with the same strategy, model, and affinity identity. The identity is selected in this order:
|
|
167
|
+
|
|
168
|
+
- Anthropic Messages: `metadata.user_id`, then the xAPI key;
|
|
169
|
+
- OpenAI Chat Completions: `prompt_cache_key`, then `user`, then the xAPI key;
|
|
170
|
+
- other interfaces, including Responses and embeddings: the xAPI key.
|
|
171
|
+
|
|
172
|
+
Affinity is isolated between routing strategies and only changes candidate order. It does not bypass health, circuit-breaker, model, modality, or active-provider checks, so clients must not rely on a provider remaining fixed for the full hour.
|
|
173
|
+
|
|
174
|
+
## Streaming and protocol translation
|
|
175
|
+
|
|
176
|
+
Set `"stream": true` in Chat Completions, Responses, or Messages requests to receive an SSE stream in the requested protocol.
|
|
177
|
+
|
|
178
|
+
The Gateway can route across providers with different upstream protocols. When translation is available, it converts the request and response while preserving the inbound Anthropic or OpenAI interface. Model-specific features such as tool calling, thinking, images, or structured output still depend on the selected model and available adapter.
|
|
179
|
+
|
|
180
|
+
Client-side validation errors normally stop immediately. Provider reliability failures such as authentication/configuration failures, rate limits, timeouts, and server errors may trigger fallback to another eligible provider.
|
|
181
|
+
|
|
182
|
+
## Routing and billing headers
|
|
183
|
+
|
|
184
|
+
Successful routed responses can include:
|
|
185
|
+
|
|
186
|
+
| Header | Meaning |
|
|
187
|
+
|---|---|
|
|
188
|
+
| `X-Routing-Provider` | Provider that served the final response. |
|
|
189
|
+
| `X-Routing-Attempts` | Number of candidates attempted. |
|
|
190
|
+
| `X-Routing-Fallback` | `true` when a later candidate succeeded. |
|
|
191
|
+
| `X-Routing-Translated` | Present when protocol translation was used. |
|
|
192
|
+
| `X-XAPI-Cost` | Aggregated USD cost for the request attempts. |
|
|
193
|
+
| `X-XAPI-Cost-Unit` | Cost currency, currently `USD`. |
|
|
194
|
+
| `X-XAPI-Billing` | Billing status. |
|
|
195
|
+
| `X-XAPI-Billing-Type` | Billing mode, such as `PER_TOKEN` or `ASYNC`. |
|
|
196
|
+
|
|
197
|
+
Do not use provider names as a stable application contract. Provider selection can change with availability, configuration, pricing, and routing policy.
|
|
198
|
+
|
|
199
|
+
## Image, video, and rerank endpoints
|
|
200
|
+
|
|
201
|
+
These endpoints are direct Gateway interfaces and do not use a strategy prefix.
|
|
202
|
+
|
|
203
|
+
### Images
|
|
204
|
+
|
|
205
|
+
```bash
|
|
206
|
+
curl https://ai.xapi.to/v1/images/generations \
|
|
207
|
+
-H 'authorization: Bearer <XAPI_KEY>' \
|
|
208
|
+
-H 'content-type: application/json' \
|
|
209
|
+
-H 'X-Provider: gpt88' \
|
|
210
|
+
-d '{"model":"gpt-image-2","prompt":"A moonlit mountain lake"}'
|
|
211
|
+
```
|
|
212
|
+
|
|
213
|
+
Image provider selection is hard-pinned with `X-Provider` and has no fallback. The default is `gpt88`; `skyimage` is also available, but the model must be compatible with the selected provider.
|
|
214
|
+
|
|
215
|
+
### Videos
|
|
216
|
+
|
|
217
|
+
```bash
|
|
218
|
+
curl https://ai.xapi.to/v1/videos \
|
|
219
|
+
-H 'authorization: Bearer <XAPI_KEY>' \
|
|
220
|
+
-H 'content-type: application/json' \
|
|
221
|
+
-H 'X-Provider: openrouter' \
|
|
222
|
+
-d '{"model":"bytedance/seedance-2.0-fast","prompt":"A cat playing piano in a jazz bar"}'
|
|
223
|
+
```
|
|
224
|
+
|
|
225
|
+
The current video provider is `openrouter`, which is also the default and is hard-pinned with no fallback.
|
|
226
|
+
|
|
227
|
+
Image and video generation are asynchronous. A successful submit returns a `task_id`, `status`, and `poll_url`. Follow the authenticated `poll_url`, or poll the same task through the CLI:
|
|
228
|
+
|
|
229
|
+
```bash
|
|
230
|
+
npx xapi-to task wait <task_id> --interval 2s --timeout 10m
|
|
231
|
+
```
|
|
232
|
+
|
|
233
|
+
### Rerank
|
|
234
|
+
|
|
235
|
+
```bash
|
|
236
|
+
curl https://ai.xapi.to/v1/rerank \
|
|
237
|
+
-H 'authorization: Bearer <XAPI_KEY>' \
|
|
238
|
+
-H 'content-type: application/json' \
|
|
239
|
+
-d '{"model":"<rerank-model>","query":"What is xAPI?","documents":["...","..."]}'
|
|
240
|
+
```
|
|
241
|
+
|
|
242
|
+
Rerank currently routes directly through OpenRouter rather than the strategy-based candidate pool.
|
|
243
|
+
|
|
244
|
+
## Known limitations
|
|
245
|
+
|
|
246
|
+
- `POST /v1/messages/count_tokens` is not implemented and currently returns `404`.
|
|
247
|
+
- `speed` and `quality` are accepted strategy names but currently use default ordering.
|
|
248
|
+
- Image and video endpoints submit asynchronous tasks; they do not return final media in the initial response.
|
|
249
|
+
- Image/video provider selection is hard-pinned and does not use chat-style fallback.
|
|
250
|
+
- Text-to-speech and speech-to-text are not exposed as HTTP AI Gateway routes. Use `ai.audio.generate` and `ai.audio.transcribe` through the xAPI CLI for synchronous calls, or `guides/ws_gateway.md` for provider-native streaming sessions.
|
|
251
|
+
- Model and feature availability is dynamic. Use `GET /v1/models` and handle unsupported-model or modality errors.
|
|
252
|
+
- Path-selected models must fit in one URL path segment; otherwise send the model in the body.
|
|
253
|
+
|
|
254
|
+
## Error handling and security
|
|
255
|
+
|
|
256
|
+
- **401 / authentication error** → verify that the xAPI key is sent in one supported authentication header.
|
|
257
|
+
- **Model not found** → use `GET /v1/models` and select a currently routable model ID.
|
|
258
|
+
- **No candidates / 503** → no active provider currently serves that model and protocol combination; retry later or choose another model.
|
|
259
|
+
- **Unsupported modality** → choose a model that accepts the request's text, image, or other input type.
|
|
260
|
+
- **All providers failed** → retry with backoff; changing strategy may reorder candidates but cannot make an unavailable model routable.
|
|
261
|
+
- **Async task failed or expired** → inspect the poll result and resubmit when appropriate.
|
|
262
|
+
|
|
263
|
+
Never send the xAPI key to a domain outside `*.xapi.to`. Do not print, persist, or share the key, payment URLs, or authenticated polling URLs.
|
|
@@ -0,0 +1,197 @@
|
|
|
1
|
+
# Crypto Guide
|
|
2
|
+
|
|
3
|
+
Complete guide for crypto/on-chain data via xAPI — token price & market data, holders, security, OHLCV, wallet analytics, DEX pairs, CEX spot prices, and news.
|
|
4
|
+
|
|
5
|
+
All crypto endpoints are **built-in capabilities** (`--source capability`). Pass parameters with `--input` as a JSON object.
|
|
6
|
+
|
|
7
|
+
## Contents
|
|
8
|
+
|
|
9
|
+
- [Addressing models](#the-two-addressing-models-read-this-first)
|
|
10
|
+
- [Chains](#chains)
|
|
11
|
+
- [Token data](#token-data-by-contract-address)
|
|
12
|
+
- [Wallet analytics](#wallet-analytics-by-wallet-address)
|
|
13
|
+
- [Transactions and DEX pairs](#transaction-and-dex-pair)
|
|
14
|
+
- [CEX spot data](#cex-spot-data-by-symbol)
|
|
15
|
+
- [News](#news)
|
|
16
|
+
- [Symbol-to-contract workflow](#common-workflow-from-symbol-to-on-chain-data)
|
|
17
|
+
- [Pagination](#cursor-pagination)
|
|
18
|
+
- [Error handling](#error-handling)
|
|
19
|
+
|
|
20
|
+
## The two addressing models (read this first)
|
|
21
|
+
|
|
22
|
+
Crypto endpoints split into two families by how you identify the asset:
|
|
23
|
+
|
|
24
|
+
| Family | Identify by | Endpoints | Use when |
|
|
25
|
+
|--------|-------------|-----------|----------|
|
|
26
|
+
| **On-chain** | **contract / wallet / pool address** + `chain` | `crypto.token.*`, `crypto.wallet.*`, `crypto.tx.*`, `crypto.dex.*` | You have (or can resolve) a contract address on a specific chain |
|
|
27
|
+
| **CEX** | **symbol** (BTC, ETH, …) | `crypto.cex.*` | You only have a ticker symbol and want a centralized-exchange spot price |
|
|
28
|
+
|
|
29
|
+
**Common mistake:** do NOT pass a symbol like `"BTC"` as the `token` of `crypto.token.price` — that field is a **contract address**. For "how much is BTC worth?" use `crypto.cex.price` with `{"symbol":"BTC"}`. If the user gives you a name/symbol and you need on-chain data, first resolve it to an address with `crypto.token.search` (see workflow below).
|
|
30
|
+
|
|
31
|
+
## Chains
|
|
32
|
+
|
|
33
|
+
`chain` accepts these canonical values (default `bsc`):
|
|
34
|
+
|
|
35
|
+
`eth` · `bsc` · `solana` · `base` · `arbitrum` · `polygon` · `optimism` · `avalanche`
|
|
36
|
+
|
|
37
|
+
Common aliases are normalized automatically: `ethereum`/`ether` → `eth`, `bnb`/`bnb-chain`/`binance`/`binance-smart-chain` → `bsc`, `sol` → `solana`.
|
|
38
|
+
|
|
39
|
+
All on-chain endpoints accept an optional `provider` to pin a specific upstream and **disable automatic fallback**. By default the gateway aggregates several upstreams (e.g. moralis / birdeye / dexscreener, depending on chain and endpoint) and falls back on failure. The valid `provider` values differ per endpoint — run `npx xapi-to get <id>` to see the exact enum. Only pin a provider for debugging or when you need a specific source.
|
|
40
|
+
|
|
41
|
+
## Token data (by contract address)
|
|
42
|
+
|
|
43
|
+
### Price + 24h market data
|
|
44
|
+
|
|
45
|
+
```bash
|
|
46
|
+
npx xapi-to call crypto.token.price \
|
|
47
|
+
--input '{"token":"0x55d398326f99059ff775485246999027b3197955","chain":"bsc"}'
|
|
48
|
+
```
|
|
49
|
+
|
|
50
|
+
Returns `data.priceUsd`, `symbol`, `name`, plus 24h change / volume / liquidity / market cap (fields depend on the resolving provider).
|
|
51
|
+
|
|
52
|
+
### Full overview (metadata + price + market in one call) — preferred
|
|
53
|
+
|
|
54
|
+
```bash
|
|
55
|
+
npx xapi-to call crypto.token.overview \
|
|
56
|
+
--input '{"token":"0x55d398326f99059ff775485246999027b3197955","chain":"bsc"}'
|
|
57
|
+
```
|
|
58
|
+
|
|
59
|
+
Prefer `crypto.token.overview` over the deprecated `crypto.token.metadata` — it returns name/symbol/decimals/logo **and** price/market data in a single request.
|
|
60
|
+
|
|
61
|
+
> `crypto.token.metadata` still works but is **deprecated**; migrate to `crypto.token.overview`.
|
|
62
|
+
|
|
63
|
+
### OHLCV candles
|
|
64
|
+
|
|
65
|
+
```bash
|
|
66
|
+
npx xapi-to call crypto.token.ohlcv \
|
|
67
|
+
--input '{"token":"0x...","chain":"bsc","interval":"1h","limit":100}'
|
|
68
|
+
```
|
|
69
|
+
|
|
70
|
+
`interval` defaults to `1d`; valid values are `1m`, `5m`, `15m`, `1h`, `4h`, `1d`, `1w`. `limit` is the number of candles. (Same interval set applies to `crypto.cex.ohlcv`.)
|
|
71
|
+
|
|
72
|
+
### Holders / top traders / security
|
|
73
|
+
|
|
74
|
+
```bash
|
|
75
|
+
# Top holders (optional limit)
|
|
76
|
+
npx xapi-to call crypto.token.holders --input '{"token":"0x...","chain":"bsc","limit":50}'
|
|
77
|
+
|
|
78
|
+
# Top traders of the token
|
|
79
|
+
npx xapi-to call crypto.token.top_traders --input '{"token":"0x...","chain":"bsc"}'
|
|
80
|
+
|
|
81
|
+
# Security check (honeypot, buy/sell tax, ownership, etc.)
|
|
82
|
+
npx xapi-to call crypto.token.security --input '{"token":"0x...","chain":"bsc"}'
|
|
83
|
+
```
|
|
84
|
+
|
|
85
|
+
Run `crypto.token.security` before treating any token as tradeable — it flags honeypots and abnormal taxes.
|
|
86
|
+
|
|
87
|
+
`crypto.token.holders` is paginated. When the response contains `data.next_cursor`, pass it back unchanged:
|
|
88
|
+
|
|
89
|
+
```bash
|
|
90
|
+
npx xapi-to call crypto.token.holders \
|
|
91
|
+
--input '{"token":"0x...","chain":"bsc","limit":50,"cursor":"<next_cursor>"}'
|
|
92
|
+
```
|
|
93
|
+
|
|
94
|
+
Moralis supports holder pagination on EVM chains and Birdeye supports it on Solana. The cursor pins the provider that issued it.
|
|
95
|
+
|
|
96
|
+
### Trending tokens (chain-level, no address needed)
|
|
97
|
+
|
|
98
|
+
```bash
|
|
99
|
+
npx xapi-to call crypto.token.trending --input '{"chain":"bsc","limit":20}'
|
|
100
|
+
```
|
|
101
|
+
|
|
102
|
+
### Search tokens by name / symbol / address
|
|
103
|
+
|
|
104
|
+
```bash
|
|
105
|
+
npx xapi-to call crypto.token.search --input '{"query":"PEPE","limit":10}'
|
|
106
|
+
```
|
|
107
|
+
|
|
108
|
+
`query` can be a name, symbol, pair, or address. Results include contract addresses you can feed into the other `crypto.token.*` endpoints.
|
|
109
|
+
|
|
110
|
+
## Wallet analytics (by wallet address)
|
|
111
|
+
|
|
112
|
+
```bash
|
|
113
|
+
# Current token balances
|
|
114
|
+
npx xapi-to call crypto.wallet.balance --input '{"address":"0x...","chain":"bsc"}'
|
|
115
|
+
|
|
116
|
+
# Realized/unrealized profit & loss
|
|
117
|
+
npx xapi-to call crypto.wallet.pnl --input '{"address":"0x...","chain":"bsc"}'
|
|
118
|
+
|
|
119
|
+
# Transaction history (optional limit)
|
|
120
|
+
npx xapi-to call crypto.wallet.history --input '{"address":"0x...","chain":"bsc","limit":50}'
|
|
121
|
+
```
|
|
122
|
+
|
|
123
|
+
Typical wallet-analysis flow: `wallet.balance` (what they hold) → `wallet.pnl` (how they're doing) → `wallet.history` (recent activity).
|
|
124
|
+
|
|
125
|
+
`crypto.wallet.balance` and `crypto.wallet.history` are paginated when served by Moralis. Read `data.next_cursor` and pass it back as `cursor` for the next page. `crypto.wallet.pnl` is not paginated.
|
|
126
|
+
|
|
127
|
+
## Transaction and DEX pair
|
|
128
|
+
|
|
129
|
+
```bash
|
|
130
|
+
# Decode a single transaction
|
|
131
|
+
npx xapi-to call crypto.tx.detail --input '{"txHash":"0x...","chain":"bsc"}'
|
|
132
|
+
|
|
133
|
+
# DEX pair / pool stats by pair contract address
|
|
134
|
+
npx xapi-to call crypto.dex.pair --input '{"pair":"0x...","chain":"bsc"}'
|
|
135
|
+
```
|
|
136
|
+
|
|
137
|
+
Note `crypto.dex.pair` takes the **pool/pair contract address** (not a token address).
|
|
138
|
+
|
|
139
|
+
## CEX spot data by symbol
|
|
140
|
+
|
|
141
|
+
Use these when you only have a ticker and want a centralized-exchange price.
|
|
142
|
+
|
|
143
|
+
```bash
|
|
144
|
+
# Spot price + 24h change/volume/high/low
|
|
145
|
+
npx xapi-to call crypto.cex.price --input '{"symbol":"BTC"}'
|
|
146
|
+
|
|
147
|
+
# CEX OHLCV candles
|
|
148
|
+
npx xapi-to call crypto.cex.ohlcv --input '{"symbol":"BTC","interval":"1d","limit":100}'
|
|
149
|
+
```
|
|
150
|
+
|
|
151
|
+
`symbol` accepts a bare ticker (`BTC`, `ETH`) or a full pair (`BTCUSDT`, `BTC-USDT`). For a bare symbol you may pass `quote` (default `USDT`).
|
|
152
|
+
|
|
153
|
+
## News
|
|
154
|
+
|
|
155
|
+
```bash
|
|
156
|
+
# Latest crypto news, optionally scoped to a coin
|
|
157
|
+
npx xapi-to call crypto.news --input '{"symbol":"BTC","limit":20}'
|
|
158
|
+
```
|
|
159
|
+
|
|
160
|
+
All parameters are optional; omit `symbol` for general market news.
|
|
161
|
+
|
|
162
|
+
## Common workflow from symbol to on-chain data
|
|
163
|
+
|
|
164
|
+
The user gives you a token name or symbol but you need on-chain metrics (holders, security, liquidity):
|
|
165
|
+
|
|
166
|
+
```bash
|
|
167
|
+
# 1. Resolve the symbol/name to a contract address + chain
|
|
168
|
+
npx xapi-to call crypto.token.search --input '{"query":"PEPE"}'
|
|
169
|
+
# → pick the right result, read its contract address and chain
|
|
170
|
+
|
|
171
|
+
# 2. Query on-chain endpoints with that address
|
|
172
|
+
npx xapi-to call crypto.token.overview --input '{"token":"0x6982...","chain":"eth"}'
|
|
173
|
+
npx xapi-to call crypto.token.security --input '{"token":"0x6982...","chain":"eth"}'
|
|
174
|
+
```
|
|
175
|
+
|
|
176
|
+
For a plain "what's the price of BTC" question with no on-chain requirement, skip all of this and use `crypto.cex.price`.
|
|
177
|
+
|
|
178
|
+
## Cursor Pagination
|
|
179
|
+
|
|
180
|
+
Three crypto capabilities expose cursor pagination:
|
|
181
|
+
|
|
182
|
+
| Capability | Next cursor field | Next request input | Paging providers |
|
|
183
|
+
|---|---|---|---|
|
|
184
|
+
| `crypto.token.holders` | `data.next_cursor` | `cursor` | Moralis (EVM), Birdeye (Solana) |
|
|
185
|
+
| `crypto.wallet.balance` | `data.next_cursor` | `cursor` | Moralis |
|
|
186
|
+
| `crypto.wallet.history` | `data.next_cursor` | `cursor` | Moralis |
|
|
187
|
+
|
|
188
|
+
The cursor is an opaque `<provider>:<native>` value. Do not parse, edit, or combine it with a different explicit `provider`; pass it back unchanged. A cursor pins requests to its issuing provider, so pagination deliberately does not fall back to a different upstream. Stop when `next_cursor` is null or absent.
|
|
189
|
+
|
|
190
|
+
`crypto.token.trending` and `crypto.token.top_traders` are top-N list capabilities, not cursor-paginated feeds.
|
|
191
|
+
|
|
192
|
+
## Error handling
|
|
193
|
+
|
|
194
|
+
- **Unsupported chain** → use one of the canonical chain values listed above (or a known alias).
|
|
195
|
+
- **`token`/`address` looks like a symbol** → it must be a contract/wallet address; resolve via `crypto.token.search`, or switch to `crypto.cex.*` for symbol-based pricing.
|
|
196
|
+
- **Empty / partial fields** → different upstream providers return different field sets; pin a `provider` or try `crypto.token.overview` for the most complete payload.
|
|
197
|
+
- **Invalid or mismatched cursor** → pass `next_cursor` back unchanged and do not force a different provider; start again without `cursor` if the original cursor is unavailable.
|