@hunt-labs/bytekit-sdk 0.11.4 → 0.11.6

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 CHANGED
@@ -10,6 +10,23 @@ today, see [README.md](./README.md), which remains the authoritative usage guide
10
10
 
11
11
  ## [Unreleased]
12
12
 
13
+ ## [0.11.6] - 2026-09-24
14
+
15
+ ### Changed
16
+
17
+ - Regenerated `src/generated/api.d.ts` (#4865): a documentation-wording correction to the
18
+ `POST /v1/schema` billing description, which now says the page bandwidth is billed at its
19
+ upstream wire bytes with no endpoint factor instead of "exactly like `/v1/scrape`". No
20
+ behavior change: doc comments only, no SDK signature moves.
21
+
22
+ ## [0.11.5] - 2026-09-22
23
+
24
+ ### Changed
25
+
26
+ - **Internal `GET /v1/logs` types list schema rows (#2373).** Both `endpoint` enums add `schema`,
27
+ for `/v1/schema` structured-extraction requests, whose row ids carry the new `sch_` prefix.
28
+ No SDK method calls it.
29
+
13
30
  ## [0.11.4] - 2026-09-21
14
31
 
15
32
  ### Changed
package/README.md CHANGED
@@ -358,7 +358,7 @@ try {
358
358
 
359
359
  Note that `details` is populated only from the API's canonical
360
360
  `{ error: { … } }` envelope. A few endpoints answer with a flat, vendor-masked
361
- body instead (`/v1/search` returns `502 {"error":"search_provider_error"}`);
361
+ body instead (`/v1/search` returns `503 {"error":"search_provider_error"}`);
362
362
  those carry no structured detail, so `err.details` stays `undefined` there —
363
363
  `err.code` is still the machine-readable reason.
364
364
 
package/dist/client.d.ts CHANGED
@@ -103,7 +103,7 @@ export declare class ByteKitError extends Error {
103
103
  * The envelope's `error.details`, when it carried one — `undefined` otherwise.
104
104
  *
105
105
  * Populated ONLY from the canonical `{ error: { … } }` envelope. A flat
106
- * vendor-masked body (`/v1/search` 502 `{"error":"search_provider_error"}`)
106
+ * vendor-masked body (`/v1/search` 503 `{"error":"search_provider_error"}`)
107
107
  * has no envelope to read a detail from, so it never grows one (#2685 E3).
108
108
  *
109
109
  * A `details` that is not a JSON object — which the untyped spec field
package/dist/client.js CHANGED
@@ -470,9 +470,9 @@ export class ByteKit {
470
470
  }
471
471
  }
472
472
  else if (typeof json.error === 'string' && json.error.length > 0) {
473
- // Flat vendor-masked shape, e.g. /v1/search 502
473
+ // Flat vendor-masked shape, e.g. /v1/search 503
474
474
  // {"error":"search_provider_error"} (docs/api/openapi.yaml §/v1/search
475
- // 502). The string IS the error code. `message` falls back to it only
475
+ // 503). The string IS the error code. `message` falls back to it only
476
476
  // when the response carried no statusText, so the thrown error is
477
477
  // never message-empty.
478
478
  code = json.error;
@@ -640,7 +640,8 @@ export interface paths {
640
640
  * `wait_for_selector`) cause a `400 unsupported_option`.
641
641
  *
642
642
  * Dual-axis billing: a fixed per-request credit charge **plus** the
643
- * underlying page's bandwidth, billed exactly like `/v1/scrape`. The
643
+ * underlying page's bandwidth, billed at its upstream wire bytes with no
644
+ * endpoint factor (a 100 KiB estimate is pre-charged, then reconciled). The
644
645
  * bandwidth is still billed when the scrape succeeds but extraction later
645
646
  * fails; both axes are refunded only when the scrape itself never runs.
646
647
  *
@@ -720,7 +721,7 @@ export interface paths {
720
721
  };
721
722
  /**
722
723
  * Get the unified request log feed
723
- * @description Returns a unified, newest-first feed of the account's requests across scrape, fetch, screenshots, recordings and search, plus webhook delivery attempts, for the dashboard /logs screen. Monitor runs are listed as the scrape and screenshots rows they produce (`source: monitor`). Cursor-paginated; default range is the last 30 days, max 366 days.
724
+ * @description Returns a unified, newest-first feed of the account's requests across scrape, fetch, screenshots, recordings, search and schema, plus webhook delivery attempts, for the dashboard /logs screen. Monitor runs are listed as the scrape and screenshots rows they produce (`source: monitor`). Cursor-paginated; default range is the last 30 days, max 366 days.
724
725
  */
725
726
  get: operations["getLogs"];
726
727
  put?: never;
@@ -1160,6 +1161,29 @@ export interface paths {
1160
1161
  patch?: never;
1161
1162
  trace?: never;
1162
1163
  };
1164
+ "/v1/account/complete-onboarding": {
1165
+ parameters: {
1166
+ query?: never;
1167
+ header?: never;
1168
+ path?: never;
1169
+ cookie?: never;
1170
+ };
1171
+ get?: never;
1172
+ put?: never;
1173
+ /**
1174
+ * Mark onboarding as finished
1175
+ * @description Records that the account left the dashboard's onboarding flow through one
1176
+ * of its exits, so `onboarding_completed` on GET /v1/account reads true from
1177
+ * then on. Idempotent: a repeat call keeps the first timestamp and still
1178
+ * answers 200. Requires an active membership (admin or member).
1179
+ */
1180
+ post: operations["completeOnboarding"];
1181
+ delete?: never;
1182
+ options?: never;
1183
+ head?: never;
1184
+ patch?: never;
1185
+ trace?: never;
1186
+ };
1163
1187
  "/v1/me": {
1164
1188
  parameters: {
1165
1189
  query?: never;
@@ -2704,8 +2728,10 @@ export interface components {
2704
2728
  terms_version: string;
2705
2729
  /** Format: date-time */
2706
2730
  created_at: string;
2707
- /** @description True once the account has SUCCESSFULLY COMPLETED at least one billable request (a scrape/screenshot/fetch/… that settled and was charged credits), regardless of whether it was authenticated with a Clerk session or an API key. All-time — never windowed. A request that failed does not flip it, even when its bandwidth was billed: the monitor terminal-preflight-failure path records bytes without credits, and only the credited settlement counts here. Powers the dashboard onboarding gate — the app shows the guided onboarding flow until this is true, then the dashboard. Lags by up to one usage rollup: the completion service writes the row after the response is returned, so a just-completed first request may still read false for a moment. Treat that as "not visible yet", never as "this account has never made a request". */
2731
+ /** @description True once the account has SUCCESSFULLY COMPLETED at least one billable request (a scrape/screenshot/fetch/… that settled and was charged credits), regardless of whether it was authenticated with a Clerk session or an API key. All-time — never windowed. A request that failed does not flip it, even when its bandwidth was billed: the monitor terminal-preflight-failure path records bytes without credits, and only the credited settlement counts here. Powers the dashboard onboarding gate — the app shows the guided onboarding flow until this or `onboarding_completed` is true, then the dashboard. Lags by up to one usage rollup: the completion service writes the row after the response is returned, so a just-completed first request may still read false for a moment. Treat that as "not visible yet", never as "this account has never made a request". */
2708
2732
  has_activity: boolean;
2733
+ /** @description True once a member of the account left onboarding through one of its exits (POST /v1/account/complete-onboarding). Never reset. With `has_activity` it gates the dashboard: the app shows the guided onboarding flow until either one is true, so a user whose first request failed can still reach the dashboard. */
2734
+ onboarding_completed: boolean;
2709
2735
  /** @description True when the account has a Stripe subscription, keyed on the same `stripe_subscription_id` column that GET /v1/billing/change-plan's `no_subscription` guard tests — so a client can use it to decide whether that endpoint will answer at all. Stays TRUE while a subscription is mid-cancellation (cancelled but running to the period end): the subscription still exists and a booked plan change is still revocable. It is a boolean, not the bearer path's `subscription` object: this response has no role-dependent fields, so a non-admin member receives it too, and plan pricing does not belong there. */
2710
2736
  has_subscription: boolean;
2711
2737
  };
@@ -4150,35 +4176,20 @@ export interface operations {
4150
4176
  "application/json": components["schemas"]["Error"];
4151
4177
  };
4152
4178
  };
4153
- /**
4154
- * @description Content transform failed, or a non-2xx upstream response relayed as the unified
4155
- * Error envelope. On an upstream relay the HTTP status equals the upstream status
4156
- * (code `upstream_error`), so any 4xx/5xx the target returns surfaces here as an
4157
- * Error envelope rather than a raw body (#1462).
4158
- *
4159
- * **One divergence.** An upstream `502` is relayed at HTTP `503`, not `502` — see
4160
- * the `503` response below. A fetch service that cannot be reached also answers
4161
- * `503`, not `502` (#3373); this status no longer covers that condition.
4162
- */
4163
- 502: {
4164
- headers: {
4165
- [name: string]: unknown;
4166
- };
4167
- content: {
4168
- "application/json": components["schemas"]["Error"];
4169
- };
4170
- };
4171
4179
  /**
4172
4180
  * @description Two distinct conditions answer `503`, and they disagree about what the body's
4173
4181
  * `error.http_status` reports. Read `error.code` to tell them apart.
4174
4182
  *
4175
- * - **`upstream_error`** — the target returned HTTP `502`, relayed here as `503`.
4176
- * Cloudflare fronts this API and replaces a clean origin 502 with its own generic
4177
- * `text/plain` error page, discarding the envelope before it reaches you, while a
4178
- * 503 is passed through unchanged. The body's `error.http_status` still reports
4179
- * the **true upstream status**, `502` — not `503` — and is the only surviving
4180
- * record of what the target answered, so the body rather than the HTTP status is
4181
- * authoritative here (#3355).
4183
+ * - **`upstream_error`** — the target returned HTTP `502` or `504`, relayed here as
4184
+ * `503`. Cloudflare fronts this API and replaces a clean origin 502 or 504 with its
4185
+ * own generic `text/plain` error page, discarding the envelope before it reaches
4186
+ * you, while a 503 is passed through unchanged. The body's `error.http_status`
4187
+ * still reports the **true upstream status**, `502` or `504` — not `503` — and is
4188
+ * the only surviving record of what the target answered, so the body rather than
4189
+ * the HTTP status is authoritative here (#3355, #4891). Every other non-2xx
4190
+ * upstream response is relayed at its own HTTP status with the same
4191
+ * `upstream_error` envelope, so any other 4xx/5xx the target returns surfaces as an
4192
+ * Error envelope rather than a raw body (#1462).
4182
4193
  * - **`internal_error`** (message `Fetch service unavailable.`) — no fetch service
4183
4194
  * endpoint could be resolved on this deployment, a fault of this API and not of the
4184
4195
  * target. There is no upstream status to preserve: the `503` is this API's own
@@ -4300,35 +4311,20 @@ export interface operations {
4300
4311
  "application/json": components["schemas"]["Error"];
4301
4312
  };
4302
4313
  };
4303
- /**
4304
- * @description Content transform failed, or a non-2xx upstream response relayed as the unified
4305
- * Error envelope. On an upstream relay the HTTP status equals the upstream status
4306
- * (code `upstream_error`), so any 4xx/5xx the target returns surfaces here as an
4307
- * Error envelope rather than a raw body (#1462).
4308
- *
4309
- * **One divergence.** An upstream `502` is relayed at HTTP `503`, not `502` — see
4310
- * the `503` response below. A fetch service that cannot be reached also answers
4311
- * `503`, not `502` (#3373); this status no longer covers that condition.
4312
- */
4313
- 502: {
4314
- headers: {
4315
- [name: string]: unknown;
4316
- };
4317
- content: {
4318
- "application/json": components["schemas"]["Error"];
4319
- };
4320
- };
4321
4314
  /**
4322
4315
  * @description Two distinct conditions answer `503`, and they disagree about what the body's
4323
4316
  * `error.http_status` reports. Read `error.code` to tell them apart.
4324
4317
  *
4325
- * - **`upstream_error`** — the target returned HTTP `502`, relayed here as `503`.
4326
- * Cloudflare fronts this API and replaces a clean origin 502 with its own generic
4327
- * `text/plain` error page, discarding the envelope before it reaches you, while a
4328
- * 503 is passed through unchanged. The body's `error.http_status` still reports
4329
- * the **true upstream status**, `502` — not `503` — and is the only surviving
4330
- * record of what the target answered, so the body rather than the HTTP status is
4331
- * authoritative here (#3355).
4318
+ * - **`upstream_error`** — the target returned HTTP `502` or `504`, relayed here as
4319
+ * `503`. Cloudflare fronts this API and replaces a clean origin 502 or 504 with its
4320
+ * own generic `text/plain` error page, discarding the envelope before it reaches
4321
+ * you, while a 503 is passed through unchanged. The body's `error.http_status`
4322
+ * still reports the **true upstream status**, `502` or `504` — not `503` — and is
4323
+ * the only surviving record of what the target answered, so the body rather than
4324
+ * the HTTP status is authoritative here (#3355, #4891). Every other non-2xx
4325
+ * upstream response is relayed at its own HTTP status with the same
4326
+ * `upstream_error` envelope, so any other 4xx/5xx the target returns surfaces as an
4327
+ * Error envelope rather than a raw body (#1462).
4332
4328
  * - **`internal_error`** (message `Fetch service unavailable.`) — no fetch service
4333
4329
  * endpoint could be resolved on this deployment, a fault of this API and not of the
4334
4330
  * target. There is no upstream status to preserve: the `503` is this API's own
@@ -4474,7 +4470,7 @@ export interface operations {
4474
4470
  /** @example bulk_01j9abc123 */
4475
4471
  id: string;
4476
4472
  /** @enum {string} */
4477
- status: "processing" | "completed" | "failed";
4473
+ status: "processing" | "completed" | "failed" | "cancelled";
4478
4474
  total: number;
4479
4475
  completed: number;
4480
4476
  failed: number;
@@ -4547,11 +4543,12 @@ export interface operations {
4547
4543
  };
4548
4544
  };
4549
4545
  /**
4550
- * @description Bulk job still processing. `routes/fetch-bulk.ts` ends the poll handler
4551
- * with `status: isTerminal ? 200 : 202` over an identical body, so this is
4552
- * the SAME envelope the 200 documents — only the status code and the
4553
- * reachable `status` values differ. Keep polling until you get a 200; a
4554
- * **cancelled** job stays on this branch forever (issue #3533).
4546
+ * @description Bulk job still processing. The poll answers 200 for a job in
4547
+ * `BULK_TERMINAL_STATUSES` (`completed`, `failed`, `cancelled`) and 202
4548
+ * otherwise, over an identical body, so this is the SAME envelope the 200
4549
+ * documents — only the status code and the reachable `status` values
4550
+ * differ. Keep polling until you get a 200; a **cancelled** job is served
4551
+ * 200, not 202 (issues #3533, #4754).
4555
4552
  *
4556
4553
  * Item `content_url` values are pre-signed exactly as on the 200 — a fresh
4557
4554
  * 600-second signature on every poll.
@@ -4565,7 +4562,7 @@ export interface operations {
4565
4562
  /** @example bulk_01j9abc123 */
4566
4563
  id: string;
4567
4564
  /** @enum {string} */
4568
- status: "processing" | "cancelled";
4565
+ status: "processing";
4569
4566
  total: number;
4570
4567
  completed: number;
4571
4568
  failed: number;
@@ -5711,13 +5708,14 @@ export interface operations {
5711
5708
  };
5712
5709
  };
5713
5710
  /**
5714
- * @description Upstream search provider error. The body is a fixed,
5711
+ * @description Upstream search provider error, answered at `503` rather than `502` because
5712
+ * Cloudflare replaces an origin 502 body with its own page (#4891). The body is a fixed,
5715
5713
  * vendor-masked shape — deliberately NOT the unified `Error`
5716
5714
  * envelope. The upstream provider's identity and message are
5717
5715
  * never surfaced, so the response carries only the constant
5718
5716
  * `error` code `search_provider_error`.
5719
5717
  */
5720
- 502: {
5718
+ 503: {
5721
5719
  headers: {
5722
5720
  [name: string]: unknown;
5723
5721
  };
@@ -5877,16 +5875,15 @@ export interface operations {
5877
5875
  "application/json": components["schemas"]["Error"];
5878
5876
  };
5879
5877
  };
5880
- /** @description Underlying scrape failed (`scrape_failed`) or upstream provider error (`provider_error`). */
5881
- 502: {
5882
- headers: {
5883
- [name: string]: unknown;
5884
- };
5885
- content: {
5886
- "application/json": components["schemas"]["Error"];
5887
- };
5888
- };
5889
- /** @description Extraction provider unconfigured (`provider_unavailable`). */
5878
+ /**
5879
+ * @description Read `error.code` to tell the conditions apart: underlying scrape failed or the
5880
+ * extraction service was unreachable (`scrape_failed`), upstream provider error
5881
+ * (`provider_error`), extraction provider unconfigured (`provider_unavailable`), or
5882
+ * upstream provider timed out (`provider_timeout`). None of these answers `502` or
5883
+ * `504`: Cloudflare fronts this API and replaces an origin 502 or 504 with its own
5884
+ * `text/plain` page, discarding the error envelope, while a 503 passes through
5885
+ * unchanged (#4891).
5886
+ */
5890
5887
  503: {
5891
5888
  headers: {
5892
5889
  [name: string]: unknown;
@@ -5895,15 +5892,6 @@ export interface operations {
5895
5892
  "application/json": components["schemas"]["Error"];
5896
5893
  };
5897
5894
  };
5898
- /** @description Upstream provider timed out (`provider_timeout`). */
5899
- 504: {
5900
- headers: {
5901
- [name: string]: unknown;
5902
- };
5903
- content: {
5904
- "application/json": components["schemas"]["Error"];
5905
- };
5906
- };
5907
5895
  };
5908
5896
  };
5909
5897
  getUsage: {
@@ -6106,7 +6094,7 @@ export interface operations {
6106
6094
  /** @description End date (YYYY-MM-DD), inclusive. Default today. */
6107
6095
  to?: string;
6108
6096
  /** @description Filter to a single endpoint kind. */
6109
- endpoint?: "scrape" | "fetch" | "screenshots" | "recordings" | "search" | "webhook";
6097
+ endpoint?: "scrape" | "fetch" | "screenshots" | "recordings" | "search" | "webhook" | "schema";
6110
6098
  /** @description Filter by job outcome. */
6111
6099
  status?: "pending" | "processing" | "completed" | "failed";
6112
6100
  /** @description Case-insensitive substring match on the request URL — the search query on search rows and the target URL on webhook rows. */
@@ -6132,13 +6120,13 @@ export interface operations {
6132
6120
  content: {
6133
6121
  "application/json": {
6134
6122
  data: {
6135
- /** @description Prefixed request id (sc_/ss_/rec_/sr_/wh_). */
6123
+ /** @description Prefixed request id (sc_/ss_/rec_/sr_/wh_/sch_). */
6136
6124
  id: string;
6137
6125
  /**
6138
- * @description The request kind. `webhook` rows are webhook delivery attempts ByteKit sent to your endpoint, not requests you made.
6126
+ * @description The request kind. `webhook` rows are webhook delivery attempts ByteKit sent to your endpoint, not requests you made. `schema` rows are /v1/schema structured-extraction requests.
6139
6127
  * @enum {string}
6140
6128
  */
6141
- endpoint: "scrape" | "fetch" | "screenshots" | "recordings" | "search" | "webhook";
6129
+ endpoint: "scrape" | "fetch" | "screenshots" | "recordings" | "search" | "webhook" | "schema";
6142
6130
  /** @description HTTP method. Not persisted; capture and search endpoints are POST, and webhook deliveries are sent as POST (so this is always "POST"). /v1/fetch also accepts GET, but the stored row cannot distinguish it. */
6143
6131
  method: string;
6144
6132
  /** @description The request URL. On a search row this is the search query (empty once the retention window has redacted it); on a webhook row it is the delivery target URL. */
@@ -6149,17 +6137,17 @@ export interface operations {
6149
6137
  * @enum {string}
6150
6138
  */
6151
6139
  status: "pending" | "processing" | "completed" | "failed";
6152
- /** @description Upstream target HTTP status on scrape/fetch rows; the HTTP status your endpoint answered on webhook rows. null on every other row. */
6140
+ /** @description Upstream target HTTP status on scrape/fetch rows, and the target site's HTTP status on completed schema and screenshot rows (null when none was recorded); the HTTP status your endpoint answered on webhook rows. null on every other row. */
6153
6141
  status_code?: number | null;
6154
- /** @description Raw upstream bytes the request carried (the billing base before the multiplier). null while pending/failed. */
6142
+ /** @description Raw upstream bytes the request carried (the billing base before the multiplier). null while pending/failed, and always null on search, webhook and schema rows. */
6155
6143
  raw_bytes?: number | null;
6156
- /** @description The bytes this request was BILLED — the same amount its own response reported in `X-Billable-Bytes`. For a scrape or fetch request this is the settled decomposition replayed as it was recorded at completion, so it already carries every factor that applied: the endpoint factor (`scrape` 1.0, `scrape_md` 1.5, `fetch` 1.0, `fetch_md` 1.5, a monitor run 1.0), the cache-hit ×0.5, and the clean-markdown ×3. Screenshots and recordings are `raw_bytes` × the fixed 1.5 Phase-1 render factor whatever capture options they carried — capture billing composes no discount factor, so that product is exact. This is the settled amount itself, never a product reconstructed from another field: `billing_multiplier` below is DERIVED from it (that field is this value over `raw_bytes`), so the dependency runs this way and not the other. One residual: a scrape or fetch row completed before the decomposition was recorded is reconstructed from its endpoint and cache-hit factors, which leaves a markdown `/v1/fetch` request of that vintage reported at 1.0 rather than 1.5 — nothing on such a row distinguishes it. That population ages out of this feed's retention window and is not backfilled. null while pending/failed (the row has no byte basis yet). */
6144
+ /** @description The bytes this request was BILLED — the same amount its own response reported in `X-Billable-Bytes`. For a scrape or fetch request this is the settled decomposition replayed as it was recorded at completion, so it already carries every factor that applied: the endpoint factor (`scrape` 1.0, `scrape_md` 1.5, `fetch` 1.0, `fetch_md` 1.5, a monitor run 1.0), the cache-hit ×0.5, and the clean-markdown ×3. Screenshots and recordings are `raw_bytes` × the fixed 1.5 Phase-1 render factor whatever capture options they carried — capture billing composes no discount factor, so that product is exact. This is the settled amount itself, never a product reconstructed from another field: `billing_multiplier` below is DERIVED from it (that field is this value over `raw_bytes`), so the dependency runs this way and not the other. One residual: a scrape or fetch row completed before the decomposition was recorded is reconstructed from its endpoint and cache-hit factors, which leaves a markdown `/v1/fetch` request of that vintage reported at 1.0 rather than 1.5 — nothing on such a row distinguishes it. That population ages out of this feed's retention window and is not backfilled. null while pending/failed (the row has no byte basis yet). On a schema row this is the byte amount the request settled at, recorded when it ended: 0 where the charge was refunded, null where it is unknown. */
6157
6145
  billable_bytes?: number | null;
6158
- /** @description The bandwidth factor this request settled at, DERIVED from the two fields above as `billable_bytes` / `raw_bytes`, ROUNDED TO 2 DECIMAL PLACES. It carries every factor that applied to the settled amount, composed: the endpoint factor, the cache-hit ×0.5 and the clean-markdown ×3 on a scrape or fetch row, and the flat 1.5 Phase-1 render factor on every screenshot and recording row whatever capture options it carried. Every factor reachable that way is a multiple of 0.25 (0.5, 0.75, 1, 1.5, 2.25, 3, 4.5), so 2 places reports each of them exactly on any basis of 100 bytes or more. The rounding is there because `billable_bytes` is itself rounded, which on an odd basis would otherwise surface here as 1.500001943158721 rather than 1.5. `raw_bytes` × `billing_multiplier`, rounded to the nearest byte, reproduces `billable_bytes` at every basis. CHANGED: this field used to report the row's persisted `credits_charged` — an account CREDIT count on a per-endpoint scale, not a bandwidth factor. On a screenshot that count is charged per capture option (`full_page`, `mobile`), so two captures billed at the same 1.5 factor reported different multipliers. See https://bytekit.com/docs/billing/credits for the credit counts each endpoint charges, which this field no longer reports. This is a LOGS ROW field and is NOT the scrape response envelope field — the envelope carries no flat `billing_multiplier` at all; its billing surface is the `billing` node (see BillingNode). It reports the same composed value as `billing.multiplier` and the X-Billing-Multiplier response header wherever `billable_bytes` is exact, which is every row but one: the residual described above for `billable_bytes`, a markdown `/v1/fetch` request completed before the decomposition was recorded, is reconstructed at 1.0 where settlement charged 1.5, and this field reports that same 1.0. null where the row has no factor to report: while pending/failed; on a search or webhook row (neither has a byte basis); where the basis is zero because Phase 1 was skipped or failed and the request billed nothing; and on a completed screenshot or recording old enough that no Phase-1 basis was ever recorded for it, which reports null rather than claiming a real past charge was nothing. */
6146
+ /** @description The bandwidth factor this request settled at, DERIVED from the two fields above as `billable_bytes` / `raw_bytes`, ROUNDED TO 2 DECIMAL PLACES. It carries every factor that applied to the settled amount, composed: the endpoint factor, the cache-hit ×0.5 and the clean-markdown ×3 on a scrape or fetch row, and the flat 1.5 Phase-1 render factor on every screenshot and recording row whatever capture options it carried. Every factor reachable that way is a multiple of 0.25 (0.5, 0.75, 1, 1.5, 2.25, 3, 4.5), so 2 places reports each of them exactly on any basis of 100 bytes or more. The rounding is there because `billable_bytes` is itself rounded, which on an odd basis would otherwise surface here as 1.500001943158721 rather than 1.5. `raw_bytes` × `billing_multiplier`, rounded to the nearest byte, reproduces `billable_bytes` at every basis. CHANGED: this field used to report the row's persisted `credits_charged` — an account CREDIT count on a per-endpoint scale, not a bandwidth factor. On a screenshot that count is charged per capture option (`full_page`, `mobile`), so two captures billed at the same 1.5 factor reported different multipliers. See https://bytekit.com/docs/billing/credits for the credit counts each endpoint charges, which this field no longer reports. This is a LOGS ROW field and is NOT the scrape response envelope field — the envelope carries no flat `billing_multiplier` at all; its billing surface is the `billing` node (see BillingNode). It reports the same composed value as `billing.multiplier` and the X-Billing-Multiplier response header wherever `billable_bytes` is exact, which is every row but one: the residual described above for `billable_bytes`, a markdown `/v1/fetch` request completed before the decomposition was recorded, is reconstructed at 1.0 where settlement charged 1.5, and this field reports that same 1.0. null where the row has no factor to report: while pending/failed; on a search, webhook or schema row (none has a raw byte basis); where the basis is zero because Phase 1 was skipped or failed and the request billed nothing; and on a completed screenshot or recording old enough that no Phase-1 basis was ever recorded for it, which reports null rather than claiming a real past charge was nothing. */
6159
6147
  billing_multiplier?: number | null;
6160
6148
  /** @description Request duration in milliseconds; on a webhook row, how long your endpoint took to answer the latest attempt. */
6161
6149
  duration_ms?: number | null;
6162
- /** @description How the request originated (single/bulk/monitor). null on search and webhook rows. */
6150
+ /** @description How the request originated (single/bulk/monitor). null on search, webhook and schema rows. */
6163
6151
  source?: string | null;
6164
6152
  error_code?: string | null;
6165
6153
  error_message?: string | null;
@@ -6167,7 +6155,7 @@ export interface operations {
6167
6155
  api_key_id?: string | null;
6168
6156
  /** @description Stored content, image or video URL. For a `completed` row with a non-empty storage key this is a **pre-signed** download URL, minted fresh on every read of this endpoint and valid for **600 seconds (10 minutes)** — the same signing lifetime as `content_url` on `GET /v1/fetch/bulk/{id}` and `image_url` on `GET /v1/bulk/{id}/screenshots`. Download inside that window, or re-poll this endpoint for a fresh signature. For every other row the stored value is returned unchanged — `null` while no object has been stored, and otherwise a private, unsigned storage URL that returns 401 on download. That covers rows that are not `completed`, completed rows with no storage key, and completed rows whose object could not be signed; this endpoint raises no `artifact_unavailable` signal for any of them. */
6169
6157
  artifact_url?: string | null;
6170
- /** @description The original request options. */
6158
+ /** @description The original request options. Empty on schema rows: the schema, prompt and extraction result are not stored. */
6171
6159
  options?: {
6172
6160
  [key: string]: unknown;
6173
6161
  } | null;
@@ -6375,8 +6363,8 @@ export interface operations {
6375
6363
  "application/json": components["schemas"]["Error"];
6376
6364
  };
6377
6365
  };
6378
- /** @description Stripe error creating the Checkout session. */
6379
- 502: {
6366
+ /** @description Stripe error creating the Checkout session (`stripe_error`). Answered at `503`, not `502`, because Cloudflare replaces an origin 502 body with its own page (#4891). */
6367
+ 503: {
6380
6368
  headers: {
6381
6369
  [name: string]: unknown;
6382
6370
  };
@@ -6447,8 +6435,8 @@ export interface operations {
6447
6435
  "application/json": components["schemas"]["Error"];
6448
6436
  };
6449
6437
  };
6450
- /** @description The Stripe subscription schedule could not be read. */
6451
- 502: {
6438
+ /** @description The Stripe subscription schedule could not be read (`stripe_error`). Answered at `503`, not `502`, because Cloudflare replaces an origin 502 body with its own page (#4891). */
6439
+ 503: {
6452
6440
  headers: {
6453
6441
  [name: string]: unknown;
6454
6442
  };
@@ -6845,8 +6833,8 @@ export interface operations {
6845
6833
  "application/json": components["schemas"]["Error"];
6846
6834
  };
6847
6835
  };
6848
- /** @description Stripe API error. */
6849
- 502: {
6836
+ /** @description Stripe API error (`stripe_error`). Answered at `503`, not `502`, because Cloudflare replaces an origin 502 body with its own page (#4891). */
6837
+ 503: {
6850
6838
  headers: {
6851
6839
  [name: string]: unknown;
6852
6840
  };
@@ -7142,6 +7130,47 @@ export interface operations {
7142
7130
  };
7143
7131
  };
7144
7132
  };
7133
+ completeOnboarding: {
7134
+ parameters: {
7135
+ query?: never;
7136
+ header?: never;
7137
+ path?: never;
7138
+ cookie?: never;
7139
+ };
7140
+ requestBody?: never;
7141
+ responses: {
7142
+ /** @description Onboarding marked as finished. */
7143
+ 200: {
7144
+ headers: {
7145
+ [name: string]: unknown;
7146
+ };
7147
+ content: {
7148
+ "application/json": {
7149
+ /** @enum {boolean} */
7150
+ onboarding_completed: true;
7151
+ };
7152
+ };
7153
+ };
7154
+ /** @description Missing or invalid Clerk JWT. */
7155
+ 401: {
7156
+ headers: {
7157
+ [name: string]: unknown;
7158
+ };
7159
+ content: {
7160
+ "application/json": components["schemas"]["Error"];
7161
+ };
7162
+ };
7163
+ /** @description Session has no active account membership. */
7164
+ 403: {
7165
+ headers: {
7166
+ [name: string]: unknown;
7167
+ };
7168
+ content: {
7169
+ "application/json": components["schemas"]["Error"];
7170
+ };
7171
+ };
7172
+ };
7173
+ };
7145
7174
  getMe: {
7146
7175
  parameters: {
7147
7176
  query?: never;
package/dist/version.d.ts CHANGED
@@ -5,4 +5,4 @@
5
5
  * outbound request carries — see the emit site in `client.ts`. The header name is spelled
6
6
  * only there, so issue #2905's pre-merge gate 1 counts exactly one occurrence in `src/`.
7
7
  */
8
- export declare const SDK_VERSION = "0.11.4";
8
+ export declare const SDK_VERSION = "0.11.6";
package/dist/version.js CHANGED
@@ -9,4 +9,4 @@
9
9
  * outbound request carries — see the emit site in `client.ts`. The header name is spelled
10
10
  * only there, so issue #2905's pre-merge gate 1 counts exactly one occurrence in `src/`.
11
11
  */
12
- export const SDK_VERSION = '0.11.4';
12
+ export const SDK_VERSION = '0.11.6';
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@hunt-labs/bytekit-sdk",
3
- "version": "0.11.4",
3
+ "version": "0.11.6",
4
4
  "description": "Official TypeScript SDK for the ByteKit API",
5
5
  "license": "MIT",
6
6
  "type": "module",