@hunt-labs/bytekit-sdk 0.9.3 → 0.11.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.
@@ -194,7 +194,17 @@ export interface paths {
194
194
  put?: never;
195
195
  /**
196
196
  * Scrape a URL
197
- * @description Fetches and processes a URL, returning content in one or more formats wrapped in a ScrapeEnvelope. Most requests return synchronously in under a second; requests needing a full page render return HTTP 202 and complete asynchronously.
197
+ * @description Fetches and processes a URL, returning content in one or more formats wrapped in a ScrapeEnvelope.
198
+ *
199
+ * **The response shape is decided by your request, not by how we route it.** In precedence order:
200
+ *
201
+ * 1. `async: true` → **202** with a `ScrapeQueuedEnvelope` receipt, returned immediately. Poll `GET /v1/scrape/{id}` for the result.
202
+ * 2. Otherwise, a request that needs a full page render — today that is `delay_ms > 0` — is **held open** until the render reaches a terminal state, then returns **200** with the content envelope (`success` or `failed`). If the render is still running when the hold window expires (28 seconds by default), the request returns the **202** receipt instead and the job continues in the background.
203
+ * 3. Otherwise the request is served by the fast HTTP path and returns **200** with the content envelope, typically in under a second.
204
+ *
205
+ * **A failed fetch is a result, not a transport error.** An unreachable host, a refused connection, or a target whose bot protection defeats every proxy tier all come back on the same **200** as a `failed` envelope — never a 5xx. Narrow on the envelope's `status` before reading the body. A failure the fast path decides inline is recorded as a failed job, so its envelope normally carries that job's `id` and `GET /v1/scrape/{id}` returns the same envelope; if recording the failed job itself fails, the envelope still arrives on the same 200 with `id` set to `null` and there is nothing to poll. A failure a held render reaches carries that render's real `id`. Either way the request transfers no billable bytes and is charged nothing.
206
+ *
207
+ * So a 202 means one of exactly two things: you asked for one with `async: true`, or the hold window expired. `wait_for_selector` and `wait_until` are `ScreenshotRequest` options, not `ScrapeRequest` options — sending either to this endpoint returns `422 validation_error`, so neither can produce a 202 here.
198
208
  */
199
209
  post: operations["createScrape"];
200
210
  delete?: never;
@@ -235,9 +245,10 @@ export interface paths {
235
245
  /**
236
246
  * Bulk scrape URLs
237
247
  * @description Enqueues multiple URLs for scraping. Results delivered via webhook.
238
- * Webhook deliveries include `X-ByteKit-Event: scrape.completed` or
239
- * `X-ByteKit-Event: scrape.failed` so receivers can dispatch on the
240
- * header without parsing the body shape.
248
+ * Completion deliveries use `X-ByteKit-Event: bulk.completed` and the
249
+ * `BulkCompletedWebhook` contract: at most 500 complete items and 1 MiB,
250
+ * followed by cursor recovery through `GET /v1/scrape/bulk/{id}` whenever
251
+ * `recovery_required` is true.
241
252
  */
242
253
  post: operations["createScrapeBulk"];
243
254
  delete?: never;
@@ -253,7 +264,20 @@ export interface paths {
253
264
  path?: never;
254
265
  cookie?: never;
255
266
  };
256
- /** Get scrape bulk job status */
267
+ /**
268
+ * Get scrape bulk job status
269
+ * @description Returns the job envelope plus its rehydrated per-URL scrape envelopes.
270
+ *
271
+ * **Downloading item content.** A `raw` or `markdown` artifact within the
272
+ * 10-MiB inline cap is returned inline. An oversized one is replaced by a
273
+ * **pre-signed** URL, minted fresh on every read of this endpoint and valid
274
+ * for **86400 seconds (24 hours)**. The underlying objects are private, so an
275
+ * unsigned URL returns `401`: download the content inside that window, or
276
+ * re-poll this endpoint for a fresh signature. An artifact that was never
277
+ * stored, or whose object cannot be signed, is omitted from `formats` and
278
+ * reported as `artifact_unavailable` in `warnings`. The private unsigned
279
+ * storage URL is never returned.
280
+ */
257
281
  get: operations["getScrapeBulk"];
258
282
  put?: never;
259
283
  post?: never;
@@ -305,6 +329,10 @@ export interface paths {
305
329
  * Bulk fetch URLs
306
330
  * @description Enqueues multiple URLs for HTTP fetching. Results delivered via webhook.
307
331
  * Does not support options that require page rendering (wait_for_selector, etc.).
332
+ * Completion deliveries use `X-ByteKit-Event: bulk.completed` and the
333
+ * `BulkCompletedWebhook` contract: at most 500 complete items and 1 MiB,
334
+ * followed by cursor recovery through `GET /v1/fetch/bulk/{id}` whenever
335
+ * `recovery_required` is true.
308
336
  *
309
337
  * **Limits:** request bodies are guarded in a two-tier shape. A streamed body
310
338
  * with no `Content-Length` header is capped at 2 MB before your API key
@@ -342,7 +370,9 @@ export interface paths {
342
370
  * objects are private, so an unsigned URL returns `401`: download the
343
371
  * content inside that window, or re-poll this endpoint for a fresh
344
372
  * signature. Items that are not `completed`, and completed items with no
345
- * stored object, carry `null` or the unsigned stored URL instead.
373
+ * stored object, or completed items whose object cannot be signed, carry
374
+ * `null`; the latter report `artifact_unavailable`. The private unsigned
375
+ * storage URL is never returned.
346
376
  */
347
377
  get: operations["getFetchBulk"];
348
378
  put?: never;
@@ -361,9 +391,13 @@ export interface paths {
361
391
  cookie?: never;
362
392
  };
363
393
  /**
364
- * List in-flight bulk jobs
365
- * @description Returns the caller's bulk jobs, most recent first. Optionally filter
366
- * to a single status; when omitted, jobs of every status are returned.
394
+ * List bulk jobs
395
+ * @description Returns the caller's bulk jobs, most recent first, one cursor-paginated
396
+ * page at a time. Optionally filter to a single status; when omitted, jobs
397
+ * of every status are returned. `status` narrows the set and the cursor
398
+ * addresses a position inside that already-ordered, already-filtered set,
399
+ * so the two can be combined in one request. Follow `next_cursor` while
400
+ * `has_more` is true.
367
401
  */
368
402
  get: operations["listBulk"];
369
403
  put?: never;
@@ -373,6 +407,9 @@ export interface paths {
373
407
  * Provide `urls` (simple list) or `items` (per-item config), not both.
374
408
  * Webhook deliveries include `X-ByteKit-Event: bulk.completed` so
375
409
  * receivers can dispatch on the header without parsing the body shape.
410
+ * The body follows `BulkCompletedWebhook`: at most 500 complete items and
411
+ * 1 MiB, followed by cursor recovery through the existing mixed-item route
412
+ * whenever `recovery_required` is true.
376
413
  *
377
414
  * **Limits:** request bodies are guarded in a two-tier shape. A streamed body
378
415
  * with no `Content-Length` header is capped at 4 MB before your API key
@@ -424,15 +461,25 @@ export interface paths {
424
461
  * List bulk job items
425
462
  * @description Returns the bulk job's items, discriminated by `type`.
426
463
  *
427
- * **Downloading item artifacts.** `image_url` (`type: screenshot`) and both
428
- * `content_url` and `markdown_url` (`type: scrape`) are **pre-signed** URLs,
429
- * minted fresh on every read of this endpoint and valid for **600 seconds
430
- * (10 minutes)** —
464
+ * **Downloading item artifacts.** For a `completed` item with a storage key,
465
+ * `image_url` (`type: screenshot`) and both `content_url` and `markdown_url`
466
+ * (`type: scrape`) are **pre-signed** URLs, minted fresh on every read of
467
+ * this endpoint and valid for **600 seconds (10 minutes)** —
431
468
  * the same signing lifetime as `content_url` on `GET /v1/fetch/bulk/{id}`.
432
- * The underlying objects are private, so an unsigned URL returns `401`:
433
- * download inside that window, or re-poll this endpoint for a fresh
434
- * signature. Items that are not `completed`, and completed items with no
435
- * stored object, carry `null` or the unsigned stored URL instead.
469
+ * Download inside that window, or re-poll this endpoint for a fresh
470
+ * signature.
471
+ *
472
+ * **When no signature is minted.** Three cases mint none: an item that is not
473
+ * `completed`, a `completed` item with no storage key, and a `completed` item
474
+ * whose object could not be signed — during an object-storage outage, for
475
+ * instance. In all three the item's stored value is returned unchanged: `null`
476
+ * while nothing has been stored, and otherwise a **private, unsigned**
477
+ * object-storage URL that answers `401`. These fields are neither nulled nor
478
+ * flagged in that case, so treat an artifact URL as usable only once you have
479
+ * downloaded it, and re-poll for a fresh signature otherwise.
480
+ * `artifact_warnings` and its `artifact_unavailable` code describe the sibling
481
+ * `artifacts` object on `type: scrape` items only — they say nothing about
482
+ * `image_url`, `content_url`, or `markdown_url`.
436
483
  */
437
484
  get: operations["listBulkScreenshots"];
438
485
  put?: never;
@@ -673,7 +720,7 @@ export interface paths {
673
720
  };
674
721
  /**
675
722
  * Get the unified request log feed
676
- * @description Returns a unified, newest-first feed of the account's capture requests across scrape, fetch, screenshots, and recordings, for the dashboard /logs screen. Cursor-paginated; default range is the last 30 days, max 366 days.
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.
677
724
  */
678
725
  get: operations["getLogs"];
679
726
  put?: never;
@@ -752,11 +799,13 @@ export interface paths {
752
799
  get?: never;
753
800
  put?: never;
754
801
  /**
755
- * One-time bandwidth purchase
756
- * @description Creates a hosted Stripe Checkout session for a bandwidth top-up and
757
- * returns its URL. The caller redirects the user to `checkout_url`; the
758
- * balance is credited asynchronously by the `payment_intent.succeeded`
759
- * webhook once payment completes.
802
+ * One-time dollar deposit
803
+ * @description Creates a hosted Stripe Checkout session for a deposit into the account's
804
+ * USD balance and returns its URL. The caller redirects the user to
805
+ * `checkout_url`; the balance is credited asynchronously by the
806
+ * `payment_intent.succeeded` webhook once payment completes. The balance
807
+ * never expires and pays for usage beyond the included allowance, for
808
+ * bandwidth and search credits alike, at the plan's rate when it is used.
760
809
  */
761
810
  post: operations["createTopup"];
762
811
  delete?: never;
@@ -765,29 +814,6 @@ export interface paths {
765
814
  patch?: never;
766
815
  trace?: never;
767
816
  };
768
- "/v1/billing/credit-topup": {
769
- parameters: {
770
- query?: never;
771
- header?: never;
772
- path?: never;
773
- cookie?: never;
774
- };
775
- get?: never;
776
- put?: never;
777
- /**
778
- * One-time credit purchase
779
- * @description Creates a hosted Stripe Checkout session for a credit top-up and returns
780
- * its URL. The caller redirects the user to `checkout_url`; credits are
781
- * added asynchronously by the `payment_intent.succeeded` webhook once
782
- * payment completes.
783
- */
784
- post: operations["createCreditTopup"];
785
- delete?: never;
786
- options?: never;
787
- head?: never;
788
- patch?: never;
789
- trace?: never;
790
- };
791
817
  "/v1/billing/cancel": {
792
818
  parameters: {
793
819
  query?: never;
@@ -881,8 +907,9 @@ export interface paths {
881
907
  get?: never;
882
908
  /**
883
909
  * Configure auto-topup
884
- * @description Enable or disable automatic bandwidth top-ups. When enabling,
885
- * threshold_bytes, amount_bytes, and monthly_cap_cents are all required.
910
+ * @description Enable or disable automatic top-ups of the USD balance. When enabling,
911
+ * threshold_cents, amount_cents, and monthly_cap_cents must all be present;
912
+ * monthly_cap_cents may be null, which means no monthly cap.
886
913
  */
887
914
  put: operations["updateAutoTopup"];
888
915
  post?: never;
@@ -1413,6 +1440,95 @@ export interface components {
1413
1440
  details?: unknown;
1414
1441
  };
1415
1442
  };
1443
+ /**
1444
+ * @description Item-local terminal artifact failure. The item's stable id remains usable for paginated recovery, but the requested stored content or signed reference could not be produced. Wherever this code is raised the URL field it describes is `null`; a private object-storage URL is never returned as a substitute for it. Endpoints that do not raise this code document their own fallback — see `image_url` on `GET /v1/bulk/{id}/screenshots`.
1445
+ *
1446
+ * REFERENCE DOCUMENTATION ONLY (#4340). No operation `$ref`s this schema and no response ever carries an object of this shape, so no client model is generated from it and no SDK re-exports it. On the wire the value appears as the FLAT `error_code` / `error_message` fields on a bulk list item — `GET /v1/fetch/bulk/{id}`, `GET /v1/bulk/{id}/screenshots` — and on the `items[]` entries of the `bulk.completed` webhook body, never as a nested `{ code, message }` object. This schema names the `artifact_unavailable` code and the contract that goes with it; the two properties below describe that code and message, not a wire envelope.
1447
+ */
1448
+ BulkArtifactUnavailableError: {
1449
+ /** @enum {string} */
1450
+ code: "artifact_unavailable";
1451
+ message: string;
1452
+ };
1453
+ /** @description Mandatory bounded scrape record emitted when the ordinary rehydrated envelope cannot fit within the 16-MiB page bound. The stable item identity and terminal outcome always remain available; bounded signed references and failure detail are included when they fit. */
1454
+ BulkMandatoryScrapeItem: {
1455
+ id: string;
1456
+ /** @enum {string} */
1457
+ type: "scrape";
1458
+ /** @enum {string} */
1459
+ terminal_outcome: "pending" | "processing" | "completed" | "failed" | "cancelled";
1460
+ /** Format: uri */
1461
+ url: string;
1462
+ /** @description Bounded signed references retained from the ordinary scrape envelope. Only the formats the job requested are present; the key set is the `/v1/scrape` format vocabulary. */
1463
+ formats?: {
1464
+ raw?: string | null;
1465
+ markdown?: string | null;
1466
+ links?: null | (string | components["schemas"]["ScrapeScoredLink"])[];
1467
+ images?: null | (string | components["schemas"]["ScrapeScoredImage"])[];
1468
+ };
1469
+ error?: {
1470
+ code: string;
1471
+ message: string | null;
1472
+ /** Format: date-time */
1473
+ failed_at: string | null;
1474
+ };
1475
+ };
1476
+ /** @description Whole-job counters. These do not reset or shrink with the current page. */
1477
+ BulkJobCounters: {
1478
+ total: number;
1479
+ completed: number;
1480
+ failed: number;
1481
+ };
1482
+ /**
1483
+ * @description Customer body for `X-ByteKit-Event: bulk.completed`. Delivery is bounded to
1484
+ * 500 complete items and 1 MiB of customer-visible JSON, stopping only between
1485
+ * items. When either item coverage or artifact coverage is incomplete, follow
1486
+ * `recovery_url` with cursor pagination; stable `bulk_id` plus each item `id`
1487
+ * supports idempotent processing after duplicate, delayed, or retried delivery.
1488
+ */
1489
+ BulkCompletedWebhook: {
1490
+ bulk_id: string;
1491
+ /** @enum {string} */
1492
+ status: "completed";
1493
+ total: number;
1494
+ completed: number;
1495
+ failed: number;
1496
+ total_credits_charged: number;
1497
+ /** Format: uri */
1498
+ webhook_url: string;
1499
+ /** @description Complete item records included before the 500-item or 1-MiB manifest bound. Every record carries a stable `id`, a `type`, and a terminal `status`. */
1500
+ items: ({
1501
+ /** @description Stable prefixed item id; deduplicate with `bulk_id` plus this id. */
1502
+ id: string;
1503
+ /** @enum {string} */
1504
+ type: "fetch" | "scrape" | "screenshot" | "recording";
1505
+ /** @enum {string} */
1506
+ status: "success" | "completed" | "failed" | "cancelled";
1507
+ /** @description May be `artifact_unavailable` when no usable result reference exists. */
1508
+ error_code?: string | null;
1509
+ error_message?: string | null;
1510
+ /** @description Present and true when the manifest bounded a long error message. */
1511
+ error_message_truncated?: boolean;
1512
+ } & {
1513
+ [key: string]: unknown;
1514
+ })[];
1515
+ /** @enum {string} */
1516
+ recovery_api: "fetch" | "scrape" | "mixed";
1517
+ /**
1518
+ * @description Existing paginated result-recovery path for this job.
1519
+ * @example /v1/fetch/bulk/bulk_01j9abc123
1520
+ */
1521
+ recovery_url: string;
1522
+ manifest_item_count: number;
1523
+ /** @description True when every terminal job item is present in this webhook body. */
1524
+ manifest_items_complete: boolean;
1525
+ /** @description True when every included completed item has a usable artifact or reference. */
1526
+ manifest_artifacts_complete: boolean;
1527
+ /** @description True only when both item and artifact coverage are complete. */
1528
+ manifest_complete: boolean;
1529
+ /** @description Inverse of `manifest_complete`; follow `recovery_url` when true. */
1530
+ recovery_required: boolean;
1531
+ };
1416
1532
  Viewport: {
1417
1533
  width: number;
1418
1534
  height: number;
@@ -1535,11 +1651,17 @@ export interface components {
1535
1651
  formats: ("raw" | "markdown" | "links" | "images")[];
1536
1652
  /** @default US */
1537
1653
  country: string;
1538
- /** @default 0 */
1654
+ /**
1655
+ * @description Milliseconds to wait after page load before capturing, for content that renders late. Any value above 0 puts the request on the full browser render path. Unless `async: true` is also set, the request is then HELD until the render finishes and returns 200 with the content envelope, or returns the 202 receipt if the hold window expires first. `0` (the default) keeps the request on the fast HTTP path, which returns 200 in one round trip.
1656
+ * @default 0
1657
+ */
1539
1658
  delay_ms: number;
1540
1659
  /** @default 30000 */
1541
1660
  timeout_ms: number;
1542
- /** @default false */
1661
+ /**
1662
+ * @description When true, the request returns 202 with a `ScrapeQueuedEnvelope` receipt immediately and the scrape runs in the background; poll `GET /v1/scrape/{id}` for the result. This is the only way to ASK for a receipt, and it outranks every routing consequence: with `async: false` (the default) a browser-path request is held to completion instead of being receipted. A 202 can still arrive with `async: false`, but only when the hold window expires.
1663
+ * @default false
1664
+ */
1543
1665
  async: boolean;
1544
1666
  /**
1545
1667
  * Format: uri
@@ -1599,6 +1721,11 @@ export interface components {
1599
1721
  * @default false
1600
1722
  */
1601
1723
  mobile: boolean;
1724
+ /**
1725
+ * @description Attempts to clear a Cloudflare challenge; success is not guaranteed. Billed as a normal browser render.
1726
+ * @default false
1727
+ */
1728
+ solve_challenge: boolean;
1602
1729
  /**
1603
1730
  * @description When true (default), base64-encoded `data:` image sources are stripped from the HTML before markdown conversion. Set to false to preserve base64 images in the pipeline output. Does not affect `raw`, which always returns the original source unchanged.
1604
1731
  * @default true
@@ -1829,17 +1956,19 @@ export interface components {
1829
1956
  * from a prior cache entry (billed at 0.5×). `miss` — no reusable entry was
1830
1957
  * found, so the result was freshly fetched. `bypass` — `cache_ttl: '0'`
1831
1958
  * skipped the read. Cache-eligible fresh results are written through;
1832
- * safety-classified WAF husks remain live-only. Present on the async success
1833
- * envelope (synchronous and webhook delivery); omitted by paths with no cache
1834
- * verdict (e.g. bulk results).
1959
+ * safety-classified WAF husks remain live-only. Present on the synchronous
1960
+ * response, on webhook delivery, and on `GET /v1/scrape/{id}` for a row whose
1961
+ * terminal write recorded a disposition; omitted by paths with no cache verdict
1962
+ * (e.g. bulk results) and for a stored row that recorded none, where absent
1963
+ * means unknown rather than `miss`.
1835
1964
  * @enum {string}
1836
1965
  */
1837
1966
  cache?: "miss" | "hit" | "bypass";
1838
- /** @description Age in whole seconds of the cache entry replayed on a `hit`. Clamped to ≥ 0 to absorb clock skew. Present only on `cache: hit`. */
1967
+ /** @description Age in whole seconds of the cache entry replayed on a `hit`. Clamped to ≥ 0 to absorb clock skew. Present only on `cache: hit`. `GET /v1/scrape/{id}` reports `cache: hit` without this field: the age is a property of the replay that happened at completion time, is not persisted on the row, and cannot be derived honestly afterwards. */
1839
1968
  cache_age_s?: number;
1840
1969
  };
1841
1970
  /**
1842
- * @description Terminal asynchronous scrape failures are delivered to subscribers of `failed` as this payload with `X-ByteKit-Event: scrape.failed`.
1971
+ * @description The canonical terminal failure payload. It is returned inline on a `POST /v1/scrape` that fails upstream (HTTP 200, `id` naming the failed job it is recorded as, or `null` in the rare case that recording itself failed), by `GET /v1/scrape/{id}` once a queued job has failed, and delivered to subscribers of `failed` with `X-ByteKit-Event: scrape.failed`.
1843
1972
  * @example {
1844
1973
  * "schema_version": 1,
1845
1974
  * "status": "failed",
@@ -2166,7 +2295,7 @@ export interface components {
2166
2295
  options?: {
2167
2296
  [key: string]: unknown;
2168
2297
  };
2169
- /** @description Scrape monitor options (formats, country, headers, etc.). Only for type=scrape. */
2298
+ /** @description Scrape monitor options (formats, country, wait_for_selector, wait_until, delay_ms). Only for type=scrape. */
2170
2299
  scrape_options?: {
2171
2300
  [key: string]: unknown;
2172
2301
  };
@@ -2530,8 +2659,8 @@ export interface components {
2530
2659
  };
2531
2660
  auto_topup: {
2532
2661
  enabled: boolean;
2533
- threshold_bytes: number;
2534
- amount_bytes: number;
2662
+ threshold_cents: number;
2663
+ amount_cents: number;
2535
2664
  monthly_cap_cents: number;
2536
2665
  };
2537
2666
  /** Format: date-time */
@@ -2544,7 +2673,7 @@ export interface components {
2544
2673
  /** Format: date-time */
2545
2674
  created_at: string;
2546
2675
  };
2547
- /** @description Minimal account shape returned by GET /v1/account when authenticated with a Clerk session JWT. Omits api_key, subscription, and auto_topup. */
2676
+ /** @description Minimal account shape returned by GET /v1/account when authenticated with a Clerk session JWT. Omits api_key, subscription, and auto_topup; the single boolean `has_subscription` stands in for the bearer path's `subscription` object. */
2548
2677
  AccountSessionResponse: {
2549
2678
  id: string;
2550
2679
  email: string;
@@ -2577,6 +2706,42 @@ export interface components {
2577
2706
  created_at: string;
2578
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". */
2579
2708
  has_activity: boolean;
2709
+ /** @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
+ has_subscription: boolean;
2711
+ };
2712
+ /** @description Account shape returned by PATCH /v1/account. Identical to AccountSessionResponse except that it omits `has_activity`: the PATCH handler returns the shared session-account body unchanged and does not run the extra activity lookup that GET /v1/account layers on top of it (issue #4187). */
2713
+ AccountPatchResponse: {
2714
+ id: string;
2715
+ email: string;
2716
+ name: string | null;
2717
+ plan: {
2718
+ id: string;
2719
+ slug: string;
2720
+ name: string;
2721
+ included_screenshots: number;
2722
+ has_overage: boolean;
2723
+ overage_price_cents: number | null;
2724
+ max_concurrency: number;
2725
+ rate_limit_per_sec: number;
2726
+ max_bulk_size: number;
2727
+ max_monitors: number;
2728
+ retention_days: number;
2729
+ };
2730
+ /** @description Prefixed user id of the calling admin user. Null for non-admin members. */
2731
+ owner_user_id: string | null;
2732
+ /** @description Account notification preferences (bandwidth alerts). */
2733
+ notifications: {
2734
+ /** @description Whether the account admin wants an email when bandwidth reaches 80 % of the plan limit. */
2735
+ bandwidth_80_enabled: boolean;
2736
+ /** @description Whether the account admin wants an email when bandwidth reaches 100 % of the plan limit. */
2737
+ bandwidth_100_enabled: boolean;
2738
+ };
2739
+ /** @description The Terms of Service version this account has accepted. An empty string means the account predates clickwrap acceptance (issue #1025). The dashboard diffs this against the published current version to decide whether to show the re-acceptance prompt. */
2740
+ terms_version: string;
2741
+ /** @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. */
2742
+ has_subscription: boolean;
2743
+ /** Format: date-time */
2744
+ created_at: string;
2580
2745
  };
2581
2746
  /** @description Partial update payload for PATCH /v1/account. All fields are optional; at least one of name, email, or notifications must be provided. */
2582
2747
  PatchAccountRequest: {
@@ -2618,24 +2783,24 @@ export interface components {
2618
2783
  used_bytes: number;
2619
2784
  limit_bytes: number;
2620
2785
  remaining_bytes: number;
2621
- /** @description Total spendable bytes remaining across purchased top-up and starter-grant lots, after active refund reservations. */
2786
+ /** @description Total spendable top-up bytes: the USD balance's current-plan estimate (`purchased_topup_bytes`) plus the starter grant. */
2622
2787
  topup_bytes: number;
2623
- /** @description Bytes remaining in purchased top-up lots, after active refund reservations. Starter-grant bytes are excluded. */
2788
+ /** @description Estimate of the bytes the USD balance buys at the current plan's rate, after amounts held by open refunds. Not a separate balance: it changes when the plan changes. Starter-grant bytes are excluded. */
2624
2789
  purchased_topup_bytes: number;
2625
- /** @description Bytes remaining in starter-grant lots, after active refund reservations. Purchased top-up bytes are excluded. */
2790
+ /** @description Bytes remaining in starter-grant lots, after active refund reservations. The USD balance estimate is excluded. */
2626
2791
  granted_topup_bytes: number;
2627
- /** @description Unspent subscription allowance carried over from earlier billing periods: bytes remaining in allowance lots granted before the current period started, after active refund reservations. While your plan tier is unchanged, earlier lots are drawn first, so carried-over allowance is spent before the current period's; after an upgrade, allowance acquired at the higher tier is drawn first. Value is spent in one order: your plan's included allowance, including any rollover from earlier periods, then purchased top-ups, then the one-time starter grant. */
2792
+ /** @description Unspent subscription allowance carried over from earlier billing periods: bytes remaining in allowance lots granted before the current period started, after active refund reservations. While your plan tier is unchanged, earlier lots are drawn first, so carried-over allowance is spent before the current period's; after an upgrade, allowance acquired at the higher tier is drawn first. Value is spent in one order: your plan's included allowance, including any rollover from earlier periods, then the USD balance, then the one-time starter grant. */
2628
2793
  rollover_bytes: number;
2629
2794
  };
2630
2795
  CreditBalance: {
2631
2796
  used: number;
2632
2797
  limit: number;
2633
2798
  remaining: number;
2634
- /** @description Total spendable credits remaining across purchased top-up and starter-grant lots, after active refund reservations. */
2799
+ /** @description Total spendable top-up credits: the USD balance's current-plan estimate (`purchased_topup_credits`) plus the starter grant. */
2635
2800
  topup_credits: number;
2636
- /** @description Credits remaining in purchased top-up lots, after active refund reservations. Starter-grant credits are excluded. */
2801
+ /** @description Estimate of the credits the USD balance buys at the current plan's rate, after amounts held by open refunds. Not a separate balance: it changes when the plan changes. Starter-grant credits are excluded. */
2637
2802
  purchased_topup_credits: number;
2638
- /** @description Credits remaining in starter-grant lots, after active refund reservations. Purchased top-up credits are excluded. */
2803
+ /** @description Credits remaining in starter-grant lots, after active refund reservations. The USD balance estimate is excluded. */
2639
2804
  granted_topup_credits: number;
2640
2805
  /** @description Always `0`. Search credits do not carry over between billing periods; the field is retained for contract stability and will not become non-zero without an announced plan change. */
2641
2806
  rollover_credits: number;
@@ -2906,7 +3071,7 @@ export interface operations {
2906
3071
  [name: string]: unknown;
2907
3072
  };
2908
3073
  content: {
2909
- "application/json": components["schemas"]["Account"];
3074
+ "application/json": components["schemas"]["AccountPatchResponse"];
2910
3075
  };
2911
3076
  };
2912
3077
  /** @description Missing or invalid Clerk JWT. */
@@ -3423,7 +3588,7 @@ export interface operations {
3423
3588
  };
3424
3589
  };
3425
3590
  responses: {
3426
- /** @description Scrape completed synchronously. */
3591
+ /** @description Scrape reached a terminal state and the body is that terminal envelope: `success` carrying content, or `failed` carrying the error envelope. Returned by the fast HTTP path in one round trip, and by a browser-path request without `async: true` once its render reaches a terminal state inside the hold window. A held render that ends in failure answers 200 with the same `failed` envelope `GET /v1/scrape/{id}` returns — narrow on `status` before reading the body. A definitive upstream outcome is a result, not a transport error: an unreachable host, a refused connection, or a target whose bot protection defeats every proxy tier all answer 200 with the `failed` envelope, never a 5xx. An inline failure is recorded as a failed job, so its envelope normally carries that job's `id` and polling it returns the same envelope; `id` is `null` only when recording the failed job itself failed. `error.http_status` is present only when a real upstream HTTP status is known. */
3427
3592
  200: {
3428
3593
  headers: {
3429
3594
  /** @description Stable scrape identifier (also present on the envelope as `id`). */
@@ -3476,7 +3641,7 @@ export interface operations {
3476
3641
  "X-Scrape-Markdown-Length"?: number;
3477
3642
  /** @description Legacy numeric form of the tier that served: 1 datacenter, 2 residential, 3 mobile. Omitted for the lean-browser tier, which has no numeric form. Deprecated — use X-Scrape-Proxy-Tier-Label. */
3478
3643
  "X-Scrape-Proxy-Tier"?: number;
3479
- /** @description The proxy tier that actually served this request's fetch, after any escalation — never the tier first attempted. One of datacenter, residential, mobile, lean. Diagnostic only: it is never an input to routing, billing, caching or escalation. Present on sync fast-path responses. Omitted on a cache hit, which replayed stored bytes and ran no tier, and on responses the fast path did not serve. */
3644
+ /** @description The proxy tier that actually served this request's fetch, after any escalation — never the tier first attempted. One of datacenter, residential, mobile, lean. Diagnostic only: it is never an input to routing, billing, caching or escalation. Present on sync fast-path responses. Omitted on a cache hit, which replayed stored bytes and ran no tier; and on responses the fast path did not serve. A third omission — a response replayed from stored bytes after this request's own cache lookup missed, which reports X-Scrape-Cache: miss and likewise ran no tier — exists only as an internal deploy-skew safeguard and is not reachable through this API. */
3480
3645
  "X-Scrape-Proxy-Tier-Label"?: string;
3481
3646
  /** @description WAF vendor detected on the target, if any (diagnostic). May be "suspected" when a low-confidence fail-open block marker was served. Omitted when no WAF is detected. */
3482
3647
  "X-Scrape-Waf"?: string;
@@ -3487,10 +3652,10 @@ export interface operations {
3487
3652
  [name: string]: unknown;
3488
3653
  };
3489
3654
  content: {
3490
- "application/json": components["schemas"]["ScrapeSuccessEnvelope"];
3655
+ "application/json": components["schemas"]["ScrapeSuccessEnvelope"] | components["schemas"]["ScrapeErrorEnvelope"];
3491
3656
  };
3492
3657
  };
3493
- /** @description Scrape accepted for async processing. */
3658
+ /** @description Scrape accepted for background processing; the body is a receipt, not content. Returned when `async: true` was requested, or when a browser-path request's hold window expired before the render finished. Poll `GET /v1/scrape/{id}` for the result. */
3494
3659
  202: {
3495
3660
  headers: {
3496
3661
  /** @description Stable scrape identifier for the queued job. */
@@ -3779,7 +3944,14 @@ export interface operations {
3779
3944
  };
3780
3945
  getScrapeBulk: {
3781
3946
  parameters: {
3782
- query?: never;
3947
+ query?: {
3948
+ /** @description Opaque cursor returned by the preceding page. It is bound to this bulk id, this recovery route, and the exact status filter; cross-scope cursors return 422. */
3949
+ cursor?: string;
3950
+ /** @description Maximum result rows considered for this page; the 16-MiB response bound may stop sooner. */
3951
+ limit?: number;
3952
+ /** @description Optional item-status filter. A cursor may be reused only with the same filter. */
3953
+ status?: "pending" | "processing" | "completed" | "failed" | "cancelled";
3954
+ };
3783
3955
  header?: never;
3784
3956
  path: {
3785
3957
  id: string;
@@ -3818,8 +3990,12 @@ export interface operations {
3818
3990
  estimated_credits: number | null;
3819
3991
  /** @description Webhook endpoint URL (HTTPS only; http:// rejected with 400 invalid_url, reason scheme_unsupported) */
3820
3992
  webhook_url: string;
3821
- /** @description Rehydrated per-URL scrape envelopes — the terminal page of results (default 100 rows, `?limit=` up to 500). `routes/scrape-bulk.ts` spreads this key into the SAME body on both status branches, so it is present here exactly as it is on the 202; on the 200 the entries carry their final success or error envelopes (issue #3632). */
3822
- items: components["schemas"]["ScrapeEnvelope"][];
3993
+ /** @description Opaque cursor for the next stable page; null when traversal is complete. */
3994
+ next_cursor: string | null;
3995
+ /** @description True when another page is available through `next_cursor`. */
3996
+ has_more: boolean;
3997
+ /** @description Rehydrated per-URL scrape envelopes — the terminal page of results (default 500 rows, `?limit=` up to 500). `routes/scrape-bulk.ts` spreads this key into the SAME body on both status branches, so it is present here exactly as it is on the 202; on the 200 the entries carry their final success or error envelopes (issue #3632). */
3998
+ items: (components["schemas"]["ScrapeEnvelope"] | components["schemas"]["BulkMandatoryScrapeItem"])[];
3823
3999
  };
3824
4000
  };
3825
4001
  };
@@ -3853,8 +4029,12 @@ export interface operations {
3853
4029
  estimated_credits: number | null;
3854
4030
  /** @description Webhook endpoint URL (HTTPS only; http:// rejected with 400 invalid_url, reason scheme_unsupported) */
3855
4031
  webhook_url: string;
3856
- /** @description Rehydrated per-URL scrape envelopes — the same page the 200 returns (default 100 rows, `?limit=` up to 500). While the job is non-terminal most entries carry the `queued` envelope. */
3857
- items: components["schemas"]["ScrapeEnvelope"][];
4032
+ /** @description Opaque cursor for the next stable page; null when traversal is complete. */
4033
+ next_cursor: string | null;
4034
+ /** @description True when another page is available through `next_cursor`. */
4035
+ has_more: boolean;
4036
+ /** @description Rehydrated per-URL scrape envelopes — the same page the 200 returns (default 500 rows, `?limit=` up to 500). While the job is non-terminal most entries carry the `queued` envelope. */
4037
+ items: (components["schemas"]["ScrapeEnvelope"] | components["schemas"]["BulkMandatoryScrapeItem"])[];
3858
4038
  };
3859
4039
  };
3860
4040
  };
@@ -4220,7 +4400,14 @@ export interface operations {
4220
4400
  };
4221
4401
  getFetchBulk: {
4222
4402
  parameters: {
4223
- query?: never;
4403
+ query?: {
4404
+ /** @description Opaque cursor returned by the preceding page. It is bound to this bulk id, this recovery route, and the exact status filter; cross-scope cursors return 422. */
4405
+ cursor?: string;
4406
+ /** @description Maximum result rows considered for this page; the 16-MiB response bound may stop sooner. */
4407
+ limit?: number;
4408
+ /** @description Optional item-status filter. A cursor may be reused only with the same filter. */
4409
+ status?: "pending" | "processing" | "completed" | "failed" | "cancelled";
4410
+ };
4224
4411
  header?: never;
4225
4412
  path: {
4226
4413
  id: string;
@@ -4253,8 +4440,12 @@ export interface operations {
4253
4440
  estimated_credits: number | null;
4254
4441
  /** @description Webhook endpoint URL (HTTPS only; http:// rejected with 400 invalid_url, reason scheme_unsupported) */
4255
4442
  webhook_url: string;
4256
- /** @description Per-URL fetch items, oldest first, capped at 500 (listBulkFetchItemsWithLatestAttempt). */
4257
- items: {
4443
+ /** @description Opaque cursor for the next stable page; null when traversal is complete. */
4444
+ next_cursor: string | null;
4445
+ /** @description True when another page is available through `next_cursor`. */
4446
+ has_more: boolean;
4447
+ /** @description Stable per-URL fetch items, oldest first. Follow `next_cursor` while `has_more` is true to enumerate the complete filtered job; each page considers at most 500 rows and is bounded to 16 MiB. */
4448
+ items: ({
4258
4449
  /**
4259
4450
  * @description Scrape-row id, `sc_`-prefixed. Fetch-bulk items are rows of the same resource sync `/v1/scrape` returns, so they share its prefix. Not to be confused with the `ft_`-prefixed `X-Fetch-ID` correlation header on sync `/v1/fetch`, which identifies a request rather than a stored item.
4260
4451
  * @example sc_01j9abc123
@@ -4264,25 +4455,46 @@ export interface operations {
4264
4455
  url: string;
4265
4456
  /** @enum {string} */
4266
4457
  status: "pending" | "processing" | "completed" | "failed" | "cancelled";
4267
- content_type: string | null;
4268
- content_length: number | null;
4269
- /** @description Pre-signed download URL for the fetched body, valid for 600 seconds (10 minutes) from the moment this response was generated — matching the signing TTL of `image_url` on `GET /v1/bulk/{id}/screenshots`. A new signature is minted on every poll. Null for items with no stored body; a completed item whose object cannot be signed falls back to the unsigned stored URL, which returns 401 on download. */
4458
+ content_type?: string | null;
4459
+ content_length?: number | null;
4460
+ /** @description Pre-signed download URL for the fetched body, valid for 600 seconds (10 minutes) from the moment this response was generated — matching the signing TTL of `image_url` on `GET /v1/bulk/{id}/screenshots`. A new signature is minted on every poll. Null for items with no stored body or whose object cannot be signed. In the latter case `error_code` is `artifact_unavailable`; the private unsigned storage URL is never returned. */
4270
4461
  content_url: string | null;
4271
- waf_vendor: string | null;
4272
- cache_hit: boolean;
4462
+ waf_vendor?: string | null;
4463
+ cache_hit?: boolean;
4273
4464
  /**
4274
4465
  * @description Itemised account of this item's charge — the basis, the named factors
4275
4466
  * that composed the multiplier, and the resulting billed bytes. Omitted
4276
4467
  * for rows that completed before the billing node was persisted.
4277
4468
  */
4278
4469
  billing?: components["schemas"]["BillingNode"];
4470
+ /** @description Stable item-local error code. `artifact_unavailable` means the stored result or a usable signed reference could not be produced. */
4279
4471
  error_code: string | null;
4280
4472
  error_message: string | null;
4281
4473
  /** Format: date-time */
4282
- created_at: string;
4474
+ created_at?: string;
4283
4475
  /** Format: date-time */
4284
- completed_at: string | null;
4285
- }[];
4476
+ completed_at?: string | null;
4477
+ } | {
4478
+ /**
4479
+ * @description Scrape-row id, `sc_`-prefixed — the same stable identity the ordinary item carries, so recovery pagination is unaffected.
4480
+ * @example sc_01j9abc123
4481
+ */
4482
+ id: string;
4483
+ /** @enum {string} */
4484
+ type: "fetch";
4485
+ /**
4486
+ * @description Terminal state of the item. This is the contract's terminal signal and outranks the ordinary item's legacy `status` spelling.
4487
+ * @enum {string}
4488
+ */
4489
+ terminal_outcome: "pending" | "processing" | "completed" | "failed" | "cancelled";
4490
+ /** Format: uri */
4491
+ url: string;
4492
+ /** @description Bounded pre-signed download URL retained from the ordinary item, or `null` when the reference did not fit or could not be produced. */
4493
+ content_url: string | null;
4494
+ error_code: string | null;
4495
+ /** @description Bounded failure detail; a long message is truncated. */
4496
+ error_message: string | null;
4497
+ })[];
4286
4498
  };
4287
4499
  };
4288
4500
  };
@@ -4319,8 +4531,12 @@ export interface operations {
4319
4531
  estimated_credits: number | null;
4320
4532
  /** @description Webhook endpoint URL (HTTPS only; http:// rejected with 400 invalid_url, reason scheme_unsupported) */
4321
4533
  webhook_url: string;
4322
- /** @description Per-URL fetch items, oldest first, capped at 500 (listBulkFetchItemsWithLatestAttempt). */
4323
- items: {
4534
+ /** @description Opaque cursor for the next stable page; null when traversal is complete. */
4535
+ next_cursor: string | null;
4536
+ /** @description True when another page is available through `next_cursor`. */
4537
+ has_more: boolean;
4538
+ /** @description Stable per-URL fetch items, oldest first. Follow `next_cursor` while `has_more` is true to enumerate the complete filtered job; each page considers at most 500 rows and is bounded to 16 MiB. */
4539
+ items: ({
4324
4540
  /**
4325
4541
  * @description Scrape-row id, `sc_`-prefixed. Fetch-bulk items are rows of the same resource sync `/v1/scrape` returns, so they share its prefix. Not to be confused with the `ft_`-prefixed `X-Fetch-ID` correlation header on sync `/v1/fetch`, which identifies a request rather than a stored item.
4326
4542
  * @example sc_01j9abc123
@@ -4330,25 +4546,46 @@ export interface operations {
4330
4546
  url: string;
4331
4547
  /** @enum {string} */
4332
4548
  status: "pending" | "processing" | "completed" | "failed" | "cancelled";
4333
- content_type: string | null;
4334
- content_length: number | null;
4335
- /** @description Pre-signed download URL for the fetched body, valid for 600 seconds (10 minutes) from the moment this response was generated — matching the signing TTL of `image_url` on `GET /v1/bulk/{id}/screenshots`. A new signature is minted on every poll. Null for items with no stored body; a completed item whose object cannot be signed falls back to the unsigned stored URL, which returns 401 on download. */
4549
+ content_type?: string | null;
4550
+ content_length?: number | null;
4551
+ /** @description Pre-signed download URL for the fetched body, valid for 600 seconds (10 minutes) from the moment this response was generated — matching the signing TTL of `image_url` on `GET /v1/bulk/{id}/screenshots`. A new signature is minted on every poll. Null for items with no stored body or whose object cannot be signed. In the latter case `error_code` is `artifact_unavailable`; the private unsigned storage URL is never returned. */
4336
4552
  content_url: string | null;
4337
- waf_vendor: string | null;
4338
- cache_hit: boolean;
4553
+ waf_vendor?: string | null;
4554
+ cache_hit?: boolean;
4339
4555
  /**
4340
4556
  * @description Itemised account of this item's charge — the basis, the named factors
4341
4557
  * that composed the multiplier, and the resulting billed bytes. Omitted
4342
4558
  * for rows that completed before the billing node was persisted.
4343
4559
  */
4344
4560
  billing?: components["schemas"]["BillingNode"];
4561
+ /** @description Stable item-local error code. `artifact_unavailable` means the stored result or a usable signed reference could not be produced. */
4345
4562
  error_code: string | null;
4346
4563
  error_message: string | null;
4347
4564
  /** Format: date-time */
4348
- created_at: string;
4565
+ created_at?: string;
4349
4566
  /** Format: date-time */
4350
- completed_at: string | null;
4351
- }[];
4567
+ completed_at?: string | null;
4568
+ } | {
4569
+ /**
4570
+ * @description Scrape-row id, `sc_`-prefixed — the same stable identity the ordinary item carries, so recovery pagination is unaffected.
4571
+ * @example sc_01j9abc123
4572
+ */
4573
+ id: string;
4574
+ /** @enum {string} */
4575
+ type: "fetch";
4576
+ /**
4577
+ * @description Terminal state of the item. This is the contract's terminal signal and outranks the ordinary item's legacy `status` spelling.
4578
+ * @enum {string}
4579
+ */
4580
+ terminal_outcome: "pending" | "processing" | "completed" | "failed" | "cancelled";
4581
+ /** Format: uri */
4582
+ url: string;
4583
+ /** @description Bounded pre-signed download URL retained from the ordinary item, or `null` when the reference did not fit or could not be produced. */
4584
+ content_url: string | null;
4585
+ error_code: string | null;
4586
+ /** @description Bounded failure detail; a long message is truncated. */
4587
+ error_message: string | null;
4588
+ })[];
4352
4589
  };
4353
4590
  };
4354
4591
  };
@@ -4366,6 +4603,9 @@ export interface operations {
4366
4603
  listBulk: {
4367
4604
  parameters: {
4368
4605
  query?: {
4606
+ limit?: components["parameters"]["LimitParam"];
4607
+ /** @description Pagination cursor from a previous response. */
4608
+ cursor?: components["parameters"]["CursorParam"];
4369
4609
  status?: "processing" | "completed" | "failed";
4370
4610
  };
4371
4611
  header?: never;
@@ -4381,27 +4621,31 @@ export interface operations {
4381
4621
  };
4382
4622
  content: {
4383
4623
  "application/json": {
4384
- /** @example bulk_01j9abc123 */
4385
- id: string;
4386
- /** @enum {string} */
4387
- status: "processing" | "completed" | "failed";
4388
- total: number;
4389
- completed: number;
4390
- failed: number;
4391
- /** Format: date-time */
4392
- created_at: string;
4393
- /** Format: date-time */
4394
- completed_at: string | null;
4395
- /** @description Total credits billed for the job. Null until the job is billed. Fractional — credits are NUMERIC(10,2). */
4396
- total_credits_charged: number | null;
4397
- /** @description Null in GET responses (computed at submission time only). */
4398
- estimated_credits: number | null;
4399
- /** @description Webhook endpoint URL (HTTPS only; http:// rejected with 400 invalid_url, reason scheme_unsupported) */
4400
- webhook_url: string;
4401
- }[];
4624
+ next_cursor: string | null;
4625
+ has_more: boolean;
4626
+ data: {
4627
+ /** @example bulk_01j9abc123 */
4628
+ id: string;
4629
+ /** @enum {string} */
4630
+ status: "processing" | "completed" | "failed";
4631
+ total: number;
4632
+ completed: number;
4633
+ failed: number;
4634
+ /** Format: date-time */
4635
+ created_at: string;
4636
+ /** Format: date-time */
4637
+ completed_at: string | null;
4638
+ /** @description Total credits billed for the job. Null until the job is billed. Fractional — credits are NUMERIC(10,2). */
4639
+ total_credits_charged: number | null;
4640
+ /** @description Null in GET responses (computed at submission time only). */
4641
+ estimated_credits: number | null;
4642
+ /** @description Webhook endpoint URL (HTTPS only; http:// rejected with 400 invalid_url, reason scheme_unsupported) */
4643
+ webhook_url: string;
4644
+ }[];
4645
+ };
4402
4646
  };
4403
4647
  };
4404
- /** @description Validation error. Returned when `status` is not one of the documented values. */
4648
+ /** @description Validation error. Returned when `status` is not one of the documented values, or when `cursor` is not a cursor this endpoint issued. */
4405
4649
  422: {
4406
4650
  headers: {
4407
4651
  [name: string]: unknown;
@@ -4789,7 +5033,14 @@ export interface operations {
4789
5033
  };
4790
5034
  listBulkScreenshots: {
4791
5035
  parameters: {
4792
- query?: never;
5036
+ query?: {
5037
+ /** @description Opaque per-type seek cursor returned by the preceding page. It is bound to this bulk id, this mixed recovery route, and the exact status filter; cross-scope cursors return 422. */
5038
+ cursor?: string;
5039
+ /** @description Maximum rows selected per requested item type; the 16-MiB response bound may stop sooner. */
5040
+ limit?: number;
5041
+ /** @description Optional item-status filter. A cursor may be reused only with the same filter. */
5042
+ status?: "pending" | "processing" | "completed" | "failed" | "cancelled";
5043
+ };
4793
5044
  header?: never;
4794
5045
  path: {
4795
5046
  id: string;
@@ -4809,8 +5060,13 @@ export interface operations {
4809
5060
  bulk_id: string;
4810
5061
  /** @description Number of items in `items` (page size, not the job total). */
4811
5062
  total: number;
5063
+ /** @description Opaque per-type cursor for the next stable page; null when every selected item type is exhausted. Never advances past an item omitted by the byte bound. */
5064
+ next_cursor: string | null;
5065
+ /** @description True when another page is available through `next_cursor`. */
5066
+ has_more: boolean;
5067
+ job_counters: components["schemas"]["BulkJobCounters"];
4812
5068
  /** @description Heterogeneous capture items discriminated by `type`. Fields outside the common set are present only for the matching `type`. */
4813
- items: {
5069
+ items: ({
4814
5070
  /** @enum {string} */
4815
5071
  type: "screenshot" | "recording" | "scrape";
4816
5072
  /** @description Prefixed id — `ss_` / `rec_` / `sc_` per `type`. */
@@ -4819,7 +5075,7 @@ export interface operations {
4819
5075
  status: "pending" | "processing" | "completed" | "failed" | "cancelled";
4820
5076
  /** Format: uri */
4821
5077
  url: string;
4822
- credits_charged: number | null;
5078
+ credits_charged?: number | null;
4823
5079
  /**
4824
5080
  * @description Itemised account of this item's charge — the basis, the named factors
4825
5081
  * that composed the multiplier, and the resulting billed bytes. Omitted
@@ -4827,12 +5083,13 @@ export interface operations {
4827
5083
  */
4828
5084
  billing?: components["schemas"]["BillingNode"];
4829
5085
  error_code: string | null;
5086
+ /** @description Bounded human-readable failure detail. */
4830
5087
  error_message: string | null;
4831
5088
  /** Format: date-time */
4832
- created_at: string;
5089
+ created_at?: string;
4833
5090
  /** Format: date-time */
4834
- completed_at: string | null;
4835
- /** @description `type: screenshot` only. Presigned for completed rows with a storage key; raw image_url otherwise. */
5091
+ completed_at?: string | null;
5092
+ /** @description `type: screenshot` only. Pre-signed download URL for the image, minted fresh for completed rows with a storage key and valid for 600 seconds (10 minutes). For every other row the stored value is returned unchanged — `null` while no image has been stored, and otherwise a private, unsigned storage URL that returns 401 on download. That covers non-completed rows, completed rows with no storage key, and completed rows whose object could not be signed; none of them raise an `artifact_warnings` entry. */
4836
5093
  image_url?: string | null;
4837
5094
  /** @description `type: screenshot` and `type: scrape` only. */
4838
5095
  page_title?: string | null;
@@ -4840,7 +5097,7 @@ export interface operations {
4840
5097
  format?: string;
4841
5098
  /** @description `type: recording` only. */
4842
5099
  video_url?: string | null;
4843
- /** @description `type: scrape` only. Pre-signed download URL for the scraped body, valid for 600 seconds (10 minutes) from the moment this response was generated — matching the signing TTL of `image_url` above and of `content_url` on `GET /v1/fetch/bulk/{id}`. A new signature is minted on every poll. Null for items with no stored body; a completed item whose object cannot be signed falls back to the unsigned stored URL, which returns 401 on download. */
5100
+ /** @description `type: scrape` only. Pre-signed download URL for the scraped body, valid for 600 seconds (10 minutes) from the moment this response was generated — matching the signing TTL of `image_url` above and of `content_url` on `GET /v1/fetch/bulk/{id}`. A new signature is minted on every poll for a completed item with a storage key. For every other item the stored value is returned unchanged — `null` while no body has been stored, and otherwise a private, unsigned storage URL that returns 401 on download. No `artifact_warnings` entry is raised for this field; unlike `GET /v1/fetch/bulk/{id}`, this endpoint reports no `artifact_unavailable` when signing fails. */
4844
5101
  content_url?: string | null;
4845
5102
  /** @description `type: scrape` only. */
4846
5103
  content_type?: string | null;
@@ -4848,9 +5105,33 @@ export interface operations {
4848
5105
  content_length?: number | null;
4849
5106
  /** @description `type: scrape` only. Always null in bulk listings — fetch the body via `markdown_url`. */
4850
5107
  markdown?: string | null;
4851
- /** @description `type: scrape` only. Pre-signed download URL for the markdown rendering of the page, valid for 600 seconds (10 minutes) from the moment this response was generated — the same signing TTL as `content_url` and `image_url` above. A new signature is minted on every poll. Null for items with no stored markdown; a completed item whose object cannot be signed falls back to the unsigned stored URL, which returns 401 on download. */
5108
+ /** @description `type: scrape` only. Pre-signed download URL for the markdown rendering of the page, valid for 600 seconds (10 minutes) from the moment this response was generated — the same signing TTL as `content_url` and `image_url` above. A new signature is minted on every poll for a completed item with a markdown key. For every other item the stored value is returned unchanged — `null` while no markdown has been stored, and otherwise a private, unsigned storage URL that returns 401 on download. No `artifact_warnings` entry is raised for this field; unlike `GET /v1/fetch/bulk/{id}`, this endpoint reports no `artifact_unavailable` when signing fails. */
4852
5109
  markdown_url?: string | null;
4853
- }[];
5110
+ /** @description `type: scrape` only. Exact requested artifact values or signed references. Every key is present; unrequested or unavailable values are null, with nonfatal reference failures in `artifact_warnings`. */
5111
+ artifacts?: {
5112
+ raw: string | null;
5113
+ markdown: string | null;
5114
+ links: null | (string | components["schemas"]["ScrapeScoredLink"])[];
5115
+ images: null | (string | components["schemas"]["ScrapeScoredImage"])[];
5116
+ };
5117
+ /** @description Nonfatal artifact reference failures for this scrape item. */
5118
+ artifact_warnings?: components["schemas"]["ScrapeWarning"][];
5119
+ } | {
5120
+ /** @description Prefixed id — `ss_` / `rec_` / `sc_` per `type`. The same stable identity the ordinary item carries. */
5121
+ id: string;
5122
+ /** @enum {string} */
5123
+ type: "screenshot" | "recording" | "scrape";
5124
+ /**
5125
+ * @description Terminal state of the item. This is the contract's terminal signal and outranks the ordinary item's legacy `status` spelling.
5126
+ * @enum {string}
5127
+ */
5128
+ terminal_outcome: "pending" | "processing" | "completed" | "failed" | "cancelled";
5129
+ /** Format: uri */
5130
+ url: string;
5131
+ error_code: string | null;
5132
+ /** @description Bounded failure detail; a long message is truncated. */
5133
+ error_message: string | null;
5134
+ })[];
4854
5135
  };
4855
5136
  };
4856
5137
  };
@@ -5472,10 +5753,10 @@ export interface operations {
5472
5753
  };
5473
5754
  content: {
5474
5755
  "application/json": {
5475
- /** @description Extracted JSON conforming to the normalized schema, or `null` when the model returned a refusal. */
5756
+ /** @description Extracted JSON conforming to the normalized schema, or `null` when `validated` is `false` — see `validated` for the cases. A `validated: true` response always carries an object here, never `null`. */
5476
5757
  data: Record<string, never> | null;
5477
5758
  model: string;
5478
- /** @description `true` when the output passed Ajv re-validation; `false` when retries were exhausted (`data` carries the last raw output, with `extract_validation_failed` in `warnings`). */
5759
+ /** @description `true` when the output passed Ajv re-validation and at least one leaf is non-null. An all-null output is also `true` when your schema explicitly allows it: every leaf the output returned as `null` sits at a node whose `type` is a union containing `"null"` in the schema you sent (only that form counts — `nullable: true`, an `enum` containing `null` and `const: null` do not). An output that is itself `null` rather than an object is never accepted, whatever your root schema declares. `false` (with `data: null`) when the model refused (`model_refusal`), when retries were exhausted (`extract_validation_failed`, `exhausted_retries`), or when a schema-valid output has every leaf `null` and is not one the declaration above accepts (`empty_extraction`). The per-request credits are charged only for `true`. */
5479
5760
  validated: boolean;
5480
5761
  metrics: {
5481
5762
  scrape_ms: number;
@@ -5495,7 +5776,7 @@ export interface operations {
5495
5776
  /** @description True when markdown exceeded the LLM token budget and was tail-truncated. */
5496
5777
  truncated: boolean;
5497
5778
  };
5498
- /** @description Additive warning codes, e.g. `content_truncated`, `extract_validation_failed`, `exhausted_retries`, `model_refusal`. */
5779
+ /** @description Additive warning codes, e.g. `content_truncated`, `extract_validation_failed`, `exhausted_retries`, `model_refusal`, `empty_extraction`. */
5499
5780
  warnings: string[];
5500
5781
  };
5501
5782
  };
@@ -5602,6 +5883,8 @@ export interface operations {
5602
5883
  credits_single: number;
5603
5884
  credits_bulk: number;
5604
5885
  credits_monitor: number;
5886
+ /** @description Credits drawn under the scrape usage source this billing period, such as `/v1/schema` extractions. `credits_single`, `credits_bulk`, `credits_monitor`, `credits_scrape` and `credits_search` together sum to `credits_used`. */
5887
+ credits_scrape: number;
5605
5888
  /** @description Credits consumed by the search endpoint this billing period. Reported as a distinct line item, not folded into other per-source credit counts. */
5606
5889
  credits_search: number;
5607
5890
  credits_limit: number;
@@ -5619,7 +5902,7 @@ export interface operations {
5619
5902
  plan_type: "payg" | "subscription";
5620
5903
  /** @description Total top-up spend in cents for this billing period. Present only in dual/bytes billing mode. */
5621
5904
  topup_spent_cents?: number;
5622
- /** @description Remaining purchased top-up bytes, already net of any overage consumed against them. Equal to topup_bytes. Present only in dual/bytes billing mode. */
5905
+ /** @description Remaining top-up bytes: the current-plan estimate of what the USD balance buys plus the one-time starter grant, already net of any overage consumed against them. Equal to topup_bytes. Present only in dual/bytes billing mode. */
5623
5906
  topup_balance_bytes?: number;
5624
5907
  /** @description Days elapsed since period_start. */
5625
5908
  period_days_elapsed: number;
@@ -5629,13 +5912,13 @@ export interface operations {
5629
5912
  bytes_bulk: number;
5630
5913
  bytes_scrape: number;
5631
5914
  bytes_monitor: number;
5632
- /** @description The spendable byte budget for this period, summed over the account's value lots: the allowance granted for the current period, plus unspent allowance carried over from earlier periods, plus purchased top-up and starter-grant bytes. The figure falls as those lots are consumed. */
5915
+ /** @description The spendable byte budget for this period, summed over the account's value lots: the allowance granted for the current period, plus unspent allowance carried over from earlier periods, plus the USD balance's current-plan byte estimate and the starter grant. The figure falls as they are consumed. */
5633
5916
  bytes_limit: number;
5634
5917
  /** @description Bytes still available across every active lot, after active refund reservations. */
5635
5918
  bytes_remaining: number;
5636
- /** @description Unspent allowance carried over from earlier billing periods. Value is spent in one order: your plan's included allowance, including any rollover from earlier periods, then purchased top-ups, then the one-time starter grant. */
5919
+ /** @description Unspent allowance carried over from earlier billing periods. Value is spent in one order: your plan's included allowance, including any rollover from earlier periods, then the USD balance, then the one-time starter grant. */
5637
5920
  rollover_bytes: number;
5638
- /** @description Bytes remaining in purchased top-up and starter-grant lots. Subscription allowance is excluded. */
5921
+ /** @description The USD balance's current-plan byte estimate plus the starter grant. Subscription allowance is excluded. */
5639
5922
  topup_bytes: number;
5640
5923
  /** @description Total API requests in the current billing period. */
5641
5924
  request_count: number;
@@ -5681,6 +5964,8 @@ export interface operations {
5681
5964
  credits_single: number;
5682
5965
  credits_bulk: number;
5683
5966
  credits_monitor: number;
5967
+ /** @description Credits drawn under the scrape usage source on this day, such as `/v1/schema` extractions. */
5968
+ credits_scrape: number;
5684
5969
  /** @description Credits consumed by the search endpoint on this day. */
5685
5970
  credits_search: number;
5686
5971
  credits_total: number;
@@ -5771,12 +6056,12 @@ export interface operations {
5771
6056
  /** @description End date (YYYY-MM-DD), inclusive. Default today. */
5772
6057
  to?: string;
5773
6058
  /** @description Filter to a single endpoint kind. */
5774
- endpoint?: "scrape" | "fetch" | "screenshots" | "recordings";
6059
+ endpoint?: "scrape" | "fetch" | "screenshots" | "recordings" | "search" | "webhook";
5775
6060
  /** @description Filter by job outcome. */
5776
6061
  status?: "pending" | "processing" | "completed" | "failed";
5777
- /** @description Case-insensitive substring match on the request URL. */
6062
+ /** @description Case-insensitive substring match on the request URL — the search query on search rows and the target URL on webhook rows. */
5778
6063
  url?: string;
5779
- /** @description Filter by API key (prefixed ID, e.g. `ak_xxx`). The key must belong to the requesting account; cross-account keys return an empty feed. Resolves the account's playground key too. */
6064
+ /** @description Filter by API key (prefixed ID, e.g. `ak_xxx`). The key must belong to the requesting account; cross-account keys return an empty feed. Resolves the account's playground key too. Webhook delivery attempts are not issued by an API key, so this filter excludes them. */
5780
6065
  api_key?: string;
5781
6066
  /** @description Opaque pagination cursor from a prior response's `next_cursor`. */
5782
6067
  cursor?: string;
@@ -5797,35 +6082,40 @@ export interface operations {
5797
6082
  content: {
5798
6083
  "application/json": {
5799
6084
  data: {
5800
- /** @description Prefixed request id (sc_/ss_/rec_). */
6085
+ /** @description Prefixed request id (sc_/ss_/rec_/sr_/wh_). */
5801
6086
  id: string;
5802
- /** @enum {string} */
5803
- endpoint: "scrape" | "fetch" | "screenshots" | "recordings";
5804
- /** @description HTTP method. Not persisted; capture endpoints are POST (so this is always "POST"). /v1/fetch also accepts GET, but the stored row cannot distinguish it. */
6087
+ /**
6088
+ * @description The request kind. `webhook` rows are webhook delivery attempts ByteKit sent to your endpoint, not requests you made.
6089
+ * @enum {string}
6090
+ */
6091
+ endpoint: "scrape" | "fetch" | "screenshots" | "recordings" | "search" | "webhook";
6092
+ /** @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. */
5805
6093
  method: string;
6094
+ /** @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. */
5806
6095
  url: string;
5807
6096
  final_url?: string | null;
5808
6097
  /**
5809
- * @description Job outcome.
6098
+ * @description Job outcome. On a webhook row: `completed` = delivered, `processing` = a failed attempt that will be retried, `failed` = retries exhausted, `pending` = not yet delivered or failed (an attempt may be in flight).
5810
6099
  * @enum {string}
5811
6100
  */
5812
6101
  status: "pending" | "processing" | "completed" | "failed";
5813
- /** @description Upstream target HTTP status; scrape/fetch only. */
6102
+ /** @description Upstream target HTTP status on scrape/fetch rows; the HTTP status your endpoint answered on webhook rows. null on every other row. */
5814
6103
  status_code?: number | null;
5815
6104
  /** @description Raw upstream bytes the request carried (the billing base before the multiplier). null while pending/failed. */
5816
6105
  raw_bytes?: number | null;
5817
- /** @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. It is NOT `raw_bytes` × `billing_multiplier`: that field reports a CREDIT count, a different quantity from the byte factors above, and on a recordings row their product is not bytes at all. 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). */
6106
+ /** @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). */
5818
6107
  billable_bytes?: number | null;
5819
- /** @description BASE billing multiplier persisted for this request — the settled `credits_charged` factor. It is NOT what `billable_bytes` above is derived from: that field reports settled BYTES, and multiplying `raw_bytes` by this credit count does not give the amount billed. Its scale is not uniform and is not a rate you can carry from one row to another: each endpoint persists its own credit unit, and the single and bulk paths of the same endpoint may persist different factors for identical options. Read this as the factor this one row settled at, and see https://bytekit.com/docs/billing/credits for what each endpoint charges. 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). This row reports only the base settled factor, so it can differ from `billing.multiplier` and from the X-Billing-Multiplier response header, both of which report the composed real-endpoint value. null while pending/failed. */
6108
+ /** @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. */
5820
6109
  billing_multiplier?: number | null;
6110
+ /** @description Request duration in milliseconds; on a webhook row, how long your endpoint took to answer the latest attempt. */
5821
6111
  duration_ms?: number | null;
5822
- /** @description How the request originated (single/bulk/monitor). */
5823
- source?: string;
6112
+ /** @description How the request originated (single/bulk/monitor). null on search and webhook rows. */
6113
+ source?: string | null;
5824
6114
  error_code?: string | null;
5825
6115
  error_message?: string | null;
5826
6116
  /** @description Prefixed key id (ak_) that issued the request. */
5827
6117
  api_key_id?: string | null;
5828
- /** @description Stored content, image or video URL — null when the row has no stored object. For a `completed` row with a stored object 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`. The underlying objects are private, so an unsigned URL returns 401: download inside that window, or re-poll this endpoint for a fresh signature. Rows that are not `completed`, and completed rows whose object cannot be signed, fall back to the unsigned stored URL, which returns 401 on download. */
6118
+ /** @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. */
5829
6119
  artifact_url?: string | null;
5830
6120
  /** @description The original request options. */
5831
6121
  options?: {
@@ -5986,81 +6276,10 @@ export interface operations {
5986
6276
  content: {
5987
6277
  "application/json": {
5988
6278
  /**
5989
- * @description Bytes to purchase. Allowed tiers — 5, 25, 50, 75, 100 GB (1 GB = 1,000,000,000 bytes).
5990
- * @enum {integer}
5991
- */
5992
- bytes: 5000000000 | 25000000000 | 50000000000 | 75000000000 | 100000000000;
5993
- /**
5994
- * Format: uri
5995
- * @description Redirect target after a completed Checkout.
5996
- */
5997
- success_url: string;
5998
- /**
5999
- * Format: uri
6000
- * @description Redirect target when the user abandons Checkout.
6001
- */
6002
- cancel_url: string;
6003
- };
6004
- };
6005
- };
6006
- responses: {
6007
- /** @description Hosted Checkout session created. */
6008
- 200: {
6009
- headers: {
6010
- [name: string]: unknown;
6011
- };
6012
- content: {
6013
- "application/json": {
6014
- /** Format: uri */
6015
- checkout_url: string;
6016
- session_id: string;
6017
- };
6018
- };
6019
- };
6020
- /** @description No customer or free plan. */
6021
- 400: {
6022
- headers: {
6023
- [name: string]: unknown;
6024
- };
6025
- content: {
6026
- "application/json": components["schemas"]["Error"];
6027
- };
6028
- };
6029
- /** @description Validation error (missing/invalid fields). */
6030
- 422: {
6031
- headers: {
6032
- [name: string]: unknown;
6033
- };
6034
- content: {
6035
- "application/json": components["schemas"]["Error"];
6036
- };
6037
- };
6038
- /** @description Stripe error creating the Checkout session. */
6039
- 502: {
6040
- headers: {
6041
- [name: string]: unknown;
6042
- };
6043
- content: {
6044
- "application/json": components["schemas"]["Error"];
6045
- };
6046
- };
6047
- };
6048
- };
6049
- createCreditTopup: {
6050
- parameters: {
6051
- query?: never;
6052
- header?: never;
6053
- path?: never;
6054
- cookie?: never;
6055
- };
6056
- requestBody: {
6057
- content: {
6058
- "application/json": {
6059
- /**
6060
- * @description Credits to purchase. Allowed tiers — 1k, 10k, 25k, 50k, 100k.
6279
+ * @description Amount to deposit, in US cents. Allowed amounts — $10, $25, $50, $100, $500. Charged exactly; the plan rate prices usage, not the deposit.
6061
6280
  * @enum {integer}
6062
6281
  */
6063
- credits: 1000 | 10000 | 25000 | 50000 | 100000;
6282
+ amount_cents: 1000 | 2500 | 5000 | 10000 | 50000;
6064
6283
  /**
6065
6284
  * Format: uri
6066
6285
  * @description Redirect target after a completed Checkout.
@@ -6337,7 +6556,10 @@ export interface operations {
6337
6556
  };
6338
6557
  content: {
6339
6558
  "application/json": {
6340
- bandwidth: components["schemas"]["BandwidthBalance"];
6559
+ bandwidth: components["schemas"]["BandwidthBalance"] & {
6560
+ /** @description Remaining balance of your subscription allowance: bytes still unspent across all allowance lots, the current period's and any rolled over from earlier periods alike, after active refund reservations. This is a remaining balance and falls to zero as the allowance is drawn down. It is not `included_bytes`, which is the plan's configured grant for a period and does not move as it is spent; do not subtract one from the other. `rollover_bytes` is a subset of this figure. */
6561
+ remaining_allowance_bytes: number;
6562
+ };
6341
6563
  credits: components["schemas"]["CreditBalance"];
6342
6564
  rates: {
6343
6565
  /** @description Bandwidth top-up price in cents per MB. When the authenticated account is on a plan that does not explicitly configure a top-up price (e.g. free, payg, or a custom plan without an explicit value), the API falls back to the rack rate — the highest `topup_price_per_mb_cents` configured across all plans — so the UI never advertises `$0.00/GB`. */
@@ -6352,10 +6574,17 @@ export interface operations {
6352
6574
  included_bytes?: number;
6353
6575
  /** @description Number of automatic top-up transactions (bandwidth and credit) that have been triggered in the current calendar month. Includes both pending and completed transactions. */
6354
6576
  triggers_this_month?: number;
6577
+ /** @description The account's USD top-up balance. It never expires and is spent on usage beyond the included allowance, at the rate of the plan in force when the usage happens. */
6578
+ usd_balance: {
6579
+ /** @description Balance in whole US cents, rounded down. Can be negative when usage settled after the balance ran out. */
6580
+ cents: number;
6581
+ /** @description Part of `cents` held by an open refund and not spendable, in whole US cents, rounded down. */
6582
+ reserved_cents: number;
6583
+ };
6355
6584
  auto_topup: {
6356
6585
  enabled: boolean;
6357
- threshold_bytes: number | null;
6358
- amount_bytes: number | null;
6586
+ threshold_cents: number | null;
6587
+ amount_cents: number | null;
6359
6588
  monthly_cap_cents: number | null;
6360
6589
  monthly_spend_cents: number;
6361
6590
  };
@@ -6375,15 +6604,12 @@ export interface operations {
6375
6604
  content: {
6376
6605
  "application/json": {
6377
6606
  enabled: boolean;
6378
- /** @description Min 1 MB (1,000,000 bytes). Required when enabled. */
6379
- threshold_bytes?: number;
6380
- /**
6381
- * @description Allowed tiers — 5, 25, 50, 75, 100 GB (1 GB = 1,000,000,000 bytes). Required when enabled.
6382
- * @enum {integer}
6383
- */
6384
- amount_bytes?: 5000000000 | 25000000000 | 50000000000 | 75000000000 | 100000000000;
6385
- /** @description $1-$1000. Required when enabled. */
6386
- monthly_cap_cents?: number;
6607
+ /** @description Top up when the remaining value (plan allowance plus USD balance, priced at the plan's top-up rate) drops below this many US cents. Min $1. Required when enabled. */
6608
+ threshold_cents?: number;
6609
+ /** @description US cents added to the USD balance on each auto top-up, $5-$1000. Required when enabled. */
6610
+ amount_cents?: number;
6611
+ /** @description $1-$1000, or null for no monthly cap. Required when enabled — send an explicit null to remove the cap; omitting the key is rejected. */
6612
+ monthly_cap_cents?: number | null;
6387
6613
  };
6388
6614
  };
6389
6615
  };
@@ -6396,8 +6622,8 @@ export interface operations {
6396
6622
  content: {
6397
6623
  "application/json": {
6398
6624
  enabled: boolean;
6399
- threshold_bytes: number | null;
6400
- amount_bytes: number | null;
6625
+ threshold_cents: number | null;
6626
+ amount_cents: number | null;
6401
6627
  monthly_cap_cents: number | null;
6402
6628
  };
6403
6629
  };