Topolo Docs Topolo Platform
Open workspace

Find placeable form references

Search authorized draft and published form projections, using returned pagination without assuming bounded backend work.

Outcome

Search authorized draft and published form projections, using returned pagination without assuming bounded backend work.

GET /api/forms/references

Before you start

Use the original authorized organization and discovered canonical Forms workspace, bound separately as a resource. The action needs workspace:read and verified read workspace access; a form/reference id or optional workspaceId input is not a grant.

These authenticated Connected Apps reads include drafts and are distinct from public form access. A returned reference projection, URL or embed URL does not create a placement, join a workspace, grant a recipient access or authorize publication/submission.

All examples are complete source-derived synthetic responses, unrun. Fictional ids and reserved example.test URLs authorize no operation. No real form/subject/placement/Auth/resource/provider/model/notification call or browser navigation was performed. Source declaration provenance, actual serving, domains, protection health and browser rendering remain separate.

Request and response

Action: app_topolo_forms.forms.references.list.

Input supports q,cursor,limit and optional workspaceId. The handler trims/lowercases q, matches title substring or exact case-insensitive id, and keeps listForms order by updated_at descending. It includes drafts; there is no implicit published-only filter.

Response is HTTP200 {items:[projection...],nextCursor:string|null}. Default limit25, maximum100. The source interprets a numeric-string cursor as an offset, slices the matching array and returns the next offset when more matches exist. Reuse the returned cursor unchanged; input schema rejects non-digit tokens and out-of-range limits.

Pagination happens after listForms loads every workspace form, performs a separate submission COUNT per form and decodes protected content. A page limit does not bound the database/decryption work. The offset is not a versioned snapshot and equal updated_at values have no stable tie-breaker; concurrent changes can shift results between pages.

The source first reads full scoped form models through the existing protected content/count path, then projects only id,label,status,updatedAt,publishedAt,workspace,url,embedUrl. Projection does not mean the underlying work is a cheap metadata-only query. Protection, auth or database errors are not an empty result.

Label is stored title with id fallback. Published status plus a nonempty configured public base produces /public/<encoded form id> and /embed/<encoded form id>; otherwise both URLs are null. Drafts remain discoverable with draft status and null URLs. A published record can also have null URLs when no public base is configured.

The projection carries plain form id, not a returned topolo: reference URI. The source canonical format is topolo:<appId>/<workspaceId>/forms.form/<formId> for validated components, but actual placement/reference discovery must use supported credential-scoped Connected Apps actions and resolved identities; never manufacture cross-context ids or invent a placement grant.

Reading these actions performs no form edit, publication, placement mutation, respondent submission or reference notification. Conditional change/removal events occur in separate mutation paths; their source declarations do not prove a consumer received an event or rendered an embed.

Complete worked responses

First reference page

Complete source-derived synthetic, unrun HTTP200. Assumes exactly the published fixture and older draft fixture match, successful original auth/workspace/read checks and readable content. Configured public base is https://forms.example.test, a fictional domain.

Input:

{
  "limit": 1
}

Response:

{
  "items": [
    {
      "id": "forms_docs_fixture",
      "label": "Fixture feedback",
      "status": "published",
      "updatedAt": "2026-10-21T01:00:00.000Z",
      "publishedAt": "2026-10-02T08:00:00.000Z",
      "workspace": "ws_forms_docs_fixture",
      "url": "https://forms.example.test/public/forms_docs_fixture",
      "embedUrl": "https://forms.example.test/embed/forms_docs_fixture"
    }
  ],
  "nextCursor": "1"
}

Verify the actual target and publication/URL semantics below; this fixture creates no reference placement or access.

Continue the same fictional page sequence

Complete source-derived synthetic, unrun HTTP200. Assumes the same unchanged two-record matching order as the first example. Draft is discoverable but its URLs remain null; this is not a public-access grant.

Input:

{
  "limit": 1,
  "cursor": "1"
}

Response:

{
  "items": [
    {
      "id": "forms_draft_docs_fixture",
      "label": "Fixture draft",
      "status": "draft",
      "updatedAt": "2026-10-20T01:00:00.000Z",
      "publishedAt": null,
      "workspace": "ws_forms_docs_fixture",
      "url": null,
      "embedUrl": null
    }
  ],
  "nextCursor": null
}

Verify the actual target and publication/URL semantics below; this fixture creates no reference placement or access.

No search matches

Complete source-derived synthetic, unrun HTTP200. Assumes successful underlying reads with no title/id match. This does not represent a suppressed permission or protection failure.

Input:

{
  "q": "no-match-docs-fixture"
}

Response:

{
  "items": [],
  "nextCursor": null
}

Verify the actual target and publication/URL semantics below; this fixture creates no reference placement or access.

Verify and recover

  1. Compare every returned workspace with the original authorized resource. Keep ids/status/URLs distinct and stop on an unexpected context.

  2. Reuse nextCursor only for the same intended query/resource, stopping at null. Reconcile changes or duplicates under concurrent edits rather than treating offset pages as an immutable inventory.

This read needs no data rollback. On a failure preserve the actual request id and sanitized response for the owner; do not create a workspace, publish a draft, change protection or submit real data as recovery.

Refusals

400 / workspace_required: Resolve the real canonical workspace through supported Auth and bind it separately, without a guessed resource.

403 / forbidden: Retain the original caller/context and actual denial; use the owner for legitimate read access.

400 / invalid_cursor: Use the unchanged returned cursor for the same resource/query; the source also rejects unsafe numeric offsets. Invalid strict-schema input is refused locally before transport.

400 / invalid_limit: Use a current schema-valid integer1..100, default25. Do not imply this bounds underlying collection/count/decryption work.

Shared runtime/Auth/protection errors require their actual carrier evidence; the success schema does not describe every failure.

Change log

  • 2026-10-21: Added precise reference projection, original workspace/privacy boundaries, draft/URL semantics, source pagination limits and complete illustrative responses. All examples remain synthetic and unrun.