@qtsurfer/api-client 0.23.1 → 0.25.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/README.md CHANGED
@@ -57,8 +57,14 @@ const { data, error } = await authenticate({
57
57
  if (error) throw error;
58
58
 
59
59
  const { access_token: jwt } = data; // feed to client.setConfig() for the rest
60
+ console.log(data.scopes); // e.g. { exchanges: ['read'], backtests: ['read', 'execute'] }
60
61
  ```
61
62
 
63
+ An invalid, revoked, or expired key returns `401`. Where a deployment requires scopes, a key
64
+ with none returns `403` with `AuthTokenError.code === 'apikey_without_scopes'`, and no token is
65
+ minted. Create a key with at least one resource/action scope in the web app; retrying the same
66
+ scope-less key does not fix the rejection. Read the code from `error` and the status from `response`.
67
+
62
68
  For production use, prefer the [`@qtsurfer/sdk`](https://github.com/QTSurfer/sdk-ts)
63
69
  `authenticate(apikey)` helper — it returns a session that refreshes the JWT
64
70
  transparently, reads `QTSURFER_APIKEY` from the environment, and supports
@@ -69,7 +75,7 @@ pluggable token stores so callers don't reinvent that plumbing.
69
75
  All operations are exported as standalone functions; every operation accepts an `Options` object and returns `{ data, error, response }`.
70
76
 
71
77
  The table is exhaustive: `src/generated/` is produced from the OpenAPI spec, so **all 48 operations**
72
- the spec declares are exported. The rows below describe **spec version 0.128.20**, which is versioned
78
+ the spec declares are exported. The rows below describe **spec version 0.128.37**, which is versioned
73
79
  independently of this package.
74
80
 
75
81
  | Function | Method | Path | Purpose |
@@ -78,8 +84,8 @@ independently of this package.
78
84
  | `getAccount` | GET | `/account` | Read the authenticated account tier and limits, including the full-grid sweep limit |
79
85
  | `getAccountUsage` | GET | `/account/usage` | Read current resource and storage use |
80
86
  | `listExchanges` | GET | `/exchanges` | List the available exchanges |
81
- | `listInstruments` | GET | `/exchange/{exchangeId}/instruments` | List an exchange's instruments (default spot segment) |
82
- | `listSegmentInstruments` | GET | `/exchange/{exchangeId}/{segment}/instruments` | List an exchange segment's instruments |
87
+ | `listInstruments` | GET | `/exchange/{exchangeId}/instruments` | List CEX instruments or DEX pools in the default segment |
88
+ | `listSegmentInstruments` | GET | `/exchange/{exchangeId}/{segment}/instruments` | List CEX instruments or DEX pools in a discovered segment |
83
89
  | `downloadTickers` | GET | `/exchange/{exchangeId}/tickers/{base}/{quote}` | Download one hour of tickers as a Lastra segment |
84
90
  | `downloadKlines` | GET | `/exchange/{exchangeId}/klines/{base}/{quote}` | Download one hour of klines as a Lastra segment |
85
91
  | `listStrategies` | GET | `/strategies` | List your registered strategies, optionally including deleted strategies and their deletion times |
@@ -105,9 +111,9 @@ independently of this package.
105
111
  | `openDatasetUpload` | POST | `/datasets/{datasetId}/uploads` | Open an upload session for a later dataset version |
106
112
  | `finalizeDatasetUpload` | POST | `/datasets/{datasetId}/uploads/{uploadId}/finalize` | Queue ingest after uploading a file |
107
113
  | `getDatasetUpload` | GET | `/datasets/{datasetId}/uploads/{uploadId}` | Get an upload's ingestion state |
108
- | `importDataset` | POST | `/datasets/imports` | Create a dataset by importing external history |
114
+ | `importDataset` | POST | `/datasets/imports` | Create a dataset by importing CEX market history or DEX pool history |
109
115
  | `getDatasetImport` | GET | `/datasets/{datasetId}/imports/{importId}` | Get an import's fetch and ingestion state |
110
- | `startLive` | POST | `/strategy/{strategyId}/live` | Start a compiled strategy on a live feed; optionally set its warm-up replay window with `warmFrom`, simulate fills and equity with `paper`, or request a plain WebSocket stream URL |
116
+ | `startLive` | POST | `/strategy/{strategyId}/live` | Start a compiled strategy on a live feed; request a sandbox run with `sandbox: true`, set its warm-up replay window with `warmFrom`, simulate fills and equity with `paper`, or request a plain WebSocket stream URL |
111
117
  | `getLive` | GET | `/strategy/{strategyId}/live` | Read a strategy's current or most recent live run |
112
118
  | `stopLive` | DELETE | `/strategy/{strategyId}/live` | Request a strategy's active live run to stop |
113
119
  | `listLive` | GET | `/live` | Page all live runs owned by the authenticated account |
@@ -125,6 +131,34 @@ independently of this package.
125
131
 
126
132
  All generated types (`Exchange`, `InstrumentDetail`, `BacktestJobResult`, `PrepareJobState`, `ResultMap`, `LiveRunStats`, `LiveRunDetail`, `LiveRunWithStream`, `LiveStreamUrl`, `LiveStreamRevoked`, `LivePaper`, `LivePaperAccount`, `LivePaperEquityPage`, `SendLiveCommandRequest`, `LiveCommandResult`, etc.) are re-exported from the root.
127
133
 
134
+ ### Venue discovery, history, and scopes
135
+
136
+ `Exchange.venueType` is `cex` or `dex`; `segments` lists its catalogues and `liveSegments` the
137
+ segments a live run can consume. Both instrument operations return `InstrumentCatalogueResponse`,
138
+ a union of `InstrumentListResponse` and `PoolListResponse`, distinguished by `meta.venueType`.
139
+ Pool `id` is the address used to start a DEX live run; `symbol` is its signal pair. Unknown prices,
140
+ volumes, and pool creation dates are absent. DEX live sources require one pool address and `type: 'kline'`.
141
+ New requests use `cex`/`dex`; the server still accepts the older `cx`/`dx` spelling.
142
+
143
+ `DatasetImportRequest` accepts `type: 'cex'` with a `cex` block (`exchange`, `segment: 'spot'`,
144
+ `dataType: 'ticker' | 'klines'`), or `type: 'dex'` with its `dex` block. CEX import and kline
145
+ preparation support all fifteen cadence labels from `1s` through `1q`.
146
+
147
+ `AuthTokenResponse.scopes` and `Account.scopes` use `KeyScopes`, a resource-to-actions map such
148
+ as `{ exchanges: ['read'], backtests: ['read', 'execute'] }`; a key with none reports `{}`.
149
+ A scope is one resource and one action; resources with no actions are omitted. The API reports
150
+ these grants without refusing individual operations for missing scopes, although token issuance
151
+ can reject a key with no scopes as described above.
152
+
153
+ Hourly downloads cover the last seven days. Lastra content is `application/vnd.qtsurfer.lastra`
154
+ and its `ts` column uses microseconds (`X-Ts-Unit: micros`); Parquet timestamps use milliseconds.
155
+ Inspect `response.headers` for `X-Data-Status: provisional` and `X-Data-Through`: provisional
156
+ bytes may grow and must be fetched again to obtain the stored hour. Some deployments instead
157
+ answer recent hours with `404` `NOT_YET_AVAILABLE` and `Retry-After`. `ResponseError.reason`
158
+ distinguishes that case from `NO_DATA`, `OUTSIDE_WINDOW` (`400`, with `next` describing a dataset
159
+ import), and `TEMPORARILY_UNAVAILABLE` (`503`, with `Retry-After`). Treat unknown reasons like an
160
+ absent reason, and add caller-specific fields such as a dataset name to a suggested `ErrorNextCall`.
161
+
128
162
  `sendLiveCommand` sends a command to every execution behind an owned live run. The strategy must
129
163
  implement the engine's `CommandRequestHandler`; `202` means the command was accepted, not that the
130
164
  strategy has completed handling it: