From 0a781da687588e113f2df392babb8a6a197702c1 Mon Sep 17 00:00:00 2001 From: Andrew Harris Date: Wed, 1 Jul 2026 08:14:42 +0100 Subject: [PATCH 1/5] docs(build-plugin): document webLink paging realm and nextUrl absolute-URL requirement MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit The webLink realm (Link-header pagination) is used by every GitHub and Checkly nextUrl stream but wasn't documented at all. Also note that the extracted next-page value is used verbatim as the next request URL, so it must be absolute — relative URLs aren't handled by the runtime. --- .../skills/build-plugin/references/data-streams.md | 14 ++++++++++++++ 1 file changed, 14 insertions(+) diff --git a/.claude/skills/build-plugin/references/data-streams.md b/.claude/skills/build-plugin/references/data-streams.md index 1e4a94e4..42ad4513 100644 --- a/.claude/skills/build-plugin/references/data-streams.md +++ b/.claude/skills/build-plugin/references/data-streams.md @@ -402,6 +402,20 @@ The `paging` block in `config` controls how SquaredUp fetches multiple pages. } ``` +**Next-URL via `Link` header** — API returns pagination links in a standard HTTP `Link` header (RFC 8288) instead of the body, e.g. GitHub, Checkly: + +```json +"paging": { + "mode": "nextUrl", + "pageSize": { "realm": "queryArg", "path": "per_page", "value": "100" }, + "in": { "realm": "webLink", "path": "next" } +} +``` + +> ⚠️ For `realm: "webLink"`, `path` is the link's **rel name** (`next`, `prev`, `last`, `first`), not a JSON path — the server parses the `Link` header and looks up that rel. This differs from every other realm, where `path` is a dot-notation path or header name. + +> ⚠️ Whatever value `in` extracts (`payload`, `header`, or `webLink`) is used as the **complete URL for the next request** — it is not appended to `baseUrl`/`endpointPath`. The API must return a fully-qualified URL; a relative path will break pagination. + **Token** — API returns a cursor/token to send with the next request: ```json From cb5d5880da11a9fc8d25abcbefe7075487a78e6f Mon Sep 17 00:00:00 2001 From: Andrew Harris Date: Wed, 1 Jul 2026 08:15:03 +0100 Subject: [PATCH 2/5] docs(build-plugin): warn that body-realm paging needs an object postBody paging.out/pageSize with realm "body" writes into postBody via a path-based set that's a no-op against a string. The POST-requests section documents postBody-as-string as valid, so call out the silent-failure interaction explicitly where it applies. --- .claude/skills/build-plugin/references/data-streams.md | 2 ++ 1 file changed, 2 insertions(+) diff --git a/.claude/skills/build-plugin/references/data-streams.md b/.claude/skills/build-plugin/references/data-streams.md index 42ad4513..f7352c93 100644 --- a/.claude/skills/build-plugin/references/data-streams.md +++ b/.claude/skills/build-plugin/references/data-streams.md @@ -360,6 +360,8 @@ In OOB dashboard tiles, set the stream parameter in the tile's `dataStream` conf } ``` +> ⚠️ **`postBody` must be a JSON object, not a string, if [`paging`](#pagination) uses `realm: "body"`.** The server writes the page-size/cursor/offset value into the body with a path-based `set` that only runs against an object — against a string `postBody` it silently does nothing, and the request goes out without the paging value, with no error. + --- ## expandInnerObjects From 6e50674747e243fc06e62e38119f3e9b94a3cbf9 Mon Sep 17 00:00:00 2001 From: Andrew Harris Date: Wed, 1 Jul 2026 08:15:28 +0100 Subject: [PATCH 3/5] docs(build-plugin): note pageSize is optional in paging config Every prior example includes pageSize, implying it's required. In practice many nextUrl streams (e.g. all of AutoTask's) omit it because the returned URL already encodes the page size. --- .claude/skills/build-plugin/references/data-streams.md | 9 +++++++++ 1 file changed, 9 insertions(+) diff --git a/.claude/skills/build-plugin/references/data-streams.md b/.claude/skills/build-plugin/references/data-streams.md index f7352c93..843ea228 100644 --- a/.claude/skills/build-plugin/references/data-streams.md +++ b/.claude/skills/build-plugin/references/data-streams.md @@ -418,6 +418,15 @@ The `paging` block in `config` controls how SquaredUp fetches multiple pages. > ⚠️ Whatever value `in` extracts (`payload`, `header`, or `webLink`) is used as the **complete URL for the next request** — it is not appended to `baseUrl`/`endpointPath`. The API must return a fully-qualified URL; a relative path will break pagination. +`pageSize` is optional on every mode — omit it (or set `"pageSize": { "realm": "none" }`) when the API has no separate page-size parameter, e.g. a `nextUrl` response whose URL already encodes the page size: + +```json +"paging": { + "mode": "nextUrl", + "in": { "realm": "payload", "path": "pageDetails.nextPageUrl" } +} +``` + **Token** — API returns a cursor/token to send with the next request: ```json From 96410ba86c33dab241e959e97a3aae8e249263f0 Mon Sep 17 00:00:00 2001 From: Andrew Harris Date: Wed, 1 Jul 2026 08:15:49 +0100 Subject: [PATCH 4/5] docs(build-plugin): clarify root-array path convention for payload paging payload/payloadArraySize paths use a literal "." for a root-level array, which looks like the pathToData convention but isn't the same (pathToData is omitted for a root array; paging paths are not). --- .claude/skills/build-plugin/references/data-streams.md | 2 ++ 1 file changed, 2 insertions(+) diff --git a/.claude/skills/build-plugin/references/data-streams.md b/.claude/skills/build-plugin/references/data-streams.md index 843ea228..4df84f2d 100644 --- a/.claude/skills/build-plugin/references/data-streams.md +++ b/.claude/skills/build-plugin/references/data-streams.md @@ -453,6 +453,8 @@ The `paging` block in `config` controls how SquaredUp fetches multiple pages. } ``` +> For a `payload`/`payloadArraySize` path (`in`, `rowCountIn`), use `"."` to mean "the response body itself is the array" — unlike [`pathToData`](#pathtodata), where a root-level array means omitting the field entirely, an empty/omitted `path` here is not equivalent to `"."`. + `realm` options: `"queryArg"`, `"header"`, `"body"` (POST only), `"payload"`, `"payloadArraySize"`. `offset.mode`: `"page"` (increments 1,2,3…) or `"row"` (increments by page size). From e308888b5401b5ca1933b2947b349998f1597d61 Mon Sep 17 00:00:00 2001 From: Andrew Harris Date: Wed, 1 Jul 2026 08:16:13 +0100 Subject: [PATCH 5/5] docs(build-plugin): replace misleading combined realm-options list with a per-field table MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit The single "realm options: queryArg, header, body, payload, payloadArraySize" line implied one shared enum, but each paging field (pageSize, out, in, rowCountIn) actually accepts a different subset — queryArg is never valid for in/rowCountIn, and payload/payloadArraySize are never valid for pageSize/out. Following the old line would produce a config that fails schema validation with no indication why. --- .../skills/build-plugin/references/data-streams.md | 13 +++++++++++-- 1 file changed, 11 insertions(+), 2 deletions(-) diff --git a/.claude/skills/build-plugin/references/data-streams.md b/.claude/skills/build-plugin/references/data-streams.md index 4df84f2d..8c220cd1 100644 --- a/.claude/skills/build-plugin/references/data-streams.md +++ b/.claude/skills/build-plugin/references/data-streams.md @@ -455,8 +455,17 @@ The `paging` block in `config` controls how SquaredUp fetches multiple pages. > For a `payload`/`payloadArraySize` path (`in`, `rowCountIn`), use `"."` to mean "the response body itself is the array" — unlike [`pathToData`](#pathtodata), where a root-level array means omitting the field entirely, an empty/omitted `path` here is not equivalent to `"."`. -`realm` options: `"queryArg"`, `"header"`, `"body"` (POST only), `"payload"`, `"payloadArraySize"`. -`offset.mode`: `"page"` (increments 1,2,3…) or `"row"` (increments by page size). +**`realm` options differ per field — they are not interchangeable:** + +| Field | Valid `realm` values | +| ----------------------------------- | ----------------------------------------- | +| `pageSize` | `none`, `queryArg`, `header`, `body` (POST only) | +| `out` (token/offset) | `queryArg`, `header`, `body` (POST only) | +| `in` on `nextUrl` | `header`, `payload`, `webLink` | +| `in` on `token` | `header`, `payload` | +| `offset.rowCountIn` | `header`, `payload`, `payloadArraySize` | + +`offset.mode`: `"page"` (increments 1,2,3…) or `"row"` (increments by the number of rows actually returned, read via `rowCountIn` — not necessarily the configured `pageSize`). ---