Support/Builder Guide/Headless application guide and copy/paste kit

Builder Guide

Headless application guide and copy/paste kit

Build a custom frontend over BuildWithHQ authentication, scoped APIs, first-class modules, Inbox, Workflow, Files and exact server-side authorization.

Open raw .md
Capabilities
25
Page routes
269
Additional routes
105

A headless BuildWithHQ application replaces the native page presentation with your own React, Vue, mobile, desktop, or server-rendered interface. It does not replace authentication, tenant routing, DataRoles, Locations, stored-procedure contracts, audit, rate limits, files, Workflow, Inbox, or AI authorization.

Note

This guide is generated from the same catalog as the native React kit: 25 capabilities, 269 page-module routes, and 105 additional tenant/Design routes. It does not invent a second backend.

1. Choose the correct headless boundary

CallerUseDo not do
Custom tenant browser UIThe current same-origin tenant session plus the typed tenant APIs cataloged below.Do not store the access token in localStorage or submit tenant/database identity as authorization.
External server or integrationThe published Developer Platform, app-bound credentials, generated OpenAPI and versioned gateway routes. Exchange an external subject for a short-lived delegated-user token when a browser must call modules directly.Do not place the long-lived bwk_live_ app key in browser/mobile bundles or call internal tenant routes as an unauthenticated proxy.
Custom appliance serviceA declared installed-service endpoint with reviewed egress, secret references, action permissions and correlation.Do not expose provider credentials, unrestricted SQL or tenant infrastructure to the frontend.
Important

The generated transport below intentionally accepts only same-origin /api/ paths. If the frontend runs on another origin, use the published Developer API contract and its supported authentication/CORS boundary; do not weaken this check.

External identity and delegated-user tokens

The Developer API can create AppAccounts and passwordless TenantUsers, assign DataRoles and Locations, and exchange the ISV's authenticated external subject for a 2–15 minute bwu_live_ token. The app key remains on the trusted server. The delegated token carries no database route or caller-supplied authorization, cannot manage identities, and is rechecked against the current parent grant and active TenantUser on use.

Use tenant-accounts.read/write, tenant-users.read/write, and tenant-users.tokens.issue only on the trusted server. Use module read/write scopes on the short token. Revocation is immediate, and deactivating a user revokes all active tokens for that app/account/user.

2. Copy the same-origin transport

The transport adds the current in-memory bearer token, delegates unsafe-method CSRF handling to the existing security helper, assigns a correlation ID, preserves server-side status/code/error/correlation details, clears local session state on 401, and never accepts a database name.


export type HeadlessMethod = "GET" | "POST" | "PUT" | "PATCH" | "DELETE";

export interface HeadlessRequest {
  readonly method?: HeadlessMethod;
  readonly body?: unknown;
  readonly signal?: AbortSignal;
  readonly headers?: Readonly<Record<string, string>>;
}

export interface HeadlessTransportOptions {
  readonly accessToken: () => string | null | undefined;
  readonly fetchImplementation?: typeof fetch;
  readonly applyCsrfHeader?: (headers: Headers, method: string) => void;
  readonly onUnauthorized?: () => void;
}

export interface HeadlessTransport {
  request<T>(path: string, request?: HeadlessRequest): Promise<T>;
}

export class HeadlessApiError extends Error {
  public constructor(
    message: string,
    public readonly status: number,
    public readonly code: string,
    public readonly correlationId?: string,
    public readonly retryAfterSeconds?: number,
  ) { super(message); this.name = "HeadlessApiError"; }
}

const sameOriginApiPath = (path: string): string => {
  if (!path.startsWith("/api/") || path.includes("://") || path.includes("#") || path.length > 4000) {
    throw new TypeError("Headless tenant requests require a bounded same-origin /api/ path.");
  }
  return path;
};

const readProblem = async (response: Response): Promise<HeadlessApiError> => {
  let body: Record<string, unknown> = {};
  try { body = await response.json() as Record<string, unknown>; } catch { /* safe fallback below */ }
  const retryHeader = Number(response.headers.get("Retry-After"));
  const retryBody = Number(body.retryAfterSeconds);
  const retryAfterSeconds = Number.isFinite(retryBody) ? retryBody : Number.isFinite(retryHeader) ? retryHeader : undefined;
  return new HeadlessApiError(
    typeof body.error === "string" ? body.error : `Request failed (${response.status}).`,
    response.status,
    typeof body.code === "string" ? body.code : "request_failed",
    typeof body.correlationId === "string" ? body.correlationId : response.headers.get("X-Correlation-ID") ?? undefined,
    retryAfterSeconds,
  );
};

export const createSameOriginHeadlessTransport = (options: HeadlessTransportOptions): HeadlessTransport => {
  const fetchImplementation = options.fetchImplementation ?? globalThis.fetch;
  if (!fetchImplementation) throw new TypeError("A fetch implementation is required.");
  return {
    async request<T>(path: string, request: HeadlessRequest = {}): Promise<T> {
      const method = request.method ?? "GET";
      const headers = new Headers({ Accept: "application/json", ...request.headers });
      const token = options.accessToken();
      if (!token) { options.onUnauthorized?.(); throw new HeadlessApiError("Sign in before loading tenant data.", 401, "tenant_session_required"); }
      headers.set("Authorization", `Bearer ${token}`);
      headers.set("X-Correlation-ID", crypto.randomUUID());
      if (request.body !== undefined) headers.set("Content-Type", "application/json");
      options.applyCsrfHeader?.(headers, method);
      const response = await fetchImplementation(sameOriginApiPath(path), {
        method,
        credentials: "same-origin",
        headers,
        body: request.body === undefined ? undefined : JSON.stringify(request.body),
        signal: request.signal,
      });
      if (response.status === 401) options.onUnauthorized?.();
      if (!response.ok) throw await readProblem(response);
      if (response.status === 204) return undefined as T;
      return await response.json() as T;
    },
  };
};

/* In apps/tenant-runtime, inject getTenantAccessToken, applyCsrfHeader and
   clearTenantSession. Keep refresh/session rotation in the official auth client. */

Wire it to the official tenant session

import { clearTenantSession, getTenantAccessToken } from "./api";
import { applyCsrfHeader } from "./webSecurity";
import { createSameOriginHeadlessTransport } from "./HeadlessTransport";

export const transport = createSameOriginHeadlessTransport({
  accessToken: getTenantAccessToken,
  applyCsrfHeader,
  onUnauthorized: clearTenantSession,
});

// Keep login, refresh rotation, logout and session restore in the official
// tenant auth client. The custom component consumes only this transport.

Let the existing login/refresh client own refresh-cookie rotation and session restore. A 401 should return the app to its sign-in state; a 403 is an authorization denial, 404 keeps absent and foreign identifiers indistinguishable, 409 requires reloading stale state, and 429 requires honoring the retry window.

3. Working, paginated read/write example

This example requests exactly one 25-row page from /api/modules/contacts, parses the response through parseContactList, creates through the reviewed POST contract, validates the receipt with parseContactMutation, aborts obsolete reads, and never fetches a full table to filter in React.


import { useEffect, useState, type FormEvent } from "react";
import {
  contactsModule,
  parseContactList,
  parseContactMutation,
  type ContactList,
} from "@buildwithhq/module-sdk";
import type { HeadlessTransport } from "./HeadlessTransport";

export interface HeadlessContactsExampleProps {
  readonly transport: HeadlessTransport;
  readonly styled?: boolean;
}

export const HeadlessContactsExample = ({ transport, styled = false }: HeadlessContactsExampleProps) => {
  const [page, setPage] = useState(1);
  const [search, setSearch] = useState("");
  const [result, setResult] = useState<ContactList>();
  const [error, setError] = useState<string>();
  const [refresh, setRefresh] = useState(0);
  const [firstName, setFirstName] = useState("");
  const [lastName, setLastName] = useState("");
  const [email, setEmail] = useState("");

  useEffect(() => {
    const controller = new AbortController();
    const query = new URLSearchParams({ pageNumber: String(page), pageSize: "25" });
    if (search.trim()) query.set("search", search.trim());
    setError(undefined);
    void transport.request<unknown>(`${contactsModule.apiBasePath}?${query}`, { signal: controller.signal })
      .then((value) => setResult(parseContactList(value)))
      .catch((failure: unknown) => { if (!controller.signal.aborted) setError(failure instanceof Error ? failure.message : "Contacts unavailable."); });
    return () => controller.abort();
  }, [page, refresh, search, transport]);

  const create = async (event: FormEvent) => {
    event.preventDefault(); setError(undefined);
    try {
      const value = await transport.request<unknown>(contactsModule.apiBasePath, {
        method: "POST", body: { firstName, lastName, email },
      });
      parseContactMutation(value);
      setFirstName(""); setLastName(""); setEmail(""); setPage(1); setRefresh((value) => value + 1);
    } catch (failure) { setError(failure instanceof Error ? failure.message : "Contact could not be created."); }
  };

  return <section className={styled ? "bwhq-headless-resource" : undefined}>
    <header><div><p>Headless first-class module</p><h2>Contacts</h2></div><label>Search visible contacts<input type="search" value={search} onChange={(event) => { setSearch(event.target.value); setPage(1); }} /></label></header>
    {error && <p role="alert">{error}</p>}
    {!result && !error && <p role="status">Loading contacts…</p>}
    {result && <><ul>{result.items.map((contact) => <li key={contact.recordId}><strong>{contact.title}</strong><span>{contact.email || contact.companyName || "No secondary value"}</span></li>)}</ul><nav aria-label="Contact pages"><button disabled={page <= 1} onClick={() => setPage((value) => value - 1)} type="button">Previous</button><span>Page {result.pageNumber} of {Math.max(1, result.totalPages)}</span><button disabled={page >= result.totalPages} onClick={() => setPage((value) => value + 1)} type="button">Next</button></nav></>}
    <form onSubmit={(event) => void create(event)}><h3>Create a contact</h3><label>First name<input value={firstName} onChange={(event) => setFirstName(event.target.value)} /></label><label>Last name<input value={lastName} onChange={(event) => setLastName(event.target.value)} /></label><label>Email<input type="email" value={email} onChange={(event) => setEmail(event.target.value)} /></label><button type="submit">Create contact</button></form>
  </section>;
};

Use it

import { HeadlessContactsExample } from "./HeadlessContactsExample";
import { transport } from "./transport";

export const ContactsPage = () => (
  <HeadlessContactsExample transport={transport} styled />
);
Tip

Copy the pattern, not the Contacts field names: bounded query parameters, unknown JSON at the transport boundary, official SDK parser, server pagination, explicit loading/empty/error states, and one narrow mutation receipt.

4. Headless data bindings

For custom page-shaped projections, request a reviewed binding key. The server resolves it to an approved sp_ds_* contract and applies the signed-in identity. The client does not send SQL, a procedure name, a SaaS ID, or a database selector.

import { parseRuntimeDataBinding } from "@buildwithhq/page-runtime";
import { transport } from "./transport";

export const loadOpenWork = async (signal: AbortSignal) => {
  const bindingKey = "work.open";
  const raw = await transport.request<unknown>(
    `/api/runtime/data/${encodeURIComponent(bindingKey)}`,
    { signal },
  );
  return parseRuntimeDataBinding(raw, bindingKey).data;
};

Embed a published page from an external application

Developer Kit 1.16.0 adds BuildWithHQRuntimeClient for a short-lived bwu_live_ token. getPageBody returns components + page without menus or shell; getPageBootstrap returns the complete shell + components + page. Body reads omit page design tokens by default so the host theme wins.

Grant runtime.pages.read for either page read and runtime.bindings.read for resolveBindings. The batch accepts 1-24 unique keys. These public routes reuse the native page resolution, entitlement fallback, binding procedures, DataRole/Location filters, record authorization, tenant routing, and page audit.

5. Universal Inbox, support tickets and GoClaw

The official package exposes typed clients independently from its native UI. A headless component can consume those clients for bounded queues, ticket-only views, badge/notifications, email ticketing settings, human state, Workflow decisions and GoClaw review work. Use the native components when you want the complete lifecycle without reimplementing every control.

import {
  createApprovalQueueHttpClient,
  createUniversalInboxHttpClient,
} from "@buildwithhq/universal-inbox";
import { ensureCsrfToken } from "./webSecurity";
import { getTenantAccessToken } from "./api";
import {
  HeadlessApprovalQueueStarter,
  HeadlessInboxQueueStarter,
} from "./UniversalInboxStarters";

const inboxClient = createUniversalInboxHttpClient({
  accessToken: getTenantAccessToken,
  csrfToken: ensureCsrfToken,
});
const approvalClient = createApprovalQueueHttpClient({
  accessToken: getTenantAccessToken,
  csrfToken: ensureCsrfToken,
});

export const SupportQueue = () => (
  <HeadlessInboxQueueStarter client={inboxClient} ticketingOnly styled />
);
export const AiReviewQueue = () => (
  <HeadlessApprovalQueueStarter client={approvalClient} styled />
);
Copy all native and headless Inbox/GoClaw starters

import { useEffect, useState } from "react";

export interface InboxQueueItem {
  readonly inboxItemId: string;
  readonly source: { readonly sourceType: string };
  readonly subject?: string | null;
  readonly previewText?: string | null;
  readonly status: string;
  readonly ticket?: { readonly key?: string | null } | null;
}
export interface UniversalInboxClient {
  list(request: { readonly ticketingOnly?: boolean; readonly assignedToMe?: boolean; readonly topN: number }, signal?: AbortSignal): Promise<readonly InboxQueueItem[]>;
}
export interface ApprovalQueueItem {
  readonly suggestionBatchId: string;
  readonly subject?: string | null;
  readonly summary?: string | null;
  readonly sourceType?: string | null;
  readonly batchStatus: string;
  readonly isStale: boolean;
}
export interface ApprovalQueueClient {
  list(top: number, signal?: AbortSignal): Promise<readonly ApprovalQueueItem[]>;
}

interface InboxStarterProps {
  readonly client: UniversalInboxClient;
  readonly ticketingOnly?: boolean;
  readonly assignedToMe?: boolean;
  readonly onOpen?: (inboxItemId: string) => void;
  readonly styled?: boolean;
}

export const HeadlessInboxQueueStarter = ({ client, ticketingOnly, assignedToMe, onOpen, styled = false }: InboxStarterProps) => {
  const [items, setItems] = useState<readonly InboxQueueItem[]>([]);
  const [error, setError] = useState<string>();
  const [loading, setLoading] = useState(true);
  useEffect(() => {
    const controller = new AbortController();
    setLoading(true); setError(undefined);
    void client.list({ ticketingOnly, assignedToMe, topN: 100 }, controller.signal)
      .then(setItems)
      .catch((failure: unknown) => { if (!controller.signal.aborted) setError(failure instanceof Error ? failure.message : "Inbox unavailable."); })
      .finally(() => { if (!controller.signal.aborted) setLoading(false); });
    return () => controller.abort();
  }, [assignedToMe, client, ticketingOnly]);
  return <section aria-busy={loading} className={styled ? "bwhq-headless-list" : undefined}>
    <h2>{ticketingOnly ? "Support tickets" : "Universal Inbox"}</h2>
    {loading && <p role="status">Loading inbox…</p>}
    {error && <p role="alert">{error}</p>}
    {!loading && !error && items.length === 0 && <p>No visible work.</p>}
    <ul>{items.map((item) => <li key={item.inboxItemId}><button type="button" onClick={() => onOpen?.(item.inboxItemId)}><strong>{item.ticket?.key ? item.ticket.key + " · " : ""}{item.subject || item.source.sourceType}</strong><span>{item.status} · {item.previewText || "No preview"}</span></button></li>)}</ul>
  </section>;
};

interface ApprovalStarterProps {
  readonly client: ApprovalQueueClient;
  readonly onOpen?: (item: ApprovalQueueItem) => void;
  readonly styled?: boolean;
}

export const HeadlessApprovalQueueStarter = ({ client, onOpen, styled = false }: ApprovalStarterProps) => {
  const [items, setItems] = useState<readonly ApprovalQueueItem[]>([]);
  const [error, setError] = useState<string>();
  useEffect(() => {
    const controller = new AbortController();
    void client.list(100, controller.signal).then(setItems)
      .catch((failure: unknown) => { if (!controller.signal.aborted) setError(failure instanceof Error ? failure.message : "Approval queue unavailable."); });
    return () => controller.abort();
  }, [client]);
  return <section className={styled ? "bwhq-headless-list" : undefined}>
    <h2>GoClaw approval work</h2>{error && <p role="alert">{error}</p>}
    <ul>{items.map((item) => <li key={item.suggestionBatchId}><button type="button" onClick={() => onOpen?.(item)}><strong>{item.subject || item.summary || item.sourceType}</strong><span>{item.batchStatus}{item.isStale ? " · stale" : ""}</span></button></li>)}</ul>
  </section>;
};

/* Self-contained starter aliases: no unpublished product package is required. */
export const BareNativeUniversalInbox = (props: { readonly client: UniversalInboxClient; readonly initialInboxItemId?: string }) =>
  <HeadlessInboxQueueStarter client={props.client} />;
export const FramedNativeUniversalInbox = (props: { readonly client: UniversalInboxClient; readonly initialInboxItemId?: string }) =>
  <div className="bwhq-native-frame"><HeadlessInboxQueueStarter client={props.client} styled /></div>;
export const BareNativeGoClawApprovalQueue = (props: { readonly client: ApprovalQueueClient }) =>
  <HeadlessApprovalQueueStarter client={props.client} />;
export const FramedNativeGoClawApprovalQueue = (props: { readonly client: ApprovalQueueClient }) =>
  <div className="bwhq-native-frame"><HeadlessApprovalQueueStarter client={props.client} styled /></div>;
Important

The headless list starters demonstrate reads and selection. They do not silently implement ticket resolution, proof/file handling, Workflow approval, GoClaw edits or delivery retry. Call the corresponding typed client method only from an explicit UI action and preserve ActivityVersion/stale-state inputs.

6. Menus and the custom workspace shell

Use the server-returned User Type menu as route eligibility, then render it in your design. Menu visibility is not record permission. The current shell starter stays left aligned and expands the center while allowing an optional 280px context panel.

import { BuildWithHQMenu } from "./BuildWithHQMenu";
import { StyledTenantWorkspaceShell } from "./TenantWorkspaceShell";

export const AppShell = ({ menu, pageKey, children }) => (
  <StyledTenantWorkspaceShell
    applicationName="Your SaaS"
    pageTitle="Workspace"
    menu={<BuildWithHQMenu
      items={menu}
      activePageKey={pageKey}
      resolvePageHref={(key) => `/?page=${encodeURIComponent(key)}`}
      styled
    />}
    contextPanel={<p>Page-specific context belongs here.</p>}
  >
    {children}
  </StyledTenantWorkspaceShell>
);
Copy the complete menu component

import type { ReactNode } from "react";

export interface BuildWithHQMenuItem {
  readonly id: string;
  readonly parentId?: string | null;
  readonly label: string;
  readonly iconKey?: string | null;
  readonly targetType: "Page" | "Group" | "Module" | "External";
  readonly pageKey?: string | null;
  readonly url?: string | null;
  readonly sortOrder: number;
}

export interface BuildWithHQMenuProps {
  readonly items: readonly BuildWithHQMenuItem[];
  readonly activePageKey?: string;
  readonly resolvePageHref: (pageKey: string) => string;
  readonly icon?: (iconKey: string) => ReactNode;
  readonly styled?: boolean;
}

const safeExternalUrl = (value: string | null | undefined): string | undefined => {
  if (!value || value.length > 2000) return undefined;
  try {
    const url = new URL(value);
    return url.protocol === "https:" && !url.username && !url.password ? url.toString() : undefined;
  } catch { return undefined; }
};

export const BuildWithHQMenu = ({ items, activePageKey, resolvePageHref, icon, styled = false }: BuildWithHQMenuProps) => {
  const roots = items.filter((item) => !item.parentId).sort((left, right) => left.sortOrder - right.sortOrder);
  const renderItem = (item: BuildWithHQMenuItem): ReactNode => {
    const children = items.filter((candidate) => candidate.parentId === item.id).sort((left, right) => left.sortOrder - right.sortOrder);
    if (item.targetType === "Group") return <li key={item.id}><span>{item.iconKey && icon?.(item.iconKey)}{item.label}</span>{children.length > 0 && <ul>{children.map(renderItem)}</ul>}</li>;
    const href = item.targetType === "Page" && item.pageKey ? resolvePageHref(item.pageKey)
      : item.targetType === "External" ? safeExternalUrl(item.url) : undefined;
    return <li key={item.id}>{href ? <a href={href} aria-current={item.pageKey === activePageKey ? "page" : undefined}>{item.iconKey && icon?.(item.iconKey)}{item.label}</a> : <span aria-disabled="true">{item.label}</span>}</li>;
  };
  return <nav aria-label="Application" className={styled ? "bwhq-app-menu" : undefined}><ul>{roots.map(renderItem)}</ul></nav>;
};
Copy the complete workspace shell

import type { ReactNode } from "react";

export interface TenantWorkspaceShellProps {
  readonly applicationName: string;
  readonly pageTitle: string;
  readonly menu: ReactNode;
  readonly children: ReactNode;
  readonly headerActions?: ReactNode;
  readonly contextPanel?: ReactNode;
  readonly styled?: boolean;
}

const TenantWorkspaceShellBody = ({ applicationName, pageTitle, menu, children, headerActions, contextPanel, styled = false }: TenantWorkspaceShellProps) => (
  <div className={styled ? "bwhq-workspace" : undefined}>
    <header className={styled ? "bwhq-workspace__header" : undefined}>
      <div><p>{applicationName}</p><h1>{pageTitle}</h1></div>
      {headerActions && <div aria-label="Page actions">{headerActions}</div>}
    </header>
    <div className={styled ? "bwhq-workspace__columns" : undefined}>
      <aside aria-label="Application menu" className={styled ? "bwhq-workspace__menu" : undefined}>{menu}</aside>
      <main className={styled ? "bwhq-workspace__main" : undefined}>{children}</main>
      {contextPanel && <aside aria-label="Page context" className={styled ? "bwhq-workspace__context" : undefined}>{contextPanel}</aside>}
    </div>
  </div>
);

export const UnstyledTenantWorkspaceShell = (props: Omit<TenantWorkspaceShellProps, "styled">) =>
  <TenantWorkspaceShellBody {...props} styled={false} />;

export const StyledTenantWorkspaceShell = (props: Omit<TenantWorkspaceShellProps, "styled">) =>
  <TenantWorkspaceShellBody {...props} styled />;

7. Files and binary responses

HeadlessTransport is intentionally JSON-only. For multipart upload and Blob download, reuse the current typed uploadFile, downloadFileContent, uploadTenantAsset, and loadTenantAssetContent functions or implement their exact reviewed contracts. Keep MIME/size validation, CSRF, unauthorized-download denial, malware scanning state, orphan cleanup and native File authorization intact.

8. Every capability and exact operation

Each section lists the current integration kind, page key where one exists, API roots, public package-client methods, exact HTTP routes, current browser function and response parser. A background capability with no interactive route is explicitly left without one rather than given an invented endpoint.

Connected work 3 headless operations

Integration: product-solution-renderer · Native key: module.connected-work
API roots: /api/modules/record-graph

Exact HTTP routeCurrent browser functionResponse parser
GET
/api/modules/record-graph/records
searchRecordGraphparseRecordGraphSearch
GET
/api/modules/record-graph/{recordId:guid}
getRecordGraphparseRecordGraph
GET
/api/runtime/record-scope/records/{recordId:guid}/pages
getNativeRecordPagesparseNativeRecordPages
Knowledge finder 3 headless operations

Integration: product-solution-renderer · Native key: module.knowledge-finder
API roots: /api/modules/knowledge-core

Exact HTTP routeCurrent browser functionResponse parser
GET
/api/modules/knowledge-core
listKnowledgeCoreparseKnowledgeCoreList
GET
/api/modules/knowledge-core/{recordId:guid}
getKnowledgeCoreparseKnowledgeCoreDetail
GET
/api/runtime/record-scope/records/{recordId:guid}/pages
getNativeRecordPagesparseNativeRecordPages
Universal Inbox 22 headless operations

Integration: shell-and-page-component · Native key: core.universal-inbox
API roots: /api/inbox, /api/inbox/items
Typed client methods: list, get, badge, badgeIndicator, notifications, deliveryDebug, retryDelivery, setReadState, setStatus, setPriority, setAssignment, reply, getChannelTicketingSettings, setChannelTicketing, getEmailTicketingSettings, setEmailTicketing, decideWorkflowApproval

Exact HTTP routeCurrent browser functionResponse parser
GET
/api/inbox/support-lanes
Use the typed transport/clientUse the returned typed contract
GET
/api/inbox/support-lanes/{laneId:guid}
Use the typed transport/clientUse the returned typed contract
GET
/api/inbox/support-lanes/options
Use the typed transport/clientUse the returned typed contract
POST
/api/inbox/support-lanes
Use the typed transport/clientUse the returned typed contract
PUT
/api/inbox/support-lanes/{laneId:guid}
Use the typed transport/clientUse the returned typed contract
POST
/api/inbox/support-lanes/{laneId:guid}/retire
Use the typed transport/clientUse the returned typed contract
GET
/api/inbox/lego-catalog
getInboxLegoCatalogparseSuccessfulResponse
GET
/api/inbox/lego-presentation
getInboxLegoPresentationparseSuccessfulResponse
GET
/api/inbox/items
Use the typed transport/clientUse the returned typed contract
GET
/api/inbox/email-channels/ticketing
Use the typed transport/clientUse the returned typed contract
PUT
/api/inbox/email-channels/{channelConnectionId:guid}/ticketing
Use the typed transport/clientUse the returned typed contract
GET
/api/inbox/items/{inboxItemId:guid}
Use the typed transport/clientUse the returned typed contract
GET
/api/inbox/badge
Use the typed transport/clientUse the returned typed contract
GET
/api/inbox/notifications
Use the typed transport/clientUse the returned typed contract
GET
/api/inbox/delivery/debug
Use the typed transport/clientUse the returned typed contract
POST
/api/inbox/delivery/{outboundMessageId:guid}/retry
Use the typed transport/clientUse the returned typed contract
PUT
/api/inbox/items/{inboxItemId:guid}/human-state
Use the typed transport/clientUse the returned typed contract
GET
/api/inbox/badge/indicator
Use the typed transport/clientUse the returned typed contract
GET
/api/inbox/channels/ticketing
Use the typed transport/clientUse the returned typed contract
PUT
/api/inbox/channels/{channelConnectionId:guid}/ticketing
Use the typed transport/clientUse the returned typed contract
POST
/api/inbox/items/{inboxItemId:guid}/reply
Use the typed transport/clientUse the returned typed contract
POST
/api/inbox/items/{inboxItemId:guid}/workflow-approval
Use the typed transport/clientUse the returned typed contract
Checklists & Signoffs 14 headless operations

Integration: page-module · Native key: module.checklists-signoffs
API roots: /api/modules/checklists-signoffs

Exact HTTP routeCurrent browser functionResponse parser
GET
/api/modules/checklists-signoffs/lego/catalog
Use the typed transport/clientUse the returned typed contract
GET
/api/modules/checklists-signoffs/lookups/{lookupId:guid}
Use the typed transport/clientUse the returned typed contract
GET
/api/modules/checklists-signoffs/templates
listChecklistTemplatesparseChecklistTemplateList
POST
/api/modules/checklists-signoffs/templates
createChecklistTemplateparseChecklistMutation
GET
/api/modules/checklists-signoffs/templates/{checklistTemplateId:guid}
getChecklistTemplateparseChecklistTemplateDetail
PUT
/api/modules/checklists-signoffs/templates/{checklistTemplateId:guid}
updateChecklistTemplateparseChecklistMutation
DELETE
/api/modules/checklists-signoffs/templates/{checklistTemplateId:guid}
removeChecklistTemplateparseChecklistTemplateRemoval
GET
/api/modules/checklists-signoffs/runs
listChecklistRunsparseChecklistRunList
GET
/api/modules/checklists-signoffs/runs/{checklistRunId:guid}
getChecklistRunparseChecklistRunDetail
POST
/api/modules/checklists-signoffs/runs
startChecklistRunparseChecklistMutation
PUT
/api/modules/checklists-signoffs/items/{checklistRunItemId:guid}
updateChecklistItemparseChecklistMutation
POST
/api/modules/checklists-signoffs/items/{checklistRunItemId:guid}/proof
attachChecklistProofparseChecklistMutation
DELETE
/api/modules/checklists-signoffs/proof/{checklistItemEvidenceId:guid}
removeChecklistProofparseChecklistMutation
POST
/api/modules/checklists-signoffs/runs/{checklistRunId:guid}/submit
submitChecklistForSignoffparseChecklistMutation
GoClaw 8 headless operations

Integration: shell-and-page-component · Native key: module.goclaw
API roots: /api/goclaw/agents, /api/goclaw/approvals
Typed client methods: list, approve, reject, takeOver, retry

Exact HTTP routeCurrent browser functionResponse parser
GET
/api/goclaw/approvals
Use the typed transport/clientUse the returned typed contract
GET
/api/goclaw/approvals/lego/catalog
Use the typed transport/clientUse the returned typed contract
GET
/api/goclaw/approvals/lego/presentation
Use the typed transport/clientUse the returned typed contract
POST
/api/goclaw/approvals/{suggestionBatchId:guid}/approve
Use the typed transport/clientUse the returned typed contract
POST
/api/goclaw/approvals/{suggestionBatchId:guid}/reject
Use the typed transport/clientUse the returned typed contract
POST
/api/goclaw/approvals/{suggestionBatchId:guid}/take-over
Use the typed transport/clientUse the returned typed contract
POST
/api/goclaw/approvals/{suggestionBatchId:guid}/retry
Use the typed transport/clientUse the returned typed contract
PUT
/api/goclaw/agents/{goClawAgentId:guid}/authority
Use the typed transport/clientUse the returned typed contract
AI Insights 3 headless operations

Integration: page-module · Native key: module.ai-insights
API roots: /api/modules/ai-insights

Exact HTTP routeCurrent browser functionResponse parser
GET
/api/modules/ai-insights
listAiInsightsparseAiInsightList
GET
/api/modules/ai-insights/{insightId:guid}
getAiInsightparseAiInsightDetail
PUT
/api/modules/ai-insights/{insightId:guid}/state
setAiInsightStateparseAiInsightState
Contacts 10 headless operations

Integration: page-module · Native key: module.contacts
API roots: /api/modules/contacts

Exact HTTP routeCurrent browser functionResponse parser
GET
/api/modules/contacts/schema
getContactsLegoCatalogparseSuccessfulResponse
GET
/api/modules/contacts/lookups/{lookupId:guid}
getContactsLegoLookupparseSuccessfulResponse
GET
/api/modules/contacts/create-visibility-options
getContactCreateVisibilityOptionsUse the returned typed contract
GET
/api/modules/contacts
listContactsparseContactList, parseSecuredRecordCount
GET
/api/modules/contacts/count
listContactsparseContactList, parseSecuredRecordCount
GET
/api/modules/contacts/{recordId:guid}
getContactparseContactDetail
POST
/api/modules/contacts
createContactparseContactMutation
PUT
/api/modules/contacts/{recordId:guid}
updateContactparseContactMutation
DELETE
/api/modules/contacts/{recordId:guid}
removeContactparseContactRemoval
PUT
/api/modules/contacts/{recordId:guid}/favorite
setContactFavoriteparseContactMutation
Work Orders 10 headless operations

Integration: page-module · Native key: module.work-orders
API roots: /api/modules/work-orders

Exact HTTP routeCurrent browser functionResponse parser
GET
/api/modules/work-orders/schema
getWorkOrderLegoCatalogparseSuccessfulResponse
GET
/api/modules/work-orders/lookups/{lookupId:guid}
getWorkOrderLegoLookupparseSuccessfulResponse
GET
/api/modules/work-orders/{recordId:guid}/status-transitions
getWorkOrderStatusTransitionsparseSuccessfulResponse
GET
/api/modules/work-orders
listWorkOrdersparseWorkOrderList
GET
/api/modules/work-orders/{recordId:guid}
getWorkOrderparseWorkOrderDetail
POST
/api/modules/work-orders
createWorkOrderparseWorkOrderMutation
PUT
/api/modules/work-orders/{recordId:guid}
updateWorkOrderparseWorkOrderMutation
DELETE
/api/modules/work-orders/{recordId:guid}
removeWorkOrderparseWorkOrderRemoval
PUT
/api/modules/work-orders/{recordId:guid}/status
setWorkOrderStatusparseWorkOrderMutation
PUT
/api/modules/work-orders/{recordId:guid}/assignment
assignWorkOrderparseWorkOrderMutation
Reservations 11 headless operations

Integration: page-module · Native key: module.reservations
API roots: /api/modules/reservations

Exact HTTP routeCurrent browser functionResponse parser
GET
/api/modules/reservations/products
listReservationProductsparseReservationProductList
POST
/api/modules/reservations/products
saveReservationProductparseReservationMutation
GET
/api/modules/reservations
listReservationsparseReservationList
GET
/api/modules/reservations/assignees
listReservationAssigneesparseReservationAssigneeLookup
GET
/api/modules/reservations/capabilities
Use the typed transport/clientUse the returned typed contract
GET
/api/modules/reservations/{recordId:guid}
getReservationparseReservationDetail
POST
/api/modules/reservations/purchase
purchaseReservationparseReservationMutation
PUT
/api/modules/reservations/{recordId:guid}/status
setReservationStatusparseReservationMutation
PUT
/api/modules/reservations/{recordId:guid}/schedule
rescheduleReservationparseReservationMutation
PUT
/api/modules/reservations/{recordId:guid}/followups
updateReservationFollowupparseReservationMutation
GET
/api/modules/reservations/lego/catalog
Use the typed transport/clientUse the returned typed contract
Calendar 8 headless operations

Integration: page-module · Native key: module.calendar
API roots: /api/modules/calendar

Exact HTTP routeCurrent browser functionResponse parser
GET
/api/modules/calendar
listCalendarEventsparseCalendarEventList
GET
/api/modules/calendar/{recordId:guid}
getCalendarEventparseCalendarEventDetail
POST
/api/modules/calendar
createCalendarEventparseCalendarMutation
PUT
/api/modules/calendar/{recordId:guid}
updateCalendarEventparseCalendarMutation
GET
/api/modules/calendar/capabilities
Use the typed transport/clientUse the returned typed contract
DELETE
/api/modules/calendar/{recordId:guid}
removeCalendarEventparseCalendarRemoval
PUT
/api/modules/calendar/{recordId:guid}/favorite
setCalendarFavoriteparseCalendarMutation
GET
/api/modules/calendar/lego/catalog
Use the typed transport/clientUse the returned typed contract
Files 12 headless operations

Integration: page-module · Native key: module.files
API roots: /api/modules/files

Exact HTTP routeCurrent browser functionResponse parser
GET
/api/modules/files
listFilesparseFileList
GET
/api/modules/files/capabilities
Use the typed transport/clientUse the returned typed contract
GET
/api/modules/files/{recordId:guid}
getFileparseFileDetail
POST
/api/modules/files/upload
uploadFileparseFileMutation
PUT
/api/modules/files/{recordId:guid}
updateFileparseFileMutation
DELETE
/api/modules/files/{recordId:guid}
removeFileparseFileRemoval
POST
/api/modules/files/{recordId:guid}/attachments
attachFileparseFileMutation
DELETE
/api/modules/files/{recordId:guid}/attachments/{attachmentId:guid}
detachFileparseFileMutation
PUT
/api/modules/files/{recordId:guid}/favorite
setFileFavoriteparseFileMutation
GET
/api/modules/files/lego/catalog
Use the typed transport/clientUse the returned typed contract
GET
/api/modules/files/{recordId:guid}/content
downloadFileContentUse the returned typed contract
GET
/api/tenant/native-message-attachments/{recordId:guid}/content
downloadNativeMessageAttachmentUse the returned typed contract
Conversations 13 headless operations

Integration: page-module · Native key: module.conversations
API roots: /api/modules/conversations

Exact HTTP routeCurrent browser functionResponse parser
GET
/api/modules/conversations
listConversationsparseConversationList
GET
/api/modules/conversations/{recordId:guid}
getConversationparseConversationDetail
GET
/api/modules/conversations/{recordId:guid}/messages/{messageId:guid}/attachments/{fileId:guid}/content
downloadConversationAttachmentUse the returned typed contract
POST
/api/modules/conversations
createConversationparseConversationMutation
PUT
/api/modules/conversations/{recordId:guid}
updateConversationparseConversationMutation
GET
/api/modules/conversations/lego-catalog
getConversationsLegoCatalogparseSuccessfulResponse
GET
/api/modules/conversations/lego-presentation
getConversationsLegoPresentationparseSuccessfulResponse
GET
/api/modules/conversations/capabilities
Use the typed transport/clientUse the returned typed contract
DELETE
/api/modules/conversations/{recordId:guid}
removeConversationparseConversationRemoval
POST
/api/modules/conversations/{recordId:guid}/messages
postConversationMessageparseConversationMutation
GET
/api/modules/conversations/direct/scope
Use the typed transport/clientUse the returned typed contract
POST
/api/modules/conversations/direct
sendDirectConversationparseConversationMutation
PUT
/api/modules/conversations/{recordId:guid}/favorite
setConversationFavoriteparseConversationMutation
Company news 9 headless operations

Integration: page-module · Native key: module.company-news
API roots: /api/modules/company-news

Exact HTTP routeCurrent browser functionResponse parser
GET
/api/modules/company-news/schema
getCompanyNewsLegoCatalogparseSuccessfulResponse
GET
/api/modules/company-news/lookups/{lookupId:guid}
getCompanyNewsLegoLookupparseSuccessfulResponse
GET
/api/modules/company-news
listCompanyNewsparseCompanyNewsList
GET
/api/modules/company-news/{recordId:guid}
getCompanyNewsparseCompanyNewsDetail
POST
/api/modules/company-news
createCompanyNewsparseCompanyNewsMutation
PUT
/api/modules/company-news/{recordId:guid}
updateCompanyNewsparseCompanyNewsMutation
PUT
/api/modules/company-news/{recordId:guid}/favorite
setCompanyNewsFavoriteparseCompanyNewsMutation
PUT
/api/modules/company-news/{recordId:guid}/published
setCompanyNewsPublishedparseCompanyNewsMutation
DELETE
/api/modules/company-news/{recordId:guid}
removeCompanyNewsparseCompanyNewsRemoval
Knowledge Core 40 headless operations

Integration: page-module · Native key: module.knowledge-articles
API roots: /api/modules/knowledge-articles, /api/modules/knowledge-core

Exact HTTP routeCurrent browser functionResponse parser
GET
/api/modules/knowledge-articles
listKnowledgeArticlesparseKnowledgeArticlesList
GET
/api/modules/knowledge-articles/{recordId:guid}
getKnowledgeArticleparseKnowledgeArticleDetail
POST
/api/modules/knowledge-articles
createKnowledgeArticleparseKnowledgeArticleMutation
PUT
/api/modules/knowledge-articles/{recordId:guid}
updateKnowledgeArticleparseKnowledgeArticleMutation
PUT
/api/modules/knowledge-articles/{recordId:guid}/favorite
setKnowledgeArticleFavoriteparseKnowledgeArticleMutation
DELETE
/api/modules/knowledge-articles/{recordId:guid}
Use the typed transport/clientUse the returned typed contract
GET
/api/modules/knowledge-articles/lego/catalog
Use the typed transport/clientUse the returned typed contract
GET
/api/modules/knowledge-core
listKnowledgeCoreparseKnowledgeCoreList
GET
/api/modules/knowledge-core/{recordId:guid}
getKnowledgeCoreparseKnowledgeCoreDetail
POST
/api/modules/knowledge-core
createKnowledgeCoreparseKnowledgeCoreMutation
PUT
/api/modules/knowledge-core/{recordId:guid}
updateKnowledgeCoreparseKnowledgeCoreMutation
POST
/api/modules/knowledge-core/{recordId:guid}/publish
publishKnowledgeCoreparseKnowledgeCoreMutation
POST
/api/modules/knowledge-core/{recordId:guid}/archive
archiveKnowledgeCoreparseKnowledgeCoreMutation
GET
/api/modules/knowledge-core/{recordId:guid}/revisions
getKnowledgeCoreRevisionsparseKnowledgeRevisions
POST
/api/modules/knowledge-core/{recordId:guid}/restore
restoreKnowledgeCoreRevisionparseKnowledgeCoreMutation
GET
/api/modules/knowledge-core/collections
listKnowledgeCoreCollectionsparseKnowledgeCollections
POST
/api/modules/knowledge-core/collections
createKnowledgeCoreCollectionparseKnowledgeCollectionMutation
PUT
/api/modules/knowledge-core/collections/{collectionId:guid}
updateKnowledgeCoreCollectionparseKnowledgeCollectionMutation
POST
/api/modules/knowledge-core/collections/{collectionId:guid}/items/{recordId:guid}
addKnowledgeCoreCollectionItemparseKnowledgeCollectionMutation
DELETE
/api/modules/knowledge-core/collections/{collectionId:guid}/items/{recordId:guid}
removeKnowledgeCoreCollectionItemparseKnowledgeCollectionMutation
GET
/api/modules/knowledge-core/{recordId:guid}/owners
getKnowledgeCoreOwnersparseKnowledgeOwners
POST
/api/modules/knowledge-core/{recordId:guid}/owners
setKnowledgeCoreOwnerparseKnowledgeOwnerMutation
DELETE
/api/modules/knowledge-core/owners/{knowledgeOwnerId:guid}
removeKnowledgeCoreOwnerparseKnowledgeOwnerMutation
GET
/api/modules/knowledge-core/unowned
listUnownedKnowledgeCoreparseKnowledgeCoreList
GET
/api/modules/knowledge-core/assignment-lookup
getKnowledgeAssignmentLookupparseKnowledgeAssignmentLookup
GET
/api/modules/knowledge-core/reviews
listKnowledgeReviewsparseKnowledgeReviews
POST
/api/modules/knowledge-core/reviews/{reviewCycleId:guid}/begin
beginKnowledgeReviewparseKnowledgeReviewMutation
POST
/api/modules/knowledge-core/reviews/{reviewCycleId:guid}/complete
completeKnowledgeReviewparseKnowledgeReviewMutation
POST
/api/modules/knowledge-core/reviews/{reviewCycleId:guid}/reassign
reassignKnowledgeReviewparseKnowledgeReviewMutation
GET
/api/modules/knowledge-core/health
getKnowledgeHealthparseKnowledgeHealth
GET
/api/modules/knowledge-core/questions
listKnowledgeQuestionsparseKnowledgeQuestions
POST
/api/modules/knowledge-core/questions
createKnowledgeQuestionparseKnowledgeQuestionMutation
POST
/api/modules/knowledge-core/questions/{knowledgeQuestionId:guid}/assign
assignKnowledgeQuestionparseKnowledgeQuestionMutation
POST
/api/modules/knowledge-core/questions/{knowledgeQuestionId:guid}/answer
answerKnowledgeQuestionparseKnowledgeQuestionMutation
POST
/api/modules/knowledge-core/questions/{knowledgeQuestionId:guid}/convert
convertKnowledgeQuestionparseKnowledgeQuestionMutation
POST
/api/modules/knowledge-core/{recordId:guid}/feedback
recordKnowledgeFeedbackparseKnowledgeFeedbackMutation
GET
/api/modules/knowledge-core/{recordId:guid}/feedback
getKnowledgeFeedbackparseKnowledgeFeedbackSummary
GET
/api/modules/knowledge-core/gaps
getKnowledgeGapsparseKnowledgeGaps
GET
/api/modules/knowledge-core/support-learning/candidates
Use the typed transport/clientUse the returned typed contract
POST
/api/modules/knowledge-core/support-learning/candidates
Use the typed transport/clientUse the returned typed contract
Chat rooms 14 headless operations

Integration: page-module · Native key: module.chat-rooms
API roots: /api/modules/chat-rooms

Exact HTTP routeCurrent browser functionResponse parser
GET
/api/modules/chat-rooms
listChatRoomsparseChatRoomsList
GET
/api/modules/chat-rooms/{recordId:guid}
Use the typed transport/clientUse the returned typed contract
POST
/api/modules/chat-rooms
createChatRoomparseChatRoomMutation
PUT
/api/modules/chat-rooms/{recordId:guid}
updateChatRoomparseChatRoomMutation
GET
/api/modules/chat-rooms/lego/catalog
Use the typed transport/clientUse the returned typed contract
DELETE
/api/modules/chat-rooms/{recordId:guid}
removeChatRoomparseChatRoomRemoval
POST
/api/modules/chat-rooms/{recordId:guid}/messages
postChatMessageparseChatRoomMutation
PUT
/api/modules/chat-rooms/{recordId:guid}/messages/{chatMessageId:guid}
updateChatMessageparseChatRoomMutation
DELETE
/api/modules/chat-rooms/{recordId:guid}/messages/{chatMessageId:guid}
removeChatMessageparseChatRoomMutation
PUT
/api/modules/chat-rooms/{recordId:guid}/messages/{chatMessageId:guid}/reaction
setChatReactionparseChatRoomMutation
PUT
/api/modules/chat-rooms/{recordId:guid}/members/{memberUserId:guid}
setChatRoomMemberparseChatRoomMutation
GET
/api/modules/chat-rooms/{recordId:guid}/members/lookup
getChatRoomMemberLookupparseChatRoomMemberLookup
PUT
/api/modules/chat-rooms/{recordId:guid}/read
markChatRoomReadparseChatRoomMutation
PUT
/api/modules/chat-rooms/{recordId:guid}/favorite
setChatRoomFavoriteparseChatRoomMutation
Discussion Boards 14 headless operations

Integration: page-module · Native key: module.discussion-boards
API roots: /api/modules/discussion-boards

Exact HTTP routeCurrent browser functionResponse parser
GET
/api/modules/discussion-boards
listDiscussionBoardsparseDiscussionBoardsList
GET
/api/modules/discussion-boards/{recordId:guid}
getDiscussionBoardparseDiscussionBoardDetail
POST
/api/modules/discussion-boards
createDiscussionBoardparseDiscussionMutation
PUT
/api/modules/discussion-boards/{recordId:guid}
updateDiscussionBoardparseDiscussionMutation
GET
/api/modules/discussion-boards/lego/catalog
Use the typed transport/clientUse the returned typed contract
DELETE
/api/modules/discussion-boards/{recordId:guid}
removeDiscussionBoardparseDiscussionBoardRemoval
POST
/api/modules/discussion-boards/{boardRecordId:guid}/topics
createDiscussionTopicparseDiscussionMutation
GET
/api/modules/discussion-boards/topics/{recordId:guid}
Use the typed transport/clientUse the returned typed contract
PUT
/api/modules/discussion-boards/topics/{recordId:guid}
updateDiscussionTopicparseDiscussionMutation
DELETE
/api/modules/discussion-boards/topics/{recordId:guid}
removeDiscussionTopicparseDiscussionTopicRemoval
POST
/api/modules/discussion-boards/topics/{topicRecordId:guid}/posts
postDiscussionReplyparseDiscussionMutation
PUT
/api/modules/discussion-boards/posts/{recordId:guid}
updateDiscussionPostparseDiscussionMutation
DELETE
/api/modules/discussion-boards/posts/{recordId:guid}
removeDiscussionPostparseDiscussionPostRemoval
PUT
/api/modules/discussion-boards/records/{recordId:guid}/favorite
setDiscussionFavoriteparseDiscussionMutation
Mail reader 10 headless operations

Integration: page-module · Native key: module.mail-reader
API roots: /api/modules/mail-reader

Exact HTTP routeCurrent browser functionResponse parser
GET
/api/modules/mail-reader
listMailReaderMessagesparseMailReaderList
GET
/api/modules/mail-reader/{recordId:guid}
getMailReaderMessageparseMailReaderDetail
PUT
/api/modules/mail-reader/{recordId:guid}/read
setMailReaderReadUse the returned typed contract
POST
/api/modules/mail-reader/{recordId:guid}/archive
archiveMailReaderMessageUse the returned typed contract
GET
/api/modules/mail-reader/mailboxes
listMailReaderMailboxesparseMailReaderMailboxes
POST
/api/modules/mail-reader/mailboxes
createMailReaderMailboxparseMailReaderMailboxMutation
PUT
/api/modules/mail-reader/mailboxes/{mailboxId:guid}
updateMailReaderMailboxparseMailReaderMailboxMutation
PUT
/api/modules/mail-reader/{recordId:guid}/favorite
setMailReaderFavoriteUse the returned typed contract
PUT
/api/modules/mail-reader/mailboxes/{mailboxRecordId:guid}/credentials/{purpose}
setMailReaderCredentialparseMailReaderCredentialStatus
POST
/api/modules/mail-reader/mailboxes/{mailboxRecordId:guid}/compose
composeMailReaderEmailparseMailReaderComposeResult
Favorites 7 headless operations

Integration: page-module · Native key: module.favorites
API roots: /api/modules/favorites

Exact HTTP routeCurrent browser functionResponse parser
GET
/api/modules/favorites/schema
getFavoritesLegoCatalogparseSuccessfulResponse
GET
/api/modules/favorites/presentation
Use the typed transport/clientUse the returned typed contract
GET
/api/modules/favorites
listFavoritesparseFavoritesList
GET
/api/modules/favorites/{recordId:guid}
getFavoriteparseFavoriteDetail
GET
/api/modules/favorites/{recordId:guid}/state
getFavoriteStateparseFavoriteMutation
PUT
/api/modules/favorites/{recordId:guid}/favorite
setFavoriteparseFavoriteMutation
PUT
/api/modules/favorites/{recordId:guid}/preferences
updateFavoritePreferencesparseFavoriteMutation
Notifications 6 headless operations

Integration: page-module · Native key: module.notifications
API roots: /api/modules/notifications

Exact HTTP routeCurrent browser functionResponse parser
GET
/api/modules/notifications
listNotificationsparseNotificationList
GET
/api/modules/notifications/lego-catalog
getNotificationsLegoCatalogparseSuccessfulResponse
GET
/api/modules/notifications/lego-presentation
getNotificationsLegoPresentationparseSuccessfulResponse
GET
/api/modules/notifications/{notificationId:guid}
getNotificationparseNotificationDetail
PUT
/api/modules/notifications/{notificationId:guid}/state
setNotificationStateparseNotificationMutation
PUT
/api/modules/notifications/{notificationId:guid}/source-favorite
setNotificationSourceFavoriteparseNotificationMutation
Dynamic Records 11 headless operations

Integration: page-module · Native key: module.dynamic-records
API roots: /api/modules/dynamic

Exact HTTP routeCurrent browser functionResponse parser
GET
/api/modules/dynamic
listDynamicModuleSchemasparseDynamicModuleCatalog
GET
/api/modules/dynamic/{moduleKey}/schema
getDynamicModuleSchemaparseDynamicModuleSchema
GET
/api/modules/dynamic/{moduleKey}/lookups/{lookupId:guid}
Use the typed transport/clientUse the returned typed contract
GET
/api/modules/dynamic/{moduleKey}/lego/catalog
Use the typed transport/clientUse the returned typed contract
GET
/api/modules/dynamic/{moduleKey}
listDynamicModuleRecordsparseDynamicModuleList
GET
/api/modules/dynamic/{moduleKey}/{recordId:guid}
getDynamicModuleRecordparseDynamicModuleDetail
POST
/api/modules/dynamic/{moduleKey}
createDynamicModuleRecordparseDynamicModuleMutation
PUT
/api/modules/dynamic/{moduleKey}/{recordId:guid}
updateDynamicModuleRecordparseDynamicModuleMutation
DELETE
/api/modules/dynamic/{moduleKey}/{recordId:guid}
deleteDynamicModuleRecordparseDynamicModuleRemoval
PUT
/api/modules/dynamic/{moduleKey}/{recordId:guid}/favorite
setDynamicModuleFavoriteparseDynamicModuleMutation
POST
/api/modules/dynamic/caseflow-cases/{recordId:guid}/transition
transitionCaseFlowCaseUse the returned typed contract
ActiveWorkplace 14 headless operations

Integration: page-module · Native key: module.active-workplace
API roots: /api/modules/active-workplace

Exact HTTP routeCurrent browser functionResponse parser
GET
/api/modules/active-workplace
listActiveWorkplacesparseActiveWorkplaceList
GET
/api/modules/active-workplace/lego/catalog
Use the typed transport/clientUse the returned typed contract
GET
/api/modules/active-workplace/lego/lookups/{lookupId:guid}
Use the typed transport/clientUse the returned typed contract
GET
/api/modules/active-workplace/lego/presentation
Use the typed transport/clientUse the returned typed contract
POST
/api/modules/active-workplace
createActiveWorkplaceparseActiveWorkplaceMutation
GET
/api/modules/active-workplace/{activeWorkplaceId:guid}
getActiveWorkplaceparseActiveWorkplaceDetail
PATCH
/api/modules/active-workplace/{activeWorkplaceId:guid}
updateActiveWorkplaceparseActiveWorkplaceMutation
POST
/api/modules/active-workplace/{activeWorkplaceId:guid}/status
setActiveWorkplaceStatusparseActiveWorkplaceMutation
GET
/api/modules/active-workplace/{activeWorkplaceId:guid}/participants/catalog
getActiveWorkplaceParticipantCatalogparseActiveWorkplaceCatalog
POST
/api/modules/active-workplace/{activeWorkplaceId:guid}/participants
addActiveWorkplaceParticipantparseActiveWorkplaceMutation
DELETE
/api/modules/active-workplace/{activeWorkplaceId:guid}/participants/{activeWorkplaceParticipantId:guid}
removeActiveWorkplaceParticipantparseActiveWorkplaceMutation
POST
/api/modules/active-workplace/{activeWorkplaceId:guid}/activity
recordActiveWorkplaceActivityparseActiveWorkplaceMutation
POST
/api/modules/active-workplace/{activeWorkplaceId:guid}/graph/refresh
refreshActiveWorkplaceGraphparseActiveWorkplaceMutation
GET
/api/modules/active-workplace/{activeWorkplaceId:guid}/playback
getActiveWorkplacePlaybackparseActiveWorkplacePlayback
Record relations 9 headless operations

Integration: page-module · Native key: module.record-graph
API roots: /api/modules/record-graph

Exact HTTP routeCurrent browser functionResponse parser
GET
/api/modules/record-graph/records
searchRecordGraphparseRecordGraphSearch
GET
/api/modules/record-graph/{recordId:guid}
getRecordGraphparseRecordGraph
PUT
/api/modules/record-graph/{recordId:guid}/relations
addRecordGraphRelationparseRecordGraphMutation
DELETE
/api/modules/record-graph/relations/{recordRelationId:guid}
removeRecordGraphRelationparseRecordGraphMutation
PUT
/api/modules/record-graph/{recordId:guid}/favorite
setRecordGraphFavoriteparseFavoriteMutation
GET
/api/modules/record-graph/{recordId:guid}/knowledge
getRelatedKnowledgeparseRelatedKnowledge
GET
/api/modules/record-graph/{recordId:guid}/knowledge/candidates
getContextualKnowledgeparseContextualKnowledge
PUT
/api/modules/record-graph/{recordId:guid}/knowledge
linkKnowledgeToRecordparseKnowledgeRelationMutation
DELETE
/api/modules/record-graph/knowledge-relations/{recordRelationId:guid}
unlinkKnowledgeFromRecordparseKnowledgeRelationMutation
Record activity 3 headless operations

Integration: page-module · Native key: module.record-activity
API roots: /api/modules/record-activity

Exact HTTP routeCurrent browser functionResponse parser
GET
/api/modules/record-activity/records
searchRecordActivityparseRecordActivitySearch
GET
/api/modules/record-activity/{recordId:guid}
getRecordActivityparseRecordActivity
PUT
/api/modules/record-activity/{recordId:guid}/favorite
setRecordActivityFavoriteparseFavoriteMutation
Support Lanes API 0 headless operations

Integration: api-surface · Native key: module.support-lanes
API roots: /api/inbox/support-lanes

This API surface supports other first-class modules and has no standalone page renderer.

Company Iq API 0 headless operations

Integration: api-surface · Native key: module.company-iq
API roots: /api/modules/company-iq

This API surface supports other first-class modules and has no standalone page renderer.

Ops Atlas API 0 headless operations

Integration: api-surface · Native key: module.ops-atlas
API roots: /api/modules/ops-atlas

This API surface supports other first-class modules and has no standalone page renderer.

Payments Module API 12 headless operations

Integration: api-surface · Native key: Not a page block
API roots: /api/modules/payments

Exact HTTP routeCurrent browser functionResponse parser
GET
/api/modules/payments/settings
getTenantPaymentSettingsparseTenantPaymentSettings
PUT
/api/modules/payments/settings/{moduleKey}
updateTenantPaymentPolicyparseTenantPaymentMutation
PUT
/api/modules/payments/connectors
upsertTenantPaymentConnectorparseTenantPaymentMutation
DELETE
/api/modules/payments/connectors/{connectorId:guid}
deactivateTenantPaymentConnectorparseTenantPaymentMutation
GET
/api/modules/payments/methods
Use the typed transport/clientUse the returned typed contract
POST
/api/modules/payments/methods
registerTenantPaymentMethodparseTenantPaymentMutation
GET
/api/modules/payments/methods/{paymentMethodId:guid}
getTenantPaymentMethodparseTenantPaymentMethod
PUT
/api/modules/payments/methods/{paymentMethodId:guid}/default
setDefaultTenantPaymentMethodparseTenantPaymentMutation
DELETE
/api/modules/payments/methods/{paymentMethodId:guid}
revokeTenantPaymentMethodparseTenantPaymentMutation
GET
/api/modules/payments/records/{recordId:guid}
getTenantRecordPaymentsparseTenantRecordPaymentSummary
POST
/api/modules/payments/records/{recordId:guid}/charges
createTenantRecordChargeparseTenantPaymentMutation
DELETE
/api/modules/payments/records/{recordId:guid}/charges/{chargeIntentId:guid}
cancelTenantRecordChargeparseTenantPaymentMutation
Copy the searchable styled/unstyled operation directory

import { useMemo, useState } from "react";
import { headlessCapabilityRecipes } from "./HeadlessCapabilityRecipes.generated";

export const HeadlessOperationDirectory = ({ styled = false }: { readonly styled?: boolean }) => {
  const [query, setQuery] = useState("");
  const recipes = useMemo(() => {
    const needle = query.trim().toLowerCase();
    return needle ? headlessCapabilityRecipes.filter((recipe) => [recipe.title, recipe.slug, ...recipe.apiBasePaths, ...recipe.operations.flatMap((operation) => [operation.method, operation.route, ...operation.browserFunctions])].some((value) => value.toLowerCase().includes(needle))) : headlessCapabilityRecipes;
  }, [query]);
  return <section className={styled ? "bwhq-headless-directory" : undefined}>
    <header><h1>Headless capability operations</h1><label>Search capability, route, or function<input type="search" value={query} onChange={(event) => setQuery(event.target.value)} /></label></header>
    {recipes.map((recipe) => <details key={recipe.slug}><summary><strong>{recipe.title}</strong> <span>{recipe.operations.length} operations</span></summary><p>{recipe.integrationKind} · {recipe.nativeComponentKey || "No native page block"}</p>{hasOperations(recipe.operations) ? <table><thead><tr><th>HTTP</th><th>Browser function</th><th>Parser</th></tr></thead><tbody>{recipe.operations.map((operation) => <tr key={`${operation.method} ${operation.route}`}><td><strong>{operation.method}</strong><br /><code>{operation.route}</code></td><td>{operation.browserFunctions.join(", ") || "Use typed transport/client"}</td><td>{operation.parsers.join(", ") || "See typed client contract"}</td></tr>)}</tbody></table> : <p>{recipe.integrationNote}</p>}</details>)}
  </section>;
};

const hasOperations = (operations: readonly unknown[]) => operations.length > 0;

export const UnstyledHeadlessOperationDirectory = () => <HeadlessOperationDirectory />;
export const StyledHeadlessOperationDirectory = () => <HeadlessOperationDirectory styled />;
Copy the complete machine-readable headless recipes
export interface HeadlessOperationRecipe {
  readonly method: string;
  readonly route: string;
  readonly browserFunctions: readonly string[];
  readonly parsers: readonly string[];
  readonly procedures: readonly string[];
}

export interface HeadlessCapabilityRecipe {
  readonly slug: string;
  readonly title: string;
  readonly integrationKind: "page-module" | "product-solution-renderer" | "shell-component" | "shell-and-page-component" | "background-service" | "api-surface";
  readonly nativeComponentKey: string | null;
  readonly apiBasePaths: readonly string[];
  readonly clientMethods: readonly string[];
  readonly operations: readonly HeadlessOperationRecipe[];
  readonly integrationNote: string;
}

export const headlessCapabilityRecipes = [
  {
    "slug": "connected-work",
    "title": "Connected work",
    "integrationKind": "product-solution-renderer",
    "nativeComponentKey": "module.connected-work",
    "apiBasePaths": [
      "/api/modules/record-graph"
    ],
    "clientMethods": [],
    "operations": [
      {
        "method": "GET",
        "route": "/api/modules/record-graph/records",
        "browserFunctions": [
          "searchRecordGraph"
        ],
        "parsers": [
          "parseRecordGraphSearch"
        ],
        "procedures": [
          "sp_RecordGraph_SearchSecured"
        ]
      },
      {
        "method": "GET",
        "route": "/api/modules/record-graph/{recordId:guid}",
        "browserFunctions": [
          "getRecordGraph"
        ],
        "parsers": [
          "parseRecordGraph"
        ],
        "procedures": [
          "sp_RecordGraph_GetSecured"
        ]
      },
      {
        "method": "GET",
        "route": "/api/runtime/record-scope/records/{recordId:guid}/pages",
        "browserFunctions": [
          "getNativeRecordPages"
        ],
        "parsers": [
          "parseNativeRecordPages"
        ],
        "procedures": [
          "sp_RecordScope_GetNativePagesSecured"
        ]
      }
    ],
    "integrationNote": "Read-only discovery using the listed existing secured GET contracts. NativeRecordLink resolves persisted native destinations; lifecycle mutations remain on the owning module. Native page resolution is a tenant-runtime contract, not an invented Developer API route."
  },
  {
    "slug": "knowledge-finder",
    "title": "Knowledge finder",
    "integrationKind": "product-solution-renderer",
    "nativeComponentKey": "module.knowledge-finder",
    "apiBasePaths": [
      "/api/modules/knowledge-core"
    ],
    "clientMethods": [],
    "operations": [
      {
        "method": "GET",
        "route": "/api/modules/knowledge-core",
        "browserFunctions": [
          "listKnowledgeCore"
        ],
        "parsers": [
          "parseKnowledgeCoreList"
        ],
        "procedures": [
          "sp_kc_ListKnowledgeItemsSecured"
        ]
      },
      {
        "method": "GET",
        "route": "/api/modules/knowledge-core/{recordId:guid}",
        "browserFunctions": [
          "getKnowledgeCore"
        ],
        "parsers": [
          "parseKnowledgeCoreDetail"
        ],
        "procedures": [
          "sp_kc_GetKnowledgeItemSecured"
        ]
      },
      {
        "method": "GET",
        "route": "/api/runtime/record-scope/records/{recordId:guid}/pages",
        "browserFunctions": [
          "getNativeRecordPages"
        ],
        "parsers": [
          "parseNativeRecordPages"
        ],
        "procedures": [
          "sp_RecordScope_GetNativePagesSecured"
        ]
      }
    ],
    "integrationNote": "Read-only discovery using the listed existing secured GET contracts. NativeRecordLink resolves persisted native destinations; lifecycle mutations remain on the owning module. Native page resolution is a tenant-runtime contract, not an invented Developer API route."
  },
  {
    "slug": "universal-inbox",
    "title": "Universal Inbox",
    "integrationKind": "shell-and-page-component",
    "nativeComponentKey": "core.universal-inbox",
    "apiBasePaths": [
      "/api/inbox",
      "/api/inbox/items"
    ],
    "clientMethods": [
      "list",
      "get",
      "badge",
      "badgeIndicator",
      "notifications",
      "deliveryDebug",
      "retryDelivery",
      "setReadState",
      "setStatus",
      "setPriority",
      "setAssignment",
      "reply",
      "getChannelTicketingSettings",
      "setChannelTicketing",
      "getEmailTicketingSettings",
      "setEmailTicketing",
      "decideWorkflowApproval"
    ],
    "operations": [
      {
        "method": "GET",
        "route": "/api/inbox/support-lanes",
        "browserFunctions": [],
        "parsers": [],
        "procedures": [
          "sp_Inbox_ListSupportLanesSecured"
        ]
      },
      {
        "method": "GET",
        "route": "/api/inbox/support-lanes/{laneId:guid}",
        "browserFunctions": [],
        "parsers": [],
        "procedures": [
          "sp_Inbox_ListSupportLanesSecured"
        ]
      },
      {
        "method": "GET",
        "route": "/api/inbox/support-lanes/options",
        "browserFunctions": [],
        "parsers": [],
        "procedures": [
          "sp_Inbox_ListSupportLaneOptionsSecured"
        ]
      },
      {
        "method": "POST",
        "route": "/api/inbox/support-lanes",
        "browserFunctions": [],
        "parsers": [],
        "procedures": [
          "sp_Inbox_SaveSupportLaneSecured"
        ]
      },
      {
        "method": "PUT",
        "route": "/api/inbox/support-lanes/{laneId:guid}",
        "browserFunctions": [],
        "parsers": [],
        "procedures": [
          "sp_Inbox_SaveSupportLaneSecured"
        ]
      },
      {
        "method": "POST",
        "route": "/api/inbox/support-lanes/{laneId:guid}/retire",
        "browserFunctions": [],
        "parsers": [],
        "procedures": [
          "sp_Inbox_RetireSupportLaneSecured"
        ]
      },
      {
        "method": "GET",
        "route": "/api/inbox/lego-catalog",
        "browserFunctions": [
          "getInboxLegoCatalog"
        ],
        "parsers": [
          "parseSuccessfulResponse"
        ],
        "procedures": []
      },
      {
        "method": "GET",
        "route": "/api/inbox/lego-presentation",
        "browserFunctions": [
          "getInboxLegoPresentation"
        ],
        "parsers": [
          "parseSuccessfulResponse"
        ],
        "procedures": [
          "sp_Inbox_GetQueueSecured"
        ]
      },
      {
        "method": "GET",
        "route": "/api/inbox/items",
        "browserFunctions": [],
        "parsers": [],
        "procedures": [
          "sp_Inbox_GetQueueSecured"
        ]
      },
      {
        "method": "GET",
        "route": "/api/inbox/email-channels/ticketing",
        "browserFunctions": [],
        "parsers": [],
        "procedures": [
          "sp_Inbox_GetEmailTicketingSettingsSecured"
        ]
      },
      {
        "method": "PUT",
        "route": "/api/inbox/email-channels/{channelConnectionId:guid}/ticketing",
        "browserFunctions": [],
        "parsers": [],
        "procedures": [
          "sp_Inbox_SetEmailTicketingSecured"
        ]
      },
      {
        "method": "GET",
        "route": "/api/inbox/items/{inboxItemId:guid}",
        "browserFunctions": [],
        "parsers": [],
        "procedures": [
          "sp_Inbox_GetItemDetailSecured"
        ]
      },
      {
        "method": "GET",
        "route": "/api/inbox/badge",
        "browserFunctions": [],
        "parsers": [],
        "procedures": [
          "sp_GetInboxBadgeSecured"
        ]
      },
      {
        "method": "GET",
        "route": "/api/inbox/notifications",
        "browserFunctions": [],
        "parsers": [],
        "procedures": [
          "sp_GetInboxNotificationsSecured"
        ]
      },
      {
        "method": "GET",
        "route": "/api/inbox/delivery/debug",
        "browserFunctions": [],
        "parsers": [],
        "procedures": [
          "sp_GetDeliveryDebugSecured"
        ]
      },
      {
        "method": "POST",
        "route": "/api/inbox/delivery/{outboundMessageId:guid}/retry",
        "browserFunctions": [],
        "parsers": [],
        "procedures": [
          "sp_RetryOutboundMessage"
        ]
      },
      {
        "method": "PUT",
        "route": "/api/inbox/items/{inboxItemId:guid}/human-state",
        "browserFunctions": [],
        "parsers": [],
        "procedures": [
          "WriteAuditLog",
          "sp_Inbox_MarkRead",
          "sp_Inbox_SetStatusSecured"
        ]
      },
      {
        "method": "GET",
        "route": "/api/inbox/badge/indicator",
        "browserFunctions": [],
        "parsers": [],
        "procedures": [
          "sp_GetInboxBadgeIndicatorSecured"
        ]
      },
      {
        "method": "GET",
        "route": "/api/inbox/channels/ticketing",
        "browserFunctions": [],
        "parsers": [],
        "procedures": [
          "sp_Inbox_GetChannelTicketingSettingsSecured"
        ]
      },
      {
        "method": "PUT",
        "route": "/api/inbox/channels/{channelConnectionId:guid}/ticketing",
        "browserFunctions": [],
        "parsers": [],
        "procedures": [
          "sp_Inbox_SetChannelTicketingSecured"
        ]
      },
      {
        "method": "POST",
        "route": "/api/inbox/items/{inboxItemId:guid}/reply",
        "browserFunctions": [],
        "parsers": [],
        "procedures": [
          "sp_Inbox_ReplySecured"
        ]
      },
      {
        "method": "POST",
        "route": "/api/inbox/items/{inboxItemId:guid}/workflow-approval",
        "browserFunctions": [],
        "parsers": [],
        "procedures": []
      }
    ],
    "integrationNote": "Use the current typed client or the exact operations listed here."
  },
  {
    "slug": "checklists-signoffs",
    "title": "Checklists & Signoffs",
    "integrationKind": "page-module",
    "nativeComponentKey": "module.checklists-signoffs",
    "apiBasePaths": [
      "/api/modules/checklists-signoffs"
    ],
    "clientMethods": [],
    "operations": [
      {
        "method": "GET",
        "route": "/api/modules/checklists-signoffs/lego/catalog",
        "browserFunctions": [],
        "parsers": [],
        "procedures": []
      },
      {
        "method": "GET",
        "route": "/api/modules/checklists-signoffs/lookups/{lookupId:guid}",
        "browserFunctions": [],
        "parsers": [],
        "procedures": []
      },
      {
        "method": "GET",
        "route": "/api/modules/checklists-signoffs/templates",
        "browserFunctions": [
          "listChecklistTemplates"
        ],
        "parsers": [
          "parseChecklistTemplateList"
        ],
        "procedures": [
          "sp_Checklists_ListTemplatesSecured"
        ]
      },
      {
        "method": "POST",
        "route": "/api/modules/checklists-signoffs/templates",
        "browserFunctions": [
          "createChecklistTemplate"
        ],
        "parsers": [
          "parseChecklistMutation"
        ],
        "procedures": [
          "sp_Checklists_CreateTemplateSecured"
        ]
      },
      {
        "method": "GET",
        "route": "/api/modules/checklists-signoffs/templates/{checklistTemplateId:guid}",
        "browserFunctions": [
          "getChecklistTemplate"
        ],
        "parsers": [
          "parseChecklistTemplateDetail"
        ],
        "procedures": [
          "sp_Checklists_GetTemplateSecured"
        ]
      },
      {
        "method": "PUT",
        "route": "/api/modules/checklists-signoffs/templates/{checklistTemplateId:guid}",
        "browserFunctions": [
          "updateChecklistTemplate"
        ],
        "parsers": [
          "parseChecklistMutation"
        ],
        "procedures": [
          "sp_Checklists_UpdateTemplateSecured"
        ]
      },
      {
        "method": "DELETE",
        "route": "/api/modules/checklists-signoffs/templates/{checklistTemplateId:guid}",
        "browserFunctions": [
          "removeChecklistTemplate"
        ],
        "parsers": [
          "parseChecklistTemplateRemoval"
        ],
        "procedures": [
          "sp_Checklists_DeactivateTemplateSecured"
        ]
      },
      {
        "method": "GET",
        "route": "/api/modules/checklists-signoffs/runs",
        "browserFunctions": [
          "listChecklistRuns"
        ],
        "parsers": [
          "parseChecklistRunList"
        ],
        "procedures": [
          "sp_Checklists_ListRunsSecured"
        ]
      },
      {
        "method": "GET",
        "route": "/api/modules/checklists-signoffs/runs/{checklistRunId:guid}",
        "browserFunctions": [
          "getChecklistRun"
        ],
        "parsers": [
          "parseChecklistRunDetail"
        ],
        "procedures": [
          "sp_Checklists_GetRunSecured"
        ]
      },
      {
        "method": "POST",
        "route": "/api/modules/checklists-signoffs/runs",
        "browserFunctions": [
          "startChecklistRun"
        ],
        "parsers": [
          "parseChecklistMutation"
        ],
        "procedures": [
          "sp_Checklists_StartRunSecured"
        ]
      },
      {
        "method": "PUT",
        "route": "/api/modules/checklists-signoffs/items/{checklistRunItemId:guid}",
        "browserFunctions": [
          "updateChecklistItem"
        ],
        "parsers": [
          "parseChecklistMutation"
        ],
        "procedures": [
          "sp_Checklists_UpdateItemSecured"
        ]
      },
      {
        "method": "POST",
        "route": "/api/modules/checklists-signoffs/items/{checklistRunItemId:guid}/proof",
        "browserFunctions": [
          "attachChecklistProof"
        ],
        "parsers": [
          "parseChecklistMutation"
        ],
        "procedures": [
          "sp_Checklists_AttachProofSecured"
        ]
      },
      {
        "method": "DELETE",
        "route": "/api/modules/checklists-signoffs/proof/{checklistItemEvidenceId:guid}",
        "browserFunctions": [
          "removeChecklistProof"
        ],
        "parsers": [
          "parseChecklistMutation"
        ],
        "procedures": [
          "sp_Checklists_RemoveProofSecured"
        ]
      },
      {
        "method": "POST",
        "route": "/api/modules/checklists-signoffs/runs/{checklistRunId:guid}/submit",
        "browserFunctions": [
          "submitChecklistForSignoff"
        ],
        "parsers": [
          "parseChecklistMutation"
        ],
        "procedures": [
          "sp_Checklists_SubmitForSignoffSecured"
        ]
      }
    ],
    "integrationNote": "Use the current typed client or the exact operations listed here."
  },
  {
    "slug": "goclaw",
    "title": "GoClaw",
    "integrationKind": "shell-and-page-component",
    "nativeComponentKey": "module.goclaw",
    "apiBasePaths": [
      "/api/goclaw/agents",
      "/api/goclaw/approvals"
    ],
    "clientMethods": [
      "list",
      "approve",
      "reject",
      "takeOver",
      "retry"
    ],
    "operations": [
      {
        "method": "GET",
        "route": "/api/goclaw/approvals",
        "browserFunctions": [],
        "parsers": [],
        "procedures": [
          "sp_AiAction_GetApprovalQueueSecured"
        ]
      },
      {
        "method": "GET",
        "route": "/api/goclaw/approvals/lego/catalog",
        "browserFunctions": [],
        "parsers": [],
        "procedures": []
      },
      {
        "method": "GET",
        "route": "/api/goclaw/approvals/lego/presentation",
        "browserFunctions": [],
        "parsers": [],
        "procedures": [
          "sp_AiAction_GetApprovalQueueSecured"
        ]
      },
      {
        "method": "POST",
        "route": "/api/goclaw/approvals/{suggestionBatchId:guid}/approve",
        "browserFunctions": [],
        "parsers": [],
        "procedures": [
          "sp_AiAction_EditAndApproveSuggestionBatch"
        ]
      },
      {
        "method": "POST",
        "route": "/api/goclaw/approvals/{suggestionBatchId:guid}/reject",
        "browserFunctions": [],
        "parsers": [],
        "procedures": [
          "sp_AiAction_RejectSuggestionBatch"
        ]
      },
      {
        "method": "POST",
        "route": "/api/goclaw/approvals/{suggestionBatchId:guid}/take-over",
        "browserFunctions": [],
        "parsers": [],
        "procedures": [
          "sp_AiAction_ReviewDisposition"
        ]
      },
      {
        "method": "POST",
        "route": "/api/goclaw/approvals/{suggestionBatchId:guid}/retry",
        "browserFunctions": [],
        "parsers": [],
        "procedures": [
          "sp_AiAction_ReviewDisposition"
        ]
      },
      {
        "method": "PUT",
        "route": "/api/goclaw/agents/{goClawAgentId:guid}/authority",
        "browserFunctions": [],
        "parsers": [],
        "procedures": []
      }
    ],
    "integrationNote": "Use the current typed client or the exact operations listed here."
  },
  {
    "slug": "ai-insights",
    "title": "AI Insights",
    "integrationKind": "page-module",
    "nativeComponentKey": "module.ai-insights",
    "apiBasePaths": [
      "/api/modules/ai-insights"
    ],
    "clientMethods": [],
    "operations": [
      {
        "method": "GET",
        "route": "/api/modules/ai-insights",
        "browserFunctions": [
          "listAiInsights"
        ],
        "parsers": [
          "parseAiInsightList"
        ],
        "procedures": [
          "sp_AiInsights_ListSecured"
        ]
      },
      {
        "method": "GET",
        "route": "/api/modules/ai-insights/{insightId:guid}",
        "browserFunctions": [
          "getAiInsight"
        ],
        "parsers": [
          "parseAiInsightDetail"
        ],
        "procedures": [
          "sp_AiInsights_GetSecured"
        ]
      },
      {
        "method": "PUT",
        "route": "/api/modules/ai-insights/{insightId:guid}/state",
        "browserFunctions": [
          "setAiInsightState"
        ],
        "parsers": [
          "parseAiInsightState"
        ],
        "procedures": [
          "sp_AiInsights_SetStateSecured"
        ]
      }
    ],
    "integrationNote": "Use the current typed client or the exact operations listed here."
  },
  {
    "slug": "contacts",
    "title": "Contacts",
    "integrationKind": "page-module",
    "nativeComponentKey": "module.contacts",
    "apiBasePaths": [
      "/api/modules/contacts"
    ],
    "clientMethods": [],
    "operations": [
      {
        "method": "GET",
        "route": "/api/modules/contacts/schema",
        "browserFunctions": [
          "getContactsLegoCatalog"
        ],
        "parsers": [
          "parseSuccessfulResponse"
        ],
        "procedures": [
          "sp_Contacts_GetLegoCatalogSecured"
        ]
      },
      {
        "method": "GET",
        "route": "/api/modules/contacts/lookups/{lookupId:guid}",
        "browserFunctions": [
          "getContactsLegoLookup"
        ],
        "parsers": [
          "parseSuccessfulResponse"
        ],
        "procedures": [
          "sp_Contacts_GetLegoLookupSecured"
        ]
      },
      {
        "method": "GET",
        "route": "/api/modules/contacts/create-visibility-options",
        "browserFunctions": [
          "getContactCreateVisibilityOptions"
        ],
        "parsers": [],
        "procedures": [
          "sp_Contacts_GetCreateVisibilityOptionsSecured"
        ]
      },
      {
        "method": "GET",
        "route": "/api/modules/contacts",
        "browserFunctions": [
          "listContacts"
        ],
        "parsers": [
          "parseContactList",
          "parseSecuredRecordCount"
        ],
        "procedures": [
          "sp_Contacts_ListSecured"
        ]
      },
      {
        "method": "GET",
        "route": "/api/modules/contacts/count",
        "browserFunctions": [
          "listContacts"
        ],
        "parsers": [
          "parseContactList",
          "parseSecuredRecordCount"
        ],
        "procedures": [
          "sp_Contacts_CountSecured"
        ]
      },
      {
        "method": "GET",
        "route": "/api/modules/contacts/{recordId:guid}",
        "browserFunctions": [
          "getContact"
        ],
        "parsers": [
          "parseContactDetail"
        ],
        "procedures": [
          "sp_Contacts_GetSecured"
        ]
      },
      {
        "method": "POST",
        "route": "/api/modules/contacts",
        "browserFunctions": [
          "createContact"
        ],
        "parsers": [
          "parseContactMutation"
        ],
        "procedures": [
          "sp_Contacts_CreateSecured"
        ]
      },
      {
        "method": "PUT",
        "route": "/api/modules/contacts/{recordId:guid}",
        "browserFunctions": [
          "updateContact"
        ],
        "parsers": [
          "parseContactMutation"
        ],
        "procedures": [
          "sp_Contacts_UpdateSecured",
          "sp_RecordScope_GetCurrentSecured",
          "sp_Contacts_GetSecured"
        ]
      },
      {
        "method": "DELETE",
        "route": "/api/modules/contacts/{recordId:guid}",
        "browserFunctions": [
          "removeContact"
        ],
        "parsers": [
          "parseContactRemoval"
        ],
        "procedures": [
          "sp_Developer_DeleteRecord",
          "sp_RecordScope_GetCurrentSecured",
          "sp_Contacts_GetSecured"
        ]
      },
      {
        "method": "PUT",
        "route": "/api/modules/contacts/{recordId:guid}/favorite",
        "browserFunctions": [
          "setContactFavorite"
        ],
        "parsers": [
          "parseContactMutation"
        ],
        "procedures": [
          "sp_Contacts_SetFavoriteSecured"
        ]
      }
    ],
    "integrationNote": "Use the current typed client or the exact operations listed here."
  },
  {
    "slug": "work-orders",
    "title": "Work Orders",
    "integrationKind": "page-module",
    "nativeComponentKey": "module.work-orders",
    "apiBasePaths": [
      "/api/modules/work-orders"
    ],
    "clientMethods": [],
    "operations": [
      {
        "method": "GET",
        "route": "/api/modules/work-orders/schema",
        "browserFunctions": [
          "getWorkOrderLegoCatalog"
        ],
        "parsers": [
          "parseSuccessfulResponse"
        ],
        "procedures": [
          "sp_WorkOrders_GetLegoCatalogSecured"
        ]
      },
      {
        "method": "GET",
        "route": "/api/modules/work-orders/lookups/{lookupId:guid}",
        "browserFunctions": [
          "getWorkOrderLegoLookup"
        ],
        "parsers": [
          "parseSuccessfulResponse"
        ],
        "procedures": [
          "sp_WorkOrders_GetLegoLookupSecured"
        ]
      },
      {
        "method": "GET",
        "route": "/api/modules/work-orders/{recordId:guid}/status-transitions",
        "browserFunctions": [
          "getWorkOrderStatusTransitions"
        ],
        "parsers": [
          "parseSuccessfulResponse"
        ],
        "procedures": [
          "sp_WorkOrders_GetStatusTransitionsSecured"
        ]
      },
      {
        "method": "GET",
        "route": "/api/modules/work-orders",
        "browserFunctions": [
          "listWorkOrders"
        ],
        "parsers": [
          "parseWorkOrderList"
        ],
        "procedures": [
          "sp_WorkOrders_ListSecured"
        ]
      },
      {
        "method": "GET",
        "route": "/api/modules/work-orders/{recordId:guid}",
        "browserFunctions": [
          "getWorkOrder"
        ],
        "parsers": [
          "parseWorkOrderDetail"
        ],
        "procedures": [
          "sp_WorkOrders_GetSecured",
          "sp_Tenant_RecordDynamicFields_GetSecured"
        ]
      },
      {
        "method": "POST",
        "route": "/api/modules/work-orders",
        "browserFunctions": [
          "createWorkOrder"
        ],
        "parsers": [
          "parseWorkOrderMutation"
        ],
        "procedures": [
          "sp_WorkOrders_CreateWithDynamicFieldsSecured"
        ]
      },
      {
        "method": "PUT",
        "route": "/api/modules/work-orders/{recordId:guid}",
        "browserFunctions": [
          "updateWorkOrder"
        ],
        "parsers": [
          "parseWorkOrderMutation"
        ],
        "procedures": [
          "sp_WorkOrders_GetSecured",
          "sp_WorkOrders_UpdateWithDynamicFieldsSecured",
          "sp_RecordScope_GetCurrentSecured"
        ]
      },
      {
        "method": "DELETE",
        "route": "/api/modules/work-orders/{recordId:guid}",
        "browserFunctions": [
          "removeWorkOrder"
        ],
        "parsers": [
          "parseWorkOrderRemoval"
        ],
        "procedures": [
          "sp_WorkOrders_GetSecured",
          "sp_WorkOrders_RemoveSecured",
          "sp_RecordScope_GetCurrentSecured"
        ]
      },
      {
        "method": "PUT",
        "route": "/api/modules/work-orders/{recordId:guid}/status",
        "browserFunctions": [
          "setWorkOrderStatus"
        ],
        "parsers": [
          "parseWorkOrderMutation"
        ],
        "procedures": [
          "sp_WorkOrders_GetSecured",
          "sp_WorkOrders_SetStatusSecured",
          "sp_RecordScope_GetCurrentSecured"
        ]
      },
      {
        "method": "PUT",
        "route": "/api/modules/work-orders/{recordId:guid}/assignment",
        "browserFunctions": [
          "assignWorkOrder"
        ],
        "parsers": [
          "parseWorkOrderMutation"
        ],
        "procedures": [
          "sp_WorkOrders_GetSecured",
          "sp_WorkOrders_AssignSecured",
          "sp_RecordScope_GetCurrentSecured"
        ]
      }
    ],
    "integrationNote": "Use the current typed client or the exact operations listed here."
  },
  {
    "slug": "reservations",
    "title": "Reservations",
    "integrationKind": "page-module",
    "nativeComponentKey": "module.reservations",
    "apiBasePaths": [
      "/api/modules/reservations"
    ],
    "clientMethods": [],
    "operations": [
      {
        "method": "GET",
        "route": "/api/modules/reservations/products",
        "browserFunctions": [
          "listReservationProducts"
        ],
        "parsers": [
          "parseReservationProductList"
        ],
        "procedures": [
          "sp_ReservationProducts_ListSecured"
        ]
      },
      {
        "method": "POST",
        "route": "/api/modules/reservations/products",
        "browserFunctions": [
          "saveReservationProduct"
        ],
        "parsers": [
          "parseReservationMutation"
        ],
        "procedures": [
          "sp_ReservationProducts_UpsertSecured"
        ]
      },
      {
        "method": "GET",
        "route": "/api/modules/reservations",
        "browserFunctions": [
          "listReservations"
        ],
        "parsers": [
          "parseReservationList"
        ],
        "procedures": [
          "sp_Reservations_ListSecured"
        ]
      },
      {
        "method": "GET",
        "route": "/api/modules/reservations/assignees",
        "browserFunctions": [
          "listReservationAssignees"
        ],
        "parsers": [
          "parseReservationAssigneeLookup"
        ],
        "procedures": [
          "sp_Reservations_GetAssigneesSecured"
        ]
      },
      {
        "method": "GET",
        "route": "/api/modules/reservations/capabilities",
        "browserFunctions": [],
        "parsers": [],
        "procedures": [
          "sp_Runtime_GetModuleCapabilitiesSecured"
        ]
      },
      {
        "method": "GET",
        "route": "/api/modules/reservations/{recordId:guid}",
        "browserFunctions": [
          "getReservation"
        ],
        "parsers": [
          "parseReservationDetail"
        ],
        "procedures": [
          "sp_Reservations_GetSecured"
        ]
      },
      {
        "method": "POST",
        "route": "/api/modules/reservations/purchase",
        "browserFunctions": [
          "purchaseReservation"
        ],
        "parsers": [
          "parseReservationMutation"
        ],
        "procedures": [
          "sp_Reservations_PurchaseSecured"
        ]
      },
      {
        "method": "PUT",
        "route": "/api/modules/reservations/{recordId:guid}/status",
        "browserFunctions": [
          "setReservationStatus"
        ],
        "parsers": [
          "parseReservationMutation"
        ],
        "procedures": [
          "sp_Reservations_SetStatusSecured"
        ]
      },
      {
        "method": "PUT",
        "route": "/api/modules/reservations/{recordId:guid}/schedule",
        "browserFunctions": [
          "rescheduleReservation"
        ],
        "parsers": [
          "parseReservationMutation"
        ],
        "procedures": [
          "sp_Reservations_RescheduleSecured"
        ]
      },
      {
        "method": "PUT",
        "route": "/api/modules/reservations/{recordId:guid}/followups",
        "browserFunctions": [
          "updateReservationFollowup"
        ],
        "parsers": [
          "parseReservationMutation"
        ],
        "procedures": [
          "sp_ReservationFollowups_UpdateSecured"
        ]
      },
      {
        "method": "GET",
        "route": "/api/modules/reservations/lego/catalog",
        "browserFunctions": [],
        "parsers": [],
        "procedures": []
      }
    ],
    "integrationNote": "Use the current typed client or the exact operations listed here."
  },
  {
    "slug": "calendar",
    "title": "Calendar",
    "integrationKind": "page-module",
    "nativeComponentKey": "module.calendar",
    "apiBasePaths": [
      "/api/modules/calendar"
    ],
    "clientMethods": [],
    "operations": [
      {
        "method": "GET",
        "route": "/api/modules/calendar",
        "browserFunctions": [
          "listCalendarEvents"
        ],
        "parsers": [
          "parseCalendarEventList"
        ],
        "procedures": [
          "sp_Calendar_ListSecured",
          "sp_Calendar_UpdateSecured"
        ]
      },
      {
        "method": "GET",
        "route": "/api/modules/calendar/{recordId:guid}",
        "browserFunctions": [
          "getCalendarEvent"
        ],
        "parsers": [
          "parseCalendarEventDetail"
        ],
        "procedures": [
          "sp_Calendar_GetSecured",
          "sp_Calendar_UpdateSecured"
        ]
      },
      {
        "method": "POST",
        "route": "/api/modules/calendar",
        "browserFunctions": [
          "createCalendarEvent"
        ],
        "parsers": [
          "parseCalendarMutation"
        ],
        "procedures": [
          "WriteAuditLog",
          "sp_Calendar_CreateSecured",
          "sp_Calendar_UpdateSecured"
        ]
      },
      {
        "method": "PUT",
        "route": "/api/modules/calendar/{recordId:guid}",
        "browserFunctions": [
          "updateCalendarEvent"
        ],
        "parsers": [
          "parseCalendarMutation"
        ],
        "procedures": [
          "WriteAuditLog",
          "sp_Calendar_UpdateSecured",
          "sp_RecordScope_GetCurrentSecured",
          "sp_Calendar_GetSecured"
        ]
      },
      {
        "method": "GET",
        "route": "/api/modules/calendar/capabilities",
        "browserFunctions": [],
        "parsers": [],
        "procedures": [
          "sp_Calendar_UpdateSecured",
          "sp_Runtime_GetModuleCapabilitiesSecured"
        ]
      },
      {
        "method": "DELETE",
        "route": "/api/modules/calendar/{recordId:guid}",
        "browserFunctions": [
          "removeCalendarEvent"
        ],
        "parsers": [
          "parseCalendarRemoval"
        ],
        "procedures": [
          "sp_Calendar_UpdateSecured",
          "sp_Developer_DeleteRecord",
          "sp_RecordScope_GetCurrentSecured",
          "sp_Calendar_GetSecured"
        ]
      },
      {
        "method": "PUT",
        "route": "/api/modules/calendar/{recordId:guid}/favorite",
        "browserFunctions": [
          "setCalendarFavorite"
        ],
        "parsers": [
          "parseCalendarMutation"
        ],
        "procedures": [
          "sp_Calendar_UpdateSecured",
          "sp_Calendar_SetFavoriteSecured"
        ]
      },
      {
        "method": "GET",
        "route": "/api/modules/calendar/lego/catalog",
        "browserFunctions": [],
        "parsers": [],
        "procedures": []
      }
    ],
    "integrationNote": "Use the current typed client or the exact operations listed here."
  },
  {
    "slug": "files",
    "title": "Files",
    "integrationKind": "page-module",
    "nativeComponentKey": "module.files",
    "apiBasePaths": [
      "/api/modules/files"
    ],
    "clientMethods": [],
    "operations": [
      {
        "method": "GET",
        "route": "/api/modules/files",
        "browserFunctions": [
          "listFiles"
        ],
        "parsers": [
          "parseFileList"
        ],
        "procedures": [
          "sp_Files_ListSecured"
        ]
      },
      {
        "method": "GET",
        "route": "/api/modules/files/capabilities",
        "browserFunctions": [],
        "parsers": [],
        "procedures": [
          "sp_Runtime_GetModuleCapabilitiesSecured"
        ]
      },
      {
        "method": "GET",
        "route": "/api/modules/files/{recordId:guid}",
        "browserFunctions": [
          "getFile"
        ],
        "parsers": [
          "parseFileDetail"
        ],
        "procedures": [
          "sp_Files_GetSecured"
        ]
      },
      {
        "method": "POST",
        "route": "/api/modules/files/upload",
        "browserFunctions": [
          "uploadFile"
        ],
        "parsers": [
          "parseFileMutation"
        ],
        "procedures": [
          "sp_FileStorage_ReserveFilesUploadSecured",
          "sp_FileStorage_CommitFilesUploadSecured",
          "sp_FileStorage_RetireFilesUploadSecured"
        ]
      },
      {
        "method": "PUT",
        "route": "/api/modules/files/{recordId:guid}",
        "browserFunctions": [
          "updateFile"
        ],
        "parsers": [
          "parseFileMutation"
        ],
        "procedures": [
          "sp_Files_UpdateSecured"
        ]
      },
      {
        "method": "DELETE",
        "route": "/api/modules/files/{recordId:guid}",
        "browserFunctions": [
          "removeFile"
        ],
        "parsers": [
          "parseFileRemoval"
        ],
        "procedures": [
          "sp_Files_RemoveSecured"
        ]
      },
      {
        "method": "POST",
        "route": "/api/modules/files/{recordId:guid}/attachments",
        "browserFunctions": [
          "attachFile"
        ],
        "parsers": [
          "parseFileMutation"
        ],
        "procedures": [
          "sp_Files_AttachSecured"
        ]
      },
      {
        "method": "DELETE",
        "route": "/api/modules/files/{recordId:guid}/attachments/{attachmentId:guid}",
        "browserFunctions": [
          "detachFile"
        ],
        "parsers": [
          "parseFileMutation"
        ],
        "procedures": [
          "sp_Files_DetachSecured"
        ]
      },
      {
        "method": "PUT",
        "route": "/api/modules/files/{recordId:guid}/favorite",
        "browserFunctions": [
          "setFileFavorite"
        ],
        "parsers": [
          "parseFileMutation"
        ],
        "procedures": [
          "sp_Files_SetFavoriteSecured"
        ]
      },
      {
        "method": "GET",
        "route": "/api/modules/files/lego/catalog",
        "browserFunctions": [],
        "parsers": [],
        "procedures": []
      },
      {
        "method": "GET",
        "route": "/api/modules/files/{recordId:guid}/content",
        "browserFunctions": [
          "downloadFileContent"
        ],
        "parsers": [],
        "procedures": [
          "sp_Files_GetDownloadSecured"
        ]
      },
      {
        "method": "GET",
        "route": "/api/tenant/native-message-attachments/{recordId:guid}/content",
        "browserFunctions": [
          "downloadNativeMessageAttachment"
        ],
        "parsers": [],
        "procedures": [
          "sp_NativeMessageAttachments_GetDownloadSecured"
        ]
      }
    ],
    "integrationNote": "Use the current typed client or the exact operations listed here."
  },
  {
    "slug": "conversations",
    "title": "Conversations",
    "integrationKind": "page-module",
    "nativeComponentKey": "module.conversations",
    "apiBasePaths": [
      "/api/modules/conversations"
    ],
    "clientMethods": [],
    "operations": [
      {
        "method": "GET",
        "route": "/api/modules/conversations",
        "browserFunctions": [
          "listConversations"
        ],
        "parsers": [
          "parseConversationList"
        ],
        "procedures": [
          "sp_Conversations_ListSecured"
        ]
      },
      {
        "method": "GET",
        "route": "/api/modules/conversations/{recordId:guid}",
        "browserFunctions": [
          "getConversation"
        ],
        "parsers": [
          "parseConversationDetail"
        ],
        "procedures": [
          "sp_Conversations_GetSecured"
        ]
      },
      {
        "method": "GET",
        "route": "/api/modules/conversations/{recordId:guid}/messages/{messageId:guid}/attachments/{fileId:guid}/content",
        "browserFunctions": [
          "downloadConversationAttachment"
        ],
        "parsers": [],
        "procedures": [
          "sp_Conversations_GetAttachmentDownloadSecured"
        ]
      },
      {
        "method": "POST",
        "route": "/api/modules/conversations",
        "browserFunctions": [
          "createConversation"
        ],
        "parsers": [
          "parseConversationMutation"
        ],
        "procedures": [
          "WriteAuditLog",
          "sp_Conversations_CreateSecured"
        ]
      },
      {
        "method": "PUT",
        "route": "/api/modules/conversations/{recordId:guid}",
        "browserFunctions": [
          "updateConversation"
        ],
        "parsers": [
          "parseConversationMutation"
        ],
        "procedures": [
          "WriteAuditLog",
          "sp_Conversations_UpdateSecured"
        ]
      },
      {
        "method": "GET",
        "route": "/api/modules/conversations/lego-catalog",
        "browserFunctions": [
          "getConversationsLegoCatalog"
        ],
        "parsers": [
          "parseSuccessfulResponse"
        ],
        "procedures": []
      },
      {
        "method": "GET",
        "route": "/api/modules/conversations/lego-presentation",
        "browserFunctions": [
          "getConversationsLegoPresentation"
        ],
        "parsers": [
          "parseSuccessfulResponse"
        ],
        "procedures": [
          "sp_Conversations_ListSecured"
        ]
      },
      {
        "method": "GET",
        "route": "/api/modules/conversations/capabilities",
        "browserFunctions": [],
        "parsers": [],
        "procedures": [
          "sp_Runtime_GetModuleCapabilitiesSecured"
        ]
      },
      {
        "method": "DELETE",
        "route": "/api/modules/conversations/{recordId:guid}",
        "browserFunctions": [
          "removeConversation"
        ],
        "parsers": [
          "parseConversationRemoval"
        ],
        "procedures": [
          "sp_Conversations_DeleteSecured"
        ]
      },
      {
        "method": "POST",
        "route": "/api/modules/conversations/{recordId:guid}/messages",
        "browserFunctions": [
          "postConversationMessage"
        ],
        "parsers": [
          "parseConversationMutation"
        ],
        "procedures": [
          "WriteAuditLog",
          "sp_Conversations_ReplySecured"
        ]
      },
      {
        "method": "GET",
        "route": "/api/modules/conversations/direct/scope",
        "browserFunctions": [],
        "parsers": [],
        "procedures": [
          "sp_Conversations_GetDirectScopeSecured"
        ]
      },
      {
        "method": "POST",
        "route": "/api/modules/conversations/direct",
        "browserFunctions": [
          "sendDirectConversation"
        ],
        "parsers": [
          "parseConversationMutation"
        ],
        "procedures": [
          "sp_Conversations_SendDirectSecured"
        ]
      },
      {
        "method": "PUT",
        "route": "/api/modules/conversations/{recordId:guid}/favorite",
        "browserFunctions": [
          "setConversationFavorite"
        ],
        "parsers": [
          "parseConversationMutation"
        ],
        "procedures": [
          "sp_Conversations_SetFavoriteSecured"
        ]
      }
    ],
    "integrationNote": "Use the current typed client or the exact operations listed here."
  },
  {
    "slug": "company-news",
    "title": "Company news",
    "integrationKind": "page-module",
    "nativeComponentKey": "module.company-news",
    "apiBasePaths": [
      "/api/modules/company-news"
    ],
    "clientMethods": [],
    "operations": [
      {
        "method": "GET",
        "route": "/api/modules/company-news/schema",
        "browserFunctions": [
          "getCompanyNewsLegoCatalog"
        ],
        "parsers": [
          "parseSuccessfulResponse"
        ],
        "procedures": [
          "sp_CompanyNews_GetLegoCatalogSecured"
        ]
      },
      {
        "method": "GET",
        "route": "/api/modules/company-news/lookups/{lookupId:guid}",
        "browserFunctions": [
          "getCompanyNewsLegoLookup"
        ],
        "parsers": [
          "parseSuccessfulResponse"
        ],
        "procedures": [
          "sp_CompanyNews_GetLegoLookupSecured"
        ]
      },
      {
        "method": "GET",
        "route": "/api/modules/company-news",
        "browserFunctions": [
          "listCompanyNews"
        ],
        "parsers": [
          "parseCompanyNewsList"
        ],
        "procedures": [
          "sp_CompanyNews_ListSecured"
        ]
      },
      {
        "method": "GET",
        "route": "/api/modules/company-news/{recordId:guid}",
        "browserFunctions": [
          "getCompanyNews"
        ],
        "parsers": [
          "parseCompanyNewsDetail"
        ],
        "procedures": [
          "sp_CompanyNews_GetSecured"
        ]
      },
      {
        "method": "POST",
        "route": "/api/modules/company-news",
        "browserFunctions": [
          "createCompanyNews"
        ],
        "parsers": [
          "parseCompanyNewsMutation"
        ],
        "procedures": [
          "WriteAuditLog",
          "sp_CompanyNews_CreateSecured"
        ]
      },
      {
        "method": "PUT",
        "route": "/api/modules/company-news/{recordId:guid}",
        "browserFunctions": [
          "updateCompanyNews"
        ],
        "parsers": [
          "parseCompanyNewsMutation"
        ],
        "procedures": [
          "WriteAuditLog",
          "sp_CompanyNews_UpdateSecured"
        ]
      },
      {
        "method": "PUT",
        "route": "/api/modules/company-news/{recordId:guid}/favorite",
        "browserFunctions": [
          "setCompanyNewsFavorite"
        ],
        "parsers": [
          "parseCompanyNewsMutation"
        ],
        "procedures": [
          "sp_CompanyNews_SetFavoriteSecured"
        ]
      },
      {
        "method": "PUT",
        "route": "/api/modules/company-news/{recordId:guid}/published",
        "browserFunctions": [
          "setCompanyNewsPublished"
        ],
        "parsers": [
          "parseCompanyNewsMutation"
        ],
        "procedures": [
          "sp_CompanyNews_SetPublishedSecured"
        ]
      },
      {
        "method": "DELETE",
        "route": "/api/modules/company-news/{recordId:guid}",
        "browserFunctions": [
          "removeCompanyNews"
        ],
        "parsers": [
          "parseCompanyNewsRemoval"
        ],
        "procedures": [
          "sp_CompanyNews_RemoveSecured"
        ]
      }
    ],
    "integrationNote": "Use the current typed client or the exact operations listed here."
  },
  {
    "slug": "knowledge-core",
    "title": "Knowledge Core",
    "integrationKind": "page-module",
    "nativeComponentKey": "module.knowledge-articles",
    "apiBasePaths": [
      "/api/modules/knowledge-articles",
      "/api/modules/knowledge-core"
    ],
    "clientMethods": [],
    "operations": [
      {
        "method": "GET",
        "route": "/api/modules/knowledge-articles",
        "browserFunctions": [
          "listKnowledgeArticles"
        ],
        "parsers": [
          "parseKnowledgeArticlesList"
        ],
        "procedures": [
          "sp_KnowledgeArticles_ListSecured"
        ]
      },
      {
        "method": "GET",
        "route": "/api/modules/knowledge-articles/{recordId:guid}",
        "browserFunctions": [
          "getKnowledgeArticle"
        ],
        "parsers": [
          "parseKnowledgeArticleDetail"
        ],
        "procedures": [
          "sp_KnowledgeArticles_GetSecured"
        ]
      },
      {
        "method": "POST",
        "route": "/api/modules/knowledge-articles",
        "browserFunctions": [
          "createKnowledgeArticle"
        ],
        "parsers": [
          "parseKnowledgeArticleMutation"
        ],
        "procedures": [
          "sp_KnowledgeArticles_CreateSecured"
        ]
      },
      {
        "method": "PUT",
        "route": "/api/modules/knowledge-articles/{recordId:guid}",
        "browserFunctions": [
          "updateKnowledgeArticle"
        ],
        "parsers": [
          "parseKnowledgeArticleMutation"
        ],
        "procedures": [
          "sp_KnowledgeArticles_UpdateSecured"
        ]
      },
      {
        "method": "PUT",
        "route": "/api/modules/knowledge-articles/{recordId:guid}/favorite",
        "browserFunctions": [
          "setKnowledgeArticleFavorite"
        ],
        "parsers": [
          "parseKnowledgeArticleMutation"
        ],
        "procedures": [
          "sp_KnowledgeArticles_SetFavoriteSecured"
        ]
      },
      {
        "method": "DELETE",
        "route": "/api/modules/knowledge-articles/{recordId:guid}",
        "browserFunctions": [],
        "parsers": [],
        "procedures": [
          "sp_KnowledgeArticles_RemoveSecured"
        ]
      },
      {
        "method": "GET",
        "route": "/api/modules/knowledge-articles/lego/catalog",
        "browserFunctions": [],
        "parsers": [],
        "procedures": []
      },
      {
        "method": "GET",
        "route": "/api/modules/knowledge-core",
        "browserFunctions": [
          "listKnowledgeCore"
        ],
        "parsers": [
          "parseKnowledgeCoreList"
        ],
        "procedures": [
          "sp_kc_ListKnowledgeItemsSecured"
        ]
      },
      {
        "method": "GET",
        "route": "/api/modules/knowledge-core/{recordId:guid}",
        "browserFunctions": [
          "getKnowledgeCore"
        ],
        "parsers": [
          "parseKnowledgeCoreDetail"
        ],
        "procedures": [
          "sp_kc_GetKnowledgeItemSecured"
        ]
      },
      {
        "method": "POST",
        "route": "/api/modules/knowledge-core",
        "browserFunctions": [
          "createKnowledgeCore"
        ],
        "parsers": [
          "parseKnowledgeCoreMutation"
        ],
        "procedures": [
          "sp_kc_CreateKnowledgeItem"
        ]
      },
      {
        "method": "PUT",
        "route": "/api/modules/knowledge-core/{recordId:guid}",
        "browserFunctions": [
          "updateKnowledgeCore"
        ],
        "parsers": [
          "parseKnowledgeCoreMutation"
        ],
        "procedures": [
          "sp_kc_UpdateKnowledgeItem"
        ]
      },
      {
        "method": "POST",
        "route": "/api/modules/knowledge-core/{recordId:guid}/publish",
        "browserFunctions": [
          "publishKnowledgeCore"
        ],
        "parsers": [
          "parseKnowledgeCoreMutation"
        ],
        "procedures": [
          "sp_kc_PublishKnowledgeItem"
        ]
      },
      {
        "method": "POST",
        "route": "/api/modules/knowledge-core/{recordId:guid}/archive",
        "browserFunctions": [
          "archiveKnowledgeCore"
        ],
        "parsers": [
          "parseKnowledgeCoreMutation"
        ],
        "procedures": [
          "sp_kc_ArchiveKnowledgeItem"
        ]
      },
      {
        "method": "GET",
        "route": "/api/modules/knowledge-core/{recordId:guid}/revisions",
        "browserFunctions": [
          "getKnowledgeCoreRevisions"
        ],
        "parsers": [
          "parseKnowledgeRevisions"
        ],
        "procedures": [
          "sp_kc_GetRevisionHistorySecured"
        ]
      },
      {
        "method": "POST",
        "route": "/api/modules/knowledge-core/{recordId:guid}/restore",
        "browserFunctions": [
          "restoreKnowledgeCoreRevision"
        ],
        "parsers": [
          "parseKnowledgeCoreMutation"
        ],
        "procedures": [
          "sp_kc_RestoreRevisionAsDraft"
        ]
      },
      {
        "method": "GET",
        "route": "/api/modules/knowledge-core/collections",
        "browserFunctions": [
          "listKnowledgeCoreCollections"
        ],
        "parsers": [
          "parseKnowledgeCollections"
        ],
        "procedures": [
          "sp_kc_ListCollectionsSecured"
        ]
      },
      {
        "method": "POST",
        "route": "/api/modules/knowledge-core/collections",
        "browserFunctions": [
          "createKnowledgeCoreCollection"
        ],
        "parsers": [
          "parseKnowledgeCollectionMutation"
        ],
        "procedures": [
          "sp_kc_CreateCollection"
        ]
      },
      {
        "method": "PUT",
        "route": "/api/modules/knowledge-core/collections/{collectionId:guid}",
        "browserFunctions": [
          "updateKnowledgeCoreCollection"
        ],
        "parsers": [
          "parseKnowledgeCollectionMutation"
        ],
        "procedures": [
          "sp_kc_UpdateCollection"
        ]
      },
      {
        "method": "POST",
        "route": "/api/modules/knowledge-core/collections/{collectionId:guid}/items/{recordId:guid}",
        "browserFunctions": [
          "addKnowledgeCoreCollectionItem"
        ],
        "parsers": [
          "parseKnowledgeCollectionMutation"
        ],
        "procedures": [
          "sp_kc_AddKnowledgeItemToCollection"
        ]
      },
      {
        "method": "DELETE",
        "route": "/api/modules/knowledge-core/collections/{collectionId:guid}/items/{recordId:guid}",
        "browserFunctions": [
          "removeKnowledgeCoreCollectionItem"
        ],
        "parsers": [
          "parseKnowledgeCollectionMutation"
        ],
        "procedures": [
          "sp_kc_RemoveKnowledgeItemFromCollection"
        ]
      },
      {
        "method": "GET",
        "route": "/api/modules/knowledge-core/{recordId:guid}/owners",
        "browserFunctions": [
          "getKnowledgeCoreOwners"
        ],
        "parsers": [
          "parseKnowledgeOwners"
        ],
        "procedures": [
          "sp_kc_GetKnowledgeOwnersSecured"
        ]
      },
      {
        "method": "POST",
        "route": "/api/modules/knowledge-core/{recordId:guid}/owners",
        "browserFunctions": [
          "setKnowledgeCoreOwner"
        ],
        "parsers": [
          "parseKnowledgeOwnerMutation"
        ],
        "procedures": [
          "sp_kc_SetKnowledgeOwner"
        ]
      },
      {
        "method": "DELETE",
        "route": "/api/modules/knowledge-core/owners/{knowledgeOwnerId:guid}",
        "browserFunctions": [
          "removeKnowledgeCoreOwner"
        ],
        "parsers": [
          "parseKnowledgeOwnerMutation"
        ],
        "procedures": [
          "sp_kc_RemoveKnowledgeOwner"
        ]
      },
      {
        "method": "GET",
        "route": "/api/modules/knowledge-core/unowned",
        "browserFunctions": [
          "listUnownedKnowledgeCore"
        ],
        "parsers": [
          "parseKnowledgeCoreList"
        ],
        "procedures": [
          "sp_kc_GetUnownedKnowledgeSecured"
        ]
      },
      {
        "method": "GET",
        "route": "/api/modules/knowledge-core/assignment-lookup",
        "browserFunctions": [
          "getKnowledgeAssignmentLookup"
        ],
        "parsers": [
          "parseKnowledgeAssignmentLookup"
        ],
        "procedures": [
          "sp_kc_GetAssignmentLookupSecured"
        ]
      },
      {
        "method": "GET",
        "route": "/api/modules/knowledge-core/reviews",
        "browserFunctions": [
          "listKnowledgeReviews"
        ],
        "parsers": [
          "parseKnowledgeReviews"
        ],
        "procedures": [
          "sp_kc_ListDueReviewsSecured"
        ]
      },
      {
        "method": "POST",
        "route": "/api/modules/knowledge-core/reviews/{reviewCycleId:guid}/begin",
        "browserFunctions": [
          "beginKnowledgeReview"
        ],
        "parsers": [
          "parseKnowledgeReviewMutation"
        ],
        "procedures": [
          "sp_kc_BeginReview"
        ]
      },
      {
        "method": "POST",
        "route": "/api/modules/knowledge-core/reviews/{reviewCycleId:guid}/complete",
        "browserFunctions": [
          "completeKnowledgeReview"
        ],
        "parsers": [
          "parseKnowledgeReviewMutation"
        ],
        "procedures": [
          "sp_kc_CompleteReview"
        ]
      },
      {
        "method": "POST",
        "route": "/api/modules/knowledge-core/reviews/{reviewCycleId:guid}/reassign",
        "browserFunctions": [
          "reassignKnowledgeReview"
        ],
        "parsers": [
          "parseKnowledgeReviewMutation"
        ],
        "procedures": [
          "sp_kc_ReassignReview"
        ]
      },
      {
        "method": "GET",
        "route": "/api/modules/knowledge-core/health",
        "browserFunctions": [
          "getKnowledgeHealth"
        ],
        "parsers": [
          "parseKnowledgeHealth"
        ],
        "procedures": [
          "sp_kc_GetKnowledgeHealthSecured"
        ]
      },
      {
        "method": "GET",
        "route": "/api/modules/knowledge-core/questions",
        "browserFunctions": [
          "listKnowledgeQuestions"
        ],
        "parsers": [
          "parseKnowledgeQuestions"
        ],
        "procedures": [
          "sp_kc_GetOpenQuestionsSecured"
        ]
      },
      {
        "method": "POST",
        "route": "/api/modules/knowledge-core/questions",
        "browserFunctions": [
          "createKnowledgeQuestion"
        ],
        "parsers": [
          "parseKnowledgeQuestionMutation"
        ],
        "procedures": [
          "sp_kc_CreateQuestion"
        ]
      },
      {
        "method": "POST",
        "route": "/api/modules/knowledge-core/questions/{knowledgeQuestionId:guid}/assign",
        "browserFunctions": [
          "assignKnowledgeQuestion"
        ],
        "parsers": [
          "parseKnowledgeQuestionMutation"
        ],
        "procedures": [
          "sp_kc_AssignQuestion"
        ]
      },
      {
        "method": "POST",
        "route": "/api/modules/knowledge-core/questions/{knowledgeQuestionId:guid}/answer",
        "browserFunctions": [
          "answerKnowledgeQuestion"
        ],
        "parsers": [
          "parseKnowledgeQuestionMutation"
        ],
        "procedures": [
          "sp_kc_AnswerQuestion"
        ]
      },
      {
        "method": "POST",
        "route": "/api/modules/knowledge-core/questions/{knowledgeQuestionId:guid}/convert",
        "browserFunctions": [
          "convertKnowledgeQuestion"
        ],
        "parsers": [
          "parseKnowledgeQuestionMutation"
        ],
        "procedures": [
          "sp_kc_ConvertQuestionToKnowledge"
        ]
      },
      {
        "method": "POST",
        "route": "/api/modules/knowledge-core/{recordId:guid}/feedback",
        "browserFunctions": [
          "recordKnowledgeFeedback"
        ],
        "parsers": [
          "parseKnowledgeFeedbackMutation"
        ],
        "procedures": [
          "sp_kc_RecordFeedback"
        ]
      },
      {
        "method": "GET",
        "route": "/api/modules/knowledge-core/{recordId:guid}/feedback",
        "browserFunctions": [
          "getKnowledgeFeedback"
        ],
        "parsers": [
          "parseKnowledgeFeedbackSummary"
        ],
        "procedures": [
          "sp_kc_GetKnowledgeFeedbackSummarySecured"
        ]
      },
      {
        "method": "GET",
        "route": "/api/modules/knowledge-core/gaps",
        "browserFunctions": [
          "getKnowledgeGaps"
        ],
        "parsers": [
          "parseKnowledgeGaps"
        ],
        "procedures": [
          "sp_kc_GetKnowledgeGapsSecured"
        ]
      },
      {
        "method": "GET",
        "route": "/api/modules/knowledge-core/support-learning/candidates",
        "browserFunctions": [],
        "parsers": [],
        "procedures": [
          "sp_kc_GetSupportLearningCandidatesSecured"
        ]
      },
      {
        "method": "POST",
        "route": "/api/modules/knowledge-core/support-learning/candidates",
        "browserFunctions": [],
        "parsers": [],
        "procedures": [
          "sp_kc_CreateSupportResolutionCandidate"
        ]
      }
    ],
    "integrationNote": "Use the current typed client or the exact operations listed here."
  },
  {
    "slug": "web-links",
    "title": "Web links",
    "integrationKind": "page-module",
    "nativeComponentKey": "module.web-links",
    "apiBasePaths": [
      "/api/modules/web-links"
    ],
    "clientMethods": [],
    "operations": [
      {
        "method": "GET",
        "route": "/api/modules/web-links/lego/catalog",
        "browserFunctions": [],
        "parsers": [],
        "procedures": []
      },
      {
        "method": "GET",
        "route": "/api/modules/web-links/lookups/{lookupId:guid}",
        "browserFunctions": [],
        "parsers": [],
        "procedures": []
      },
      {
        "method": "GET",
        "route": "/api/modules/web-links",
        "browserFunctions": [
          "listWebLinks"
        ],
        "parsers": [
          "parseWebLinksList"
        ],
        "procedures": [
          "sp_WebLinks_ListSecured",
          "sp_WebLinks_UpdateSecured"
        ]
      },
      {
        "method": "GET",
        "route": "/api/modules/web-links/{recordId:guid}",
        "browserFunctions": [
          "getWebLink"
        ],
        "parsers": [
          "parseWebLinkDetail"
        ],
        "procedures": [
          "sp_WebLinks_GetSecured",
          "sp_WebLinks_UpdateSecured"
        ]
      },
      {
        "method": "POST",
        "route": "/api/modules/web-links",
        "browserFunctions": [
          "createWebLink"
        ],
        "parsers": [
          "parseWebLinkMutation"
        ],
        "procedures": [
          "sp_WebLinks_CreateSecured",
          "sp_WebLinks_UpdateSecured"
        ]
      },
      {
        "method": "PUT",
        "route": "/api/modules/web-links/{recordId:guid}",
        "browserFunctions": [
          "updateWebLink"
        ],
        "parsers": [
          "parseWebLinkMutation"
        ],
        "procedures": [
          "sp_WebLinks_UpdateSecured"
        ]
      },
      {
        "method": "DELETE",
        "route": "/api/modules/web-links/{recordId:guid}",
        "browserFunctions": [
          "removeWebLink"
        ],
        "parsers": [
          "parseWebLinkRemoval"
        ],
        "procedures": [
          "sp_WebLinks_GetSecured",
          "sp_WebLinks_UpdateSecured",
          "sp_Developer_DeleteRecord"
        ]
      },
      {
        "method": "PUT",
        "route": "/api/modules/web-links/{recordId:guid}/favorite",
        "browserFunctions": [
          "setWebLinkFavorite"
        ],
        "parsers": [
          "parseWebLinkMutation"
        ],
        "procedures": [
          "sp_WebLinks_UpdateSecured",
          "sp_WebLinks_SetFavoriteSecured"
        ]
      }
    ],
    "integrationNote": "Use the current typed client or the exact operations listed here."
  },
  {
    "slug": "chat-rooms",
    "title": "Chat rooms",
    "integrationKind": "page-module",
    "nativeComponentKey": "module.chat-rooms",
    "apiBasePaths": [
      "/api/modules/chat-rooms"
    ],
    "clientMethods": [],
    "operations": [
      {
        "method": "GET",
        "route": "/api/modules/chat-rooms",
        "browserFunctions": [
          "listChatRooms"
        ],
        "parsers": [
          "parseChatRoomsList"
        ],
        "procedures": [
          "sp_ChatRooms_ListSecured"
        ]
      },
      {
        "method": "GET",
        "route": "/api/modules/chat-rooms/{recordId:guid}",
        "browserFunctions": [],
        "parsers": [],
        "procedures": [
          "sp_ChatRooms_GetSecured"
        ]
      },
      {
        "method": "POST",
        "route": "/api/modules/chat-rooms",
        "browserFunctions": [
          "createChatRoom"
        ],
        "parsers": [
          "parseChatRoomMutation"
        ],
        "procedures": [
          "WriteAuditLog",
          "sp_ChatRooms_CreateSecured"
        ]
      },
      {
        "method": "PUT",
        "route": "/api/modules/chat-rooms/{recordId:guid}",
        "browserFunctions": [
          "updateChatRoom"
        ],
        "parsers": [
          "parseChatRoomMutation"
        ],
        "procedures": [
          "WriteAuditLog",
          "sp_ChatRooms_UpdateSecured"
        ]
      },
      {
        "method": "GET",
        "route": "/api/modules/chat-rooms/lego/catalog",
        "browserFunctions": [],
        "parsers": [],
        "procedures": []
      },
      {
        "method": "DELETE",
        "route": "/api/modules/chat-rooms/{recordId:guid}",
        "browserFunctions": [
          "removeChatRoom"
        ],
        "parsers": [
          "parseChatRoomRemoval"
        ],
        "procedures": [
          "sp_ChatRooms_DeleteSecured"
        ]
      },
      {
        "method": "POST",
        "route": "/api/modules/chat-rooms/{recordId:guid}/messages",
        "browserFunctions": [
          "postChatMessage"
        ],
        "parsers": [
          "parseChatRoomMutation"
        ],
        "procedures": [
          "WriteAuditLog",
          "sp_ChatRooms_PostMessageSecured"
        ]
      },
      {
        "method": "PUT",
        "route": "/api/modules/chat-rooms/{recordId:guid}/messages/{chatMessageId:guid}",
        "browserFunctions": [
          "updateChatMessage"
        ],
        "parsers": [
          "parseChatRoomMutation"
        ],
        "procedures": [
          "WriteAuditLog",
          "sp_ChatRooms_UpdateMessageSecured"
        ]
      },
      {
        "method": "DELETE",
        "route": "/api/modules/chat-rooms/{recordId:guid}/messages/{chatMessageId:guid}",
        "browserFunctions": [
          "removeChatMessage"
        ],
        "parsers": [
          "parseChatRoomMutation"
        ],
        "procedures": [
          "WriteAuditLog",
          "sp_ChatRooms_DeleteMessageSecured"
        ]
      },
      {
        "method": "PUT",
        "route": "/api/modules/chat-rooms/{recordId:guid}/messages/{chatMessageId:guid}/reaction",
        "browserFunctions": [
          "setChatReaction"
        ],
        "parsers": [
          "parseChatRoomMutation"
        ],
        "procedures": [
          "sp_ChatRooms_SetReactionSecured"
        ]
      },
      {
        "method": "PUT",
        "route": "/api/modules/chat-rooms/{recordId:guid}/members/{memberUserId:guid}",
        "browserFunctions": [
          "setChatRoomMember"
        ],
        "parsers": [
          "parseChatRoomMutation"
        ],
        "procedures": [
          "sp_ChatRooms_SetMemberSecured"
        ]
      },
      {
        "method": "GET",
        "route": "/api/modules/chat-rooms/{recordId:guid}/members/lookup",
        "browserFunctions": [
          "getChatRoomMemberLookup"
        ],
        "parsers": [
          "parseChatRoomMemberLookup"
        ],
        "procedures": [
          "sp_ChatRooms_GetMemberLookupSecured"
        ]
      },
      {
        "method": "PUT",
        "route": "/api/modules/chat-rooms/{recordId:guid}/read",
        "browserFunctions": [
          "markChatRoomRead"
        ],
        "parsers": [
          "parseChatRoomMutation"
        ],
        "procedures": [
          "sp_ChatRooms_MarkReadSecured"
        ]
      },
      {
        "method": "PUT",
        "route": "/api/modules/chat-rooms/{recordId:guid}/favorite",
        "browserFunctions": [
          "setChatRoomFavorite"
        ],
        "parsers": [
          "parseChatRoomMutation"
        ],
        "procedures": [
          "sp_ChatRooms_SetFavoriteSecured"
        ]
      }
    ],
    "integrationNote": "Use the current typed client or the exact operations listed here."
  },
  {
    "slug": "discussion-boards",
    "title": "Discussion Boards",
    "integrationKind": "page-module",
    "nativeComponentKey": "module.discussion-boards",
    "apiBasePaths": [
      "/api/modules/discussion-boards"
    ],
    "clientMethods": [],
    "operations": [
      {
        "method": "GET",
        "route": "/api/modules/discussion-boards",
        "browserFunctions": [
          "listDiscussionBoards"
        ],
        "parsers": [
          "parseDiscussionBoardsList"
        ],
        "procedures": [
          "sp_DiscussionBoards_ListSecured"
        ]
      },
      {
        "method": "GET",
        "route": "/api/modules/discussion-boards/{recordId:guid}",
        "browserFunctions": [
          "getDiscussionBoard"
        ],
        "parsers": [
          "parseDiscussionBoardDetail"
        ],
        "procedures": [
          "sp_DiscussionBoards_GetBoardSecured"
        ]
      },
      {
        "method": "POST",
        "route": "/api/modules/discussion-boards",
        "browserFunctions": [
          "createDiscussionBoard"
        ],
        "parsers": [
          "parseDiscussionMutation"
        ],
        "procedures": [
          "WriteAuditLog",
          "sp_DiscussionBoards_CreateBoardSecured"
        ]
      },
      {
        "method": "PUT",
        "route": "/api/modules/discussion-boards/{recordId:guid}",
        "browserFunctions": [
          "updateDiscussionBoard"
        ],
        "parsers": [
          "parseDiscussionMutation"
        ],
        "procedures": [
          "WriteAuditLog",
          "sp_DiscussionBoards_UpdateBoardSecured"
        ]
      },
      {
        "method": "GET",
        "route": "/api/modules/discussion-boards/lego/catalog",
        "browserFunctions": [],
        "parsers": [],
        "procedures": []
      },
      {
        "method": "DELETE",
        "route": "/api/modules/discussion-boards/{recordId:guid}",
        "browserFunctions": [
          "removeDiscussionBoard"
        ],
        "parsers": [
          "parseDiscussionBoardRemoval"
        ],
        "procedures": [
          "sp_DiscussionBoards_DeleteBoardSecured"
        ]
      },
      {
        "method": "POST",
        "route": "/api/modules/discussion-boards/{boardRecordId:guid}/topics",
        "browserFunctions": [
          "createDiscussionTopic"
        ],
        "parsers": [
          "parseDiscussionMutation"
        ],
        "procedures": [
          "WriteAuditLog",
          "sp_DiscussionBoards_CreateTopicSecured"
        ]
      },
      {
        "method": "GET",
        "route": "/api/modules/discussion-boards/topics/{recordId:guid}",
        "browserFunctions": [],
        "parsers": [],
        "procedures": [
          "sp_DiscussionBoards_GetTopicSecured"
        ]
      },
      {
        "method": "PUT",
        "route": "/api/modules/discussion-boards/topics/{recordId:guid}",
        "browserFunctions": [
          "updateDiscussionTopic"
        ],
        "parsers": [
          "parseDiscussionMutation"
        ],
        "procedures": [
          "WriteAuditLog",
          "sp_DiscussionBoards_UpdateTopicSecured"
        ]
      },
      {
        "method": "DELETE",
        "route": "/api/modules/discussion-boards/topics/{recordId:guid}",
        "browserFunctions": [
          "removeDiscussionTopic"
        ],
        "parsers": [
          "parseDiscussionTopicRemoval"
        ],
        "procedures": [
          "sp_DiscussionBoards_DeleteTopicSecured"
        ]
      },
      {
        "method": "POST",
        "route": "/api/modules/discussion-boards/topics/{topicRecordId:guid}/posts",
        "browserFunctions": [
          "postDiscussionReply"
        ],
        "parsers": [
          "parseDiscussionMutation"
        ],
        "procedures": [
          "WriteAuditLog",
          "sp_DiscussionBoards_PostReplySecured"
        ]
      },
      {
        "method": "PUT",
        "route": "/api/modules/discussion-boards/posts/{recordId:guid}",
        "browserFunctions": [
          "updateDiscussionPost"
        ],
        "parsers": [
          "parseDiscussionMutation"
        ],
        "procedures": [
          "WriteAuditLog",
          "sp_DiscussionBoards_UpdatePostSecured"
        ]
      },
      {
        "method": "DELETE",
        "route": "/api/modules/discussion-boards/posts/{recordId:guid}",
        "browserFunctions": [
          "removeDiscussionPost"
        ],
        "parsers": [
          "parseDiscussionPostRemoval"
        ],
        "procedures": [
          "sp_DiscussionBoards_DeletePostSecured"
        ]
      },
      {
        "method": "PUT",
        "route": "/api/modules/discussion-boards/records/{recordId:guid}/favorite",
        "browserFunctions": [
          "setDiscussionFavorite"
        ],
        "parsers": [
          "parseDiscussionMutation"
        ],
        "procedures": [
          "sp_DiscussionBoards_SetFavoriteSecured"
        ]
      }
    ],
    "integrationNote": "Use the current typed client or the exact operations listed here."
  },
  {
    "slug": "mail-reader",
    "title": "Mail reader",
    "integrationKind": "page-module",
    "nativeComponentKey": "module.mail-reader",
    "apiBasePaths": [
      "/api/modules/mail-reader"
    ],
    "clientMethods": [],
    "operations": [
      {
        "method": "GET",
        "route": "/api/modules/mail-reader",
        "browserFunctions": [
          "listMailReaderMessages"
        ],
        "parsers": [
          "parseMailReaderList"
        ],
        "procedures": [
          "sp_MailReader_ListSecured"
        ]
      },
      {
        "method": "GET",
        "route": "/api/modules/mail-reader/{recordId:guid}",
        "browserFunctions": [
          "getMailReaderMessage"
        ],
        "parsers": [
          "parseMailReaderDetail"
        ],
        "procedures": [
          "sp_MailReader_GetSecured"
        ]
      },
      {
        "method": "PUT",
        "route": "/api/modules/mail-reader/{recordId:guid}/read",
        "browserFunctions": [
          "setMailReaderRead"
        ],
        "parsers": [],
        "procedures": [
          "sp_MailReader_SetReadSecured"
        ]
      },
      {
        "method": "POST",
        "route": "/api/modules/mail-reader/{recordId:guid}/archive",
        "browserFunctions": [
          "archiveMailReaderMessage"
        ],
        "parsers": [],
        "procedures": [
          "sp_MailReader_ArchiveSecured"
        ]
      },
      {
        "method": "GET",
        "route": "/api/modules/mail-reader/mailboxes",
        "browserFunctions": [
          "listMailReaderMailboxes"
        ],
        "parsers": [
          "parseMailReaderMailboxes"
        ],
        "procedures": [
          "sp_MailReader_ListMailboxesSecured"
        ]
      },
      {
        "method": "POST",
        "route": "/api/modules/mail-reader/mailboxes",
        "browserFunctions": [
          "createMailReaderMailbox"
        ],
        "parsers": [
          "parseMailReaderMailboxMutation"
        ],
        "procedures": [
          "sp_MailReader_CreateMailboxSecured"
        ]
      },
      {
        "method": "PUT",
        "route": "/api/modules/mail-reader/mailboxes/{mailboxId:guid}",
        "browserFunctions": [
          "updateMailReaderMailbox"
        ],
        "parsers": [
          "parseMailReaderMailboxMutation"
        ],
        "procedures": [
          "sp_MailReader_UpdateMailboxSecured"
        ]
      },
      {
        "method": "PUT",
        "route": "/api/modules/mail-reader/{recordId:guid}/favorite",
        "browserFunctions": [
          "setMailReaderFavorite"
        ],
        "parsers": [],
        "procedures": [
          "sp_MailReader_SetFavoriteSecured"
        ]
      },
      {
        "method": "PUT",
        "route": "/api/modules/mail-reader/mailboxes/{mailboxRecordId:guid}/credentials/{purpose}",
        "browserFunctions": [
          "setMailReaderCredential"
        ],
        "parsers": [
          "parseMailReaderCredentialStatus"
        ],
        "procedures": [
          "sp_MailReader_SetMailboxCredentialSecured"
        ]
      },
      {
        "method": "POST",
        "route": "/api/modules/mail-reader/mailboxes/{mailboxRecordId:guid}/compose",
        "browserFunctions": [
          "composeMailReaderEmail"
        ],
        "parsers": [
          "parseMailReaderComposeResult"
        ],
        "procedures": [
          "sp_Conversations_CreateSecured",
          "sp_Conversations_ReplySecured",
          "sp_MailReader_ListMailboxesSecured"
        ]
      }
    ],
    "integrationNote": "Use the current typed client or the exact operations listed here."
  },
  {
    "slug": "favorites",
    "title": "Favorites",
    "integrationKind": "page-module",
    "nativeComponentKey": "module.favorites",
    "apiBasePaths": [
      "/api/modules/favorites"
    ],
    "clientMethods": [],
    "operations": [
      {
        "method": "GET",
        "route": "/api/modules/favorites/schema",
        "browserFunctions": [
          "getFavoritesLegoCatalog"
        ],
        "parsers": [
          "parseSuccessfulResponse"
        ],
        "procedures": []
      },
      {
        "method": "GET",
        "route": "/api/modules/favorites/presentation",
        "browserFunctions": [],
        "parsers": [],
        "procedures": [
          "sp_Favorites_ListSecured"
        ]
      },
      {
        "method": "GET",
        "route": "/api/modules/favorites",
        "browserFunctions": [
          "listFavorites"
        ],
        "parsers": [
          "parseFavoritesList"
        ],
        "procedures": [
          "sp_Favorites_ListSecured"
        ]
      },
      {
        "method": "GET",
        "route": "/api/modules/favorites/{recordId:guid}",
        "browserFunctions": [
          "getFavorite"
        ],
        "parsers": [
          "parseFavoriteDetail"
        ],
        "procedures": [
          "sp_Favorites_GetSecured"
        ]
      },
      {
        "method": "GET",
        "route": "/api/modules/favorites/{recordId:guid}/state",
        "browserFunctions": [
          "getFavoriteState"
        ],
        "parsers": [
          "parseFavoriteMutation"
        ],
        "procedures": [
          "sp_Favorites_GetStateSecured"
        ]
      },
      {
        "method": "PUT",
        "route": "/api/modules/favorites/{recordId:guid}/favorite",
        "browserFunctions": [
          "setFavorite"
        ],
        "parsers": [
          "parseFavoriteMutation"
        ],
        "procedures": [
          "sp_Favorites_SetSecured"
        ]
      },
      {
        "method": "PUT",
        "route": "/api/modules/favorites/{recordId:guid}/preferences",
        "browserFunctions": [
          "updateFavoritePreferences"
        ],
        "parsers": [
          "parseFavoriteMutation"
        ],
        "procedures": [
          "sp_Favorites_UpdateSecured"
        ]
      }
    ],
    "integrationNote": "Use the current typed client or the exact operations listed here."
  },
  {
    "slug": "notifications",
    "title": "Notifications",
    "integrationKind": "page-module",
    "nativeComponentKey": "module.notifications",
    "apiBasePaths": [
      "/api/modules/notifications"
    ],
    "clientMethods": [],
    "operations": [
      {
        "method": "GET",
        "route": "/api/modules/notifications",
        "browserFunctions": [
          "listNotifications"
        ],
        "parsers": [
          "parseNotificationList"
        ],
        "procedures": [
          "sp_Notifications_ListSecured"
        ]
      },
      {
        "method": "GET",
        "route": "/api/modules/notifications/lego-catalog",
        "browserFunctions": [
          "getNotificationsLegoCatalog"
        ],
        "parsers": [
          "parseSuccessfulResponse"
        ],
        "procedures": []
      },
      {
        "method": "GET",
        "route": "/api/modules/notifications/lego-presentation",
        "browserFunctions": [
          "getNotificationsLegoPresentation"
        ],
        "parsers": [
          "parseSuccessfulResponse"
        ],
        "procedures": [
          "sp_Notifications_ListSecured"
        ]
      },
      {
        "method": "GET",
        "route": "/api/modules/notifications/{notificationId:guid}",
        "browserFunctions": [
          "getNotification"
        ],
        "parsers": [
          "parseNotificationDetail"
        ],
        "procedures": [
          "sp_Notifications_GetSecured"
        ]
      },
      {
        "method": "PUT",
        "route": "/api/modules/notifications/{notificationId:guid}/state",
        "browserFunctions": [
          "setNotificationState"
        ],
        "parsers": [
          "parseNotificationMutation"
        ],
        "procedures": [
          "sp_Notifications_SetStateSecured"
        ]
      },
      {
        "method": "PUT",
        "route": "/api/modules/notifications/{notificationId:guid}/source-favorite",
        "browserFunctions": [
          "setNotificationSourceFavorite"
        ],
        "parsers": [
          "parseNotificationMutation"
        ],
        "procedures": [
          "sp_Notifications_SetSourceFavoriteSecured"
        ]
      }
    ],
    "integrationNote": "Use the current typed client or the exact operations listed here."
  },
  {
    "slug": "dynamic-records",
    "title": "Dynamic Records",
    "integrationKind": "page-module",
    "nativeComponentKey": "module.dynamic-records",
    "apiBasePaths": [
      "/api/modules/dynamic"
    ],
    "clientMethods": [],
    "operations": [
      {
        "method": "GET",
        "route": "/api/modules/dynamic",
        "browserFunctions": [
          "listDynamicModuleSchemas"
        ],
        "parsers": [
          "parseDynamicModuleCatalog"
        ],
        "procedures": [
          "sp_DynamicModules_ListSchemasSecured",
          "sp_DynamicModules_CreateSecured",
          "sp_DynamicModules_UpdateSecured"
        ]
      },
      {
        "method": "GET",
        "route": "/api/modules/dynamic/{moduleKey}/schema",
        "browserFunctions": [
          "getDynamicModuleSchema"
        ],
        "parsers": [
          "parseDynamicModuleSchema"
        ],
        "procedures": [
          "sp_DynamicModules_GetSchemaSecured",
          "sp_DynamicModules_CreateSecured",
          "sp_DynamicModules_UpdateSecured"
        ]
      },
      {
        "method": "GET",
        "route": "/api/modules/dynamic/{moduleKey}/lookups/{lookupId:guid}",
        "browserFunctions": [],
        "parsers": [],
        "procedures": []
      },
      {
        "method": "GET",
        "route": "/api/modules/dynamic/{moduleKey}/lego/catalog",
        "browserFunctions": [],
        "parsers": [],
        "procedures": [
          "sp_DynamicModules_GetSchemaSecured",
          "sp_DynamicModules_CreateSecured",
          "sp_DynamicModules_UpdateSecured"
        ]
      },
      {
        "method": "GET",
        "route": "/api/modules/dynamic/{moduleKey}",
        "browserFunctions": [
          "listDynamicModuleRecords"
        ],
        "parsers": [
          "parseDynamicModuleList"
        ],
        "procedures": [
          "sp_DynamicModules_ListSecured",
          "sp_DynamicModules_CreateSecured",
          "sp_DynamicModules_UpdateSecured"
        ]
      },
      {
        "method": "GET",
        "route": "/api/modules/dynamic/{moduleKey}/{recordId:guid}",
        "browserFunctions": [
          "getDynamicModuleRecord"
        ],
        "parsers": [
          "parseDynamicModuleDetail"
        ],
        "procedures": [
          "sp_DynamicModules_GetSecured",
          "sp_DynamicModules_CreateSecured",
          "sp_DynamicModules_UpdateSecured"
        ]
      },
      {
        "method": "POST",
        "route": "/api/modules/dynamic/{moduleKey}",
        "browserFunctions": [
          "createDynamicModuleRecord"
        ],
        "parsers": [
          "parseDynamicModuleMutation"
        ],
        "procedures": [
          "sp_DynamicModules_CreateSecured",
          "sp_DynamicModules_UpdateSecured"
        ]
      },
      {
        "method": "PUT",
        "route": "/api/modules/dynamic/{moduleKey}/{recordId:guid}",
        "browserFunctions": [
          "updateDynamicModuleRecord"
        ],
        "parsers": [
          "parseDynamicModuleMutation"
        ],
        "procedures": [
          "sp_DynamicModules_CreateSecured",
          "sp_DynamicModules_UpdateSecured"
        ]
      },
      {
        "method": "DELETE",
        "route": "/api/modules/dynamic/{moduleKey}/{recordId:guid}",
        "browserFunctions": [
          "deleteDynamicModuleRecord"
        ],
        "parsers": [
          "parseDynamicModuleRemoval"
        ],
        "procedures": [
          "sp_DynamicModules_CreateSecured",
          "sp_DynamicModules_UpdateSecured",
          "sp_Developer_DeleteRecord"
        ]
      },
      {
        "method": "PUT",
        "route": "/api/modules/dynamic/{moduleKey}/{recordId:guid}/favorite",
        "browserFunctions": [
          "setDynamicModuleFavorite"
        ],
        "parsers": [
          "parseDynamicModuleMutation"
        ],
        "procedures": [
          "sp_DynamicModules_CreateSecured",
          "sp_DynamicModules_UpdateSecured",
          "sp_DynamicModules_SetFavoriteSecured"
        ]
      },
      {
        "method": "POST",
        "route": "/api/modules/dynamic/caseflow-cases/{recordId:guid}/transition",
        "browserFunctions": [
          "transitionCaseFlowCase"
        ],
        "parsers": [],
        "procedures": [
          "sp_DynamicModules_CreateSecured",
          "sp_DynamicModules_UpdateSecured",
          "sp_CaseFlow_TransitionSecured"
        ]
      }
    ],
    "integrationNote": "Use the current typed client or the exact operations listed here."
  },
  {
    "slug": "active-workplace",
    "title": "ActiveWorkplace",
    "integrationKind": "page-module",
    "nativeComponentKey": "module.active-workplace",
    "apiBasePaths": [
      "/api/modules/active-workplace"
    ],
    "clientMethods": [],
    "operations": [
      {
        "method": "GET",
        "route": "/api/modules/active-workplace",
        "browserFunctions": [
          "listActiveWorkplaces"
        ],
        "parsers": [
          "parseActiveWorkplaceList"
        ],
        "procedures": [
          "sp_ActiveWorkplace_ListSecured"
        ]
      },
      {
        "method": "GET",
        "route": "/api/modules/active-workplace/lego/catalog",
        "browserFunctions": [],
        "parsers": [],
        "procedures": []
      },
      {
        "method": "GET",
        "route": "/api/modules/active-workplace/lego/lookups/{lookupId:guid}",
        "browserFunctions": [],
        "parsers": [],
        "procedures": []
      },
      {
        "method": "GET",
        "route": "/api/modules/active-workplace/lego/presentation",
        "browserFunctions": [],
        "parsers": [],
        "procedures": [
          "sp_ActiveWorkplace_ListSecured"
        ]
      },
      {
        "method": "POST",
        "route": "/api/modules/active-workplace",
        "browserFunctions": [
          "createActiveWorkplace"
        ],
        "parsers": [
          "parseActiveWorkplaceMutation"
        ],
        "procedures": [
          "sp_ActiveWorkplace_CreateWithDynamicFieldsSecured"
        ]
      },
      {
        "method": "GET",
        "route": "/api/modules/active-workplace/{activeWorkplaceId:guid}",
        "browserFunctions": [
          "getActiveWorkplace"
        ],
        "parsers": [
          "parseActiveWorkplaceDetail"
        ],
        "procedures": [
          "sp_ActiveWorkplace_GetSecured",
          "sp_Tenant_RecordDynamicFields_GetSecured"
        ]
      },
      {
        "method": "PATCH",
        "route": "/api/modules/active-workplace/{activeWorkplaceId:guid}",
        "browserFunctions": [
          "updateActiveWorkplace"
        ],
        "parsers": [
          "parseActiveWorkplaceMutation"
        ],
        "procedures": [
          "sp_ActiveWorkplace_UpdateWithDynamicFieldsSecured"
        ]
      },
      {
        "method": "POST",
        "route": "/api/modules/active-workplace/{activeWorkplaceId:guid}/status",
        "browserFunctions": [
          "setActiveWorkplaceStatus"
        ],
        "parsers": [
          "parseActiveWorkplaceMutation"
        ],
        "procedures": [
          "sp_ActiveWorkplace_SetStatusSecured"
        ]
      },
      {
        "method": "GET",
        "route": "/api/modules/active-workplace/{activeWorkplaceId:guid}/participants/catalog",
        "browserFunctions": [
          "getActiveWorkplaceParticipantCatalog"
        ],
        "parsers": [
          "parseActiveWorkplaceCatalog"
        ],
        "procedures": [
          "sp_ActiveWorkplace_GetParticipantCatalogSecured"
        ]
      },
      {
        "method": "POST",
        "route": "/api/modules/active-workplace/{activeWorkplaceId:guid}/participants",
        "browserFunctions": [
          "addActiveWorkplaceParticipant"
        ],
        "parsers": [
          "parseActiveWorkplaceMutation"
        ],
        "procedures": [
          "sp_ActiveWorkplace_AddParticipantSecured"
        ]
      },
      {
        "method": "DELETE",
        "route": "/api/modules/active-workplace/{activeWorkplaceId:guid}/participants/{activeWorkplaceParticipantId:guid}",
        "browserFunctions": [
          "removeActiveWorkplaceParticipant"
        ],
        "parsers": [
          "parseActiveWorkplaceMutation"
        ],
        "procedures": [
          "sp_ActiveWorkplace_RemoveParticipantSecured"
        ]
      },
      {
        "method": "POST",
        "route": "/api/modules/active-workplace/{activeWorkplaceId:guid}/activity",
        "browserFunctions": [
          "recordActiveWorkplaceActivity"
        ],
        "parsers": [
          "parseActiveWorkplaceMutation"
        ],
        "procedures": [
          "sp_ActiveWorkplace_RecordActivitySecured"
        ]
      },
      {
        "method": "POST",
        "route": "/api/modules/active-workplace/{activeWorkplaceId:guid}/graph/refresh",
        "browserFunctions": [
          "refreshActiveWorkplaceGraph"
        ],
        "parsers": [
          "parseActiveWorkplaceMutation"
        ],
        "procedures": [
          "sp_ActiveWorkplace_RefreshGraphSecured"
        ]
      },
      {
        "method": "GET",
        "route": "/api/modules/active-workplace/{activeWorkplaceId:guid}/playback",
        "browserFunctions": [
          "getActiveWorkplacePlayback"
        ],
        "parsers": [
          "parseActiveWorkplacePlayback"
        ],
        "procedures": [
          "sp_ActiveWorkplace_GetPlaybackSecured"
        ]
      }
    ],
    "integrationNote": "Use the current typed client or the exact operations listed here."
  },
  {
    "slug": "record-relations",
    "title": "Record relations",
    "integrationKind": "page-module",
    "nativeComponentKey": "module.record-graph",
    "apiBasePaths": [
      "/api/modules/record-graph"
    ],
    "clientMethods": [],
    "operations": [
      {
        "method": "GET",
        "route": "/api/modules/record-graph/records",
        "browserFunctions": [
          "searchRecordGraph"
        ],
        "parsers": [
          "parseRecordGraphSearch"
        ],
        "procedures": [
          "sp_RecordGraph_SearchSecured"
        ]
      },
      {
        "method": "GET",
        "route": "/api/modules/record-graph/{recordId:guid}",
        "browserFunctions": [
          "getRecordGraph"
        ],
        "parsers": [
          "parseRecordGraph"
        ],
        "procedures": [
          "sp_RecordGraph_GetSecured"
        ]
      },
      {
        "method": "PUT",
        "route": "/api/modules/record-graph/{recordId:guid}/relations",
        "browserFunctions": [
          "addRecordGraphRelation"
        ],
        "parsers": [
          "parseRecordGraphMutation"
        ],
        "procedures": [
          "sp_RecordGraph_AddRelationSecured"
        ]
      },
      {
        "method": "DELETE",
        "route": "/api/modules/record-graph/relations/{recordRelationId:guid}",
        "browserFunctions": [
          "removeRecordGraphRelation"
        ],
        "parsers": [
          "parseRecordGraphMutation"
        ],
        "procedures": [
          "sp_RecordGraph_RemoveRelationSecured"
        ]
      },
      {
        "method": "PUT",
        "route": "/api/modules/record-graph/{recordId:guid}/favorite",
        "browserFunctions": [
          "setRecordGraphFavorite"
        ],
        "parsers": [
          "parseFavoriteMutation"
        ],
        "procedures": [
          "sp_Favorites_SetSecured"
        ]
      },
      {
        "method": "GET",
        "route": "/api/modules/record-graph/{recordId:guid}/knowledge",
        "browserFunctions": [
          "getRelatedKnowledge"
        ],
        "parsers": [
          "parseRelatedKnowledge"
        ],
        "procedures": [
          "sp_kc_GetRelatedKnowledgeSecured"
        ]
      },
      {
        "method": "GET",
        "route": "/api/modules/record-graph/{recordId:guid}/knowledge/candidates",
        "browserFunctions": [
          "getContextualKnowledge"
        ],
        "parsers": [
          "parseContextualKnowledge"
        ],
        "procedures": [
          "sp_kc_GetContextualKnowledgeCandidatesSecured"
        ]
      },
      {
        "method": "PUT",
        "route": "/api/modules/record-graph/{recordId:guid}/knowledge",
        "browserFunctions": [
          "linkKnowledgeToRecord"
        ],
        "parsers": [
          "parseKnowledgeRelationMutation"
        ],
        "procedures": [
          "sp_kc_LinkKnowledgeToRecord"
        ]
      },
      {
        "method": "DELETE",
        "route": "/api/modules/record-graph/knowledge-relations/{recordRelationId:guid}",
        "browserFunctions": [
          "unlinkKnowledgeFromRecord"
        ],
        "parsers": [
          "parseKnowledgeRelationMutation"
        ],
        "procedures": [
          "sp_kc_UnlinkKnowledgeFromRecord"
        ]
      }
    ],
    "integrationNote": "Use the current typed client or the exact operations listed here."
  },
  {
    "slug": "record-activity",
    "title": "Record activity",
    "integrationKind": "page-module",
    "nativeComponentKey": "module.record-activity",
    "apiBasePaths": [
      "/api/modules/record-activity"
    ],
    "clientMethods": [],
    "operations": [
      {
        "method": "GET",
        "route": "/api/modules/record-activity/records",
        "browserFunctions": [
          "searchRecordActivity"
        ],
        "parsers": [
          "parseRecordActivitySearch"
        ],
        "procedures": [
          "sp_RecordActivity_SearchSecured"
        ]
      },
      {
        "method": "GET",
        "route": "/api/modules/record-activity/{recordId:guid}",
        "browserFunctions": [
          "getRecordActivity"
        ],
        "parsers": [
          "parseRecordActivity"
        ],
        "procedures": [
          "sp_RecordActivity_GetSecured"
        ]
      },
      {
        "method": "PUT",
        "route": "/api/modules/record-activity/{recordId:guid}/favorite",
        "browserFunctions": [
          "setRecordActivityFavorite"
        ],
        "parsers": [
          "parseFavoriteMutation"
        ],
        "procedures": [
          "sp_Favorites_SetSecured"
        ]
      }
    ],
    "integrationNote": "Use the current typed client or the exact operations listed here."
  },
  {
    "slug": "global-search",
    "title": "Global secured search",
    "integrationKind": "page-module",
    "nativeComponentKey": "module.global-search",
    "apiBasePaths": [
      "/api/modules/global-search"
    ],
    "clientMethods": [],
    "operations": [
      {
        "method": "GET",
        "route": "/api/modules/global-search",
        "browserFunctions": [
          "searchGlobalRecords"
        ],
        "parsers": [
          "parseGlobalSearch",
          "parseSecuredRecordCount"
        ],
        "procedures": [
          "sp_GlobalSearch_SearchSecured"
        ]
      },
      {
        "method": "GET",
        "route": "/api/modules/global-search/count",
        "browserFunctions": [
          "searchGlobalRecords"
        ],
        "parsers": [
          "parseGlobalSearch",
          "parseSecuredRecordCount"
        ],
        "procedures": [
          "sp_GlobalSearch_CountSecured"
        ]
      },
      {
        "method": "PUT",
        "route": "/api/modules/global-search/records/{recordId:guid}/favorite",
        "browserFunctions": [
          "setGlobalSearchFavorite"
        ],
        "parsers": [
          "parseFavoriteMutation"
        ],
        "procedures": [
          "sp_Favorites_SetSecured"
        ]
      }
    ],
    "integrationNote": "Use the current typed client or the exact operations listed here."
  },
  {
    "slug": "api-inbox-support-lanes-api",
    "title": "Support Lanes API",
    "integrationKind": "api-surface",
    "nativeComponentKey": "module.support-lanes",
    "apiBasePaths": [
      "/api/inbox/support-lanes"
    ],
    "clientMethods": [],
    "operations": [],
    "integrationNote": "This API surface supports other first-class modules and has no standalone page renderer."
  },
  {
    "slug": "api-modules-company-iq-api",
    "title": "Company Iq API",
    "integrationKind": "api-surface",
    "nativeComponentKey": "module.company-iq",
    "apiBasePaths": [
      "/api/modules/company-iq"
    ],
    "clientMethods": [],
    "operations": [],
    "integrationNote": "This API surface supports other first-class modules and has no standalone page renderer."
  },
  {
    "slug": "api-modules-ops-atlas-api",
    "title": "Ops Atlas API",
    "integrationKind": "api-surface",
    "nativeComponentKey": "module.ops-atlas",
    "apiBasePaths": [
      "/api/modules/ops-atlas"
    ],
    "clientMethods": [],
    "operations": [],
    "integrationNote": "This API surface supports other first-class modules and has no standalone page renderer."
  },
  {
    "slug": "api-modules-payments-api",
    "title": "Payments Module API",
    "integrationKind": "api-surface",
    "nativeComponentKey": null,
    "apiBasePaths": [
      "/api/modules/payments"
    ],
    "clientMethods": [],
    "operations": [
      {
        "method": "GET",
        "route": "/api/modules/payments/settings",
        "browserFunctions": [
          "getTenantPaymentSettings"
        ],
        "parsers": [
          "parseTenantPaymentSettings"
        ],
        "procedures": [
          "sp_TenantPayments_GetSettingsSecured"
        ]
      },
      {
        "method": "PUT",
        "route": "/api/modules/payments/settings/{moduleKey}",
        "browserFunctions": [
          "updateTenantPaymentPolicy"
        ],
        "parsers": [
          "parseTenantPaymentMutation"
        ],
        "procedures": [
          "sp_TenantPayments_UpdatePolicySecured"
        ]
      },
      {
        "method": "PUT",
        "route": "/api/modules/payments/connectors",
        "browserFunctions": [
          "upsertTenantPaymentConnector"
        ],
        "parsers": [
          "parseTenantPaymentMutation"
        ],
        "procedures": [
          "sp_TenantPayments_UpsertConnectorSecured"
        ]
      },
      {
        "method": "DELETE",
        "route": "/api/modules/payments/connectors/{connectorId:guid}",
        "browserFunctions": [
          "deactivateTenantPaymentConnector"
        ],
        "parsers": [
          "parseTenantPaymentMutation"
        ],
        "procedures": [
          "sp_TenantPayments_DeactivateConnectorSecured"
        ]
      },
      {
        "method": "GET",
        "route": "/api/modules/payments/methods",
        "browserFunctions": [],
        "parsers": [],
        "procedures": [
          "sp_TenantPayments_ListMethodsSecured"
        ]
      },
      {
        "method": "POST",
        "route": "/api/modules/payments/methods",
        "browserFunctions": [
          "registerTenantPaymentMethod"
        ],
        "parsers": [
          "parseTenantPaymentMutation"
        ],
        "procedures": [
          "sp_TenantPayments_CreateMethodSecured"
        ]
      },
      {
        "method": "GET",
        "route": "/api/modules/payments/methods/{paymentMethodId:guid}",
        "browserFunctions": [
          "getTenantPaymentMethod"
        ],
        "parsers": [
          "parseTenantPaymentMethod"
        ],
        "procedures": [
          "sp_TenantPayments_GetMethodSecured"
        ]
      },
      {
        "method": "PUT",
        "route": "/api/modules/payments/methods/{paymentMethodId:guid}/default",
        "browserFunctions": [
          "setDefaultTenantPaymentMethod"
        ],
        "parsers": [
          "parseTenantPaymentMutation"
        ],
        "procedures": [
          "sp_TenantPayments_SetMethodDefaultSecured"
        ]
      },
      {
        "method": "DELETE",
        "route": "/api/modules/payments/methods/{paymentMethodId:guid}",
        "browserFunctions": [
          "revokeTenantPaymentMethod"
        ],
        "parsers": [
          "parseTenantPaymentMutation"
        ],
        "procedures": [
          "sp_TenantPayments_RevokeMethodSecured"
        ]
      },
      {
        "method": "GET",
        "route": "/api/modules/payments/records/{recordId:guid}",
        "browserFunctions": [
          "getTenantRecordPayments"
        ],
        "parsers": [
          "parseTenantRecordPaymentSummary"
        ],
        "procedures": [
          "sp_TenantPayments_GetRecordSummarySecured"
        ]
      },
      {
        "method": "POST",
        "route": "/api/modules/payments/records/{recordId:guid}/charges",
        "browserFunctions": [
          "createTenantRecordCharge"
        ],
        "parsers": [
          "parseTenantPaymentMutation"
        ],
        "procedures": [
          "sp_TenantPayments_CreateChargeSecured"
        ]
      },
      {
        "method": "DELETE",
        "route": "/api/modules/payments/records/{recordId:guid}/charges/{chargeIntentId:guid}",
        "browserFunctions": [
          "cancelTenantRecordCharge"
        ],
        "parsers": [
          "parseTenantPaymentMutation"
        ],
        "procedures": [
          "sp_TenantPayments_CancelChargeSecured"
        ]
      }
    ],
    "integrationNote": "This API surface supports other first-class modules and has no standalone page renderer."
  }
] as const satisfies readonly HeadlessCapabilityRecipe[];

9. Headless release checklist

  • Run a real login, refresh, reload, logout and expired-session journey; do not mock the transport in the only end-to-end test.
  • Probe every detail and mutation with an own ID, another tenant's real ID, and a random ID. Foreign/absent responses must not become an existence oracle.
  • Verify DataRole, Location, secure-field, AI-read and action permission changes take effect on the next request.
  • Assert list cardinality, stable ordering, first/middle/deep pagination, bounded payload size and no client-side “fetch everything then filter” path.
  • Exercise create/update/stale update/duplicate request, file failure, Workflow approval, ticket resolution, Inbox activity changes, rate limiting and restart recovery.
  • Keep correlation IDs through browser, API, SQL, workers and provider delivery; log safe codes, never tokens, secrets, SQL parameters or returned tenant data.
  • Test keyboard/screen-reader behavior, mobile layout, large photos, slow connections, 401/403/404/409/429/5xx states and abort/navigation races.

Use the native React catalog when the platform component already matches the experience, and the Developer Platform for external/server-to-server applications.

Compare all six styling approaches in Support for React.

Capability review: 2026-09-14. For exact current technical availability, use the generated API Map and first-class module inventory.