diff --git a/apps/docs/AGENTS.md b/apps/docs/AGENTS.md new file mode 100644 index 00000000000..5c3dccfd7d6 --- /dev/null +++ b/apps/docs/AGENTS.md @@ -0,0 +1,37 @@ +# Documentation guidelines + +Read [EDITORIAL_GUIDE.md](EDITORIAL_GUIDE.md) before editing documentation. It defines the voice, terminology, page types, section order, and component choices. [COPY_AUDIT.md](COPY_AUDIT.md) records the complete audit and material source qualifications; keep new conclusions evidence-based. + +## Copy and accuracy + +- Read the complete original page before rewriting. Preserve useful prerequisites, syntax, examples, permissions, defaults, limits, failure consequences, and recovery instructions. Move repeated detail only after its canonical owner contains it and the local link works. +- Verify consequential behavior against its current implementation. Use primary documentation for external procedures. Distinguish repository defaults from deployed settings, Cloud from self-hosting, and accepted operations from completed work. +- Keep Chat content delivery separate from ordinary UI, API-key, MCP, and workflow access. A saved write can have a withheld result; do not imply that a display failure undoes the write. +- Use concise, concrete prose and sentence-case headings. Remove repetition and decorative components without making required information sparse. Honor the editing scope; shared components and assets may still serve excluded pages. + +## Sources and generation + +- Edit generated API and CLI prose at its owner, then use the generation commands in the editorial guide. Do not hand-edit generated specifications, reference pages, or marked generated regions. +- Preserve page URLs, operation IDs, method/path pairs, command options, authentication, and schema behavior. Validate copyable request bodies against the canonical input contracts. +- Check inbound heading anchors from the entire docs site and application before renaming them. Use native explicit tab triggers for provider bookmarks, with `aria-controls` matching panel IDs; preserve the reciprocal `aria-labelledby` relationship and avoid duplicate element IDs. + +## Layout and components + +- Use existing Sim tokens and EMCN chrome. Keep styling local to the component; do not add global CSS overrides or custom colors for one page. +- Use [the authored tab components](components/ui/tabs.tsx). Mixed prose/code panels retain padding; a single code fence can fill its frame. Preserve native selection, keyboard behavior, and intentional code/table scrolling. +- Page spacing belongs to the page container. The navbar, TOC, and sidebar must agree on breakpoints and reserved row heights. Use the shared section order and route matching in `lib/navigation.ts`. +- Inspect mobile, tablet, desktop, and breakpoint boundaries. Check 320px and 390px widths, both sides of 640px, 768px, 1024px, and 1280px, plus a wide desktop. Verify headings clear sticky chrome, drawers remain reachable, touch targets are usable, and prose does not overflow. Restore temporary viewport and theme changes after QA. + +## Verification + +Compile the affected MDX, check internal links and preserved anchors, run the required repository gates, and inspect the production build. Validate all affected tabs and navigation states, rather than only their default panels. Record exact scope and limitations; a successful build does not prove an external provider setup or live Cloud configuration. + + + +## This is NOT the Next.js you know + +This version has breaking changes — APIs, conventions, and file structure may all differ from your training data. Read the relevant guide in `node_modules/next/dist/docs/` (resolved from this file's directory; in monorepos the `next` package may not be visible from the repo root) before writing any code. Heed deprecation notices. + +This block is written and re-added by `next dev` — verify at `node_modules/next/dist/server/lib/generate-agent-files.js`. Removing it from a diff only re-creates the uncommitted change; committing it with your work keeps the tree clean. + + diff --git a/apps/docs/COPY_AUDIT.md b/apps/docs/COPY_AUDIT.md new file mode 100644 index 00000000000..527220f1ac6 --- /dev/null +++ b/apps/docs/COPY_AUDIT.md @@ -0,0 +1,712 @@ +# Documentation copy audit + +Audited from staging snapshot `4d2fa26f5de0532048487a94bbe1afc744500dfe`, beginning 2026-10-13. Rebased onto `origin/staging` at `9058427155` and reviewed the 20 intervening commits before final validation. The [editorial guide](EDITORIAL_GUIDE.md) defines the final voice, terminology, organization, media, and generated-source rules. + +## Scope and method + +The inventory contains **484 entries**: 153 authored MDX pages, 28 generated CLI references, and 303 generated API operations. One authored entry is the root redirect, leaving 483 readable routes. All 306 integration pages are excluded from copy changes, but their links and shared component/asset dependencies are checked. + +Each section received a complete audit before rewriting. Reviewers read the entire assigned copy, retained a per-page ledger, compared consequential claims with the owning implementation, checked examples and limits, inspected local media, and used current primary documentation for external setup. Repeated generated schema prose was read once per unique value while retaining every operation-to-field relationship. This is a documentation accuracy review, not proof of a live hosted configuration or an exhaustive security review. + +Useful facts are retained or moved to a linked canonical owner. Changes remove repeated introductions, promotional language, displaced FAQs, speculative visual placeholders, stale UI instructions, and redundant media. API and CLI prose changes occur at their canonical sources and are regenerated; identifiers, paths, permissions, schema behavior, defaults, and command options are preserved. + +## Assessment and final standard + +The original copy often contained useful technical detail, but placed it behind repeated benefits, broad promises, FAQs, and screenshots of ordinary controls. Pages mixed concepts, setup, reference, and troubleshooting in different orders. The final standard uses a short task-focused opening, sentence-case headings, exact visible labels, and a consistent order for each page type. It preserves detailed references where brevity would hide a requirement or failure consequence. + +## Coverage + +| Section | Entries | Disposition | +| --- | ---: | --- | +| Workflow blocks | 18 | complete | +| API data operations | 136 | complete | +| API workflow operations | 59 | complete | +| API workspace operations | 108 | complete | +| CLI reference | 28 | complete | +| Self hosting setup | 10 | complete | +| Self hosting operations | 12 | complete | +| Workflow core | 16 | complete | +| Enterprise governance | 8 | complete | +| Search | 21 | complete | +| Platform | 6 | complete | +| Enterprise identity | 9 | complete | +| Orientation | 6 | complete | +| Chat | 8 | complete | +| API guides | 5 | complete | +| Knowledgebase | 7 | complete | +| Agents | 5 | complete | +| CLI guides | 8 | complete | +| Files | 5 | complete | +| Tables | 3 | complete | +| Logs | 3 | complete | +| MCP | 3 | complete | + +## Main accuracy corrections + +| Area | Finding and final treatment | Implementation or canonical owner | +| --- | --- | --- | +| Workflow state and branching | Variables assign resolved values rather than calculate; Parallel shares workflow variables and unhandled errors can fail the run. Correct examples use real container names and nested result shapes. Router exposes context/reasoning rather than content; an unconnected selectedPath has an empty blockId rather than null. | `executor/handlers/variables`, `executor/execution`, workflow/block guides and shared previews | +| Runs and deployment | Draft inspection, deployed execution, sync/async receipts, token streaming, v2 framing and legacy resume differ. v2 streaming runs resume asynchronously. Workflow exports can still contain literal secrets. Thinking and tool events have separate deployment policies. Function All secrets narrows the run’s authorized environment rather than granting new access. | `lib/workflows/application`, `lib/workflows/executor`, workflow deployment guides | +| Agent and Pi | Structured output is requested, not universally guaranteed; parsed fields are not always an object in content. Cache rules vary by model. Pi includes Plan; SSH shell starts in the repository but has the account’s OS permissions. | Agent/Pi handlers and block references | +| Tables | Cells nest under row.data. Mappings populate Start fields without restricting full row context. False/empty dependencies wait; edits/output clearing can re-arm work. Completed blank results differ from incomplete runs. Expiration is scheduled deletion. | `lib/table`, workflow-column worker/UI and table guides | +| Credentials and permissions | Credential Groups grant allowed integration types. Personal secrets have grant-resolution nuances without a current sharing control. Explicit empty SCIM groups govern nobody; empty inheritance groups can broaden scope. Workspace keys differ from human principals. | Credential/permission-group use cases, platform and enterprise guides | +| Logs and retention | Refresh loads a stable snapshot; search text matches run IDs, not arbitrary run content. Current trace uses stacked sections. Run-backed alert cooldowns differ from the per-workflow No Activity cooldown. Cloud Free defaults to 30 days, paid and billing-disabled modes have no plan default, and configured cleanup is deletion rather than an archive. | Logs UI/filter implementation, cleanup dispatcher and Data retention | +| Costs | Billing mode is distinct from hosting location. Model-block cost objects and Logs API cost fields use USD while Billing/run-resource endpoints and displayed logs use credits. Unsupported purchase/voice instructions are removed; live Max limit conflicts stay qualified. | Cost contracts, billing configuration and Costs | +| Search | Supported sources retain their specific access/query/read limits. Drive’s native Sheets reads need Sheets API; OAuth setup has a canonical owner. Confluence overflow relevance pages are partial and have no cursor; native CQL supports continued paging. GitLab legacy search is unavailable; Zoom is deployment-enabled rather than universally present. | Search adapters, provider setup and Search guides | +| Chat and desktop | Recurring Chat work uses deployed workflow schedules; worker behavior is source evidence, not a live Cloud guarantee. Desktop selected-folder reads, browser uploads, Full file access and OS shell privileges are distinct. Native Mac-app control requires its deployment gate, device opt-in and app approval; Chat Find searches loaded transcript windows. | Current external-worker snapshot, desktop tools/settings and Chat/Desktop guides | +| Self-hosting | Deployment-wide schedule caps, background job inventory, Node workers, secrets/TLS/origins, storage durability and billing-disabled limits are scoped. Chart 1.11.8 is a verified published example, not a live installation claim. | Compose/Helm, config and operator guides | +| MCP | JSON operations only; read operations can have POST bodies. Catalog search is bounded without a cursor, offline refresh expires, and a result-size error can follow a committed write. | MCP catalog/dispatch/auth and MCP guides | +| Generated requests | Original rendered defaults had 17 invalid JSON bodies out of 135. Media-level validated examples and valid fork/push/pull/import examples correct these without changing the input contracts. | OpenAPI generator and owning contracts | +| CLI | Resource/lifecycle organization keeps comprehensive command lookup, flags, aliases and confirmation consequences. Inline code preserves literal pipes, backslashes and nested ticks. | CLI command metadata and documentation generator | +| Output and limits QA | Qualified Function timeout/stdout limits, Agent metadata-name collisions, Evaluator fallback/coercion, abbreviated Connections outputs, and fixed table column limits. | Current Function/Agent/Evaluator handlers and Table constants | +| Final preservation review | Restored five provider-token setup links, Stop all and manual dependency behavior, regional PII identifiers and Presidio reference, named Credential references, exact paused v2 resume lookup, and the direct migration prerequisite before upgrade commands. Workflow preview code and visible labels match their examples. | Current settings, executor, table worker, PII catalog and migration owners | +| Current source qualifications | Corrected paid retention tiers, GiB storage units, Bun/Node prerequisites, SSO/Integrations labels, drain endpoint policy, reversible encryption-key mismatch, NetworkPolicy any-source default, and Pi absolute provider TTL/account limits. | Billing cleanup, settings UI, outbound profiles, encryption, chart and sandbox adapters | +| API and CLI final comparison | Truthful full connector example uses current projected fields/scopes and incremental-sync support. CLI help distinguishes credit usage, saved changes, delete scheduling, variable batches and file references. Restoring the search keyword “spent” preserves billing discovery without the false period claim. | Connector metadata/projection, command metadata and existing search ranking tests | +| Generated output safety | The real resources input exceeds Biome’s default 1 MiB cap, which previously yielded successful empty output. The formatter now explicitly caps input/output at 16 MiB, rejects process failures and nonempty-input/empty-output results, and preserves complete parsed JSON. | `scripts/format-generated-source.ts` and actual generator boundary proof | + +## Independent final comparison + +A fresh parallel review compared every complete original page with its final version, including examples, prerequisites, useful FAQ answers, and local media. Exact ledger reconciliation covers all **484 entries across 22 sections**, without duplicate or missing assignments. Reviewers judged each entry an improvement in clarity, organization, accuracy, or useful coverage, with **zero remaining identified copy issues** after corrections. This is a documented comparative judgment, not a guarantee that every external setup or deployed policy has been exercised. The final column retains the per-page comparison and preservation conclusions. + +The final source pass also reviewed the later Chat content-delivery gate, crawler/Markdown changes, and shared file-ownership foundation from staging. Workspace access, search completeness, sharing, storage and retention wording remain supported. Newly added Project foundations are not described as a released Project Files surface. Integration landing backlinks and per-page Markdown are preserved. + +## Components and asset cleanup + +Shared navigation and API UI labels follow sentence case while preserving acronyms and product names. Authored tabs use a local wrapper around Fumadocs selection and keyboard behavior: mixed panels keep their inset, single code fences fill the frame, and mobile tab lists scroll with 44px targets. SSO provider anchors use native explicit triggers with `aria-controls` matching their panel IDs; keyboard navigation, selection, and bookmarked activation remain native. The shared tab frame uses the actual header/TOC row offset when scrolling a bookmarked panel into view. The compact drawer uses 30px visible chip faces within 44px mobile touch targets, aligned full-width dividers, and the shared section order. TOC/header rows reserve their actual heights at mobile/tablet breakpoints; prose wraps without changing intentional code/table scrolling. API method badges use existing platform surface and text tokens instead of custom color overrides. Integration MDX content remains unchanged. The final pass removes the unused ActionMedia component and its local styling, three unused workflow-preview definitions/exports, and 111 local media files (15,187,771 bytes). Every removed asset belonged to an originally reviewed page and had no basename consumer in current repository source, including integrations and application code. Shared components and media with other consumers remain. Remote media was removed from pages only; no remote assets were deleted. + +FAQ answers were folded into their relevant sections. Callouts decreased from 234 to 117; authored Image/ActionImage and Video/ActionVideo instances decreased from 178 to 23. All 36 editorial placeholders were removed. These counts cover the 153 authored entries and exclude generated reference pages and integrations. + +## Page-by-page disposition + +Every row below represents a fully reviewed inventory entry. “Rewritten” includes organization/voice changes; “corrected” highlights an accuracy fix; “generated” means the owner was changed and the page regenerated; “retained” means reviewed copy already met its purpose. Shared API changes include sentence-case summaries, authentication labels, nonpaged bounds, response-unit/retention qualifications, neutral domain-error examples, valid request/response rendering, and sentence-case UI headings. + +### Workflow blocks (18) + +| Page or operation | Result | Changes | Final comparison and preservation | +| --- | --- | --- | --- | +| [workflows/blocks/agent.mdx](content/docs/workflows/blocks/agent.mdx) | rewritten | Moved a valid structured-classification example before configuration and shortened the opening/description. Preserved provider discovery, Nebius/Jev, tools/skills, durable memory, retry recovery, fallback constraints, and the generated streaming region. Explained direct structured-output fields, malformed-JSON fallback, provider-specific schema enforcement, and supported forced-tool behavior. Replaced universal cache thresholds/discounts and free automatic-cache claims with model-specific primary documentation; described temperature/reasoning as task-dependent settings. Folded unique FAQ answers into provider/failure details and removed repeated best-practice prose. Named independent Include thinking and Include tool calls deployment policies, each requiring client protocol negotiation. Generated capability region preserved byte-for-byte. Retained estimated-cost qualification and specified USD input/output/total objects and .total reference; distinguished Logs UI/run-resource credits and linked Costs. Pi separately identifies possible sandbox cost. Qualified top-level structured fields: standard model/tokens/toolCalls/providerTiming/cost metadata overwrites same-named schema properties. | Verified improvement. Leads with actual structured classification, removes unconditional shape/forced-tool/cache/factuality guarantees, and qualifies native provider enforcement and malformed JSON. Documents metadata-name collisions and USD cost object versus run credits; independent streamed thinking/tool settings and current provider failure details are clearer. Preserved: All configuration, provider prefixes/discovery, Nebius/BYOK, complete Jev question example/answer shapes/limits, file input, dynamic Permission Mode values, skills, all memory windows, durable tool history/retrieval/summaries/retry recovery, fallback/key constraints and token controls remain. Both complete JSON Schemas, system message and classify preview were reviewed; generated model capability table is unchanged byte-for-byte from the requested baseline. Useful FAQ details moved into Provider and failure details. | +| [workflows/blocks/api.mdx](content/docs/workflows/blocks/api.mdx) | rewritten | Organized purpose, fetch example, fields, advanced controls, outputs, and failure handling. Corrected non-2xx handling to the error port; normal status branches cover successful responses. Added credential forwarding on cross-origin redirects, body-encoding qualification, and the 10 MiB fetch-time cap. Preserved timeout/retry/backoff defaults, non-idempotent retry consequence, proxy guidance, and secret syntax. | Verified improvement. Replaces failed-status-on-normal-path guidance with error-port handling for non-2xx/network/timeout failures. Adds cross-origin credential redirect control, exact retry defaults/safety, proxy boundary, and fetch-time 10 MiB response cap. Preserved: Retains all HTTP methods/default GET, dynamic URL/query/header/body configuration, automatic header overrides, timeout 300,000/max600,000ms, backoff defaults500/30,000ms, idempotency caution, publicly reachable HTTP proxy tunnel, and successful data/status/headers. Fetch/summarize preview is preserved; Start now says User ID consistent with /users/. All prior distinct FAQ details are folded into settings/failures. | +| [workflows/blocks/condition.mdx](content/docs/workflows/blocks/condition.mdx) | rewritten | Led with ordered first-true routing and a priority example; separated fields, outputs, unmatched input, errors, and a score-gating example. Preserved expression operators, literal environment comparison behavior, safe string binding, else behavior, and selectedPath object shape. Made moderation schema numeric and replaced the undefined blocking helper in its preview with a real throwing Function. Folded model-score/tier examples and unique FAQ guidance into their relevant sections. | Verified improvement. Explains first true rule order, unsupported intent use case, skipped-block output and exact selectedPath/null behavior. Shows an actual priority branch and a structured numeric toxicity gate, with throwing-expression recovery and explicit no-match/end behavior. Preserved: Retains all three JavaScript tag expressions and all three secret literal comparisons, operators/string/array/math/Date support, safe secret binding versus Function string distinction, else/catch-all and optional chaining. Priority and moderation previews remain with correct if/else handles; onboarding-tier example technique remains in prose rather than a third duplicate preview. | +| [workflows/blocks/credential.mdx](content/docs/workflows/blocks/credential.mdx) | rewritten | Reorganized all six workspace/organization OAuth/MCP operations under one configuration/output reference. Replaced cross-service Google credential reuse with compatible Slack actions; completed production/staging routing with Slack consumers. Preserved invitation email versus provider accountEmail, active-account filtering, exactly-one Find semantics, pagination, allowed-workspace/integration scope, and event delivery/legacy migration. Clarified credential IDs versus tokens and MCP connection IDs versus shared server configuration. Replaced the empty Google Ads loop screenshot with a written List → For Each → compatible action procedure. | Verified improvement. Replaces false cross-service Google-account reuse with compatible Slack references and per-action credential authorization/scopes. Orders a usable example before full OAuth/organization/MCP operations, access prerequisites, pagination, deleted credentials and trigger behavior. Preserved: Retains all six operations, invitation versus provider email, workspace/integration allowlisting, every required/optional field, limit100/max100 and cursor rules, exact-one Find, inactive exclusion, duplicates and all output fields. All three unique patterns remain: shared reference, conditional accounts, and paginated/list Loop. Accounts is explicitly named; managed connection versus shared mcpServerId, Function ID-only behavior, secret/service-account exclusions and legacy trigger replacement remain. | +| [workflows/blocks/evaluator.mdx](content/docs/workflows/blocks/evaluator.mdx) | rewritten | Led with a quality-gate example, then metrics/content/model/fallbacks, outputs, and related docs. Clarified that unnamed metrics are skipped but missing ranges are not a reliable disable mechanism. Preserved named lowercase outputs, model/key configuration, fallback ordering and one-attempt behavior. Explained that requested ranges guide the model and are not general output clamps; removed generic rubric advice repeated elsewhere. Retained estimated-cost qualification and specified USD input/output/total objects and .total reference; distinguished Logs UI/run-resource credits and linked Costs. Pi separately identifies possible sandbox cost. Documented zero fallback for missing/unparseable scores and unguarded numeric coercion; require finite, in-range scores for consequential decisions. | Verified improvement. Corrects missing-range skip and enforced-in-range promises; distinguishes requested schema from post-response range/finite validation. Makes zero fallback/unparseable response and Number-to-NaN behavior visible, while retaining retries/fallback credentials and correct cost units. Preserved: Retains Accuracy/Clarity/Relevance rubric, 1–5 example, text/structured-data versus image/audio boundary, model/advanced settings, all output names, lowercase scores, comparative-metric consistency and quality-gate preview. All fallback ordering/key inheritance/Auto restrictions remain. Gate checks Accuracy>=4 and preserves alternative review path in task prose; no useful FAQ contract is silently dropped. | +| [workflows/blocks/function.mdx](content/docs/workflows/blocks/function.mdx) | rewritten | Moved the API transformation example first, followed by runtime choice, code/secret syntax, outputs/files, sandbox lifecycle, Agent-tool secret access, distinct examples, large inputs, and errors. Preserved all JavaScript/Python/Shell return conventions, placeholder string/regex/heredoc rules, package catalog, sandbox dependency rules, build sharing/retry/install behavior, and large-value helpers. Carried the file-path remote-mount exception into the runtime table and local-runtime explanation; documented /tmp/sim/inputs and /tmp/sim/outputs and the special indexed .path reference. Separated outputPath/outputSandboxPath/outputTable as direct Function-tool controls rather than builder fields. Preserved secret-export refusal, masking/Unredacted boundaries, 20-file/50 MiB/11-directory caps, and the actual remaining-workflow timeout budget. Made input normalization and loyalty examples self-contained; converted ordinary runtime/build/helper callouts to prose and qualified Python plot capture. Qualified All secrets by the run resolved environment, identities, workspace access and secret grants; Selected secrets only narrows access, and new secrets require execution access. Used shared authored tabs with padded mixed content, wrapped prose, visible horizontal scrolling, and mobile touch targets. Documented the no-deadline Function fallback timeout, configurable local stdout truncation, and separate remote process-output versus file-export budgets. | Verified improvement. Moves runtime prerequisites ahead of code and separates builder outputs/fields from separate Function tool persistence controls. Adds bounded local stdout/remote combined process output and precise fallback/deadline timeout behavior; fixes loyalty inputs, normalized-write description, and mismatched reshape inspector. Preserved: Every code fence was read: JS/Python/Shell active-ID transform, secret expression/conversions/regex/heredoc, pandas mounted-file export, dependency/system lists, bq, one-off install, both full loyalty implementations and all lazy file-read calls. Retains local/remote/import/path distinctions, default/base package and CLI inventory, workspace sandbox authorization/build/runtime strategies/deletion/retry/restrictions, file20/50MiB/depth11 limits, exact secret/export boundaries, all-versus-selected secret tooling and large-input helper limitations. | +| [workflows/blocks/guardrails.mdx](content/docs/workflows/blocks/guardrails.mdx) | rewritten | Moved valid-JSON gating first and completed its preview with parser and rejection branches. Corrected Mask PII passed=true behavior while retaining Block Request passed=false and the original-input exposure warning. Preserved one-check-per-block behavior, JSON syntax/schema distinction, grounding thresholds/chunk limits, outputs, language support, and regional/custom PII selection. Added RE2 unsupported lookaround/backreference behavior and distinguished the custom PII pattern engine. Removed duplicate FAQ, screenshot, and remote video explanations; retained distinct grounding/PII patterns. | Verified improvement. Corrects successful Mask semantics and independent output use; adds RE2 unsupported constructs, custom engine distinction, and model-grounding qualification. Preserves and extends regional identifiers in a compact current-catalog table and restores the useful Presidio primary documentation link. Preserved: Retains all four validation types, syntax-only JSON, complete email regex, grounding0–10/default3/no model/default5max20 chunks, synchronous latency, Common/all regional identifiers/language selection, outputs and all three workflow previews. New rows retain original NIF/NIE, Italian IDs, PESEL, NRIC/FIN, ABN/ACN/TFN/Medicare and all Indian IDs while adding current VAT/UEN/Finland. Original input remains distinct from maskedText, and detection-with-no-selected-types is qualified. | +| [workflows/blocks/human-in-the-loop.mdx](content/docs/workflows/blocks/human-in-the-loop.mdx) | rewritten | Named the visible Human block and led with an actual Approval → Condition → publish/reject gate. Corrected single and two-stage previews so submitted approved=false cannot follow the action path. Used consistent named references, valid display JSON, configured metric names, and before/after submission outputs. Consolidated portal/notification/form instructions and replaced overlapping resume/execute tabs with synchronous and async v2 examples. Corrected v2 originally-streaming resumption to async202 JSON; preserved separate legacy endpoints, job receipts, pause-point lookup, selected-output and legacy SSE behavior. Retained no automatic response timeout, cancellation, multiple-pause and human-data-correction behavior. | Verified improvement. Replaces resume-equals-approval examples with explicit true/false gates in single and two-stage flows. Corrects originally-streaming v2 resume to202 JSON/background behavior, fixes named/display references and adds exact data.output.data._resume/contextId and data.runId access. Preserved: Retains complete Display Data, all notification channels/credentials/URL role, typed boolean/comments form, portal, full resumed run envelope/async receipt, all output fields and multi-stage/corrected-data use cases. Retains no automatic response timeout/cancel, pause-point GET/404, all legacy POST/job polling/SSE compatibility, selected-output auto-inclusion, repeated pauses and separate resume run IDs. Useful paused-envelope access fact is preserved explicitly rather than lost with duplicate tabs. | +| [workflows/blocks/logs.mdx](content/docs/workflows/blocks/logs.mdx) | rewritten | Added a description and a Query IDs → For Each → Get Run Details minimum procedure. Added explicit output shapes/count, trigger filtering, advanced sorting, limits and cost/duration units. Preserved the protected log-facing projection and clarified retained logs versus every internal runtime value. Corrected Free retention to the scoped30-day default and linked effective workspace/organization policy; preserved billing-disabled self-hosted behavior. Added Logs to explicit blocks navigation metadata and converted normal projection explanation to prose. Final navigation gate: retained the existing Logs integration related-page link and omitted a duplicate Core blocks child; the reviewed reference URL and inbound links remain available. | Verified improvement. Turns operation tabs into a complete named Query→For Each→Get Run Details procedure and adds trigger/sort/count controls. Corrects seven-day retention promise to effective30-day default and protected log-facing projection rather than every internal value. Preserved: Retains workspace-only access, every Query filter/limit100max200, newest-first order, full detail metadata/trace/finalOutput fields, credits/ms units and Sim-event shortcut. Retention policy is linked to an owner that contains override/cleanup rules; run-time result remains distinguished from projected logs. | +| [workflows/blocks/loop.mdx](content/docs/workflows/blocks/loop.mdx) | rewritten | Led with a named Process Reviews collection example and preserved all four type/setting behaviors. Corrected arithmetic updates to Function → Variables and the1000 value to a saved-execution default rather than a hard cap. Corrected completed-container references to normalized names and showed nested per-iteration output arrays. Preserved current index/item/items scope, missing versus empty collection behavior, unbounded conditional loops, execution budgets, nesting and error handling. Verified object collections yield [key,value] pairs in the collection resolver and documented indexed references. Removed stale full-builder screenshots whose useful scope/type information is now text. | Verified improvement. Corrects generic completed , unconditional1000 cap and unevaluated Variables arithmetic to named container results and Function→Variables. Explains nested result arrays, object key/value items, empty versus missing collection, conditional exit and execution budget. Preserved: Retains all four loop modes/check timing/fixed-count fallback, all item/index/items references, normalization, sequential work, nesting in both directions and every distinct API/variation/polling pattern. Full Process Reviews preview and both code/result examples reviewed; removed screenshots are covered by exact setting/type table, not replaced with unsupported images. | +| [workflows/blocks/parallel.mdx](content/docs/workflows/blocks/parallel.mdx) | rewritten | Led with named Process Tasks example, bounded batches, and real aggregation code. Corrected isolated-variable and independent-unhandled-error guarantees; preserved own item/index/block outputs and ordered nested results. Preserved1–20/default20 batch control, serial batch behavior, global rate-limit caveat, indexed large-output hydration, nesting, and empty collections. Documented object [key,value] items and retained a concise Parallel/Loop comparison. Removed stale repetitive full-builder screenshots and folded FAQ into state/behavior sections. | Verified improvement. Corrects false variable-isolation and independent-error guarantees to shared variables and run-level unhandled failure. Clarifies batches, per-branch Wait versus global rate limit, nested ordered results and index hydration with a correctly typed API path. Preserved: Retains count/collection modes,1–20/default20 batch bound, serial batches beyond bound, index/item/items scope, input result order versus completion order, nesting/empty collection and model/API use cases. Full Process Tasks preview aggregation code and result references reviewed. Loop comparison remains, while unsupported no-shared-state advice is replaced with actual shared-state caution. | +| [workflows/blocks/pi.mdx](content/docs/workflows/blocks/pi.mdx) | rewritten | Shortened title/description and added the missing Plan mode plus a registered Pi hero. Preserved mode-specific repository/model/search/BYOK/SSH controls and full Babysit permissions, trusted-data boundaries, pinning, partial outcomes and fixed bounds. Corrected Local Dev confinement: file paths are validated, shell commands run with SSH account permissions beyond the working directory. Extended sandbox key-exposure warnings to Plan/Create PR/Update PR and removed the exclusive Conversation/manual-model context claim. Preserved sandbox sizing/billing/lifetime/failover setup, memory exclusions, fork/protection limitations and reviewer controls; removed repeated generic best-practice/FAQ sections. Retained estimated-cost qualification and specified USD input/output/total objects and .total reference; distinguished Logs UI/run-resource credits and linked Costs. Pi separately identifies possible sandbox cost. | Verified improvement. Adds current Plan mode and minimum procedure, corrects SSH shell confinement and extends sandbox key exposure to every sandbox-model mode. Corrects current provider lifetime behavior (known versus unknown deadlines, override floor before run cap, absolute Daytona TTL/minute rounding) and qualifies independent provider/account bounds. Uses 8 GiB for repository memory allocation, links provider/account limits, and names the 24-hour E2B bound as Sim policy rather than a universal provider guarantee. Preserved: Retains all modes/settings/GitHub permissions, full Babysit pinned/trusted lifecycle, unsafe-data/key boundaries, bounds/partial outcomes/reviewer controls, SSH/tunnel/local constraints, search20 budget/provider key behavior, memory/context exclusion and all outputs. Sandbox template/build/compute/billing/orphan/normal teardown/failover facts remain; cost distinguishes USD total/sandbox costs from run credits; no unconditional Conversation/manual-model-only first-prompt safety guarantee remains. | +| [workflows/blocks/response.mdx](content/docs/workflows/blocks/response.mdx) | rewritten | Led with a quoted JSON response example, fields, outputs/terminal behavior and branch-specific statuses. Qualified custom HTTP response control by API surface and preserved v2 envelope/HTTP contract distinction. Preserved Builder versus Editor fields, nested references, filtered headers, Content-Type/nosniff defaults, first-Response behavior and competing-branch side effects. Folded useful FAQ and removed duplicated webhook acknowledgement preview. | Verified improvement. Corrects universal HTTP-control claim with explicit v2 result/status/headers envelope boundary. Places first-Response termination and competing side effects prominently, with branch-specific response examples and webhook acknowledgement distinction. Preserved: Retains Builder/Editor modes, full nested tagged JSON, status200 and success/error choices, custom headers/default JSON/nosniff/filtering, first-exit/no downstream behavior and no-Response default result. Both distinct response previews remain; removed third webhook preview repeats the preserved acknowledgement fact. Full body and header examples reviewed. | +| [workflows/blocks/router.mdx](content/docs/workflows/blocks/router.mdx) | rewritten | Led with semantic triage, then route/model/fallback configuration, outputs and unmatched errors. Preserved selectedPath destination shape, current and legacy fallback behavior and credential inheritance. Explained NO_MATCH raises an error and does not trigger fallback retries. Removed duplicate generic benefits/FAQ and kept a distinct current Workflow Inputs-mapping example. Documented the unconnected selectedPath placeholder with empty blockId, unknown blockType and chosen route title. Retained estimated-cost qualification and specified USD input/output/total objects and .total reference; distinguished Logs UI/run-resource credits and linked Costs. Pi separately identifies possible sandbox cost. | Verified improvement. Leads with intent routing and concrete routes, removes universal stronger-model guarantees, and makes NO_MATCH/error/fallback boundaries explicit. Adds actual unconnected selectedPath placeholder and USD cost fields; child-workflow example now uses current named Inputs block. Preserved: Retains context/title/description/model and local provider controls, all output fields plus token usage, fallback five/order/key/Auto behavior including legacy, no fixed route limit and route-specific connected ports. Triage/feedback previews remain; enterprise lead-routing technique remains in final prose. Unique FAQ matching/no-match facts are in explicit sections. | +| [workflows/blocks/variables.mdx](content/docs/workflows/blocks/variables.mdx) | rewritten | Replaced unevaluated retry arithmetic with an actual Function increment plus Variables assignment and a While retry example. Preserved typed conversion, pre-resolved row references and assignment order. Clarified run-scoped shared namespace including Parallel branches, block-output references, initial values and normalization collisions. Kept a distinct fetched-configuration example and removed generic duplicate FAQ. | Verified improvement. Replaces arithmetic-in-assignment retry example with complete Function increment and ordered typed assignment. Explains pre-resolved references versus assignment order, shared Parallel namespace, normalized collisions and both variable/block outputs. Preserved: Retains prior initialization/per-run reset/global namespace, literals/references, each type conversion, multiple Variables overwrites, retry and stored-profile patterns. All retry nodes, branches, counter assignments and complete increment code reviewed; successful Attempt sets3 and error path increments until While false. Configuration preview reads . | +| [workflows/blocks/wait.mdx](content/docs/workflows/blocks/wait.mdx) | rewritten | Led with request spacing, then units/mode/defaults, outputs and a delayed follow-up. Added the30-day async maximum and preserved5-minute inline maximum/default10. Clarified Async always suspends, scheduler timing is approximate, and self-hosted resumption needs the scheduler. Qualified cancelled status to interrupted inline waits and preserved execution/log duration distinction. | Verified improvement. Adds hard30-day async limit and exact always-suspend/scheduler behavior instead of exact resume-time implication. Qualifies cancellation output to inline waits and distinguishes wall-clock completion from execution/log timings and global rate limits. Preserved: Retains duration positive/default10, all mode-specific units, inline five-minute limit, status/waitDuration/resumeAt outputs and cancellation. Both two-second request-spacing and two-day follow-up previews remain; missing service tool configuration is explicitly required in prose. Self-hosted resume scheduler is linked. | +| [workflows/blocks/webhook.mdx](content/docs/workflows/blocks/webhook.mdx) | rewritten | Distinguished outbound action from inbound Webhook trigger and led with a real formatting Function/Slack payload preview. Preserved full HMAC body/timestamp signature syntax, all automatic headers, custom override effects, and request-delivery ID scope. Preserved successful outputs and error-port behavior; corrected the conditional preview to the if handle. Kept the distinct conditional-notification pattern and moved method/retry advice near related API use. | Verified improvement. Clearly separates outbound POST from inbound trigger and provides a correctly formatted Slack text example. Explains exact HMAC/header overrides/delivery-ID scope and routes non-2xx failures through error handling; fixes conditional if handle. Preserved: Retains URL/payload/AI wand/signing/header controls, full nested JSON payload, all five automatic headers and exact timestamp.body HMAC syntax, successful data/status/headers, and API alternative for method/retry/proxy. Both notify and conditional external-process previews remain. The fixed Format Function produces Slack-required text and the branch runs only on the matching condition. | +| [workflows/blocks/workflow.mdx](content/docs/workflows/blocks/workflow.mdx) | rewritten | Renamed the reference title to Workflow and led with a current mapped-input child-call example. Verified current workflow_input Inputs mapping versus hidden legacy workflow Input Variable and legacy tool-only Workflow Inputs; corrected heroes and shared previews to current workflow_input. Preserved same-workspace authorization, child credential context, output shapes, child failure/error ports, draft/deployed version and badge behavior. Preserved child-first deployment/redeployment consequences and25-hop call-chain rejection; removed stale screenshot and repetitive configure/use descriptions. | Verified improvement. Corrects current named Inputs mapping versus legacy Input Variable and prevents false parent-tool inheritance. Makes same-workspace authorization, child failure error port, draft/deployed badge difference, child-first update consequences and25-hop rejection explicit. Preserved: Retains wait-for-child/result/success/error/name/id outputs, same workspace, editor draft versus deployed child snapshot, selector self exclusion, badges/deploy/redeploy procedure and focused reuse. Full enrich-lead preview uses workflow_input, child Start input field and named Inputs mapping; previous screenshot instruction technique remains with current visible labels. | + +### API data operations (136) + +| Page or operation | Result | Changes | Final comparison and preservation | +| --- | --- | --- | --- | +| `listFiles` — `GET /api/v2/files` | rewritten | Copy standardized; no operation-specific discrepancy found. | Verified improvement. Summary: List Files → List files; sentence case matches the editorial guide. parameters[5].description: Field used to sort the result. Sorting by `name` is case-sensitive and follows the storage collation, so do not rely on a case-insensitive order. → Field used to sort the result. Do not rely on case-insensitive ordering when sorting by `name`. parameters[5].schema.description: Field used to sort the result. Sorting by `name` is case-sensitive and follows the storage collation, so do not rely on a case-insensitive order. → Field used to sort the result. Do not rely on case-insensitive ordering when sorting by `name`. responses.200.content.application/json.schema.properties.nextCursor.description: Opaque cursor for the next page. Send it back as `cursor`; `null` means there is nothing further to fetch. Never construct one yourself. → Opaque cursor for the next page. Send it back as `cursor`; `null` means there are no more pages. Do not construct a cursor yourself. 1 request/response media example set(s) now expose the owner's existing examples to the API renderer. Preserved: Compared operationId listFiles, GET /api/v2/files, security and x-sim-operation with baseline; identifiers, route and credential schemes match. Recursive prose/default/example mappings retained in final-review-api-comparison.json; 6 distinct changed field mappings were inspected for this operation. Operation-level request/response structure, parameters, required fields, defaults and status declarations are identical after removing prose/examples; referenced component changes were reviewed separately. | +| `createFile` — `POST /api/v2/files` | rewritten | Copy standardized; no operation-specific discrepancy found. Review correction: complete inline JSON is capped at 10 MiB; the decoded-file limit remains separate. | Verified improvement. Summary: Create File → Create file; sentence case matches the editorial guide. responses.503.description: A required service is temporarily unavailable. `Retry-After` carries the seconds to wait; treat it as a floor and add jitter. The header is omitted when `error.details.code` is `A… → A required service is temporarily unavailable. When present, `Retry-After` gives the minimum seconds to wait; add jitter before retrying. Check operation-specific guidance before … 2 request/response media example set(s) now expose the owner's existing examples to the API renderer. Preserved: Compared operationId createFile, POST /api/v2/files, security and x-sim-operation with baseline; identifiers, route and credential schemes match. Recursive prose/default/example mappings retained in final-review-api-comparison.json; 4 distinct changed field mappings were inspected for this operation. Operation-level request/response structure, parameters, required fields, defaults and status declarations are identical after removing prose/examples; referenced component changes were reviewed separately. | +| `createFileUpload` — `POST /api/v2/files/uploads` | rewritten | Copy standardized; no operation-specific discrepancy found. | Verified improvement. Summary: Create File Upload → Create file upload; sentence case matches the editorial guide. responses.503.description: A required service is temporarily unavailable. `Retry-After` carries the seconds to wait; treat it as a floor and add jitter. The header is omitted when `error.details.code` is `A… → A required service is temporarily unavailable. When present, `Retry-After` gives the minimum seconds to wait; add jitter before retrying. Check operation-specific guidance before … 1 request/response media example set(s) now expose the owner's existing examples to the API renderer. Preserved: Compared operationId createFileUpload, POST /api/v2/files/uploads, security and x-sim-operation with baseline; identifiers, route and credential schemes match. Recursive prose/default/example mappings retained in final-review-api-comparison.json; 3 distinct changed field mappings were inspected for this operation. Operation-level request/response structure, parameters, required fields, defaults and status declarations are identical after removing prose/examples; referenced component changes were reviewed separately. | +| `getFileUpload` — `GET /api/v2/files/uploads/{uploadId}` | rewritten | Copy standardized; no operation-specific discrepancy found. | Verified improvement. Summary: Get File Upload → Get file upload; sentence case matches the editorial guide. responses.503.description: A required service is temporarily unavailable. `Retry-After` carries the seconds to wait; treat it as a floor and add jitter. The header is omitted when `error.details.code` is `A… → A required service is temporarily unavailable. When present, `Retry-After` gives the minimum seconds to wait; add jitter before retrying. Check operation-specific guidance before … Preserved: Compared operationId getFileUpload, GET /api/v2/files/uploads/{uploadId}, security and x-sim-operation with baseline; identifiers, route and credential schemes match. Recursive prose/default/example mappings retained in final-review-api-comparison.json; 2 distinct changed field mappings were inspected for this operation. Operation-level request/response structure, parameters, required fields, defaults and status declarations are identical after removing prose/examples; referenced component changes were reviewed separately. | +| `abortFileUpload` — `DELETE /api/v2/files/uploads/{uploadId}` | rewritten | Copy standardized; no operation-specific discrepancy found. | Verified improvement. Summary: Abort File Upload → Abort file upload; sentence case matches the editorial guide. responses.503.description: A required service is temporarily unavailable. `Retry-After` carries the seconds to wait; treat it as a floor and add jitter. The header is omitted when `error.details.code` is `A… → A required service is temporarily unavailable. When present, `Retry-After` gives the minimum seconds to wait; add jitter before retrying. Check operation-specific guidance before … Preserved: Compared operationId abortFileUpload, DELETE /api/v2/files/uploads/{uploadId}, security and x-sim-operation with baseline; identifiers, route and credential schemes match. Recursive prose/default/example mappings retained in final-review-api-comparison.json; 2 distinct changed field mappings were inspected for this operation. Operation-level request/response structure, parameters, required fields, defaults and status declarations are identical after removing prose/examples; referenced component changes were reviewed separately. | +| `createFileUploadPartUrls` — `POST /api/v2/files/uploads/{uploadId}/parts` | rewritten | Copy standardized; no operation-specific discrepancy found. | Verified improvement. Summary: Create File Upload Part URLs → Create file upload part URLs; sentence case matches the editorial guide. responses.503.description: A required service is temporarily unavailable. `Retry-After` carries the seconds to wait; treat it as a floor and add jitter. The header is omitted when `error.details.code` is `A… → A required service is temporarily unavailable. When present, `Retry-After` gives the minimum seconds to wait; add jitter before retrying. Check operation-specific guidance before … 1 request/response media example set(s) now expose the owner's existing examples to the API renderer. Preserved: Compared operationId createFileUploadPartUrls, POST /api/v2/files/uploads/{uploadId}/parts, security and x-sim-operation with baseline; identifiers, route and credential schemes match. Recursive prose/default/example mappings retained in final-review-api-comparison.json; 3 distinct changed field mappings were inspected for this operation. Operation-level request/response structure, parameters, required fields, defaults and status declarations are identical after removing prose/examples; referenced component changes were reviewed separately. | +| `completeFileUpload` — `POST /api/v2/files/uploads/{uploadId}/complete` | rewritten | Copy standardized; no operation-specific discrepancy found. | Verified improvement. Summary: Complete File Upload → Complete file upload; sentence case matches the editorial guide. responses.503.description: A required service is temporarily unavailable. `Retry-After` carries the seconds to wait; treat it as a floor and add jitter. The header is omitted when `error.details.code` is `A… → A required service is temporarily unavailable. When present, `Retry-After` gives the minimum seconds to wait; add jitter before retrying. Check operation-specific guidance before … Preserved: Compared operationId completeFileUpload, POST /api/v2/files/uploads/{uploadId}/complete, security and x-sim-operation with baseline; identifiers, route and credential schemes match. Recursive prose/default/example mappings retained in final-review-api-comparison.json; 2 distinct changed field mappings were inspected for this operation. Operation-level request/response structure, parameters, required fields, defaults and status declarations are identical after removing prose/examples; referenced component changes were reviewed separately. | +| `readFileText` — `GET /api/v2/files/{fileId}/text` | rewritten | Copy standardized; no operation-specific discrepancy found. | Verified improvement. Summary: Read File Text → Read file text; sentence case matches the editorial guide. responses.503.description: A required service is temporarily unavailable. `Retry-After` carries the seconds to wait; treat it as a floor and add jitter. The header is omitted when `error.details.code` is `A… → A required service is temporarily unavailable. When present, `Retry-After` gives the minimum seconds to wait; add jitter before retrying. Check operation-specific guidance before … Preserved: Compared operationId readFileText, GET /api/v2/files/{fileId}/text, security and x-sim-operation with baseline; identifiers, route and credential schemes match. Recursive prose/default/example mappings retained in final-review-api-comparison.json; 3 distinct changed field mappings were inspected for this operation. Operation-level request/response structure, parameters, required fields, defaults and status declarations are identical after removing prose/examples; referenced component changes were reviewed separately. | +| `listFileVersions` — `GET /api/v2/files/{fileId}/versions` | rewritten | Copy standardized; no operation-specific discrepancy found. | Verified improvement. Summary: List File Versions → List file versions; sentence case matches the editorial guide. responses.200.content.application/json.schema.properties.nextCursor.description: Opaque cursor for the next page. Send it back as `cursor`; `null` means there is nothing further to fetch. Never construct one yourself. → Opaque cursor for the next page. Send it back as `cursor`; `null` means there are no more pages. Do not construct a cursor yourself. responses.503.description: A required service is temporarily unavailable. `Retry-After` carries the seconds to wait; treat it as a floor and add jitter. The header is omitted when `error.details.code` is `A… → A required service is temporarily unavailable. When present, `Retry-After` gives the minimum seconds to wait; add jitter before retrying. Check operation-specific guidance before … 1 request/response media example set(s) now expose the owner's existing examples to the API renderer. Preserved: Compared operationId listFileVersions, GET /api/v2/files/{fileId}/versions, security and x-sim-operation with baseline; identifiers, route and credential schemes match. Recursive prose/default/example mappings retained in final-review-api-comparison.json; 4 distinct changed field mappings were inspected for this operation. Operation-level request/response structure, parameters, required fields, defaults and status declarations are identical after removing prose/examples; referenced component changes were reviewed separately. | +| `getFileVersion` — `GET /api/v2/files/{fileId}/versions/{version}` | rewritten | Copy standardized; no operation-specific discrepancy found. | Verified improvement. Summary: Get File Version → Get file version; sentence case matches the editorial guide. responses.503.description: A required service is temporarily unavailable. `Retry-After` carries the seconds to wait; treat it as a floor and add jitter. The header is omitted when `error.details.code` is `A… → A required service is temporarily unavailable. When present, `Retry-After` gives the minimum seconds to wait; add jitter before retrying. Check operation-specific guidance before … 1 request/response media example set(s) now expose the owner's existing examples to the API renderer. Preserved: Compared operationId getFileVersion, GET /api/v2/files/{fileId}/versions/{version}, security and x-sim-operation with baseline; identifiers, route and credential schemes match. Recursive prose/default/example mappings retained in final-review-api-comparison.json; 3 distinct changed field mappings were inspected for this operation. Operation-level request/response structure, parameters, required fields, defaults and status declarations are identical after removing prose/examples; referenced component changes were reviewed separately. | +| `deleteFileVersion` — `DELETE /api/v2/files/{fileId}/versions/{version}` | corrected | "True when the version was removed. Stored-content deletion may finish through a background retry." Keep permanent history removal and current-version conflict, qualify immediate physical purge. | Verified improvement. Summary: Delete File Version → Delete file version; sentence case matches the editorial guide. description: Permanently delete one earlier version and its stored content, for example to purge a leaked value from history before retention removes it. The current version returns `409`; rev… → Permanently remove an earlier version from history and schedule deletion of its stored content. Storage cleanup may retry in the background. The current version returns `409`; rev… responses.200.content.application/json.schema.properties.data.properties.deleted.description: Always true: the version and its stored content are gone. → True when the version was removed from history. Stored-content deletion may finish through a background retry. responses.503.description: A required service is temporarily unavailable. `Retry-After` carries the seconds to wait; treat it as a floor and add jitter. The header is omitted when `error.details.code` is `A… → A required service is temporarily unavailable. When present, `Retry-After` gives the minimum seconds to wait; add jitter before retrying. Check operation-specific guidance before … 1 request/response media example set(s) now expose the owner's existing examples to the API renderer. Preserved: Compared operationId deleteFileVersion, DELETE /api/v2/files/{fileId}/versions/{version}, security and x-sim-operation with baseline; identifiers, route and credential schemes match. Recursive prose/default/example mappings retained in final-review-api-comparison.json; 5 distinct changed field mappings were inspected for this operation. Operation-level request/response structure, parameters, required fields, defaults and status declarations are identical after removing prose/examples; referenced component changes were reviewed separately. | +| `readFileVersionText` — `GET /api/v2/files/{fileId}/versions/{version}/text` | rewritten | Copy standardized; no operation-specific discrepancy found. | Verified improvement. Summary: Read File Version Text → Read file version text; sentence case matches the editorial guide. responses.503.description: A required service is temporarily unavailable. `Retry-After` carries the seconds to wait; treat it as a floor and add jitter. The header is omitted when `error.details.code` is `A… → A required service is temporarily unavailable. When present, `Retry-After` gives the minimum seconds to wait; add jitter before retrying. Check operation-specific guidance before … Preserved: Compared operationId readFileVersionText, GET /api/v2/files/{fileId}/versions/{version}/text, security and x-sim-operation with baseline; identifiers, route and credential schemes match. Recursive prose/default/example mappings retained in final-review-api-comparison.json; 3 distinct changed field mappings were inspected for this operation. Operation-level request/response structure, parameters, required fields, defaults and status declarations are identical after removing prose/examples; referenced component changes were reviewed separately. | +| `downloadFileVersion` — `GET /api/v2/files/{fileId}/versions/{version}/content` | rewritten | Reviewed; accurate details retained under the shared reference standard. | Verified improvement. Summary: Download File Version → Download file version; sentence case matches the editorial guide. description: Download the bytes of one version, served exactly as Download File serves the current bytes. Generated documents use compiled artifacts, returning `409` while compiling and `413` … → Download the bytes of one version, served exactly as Download file serves the current bytes. Generated documents use compiled artifacts, returning `409` while compiling and `413` … responses.503.description: A required service is temporarily unavailable. `Retry-After` carries the seconds to wait; treat it as a floor and add jitter. The header is omitted when `error.details.code` is `A… → A required service is temporarily unavailable. When present, `Retry-After` gives the minimum seconds to wait; add jitter before retrying. Check operation-specific guidance before … Preserved: Compared operationId downloadFileVersion, GET /api/v2/files/{fileId}/versions/{version}/content, security and x-sim-operation with baseline; identifiers, route and credential schemes match. Recursive prose/default/example mappings retained in final-review-api-comparison.json; 3 distinct changed field mappings were inspected for this operation. Operation-level request/response structure, parameters, required fields, defaults and status declarations are identical after removing prose/examples; referenced component changes were reviewed separately. | +| `revertFileVersion` — `POST /api/v2/files/{fileId}/versions/{version}/revert` | rewritten | Copy standardized; no operation-specific discrepancy found. | Verified improvement. Summary: Revert File Version → Revert file version; sentence case matches the editorial guide. description: Make the content of a version current again by writing it as a new `revert` version, so the revert can itself be reverted. Open editors receive the change. Reverting to the curren… → Make the content of a version current again by writing it as a new `revert` version, so the revert can itself be reverted. Open editors receive the change. Reverting to the curren… responses.503.description: A required service is temporarily unavailable. `Retry-After` carries the seconds to wait; treat it as a floor and add jitter. The header is omitted when `error.details.code` is `A… → A required service is temporarily unavailable. When present, `Retry-After` gives the minimum seconds to wait; add jitter before retrying. Check operation-specific guidance before … 2 request/response media example set(s) now expose the owner's existing examples to the API renderer. Preserved: Compared operationId revertFileVersion, POST /api/v2/files/{fileId}/versions/{version}/revert, security and x-sim-operation with baseline; identifiers, route and credential schemes match. Recursive prose/default/example mappings retained in final-review-api-comparison.json; 6 distinct changed field mappings were inspected for this operation. Operation-level request/response structure, parameters, required fields, defaults and status declarations are identical after removing prose/examples; referenced component changes were reviewed separately. | +| `bulkDownloadFiles` — `GET /api/v2/files/bulk-download` | rewritten | Reviewed; accurate details retained under the shared reference standard. | Verified improvement. Summary: Bulk Download Files → Bulk download files; sentence case matches the editorial guide. description: Stream selected files and recursive folder contents as a ZIP archive. Each selection parameter and the resolved set allow 100 entries; unmatched paths or excess entries return `40… → Stream selected files and recursive folder contents as a ZIP archive. Each selection parameter and the resolved set allow 100 entries; unmatched paths or excess entries return `40… responses.503.description: A required service is temporarily unavailable. `Retry-After` carries the seconds to wait; treat it as a floor and add jitter. The header is omitted when `error.details.code` is `A… → A required service is temporarily unavailable. When present, `Retry-After` gives the minimum seconds to wait; add jitter before retrying. Check operation-specific guidance before … Preserved: Compared operationId bulkDownloadFiles, GET /api/v2/files/bulk-download, security and x-sim-operation with baseline; identifiers, route and credential schemes match. Recursive prose/default/example mappings retained in final-review-api-comparison.json; 3 distinct changed field mappings were inspected for this operation. Operation-level request/response structure, parameters, required fields, defaults and status declarations are identical after removing prose/examples; referenced component changes were reviewed separately. | +| `unzipFile` — `POST /api/v2/files/{fileId}/unzip` | rewritten | Copy standardized; no operation-specific discrepancy found. | Verified improvement. Summary: Unzip File → Unzip file; sentence case matches the editorial guide. responses.503.description: A required service is temporarily unavailable. `Retry-After` carries the seconds to wait; treat it as a floor and add jitter. The header is omitted when `error.details.code` is `A… → A required service is temporarily unavailable. When present, `Retry-After` gives the minimum seconds to wait; add jitter before retrying. Check operation-specific guidance before … Preserved: Compared operationId unzipFile, POST /api/v2/files/{fileId}/unzip, security and x-sim-operation with baseline; identifiers, route and credential schemes match. Recursive prose/default/example mappings retained in final-review-api-comparison.json; 3 distinct changed field mappings were inspected for this operation. Operation-level request/response structure, parameters, required fields, defaults and status declarations are identical after removing prose/examples; referenced component changes were reviewed separately. | +| `downloadFile` — `GET /api/v2/files/{fileId}` | rewritten | Reviewed; accurate details retained under the shared reference standard. | Verified improvement. Summary: Download File → Download file; sentence case matches the editorial guide. description: Download current file bytes. Generated documents use compiled artifacts, returning `409` while compiling and `413` above the rendered-size ceiling. Downloading records an audit ev… → Download current file bytes. Generated documents use compiled artifacts, returning `409` while compiling and `413` above the rendered-size ceiling. Downloading records an audit ev… responses.503.description: A required service is temporarily unavailable. `Retry-After` carries the seconds to wait; treat it as a floor and add jitter. The header is omitted when `error.details.code` is `A… → A required service is temporarily unavailable. When present, `Retry-After` gives the minimum seconds to wait; add jitter before retrying. Check operation-specific guidance before … Preserved: Compared operationId downloadFile, GET /api/v2/files/{fileId}, security and x-sim-operation with baseline; identifiers, route and credential schemes match. Recursive prose/default/example mappings retained in final-review-api-comparison.json; 3 distinct changed field mappings were inspected for this operation. Operation-level request/response structure, parameters, required fields, defaults and status declarations are identical after removing prose/examples; referenced component changes were reviewed separately. | +| `deleteFile` — `DELETE /api/v2/files/{fileId}` | rewritten | Copy standardized; no operation-specific discrepancy found. | Verified improvement. Summary: Delete File → Delete file; sentence case matches the editorial guide. responses.503.description: A required service is temporarily unavailable. `Retry-After` carries the seconds to wait; treat it as a floor and add jitter. The header is omitted when `error.details.code` is `A… → A required service is temporarily unavailable. When present, `Retry-After` gives the minimum seconds to wait; add jitter before retrying. Check operation-specific guidance before … Preserved: Compared operationId deleteFile, DELETE /api/v2/files/{fileId}, security and x-sim-operation with baseline; identifiers, route and credential schemes match. Recursive prose/default/example mappings retained in final-review-api-comparison.json; 3 distinct changed field mappings were inspected for this operation. Operation-level request/response structure, parameters, required fields, defaults and status declarations are identical after removing prose/examples; referenced component changes were reviewed separately. | +| `renameFile` — `PATCH /api/v2/files/{fileId}` | rewritten | Copy standardized; no operation-specific discrepancy found. | Verified improvement. Summary: Rename File → Rename file; sentence case matches the editorial guide. responses.503.description: A required service is temporarily unavailable. `Retry-After` carries the seconds to wait; treat it as a floor and add jitter. The header is omitted when `error.details.code` is `A… → A required service is temporarily unavailable. When present, `Retry-After` gives the minimum seconds to wait; add jitter before retrying. Check operation-specific guidance before … 2 request/response media example set(s) now expose the owner's existing examples to the API renderer. Preserved: Compared operationId renameFile, PATCH /api/v2/files/{fileId}, security and x-sim-operation with baseline; identifiers, route and credential schemes match. Recursive prose/default/example mappings retained in final-review-api-comparison.json; 4 distinct changed field mappings were inspected for this operation. Operation-level request/response structure, parameters, required fields, defaults and status declarations are identical after removing prose/examples; referenced component changes were reviewed separately. | +| `restoreFile` — `POST /api/v2/files/{fileId}/restore` | corrected | "The restored file, with its resulting folderPath and name." Keep the accurate operation-level original-folder/root fallback and collision explanation. | Verified improvement. Summary: Restore File → Restore file; sentence case matches the editorial guide. responses.200.content.application/json.schema.description: The restored workspace file, at the root and under its post-restore name. → The restored file, with its resulting folderPath and name. responses.503.description: A required service is temporarily unavailable. `Retry-After` carries the seconds to wait; treat it as a floor and add jitter. The header is omitted when `error.details.code` is `A… → A required service is temporarily unavailable. When present, `Retry-After` gives the minimum seconds to wait; add jitter before retrying. Check operation-specific guidance before … 2 request/response media example set(s) now expose the owner's existing examples to the API renderer. Preserved: Compared operationId restoreFile, POST /api/v2/files/{fileId}/restore, security and x-sim-operation with baseline; identifiers, route and credential schemes match. Recursive prose/default/example mappings retained in final-review-api-comparison.json; 5 distinct changed field mappings were inspected for this operation. Operation-level request/response structure, parameters, required fields, defaults and status declarations are identical after removing prose/examples; referenced component changes were reviewed separately. | +| `getFile` — `GET /api/v2/files/{fileId}/metadata` | corrected | "Current version number. Pass as expectedCurrentVersion to require this version still be current. Use expectedRevision to detect edits folded into the same version." | Verified improvement. Summary: Get File Metadata → Get file metadata; sentence case matches the editorial guide. responses.200.content.application/json.schema.properties.data.properties.currentVersion.description: Version number of the current content. List File Versions returns the history; pass this as `expectedCurrentVersion` to revert only if nothing changed since. → Current version number. List file versions returns the history. Pass this as `expectedCurrentVersion` to require that version to remain current; use `expectedRevision` to detect e… responses.503.description: A required service is temporarily unavailable. `Retry-After` carries the seconds to wait; treat it as a floor and add jitter. The header is omitted when `error.details.code` is `A… → A required service is temporarily unavailable. When present, `Retry-After` gives the minimum seconds to wait; add jitter before retrying. Check operation-specific guidance before … 1 request/response media example set(s) now expose the owner's existing examples to the API renderer. Preserved: Compared operationId getFile, GET /api/v2/files/{fileId}/metadata, security and x-sim-operation with baseline; identifiers, route and credential schemes match. Recursive prose/default/example mappings retained in final-review-api-comparison.json; 5 distinct changed field mappings were inspected for this operation. Operation-level request/response structure, parameters, required fields, defaults and status declarations are identical after removing prose/examples; referenced component changes were reviewed separately. | +| `listAuditLogs` — `GET /api/v2/audit-logs` | corrected | Override inherited descriptions to "Include audit entries created at or after/before this UTC ISO 8601 timestamp." Preserve UTC/Z and year-zero validation details. | Verified improvement. Summary: List Audit Logs → List audit logs; sentence case matches the editorial guide. parameters[4].description: Only include runs started at or after this UTC ISO 8601 timestamp, e.g. `2026-08-06T00:00:00Z`. A date without a time, or a timestamp carrying a UTC offset instead of `Z`, is reje… → Include audit entries created at or after this UTC ISO 8601 timestamp, such as `2026-08-06T00:00:00Z`. Dates without a time, timestamps with an offset instead of `Z`, and year `00… parameters[4].schema.description: Only include runs started at or after this UTC ISO 8601 timestamp, e.g. `2026-08-06T00:00:00Z`. A date without a time, or a timestamp carrying a UTC offset instead of `Z`, is reje… → Include audit entries created at or after this UTC ISO 8601 timestamp, such as `2026-08-06T00:00:00Z`. Dates without a time, timestamps with an offset instead of `Z`, and year `00… parameters[5].description: Only include runs started at or before this UTC ISO 8601 timestamp, e.g. `2026-08-06T00:00:00Z`. A date without a time, or a timestamp carrying a UTC offset instead of `Z`, is rej… → Include audit entries created at or before this UTC ISO 8601 timestamp, such as `2026-08-06T00:00:00Z`. Dates without a time, timestamps with an offset instead of `Z`, and year `0… 1 request/response media example set(s) now expose the owner's existing examples to the API renderer. Preserved: Compared operationId listAuditLogs, GET /api/v2/audit-logs, security and x-sim-operation with baseline; identifiers, route and credential schemes match. Recursive prose/default/example mappings retained in final-review-api-comparison.json; 8 distinct changed field mappings were inspected for this operation. Operation-level request/response structure, parameters, required fields, defaults and status declarations are identical after removing prose/examples; referenced component changes were reviewed separately. | +| `getAuditLog` — `GET /api/v2/audit-logs/{auditLogId}` | rewritten | Copy standardized; no operation-specific discrepancy found. | Verified improvement. Summary: Get Audit Log → Get audit log; sentence case matches the editorial guide. responses.503.description: A required service is temporarily unavailable. `Retry-After` carries the seconds to wait; treat it as a floor and add jitter. The header is omitted when `error.details.code` is `A… → A required service is temporarily unavailable. When present, `Retry-After` gives the minimum seconds to wait; add jitter before retrying. Check operation-specific guidance before … 1 request/response media example set(s) now expose the owner's existing examples to the API renderer. Preserved: Compared operationId getAuditLog, GET /api/v2/audit-logs/{auditLogId}, security and x-sim-operation with baseline; identifiers, route and credential schemes match. Recursive prose/default/example mappings retained in final-review-api-comparison.json; 3 distinct changed field mappings were inspected for this operation. Operation-level request/response structure, parameters, required fields, defaults and status declarations are identical after removing prose/examples; referenced component changes were reviewed separately. | +| `moveFileItems` — `POST /api/v2/files/move` | rewritten | Copy standardized; no operation-specific discrepancy found. | Verified improvement. Summary: Move Files → Move files; sentence case matches the editorial guide. responses.503.description: A required service is temporarily unavailable. `Retry-After` carries the seconds to wait; treat it as a floor and add jitter. The header is omitted when `error.details.code` is `A… → A required service is temporarily unavailable. When present, `Retry-After` gives the minimum seconds to wait; add jitter before retrying. Check operation-specific guidance before … 2 request/response media example set(s) now expose the owner's existing examples to the API renderer. Preserved: Compared operationId moveFileItems, POST /api/v2/files/move, security and x-sim-operation with baseline; identifiers, route and credential schemes match. Recursive prose/default/example mappings retained in final-review-api-comparison.json; 4 distinct changed field mappings were inspected for this operation. Operation-level request/response structure, parameters, required fields, defaults and status declarations are identical after removing prose/examples; referenced component changes were reviewed separately. | +| `getFileShare` — `GET /api/v2/files/{fileId}/share` | rewritten | Copy standardized; no operation-specific discrepancy found. | Verified improvement. Summary: Get File Share → Get file share; sentence case matches the editorial guide. responses.503.description: A required service is temporarily unavailable. `Retry-After` carries the seconds to wait; treat it as a floor and add jitter. The header is omitted when `error.details.code` is `A… → A required service is temporarily unavailable. When present, `Retry-After` gives the minimum seconds to wait; add jitter before retrying. Check operation-specific guidance before … 1 request/response media example set(s) now expose the owner's existing examples to the API renderer. Preserved: Compared operationId getFileShare, GET /api/v2/files/{fileId}/share, security and x-sim-operation with baseline; identifiers, route and credential schemes match. Recursive prose/default/example mappings retained in final-review-api-comparison.json; 3 distinct changed field mappings were inspected for this operation. Operation-level request/response structure, parameters, required fields, defaults and status declarations are identical after removing prose/examples; referenced component changes were reviewed separately. | +| `upsertFileShare` — `PATCH /api/v2/files/{fileId}/share` | rewritten | Copy standardized; no operation-specific discrepancy found. | Verified improvement. Summary: Enable or Disable File Share → Enable or disable file share; sentence case matches the editorial guide. responses.503.description: A required service is temporarily unavailable. `Retry-After` carries the seconds to wait; treat it as a floor and add jitter. The header is omitted when `error.details.code` is `A… → A required service is temporarily unavailable. When present, `Retry-After` gives the minimum seconds to wait; add jitter before retrying. Check operation-specific guidance before … 2 request/response media example set(s) now expose the owner's existing examples to the API renderer. Preserved: Compared operationId upsertFileShare, PATCH /api/v2/files/{fileId}/share, security and x-sim-operation with baseline; identifiers, route and credential schemes match. Recursive prose/default/example mappings retained in final-review-api-comparison.json; 4 distinct changed field mappings were inspected for this operation. Operation-level request/response structure, parameters, required fields, defaults and status declarations are identical after removing prose/examples; referenced component changes were reviewed separately. | +| `editFileContent` — `PATCH /api/v2/files/{fileId}/content` | rewritten | Copy standardized; no operation-specific discrepancy found. | Verified improvement. Summary: Edit File Content → Edit file content; sentence case matches the editorial guide. responses.503.description: A required service is temporarily unavailable. `Retry-After` carries the seconds to wait; treat it as a floor and add jitter. The header is omitted when `error.details.code` is `A… → A required service is temporarily unavailable. When present, `Retry-After` gives the minimum seconds to wait; add jitter before retrying. Check operation-specific guidance before … 2 request/response media example set(s) now expose the owner's existing examples to the API renderer. Preserved: Compared operationId editFileContent, PATCH /api/v2/files/{fileId}/content, security and x-sim-operation with baseline; identifiers, route and credential schemes match. Recursive prose/default/example mappings retained in final-review-api-comparison.json; 6 distinct changed field mappings were inspected for this operation. Operation-level request/response structure, parameters, required fields, defaults and status declarations are identical after removing prose/examples; referenced component changes were reviewed separately. | +| `updateFileContent` — `PUT /api/v2/files/{fileId}/content` | rewritten | Copy standardized; no operation-specific discrepancy found. Review correction: complete replacement JSON is capped at 10 MiB; a small patch can edit a larger stored file. | Verified improvement. Summary: Replace File Content → Replace file content; sentence case matches the editorial guide. responses.503.description: A required service is temporarily unavailable. `Retry-After` carries the seconds to wait; treat it as a floor and add jitter. The header is omitted when `error.details.code` is `A… → A required service is temporarily unavailable. When present, `Retry-After` gives the minimum seconds to wait; add jitter before retrying. Check operation-specific guidance before … 2 request/response media example set(s) now expose the owner's existing examples to the API renderer. Preserved: Compared operationId updateFileContent, PUT /api/v2/files/{fileId}/content, security and x-sim-operation with baseline; identifiers, route and credential schemes match. Recursive prose/default/example mappings retained in final-review-api-comparison.json; 5 distinct changed field mappings were inspected for this operation. Operation-level request/response structure, parameters, required fields, defaults and status declarations are identical after removing prose/examples; referenced component changes were reviewed separately. | +| `searchFileContent` — `GET /api/v2/files/search` | rewritten | Copy standardized; no operation-specific discrepancy found. | Verified improvement. Summary: Search File Content → Search file content; sentence case matches the editorial guide. responses.503.description: A required service is temporarily unavailable. `Retry-After` carries the seconds to wait; treat it as a floor and add jitter. The header is omitted when `error.details.code` is `A… → A required service is temporarily unavailable. When present, `Retry-After` gives the minimum seconds to wait; add jitter before retrying. Check operation-specific guidance before … 1 request/response media example set(s) now expose the owner's existing examples to the API renderer. Preserved: Compared operationId searchFileContent, GET /api/v2/files/search, security and x-sim-operation with baseline; identifiers, route and credential schemes match. Recursive prose/default/example mappings retained in final-review-api-comparison.json; 3 distinct changed field mappings were inspected for this operation. Operation-level request/response structure, parameters, required fields, defaults and status declarations are identical after removing prose/examples; referenced component changes were reviewed separately. | +| `bulkDeleteFiles` — `POST /api/v2/files/bulk-delete` | rewritten | Copy standardized; no operation-specific discrepancy found. | Verified improvement. Summary: Delete Files → Delete files; sentence case matches the editorial guide. responses.503.description: A required service is temporarily unavailable. `Retry-After` carries the seconds to wait; treat it as a floor and add jitter. The header is omitted when `error.details.code` is `A… → A required service is temporarily unavailable. When present, `Retry-After` gives the minimum seconds to wait; add jitter before retrying. Check operation-specific guidance before … 2 request/response media example set(s) now expose the owner's existing examples to the API renderer. Preserved: Compared operationId bulkDeleteFiles, POST /api/v2/files/bulk-delete, security and x-sim-operation with baseline; identifiers, route and credential schemes match. Recursive prose/default/example mappings retained in final-review-api-comparison.json; 5 distinct changed field mappings were inspected for this operation. Operation-level request/response structure, parameters, required fields, defaults and status declarations are identical after removing prose/examples; referenced component changes were reviewed separately. | +| `listFilesFolders` — `GET /api/v2/files/folders` | rewritten | Copy standardized; no operation-specific discrepancy found. | Verified improvement. Summary: List Folders → List folders; sentence case matches the editorial guide. description: List workspace file folders with parent-path filtering and sorting. Use `scope=archived` to find paths accepted by Restore Folder. Returns the complete set in one page; `nextCurso… → List workspace file folders with parent-path filtering and sorting. Use `scope=archived` to find paths accepted by Restore folder. Returns one page; `nextCursor` is always null. O… parameters[3].description: Field used to sort the result. Sorting by `name` is case-sensitive and follows the storage collation, so do not rely on a case-insensitive order. → Field used to sort the result. Do not rely on case-insensitive ordering when sorting by `name`. parameters[3].schema.description: Field used to sort the result. Sorting by `name` is case-sensitive and follows the storage collation, so do not rely on a case-insensitive order. → Field used to sort the result. Do not rely on case-insensitive ordering when sorting by `name`. Preserved: Compared operationId listFilesFolders, GET /api/v2/files/folders, security and x-sim-operation with baseline; identifiers, route and credential schemes match. Recursive prose/default/example mappings retained in final-review-api-comparison.json; 6 distinct changed field mappings were inspected for this operation. Operation-level request/response structure, parameters, required fields, defaults and status declarations are identical after removing prose/examples; referenced component changes were reviewed separately. | +| `createFilesFolder` — `POST /api/v2/files/folders` | rewritten | Copy standardized; no operation-specific discrepancy found. | Verified improvement. Summary: Create Folder → Create folder; sentence case matches the editorial guide. responses.503.description: A required service is temporarily unavailable. `Retry-After` carries the seconds to wait; treat it as a floor and add jitter. The header is omitted when `error.details.code` is `A… → A required service is temporarily unavailable. When present, `Retry-After` gives the minimum seconds to wait; add jitter before retrying. Check operation-specific guidance before … 1 request/response media example set(s) now expose the owner's existing examples to the API renderer. Preserved: Compared operationId createFilesFolder, POST /api/v2/files/folders, security and x-sim-operation with baseline; identifiers, route and credential schemes match. Recursive prose/default/example mappings retained in final-review-api-comparison.json; 3 distinct changed field mappings were inspected for this operation. Operation-level request/response structure, parameters, required fields, defaults and status declarations are identical after removing prose/examples; referenced component changes were reviewed separately. | +| `relocateFilesFolder` — `PATCH /api/v2/files/folders` | rewritten | Reviewed; accurate details retained under the shared reference standard. | Verified improvement. Summary: Rename or Move Folder → Rename or move folder; sentence case matches the editorial guide. responses.503.description: A required service is temporarily unavailable. `Retry-After` carries the seconds to wait; treat it as a floor and add jitter. The header is omitted when `error.details.code` is `A… → A required service is temporarily unavailable. When present, `Retry-After` gives the minimum seconds to wait; add jitter before retrying. Check operation-specific guidance before … 1 request/response media example set(s) now expose the owner's existing examples to the API renderer. Preserved: Compared operationId relocateFilesFolder, PATCH /api/v2/files/folders, security and x-sim-operation with baseline; identifiers, route and credential schemes match. Recursive prose/default/example mappings retained in final-review-api-comparison.json; 3 distinct changed field mappings were inspected for this operation. Operation-level request/response structure, parameters, required fields, defaults and status declarations are identical after removing prose/examples; referenced component changes were reviewed separately. | +| `deleteFilesFolder` — `DELETE /api/v2/files/folders` | rewritten | Copy standardized; no operation-specific discrepancy found. | Verified improvement. Summary: Delete Folder → Delete folder; sentence case matches the editorial guide. parameters[2].description: Delete the folder's nested files and folders too. An empty folder deletes either way; a non-empty one needs this. The listed spellings are the whole accepted vocabulary and are ca… → Delete the folder's contents and nested folders too. Required for a non-empty folder. Only the listed case-sensitive spellings are accepted. parameters[2].schema.description: Delete the folder's nested files and folders too. An empty folder deletes either way; a non-empty one needs this. The listed spellings are the whole accepted vocabulary and are ca… → Delete the folder's contents and nested folders too. Required for a non-empty folder. Only the listed case-sensitive spellings are accepted. responses.503.description: A required service is temporarily unavailable. `Retry-After` carries the seconds to wait; treat it as a floor and add jitter. The header is omitted when `error.details.code` is `A… → A required service is temporarily unavailable. When present, `Retry-After` gives the minimum seconds to wait; add jitter before retrying. Check operation-specific guidance before … Preserved: Compared operationId deleteFilesFolder, DELETE /api/v2/files/folders, security and x-sim-operation with baseline; identifiers, route and credential schemes match. Recursive prose/default/example mappings retained in final-review-api-comparison.json; 5 distinct changed field mappings were inspected for this operation. Operation-level request/response structure, parameters, required fields, defaults and status declarations are identical after removing prose/examples; referenced component changes were reviewed separately. | +| `restoreFilesFolder` — `POST /api/v2/files/folders/restore` | rewritten | Copy standardized; no operation-specific discrepancy found. | Verified improvement. Summary: Restore Folder → Restore folder; sentence case matches the editorial guide. responses.503.description: A required service is temporarily unavailable. `Retry-After` carries the seconds to wait; treat it as a floor and add jitter. The header is omitted when `error.details.code` is `A… → A required service is temporarily unavailable. When present, `Retry-After` gives the minimum seconds to wait; add jitter before retrying. Check operation-specific guidance before … Preserved: Compared operationId restoreFilesFolder, POST /api/v2/files/folders/restore, security and x-sim-operation with baseline; identifiers, route and credential schemes match. Recursive prose/default/example mappings retained in final-review-api-comparison.json; 3 distinct changed field mappings were inspected for this operation. Operation-level request/response structure, parameters, required fields, defaults and status declarations are identical after removing prose/examples; referenced component changes were reviewed separately. | +| `listKnowledgeBases` — `GET /api/v2/knowledge` | rewritten | Copy standardized; no operation-specific discrepancy found. | Verified improvement. Summary: List Knowledge Bases → List knowledge bases; sentence case matches the editorial guide. parameters[4].description: Field used to sort the result. Sorting by `name` is case-sensitive and follows the storage collation, so do not rely on a case-insensitive order. → Field used to sort the result. Do not rely on case-insensitive ordering when sorting by `name`. parameters[4].schema.description: Field used to sort the result. Sorting by `name` is case-sensitive and follows the storage collation, so do not rely on a case-insensitive order. → Field used to sort the result. Do not rely on case-insensitive ordering when sorting by `name`. responses.200.content.application/json.schema.properties.data.items.properties.chunkingConfig.properties.overlap.description: Number of overlapping characters between adjacent chunks. → Requested overlap in tokens between adjacent chunks. Preserved: Compared operationId listKnowledgeBases, GET /api/v2/knowledge, security and x-sim-operation with baseline; identifiers, route and credential schemes match. Recursive prose/default/example mappings retained in final-review-api-comparison.json; 9 distinct changed field mappings were inspected for this operation. Operation-level request/response structure, parameters, required fields, defaults and status declarations are identical after removing prose/examples; referenced component changes were reviewed separately. | +| `createKnowledgeBase` — `POST /api/v2/knowledge` | corrected | Use neutral document-wide error examples, or operation-specific examples. Preserve error.details.lock and actionable detail codes. These are illustrative examples, not a claim that every server response uses that message. Root corrected inherited chunk-overlap input unit to tokens, preserving schema/default behavior. | Verified improvement. Summary: Create Knowledge Base → Create knowledge base; sentence case matches the editorial guide. requestBody.content.application/json.schema.properties.chunkingConfig.properties.overlap.description: Number of overlapping characters between adjacent chunks. → Requested overlap in tokens between adjacent chunks. responses.201.content.application/json.schema.properties.data.properties.chunkingConfig.properties.overlap.description: Number of overlapping characters between adjacent chunks. → Requested overlap in tokens between adjacent chunks. responses.503.description: A required service is temporarily unavailable. `Retry-After` carries the seconds to wait; treat it as a floor and add jitter. The header is omitted when `error.details.code` is `A… → A required service is temporarily unavailable. When present, `Retry-After` gives the minimum seconds to wait; add jitter before retrying. Check operation-specific guidance before … 1 request/response media example set(s) now expose the owner's existing examples to the API renderer. Preserved: Compared operationId createKnowledgeBase, POST /api/v2/knowledge, security and x-sim-operation with baseline; identifiers, route and credential schemes match. Recursive prose/default/example mappings retained in final-review-api-comparison.json; 7 distinct changed field mappings were inspected for this operation. Operation-level request/response structure, parameters, required fields, defaults and status declarations are identical after removing prose/examples; referenced component changes were reviewed separately. | +| `getKnowledgeBase` — `GET /api/v2/knowledge/{knowledgeBaseId}` | rewritten | Copy standardized; no operation-specific discrepancy found. | Verified improvement. Summary: Get Knowledge Base → Get knowledge base; sentence case matches the editorial guide. responses.200.content.application/json.schema.properties.data.properties.chunkingConfig.properties.overlap.description: Number of overlapping characters between adjacent chunks. → Requested overlap in tokens between adjacent chunks. responses.503.description: A required service is temporarily unavailable. `Retry-After` carries the seconds to wait; treat it as a floor and add jitter. The header is omitted when `error.details.code` is `A… → A required service is temporarily unavailable. When present, `Retry-After` gives the minimum seconds to wait; add jitter before retrying. Check operation-specific guidance before … Preserved: Compared operationId getKnowledgeBase, GET /api/v2/knowledge/{knowledgeBaseId}, security and x-sim-operation with baseline; identifiers, route and credential schemes match. Recursive prose/default/example mappings retained in final-review-api-comparison.json; 4 distinct changed field mappings were inspected for this operation. Operation-level request/response structure, parameters, required fields, defaults and status declarations are identical after removing prose/examples; referenced component changes were reviewed separately. | +| `updateKnowledgeBase` — `PATCH /api/v2/knowledge/{knowledgeBaseId}` | corrected | Use neutral document-wide error examples, or operation-specific examples. Preserve error.details.lock and actionable detail codes. These are illustrative examples, not a claim that every server response uses that message. Root corrected inherited chunk-overlap input unit to tokens, preserving schema/default behavior. | Verified improvement. Summary: Update Knowledge Base → Update knowledge base; sentence case matches the editorial guide. requestBody.content.application/json.schema.properties.chunkingConfig.properties.overlap.description: Number of overlapping characters between adjacent chunks. → Requested overlap in tokens between adjacent chunks. responses.200.content.application/json.schema.properties.data.properties.chunkingConfig.properties.overlap.description: Number of overlapping characters between adjacent chunks. → Requested overlap in tokens between adjacent chunks. responses.503.description: A required service is temporarily unavailable. `Retry-After` carries the seconds to wait; treat it as a floor and add jitter. The header is omitted when `error.details.code` is `A… → A required service is temporarily unavailable. When present, `Retry-After` gives the minimum seconds to wait; add jitter before retrying. Check operation-specific guidance before … 1 request/response media example set(s) now expose the owner's existing examples to the API renderer. Preserved: Compared operationId updateKnowledgeBase, PATCH /api/v2/knowledge/{knowledgeBaseId}, security and x-sim-operation with baseline; identifiers, route and credential schemes match. Recursive prose/default/example mappings retained in final-review-api-comparison.json; 7 distinct changed field mappings were inspected for this operation. Operation-level request/response structure, parameters, required fields, defaults and status declarations are identical after removing prose/examples; referenced component changes were reviewed separately. | +| `deleteKnowledgeBase` — `DELETE /api/v2/knowledge/{knowledgeBaseId}` | rewritten | Copy standardized; no operation-specific discrepancy found. | Verified improvement. Summary: Delete Knowledge Base → Delete knowledge base; sentence case matches the editorial guide. responses.503.description: A required service is temporarily unavailable. `Retry-After` carries the seconds to wait; treat it as a floor and add jitter. The header is omitted when `error.details.code` is `A… → A required service is temporarily unavailable. When present, `Retry-After` gives the minimum seconds to wait; add jitter before retrying. Check operation-specific guidance before … Preserved: Compared operationId deleteKnowledgeBase, DELETE /api/v2/knowledge/{knowledgeBaseId}, security and x-sim-operation with baseline; identifiers, route and credential schemes match. Recursive prose/default/example mappings retained in final-review-api-comparison.json; 3 distinct changed field mappings were inspected for this operation. Operation-level request/response structure, parameters, required fields, defaults and status declarations are identical after removing prose/examples; referenced component changes were reviewed separately. | +| `exportKnowledgeBase` — `GET /api/v2/knowledge/{knowledgeBaseId}/export` | rewritten | Reviewed; accurate details retained under the shared reference standard. | Verified improvement. Summary: Export Knowledge Base → Export knowledge base; sentence case matches the editorial guide. description: Stream a knowledge base as a bundle archive: its configuration, tag definitions, each workspace-visible document's file and chunk text, and optionally chunk vectors. Access-contro… → Stream a knowledge base as a bundle archive: its configuration, tag definitions, each workspace-visible document's file and chunk text, and optionally chunk vectors. Access-contro… responses.503.description: A required service is temporarily unavailable. `Retry-After` carries the seconds to wait; treat it as a floor and add jitter. The header is omitted when `error.details.code` is `A… → A required service is temporarily unavailable. When present, `Retry-After` gives the minimum seconds to wait; add jitter before retrying. Check operation-specific guidance before … Preserved: Compared operationId exportKnowledgeBase, GET /api/v2/knowledge/{knowledgeBaseId}/export, security and x-sim-operation with baseline; identifiers, route and credential schemes match. Recursive prose/default/example mappings retained in final-review-api-comparison.json; 3 distinct changed field mappings were inspected for this operation. Operation-level request/response structure, parameters, required fields, defaults and status declarations are identical after removing prose/examples; referenced component changes were reviewed separately. | +| `listKnowledgeConnectors` — `GET /api/v2/knowledge/{knowledgeBaseId}/connectors` | rewritten | Copy standardized; no operation-specific discrepancy found. | Verified improvement. Summary: List Knowledge Connectors → List knowledge connectors; sentence case matches the editorial guide. responses.200.content.application/json.schema.properties.nextCursor.description: Opaque cursor for the next page. Send it back as `cursor`; `null` means there is nothing further to fetch. Never construct one yourself. → Opaque cursor for the next page. Send it back as `cursor`; `null` means there are no more pages. Do not construct a cursor yourself. responses.503.description: A required service is temporarily unavailable. `Retry-After` carries the seconds to wait; treat it as a floor and add jitter. The header is omitted when `error.details.code` is `A… → A required service is temporarily unavailable. When present, `Retry-After` gives the minimum seconds to wait; add jitter before retrying. Check operation-specific guidance before … 1 request/response media example set(s) now expose the owner's existing examples to the API renderer. Preserved: Compared operationId listKnowledgeConnectors, GET /api/v2/knowledge/{knowledgeBaseId}/connectors, security and x-sim-operation with baseline; identifiers, route and credential schemes match. Recursive prose/default/example mappings retained in final-review-api-comparison.json; 4 distinct changed field mappings were inspected for this operation. Operation-level request/response structure, parameters, required fields, defaults and status declarations are identical after removing prose/examples; referenced component changes were reviewed separately. | +| `createKnowledgeConnector` — `POST /api/v2/knowledge/{knowledgeBaseId}/connectors` | corrected | Use neutral document-wide error examples, or operation-specific examples. Preserve error.details.lock and actionable detail codes. These are illustrative examples, not a claim that every server response uses that message. | Verified improvement. Summary: Create Knowledge Connector → Create knowledge connector; sentence case matches the editorial guide. responses.503.description: A required service is temporarily unavailable. `Retry-After` carries the seconds to wait; treat it as a floor and add jitter. The header is omitted when `error.details.code` is `A… → A required service is temporarily unavailable. When present, `Retry-After` gives the minimum seconds to wait; add jitter before retrying. Check operation-specific guidance before … 2 request/response media example set(s) now expose the owner's existing examples to the API renderer. Preserved: Compared operationId createKnowledgeConnector, POST /api/v2/knowledge/{knowledgeBaseId}/connectors, security and x-sim-operation with baseline; identifiers, route and credential schemes match. Recursive prose/default/example mappings retained in final-review-api-comparison.json; 5 distinct changed field mappings were inspected for this operation. Operation-level request/response structure, parameters, required fields, defaults and status declarations are identical after removing prose/examples; referenced component changes were reviewed separately. | +| `getKnowledgeConnector` — `GET /api/v2/knowledge/{knowledgeBaseId}/connectors/{connectorId}` | rewritten | Copy standardized; no operation-specific discrepancy found. | Verified improvement. Summary: Get Knowledge Connector → Get knowledge connector; sentence case matches the editorial guide. responses.503.description: A required service is temporarily unavailable. `Retry-After` carries the seconds to wait; treat it as a floor and add jitter. The header is omitted when `error.details.code` is `A… → A required service is temporarily unavailable. When present, `Retry-After` gives the minimum seconds to wait; add jitter before retrying. Check operation-specific guidance before … 1 request/response media example set(s) now expose the owner's existing examples to the API renderer. Preserved: Compared operationId getKnowledgeConnector, GET /api/v2/knowledge/{knowledgeBaseId}/connectors/{connectorId}, security and x-sim-operation with baseline; identifiers, route and credential schemes match. Recursive prose/default/example mappings retained in final-review-api-comparison.json; 3 distinct changed field mappings were inspected for this operation. Operation-level request/response structure, parameters, required fields, defaults and status declarations are identical after removing prose/examples; referenced component changes were reviewed separately. | +| `updateKnowledgeConnector` — `PATCH /api/v2/knowledge/{knowledgeBaseId}/connectors/{connectorId}` | corrected | Use neutral document-wide error examples, or operation-specific examples. Preserve error.details.lock and actionable detail codes. These are illustrative examples, not a claim that every server response uses that message. Review correction: the paused request has a paused response example with separate operation-specific metadata. | Verified improvement. Summary: Update Knowledge Connector → Update knowledge connector; sentence case matches the editorial guide. responses.503.description: A required service is temporarily unavailable. `Retry-After` carries the seconds to wait; treat it as a floor and add jitter. The header is omitted when `error.details.code` is `A… → A required service is temporarily unavailable. When present, `Retry-After` gives the minimum seconds to wait; add jitter before retrying. Check operation-specific guidance before … 2 request/response media example set(s) now expose the owner's existing examples to the API renderer. Preserved: Compared operationId updateKnowledgeConnector, PATCH /api/v2/knowledge/{knowledgeBaseId}/connectors/{connectorId}, security and x-sim-operation with baseline; identifiers, route and credential schemes match. Recursive prose/default/example mappings retained in final-review-api-comparison.json; 5 distinct changed field mappings were inspected for this operation. Operation-level request/response structure, parameters, required fields, defaults and status declarations are identical after removing prose/examples; referenced component changes were reviewed separately. | +| `deleteKnowledgeConnector` — `DELETE /api/v2/knowledge/{knowledgeBaseId}/connectors/{connectorId}` | rewritten | Copy standardized; no operation-specific discrepancy found. | Verified improvement. Summary: Delete Knowledge Connector → Delete knowledge connector; sentence case matches the editorial guide. responses.503.description: A required service is temporarily unavailable. `Retry-After` carries the seconds to wait; treat it as a floor and add jitter. The header is omitted when `error.details.code` is `A… → A required service is temporarily unavailable. When present, `Retry-After` gives the minimum seconds to wait; add jitter before retrying. Check operation-specific guidance before … 1 request/response media example set(s) now expose the owner's existing examples to the API renderer. Preserved: Compared operationId deleteKnowledgeConnector, DELETE /api/v2/knowledge/{knowledgeBaseId}/connectors/{connectorId}, security and x-sim-operation with baseline; identifiers, route and credential schemes match. Recursive prose/default/example mappings retained in final-review-api-comparison.json; 3 distinct changed field mappings were inspected for this operation. Operation-level request/response structure, parameters, required fields, defaults and status declarations are identical after removing prose/examples; referenced component changes were reviewed separately. | +| `syncKnowledgeConnector` — `POST /api/v2/knowledge/{knowledgeBaseId}/connectors/{connectorId}/sync` | corrected | Use neutral document-wide error examples, or operation-specific examples. Preserve error.details.lock and actionable detail codes. These are illustrative examples, not a claim that every server response uses that message. | Verified improvement. Summary: Sync Knowledge Connector → Sync knowledge connector; sentence case matches the editorial guide. responses.503.description: A required service is temporarily unavailable. `Retry-After` carries the seconds to wait; treat it as a floor and add jitter. The header is omitted when `error.details.code` is `A… → A required service is temporarily unavailable. When present, `Retry-After` gives the minimum seconds to wait; add jitter before retrying. Check operation-specific guidance before … 2 request/response media example set(s) now expose the owner's existing examples to the API renderer. Preserved: Compared operationId syncKnowledgeConnector, POST /api/v2/knowledge/{knowledgeBaseId}/connectors/{connectorId}/sync, security and x-sim-operation with baseline; identifiers, route and credential schemes match. Recursive prose/default/example mappings retained in final-review-api-comparison.json; 5 distinct changed field mappings were inspected for this operation. Operation-level request/response structure, parameters, required fields, defaults and status declarations are identical after removing prose/examples; referenced component changes were reviewed separately. | +| `listKnowledgeConnectorDocuments` — `GET /api/v2/knowledge/{knowledgeBaseId}/connectors/{connectorId}/documents` | rewritten | Copy standardized; no operation-specific discrepancy found. | Verified improvement. Summary: List Knowledge Connector Documents → List knowledge connector documents; sentence case matches the editorial guide. responses.200.content.application/json.schema.properties.nextCursor.description: Opaque cursor for the next page. Send it back as `cursor`; `null` means there is nothing further to fetch. Never construct one yourself. → Opaque cursor for the next page. Send it back as `cursor`; `null` means there are no more pages. Do not construct a cursor yourself. responses.503.description: A required service is temporarily unavailable. `Retry-After` carries the seconds to wait; treat it as a floor and add jitter. The header is omitted when `error.details.code` is `A… → A required service is temporarily unavailable. When present, `Retry-After` gives the minimum seconds to wait; add jitter before retrying. Check operation-specific guidance before … 1 request/response media example set(s) now expose the owner's existing examples to the API renderer. Preserved: Compared operationId listKnowledgeConnectorDocuments, GET /api/v2/knowledge/{knowledgeBaseId}/connectors/{connectorId}/documents, security and x-sim-operation with baseline; identifiers, route and credential schemes match. Recursive prose/default/example mappings retained in final-review-api-comparison.json; 4 distinct changed field mappings were inspected for this operation. Operation-level request/response structure, parameters, required fields, defaults and status declarations are identical after removing prose/examples; referenced component changes were reviewed separately. | +| `updateKnowledgeConnectorDocuments` — `PATCH /api/v2/knowledge/{knowledgeBaseId}/connectors/{connectorId}/documents` | rewritten | Copy standardized; no operation-specific discrepancy found. | Verified improvement. Summary: Update Knowledge Connector Documents → Update knowledge connector documents; sentence case matches the editorial guide. responses.503.description: A required service is temporarily unavailable. `Retry-After` carries the seconds to wait; treat it as a floor and add jitter. The header is omitted when `error.details.code` is `A… → A required service is temporarily unavailable. When present, `Retry-After` gives the minimum seconds to wait; add jitter before retrying. Check operation-specific guidance before … 2 request/response media example set(s) now expose the owner's existing examples to the API renderer. Preserved: Compared operationId updateKnowledgeConnectorDocuments, PATCH /api/v2/knowledge/{knowledgeBaseId}/connectors/{connectorId}/documents, security and x-sim-operation with baseline; identifiers, route and credential schemes match. Recursive prose/default/example mappings retained in final-review-api-comparison.json; 4 distinct changed field mappings were inspected for this operation. Operation-level request/response structure, parameters, required fields, defaults and status declarations are identical after removing prose/examples; referenced component changes were reviewed separately. | +| `searchKnowledge` — `POST /api/v2/knowledge/search` | corrected | "If reranking is unavailable, results keep their retrieval order and have no rerankerScore." Preserve best-effort status and billing details. Use neutral document-wide error examples, or operation-specific examples. Preserve error.details.lock and actionable detail codes. These are illustrative examples, not a claim that every server response uses that message. Add "For a query search, all selected bases must use the same embedding model and dimensions; search incompatible bases separately. Tag-only search does not require this." Describe omitted searchMode as workspace policy; avoid claiming a universal vector default. | Verified improvement. Summary: Search Knowledge → Search knowledge; sentence case matches the editorial guide. requestBody.content.application/json.schema.properties.knowledgeBaseIds.description: One knowledge base identifier or an array of up to 20 identifiers. → One knowledge base ID or an array of up to 20 IDs. Query searches require the same embedding model and dimensions across all selected bases; search incompatible bases separately. … requestBody.content.application/json.schema.properties.rerankerEnabled.description: Re-order retrieved chunks with a reranking model before truncating to `topK`. Ignored for a tag-only search, and billed as an additional search unit. Reranking is best-effort — a … → Reorder retrieved chunks with a reranking model before truncating to `topK`. Ignored for tag-only searches. A completed reranking call adds a search unit. If reranking is unavaila… requestBody.content.application/json.schema.properties.searchMode.description: Retrieval strategy: vector is semantic-only, while hybrid also runs full-text search. → Retrieval strategy: `vector` uses semantic search; `hybrid` also runs full-text search. Omit to use the workspace policy. 1 request/response media example set(s) now expose the owner's existing examples to the API renderer. Preserved: Compared operationId searchKnowledge, POST /api/v2/knowledge/search, security and x-sim-operation with baseline; identifiers, route and credential schemes match. Recursive prose/default/example mappings retained in final-review-api-comparison.json; 8 distinct changed field mappings were inspected for this operation. Operation-level request/response structure, parameters, required fields, defaults and status declarations are identical after removing prose/examples; referenced component changes were reviewed separately. | +| `listKnowledgeTags` — `GET /api/v2/knowledge/{knowledgeBaseId}/tags` | corrected | "Slot used by document updates: tag1–tag7, number1–number5, date1–date2, or boolean1–boolean3. Upload creation accepts text slots; use Update Document for other types." Keep display-name/slot distinction. | Verified improvement. Summary: List Tags → List tags; sentence case matches the editorial guide. description: List the knowledge base's tag definitions with display names, write slots, and field types. Filters and document reads use display names; document writes use slots. Returns the co… → List the knowledge base's tag definitions with display names, write slots, and field types. Filters and document reads use display names; document writes use slots. Returns one pa… responses.200.content.application/json.schema.properties.data.items.properties.tagSlot.description: Storage slot the tag occupies. Document writes set tag values by slot (`tag1`..`tag7`). → Slot used by document updates: `tag1`–`tag7`, `number1`–`number5`, `date1`–`date2`, or `boolean1`–`boolean3`. Upload creation accepts text slots; use Update document for other typ… responses.200.content.application/json.schema.properties.nextCursor.description: Always `null` — this list has no `cursor` or `limit` param and returns its whole bounded set in one page. Present so the list can gain pages later without a shape change. → Always `null`. This list has no `cursor` or `limit` parameters; see the operation for inventory limits. Preserved: Compared operationId listKnowledgeTags, GET /api/v2/knowledge/{knowledgeBaseId}/tags, security and x-sim-operation with baseline; identifiers, route and credential schemes match. Recursive prose/default/example mappings retained in final-review-api-comparison.json; 6 distinct changed field mappings were inspected for this operation. Operation-level request/response structure, parameters, required fields, defaults and status declarations are identical after removing prose/examples; referenced component changes were reviewed separately. | +| `createKnowledgeTag` — `POST /api/v2/knowledge/{knowledgeBaseId}/tags` | corrected | "Slot used by document updates: tag1–tag7, number1–number5, date1–date2, or boolean1–boolean3. Upload creation accepts text slots; use Update Document for other types." Keep display-name/slot distinction. Use neutral document-wide error examples, or operation-specific examples. Preserve error.details.lock and actionable detail codes. These are illustrative examples, not a claim that every server response uses that message. | Verified improvement. Summary: Create Tag → Create tag; sentence case matches the editorial guide. responses.201.content.application/json.schema.properties.data.properties.tagSlot.description: Storage slot the tag occupies. Document writes set tag values by slot (`tag1`..`tag7`). → Slot used by document updates: `tag1`–`tag7`, `number1`–`number5`, `date1`–`date2`, or `boolean1`–`boolean3`. Upload creation accepts text slots; use Update document for other typ… responses.503.description: A required service is temporarily unavailable. `Retry-After` carries the seconds to wait; treat it as a floor and add jitter. The header is omitted when `error.details.code` is `A… → A required service is temporarily unavailable. When present, `Retry-After` gives the minimum seconds to wait; add jitter before retrying. Check operation-specific guidance before … 1 request/response media example set(s) now expose the owner's existing examples to the API renderer. Preserved: Compared operationId createKnowledgeTag, POST /api/v2/knowledge/{knowledgeBaseId}/tags, security and x-sim-operation with baseline; identifiers, route and credential schemes match. Recursive prose/default/example mappings retained in final-review-api-comparison.json; 7 distinct changed field mappings were inspected for this operation. Operation-level request/response structure, parameters, required fields, defaults and status declarations are identical after removing prose/examples; referenced component changes were reviewed separately. | +| `bulkSaveKnowledgeTagDefinitions` — `PUT /api/v2/knowledge/{knowledgeBaseId}/tags` | corrected | "Slot used by document updates: tag1–tag7, number1–number5, date1–date2, or boolean1–boolean3. Upload creation accepts text slots; use Update Document for other types." Keep display-name/slot distinction. | Verified improvement. Summary: Bulk Save Tag Definitions → Bulk save tag definitions; sentence case matches the editorial guide. responses.200.content.application/json.schema.properties.data.properties.created.items.properties.tagSlot.description: Storage slot the tag occupies. Document writes set tag values by slot (`tag1`..`tag7`). → Slot used by document updates: `tag1`–`tag7`, `number1`–`number5`, `date1`–`date2`, or `boolean1`–`boolean3`. Upload creation accepts text slots; use Update document for other typ… responses.200.content.application/json.schema.properties.data.properties.updated.items.properties.tagSlot.description: Storage slot the tag occupies. Document writes set tag values by slot (`tag1`..`tag7`). → Slot used by document updates: `tag1`–`tag7`, `number1`–`number5`, `date1`–`date2`, or `boolean1`–`boolean3`. Upload creation accepts text slots; use Update document for other typ… responses.503.description: A required service is temporarily unavailable. `Retry-After` carries the seconds to wait; treat it as a floor and add jitter. The header is omitted when `error.details.code` is `A… → A required service is temporarily unavailable. When present, `Retry-After` gives the minimum seconds to wait; add jitter before retrying. Check operation-specific guidance before … 1 request/response media example set(s) now expose the owner's existing examples to the API renderer. Preserved: Compared operationId bulkSaveKnowledgeTagDefinitions, PUT /api/v2/knowledge/{knowledgeBaseId}/tags, security and x-sim-operation with baseline; identifiers, route and credential schemes match. Recursive prose/default/example mappings retained in final-review-api-comparison.json; 8 distinct changed field mappings were inspected for this operation. Operation-level request/response structure, parameters, required fields, defaults and status declarations are identical after removing prose/examples; referenced component changes were reviewed separately. | +| `deleteKnowledgeTagDefinitions` — `DELETE /api/v2/knowledge/{knowledgeBaseId}/tags` | rewritten | Copy standardized; no operation-specific discrepancy found. | Verified improvement. Summary: Delete Tag Definitions → Delete tag definitions; sentence case matches the editorial guide. responses.503.description: A required service is temporarily unavailable. `Retry-After` carries the seconds to wait; treat it as a floor and add jitter. The header is omitted when `error.details.code` is `A… → A required service is temporarily unavailable. When present, `Retry-After` gives the minimum seconds to wait; add jitter before retrying. Check operation-specific guidance before … Preserved: Compared operationId deleteKnowledgeTagDefinitions, DELETE /api/v2/knowledge/{knowledgeBaseId}/tags, security and x-sim-operation with baseline; identifiers, route and credential schemes match. Recursive prose/default/example mappings retained in final-review-api-comparison.json; 3 distinct changed field mappings were inspected for this operation. Operation-level request/response structure, parameters, required fields, defaults and status declarations are identical after removing prose/examples; referenced component changes were reviewed separately. | +| `listKnowledgeDocuments` — `GET /api/v2/knowledge/{knowledgeBaseId}/documents` | rewritten | Copy standardized; no operation-specific discrepancy found. | Verified improvement. Summary: List Documents → List documents; sentence case matches the editorial guide. parameters[5].description: Field used to sort the result. Sorting by `filename` is case-sensitive and follows the storage collation, so do not rely on a case-insensitive order. → Field used to sort the result. Do not rely on case-insensitive ordering when sorting by `filename`. parameters[5].schema.description: Field used to sort the result. Sorting by `filename` is case-sensitive and follows the storage collation, so do not rely on a case-insensitive order. → Field used to sort the result. Do not rely on case-insensitive ordering when sorting by `filename`. responses.200.content.application/json.schema.properties.nextCursor.description: Opaque cursor for the next page. Send it back as `cursor`; `null` means there is nothing further to fetch. Never construct one yourself. → Opaque cursor for the next page. Send it back as `cursor`; `null` means there are no more pages. Do not construct a cursor yourself. Preserved: Compared operationId listKnowledgeDocuments, GET /api/v2/knowledge/{knowledgeBaseId}/documents, security and x-sim-operation with baseline; identifiers, route and credential schemes match. Recursive prose/default/example mappings retained in final-review-api-comparison.json; 7 distinct changed field mappings were inspected for this operation. Operation-level request/response structure, parameters, required fields, defaults and status declarations are identical after removing prose/examples; referenced component changes were reviewed separately. | +| `bulkUpdateKnowledgeDocuments` — `PATCH /api/v2/knowledge/{knowledgeBaseId}/documents` | rewritten | Copy standardized; no operation-specific discrepancy found. | Verified improvement. Summary: Bulk Enable or Disable Documents → Bulk enable or disable documents; sentence case matches the editorial guide. responses.503.description: A required service is temporarily unavailable. `Retry-After` carries the seconds to wait; treat it as a floor and add jitter. The header is omitted when `error.details.code` is `A… → A required service is temporarily unavailable. When present, `Retry-After` gives the minimum seconds to wait; add jitter before retrying. Check operation-specific guidance before … 1 request/response media example set(s) now expose the owner's existing examples to the API renderer. Preserved: Compared operationId bulkUpdateKnowledgeDocuments, PATCH /api/v2/knowledge/{knowledgeBaseId}/documents, security and x-sim-operation with baseline; identifiers, route and credential schemes match. Recursive prose/default/example mappings retained in final-review-api-comparison.json; 4 distinct changed field mappings were inspected for this operation. Operation-level request/response structure, parameters, required fields, defaults and status declarations are identical after removing prose/examples; referenced component changes were reviewed separately. | +| `uploadKnowledgeDocument` — `POST /api/v2/knowledge/{knowledgeBaseId}/documents` | rewritten | Copy standardized; no operation-specific discrepancy found. | Verified improvement. Summary: Upload Document → Upload document; sentence case matches the editorial guide. requestBody.content.multipart/form-data.schema.properties.file.description: Document file to upload; the maximum size is 100 MB. → Document file to upload; the maximum size is 100 MiB. responses.503.description: A required service is temporarily unavailable. `Retry-After` carries the seconds to wait; treat it as a floor and add jitter. The header is omitted when `error.details.code` is `A… → A required service is temporarily unavailable. When present, `Retry-After` gives the minimum seconds to wait; add jitter before retrying. Check operation-specific guidance before … Preserved: Compared operationId uploadKnowledgeDocument, POST /api/v2/knowledge/{knowledgeBaseId}/documents, security and x-sim-operation with baseline; identifiers, route and credential schemes match. Recursive prose/default/example mappings retained in final-review-api-comparison.json; 3 distinct changed field mappings were inspected for this operation. Operation-level request/response structure, parameters, required fields, defaults and status declarations are identical after removing prose/examples; referenced component changes were reviewed separately. | +| `createKnowledgeDocumentUpload` — `POST /api/v2/knowledge/{knowledgeBaseId}/documents/uploads` | rewritten | Copy standardized; no operation-specific discrepancy found. | Verified improvement. Summary: Create Document Upload → Create document upload; sentence case matches the editorial guide. responses.503.description: A required service is temporarily unavailable. `Retry-After` carries the seconds to wait; treat it as a floor and add jitter. The header is omitted when `error.details.code` is `A… → A required service is temporarily unavailable. When present, `Retry-After` gives the minimum seconds to wait; add jitter before retrying. Check operation-specific guidance before … 1 request/response media example set(s) now expose the owner's existing examples to the API renderer. Preserved: Compared operationId createKnowledgeDocumentUpload, POST /api/v2/knowledge/{knowledgeBaseId}/documents/uploads, security and x-sim-operation with baseline; identifiers, route and credential schemes match. Recursive prose/default/example mappings retained in final-review-api-comparison.json; 3 distinct changed field mappings were inspected for this operation. Operation-level request/response structure, parameters, required fields, defaults and status declarations are identical after removing prose/examples; referenced component changes were reviewed separately. | +| `abortKnowledgeDocumentUpload` — `DELETE /api/v2/knowledge/{knowledgeBaseId}/documents/uploads/{uploadId}` | corrected | Use neutral document-wide error examples, or operation-specific examples. Preserve error.details.lock and actionable detail codes. These are illustrative examples, not a claim that every server response uses that message. | Verified improvement. Summary: Abort Document Upload → Abort document upload; sentence case matches the editorial guide. responses.503.description: A required service is temporarily unavailable. `Retry-After` carries the seconds to wait; treat it as a floor and add jitter. The header is omitted when `error.details.code` is `A… → A required service is temporarily unavailable. When present, `Retry-After` gives the minimum seconds to wait; add jitter before retrying. Check operation-specific guidance before … Preserved: Compared operationId abortKnowledgeDocumentUpload, DELETE /api/v2/knowledge/{knowledgeBaseId}/documents/uploads/{uploadId}, security and x-sim-operation with baseline; identifiers, route and credential schemes match. Recursive prose/default/example mappings retained in final-review-api-comparison.json; 3 distinct changed field mappings were inspected for this operation. Operation-level request/response structure, parameters, required fields, defaults and status declarations are identical after removing prose/examples; referenced component changes were reviewed separately. | +| `createKnowledgeDocumentUploadPartUrls` — `POST /api/v2/knowledge/{knowledgeBaseId}/documents/uploads/{uploadId}/parts` | corrected | Use neutral document-wide error examples, or operation-specific examples. Preserve error.details.lock and actionable detail codes. These are illustrative examples, not a claim that every server response uses that message. | Verified improvement. Summary: Create Document Upload Part URLs → Create document upload part URLs; sentence case matches the editorial guide. responses.503.description: A required service is temporarily unavailable. `Retry-After` carries the seconds to wait; treat it as a floor and add jitter. The header is omitted when `error.details.code` is `A… → A required service is temporarily unavailable. When present, `Retry-After` gives the minimum seconds to wait; add jitter before retrying. Check operation-specific guidance before … 1 request/response media example set(s) now expose the owner's existing examples to the API renderer. Preserved: Compared operationId createKnowledgeDocumentUploadPartUrls, POST /api/v2/knowledge/{knowledgeBaseId}/documents/uploads/{uploadId}/parts, security and x-sim-operation with baseline; identifiers, route and credential schemes match. Recursive prose/default/example mappings retained in final-review-api-comparison.json; 4 distinct changed field mappings were inspected for this operation. Operation-level request/response structure, parameters, required fields, defaults and status declarations are identical after removing prose/examples; referenced component changes were reviewed separately. | +| `completeKnowledgeDocumentUpload` — `POST /api/v2/knowledge/{knowledgeBaseId}/documents/uploads/{uploadId}/complete` | corrected | Use neutral document-wide error examples, or operation-specific examples. Preserve error.details.lock and actionable detail codes. These are illustrative examples, not a claim that every server response uses that message. | Verified improvement. Summary: Complete Document Upload → Complete document upload; sentence case matches the editorial guide. responses.503.description: A required service is temporarily unavailable. `Retry-After` carries the seconds to wait; treat it as a floor and add jitter. The header is omitted when `error.details.code` is `A… → A required service is temporarily unavailable. When present, `Retry-After` gives the minimum seconds to wait; add jitter before retrying. Check operation-specific guidance before … Preserved: Compared operationId completeKnowledgeDocumentUpload, POST /api/v2/knowledge/{knowledgeBaseId}/documents/uploads/{uploadId}/complete, security and x-sim-operation with baseline; identifiers, route and credential schemes match. Recursive prose/default/example mappings retained in final-review-api-comparison.json; 3 distinct changed field mappings were inspected for this operation. Operation-level request/response structure, parameters, required fields, defaults and status declarations are identical after removing prose/examples; referenced component changes were reviewed separately. | +| `getKnowledgeDocument` — `GET /api/v2/knowledge/{knowledgeBaseId}/documents/{documentId}` | rewritten | Copy standardized; no operation-specific discrepancy found. | Verified improvement. Summary: Get Document → Get document; sentence case matches the editorial guide. responses.503.description: A required service is temporarily unavailable. `Retry-After` carries the seconds to wait; treat it as a floor and add jitter. The header is omitted when `error.details.code` is `A… → A required service is temporarily unavailable. When present, `Retry-After` gives the minimum seconds to wait; add jitter before retrying. Check operation-specific guidance before … Preserved: Compared operationId getKnowledgeDocument, GET /api/v2/knowledge/{knowledgeBaseId}/documents/{documentId}, security and x-sim-operation with baseline; identifiers, route and credential schemes match. Recursive prose/default/example mappings retained in final-review-api-comparison.json; 3 distinct changed field mappings were inspected for this operation. Operation-level request/response structure, parameters, required fields, defaults and status declarations are identical after removing prose/examples; referenced component changes were reviewed separately. | +| `updateKnowledgeDocument` — `PATCH /api/v2/knowledge/{knowledgeBaseId}/documents/{documentId}` | rewritten | Copy standardized; no operation-specific discrepancy found. | Verified improvement. Summary: Update Document → Update document; sentence case matches the editorial guide. responses.503.description: A required service is temporarily unavailable. `Retry-After` carries the seconds to wait; treat it as a floor and add jitter. The header is omitted when `error.details.code` is `A… → A required service is temporarily unavailable. When present, `Retry-After` gives the minimum seconds to wait; add jitter before retrying. Check operation-specific guidance before … 1 request/response media example set(s) now expose the owner's existing examples to the API renderer. Preserved: Compared operationId updateKnowledgeDocument, PATCH /api/v2/knowledge/{knowledgeBaseId}/documents/{documentId}, security and x-sim-operation with baseline; identifiers, route and credential schemes match. Recursive prose/default/example mappings retained in final-review-api-comparison.json; 5 distinct changed field mappings were inspected for this operation. Operation-level request/response structure, parameters, required fields, defaults and status declarations are identical after removing prose/examples; referenced component changes were reviewed separately. | +| `deleteKnowledgeDocument` — `DELETE /api/v2/knowledge/{knowledgeBaseId}/documents/{documentId}` | rewritten | Copy standardized; no operation-specific discrepancy found. | Verified improvement. Summary: Delete Document → Delete document; sentence case matches the editorial guide. responses.503.description: A required service is temporarily unavailable. `Retry-After` carries the seconds to wait; treat it as a floor and add jitter. The header is omitted when `error.details.code` is `A… → A required service is temporarily unavailable. When present, `Retry-After` gives the minimum seconds to wait; add jitter before retrying. Check operation-specific guidance before … Preserved: Compared operationId deleteKnowledgeDocument, DELETE /api/v2/knowledge/{knowledgeBaseId}/documents/{documentId}, security and x-sim-operation with baseline; identifiers, route and credential schemes match. Recursive prose/default/example mappings retained in final-review-api-comparison.json; 2 distinct changed field mappings were inspected for this operation. Operation-level request/response structure, parameters, required fields, defaults and status declarations are identical after removing prose/examples; referenced component changes were reviewed separately. | +| `listKnowledgeFolders` — `GET /api/v2/knowledge/folders` | rewritten | Copy standardized; no operation-specific discrepancy found. | Verified improvement. Summary: List Folders → List folders; sentence case matches the editorial guide. description: List folders in the knowledge-base folder tree with filtering and sorting. Returns the complete set in one page; `nextCursor` is always null. Workspace folder trees exceeding 10,0… → List folders in the knowledge-base folder tree with filtering and sorting. Returns one page; `nextCursor` is always null. Workspace folder trees exceeding 10,000 folders return `4… parameters[3].description: Field used to sort the result. Sorting by `name` is case-sensitive and follows the storage collation, so do not rely on a case-insensitive order. → Field used to sort the result. Do not rely on case-insensitive ordering when sorting by `name`. parameters[3].schema.description: Field used to sort the result. Sorting by `name` is case-sensitive and follows the storage collation, so do not rely on a case-insensitive order. → Field used to sort the result. Do not rely on case-insensitive ordering when sorting by `name`. Preserved: Compared operationId listKnowledgeFolders, GET /api/v2/knowledge/folders, security and x-sim-operation with baseline; identifiers, route and credential schemes match. Recursive prose/default/example mappings retained in final-review-api-comparison.json; 6 distinct changed field mappings were inspected for this operation. Operation-level request/response structure, parameters, required fields, defaults and status declarations are identical after removing prose/examples; referenced component changes were reviewed separately. | +| `createKnowledgeFolder` — `POST /api/v2/knowledge/folders` | corrected | Use neutral document-wide error examples, or operation-specific examples. Preserve error.details.lock and actionable detail codes. These are illustrative examples, not a claim that every server response uses that message. | Verified improvement. Summary: Create Folder → Create folder; sentence case matches the editorial guide. responses.503.description: A required service is temporarily unavailable. `Retry-After` carries the seconds to wait; treat it as a floor and add jitter. The header is omitted when `error.details.code` is `A… → A required service is temporarily unavailable. When present, `Retry-After` gives the minimum seconds to wait; add jitter before retrying. Check operation-specific guidance before … 1 request/response media example set(s) now expose the owner's existing examples to the API renderer. Preserved: Compared operationId createKnowledgeFolder, POST /api/v2/knowledge/folders, security and x-sim-operation with baseline; identifiers, route and credential schemes match. Recursive prose/default/example mappings retained in final-review-api-comparison.json; 4 distinct changed field mappings were inspected for this operation. Operation-level request/response structure, parameters, required fields, defaults and status declarations are identical after removing prose/examples; referenced component changes were reviewed separately. | +| `relocateKnowledgeFolder` — `PATCH /api/v2/knowledge/folders` | corrected | Use neutral document-wide error examples, or operation-specific examples. Preserve error.details.lock and actionable detail codes. These are illustrative examples, not a claim that every server response uses that message. | Verified improvement. Summary: Rename or Move Folder → Rename or move folder; sentence case matches the editorial guide. responses.503.description: A required service is temporarily unavailable. `Retry-After` carries the seconds to wait; treat it as a floor and add jitter. The header is omitted when `error.details.code` is `A… → A required service is temporarily unavailable. When present, `Retry-After` gives the minimum seconds to wait; add jitter before retrying. Check operation-specific guidance before … 1 request/response media example set(s) now expose the owner's existing examples to the API renderer. Preserved: Compared operationId relocateKnowledgeFolder, PATCH /api/v2/knowledge/folders, security and x-sim-operation with baseline; identifiers, route and credential schemes match. Recursive prose/default/example mappings retained in final-review-api-comparison.json; 4 distinct changed field mappings were inspected for this operation. Operation-level request/response structure, parameters, required fields, defaults and status declarations are identical after removing prose/examples; referenced component changes were reviewed separately. | +| `deleteKnowledgeFolder` — `DELETE /api/v2/knowledge/folders` | corrected | Use neutral document-wide error examples, or operation-specific examples. Preserve error.details.lock and actionable detail codes. These are illustrative examples, not a claim that every server response uses that message. | Verified improvement. Summary: Delete Folder → Delete folder; sentence case matches the editorial guide. parameters[2].description: Delete the folder's nested files and folders too. An empty folder deletes either way; a non-empty one needs this. The listed spellings are the whole accepted vocabulary and are ca… → Delete the folder's contents and nested folders too. Required for a non-empty folder. Only the listed case-sensitive spellings are accepted. parameters[2].schema.description: Delete the folder's nested files and folders too. An empty folder deletes either way; a non-empty one needs this. The listed spellings are the whole accepted vocabulary and are ca… → Delete the folder's contents and nested folders too. Required for a non-empty folder. Only the listed case-sensitive spellings are accepted. responses.503.description: A required service is temporarily unavailable. `Retry-After` carries the seconds to wait; treat it as a floor and add jitter. The header is omitted when `error.details.code` is `A… → A required service is temporarily unavailable. When present, `Retry-After` gives the minimum seconds to wait; add jitter before retrying. Check operation-specific guidance before … Preserved: Compared operationId deleteKnowledgeFolder, DELETE /api/v2/knowledge/folders, security and x-sim-operation with baseline; identifiers, route and credential schemes match. Recursive prose/default/example mappings retained in final-review-api-comparison.json; 6 distinct changed field mappings were inspected for this operation. Operation-level request/response structure, parameters, required fields, defaults and status declarations are identical after removing prose/examples; referenced component changes were reviewed separately. | +| `restoreKnowledgeBase` — `POST /api/v2/knowledge/{knowledgeBaseId}/restore` | corrected | Use neutral document-wide error examples, or operation-specific examples. Preserve error.details.lock and actionable detail codes. These are illustrative examples, not a claim that every server response uses that message. | Verified improvement. Summary: Restore Knowledge Base → Restore knowledge base; sentence case matches the editorial guide. responses.200.content.application/json.schema.properties.data.properties.chunkingConfig.properties.overlap.description: Number of overlapping characters between adjacent chunks. → Requested overlap in tokens between adjacent chunks. responses.503.description: A required service is temporarily unavailable. `Retry-After` carries the seconds to wait; treat it as a floor and add jitter. The header is omitted when `error.details.code` is `A… → A required service is temporarily unavailable. When present, `Retry-After` gives the minimum seconds to wait; add jitter before retrying. Check operation-specific guidance before … 1 request/response media example set(s) now expose the owner's existing examples to the API renderer. Preserved: Compared operationId restoreKnowledgeBase, POST /api/v2/knowledge/{knowledgeBaseId}/restore, security and x-sim-operation with baseline; identifiers, route and credential schemes match. Recursive prose/default/example mappings retained in final-review-api-comparison.json; 6 distinct changed field mappings were inspected for this operation. Operation-level request/response structure, parameters, required fields, defaults and status declarations are identical after removing prose/examples; referenced component changes were reviewed separately. | +| `addWorkspaceFilesToKnowledgeBase` — `POST /api/v2/knowledge/{knowledgeBaseId}/documents/from-workspace-files` | corrected | "Workspace file IDs or file paths to index. Prefer IDs or canonical files// paths. Duplicates resolving to one file are indexed once." handbook.pdf example is a valid name reference; an ID example would be less ambiguous. Used MiB for verified power-of-1024 byte limits in scoped prose. | Verified improvement. Summary: Index Workspace Files → Index workspace files; sentence case matches the editorial guide. description: Queue stored workspace files for indexing without re-uploading bytes. Unreadable, unsupported, or over-100 MB files appear in `failed`; valid files are queued. Partial success ret… → Queue stored workspace files for indexing without re-uploading bytes. Unreadable, unsupported, or over-100 MiB files appear in `failed`; valid files are queued. Partial success re… requestBody.content.application/json.schema.properties.fileReferences.description: Workspace file identifiers or storage keys to index. Duplicates resolving to the same file are indexed once. → Workspace file IDs or paths to index. Prefer IDs or canonical `files//` paths. Duplicates resolving to the same file are indexed once. responses.503.description: A required service is temporarily unavailable. `Retry-After` carries the seconds to wait; treat it as a floor and add jitter. The header is omitted when `error.details.code` is `A… → A required service is temporarily unavailable. When present, `Retry-After` gives the minimum seconds to wait; add jitter before retrying. Check operation-specific guidance before … 1 request/response media example set(s) now expose the owner's existing examples to the API renderer. Preserved: Compared operationId addWorkspaceFilesToKnowledgeBase, POST /api/v2/knowledge/{knowledgeBaseId}/documents/from-workspace-files, security and x-sim-operation with baseline; identifiers, route and credential schemes match. Recursive prose/default/example mappings retained in final-review-api-comparison.json; 5 distinct changed field mappings were inspected for this operation. Operation-level request/response structure, parameters, required fields, defaults and status declarations are identical after removing prose/examples; referenced component changes were reviewed separately. | +| `listKnowledgeChunks` — `GET /api/v2/knowledge/{knowledgeBaseId}/documents/{documentId}/chunks` | corrected | Use neutral document-wide error examples, or operation-specific examples. Preserve error.details.lock and actionable detail codes. These are illustrative examples, not a claim that every server response uses that message. | Verified improvement. Summary: List Chunks → List chunks; sentence case matches the editorial guide. responses.200.content.application/json.schema.properties.nextCursor.description: Opaque cursor for the next page. Send it back as `cursor`; `null` means there is nothing further to fetch. Never construct one yourself. → Opaque cursor for the next page. Send it back as `cursor`; `null` means there are no more pages. Do not construct a cursor yourself. responses.503.description: A required service is temporarily unavailable. `Retry-After` carries the seconds to wait; treat it as a floor and add jitter. The header is omitted when `error.details.code` is `A… → A required service is temporarily unavailable. When present, `Retry-After` gives the minimum seconds to wait; add jitter before retrying. Check operation-specific guidance before … Preserved: Compared operationId listKnowledgeChunks, GET /api/v2/knowledge/{knowledgeBaseId}/documents/{documentId}/chunks, security and x-sim-operation with baseline; identifiers, route and credential schemes match. Recursive prose/default/example mappings retained in final-review-api-comparison.json; 5 distinct changed field mappings were inspected for this operation. Operation-level request/response structure, parameters, required fields, defaults and status declarations are identical after removing prose/examples; referenced component changes were reviewed separately. | +| `createKnowledgeChunk` — `POST /api/v2/knowledge/{knowledgeBaseId}/documents/{documentId}/chunks` | corrected | "Embed the chunk before returning. It appears in search when the chunk and its document are enabled and the document has completed processing." Preserve connector-managed read-only restriction. | Verified improvement. Summary: Create Chunk → Create chunk; sentence case matches the editorial guide. description: Append a chunk, embedding it before the response so it is immediately searchable. It inherits the document's tags and next `chunkIndex`. Connector-synced chunks are read-only and … → Append a chunk and embed it before returning. It inherits the document's tags and next `chunkIndex`. Search includes it when the chunk and document are enabled and the document ha… requestBody.content.application/json.schema.properties.content.description: Text to embed. It is embedded on write, so the chunk is searchable immediately. → Text embedded before the response. Search includes it when the chunk and document are enabled and the document has completed processing. responses.503.description: A required service is temporarily unavailable. `Retry-After` carries the seconds to wait; treat it as a floor and add jitter. The header is omitted when `error.details.code` is `A… → A required service is temporarily unavailable. When present, `Retry-After` gives the minimum seconds to wait; add jitter before retrying. Check operation-specific guidance before … 1 request/response media example set(s) now expose the owner's existing examples to the API renderer. Preserved: Compared operationId createKnowledgeChunk, POST /api/v2/knowledge/{knowledgeBaseId}/documents/{documentId}/chunks, security and x-sim-operation with baseline; identifiers, route and credential schemes match. Recursive prose/default/example mappings retained in final-review-api-comparison.json; 5 distinct changed field mappings were inspected for this operation. Operation-level request/response structure, parameters, required fields, defaults and status declarations are identical after removing prose/examples; referenced component changes were reviewed separately. | +| `bulkUpdateKnowledgeChunks` — `PATCH /api/v2/knowledge/{knowledgeBaseId}/documents/{documentId}/chunks` | rewritten | Copy standardized; no operation-specific discrepancy found. | Verified improvement. Summary: Bulk Update Chunks → Bulk update chunks; sentence case matches the editorial guide. responses.503.description: A required service is temporarily unavailable. `Retry-After` carries the seconds to wait; treat it as a floor and add jitter. The header is omitted when `error.details.code` is `A… → A required service is temporarily unavailable. When present, `Retry-After` gives the minimum seconds to wait; add jitter before retrying. Check operation-specific guidance before … 1 request/response media example set(s) now expose the owner's existing examples to the API renderer. Preserved: Compared operationId bulkUpdateKnowledgeChunks, PATCH /api/v2/knowledge/{knowledgeBaseId}/documents/{documentId}/chunks, security and x-sim-operation with baseline; identifiers, route and credential schemes match. Recursive prose/default/example mappings retained in final-review-api-comparison.json; 3 distinct changed field mappings were inspected for this operation. Operation-level request/response structure, parameters, required fields, defaults and status declarations are identical after removing prose/examples; referenced component changes were reviewed separately. | +| `getKnowledgeChunk` — `GET /api/v2/knowledge/{knowledgeBaseId}/documents/{documentId}/chunks/{chunkId}` | corrected | Use neutral document-wide error examples, or operation-specific examples. Preserve error.details.lock and actionable detail codes. These are illustrative examples, not a claim that every server response uses that message. | Verified improvement. Summary: Get Chunk → Get chunk; sentence case matches the editorial guide. responses.503.description: A required service is temporarily unavailable. `Retry-After` carries the seconds to wait; treat it as a floor and add jitter. The header is omitted when `error.details.code` is `A… → A required service is temporarily unavailable. When present, `Retry-After` gives the minimum seconds to wait; add jitter before retrying. Check operation-specific guidance before … Preserved: Compared operationId getKnowledgeChunk, GET /api/v2/knowledge/{knowledgeBaseId}/documents/{documentId}/chunks/{chunkId}, security and x-sim-operation with baseline; identifiers, route and credential schemes match. Recursive prose/default/example mappings retained in final-review-api-comparison.json; 3 distinct changed field mappings were inspected for this operation. Operation-level request/response structure, parameters, required fields, defaults and status declarations are identical after removing prose/examples; referenced component changes were reviewed separately. | +| `updateKnowledgeChunk` — `PATCH /api/v2/knowledge/{knowledgeBaseId}/documents/{documentId}/chunks/{chunkId}` | corrected | Use neutral document-wide error examples, or operation-specific examples. Preserve error.details.lock and actionable detail codes. These are illustrative examples, not a claim that every server response uses that message. | Verified improvement. Summary: Update Chunk → Update chunk; sentence case matches the editorial guide. responses.503.description: A required service is temporarily unavailable. `Retry-After` carries the seconds to wait; treat it as a floor and add jitter. The header is omitted when `error.details.code` is `A… → A required service is temporarily unavailable. When present, `Retry-After` gives the minimum seconds to wait; add jitter before retrying. Check operation-specific guidance before … 1 request/response media example set(s) now expose the owner's existing examples to the API renderer. Preserved: Compared operationId updateKnowledgeChunk, PATCH /api/v2/knowledge/{knowledgeBaseId}/documents/{documentId}/chunks/{chunkId}, security and x-sim-operation with baseline; identifiers, route and credential schemes match. Recursive prose/default/example mappings retained in final-review-api-comparison.json; 4 distinct changed field mappings were inspected for this operation. Operation-level request/response structure, parameters, required fields, defaults and status declarations are identical after removing prose/examples; referenced component changes were reviewed separately. | +| `deleteKnowledgeChunk` — `DELETE /api/v2/knowledge/{knowledgeBaseId}/documents/{documentId}/chunks/{chunkId}` | corrected | Use neutral document-wide error examples, or operation-specific examples. Preserve error.details.lock and actionable detail codes. These are illustrative examples, not a claim that every server response uses that message. | Verified improvement. Summary: Delete Chunk → Delete chunk; sentence case matches the editorial guide. responses.503.description: A required service is temporarily unavailable. `Retry-After` carries the seconds to wait; treat it as a floor and add jitter. The header is omitted when `error.details.code` is `A… → A required service is temporarily unavailable. When present, `Retry-After` gives the minimum seconds to wait; add jitter before retrying. Check operation-specific guidance before … Preserved: Compared operationId deleteKnowledgeChunk, DELETE /api/v2/knowledge/{knowledgeBaseId}/documents/{documentId}/chunks/{chunkId}, security and x-sim-operation with baseline; identifiers, route and credential schemes match. Recursive prose/default/example mappings retained in final-review-api-comparison.json; 3 distinct changed field mappings were inspected for this operation. Operation-level request/response structure, parameters, required fields, defaults and status declarations are identical after removing prose/examples; referenced component changes were reviewed separately. | +| `updateKnowledgeTag` — `PATCH /api/v2/knowledge/{knowledgeBaseId}/tags/{tagId}` | corrected | "Slot used by document updates: tag1–tag7, number1–number5, date1–date2, or boolean1–boolean3. Upload creation accepts text slots; use Update Document for other types." Keep display-name/slot distinction. Use neutral document-wide error examples, or operation-specific examples. Preserve error.details.lock and actionable detail codes. These are illustrative examples, not a claim that every server response uses that message. | Verified improvement. Summary: Update Tag → Update tag; sentence case matches the editorial guide. responses.200.content.application/json.schema.properties.data.properties.tagSlot.description: Storage slot the tag occupies. Document writes set tag values by slot (`tag1`..`tag7`). → Slot used by document updates: `tag1`–`tag7`, `number1`–`number5`, `date1`–`date2`, or `boolean1`–`boolean3`. Upload creation accepts text slots; use Update document for other typ… responses.503.description: A required service is temporarily unavailable. `Retry-After` carries the seconds to wait; treat it as a floor and add jitter. The header is omitted when `error.details.code` is `A… → A required service is temporarily unavailable. When present, `Retry-After` gives the minimum seconds to wait; add jitter before retrying. Check operation-specific guidance before … 1 request/response media example set(s) now expose the owner's existing examples to the API renderer. Preserved: Compared operationId updateKnowledgeTag, PATCH /api/v2/knowledge/{knowledgeBaseId}/tags/{tagId}, security and x-sim-operation with baseline; identifiers, route and credential schemes match. Recursive prose/default/example mappings retained in final-review-api-comparison.json; 6 distinct changed field mappings were inspected for this operation. Operation-level request/response structure, parameters, required fields, defaults and status declarations are identical after removing prose/examples; referenced component changes were reviewed separately. | +| `deleteKnowledgeTag` — `DELETE /api/v2/knowledge/{knowledgeBaseId}/tags/{tagId}` | corrected | Use neutral document-wide error examples, or operation-specific examples. Preserve error.details.lock and actionable detail codes. These are illustrative examples, not a claim that every server response uses that message. | Verified improvement. Summary: Delete Tag → Delete tag; sentence case matches the editorial guide. responses.503.description: A required service is temporarily unavailable. `Retry-After` carries the seconds to wait; treat it as a floor and add jitter. The header is omitted when `error.details.code` is `A… → A required service is temporarily unavailable. When present, `Retry-After` gives the minimum seconds to wait; add jitter before retrying. Check operation-specific guidance before … Preserved: Compared operationId deleteKnowledgeTag, DELETE /api/v2/knowledge/{knowledgeBaseId}/tags/{tagId}, security and x-sim-operation with baseline; identifiers, route and credential schemes match. Recursive prose/default/example mappings retained in final-review-api-comparison.json; 3 distinct changed field mappings were inspected for this operation. Operation-level request/response structure, parameters, required fields, defaults and status declarations are identical after removing prose/examples; referenced component changes were reviewed separately. | +| `getNextKnowledgeTagSlot` — `GET /api/v2/knowledge/{knowledgeBaseId}/tags/next-slot` | rewritten | Copy standardized; no operation-specific discrepancy found. | Verified improvement. Summary: Get Next Tag Slot → Get next tag slot; sentence case matches the editorial guide. responses.503.description: A required service is temporarily unavailable. `Retry-After` carries the seconds to wait; treat it as a floor and add jitter. The header is omitted when `error.details.code` is `A… → A required service is temporarily unavailable. When present, `Retry-After` gives the minimum seconds to wait; add jitter before retrying. Check operation-specific guidance before … Preserved: Compared operationId getNextKnowledgeTagSlot, GET /api/v2/knowledge/{knowledgeBaseId}/tags/next-slot, security and x-sim-operation with baseline; identifiers, route and credential schemes match. Recursive prose/default/example mappings retained in final-review-api-comparison.json; 3 distinct changed field mappings were inspected for this operation. Operation-level request/response structure, parameters, required fields, defaults and status declarations are identical after removing prose/examples; referenced component changes were reviewed separately. | +| `listKnowledgeTagUsage` — `GET /api/v2/knowledge/{knowledgeBaseId}/tags/usage` | rewritten | Copy standardized; no operation-specific discrepancy found. | Verified improvement. Summary: List Tag Usage → List tag usage; sentence case matches the editorial guide. description: Count the documents and chunks with a value for each defined tag. Returns the complete set in one page; `nextCursor` is always null. Workspace API keys return `403`; use a persona… → Count the documents and chunks with a value for each defined tag. Returns one page; `nextCursor` is always null. Workspace API keys return `403`; use a personal API key or scoped … responses.200.content.application/json.schema.properties.nextCursor.description: Always `null` — this list has no `cursor` or `limit` param and returns its whole bounded set in one page. Present so the list can gain pages later without a shape change. → Always `null`. This list has no `cursor` or `limit` parameters; see the operation for inventory limits. responses.503.description: A required service is temporarily unavailable. `Retry-After` carries the seconds to wait; treat it as a floor and add jitter. The header is omitted when `error.details.code` is `A… → A required service is temporarily unavailable. When present, `Retry-After` gives the minimum seconds to wait; add jitter before retrying. Check operation-specific guidance before … Preserved: Compared operationId listKnowledgeTagUsage, GET /api/v2/knowledge/{knowledgeBaseId}/tags/usage, security and x-sim-operation with baseline; identifiers, route and credential schemes match. Recursive prose/default/example mappings retained in final-review-api-comparison.json; 4 distinct changed field mappings were inspected for this operation. Operation-level request/response structure, parameters, required fields, defaults and status declarations are identical after removing prose/examples; referenced component changes were reviewed separately. | +| `listLogs` — `GET /api/v2/logs` | corrected | Use USD 0.005 fixed + USD 0.0022 model = USD 0.0072 in the detail example and matching list total. Logs USD response contracts remain unchanged; Billing/run-resource credit units are separate. | Verified improvement. Summary: List Logs → List logs; sentence case matches the editorial guide. description: List logs with filters, selectable detail, sorting, and cursor pagination. `includeJobRuns=true` includes chat and Sim-agent jobs only with `sortBy=startedAt`, because other order… → List logs with filters, selectable detail, sorting, and cursor pagination. `includeJobRuns=true` includes chat and Sim-agent jobs only with `sortBy=startedAt`, because other order… responses.200.content.application/json.schema.properties.nextCursor.description: Opaque cursor for the next page. Send it back as `cursor`; `null` means there is nothing further to fetch. Never construct one yourself. → Opaque cursor for the next page. Send it back as `cursor`; `null` means there are no more pages. Do not construct a cursor yourself. responses.503.description: A required service is temporarily unavailable. `Retry-After` carries the seconds to wait; treat it as a floor and add jitter. The header is omitted when `error.details.code` is `A… → A required service is temporarily unavailable. When present, `Retry-After` gives the minimum seconds to wait; add jitter before retrying. Check operation-specific guidance before … 1 request/response media example set(s) now expose the owner's existing examples to the API renderer. Preserved: Compared operationId listLogs, GET /api/v2/logs, security and x-sim-operation with baseline; identifiers, route and credential schemes match. Recursive prose/default/example mappings retained in final-review-api-comparison.json; 6 distinct changed field mappings were inspected for this operation. Operation-level request/response structure, parameters, required fields, defaults and status declarations are identical after removing prose/examples; referenced component changes were reviewed separately. Logs remain USD. Illustrative run list/detail totals agree: 0.005 fixed + 0.0022 model = 0.0072 USD. | +| `getLog` — `GET /api/v2/logs/{runId}` | corrected | Use USD 0.005 fixed + USD 0.0022 model = USD 0.0072 in the detail example and matching list total. Logs USD response contracts remain unchanged; Billing/run-resource credit units are separate. Review correction: list and detail examples agree on the run output file. | Verified improvement. Summary: Get Log → Get log; sentence case matches the editorial guide. description: Get a run's workflow graph, trace spans, final output, and cost. Trace spans expire separately, so an empty `traceSpans` array does not prove none were recorded. Expired runs are … → Get a run's workflow graph, trace spans, final output, and cost. Trace spans expire separately, so an empty `traceSpans` array does not prove none were recorded. Expired runs are … responses.503.description: A required service is temporarily unavailable. `Retry-After` carries the seconds to wait; treat it as a floor and add jitter. The header is omitted when `error.details.code` is `A… → A required service is temporarily unavailable. When present, `Retry-After` gives the minimum seconds to wait; add jitter before retrying. Check operation-specific guidance before … 1 request/response media example set(s) now expose the owner's existing examples to the API renderer. Preserved: Compared operationId getLog, GET /api/v2/logs/{runId}, security and x-sim-operation with baseline; identifiers, route and credential schemes match. Recursive prose/default/example mappings retained in final-review-api-comparison.json; 5 distinct changed field mappings were inspected for this operation. Operation-level request/response structure, parameters, required fields, defaults and status declarations are identical after removing prose/examples; referenced component changes were reviewed separately. Logs remain USD. Illustrative run list/detail totals agree: 0.005 fixed + 0.0022 model = 0.0072 USD. | +| `getLogStats` — `GET /api/v2/logs/stats` | corrected | Publish the input default as string "false" in OpenAPI metadata, while retaining the runtime boolean default. Do not change accepted inputs or runtime behavior. | Verified improvement. Summary: Get Log Statistics → Get log statistics; sentence case matches the editorial guide. description: Get bucketed run counts, success rate, errors, and mean latency for the workspace and individual workflows. Query fields describe window selection and bucketing. Folder filters co… → Get bucketed run counts, success rate, errors, and mean latency for the workspace and individual workflows. Query fields describe window selection and bucketing. Folder filters co… responses.503.description: A required service is temporarily unavailable. `Retry-After` carries the seconds to wait; treat it as a floor and add jitter. The header is omitted when `error.details.code` is `A… → A required service is temporarily unavailable. When present, `Retry-After` gives the minimum seconds to wait; add jitter before retrying. Check operation-specific guidance before … 1 request/response media example set(s) now expose the owner's existing examples to the API renderer. Preserved: Compared operationId getLogStats, GET /api/v2/logs/stats, security and x-sim-operation with baseline; identifiers, route and credential schemes match. Recursive prose/default/example mappings retained in final-review-api-comparison.json; 5 distinct changed field mappings were inspected for this operation. includeEmpty advertises string "false" to match its string vocabulary; canonical runtime transform/default remains false. | +| `listTables` — `GET /api/v2/tables` | rewritten | Copy standardized; no operation-specific discrepancy found. | Verified improvement. Summary: List Tables → List tables; sentence case matches the editorial guide. parameters[4].description: Field used to sort the result. Sorting by `name` is case-sensitive and follows the storage collation, so do not rely on a case-insensitive order. → Field used to sort the result. Do not rely on case-insensitive ordering when sorting by `name`. parameters[4].schema.description: Field used to sort the result. Sorting by `name` is case-sensitive and follows the storage collation, so do not rely on a case-insensitive order. → Field used to sort the result. Do not rely on case-insensitive ordering when sorting by `name`. responses.200.content.application/json.schema.properties.nextCursor.description: Opaque cursor for the next page. Send it back as `cursor`; `null` means there is nothing further to fetch. Never construct one yourself. → Opaque cursor for the next page. Send it back as `cursor`; `null` means there are no more pages. Do not construct a cursor yourself. Preserved: Compared operationId listTables, GET /api/v2/tables, security and x-sim-operation with baseline; identifiers, route and credential schemes match. Recursive prose/default/example mappings retained in final-review-api-comparison.json; 5 distinct changed field mappings were inspected for this operation. Operation-level request/response structure, parameters, required fields, defaults and status declarations are identical after removing prose/examples; referenced component changes were reviewed separately. | +| `createTable` — `POST /api/v2/tables` | rewritten | Copy standardized; no operation-specific discrepancy found. | Verified improvement. Summary: Create Table → Create table; sentence case matches the editorial guide. responses.503.description: A required service is temporarily unavailable. `Retry-After` carries the seconds to wait; treat it as a floor and add jitter. The header is omitted when `error.details.code` is `A… → A required service is temporarily unavailable. When present, `Retry-After` gives the minimum seconds to wait; add jitter before retrying. Check operation-specific guidance before … 1 request/response media example set(s) now expose the owner's existing examples to the API renderer. Preserved: Compared operationId createTable, POST /api/v2/tables, security and x-sim-operation with baseline; identifiers, route and credential schemes match. Recursive prose/default/example mappings retained in final-review-api-comparison.json; 4 distinct changed field mappings were inspected for this operation. Operation-level request/response structure, parameters, required fields, defaults and status declarations are identical after removing prose/examples; referenced component changes were reviewed separately. | +| `getTable` — `GET /api/v2/tables/{tableId}` | rewritten | Copy standardized; no operation-specific discrepancy found. | Verified improvement. Summary: Get Table → Get table; sentence case matches the editorial guide. responses.503.description: A required service is temporarily unavailable. `Retry-After` carries the seconds to wait; treat it as a floor and add jitter. The header is omitted when `error.details.code` is `A… → A required service is temporarily unavailable. When present, `Retry-After` gives the minimum seconds to wait; add jitter before retrying. Check operation-specific guidance before … Preserved: Compared operationId getTable, GET /api/v2/tables/{tableId}, security and x-sim-operation with baseline; identifiers, route and credential schemes match. Recursive prose/default/example mappings retained in final-review-api-comparison.json; 2 distinct changed field mappings were inspected for this operation. Operation-level request/response structure, parameters, required fields, defaults and status declarations are identical after removing prose/examples; referenced component changes were reviewed separately. | +| `deleteTable` — `DELETE /api/v2/tables/{tableId}` | corrected | Use neutral document-wide error examples, or operation-specific examples. Preserve error.details.lock and actionable detail codes. These are illustrative examples, not a claim that every server response uses that message. | Verified improvement. Summary: Delete Table → Delete table; sentence case matches the editorial guide. responses.503.description: A required service is temporarily unavailable. `Retry-After` carries the seconds to wait; treat it as a floor and add jitter. The header is omitted when `error.details.code` is `A… → A required service is temporarily unavailable. When present, `Retry-After` gives the minimum seconds to wait; add jitter before retrying. Check operation-specific guidance before … Preserved: Compared operationId deleteTable, DELETE /api/v2/tables/{tableId}, security and x-sim-operation with baseline; identifiers, route and credential schemes match. Recursive prose/default/example mappings retained in final-review-api-comparison.json; 4 distinct changed field mappings were inspected for this operation. Operation-level request/response structure, parameters, required fields, defaults and status declarations are identical after removing prose/examples; referenced component changes were reviewed separately. | +| `updateTable` — `PATCH /api/v2/tables/{tableId}` | rewritten | Reviewed; accurate details retained under the shared reference standard. | Verified improvement. Summary: Update Table → Update table; sentence case matches the editorial guide. responses.503.description: A required service is temporarily unavailable. `Retry-After` carries the seconds to wait; treat it as a floor and add jitter. The header is omitted when `error.details.code` is `A… → A required service is temporarily unavailable. When present, `Retry-After` gives the minimum seconds to wait; add jitter before retrying. Check operation-specific guidance before … 1 request/response media example set(s) now expose the owner's existing examples to the API renderer. Preserved: Compared operationId updateTable, PATCH /api/v2/tables/{tableId}, security and x-sim-operation with baseline; identifiers, route and credential schemes match. Recursive prose/default/example mappings retained in final-review-api-comparison.json; 4 distinct changed field mappings were inspected for this operation. Operation-level request/response structure, parameters, required fields, defaults and status declarations are identical after removing prose/examples; referenced component changes were reviewed separately. | +| `addTableColumn` — `POST /api/v2/tables/{tableId}/columns` | corrected | Use neutral document-wide error examples, or operation-specific examples. Preserve error.details.lock and actionable detail codes. These are illustrative examples, not a claim that every server response uses that message. | Verified improvement. Summary: Add Column → Add column; sentence case matches the editorial guide. responses.503.description: A required service is temporarily unavailable. `Retry-After` carries the seconds to wait; treat it as a floor and add jitter. The header is omitted when `error.details.code` is `A… → A required service is temporarily unavailable. When present, `Retry-After` gives the minimum seconds to wait; add jitter before retrying. Check operation-specific guidance before … 1 request/response media example set(s) now expose the owner's existing examples to the API renderer. Preserved: Compared operationId addTableColumn, POST /api/v2/tables/{tableId}/columns, security and x-sim-operation with baseline; identifiers, route and credential schemes match. Recursive prose/default/example mappings retained in final-review-api-comparison.json; 4 distinct changed field mappings were inspected for this operation. Operation-level request/response structure, parameters, required fields, defaults and status declarations are identical after removing prose/examples; referenced component changes were reviewed separately. | +| `updateTableColumn` — `PATCH /api/v2/tables/{tableId}/columns` | corrected | Use neutral document-wide error examples, or operation-specific examples. Preserve error.details.lock and actionable detail codes. These are illustrative examples, not a claim that every server response uses that message. | Verified improvement. Summary: Update Column → Update column; sentence case matches the editorial guide. responses.503.description: A required service is temporarily unavailable. `Retry-After` carries the seconds to wait; treat it as a floor and add jitter. The header is omitted when `error.details.code` is `A… → A required service is temporarily unavailable. When present, `Retry-After` gives the minimum seconds to wait; add jitter before retrying. Check operation-specific guidance before … 2 request/response media example set(s) now expose the owner's existing examples to the API renderer. Preserved: Compared operationId updateTableColumn, PATCH /api/v2/tables/{tableId}/columns, security and x-sim-operation with baseline; identifiers, route and credential schemes match. Recursive prose/default/example mappings retained in final-review-api-comparison.json; 5 distinct changed field mappings were inspected for this operation. Operation-level request/response structure, parameters, required fields, defaults and status declarations are identical after removing prose/examples; referenced component changes were reviewed separately. | +| `deleteTableColumn` — `DELETE /api/v2/tables/{tableId}/columns` | corrected | Use neutral document-wide error examples, or operation-specific examples. Preserve error.details.lock and actionable detail codes. These are illustrative examples, not a claim that every server response uses that message. | Verified improvement. Summary: Delete Column → Delete column; sentence case matches the editorial guide. responses.503.description: A required service is temporarily unavailable. `Retry-After` carries the seconds to wait; treat it as a floor and add jitter. The header is omitted when `error.details.code` is `A… → A required service is temporarily unavailable. When present, `Retry-After` gives the minimum seconds to wait; add jitter before retrying. Check operation-specific guidance before … 1 request/response media example set(s) now expose the owner's existing examples to the API renderer. Preserved: Compared operationId deleteTableColumn, DELETE /api/v2/tables/{tableId}/columns, security and x-sim-operation with baseline; identifiers, route and credential schemes match. Recursive prose/default/example mappings retained in final-review-api-comparison.json; 4 distinct changed field mappings were inspected for this operation. Operation-level request/response structure, parameters, required fields, defaults and status declarations are identical after removing prose/examples; referenced component changes were reviewed separately. | +| `listTableRows` — `GET /api/v2/tables/{tableId}/rows` | corrected | Add PayloadTooLarge to these operations and explain the 2 MiB run-state ceiling on includeRunState / row-group detail. Replace internal "sidecar/blockErrors are unbounded" rationale with the user consequence and retry action. Used MiB for verified power-of-1024 byte limits in scoped prose. | Verified improvement. Summary: List Rows → List rows; sentence case matches the editorial guide. description: List rows in default order with cursor pagination. Pages default to a 5 MB limit and may contain fewer rows than requested; continue until `nextCursor` is null. Use Query Rows for… → List rows in default order with cursor pagination. Pages default to a 5 MiB limit and may contain fewer rows than requested; continue until `nextCursor` is null. Use Query rows fo… parameters[4].description: Include per-workflow-group run state on every returned row. Off by default: run state is a separate sidecar read and its `blockErrors` are unbounded, so a full page carries it onl… → Include per-workflow-group run outcomes on every row. Off by default. Caps `limit` at 200. Run state above 2 MiB returns `413`; request fewer rows or omit run state. parameters[4].schema.description: Include per-workflow-group run state on every returned row. Off by default: run state is a separate sidecar read and its `blockErrors` are unbounded, so a full page carries it onl… → Include per-workflow-group run outcomes on every row. Off by default. Caps `limit` at 200. Run state above 2 MiB returns `413`; request fewer rows or omit run state. 1 request/response media example set(s) now expose the owner's existing examples to the API renderer. Preserved: Compared operationId listTableRows, GET /api/v2/tables/{tableId}/rows, security and x-sim-operation with baseline; identifiers, route and credential schemes match. Recursive prose/default/example mappings retained in final-review-api-comparison.json; 19 distinct changed field mappings were inspected for this operation. Only newly documented 413 response differs in operation structure; the existing 2 MiB run-state refusal is documented without route or schema behavior changes. | +| `createTableRows` — `POST /api/v2/tables/{tableId}/rows` | corrected | Use neutral document-wide error examples, or operation-specific examples. Preserve error.details.lock and actionable detail codes. These are illustrative examples, not a claim that every server response uses that message. | Verified improvement. Summary: Create Rows → Create rows; sentence case matches the editorial guide. responses.503.description: A required service is temporarily unavailable. `Retry-After` carries the seconds to wait; treat it as a floor and add jitter. The header is omitted when `error.details.code` is `A… → A required service is temporarily unavailable. When present, `Retry-After` gives the minimum seconds to wait; add jitter before retrying. Check operation-specific guidance before … 1 request/response media example set(s) now expose the owner's existing examples to the API renderer. Preserved: Compared operationId createTableRows, POST /api/v2/tables/{tableId}/rows, security and x-sim-operation with baseline; identifiers, route and credential schemes match. Recursive prose/default/example mappings retained in final-review-api-comparison.json; 4 distinct changed field mappings were inspected for this operation. Operation-level request/response structure, parameters, required fields, defaults and status declarations are identical after removing prose/examples; referenced component changes were reviewed separately. | +| `updateTableRows` — `PATCH /api/v2/tables/{tableId}/rows` | corrected | Use neutral document-wide error examples, or operation-specific examples. Preserve error.details.lock and actionable detail codes. These are illustrative examples, not a claim that every server response uses that message. | Verified improvement. Summary: Update Rows by Filter → Update rows by filter; sentence case matches the editorial guide. responses.503.description: A required service is temporarily unavailable. `Retry-After` carries the seconds to wait; treat it as a floor and add jitter. The header is omitted when `error.details.code` is `A… → A required service is temporarily unavailable. When present, `Retry-After` gives the minimum seconds to wait; add jitter before retrying. Check operation-specific guidance before … 1 request/response media example set(s) now expose the owner's existing examples to the API renderer. Preserved: Compared operationId updateTableRows, PATCH /api/v2/tables/{tableId}/rows, security and x-sim-operation with baseline; identifiers, route and credential schemes match. Recursive prose/default/example mappings retained in final-review-api-comparison.json; 4 distinct changed field mappings were inspected for this operation. Operation-level request/response structure, parameters, required fields, defaults and status declarations are identical after removing prose/examples; referenced component changes were reviewed separately. | +| `deleteTableRows` — `DELETE /api/v2/tables/{tableId}/rows` | corrected | Use neutral document-wide error examples, or operation-specific examples. Preserve error.details.lock and actionable detail codes. These are illustrative examples, not a claim that every server response uses that message. | Verified improvement. Summary: Delete Rows → Delete rows; sentence case matches the editorial guide. responses.503.description: A required service is temporarily unavailable. `Retry-After` carries the seconds to wait; treat it as a floor and add jitter. The header is omitted when `error.details.code` is `A… → A required service is temporarily unavailable. When present, `Retry-After` gives the minimum seconds to wait; add jitter before retrying. Check operation-specific guidance before … 1 request/response media example set(s) now expose the owner's existing examples to the API renderer. Preserved: Compared operationId deleteTableRows, DELETE /api/v2/tables/{tableId}/rows, security and x-sim-operation with baseline; identifiers, route and credential schemes match. Recursive prose/default/example mappings retained in final-review-api-comparison.json; 4 distinct changed field mappings were inspected for this operation. Operation-level request/response structure, parameters, required fields, defaults and status declarations are identical after removing prose/examples; referenced component changes were reviewed separately. | +| `getTableRow` — `GET /api/v2/tables/{tableId}/rows/{rowId}` | corrected | Add PayloadTooLarge to these operations and explain the 2 MiB run-state ceiling on includeRunState / row-group detail. Replace internal "sidecar/blockErrors are unbounded" rationale with the user consequence and retry action. | Verified improvement. Summary: Get Row → Get row; sentence case matches the editorial guide. parameters[3].description: Include per-workflow-group run state on the returned row. Off by default. → Include per-workflow-group run outcomes on the row. Off by default. Run state above 2 MiB returns `413`; omit this option to read the row without run state. parameters[3].schema.description: Include per-workflow-group run state on the returned row. Off by default. → Include per-workflow-group run outcomes on the row. Off by default. Run state above 2 MiB returns `413`; omit this option to read the row without run state. responses.503.description: A required service is temporarily unavailable. `Retry-After` carries the seconds to wait; treat it as a floor and add jitter. The header is omitted when `error.details.code` is `A… → A required service is temporarily unavailable. When present, `Retry-After` gives the minimum seconds to wait; add jitter before retrying. Check operation-specific guidance before … 1 request/response media example set(s) now expose the owner's existing examples to the API renderer. Preserved: Compared operationId getTableRow, GET /api/v2/tables/{tableId}/rows/{rowId}, security and x-sim-operation with baseline; identifiers, route and credential schemes match. Recursive prose/default/example mappings retained in final-review-api-comparison.json; 17 distinct changed field mappings were inspected for this operation. Only newly documented 413 response differs in operation structure; the existing 2 MiB run-state refusal is documented without route or schema behavior changes. | +| `updateTableRow` — `PATCH /api/v2/tables/{tableId}/rows/{rowId}` | corrected | Use neutral document-wide error examples, or operation-specific examples. Preserve error.details.lock and actionable detail codes. These are illustrative examples, not a claim that every server response uses that message. | Verified improvement. Summary: Update Row → Update row; sentence case matches the editorial guide. responses.503.description: A required service is temporarily unavailable. `Retry-After` carries the seconds to wait; treat it as a floor and add jitter. The header is omitted when `error.details.code` is `A… → A required service is temporarily unavailable. When present, `Retry-After` gives the minimum seconds to wait; add jitter before retrying. Check operation-specific guidance before … 1 request/response media example set(s) now expose the owner's existing examples to the API renderer. Preserved: Compared operationId updateTableRow, PATCH /api/v2/tables/{tableId}/rows/{rowId}, security and x-sim-operation with baseline; identifiers, route and credential schemes match. Recursive prose/default/example mappings retained in final-review-api-comparison.json; 4 distinct changed field mappings were inspected for this operation. Operation-level request/response structure, parameters, required fields, defaults and status declarations are identical after removing prose/examples; referenced component changes were reviewed separately. | +| `deleteTableRow` — `DELETE /api/v2/tables/{tableId}/rows/{rowId}` | corrected | Use neutral document-wide error examples, or operation-specific examples. Preserve error.details.lock and actionable detail codes. These are illustrative examples, not a claim that every server response uses that message. | Verified improvement. Summary: Delete Row → Delete row; sentence case matches the editorial guide. responses.503.description: A required service is temporarily unavailable. `Retry-After` carries the seconds to wait; treat it as a floor and add jitter. The header is omitted when `error.details.code` is `A… → A required service is temporarily unavailable. When present, `Retry-After` gives the minimum seconds to wait; add jitter before retrying. Check operation-specific guidance before … Preserved: Compared operationId deleteTableRow, DELETE /api/v2/tables/{tableId}/rows/{rowId}, security and x-sim-operation with baseline; identifiers, route and credential schemes match. Recursive prose/default/example mappings retained in final-review-api-comparison.json; 3 distinct changed field mappings were inspected for this operation. Operation-level request/response structure, parameters, required fields, defaults and status declarations are identical after removing prose/examples; referenced component changes were reviewed separately. | +| `upsertTableRow` — `POST /api/v2/tables/{tableId}/rows/upsert` | corrected | Use neutral document-wide error examples, or operation-specific examples. Preserve error.details.lock and actionable detail codes. These are illustrative examples, not a claim that every server response uses that message. | Verified improvement. Summary: Upsert Row → Upsert row; sentence case matches the editorial guide. responses.503.description: A required service is temporarily unavailable. `Retry-After` carries the seconds to wait; treat it as a floor and add jitter. The header is omitted when `error.details.code` is `A… → A required service is temporarily unavailable. When present, `Retry-After` gives the minimum seconds to wait; add jitter before retrying. Check operation-specific guidance before … 1 request/response media example set(s) now expose the owner's existing examples to the API renderer. Preserved: Compared operationId upsertTableRow, POST /api/v2/tables/{tableId}/rows/upsert, security and x-sim-operation with baseline; identifiers, route and credential schemes match. Recursive prose/default/example mappings retained in final-review-api-comparison.json; 5 distinct changed field mappings were inspected for this operation. Operation-level request/response structure, parameters, required fields, defaults and status declarations are identical after removing prose/examples; referenced component changes were reviewed separately. | +| `queryTableRows` — `POST /api/v2/tables/{tableId}/query` | corrected | "0 requests all matches, subject to the 5 MiB row-data ceiling; larger results return 400 with TABLE_QUERY_RESULT_TOO_LARGE. Use paged queries or an export." Keep includeRunState incompatibility. Distinguish fixed whole-result ceiling from configurable bounded-page default. Used MiB for verified power-of-1024 byte limits in scoped prose. | Verified improvement. Summary: Query Rows → Query rows; sentence case matches the editorial guide. description: Query rows with typed predicates, sorting, and cursor pagination. Omit the predicate to match all rows. Pages default to a 5 MB limit; continue until `nextCursor` is null. Oversiz… → Query rows with typed predicates, sorting, and cursor pagination. Omit the predicate to match all rows. Pages default to a 5 MiB limit; continue until `nextCursor` is null. Oversi… requestBody.content.application/json.schema.properties.includeRunState.description: Include per-workflow-group run state on every returned row. Off by default: run state is a separate sidecar read and its `blockErrors` are unbounded, so a full page carries it onl… → Include per-workflow-group run outcomes on every row. Off by default. Incompatible with `limit: 0`; caps `limit` at 200. Run state above 2 MiB returns `413`; request fewer rows or… requestBody.content.application/json.schema.properties.limit.description: Maximum rows to return; zero requests an unbounded result. → Maximum rows per page. `0` requests all matches, subject to a 5 MiB row-data ceiling; larger results return `400` with `TABLE_QUERY_RESULT_TOO_LARGE`. Use paged queries or an expo… 1 request/response media example set(s) now expose the owner's existing examples to the API renderer. Preserved: Compared operationId queryTableRows, POST /api/v2/tables/{tableId}/query, security and x-sim-operation with baseline; identifiers, route and credential schemes match. Recursive prose/default/example mappings retained in final-review-api-comparison.json; 7 distinct changed field mappings were inspected for this operation. Operation-level request/response structure, parameters, required fields, defaults and status declarations are identical after removing prose/examples; referenced component changes were reviewed separately. | +| `countTableRows` — `POST /api/v2/tables/{tableId}/query/count` | rewritten | Copy standardized; no operation-specific discrepancy found. | Verified improvement. Summary: Count Rows → Count rows; sentence case matches the editorial guide. responses.503.description: A required service is temporarily unavailable. `Retry-After` carries the seconds to wait; treat it as a floor and add jitter. The header is omitted when `error.details.code` is `A… → A required service is temporarily unavailable. When present, `Retry-After` gives the minimum seconds to wait; add jitter before retrying. Check operation-specific guidance before … 1 request/response media example set(s) now expose the owner's existing examples to the API renderer. Preserved: Compared operationId countTableRows, POST /api/v2/tables/{tableId}/query/count, security and x-sim-operation with baseline; identifiers, route and credential schemes match. Recursive prose/default/example mappings retained in final-review-api-comparison.json; 3 distinct changed field mappings were inspected for this operation. Operation-level request/response structure, parameters, required fields, defaults and status declarations are identical after removing prose/examples; referenced component changes were reviewed separately. | +| `listTableViews` — `GET /api/v2/tables/{tableId}/views` | rewritten | Copy standardized; no operation-specific discrepancy found. | Verified improvement. Summary: List Views → List views; sentence case matches the editorial guide. description: List saved table views, omitting references to removed columns. Returns the complete set in one page; `nextCursor` is always null. OAuth scope: `api:read`. → List saved table views, omitting references to removed columns. Returns one page; `nextCursor` is always null. OAuth scope: `api:read`. responses.200.content.application/json.schema.properties.nextCursor.description: Always `null` — this list has no `cursor` or `limit` param and returns its whole bounded set in one page. Present so the list can gain pages later without a shape change. → Always `null`. This list has no `cursor` or `limit` parameters; see the operation for inventory limits. responses.503.description: A required service is temporarily unavailable. `Retry-After` carries the seconds to wait; treat it as a floor and add jitter. The header is omitted when `error.details.code` is `A… → A required service is temporarily unavailable. When present, `Retry-After` gives the minimum seconds to wait; add jitter before retrying. Check operation-specific guidance before … Preserved: Compared operationId listTableViews, GET /api/v2/tables/{tableId}/views, security and x-sim-operation with baseline; identifiers, route and credential schemes match. Recursive prose/default/example mappings retained in final-review-api-comparison.json; 4 distinct changed field mappings were inspected for this operation. Operation-level request/response structure, parameters, required fields, defaults and status declarations are identical after removing prose/examples; referenced component changes were reviewed separately. | +| `createTableView` — `POST /api/v2/tables/{tableId}/views` | rewritten | Copy standardized; no operation-specific discrepancy found. | Verified improvement. Summary: Create View → Create view; sentence case matches the editorial guide. responses.503.description: A required service is temporarily unavailable. `Retry-After` carries the seconds to wait; treat it as a floor and add jitter. The header is omitted when `error.details.code` is `A… → A required service is temporarily unavailable. When present, `Retry-After` gives the minimum seconds to wait; add jitter before retrying. Check operation-specific guidance before … 1 request/response media example set(s) now expose the owner's existing examples to the API renderer. Preserved: Compared operationId createTableView, POST /api/v2/tables/{tableId}/views, security and x-sim-operation with baseline; identifiers, route and credential schemes match. Recursive prose/default/example mappings retained in final-review-api-comparison.json; 3 distinct changed field mappings were inspected for this operation. Operation-level request/response structure, parameters, required fields, defaults and status declarations are identical after removing prose/examples; referenced component changes were reviewed separately. | +| `getTableView` — `GET /api/v2/tables/{tableId}/views/{viewId}` | rewritten | Copy standardized; no operation-specific discrepancy found. | Verified improvement. Summary: Get View → Get view; sentence case matches the editorial guide. responses.503.description: A required service is temporarily unavailable. `Retry-After` carries the seconds to wait; treat it as a floor and add jitter. The header is omitted when `error.details.code` is `A… → A required service is temporarily unavailable. When present, `Retry-After` gives the minimum seconds to wait; add jitter before retrying. Check operation-specific guidance before … Preserved: Compared operationId getTableView, GET /api/v2/tables/{tableId}/views/{viewId}, security and x-sim-operation with baseline; identifiers, route and credential schemes match. Recursive prose/default/example mappings retained in final-review-api-comparison.json; 2 distinct changed field mappings were inspected for this operation. Operation-level request/response structure, parameters, required fields, defaults and status declarations are identical after removing prose/examples; referenced component changes were reviewed separately. | +| `updateTableView` — `PATCH /api/v2/tables/{tableId}/views/{viewId}` | rewritten | Reviewed; accurate details retained under the shared reference standard. | Verified improvement. Summary: Update View → Update view; sentence case matches the editorial guide. responses.503.description: A required service is temporarily unavailable. `Retry-After` carries the seconds to wait; treat it as a floor and add jitter. The header is omitted when `error.details.code` is `A… → A required service is temporarily unavailable. When present, `Retry-After` gives the minimum seconds to wait; add jitter before retrying. Check operation-specific guidance before … 1 request/response media example set(s) now expose the owner's existing examples to the API renderer. Preserved: Compared operationId updateTableView, PATCH /api/v2/tables/{tableId}/views/{viewId}, security and x-sim-operation with baseline; identifiers, route and credential schemes match. Recursive prose/default/example mappings retained in final-review-api-comparison.json; 3 distinct changed field mappings were inspected for this operation. Operation-level request/response structure, parameters, required fields, defaults and status declarations are identical after removing prose/examples; referenced component changes were reviewed separately. | +| `deleteTableView` — `DELETE /api/v2/tables/{tableId}/views/{viewId}` | rewritten | Copy standardized; no operation-specific discrepancy found. | Verified improvement. Summary: Delete View → Delete view; sentence case matches the editorial guide. responses.503.description: A required service is temporarily unavailable. `Retry-After` carries the seconds to wait; treat it as a floor and add jitter. The header is omitted when `error.details.code` is `A… → A required service is temporarily unavailable. When present, `Retry-After` gives the minimum seconds to wait; add jitter before retrying. Check operation-specific guidance before … Preserved: Compared operationId deleteTableView, DELETE /api/v2/tables/{tableId}/views/{viewId}, security and x-sim-operation with baseline; identifiers, route and credential schemes match. Recursive prose/default/example mappings retained in final-review-api-comparison.json; 2 distinct changed field mappings were inspected for this operation. Operation-level request/response structure, parameters, required fields, defaults and status declarations are identical after removing prose/examples; referenced component changes were reviewed separately. | +| `listTableWorkflowGroups` — `GET /api/v2/tables/{tableId}/groups` | rewritten | Copy standardized; no operation-specific discrepancy found. | Verified improvement. Summary: List Workflow Groups → List workflow groups; sentence case matches the editorial guide. description: List the workflow and enrichment groups that can be dispatched for a table. Returns the complete set in one page; `nextCursor` is always null. OAuth scope: `api:read`. → List the workflow and enrichment groups that can be dispatched for a table. Returns one page; `nextCursor` is always null. OAuth scope: `api:read`. responses.200.content.application/json.schema.properties.nextCursor.description: Always `null` — this list has no `cursor` or `limit` param and returns its whole bounded set in one page. Present so the list can gain pages later without a shape change. → Always `null`. This list has no `cursor` or `limit` parameters; see the operation for inventory limits. responses.503.description: A required service is temporarily unavailable. `Retry-After` carries the seconds to wait; treat it as a floor and add jitter. The header is omitted when `error.details.code` is `A… → A required service is temporarily unavailable. When present, `Retry-After` gives the minimum seconds to wait; add jitter before retrying. Check operation-specific guidance before … Preserved: Compared operationId listTableWorkflowGroups, GET /api/v2/tables/{tableId}/groups, security and x-sim-operation with baseline; identifiers, route and credential schemes match. Recursive prose/default/example mappings retained in final-review-api-comparison.json; 4 distinct changed field mappings were inspected for this operation. Operation-level request/response structure, parameters, required fields, defaults and status declarations are identical after removing prose/examples; referenced component changes were reviewed separately. | +| `addTableWorkflowGroup` — `POST /api/v2/tables/{tableId}/groups` | corrected | Use neutral document-wide error examples, or operation-specific examples. Preserve error.details.lock and actionable detail codes. These are illustrative examples, not a claim that every server response uses that message. | Verified improvement. Summary: Add Workflow Group → Add workflow group; sentence case matches the editorial guide. responses.503.description: A required service is temporarily unavailable. `Retry-After` carries the seconds to wait; treat it as a floor and add jitter. The header is omitted when `error.details.code` is `A… → A required service is temporarily unavailable. When present, `Retry-After` gives the minimum seconds to wait; add jitter before retrying. Check operation-specific guidance before … 1 request/response media example set(s) now expose the owner's existing examples to the API renderer. Preserved: Compared operationId addTableWorkflowGroup, POST /api/v2/tables/{tableId}/groups, security and x-sim-operation with baseline; identifiers, route and credential schemes match. Recursive prose/default/example mappings retained in final-review-api-comparison.json; 4 distinct changed field mappings were inspected for this operation. Operation-level request/response structure, parameters, required fields, defaults and status declarations are identical after removing prose/examples; referenced component changes were reviewed separately. | +| `updateTableWorkflowGroup` — `PATCH /api/v2/tables/{tableId}/groups` | corrected | Use neutral document-wide error examples, or operation-specific examples. Preserve error.details.lock and actionable detail codes. These are illustrative examples, not a claim that every server response uses that message. | Verified improvement. Summary: Update Workflow Group → Update workflow group; sentence case matches the editorial guide. responses.503.description: A required service is temporarily unavailable. `Retry-After` carries the seconds to wait; treat it as a floor and add jitter. The header is omitted when `error.details.code` is `A… → A required service is temporarily unavailable. When present, `Retry-After` gives the minimum seconds to wait; add jitter before retrying. Check operation-specific guidance before … 1 request/response media example set(s) now expose the owner's existing examples to the API renderer. Preserved: Compared operationId updateTableWorkflowGroup, PATCH /api/v2/tables/{tableId}/groups, security and x-sim-operation with baseline; identifiers, route and credential schemes match. Recursive prose/default/example mappings retained in final-review-api-comparison.json; 5 distinct changed field mappings were inspected for this operation. Operation-level request/response structure, parameters, required fields, defaults and status declarations are identical after removing prose/examples; referenced component changes were reviewed separately. | +| `deleteTableWorkflowGroup` — `DELETE /api/v2/tables/{tableId}/groups` | corrected | Use neutral document-wide error examples, or operation-specific examples. Preserve error.details.lock and actionable detail codes. These are illustrative examples, not a claim that every server response uses that message. | Verified improvement. Summary: Delete Workflow Group → Delete workflow group; sentence case matches the editorial guide. responses.503.description: A required service is temporarily unavailable. `Retry-After` carries the seconds to wait; treat it as a floor and add jitter. The header is omitted when `error.details.code` is `A… → A required service is temporarily unavailable. When present, `Retry-After` gives the minimum seconds to wait; add jitter before retrying. Check operation-specific guidance before … 1 request/response media example set(s) now expose the owner's existing examples to the API renderer. Preserved: Compared operationId deleteTableWorkflowGroup, DELETE /api/v2/tables/{tableId}/groups, security and x-sim-operation with baseline; identifiers, route and credential schemes match. Recursive prose/default/example mappings retained in final-review-api-comparison.json; 4 distinct changed field mappings were inspected for this operation. Operation-level request/response structure, parameters, required fields, defaults and status declarations are identical after removing prose/examples; referenced component changes were reviewed separately. | +| `createTableDispatch` — `POST /api/v2/tables/{tableId}/dispatches` | rewritten | Copy standardized; no operation-specific discrepancy found. | Verified improvement. Summary: Create Run Dispatch → Create run dispatch; sentence case matches the editorial guide. responses.503.description: A required service is temporarily unavailable. `Retry-After` carries the seconds to wait; treat it as a floor and add jitter. The header is omitted when `error.details.code` is `A… → A required service is temporarily unavailable. When present, `Retry-After` gives the minimum seconds to wait; add jitter before retrying. Check operation-specific guidance before … 1 request/response media example set(s) now expose the owner's existing examples to the API renderer. Preserved: Compared operationId createTableDispatch, POST /api/v2/tables/{tableId}/dispatches, security and x-sim-operation with baseline; identifiers, route and credential schemes match. Recursive prose/default/example mappings retained in final-review-api-comparison.json; 4 distinct changed field mappings were inspected for this operation. Operation-level request/response structure, parameters, required fields, defaults and status declarations are identical after removing prose/examples; referenced component changes were reviewed separately. | +| `listTableDispatches` — `GET /api/v2/tables/{tableId}/dispatches` | rewritten | Copy standardized; no operation-specific discrepancy found. | Verified improvement. Summary: List Run Dispatches → List run dispatches; sentence case matches the editorial guide. responses.200.content.application/json.schema.properties.nextCursor.description: Always `null` — this list has no `cursor` or `limit` param and returns its whole bounded set in one page. Present so the list can gain pages later without a shape change. → Always `null`. This list has no `cursor` or `limit` parameters; see the operation for inventory limits. responses.503.description: A required service is temporarily unavailable. `Retry-After` carries the seconds to wait; treat it as a floor and add jitter. The header is omitted when `error.details.code` is `A… → A required service is temporarily unavailable. When present, `Retry-After` gives the minimum seconds to wait; add jitter before retrying. Check operation-specific guidance before … Preserved: Compared operationId listTableDispatches, GET /api/v2/tables/{tableId}/dispatches, security and x-sim-operation with baseline; identifiers, route and credential schemes match. Recursive prose/default/example mappings retained in final-review-api-comparison.json; 3 distinct changed field mappings were inspected for this operation. Operation-level request/response structure, parameters, required fields, defaults and status declarations are identical after removing prose/examples; referenced component changes were reviewed separately. | +| `runRowEnrichment` — `POST /api/v2/tables/{tableId}/rows/{rowId}/enrichment/{groupId}` | rewritten | Copy standardized; no operation-specific discrepancy found. | Verified improvement. Summary: Run Enrichment For One Row → Run enrichment for one row; sentence case matches the editorial guide. responses.503.description: A required service is temporarily unavailable. `Retry-After` carries the seconds to wait; treat it as a floor and add jitter. The header is omitted when `error.details.code` is `A… → A required service is temporarily unavailable. When present, `Retry-After` gives the minimum seconds to wait; add jitter before retrying. Check operation-specific guidance before … 1 request/response media example set(s) now expose the owner's existing examples to the API renderer. Preserved: Compared operationId runRowEnrichment, POST /api/v2/tables/{tableId}/rows/{rowId}/enrichment/{groupId}, security and x-sim-operation with baseline; identifiers, route and credential schemes match. Recursive prose/default/example mappings retained in final-review-api-comparison.json; 4 distinct changed field mappings were inspected for this operation. Operation-level request/response structure, parameters, required fields, defaults and status declarations are identical after removing prose/examples; referenced component changes were reviewed separately. | +| `getRowEnrichment` — `GET /api/v2/tables/{tableId}/rows/{rowId}/enrichment/{groupId}` | corrected | Add PayloadTooLarge to these operations and explain the 2 MiB run-state ceiling on includeRunState / row-group detail. Replace internal "sidecar/blockErrors are unbounded" rationale with the user consequence and retry action. | Verified improvement. Summary: Get Row Group Run → Get row group run; sentence case matches the editorial guide. description: Read a workflow or enrichment group’s outcome for one row: `runState` (as exposed by `includeRunState`), output cells keyed by column name, and enrichment providers in cascade ord… → Read one row’s workflow or enrichment-group outcome: run state, output cells keyed by column name, and providers in cascade order with status, hosted-key cost, duration, and the m… responses.503.description: A required service is temporarily unavailable. `Retry-After` carries the seconds to wait; treat it as a floor and add jitter. The header is omitted when `error.details.code` is `A… → A required service is temporarily unavailable. When present, `Retry-After` gives the minimum seconds to wait; add jitter before retrying. Check operation-specific guidance before … 1 request/response media example set(s) now expose the owner's existing examples to the API renderer. Preserved: Compared operationId getRowEnrichment, GET /api/v2/tables/{tableId}/rows/{rowId}/enrichment/{groupId}, security and x-sim-operation with baseline; identifiers, route and credential schemes match. Recursive prose/default/example mappings retained in final-review-api-comparison.json; 16 distinct changed field mappings were inspected for this operation. Only newly documented 413 response differs in operation structure; the existing 2 MiB run-state refusal is documented without route or schema behavior changes. | +| `searchTableRows` — `POST /api/v2/tables/{tableId}/rows/search` | rewritten | Copy standardized; no operation-specific discrepancy found. | Verified improvement. Summary: Search Rows → Search rows; sentence case matches the editorial guide. responses.503.description: A required service is temporarily unavailable. `Retry-After` carries the seconds to wait; treat it as a floor and add jitter. The header is omitted when `error.details.code` is `A… → A required service is temporarily unavailable. When present, `Retry-After` gives the minimum seconds to wait; add jitter before retrying. Check operation-specific guidance before … 1 request/response media example set(s) now expose the owner's existing examples to the API renderer. Preserved: Compared operationId searchTableRows, POST /api/v2/tables/{tableId}/rows/search, security and x-sim-operation with baseline; identifiers, route and credential schemes match. Recursive prose/default/example mappings retained in final-review-api-comparison.json; 4 distinct changed field mappings were inspected for this operation. Operation-level request/response structure, parameters, required fields, defaults and status declarations are identical after removing prose/examples; referenced component changes were reviewed separately. | +| `createTableImport` — `POST /api/v2/tables/imports` | corrected | Use neutral document-wide error examples, or operation-specific examples. Preserve error.details.lock and actionable detail codes. These are illustrative examples, not a claim that every server response uses that message. | Verified improvement. Summary: Create Table Import → Create table import; sentence case matches the editorial guide. responses.503.description: A required service is temporarily unavailable. `Retry-After` carries the seconds to wait; treat it as a floor and add jitter. The header is omitted when `error.details.code` is `A… → A required service is temporarily unavailable. When present, `Retry-After` gives the minimum seconds to wait; add jitter before retrying. Check operation-specific guidance before … 1 request/response media example set(s) now expose the owner's existing examples to the API renderer. Preserved: Compared operationId createTableImport, POST /api/v2/tables/imports, security and x-sim-operation with baseline; identifiers, route and credential schemes match. Recursive prose/default/example mappings retained in final-review-api-comparison.json; 5 distinct changed field mappings were inspected for this operation. Operation-level request/response structure, parameters, required fields, defaults and status declarations are identical after removing prose/examples; referenced component changes were reviewed separately. | +| `getTableImport` — `GET /api/v2/tables/imports/{importId}` | rewritten | Copy standardized; no operation-specific discrepancy found. | Verified improvement. Summary: Get Table Import → Get table import; sentence case matches the editorial guide. responses.503.description: A required service is temporarily unavailable. `Retry-After` carries the seconds to wait; treat it as a floor and add jitter. The header is omitted when `error.details.code` is `A… → A required service is temporarily unavailable. When present, `Retry-After` gives the minimum seconds to wait; add jitter before retrying. Check operation-specific guidance before … Preserved: Compared operationId getTableImport, GET /api/v2/tables/imports/{importId}, security and x-sim-operation with baseline; identifiers, route and credential schemes match. Recursive prose/default/example mappings retained in final-review-api-comparison.json; 2 distinct changed field mappings were inspected for this operation. Operation-level request/response structure, parameters, required fields, defaults and status declarations are identical after removing prose/examples; referenced component changes were reviewed separately. | +| `cancelTableImport` — `DELETE /api/v2/tables/imports/{importId}` | rewritten | Copy standardized; no operation-specific discrepancy found. | Verified improvement. Summary: Cancel Table Import → Cancel table import; sentence case matches the editorial guide. responses.503.description: A required service is temporarily unavailable. `Retry-After` carries the seconds to wait; treat it as a floor and add jitter. The header is omitted when `error.details.code` is `A… → A required service is temporarily unavailable. When present, `Retry-After` gives the minimum seconds to wait; add jitter before retrying. Check operation-specific guidance before … Preserved: Compared operationId cancelTableImport, DELETE /api/v2/tables/imports/{importId}, security and x-sim-operation with baseline; identifiers, route and credential schemes match. Recursive prose/default/example mappings retained in final-review-api-comparison.json; 3 distinct changed field mappings were inspected for this operation. Operation-level request/response structure, parameters, required fields, defaults and status declarations are identical after removing prose/examples; referenced component changes were reviewed separately. | +| `createTableImportPartUrls` — `POST /api/v2/tables/imports/{importId}/parts` | rewritten | Copy standardized; no operation-specific discrepancy found. | Verified improvement. Summary: Create Table Import Part URLs → Create table import part URLs; sentence case matches the editorial guide. responses.503.description: A required service is temporarily unavailable. `Retry-After` carries the seconds to wait; treat it as a floor and add jitter. The header is omitted when `error.details.code` is `A… → A required service is temporarily unavailable. When present, `Retry-After` gives the minimum seconds to wait; add jitter before retrying. Check operation-specific guidance before … 1 request/response media example set(s) now expose the owner's existing examples to the API renderer. Preserved: Compared operationId createTableImportPartUrls, POST /api/v2/tables/imports/{importId}/parts, security and x-sim-operation with baseline; identifiers, route and credential schemes match. Recursive prose/default/example mappings retained in final-review-api-comparison.json; 4 distinct changed field mappings were inspected for this operation. Operation-level request/response structure, parameters, required fields, defaults and status declarations are identical after removing prose/examples; referenced component changes were reviewed separately. | +| `completeTableImportUpload` — `POST /api/v2/tables/imports/{importId}/complete` | corrected | Use neutral document-wide error examples, or operation-specific examples. Preserve error.details.lock and actionable detail codes. These are illustrative examples, not a claim that every server response uses that message. | Verified improvement. Summary: Complete Table Import Upload → Complete table import upload; sentence case matches the editorial guide. responses.503.description: A required service is temporarily unavailable. `Retry-After` carries the seconds to wait; treat it as a floor and add jitter. The header is omitted when `error.details.code` is `A… → A required service is temporarily unavailable. When present, `Retry-After` gives the minimum seconds to wait; add jitter before retrying. Check operation-specific guidance before … Preserved: Compared operationId completeTableImportUpload, POST /api/v2/tables/imports/{importId}/complete, security and x-sim-operation with baseline; identifiers, route and credential schemes match. Recursive prose/default/example mappings retained in final-review-api-comparison.json; 4 distinct changed field mappings were inspected for this operation. Operation-level request/response structure, parameters, required fields, defaults and status declarations are identical after removing prose/examples; referenced component changes were reviewed separately. | +| `createTableExport` — `POST /api/v2/tables/{tableId}/exports` | rewritten | Copy standardized; no operation-specific discrepancy found. | Verified improvement. Summary: Create Table Export → Create table export; sentence case matches the editorial guide. responses.503.description: A required service is temporarily unavailable. `Retry-After` carries the seconds to wait; treat it as a floor and add jitter. The header is omitted when `error.details.code` is `A… → A required service is temporarily unavailable. When present, `Retry-After` gives the minimum seconds to wait; add jitter before retrying. Check operation-specific guidance before … 1 request/response media example set(s) now expose the owner's existing examples to the API renderer. Preserved: Compared operationId createTableExport, POST /api/v2/tables/{tableId}/exports, security and x-sim-operation with baseline; identifiers, route and credential schemes match. Recursive prose/default/example mappings retained in final-review-api-comparison.json; 4 distinct changed field mappings were inspected for this operation. Operation-level request/response structure, parameters, required fields, defaults and status declarations are identical after removing prose/examples; referenced component changes were reviewed separately. | +| `getTableExport` — `GET /api/v2/tables/{tableId}/exports/{exportId}` | rewritten | Copy standardized; no operation-specific discrepancy found. | Verified improvement. Summary: Get Table Export → Get table export; sentence case matches the editorial guide. responses.503.description: A required service is temporarily unavailable. `Retry-After` carries the seconds to wait; treat it as a floor and add jitter. The header is omitted when `error.details.code` is `A… → A required service is temporarily unavailable. When present, `Retry-After` gives the minimum seconds to wait; add jitter before retrying. Check operation-specific guidance before … Preserved: Compared operationId getTableExport, GET /api/v2/tables/{tableId}/exports/{exportId}, security and x-sim-operation with baseline; identifiers, route and credential schemes match. Recursive prose/default/example mappings retained in final-review-api-comparison.json; 2 distinct changed field mappings were inspected for this operation. Operation-level request/response structure, parameters, required fields, defaults and status declarations are identical after removing prose/examples; referenced component changes were reviewed separately. | +| `cancelTableExport` — `DELETE /api/v2/tables/{tableId}/exports/{exportId}` | rewritten | Copy standardized; no operation-specific discrepancy found. | Verified improvement. Summary: Cancel Table Export → Cancel table export; sentence case matches the editorial guide. responses.503.description: A required service is temporarily unavailable. `Retry-After` carries the seconds to wait; treat it as a floor and add jitter. The header is omitted when `error.details.code` is `A… → A required service is temporarily unavailable. When present, `Retry-After` gives the minimum seconds to wait; add jitter before retrying. Check operation-specific guidance before … Preserved: Compared operationId cancelTableExport, DELETE /api/v2/tables/{tableId}/exports/{exportId}, security and x-sim-operation with baseline; identifiers, route and credential schemes match. Recursive prose/default/example mappings retained in final-review-api-comparison.json; 3 distinct changed field mappings were inspected for this operation. Operation-level request/response structure, parameters, required fields, defaults and status declarations are identical after removing prose/examples; referenced component changes were reviewed separately. | +| `downloadTableExport` — `GET /api/v2/tables/{tableId}/exports/{exportId}/download` | rewritten | Copy standardized; no operation-specific discrepancy found. | Verified improvement. Summary: Download Table Export → Download table export; sentence case matches the editorial guide. responses.503.description: A required service is temporarily unavailable. `Retry-After` carries the seconds to wait; treat it as a floor and add jitter. The header is omitted when `error.details.code` is `A… → A required service is temporarily unavailable. When present, `Retry-After` gives the minimum seconds to wait; add jitter before retrying. Check operation-specific guidance before … Preserved: Compared operationId downloadTableExport, GET /api/v2/tables/{tableId}/exports/{exportId}/download, security and x-sim-operation with baseline; identifiers, route and credential schemes match. Recursive prose/default/example mappings retained in final-review-api-comparison.json; 3 distinct changed field mappings were inspected for this operation. Operation-level request/response structure, parameters, required fields, defaults and status declarations are identical after removing prose/examples; referenced component changes were reviewed separately. | +| `cancelTableRuns` — `POST /api/v2/tables/{tableId}/cancel-runs` | corrected | "Workspace scope, row or all-table cancellation, and optional row predicate or exclusions." Do not advertise producer-group selection. | Verified improvement. Summary: Cancel Column Runs → Cancel column runs; sentence case matches the editorial guide. requestBody.content.application/json.schema.description: Workspace scope, cancellation scope, and optional predicate or producer groups. → Workspace scope, row or all-table cancellation, and optional row predicate or exclusions. requestBody.description: Workspace scope, cancellation scope, and optional predicate or producer groups. → Workspace scope, row or all-table cancellation, and optional row predicate or exclusions. responses.503.description: A required service is temporarily unavailable. `Retry-After` carries the seconds to wait; treat it as a floor and add jitter. The header is omitted when `error.details.code` is `A… → A required service is temporarily unavailable. When present, `Retry-After` gives the minimum seconds to wait; add jitter before retrying. Check operation-specific guidance before … 1 request/response media example set(s) now expose the owner's existing examples to the API renderer. Preserved: Compared operationId cancelTableRuns, POST /api/v2/tables/{tableId}/cancel-runs, security and x-sim-operation with baseline; identifiers, route and credential schemes match. Recursive prose/default/example mappings retained in final-review-api-comparison.json; 5 distinct changed field mappings were inspected for this operation. Operation-level request/response structure, parameters, required fields, defaults and status declarations are identical after removing prose/examples; referenced component changes were reviewed separately. | +| `listTablesFolders` — `GET /api/v2/tables/folders` | rewritten | Copy standardized; no operation-specific discrepancy found. | Verified improvement. Summary: List Folders → List folders; sentence case matches the editorial guide. description: List table folders, optionally limiting results to direct children of a parent path. Returns the complete set in one page; `nextCursor` is always null. OAuth scope: `api:read`. → List table folders, optionally limiting results to direct children of a parent path. Returns one page; `nextCursor` is always null. OAuth scope: `api:read`. parameters[3].description: Field used to sort the result. Sorting by `name` is case-sensitive and follows the storage collation, so do not rely on a case-insensitive order. → Field used to sort the result. Do not rely on case-insensitive ordering when sorting by `name`. parameters[3].schema.description: Field used to sort the result. Sorting by `name` is case-sensitive and follows the storage collation, so do not rely on a case-insensitive order. → Field used to sort the result. Do not rely on case-insensitive ordering when sorting by `name`. Preserved: Compared operationId listTablesFolders, GET /api/v2/tables/folders, security and x-sim-operation with baseline; identifiers, route and credential schemes match. Recursive prose/default/example mappings retained in final-review-api-comparison.json; 6 distinct changed field mappings were inspected for this operation. Operation-level request/response structure, parameters, required fields, defaults and status declarations are identical after removing prose/examples; referenced component changes were reviewed separately. | +| `createTablesFolder` — `POST /api/v2/tables/folders` | rewritten | Copy standardized; no operation-specific discrepancy found. | Verified improvement. Summary: Create Folder → Create folder; sentence case matches the editorial guide. responses.503.description: A required service is temporarily unavailable. `Retry-After` carries the seconds to wait; treat it as a floor and add jitter. The header is omitted when `error.details.code` is `A… → A required service is temporarily unavailable. When present, `Retry-After` gives the minimum seconds to wait; add jitter before retrying. Check operation-specific guidance before … 1 request/response media example set(s) now expose the owner's existing examples to the API renderer. Preserved: Compared operationId createTablesFolder, POST /api/v2/tables/folders, security and x-sim-operation with baseline; identifiers, route and credential schemes match. Recursive prose/default/example mappings retained in final-review-api-comparison.json; 4 distinct changed field mappings were inspected for this operation. Operation-level request/response structure, parameters, required fields, defaults and status declarations are identical after removing prose/examples; referenced component changes were reviewed separately. | +| `relocateTablesFolder` — `PATCH /api/v2/tables/folders` | rewritten | Reviewed; accurate details retained under the shared reference standard. | Verified improvement. Summary: Rename or Move Folder → Rename or move folder; sentence case matches the editorial guide. responses.503.description: A required service is temporarily unavailable. `Retry-After` carries the seconds to wait; treat it as a floor and add jitter. The header is omitted when `error.details.code` is `A… → A required service is temporarily unavailable. When present, `Retry-After` gives the minimum seconds to wait; add jitter before retrying. Check operation-specific guidance before … 1 request/response media example set(s) now expose the owner's existing examples to the API renderer. Preserved: Compared operationId relocateTablesFolder, PATCH /api/v2/tables/folders, security and x-sim-operation with baseline; identifiers, route and credential schemes match. Recursive prose/default/example mappings retained in final-review-api-comparison.json; 4 distinct changed field mappings were inspected for this operation. Operation-level request/response structure, parameters, required fields, defaults and status declarations are identical after removing prose/examples; referenced component changes were reviewed separately. | +| `deleteTablesFolder` — `DELETE /api/v2/tables/folders` | corrected | Use neutral document-wide error examples, or operation-specific examples. Preserve error.details.lock and actionable detail codes. These are illustrative examples, not a claim that every server response uses that message. | Verified improvement. Summary: Delete Folder → Delete folder; sentence case matches the editorial guide. parameters[2].description: Delete the folder's nested files and folders too. An empty folder deletes either way; a non-empty one needs this. The listed spellings are the whole accepted vocabulary and are ca… → Delete the folder's contents and nested folders too. Required for a non-empty folder. Only the listed case-sensitive spellings are accepted. parameters[2].schema.description: Delete the folder's nested files and folders too. An empty folder deletes either way; a non-empty one needs this. The listed spellings are the whole accepted vocabulary and are ca… → Delete the folder's contents and nested folders too. Required for a non-empty folder. Only the listed case-sensitive spellings are accepted. responses.503.description: A required service is temporarily unavailable. `Retry-After` carries the seconds to wait; treat it as a floor and add jitter. The header is omitted when `error.details.code` is `A… → A required service is temporarily unavailable. When present, `Retry-After` gives the minimum seconds to wait; add jitter before retrying. Check operation-specific guidance before … Preserved: Compared operationId deleteTablesFolder, DELETE /api/v2/tables/folders, security and x-sim-operation with baseline; identifiers, route and credential schemes match. Recursive prose/default/example mappings retained in final-review-api-comparison.json; 7 distinct changed field mappings were inspected for this operation. Operation-level request/response structure, parameters, required fields, defaults and status declarations are identical after removing prose/examples; referenced component changes were reviewed separately. | +| `restoreTablesFolder` — `POST /api/v2/tables/folders/restore` | rewritten | Copy standardized; no operation-specific discrepancy found. | Verified improvement. Summary: Restore Folder → Restore folder; sentence case matches the editorial guide. responses.503.description: A required service is temporarily unavailable. `Retry-After` carries the seconds to wait; treat it as a floor and add jitter. The header is omitted when `error.details.code` is `A… → A required service is temporarily unavailable. When present, `Retry-After` gives the minimum seconds to wait; add jitter before retrying. Check operation-specific guidance before … 1 request/response media example set(s) now expose the owner's existing examples to the API renderer. Preserved: Compared operationId restoreTablesFolder, POST /api/v2/tables/folders/restore, security and x-sim-operation with baseline; identifiers, route and credential schemes match. Recursive prose/default/example mappings retained in final-review-api-comparison.json; 5 distinct changed field mappings were inspected for this operation. Operation-level request/response structure, parameters, required fields, defaults and status declarations are identical after removing prose/examples; referenced component changes were reviewed separately. | +| `restoreTable` — `POST /api/v2/tables/{tableId}/restore` | rewritten | Copy standardized; no operation-specific discrepancy found. | Verified improvement. Summary: Restore Table → Restore table; sentence case matches the editorial guide. responses.503.description: A required service is temporarily unavailable. `Retry-After` carries the seconds to wait; treat it as a floor and add jitter. The header is omitted when `error.details.code` is `A… → A required service is temporarily unavailable. When present, `Retry-After` gives the minimum seconds to wait; add jitter before retrying. Check operation-specific guidance before … 1 request/response media example set(s) now expose the owner's existing examples to the API renderer. Preserved: Compared operationId restoreTable, POST /api/v2/tables/{tableId}/restore, security and x-sim-operation with baseline; identifiers, route and credential schemes match. Recursive prose/default/example mappings retained in final-review-api-comparison.json; 5 distinct changed field mappings were inspected for this operation. Operation-level request/response structure, parameters, required fields, defaults and status declarations are identical after removing prose/examples; referenced component changes were reviewed separately. | +| `bulkUpdateTableRows` — `POST /api/v2/tables/{tableId}/rows/bulk-update` | corrected | Use neutral document-wide error examples, or operation-specific examples. Preserve error.details.lock and actionable detail codes. These are illustrative examples, not a claim that every server response uses that message. | Verified improvement. Summary: Bulk Update Rows → Bulk update rows; sentence case matches the editorial guide. responses.503.description: A required service is temporarily unavailable. `Retry-After` carries the seconds to wait; treat it as a floor and add jitter. The header is omitted when `error.details.code` is `A… → A required service is temporarily unavailable. When present, `Retry-After` gives the minimum seconds to wait; add jitter before retrying. Check operation-specific guidance before … 1 request/response media example set(s) now expose the owner's existing examples to the API renderer. Preserved: Compared operationId bulkUpdateTableRows, POST /api/v2/tables/{tableId}/rows/bulk-update, security and x-sim-operation with baseline; identifiers, route and credential schemes match. Recursive prose/default/example mappings retained in final-review-api-comparison.json; 5 distinct changed field mappings were inspected for this operation. Operation-level request/response structure, parameters, required fields, defaults and status declarations are identical after removing prose/examples; referenced component changes were reviewed separately. | +| `getTableDispatch` — `GET /api/v2/tables/{tableId}/dispatches/{dispatchId}` | rewritten | Copy standardized; no operation-specific discrepancy found. | Verified improvement. Summary: Get Run Dispatch → Get run dispatch; sentence case matches the editorial guide. responses.503.description: A required service is temporarily unavailable. `Retry-After` carries the seconds to wait; treat it as a floor and add jitter. The header is omitted when `error.details.code` is `A… → A required service is temporarily unavailable. When present, `Retry-After` gives the minimum seconds to wait; add jitter before retrying. Check operation-specific guidance before … Preserved: Compared operationId getTableDispatch, GET /api/v2/tables/{tableId}/dispatches/{dispatchId}, security and x-sim-operation with baseline; identifiers, route and credential schemes match. Recursive prose/default/example mappings retained in final-review-api-comparison.json; 2 distinct changed field mappings were inspected for this operation. Operation-level request/response structure, parameters, required fields, defaults and status declarations are identical after removing prose/examples; referenced component changes were reviewed separately. | +| `cancelTableDispatch` — `DELETE /api/v2/tables/{tableId}/dispatches/{dispatchId}` | rewritten | Copy standardized; no operation-specific discrepancy found. | Verified improvement. Summary: Cancel Run Dispatch → Cancel run dispatch; sentence case matches the editorial guide. responses.503.description: A required service is temporarily unavailable. `Retry-After` carries the seconds to wait; treat it as a floor and add jitter. The header is omitted when `error.details.code` is `A… → A required service is temporarily unavailable. When present, `Retry-After` gives the minimum seconds to wait; add jitter before retrying. Check operation-specific guidance before … Preserved: Compared operationId cancelTableDispatch, DELETE /api/v2/tables/{tableId}/dispatches/{dispatchId}, security and x-sim-operation with baseline; identifiers, route and credential schemes match. Recursive prose/default/example mappings retained in final-review-api-comparison.json; 3 distinct changed field mappings were inspected for this operation. Operation-level request/response structure, parameters, required fields, defaults and status declarations are identical after removing prose/examples; referenced component changes were reviewed separately. | +| `moveTables` — `POST /api/v2/tables/move` | rewritten | Reviewed; accurate details retained under the shared reference standard. | Verified improvement. Summary: Move Tables and Folders → Move tables and folders; sentence case matches the editorial guide. responses.503.description: A required service is temporarily unavailable. `Retry-After` carries the seconds to wait; treat it as a floor and add jitter. The header is omitted when `error.details.code` is `A… → A required service is temporarily unavailable. When present, `Retry-After` gives the minimum seconds to wait; add jitter before retrying. Check operation-specific guidance before … 1 request/response media example set(s) now expose the owner's existing examples to the API renderer. Preserved: Compared operationId moveTables, POST /api/v2/tables/move, security and x-sim-operation with baseline; identifiers, route and credential schemes match. Recursive prose/default/example mappings retained in final-review-api-comparison.json; 3 distinct changed field mappings were inspected for this operation. Operation-level request/response structure, parameters, required fields, defaults and status declarations are identical after removing prose/examples; referenced component changes were reviewed separately. | +| `bulkDeleteTables` — `POST /api/v2/tables/bulk-delete` | corrected | Use neutral document-wide error examples, or operation-specific examples. Preserve error.details.lock and actionable detail codes. These are illustrative examples, not a claim that every server response uses that message. | Verified improvement. Summary: Bulk Delete Tables and Folders → Bulk delete tables and folders; sentence case matches the editorial guide. responses.503.description: A required service is temporarily unavailable. `Retry-After` carries the seconds to wait; treat it as a floor and add jitter. The header is omitted when `error.details.code` is `A… → A required service is temporarily unavailable. When present, `Retry-After` gives the minimum seconds to wait; add jitter before retrying. Check operation-specific guidance before … 2 request/response media example set(s) now expose the owner's existing examples to the API renderer. Preserved: Compared operationId bulkDeleteTables, POST /api/v2/tables/bulk-delete, security and x-sim-operation with baseline; identifiers, route and credential schemes match. Recursive prose/default/example mappings retained in final-review-api-comparison.json; 6 distinct changed field mappings were inspected for this operation. Operation-level request/response structure, parameters, required fields, defaults and status declarations are identical after removing prose/examples; referenced component changes were reviewed separately. | + +### API workflow operations (59) + +| Page or operation | Result | Changes | Final comparison and preservation | +| --- | --- | --- | --- | +| `listWorkflows` — `GET /api/v2/workflows` | rewritten | Copy standardized; no operation-specific discrepancy found. | Verified improvement. Summary: List Workflows → List workflows; sentence case matches the editorial guide. description: List active workflows in a workspace. Use `scope=archived` to find workflows available for restoration. Supports folder and deployment filters, search, sorting, and cursor paginat… → List active workflows in a workspace with workspace read access. Use `scope=archived` to find workflows available for restoration. Filter by folder, deployment, or name; sort and … parameters[7].description: Field used to sort the result. Sorting by `name` is case-sensitive and follows the storage collation, so do not rely on a case-insensitive order. → Field used to sort the result. Do not rely on case-insensitive ordering when sorting by `name`. parameters[7].schema.description: Field used to sort the result. Sorting by `name` is case-sensitive and follows the storage collation, so do not rely on a case-insensitive order. → Field used to sort the result. Do not rely on case-insensitive ordering when sorting by `name`. 1 request/response media example set(s) now expose the owner's existing examples to the API renderer. Preserved: Compared operationId listWorkflows, GET /api/v2/workflows, security and x-sim-operation with baseline; identifiers, route and credential schemes match. Recursive prose/default/example mappings retained in final-review-api-comparison.json; 8 distinct changed field mappings were inspected for this operation. Operation-level request/response structure, parameters, required fields, defaults and status declarations are identical after removing prose/examples; referenced component changes were reviewed separately. | +| `createWorkflowV2` — `POST /api/v2/workflows` | rewritten | Copy standardized; no operation-specific discrepancy found. | Verified improvement. Summary: Create Workflow → Create workflow; sentence case matches the editorial guide. description: Create a workflow at the workspace root or in a workflow folder. The response includes seeded blocks and their IDs for attaching edges. Workspace folder trees exceeding 10,000 fol… → Create an undeployed workflow at the workspace root or in a workflow folder. Requires workspace write access. The response includes the seeded start block and its ID for connectin… responses.503.description: A required service is temporarily unavailable. `Retry-After` carries the seconds to wait; treat it as a floor and add jitter. The header is omitted when `error.details.code` is `A… → A required service is temporarily unavailable. When present, `Retry-After` gives the minimum seconds to wait; add jitter before retrying. Check operation-specific guidance before … 2 request/response media example set(s) now expose the owner's existing examples to the API renderer. Preserved: Compared operationId createWorkflowV2, POST /api/v2/workflows, security and x-sim-operation with baseline; identifiers, route and credential schemes match. Recursive prose/default/example mappings retained in final-review-api-comparison.json; 7 distinct changed field mappings were inspected for this operation. Operation-level request/response structure, parameters, required fields, defaults and status declarations are identical after removing prose/examples; referenced component changes were reviewed separately. | +| `getWorkflowState` — `GET /api/v2/workflows/{workflowId}/state` | corrected | Kept undeployed-copy, same-workflow source state, trigger shutdown, and pending-rollback consequences close to their actions. | Verified improvement. Summary: Get Workflow State → Get workflow state; sentence case matches the editorial guide. description: Get the editable draft graph, including blocks, edges, loop and parallel containers, and variables. Use this state with Replace Workflow State to preserve workspace bindings; Expo… → Read the saved editable draft, including blocks, edges, loop and parallel containers, and variables. Requires workspace read access. Configured values are included; use this state… responses.503.description: A required service is temporarily unavailable. `Retry-After` carries the seconds to wait; treat it as a floor and add jitter. The header is omitted when `error.details.code` is `A… → A required service is temporarily unavailable. When present, `Retry-After` gives the minimum seconds to wait; add jitter before retrying. Check operation-specific guidance before … 1 request/response media example set(s) now expose the owner's existing examples to the API renderer. Preserved: Compared operationId getWorkflowState, GET /api/v2/workflows/{workflowId}/state, security and x-sim-operation with baseline; identifiers, route and credential schemes match. Recursive prose/default/example mappings retained in final-review-api-comparison.json; 4 distinct changed field mappings were inspected for this operation. Operation-level request/response structure, parameters, required fields, defaults and status declarations are identical after removing prose/examples; referenced component changes were reviewed separately. | +| `replaceWorkflowState` — `PUT /api/v2/workflows/{workflowId}/state` | rewritten | Copy standardized; no operation-specific discrepancy found. | Verified improvement. Summary: Replace Workflow State → Replace workflow state; sentence case matches the editorial guide. description: Atomically replace the draft graph; row-locked concurrent writes are last-write-wins. Block, edge, or subflow IDs owned by another workflow return `409`. Deployments remain immuta… → Replace the draft graph in one write. Requires workspace write access. Concurrent row-locked writes are last-write-wins; IDs owned by another workflow return `409`. Deployments, s… responses.503.description: A required service is temporarily unavailable. `Retry-After` carries the seconds to wait; treat it as a floor and add jitter. The header is omitted when `error.details.code` is `A… → A required service is temporarily unavailable. When present, `Retry-After` gives the minimum seconds to wait; add jitter before retrying. Check operation-specific guidance before … 2 request/response media example set(s) now expose the owner's existing examples to the API renderer. Preserved: Compared operationId replaceWorkflowState, PUT /api/v2/workflows/{workflowId}/state, security and x-sim-operation with baseline; identifiers, route and credential schemes match. Recursive prose/default/example mappings retained in final-review-api-comparison.json; 6 distinct changed field mappings were inspected for this operation. Operation-level request/response structure, parameters, required fields, defaults and status declarations are identical after removing prose/examples; referenced component changes were reviewed separately. | +| `applyWorkflowOperations` — `POST /api/v2/workflows/{workflowId}/operations` | corrected | Aligned request label, mintedBlockIds key, and lint block UUID in the edit example. | Verified improvement. Summary: Apply Workflow Operations → Apply workflow operations; sentence case matches the editorial guide. description: Edit the draft graph and block enablement in one write. Inspect `skipped` for failures; do not retry `deferred` edges. With `atomic=true`, skipped operations or dropped inputs ret… → Apply draft edits and block enablement changes in one write. Requires workspace write access. The live deployment is unchanged; lint is advisory. Inspect `skipped` and `inputValid… responses.503.description: A required service is temporarily unavailable. `Retry-After` carries the seconds to wait; treat it as a floor and add jitter. The header is omitted when `error.details.code` is `A… → A required service is temporarily unavailable. When present, `Retry-After` gives the minimum seconds to wait; add jitter before retrying. Check operation-specific guidance before … 2 request/response media example set(s) now expose the owner's existing examples to the API renderer. Preserved: Compared operationId applyWorkflowOperations, POST /api/v2/workflows/{workflowId}/operations, security and x-sim-operation with baseline; identifiers, route and credential schemes match. Recursive prose/default/example mappings retained in final-review-api-comparison.json; 7 distinct changed field mappings were inspected for this operation. Operation-level request/response structure, parameters, required fields, defaults and status declarations are identical after removing prose/examples; referenced component changes were reviewed separately. | +| `applyWorkflowVariables` — `PATCH /api/v2/workflows/{workflowId}/variables` | rewritten | Copy standardized; no operation-specific discrepancy found. | Verified improvement. Summary: Update Workflow Variables → Update workflow variables; sentence case matches the editorial guide. description: Add, edit, or delete variables by name, applying operations in order. Values are coerced to their declared type when possible; otherwise they are stored as supplied. A batch with … → Add, edit, or delete variables by name with workspace write access. Operations run in order. Values are coerced to their declared type when possible and otherwise stored as suppli… responses.200.content.application/json.schema.properties.data.properties.variableCount.description: Variables the workflow now holds. → Number of variables after the batch. responses.503.description: A required service is temporarily unavailable. `Retry-After` carries the seconds to wait; treat it as a floor and add jitter. The header is omitted when `error.details.code` is `A… → A required service is temporarily unavailable. When present, `Retry-After` gives the minimum seconds to wait; add jitter before retrying. Check operation-specific guidance before … 1 request/response media example set(s) now expose the owner's existing examples to the API renderer. Preserved: Compared operationId applyWorkflowVariables, PATCH /api/v2/workflows/{workflowId}/variables, security and x-sim-operation with baseline; identifiers, route and credential schemes match. Recursive prose/default/example mappings retained in final-review-api-comparison.json; 6 distinct changed field mappings were inspected for this operation. Operation-level request/response structure, parameters, required fields, defaults and status declarations are identical after removing prose/examples; referenced component changes were reviewed separately. | +| `duplicateWorkflow` — `POST /api/v2/workflows/{workflowId}/duplicate` | corrected | Kept undeployed-copy, same-workflow source state, trigger shutdown, and pending-rollback consequences close to their actions. | Verified improvement. Summary: Duplicate Workflow → Duplicate workflow; sentence case matches the editorial guide. description: Copy a workflow's graph and variables into the same workspace. Omit `name` to reuse the source name; name collisions in the destination folder are resolved automatically. Workspac… → Create an undeployed copy of a workflow's graph and variables in the same workspace. Requires workspace write access. The destination folder and name default to the source; name c… responses.503.description: A required service is temporarily unavailable. `Retry-After` carries the seconds to wait; treat it as a floor and add jitter. The header is omitted when `error.details.code` is `A… → A required service is temporarily unavailable. When present, `Retry-After` gives the minimum seconds to wait; add jitter before retrying. Check operation-specific guidance before … 2 request/response media example set(s) now expose the owner's existing examples to the API renderer. Preserved: Compared operationId duplicateWorkflow, POST /api/v2/workflows/{workflowId}/duplicate, security and x-sim-operation with baseline; identifiers, route and credential schemes match. Recursive prose/default/example mappings retained in final-review-api-comparison.json; 7 distinct changed field mappings were inspected for this operation. Operation-level request/response structure, parameters, required fields, defaults and status declarations are identical after removing prose/examples; referenced component changes were reviewed separately. | +| `restoreWorkflow` — `POST /api/v2/workflows/{workflowId}/restore` | rewritten | Copy standardized; no operation-specific discrepancy found. | Verified improvement. Summary: Restore Workflow → Restore workflow; sentence case matches the editorial guide. description: Restore an archived workflow and the schedules, webhooks, MCP tools, and chats archived with it. An active workflow returns `409`. If its folder is archived, the workflow returns … → Restore an archived workflow and its archived schedules, webhooks, MCP tools, and hosted chat. Requires workspace write access. An active workflow returns `409`. If its folder is … responses.503.description: A required service is temporarily unavailable. `Retry-After` carries the seconds to wait; treat it as a floor and add jitter. The header is omitted when `error.details.code` is `A… → A required service is temporarily unavailable. When present, `Retry-After` gives the minimum seconds to wait; add jitter before retrying. Check operation-specific guidance before … 1 request/response media example set(s) now expose the owner's existing examples to the API renderer. Preserved: Compared operationId restoreWorkflow, POST /api/v2/workflows/{workflowId}/restore, security and x-sim-operation with baseline; identifiers, route and credential schemes match. Recursive prose/default/example mappings retained in final-review-api-comparison.json; 6 distinct changed field mappings were inspected for this operation. Operation-level request/response structure, parameters, required fields, defaults and status declarations are identical after removing prose/examples; referenced component changes were reviewed separately. | +| `moveWorkflows` — `POST /api/v2/workflows/move` | rewritten | Copy standardized; no operation-specific discrepancy found. | Verified improvement. Summary: Move Workflows → Move workflows; sentence case matches the editorial guide. description: Move up to 100 workflows into one folder. Moves succeed or fail independently; missing, archived, or locked workflows appear in `failed`. Duplicate IDs are ignored. Workspace fold… → Move up to 100 workflows to one folder with workspace write access. Each move succeeds or fails independently; missing, archived, or locked workflows appear in `failed`. Duplicate… responses.503.description: A required service is temporarily unavailable. `Retry-After` carries the seconds to wait; treat it as a floor and add jitter. The header is omitted when `error.details.code` is `A… → A required service is temporarily unavailable. When present, `Retry-After` gives the minimum seconds to wait; add jitter before retrying. Check operation-specific guidance before … 2 request/response media example set(s) now expose the owner's existing examples to the API renderer. Preserved: Compared operationId moveWorkflows, POST /api/v2/workflows/move, security and x-sim-operation with baseline; identifiers, route and credential schemes match. Recursive prose/default/example mappings retained in final-review-api-comparison.json; 5 distinct changed field mappings were inspected for this operation. Operation-level request/response structure, parameters, required fields, defaults and status declarations are identical after removing prose/examples; referenced component changes were reviewed separately. | +| `getWorkflow` — `GET /api/v2/workflows/{workflowId}` | corrected | Identified trigger inputs as saved-draft fields, not deployed inputs. | Verified improvement. Summary: Get Workflow → Get workflow; sentence case matches the editorial guide. description: Get a workflow with its variables and deployed API-trigger inputs. Workspace folder trees exceeding 10,000 folders return `413`. OAuth scope: `api:read`. → Get workflow metadata, variables, and trigger input fields from the saved draft. Requires workspace read access. Input fields may differ from the live deployment. Workspace folder… responses.200.content.application/json.schema.properties.data.properties.inputs.description: Input fields exposed by the workflow API trigger. → Input fields from the saved draft's input-definition trigger; they may differ from the live deployment. responses.200.content.application/json.schema.properties.data.properties.inputs.items.description: A deployed API trigger input exposed by a workflow. → An input field from an input-definition trigger in the saved draft. 1 request/response media example set(s) now expose the owner's existing examples to the API renderer. Preserved: Compared operationId getWorkflow, GET /api/v2/workflows/{workflowId}, security and x-sim-operation with baseline; identifiers, route and credential schemes match. Recursive prose/default/example mappings retained in final-review-api-comparison.json; 7 distinct changed field mappings were inspected for this operation. Operation-level request/response structure, parameters, required fields, defaults and status declarations are identical after removing prose/examples; referenced component changes were reviewed separately. | +| `updateWorkflowV2` — `PATCH /api/v2/workflows/{workflowId}` | rewritten | Copy standardized; no operation-specific discrepancy found. | Verified improvement. Summary: Update Workflow → Update workflow; sentence case matches the editorial guide. description: Update a workflow's name, description, or folder path. Workspace folder trees exceeding 10,000 folders return `413`. OAuth scope: `api:write`. → Update a workflow's name, description, or folder path with workspace write access. Omitted fields remain unchanged; `description: null` clears the description. Workspace folder tr… responses.503.description: A required service is temporarily unavailable. `Retry-After` carries the seconds to wait; treat it as a floor and add jitter. The header is omitted when `error.details.code` is `A… → A required service is temporarily unavailable. When present, `Retry-After` gives the minimum seconds to wait; add jitter before retrying. Check operation-specific guidance before … 2 request/response media example set(s) now expose the owner's existing examples to the API renderer. Preserved: Compared operationId updateWorkflowV2, PATCH /api/v2/workflows/{workflowId}, security and x-sim-operation with baseline; identifiers, route and credential schemes match. Recursive prose/default/example mappings retained in final-review-api-comparison.json; 7 distinct changed field mappings were inspected for this operation. Operation-level request/response structure, parameters, required fields, defaults and status declarations are identical after removing prose/examples; referenced component changes were reviewed separately. | +| `deleteWorkflowV2` — `DELETE /api/v2/workflows/{workflowId}` | rewritten | Copy standardized; no operation-specific discrepancy found. | Verified improvement. Summary: Delete Workflow → Delete workflow; sentence case matches the editorial guide. description: Archive a workflow and stop its schedules, webhooks, MCP tools, and chats. Use List Workflows with `scope=archived` to find it and Restore Workflow to recover it and its archived … → Archive a workflow and stop its schedules, webhooks, MCP tools, and hosted chat. Requires workspace write access. Find it with List workflows (`scope=archived`) and recover it wit… responses.503.description: A required service is temporarily unavailable. `Retry-After` carries the seconds to wait; treat it as a floor and add jitter. The header is omitted when `error.details.code` is `A… → A required service is temporarily unavailable. When present, `Retry-After` gives the minimum seconds to wait; add jitter before retrying. Check operation-specific guidance before … 1 request/response media example set(s) now expose the owner's existing examples to the API renderer. Preserved: Compared operationId deleteWorkflowV2, DELETE /api/v2/workflows/{workflowId}, security and x-sim-operation with baseline; identifiers, route and credential schemes match. Recursive prose/default/example mappings retained in final-review-api-comparison.json; 5 distinct changed field mappings were inspected for this operation. Operation-level request/response structure, parameters, required fields, defaults and status declarations are identical after removing prose/examples; referenced component changes were reviewed separately. | +| `listWorkflowVersionsV2` — `GET /api/v2/workflows/{workflowId}/versions` | rewritten | Copy standardized; no operation-specific discrepancy found. | Verified improvement. Summary: List Workflow Versions → List workflow versions; sentence case matches the editorial guide. description: List immutable deployment versions of a workflow, newest first. OAuth scope: `api:read`. → List saved deployment versions, newest first, with workspace read access. Each version pins an immutable graph; its name and release note can be updated. OAuth scope: `api:read`. responses.200.content.application/json.schema.properties.nextCursor.description: Opaque cursor for the next page. Send it back as `cursor`; `null` means there is nothing further to fetch. Never construct one yourself. → Opaque cursor for the next page. Send it back as `cursor`; `null` means there are no more pages. Do not construct a cursor yourself. responses.503.description: A required service is temporarily unavailable. `Retry-After` carries the seconds to wait; treat it as a floor and add jitter. The header is omitted when `error.details.code` is `A… → A required service is temporarily unavailable. When present, `Retry-After` gives the minimum seconds to wait; add jitter before retrying. Check operation-specific guidance before … 1 request/response media example set(s) now expose the owner's existing examples to the API renderer. Preserved: Compared operationId listWorkflowVersionsV2, GET /api/v2/workflows/{workflowId}/versions, security and x-sim-operation with baseline; identifiers, route and credential schemes match. Recursive prose/default/example mappings retained in final-review-api-comparison.json; 5 distinct changed field mappings were inspected for this operation. Operation-level request/response structure, parameters, required fields, defaults and status declarations are identical after removing prose/examples; referenced component changes were reviewed separately. | +| `compareWorkflowVersionsV2` — `GET /api/v2/workflows/{workflowId}/versions/compare` | rewritten | Copy standardized; no operation-specific discrepancy found. | Verified improvement. Summary: Compare Workflow Versions → Compare workflow versions; sentence case matches the editorial guide. description: Compare two deployment versions of the same workflow. Reports semantic changes, excluding canvas layout; credential-bearing values are withheld while their changes remain visible.… → Compare two deployment versions of the same workflow with workspace read access. The comparison excludes layout changes and withholds credential-bearing values while reporting the… responses.503.description: A required service is temporarily unavailable. `Retry-After` carries the seconds to wait; treat it as a floor and add jitter. The header is omitted when `error.details.code` is `A… → A required service is temporarily unavailable. When present, `Retry-After` gives the minimum seconds to wait; add jitter before retrying. Check operation-specific guidance before … 1 request/response media example set(s) now expose the owner's existing examples to the API renderer. Preserved: Compared operationId compareWorkflowVersionsV2, GET /api/v2/workflows/{workflowId}/versions/compare, security and x-sim-operation with baseline; identifiers, route and credential schemes match. Recursive prose/default/example mappings retained in final-review-api-comparison.json; 4 distinct changed field mappings were inspected for this operation. Operation-level request/response structure, parameters, required fields, defaults and status declarations are identical after removing prose/examples; referenced component changes were reviewed separately. | +| `getWorkflowVersionV2` — `GET /api/v2/workflows/{workflowId}/versions/{version}` | corrected | Qualified known-field credential redaction; preserved ordinary variables and unresolved environment references, with export-review guidance. Kept undeployed-copy, same-workflow source state, trigger shutdown, and pending-rollback consequences close to their actions. | Verified improvement. Summary: Get Workflow Version → Get workflow version; sentence case matches the editorial guide. description: Get an immutable deployment version and its pinned workflow graph snapshot. OAuth scope: `api:read`. → Get a deployment version and its pinned graph with workspace read access. Registered credential fields and opaque table/tool values are cleared. Environment references and ordinar… responses.200.content.application/json.schema.properties.data.properties.state.description: Workflow graph saved with this deployment version. Sensitive values are redacted to null. → Graph pinned by this version, with registered credential fields and opaque table/tool values cleared. Environment references and ordinary workflow variables remain included; inspe… responses.503.description: A required service is temporarily unavailable. `Retry-After` carries the seconds to wait; treat it as a floor and add jitter. The header is omitted when `error.details.code` is `A… → A required service is temporarily unavailable. When present, `Retry-After` gives the minimum seconds to wait; add jitter before retrying. Check operation-specific guidance before … 1 request/response media example set(s) now expose the owner's existing examples to the API renderer. Preserved: Compared operationId getWorkflowVersionV2, GET /api/v2/workflows/{workflowId}/versions/{version}, security and x-sim-operation with baseline; identifiers, route and credential schemes match. Recursive prose/default/example mappings retained in final-review-api-comparison.json; 5 distinct changed field mappings were inspected for this operation. Operation-level request/response structure, parameters, required fields, defaults and status declarations are identical after removing prose/examples; referenced component changes were reviewed separately. | +| `updateWorkflowVersionV2` — `PATCH /api/v2/workflows/{workflowId}/versions/{version}` | rewritten | Copy standardized; no operation-specific discrepancy found. | Verified improvement. Summary: Update Workflow Version → Update workflow version; sentence case matches the editorial guide. description: Update a deployment version's name or release note. Omitted fields remain unchanged; `description: null` clears the note. The graph and live version remain unchanged. Use Activate… → Update a deployment version's name or release note with workspace write access. Omitted fields remain unchanged; `description: null` clears the note. The graph and live version ar… responses.503.description: A required service is temporarily unavailable. `Retry-After` carries the seconds to wait; treat it as a floor and add jitter. The header is omitted when `error.details.code` is `A… → A required service is temporarily unavailable. When present, `Retry-After` gives the minimum seconds to wait; add jitter before retrying. Check operation-specific guidance before … 2 request/response media example set(s) now expose the owner's existing examples to the API renderer. Preserved: Compared operationId updateWorkflowVersionV2, PATCH /api/v2/workflows/{workflowId}/versions/{version}, security and x-sim-operation with baseline; identifiers, route and credential schemes match. Recursive prose/default/example mappings retained in final-review-api-comparison.json; 5 distinct changed field mappings were inspected for this operation. Operation-level request/response structure, parameters, required fields, defaults and status declarations are identical after removing prose/examples; referenced component changes were reviewed separately. | +| `activateWorkflowVersion` — `POST /api/v2/workflows/{workflowId}/versions/{version}/activate` | corrected | Named required workspace Admin role separately from OAuth scope and credential-kind restrictions. | Verified improvement. Summary: Activate Workflow Version → Activate workflow version; sentence case matches the editorial guide. description: Asynchronously activate a specific deployment version, including when the workflow is not currently deployed. The draft remains unchanged. Read Get Workflow Deployment for `isDepl… → Activate a specific deployment version asynchronously. Requires workspace Admin access and works when the workflow is undeployed. The draft is unchanged. Poll Get workflow deploym… responses.503.description: A required service is temporarily unavailable. `Retry-After` carries the seconds to wait; treat it as a floor and add jitter. The header is omitted when `error.details.code` is `A… → A required service is temporarily unavailable. When present, `Retry-After` gives the minimum seconds to wait; add jitter before retrying. Check operation-specific guidance before … 2 request/response media example set(s) now expose the owner's existing examples to the API renderer. Preserved: Compared operationId activateWorkflowVersion, POST /api/v2/workflows/{workflowId}/versions/{version}/activate, security and x-sim-operation with baseline; identifiers, route and credential schemes match. Recursive prose/default/example mappings retained in final-review-api-comparison.json; 6 distinct changed field mappings were inspected for this operation. Operation-level request/response structure, parameters, required fields, defaults and status declarations are identical after removing prose/examples; referenced component changes were reviewed separately. | +| `revertWorkflowVersion` — `POST /api/v2/workflows/{workflowId}/versions/{version}/revert` | corrected | Named required workspace Admin role separately from OAuth scope and credential-kind restrictions. | Verified improvement. Summary: Revert Workflow To Version → Revert workflow to version; sentence case matches the editorial guide. description: Replace the editable draft with a deployment version, discarding current draft edits. Use `active` for the live version. The live deployment remains unchanged; Activate Workflow V… → Overwrite the editable draft with a deployment version, discarding current draft edits. Requires workspace Admin access. Use `active` for the live version. The live deployment is … responses.503.description: A required service is temporarily unavailable. `Retry-After` carries the seconds to wait; treat it as a floor and add jitter. The header is omitted when `error.details.code` is `A… → A required service is temporarily unavailable. When present, `Retry-After` gives the minimum seconds to wait; add jitter before retrying. Check operation-specific guidance before … 2 request/response media example set(s) now expose the owner's existing examples to the API renderer. Preserved: Compared operationId revertWorkflowVersion, POST /api/v2/workflows/{workflowId}/versions/{version}/revert, security and x-sim-operation with baseline; identifiers, route and credential schemes match. Recursive prose/default/example mappings retained in final-review-api-comparison.json; 6 distinct changed field mappings were inspected for this operation. Operation-level request/response structure, parameters, required fields, defaults and status declarations are identical after removing prose/examples; referenced component changes were reviewed separately. | +| `getWorkflowDeployment` — `GET /api/v2/workflows/{workflowId}/deployment` | rewritten | Copy standardized; no operation-specific discrepancy found. | Verified improvement. Summary: Get Workflow Deployment → Get workflow deployment; sentence case matches the editorial guide. description: Read live status, deployment time, latest attempt readiness and failure, draft divergence (`needsRedeployment`), anonymous execution access (`isPublicApi`), and registered webhook… → Read live deployment status, the latest attempt's readiness or failure, and draft divergence (`needsRedeployment`). Requires workspace read access. `isPublicApi` reports anonymous… responses.503.description: A required service is temporarily unavailable. `Retry-After` carries the seconds to wait; treat it as a floor and add jitter. The header is omitted when `error.details.code` is `A… → A required service is temporarily unavailable. When present, `Retry-After` gives the minimum seconds to wait; add jitter before retrying. Check operation-specific guidance before … 1 request/response media example set(s) now expose the owner's existing examples to the API renderer. Preserved: Compared operationId getWorkflowDeployment, GET /api/v2/workflows/{workflowId}/deployment, security and x-sim-operation with baseline; identifiers, route and credential schemes match. Recursive prose/default/example mappings retained in final-review-api-comparison.json; 4 distinct changed field mappings were inspected for this operation. Operation-level request/response structure, parameters, required fields, defaults and status declarations are identical after removing prose/examples; referenced component changes were reviewed separately. | +| `updateWorkflowPublicApi` — `PATCH /api/v2/workflows/{workflowId}/deployment` | corrected | Named required workspace Admin role separately from OAuth scope and credential-kind restrictions. | Verified improvement. Summary: Update Workflow Public API Access → Update workflow public API access; sentence case matches the editorial guide. description: Enable or disable unauthenticated execution of the deployed workflow. Enabling allows anyone with the execution URL to consume billed usage. Organization sharing restrictions retu… → Enable or disable unauthenticated execution of the deployed workflow. Requires workspace Admin access. Enabling lets anyone with the execution URL consume billed usage. Organizati… responses.503.description: A required service is temporarily unavailable. `Retry-After` carries the seconds to wait; treat it as a floor and add jitter. The header is omitted when `error.details.code` is `A… → A required service is temporarily unavailable. When present, `Retry-After` gives the minimum seconds to wait; add jitter before retrying. Check operation-specific guidance before … 2 request/response media example set(s) now expose the owner's existing examples to the API renderer. Preserved: Compared operationId updateWorkflowPublicApi, PATCH /api/v2/workflows/{workflowId}/deployment, security and x-sim-operation with baseline; identifiers, route and credential schemes match. Recursive prose/default/example mappings retained in final-review-api-comparison.json; 5 distinct changed field mappings were inspected for this operation. Operation-level request/response structure, parameters, required fields, defaults and status declarations are identical after removing prose/examples; referenced component changes were reviewed separately. | +| `deployWorkflow` — `POST /api/v2/workflows/{workflowId}/deploy` | corrected | Named required workspace Admin role separately from OAuth scope and credential-kind restrictions. | Verified improvement. Summary: Deploy Workflow → Deploy workflow; sentence case matches the editorial guide. description: Create and asynchronously activate a deployment version. Every call creates a new version; retrying after a timeout can create a duplicate. Read Get Workflow Deployment to check a… → Create a deployment version and activate it asynchronously. Requires workspace Admin access. Each accepted deploy creates a new version; retrying after a timeout can create a dupl… responses.200.content.application/json.schema.properties.data.properties.lint.description: Advisory lint findings for the version this deploy publishes, checked as the deploying user. Findings never block a deploy. Null when the lint could not complete within its time b… → Advisory lint for the admitted version, checked as the deploying member. Findings never block deployment. Null when lint exceeds its time budget or cannot complete; the deployment… responses.503.description: A required service is temporarily unavailable. `Retry-After` carries the seconds to wait; treat it as a floor and add jitter. The header is omitted when `error.details.code` is `A… → A required service is temporarily unavailable. When present, `Retry-After` gives the minimum seconds to wait; add jitter before retrying. Check operation-specific guidance before … 2 request/response media example set(s) now expose the owner's existing examples to the API renderer. Preserved: Compared operationId deployWorkflow, POST /api/v2/workflows/{workflowId}/deploy, security and x-sim-operation with baseline; identifiers, route and credential schemes match. Recursive prose/default/example mappings retained in final-review-api-comparison.json; 7 distinct changed field mappings were inspected for this operation. Operation-level request/response structure, parameters, required fields, defaults and status declarations are identical after removing prose/examples; referenced component changes were reviewed separately. | +| `undeployWorkflow` — `DELETE /api/v2/workflows/{workflowId}/deploy` | corrected | Named required workspace Admin role separately from OAuth scope and credential-kind restrictions. Kept undeployed-copy, same-workflow source state, trigger shutdown, and pending-rollback consequences close to their actions. | Verified improvement. Summary: Undeploy Workflow → Undeploy workflow; sentence case matches the editorial guide. description: Deactivate the currently serving workflow version. Workspace API keys return `403`; use a personal API key or scoped OAuth token. OAuth scope: `api:write`. → Deactivate the live workflow version and stop its scheduled and webhook triggers. Requires workspace Admin access and a deployed workflow. Deployed MCP tools become inactive; `arc… responses.503.description: A required service is temporarily unavailable. `Retry-After` carries the seconds to wait; treat it as a floor and add jitter. The header is omitted when `error.details.code` is `A… → A required service is temporarily unavailable. When present, `Retry-After` gives the minimum seconds to wait; add jitter before retrying. Check operation-specific guidance before … 1 request/response media example set(s) now expose the owner's existing examples to the API renderer. Preserved: Compared operationId undeployWorkflow, DELETE /api/v2/workflows/{workflowId}/deploy, security and x-sim-operation with baseline; identifiers, route and credential schemes match. Recursive prose/default/example mappings retained in final-review-api-comparison.json; 4 distinct changed field mappings were inspected for this operation. Operation-level request/response structure, parameters, required fields, defaults and status declarations are identical after removing prose/examples; referenced component changes were reviewed separately. | +| `rollbackWorkflow` — `POST /api/v2/workflows/{workflowId}/rollback` | corrected | Named required workspace Admin role separately from OAuth scope and credential-kind restrictions. | Verified improvement. Summary: Rollback Workflow → Rollback workflow; sentence case matches the editorial guide. description: Asynchronously activate a previous deployment version, defaulting to the preceding active version. Requires a deployed workflow and leaves the draft unchanged. Use Activate Workfl… → Activate a previous deployment version asynchronously, defaulting to the preceding active version. Requires workspace Admin access and a deployed workflow. The draft is unchanged.… responses.503.description: A required service is temporarily unavailable. `Retry-After` carries the seconds to wait; treat it as a floor and add jitter. The header is omitted when `error.details.code` is `A… → A required service is temporarily unavailable. When present, `Retry-After` gives the minimum seconds to wait; add jitter before retrying. Check operation-specific guidance before … 2 request/response media example set(s) now expose the owner's existing examples to the API renderer. Preserved: Compared operationId rollbackWorkflow, POST /api/v2/workflows/{workflowId}/rollback, security and x-sim-operation with baseline; identifiers, route and credential schemes match. Recursive prose/default/example mappings retained in final-review-api-comparison.json; 6 distinct changed field mappings were inspected for this operation. Operation-level request/response structure, parameters, required fields, defaults and status declarations are identical after removing prose/examples; referenced component changes were reviewed separately. | +| `exportWorkflow` — `GET /api/v2/workflows/{workflowId}/export` | corrected | Qualified known-field credential redaction; preserved ordinary variables and unresolved environment references, with export-review guidance. Made binding clearing conditional on default exports and actual missing required fields. | Verified improvement. Summary: Export Workflow → Export workflow; sentence case matches the editorial guide. description: Export a portable, secret-sanitized workflow. Use includeReferences=true for non-secret source identities and field occurrences used by mapped imports. Use includeWorkspaceBinding… → Export the saved draft as portable workflow data with workspace read access. Registered credential fields and opaque table/tool values are cleared; environment references and ordi… parameters[2].description: Whether to keep workspace-scoped bindings — table, knowledge base, document, folder, channel, and other resource selectors — in the exported state. Defaults to false, the sharing-… → Keep non-secret table, knowledge base, document, folder, channel, and other workspace bindings for a same-workspace import. Defaults to false, which clears these IDs. Registered c… parameters[2].schema.description: Whether to keep workspace-scoped bindings — table, knowledge base, document, folder, channel, and other resource selectors — in the exported state. Defaults to false, the sharing-… → Keep non-secret table, knowledge base, document, folder, channel, and other workspace bindings for a same-workspace import. Defaults to false, which clears these IDs. Registered c… 1 request/response media example set(s) now expose the owner's existing examples to the API renderer. Preserved: Compared operationId exportWorkflow, GET /api/v2/workflows/{workflowId}/export, security and x-sim-operation with baseline; identifiers, route and credential schemes match. Recursive prose/default/example mappings retained in final-review-api-comparison.json; 8 distinct changed field mappings were inspected for this operation. Operation-level request/response structure, parameters, required fields, defaults and status declarations are identical after removing prose/examples; referenced component changes were reviewed separately. | +| `importWorkflow` — `POST /api/v2/workflows/import` | corrected | Made binding clearing conditional on default exports and actual missing required fields. Added syntax-valid root examples; import example also passes the portable-workflow parser. Preview hashes are explicitly illustrative. Restored exact-preview choice matching and identical-request retry behavior on fields and apply intros. | Verified improvement. Summary: Import Workflow → Import workflow; sentence case matches the editorial guide. description: Create an undeployed workflow from a portable export object, bare state, or JSON string. Mapping options require a preview fingerprint and stable request ID; unresolved required c… → Create an undeployed workflow from a portable export object, bare draft state, or JSON string. Requires workspace write access. The empty-state example creates a draft that needs … requestBody.content.application/json.schema.description: Workflow document, destination, and optional reviewed mappings. → Workflow document, destination, and optional reviewed mappings. This example creates an empty draft. requestBody.content.application/json.schema.properties.dependentValues.description: Destination-dependent choices keyed by source workflow, block, and field identities. → Destination-specific values addressed by the source block ID and field key, before imported IDs are regenerated. 2 request/response media example set(s) now expose the owner's existing examples to the API renderer. Preserved: Compared operationId importWorkflow, POST /api/v2/workflows/import, security and x-sim-operation with baseline; identifiers, route and credential schemes match. Recursive prose/default/example mappings retained in final-review-api-comparison.json; 20 distinct changed field mappings were inspected for this operation. Operation-level request/response structure, parameters, required fields, defaults and status declarations are identical after removing prose/examples; referenced component changes were reviewed separately. | +| `listChatDeployments` — `GET /api/v2/chat-deployments` | rewritten | Copy standardized; no operation-specific discrepancy found. | Verified improvement. Summary: List Chat Deployments → List chat deployments; sentence case matches the editorial guide. description: List hosted chats and their public URLs with cursor pagination. Filter by `workflowId` for one workflow's chat. The list requires workspace read access; Get Workflow Chat Deployme… → List hosted chats and their URLs with workspace read access and cursor pagination. Filter by `workflowId` for one workflow's chat. The admin-only detail read also includes visitor… responses.200.content.application/json.schema.properties.nextCursor.description: Opaque cursor for the next page. Send it back as `cursor`; `null` means there is nothing further to fetch. Never construct one yourself. → Opaque cursor for the next page. Send it back as `cursor`; `null` means there are no more pages. Do not construct a cursor yourself. responses.503.description: A required service is temporarily unavailable. `Retry-After` carries the seconds to wait; treat it as a floor and add jitter. The header is omitted when `error.details.code` is `A… → A required service is temporarily unavailable. When present, `Retry-After` gives the minimum seconds to wait; add jitter before retrying. Check operation-specific guidance before … 1 request/response media example set(s) now expose the owner's existing examples to the API renderer. Preserved: Compared operationId listChatDeployments, GET /api/v2/chat-deployments, security and x-sim-operation with baseline; identifiers, route and credential schemes match. Recursive prose/default/example mappings retained in final-review-api-comparison.json; 5 distinct changed field mappings were inspected for this operation. Operation-level request/response structure, parameters, required fields, defaults and status declarations are identical after removing prose/examples; referenced component changes were reviewed separately. | +| `getWorkflowChatDeployment` — `GET /api/v2/workflows/{workflowId}/deployments/chat` | rewritten | Copy standardized; no operation-specific discrepancy found. | Verified improvement. Summary: Get Workflow Chat Deployment → Get workflow chat deployment; sentence case matches the editorial guide. description: Get a workflow's hosted chat and visitor access settings. Requires workspace admin access; a missing chat returns `404`. Passwords are never returned; `hasPassword` indicates whet… → Get a workflow's hosted chat and visitor access settings with workspace Admin access. A missing chat returns `404`. Passwords are never returned; `hasPassword` reports whether one… responses.503.description: A required service is temporarily unavailable. `Retry-After` carries the seconds to wait; treat it as a floor and add jitter. The header is omitted when `error.details.code` is `A… → A required service is temporarily unavailable. When present, `Retry-After` gives the minimum seconds to wait; add jitter before retrying. Check operation-specific guidance before … 1 request/response media example set(s) now expose the owner's existing examples to the API renderer. Preserved: Compared operationId getWorkflowChatDeployment, GET /api/v2/workflows/{workflowId}/deployments/chat, security and x-sim-operation with baseline; identifiers, route and credential schemes match. Recursive prose/default/example mappings retained in final-review-api-comparison.json; 4 distinct changed field mappings were inspected for this operation. Operation-level request/response structure, parameters, required fields, defaults and status declarations are identical after removing prose/examples; referenced component changes were reviewed separately. | +| `replaceWorkflowChatDeployment` — `PUT /api/v2/workflows/{workflowId}/deployments/chat` | corrected | Documented omitted/empty image and empty welcome-message merge exceptions. Named required workspace Admin role separately from OAuth scope and credential-kind restrictions. | Verified improvement. Summary: Create or Replace Workflow Chat Deployment → Create or replace workflow chat deployment; sentence case matches the editorial guide. description: Create or replace a workflow's hosted chat and deploy its draft. Omitted fields reset to defaults except per-field customizations. Password authentication requires `password`; ema… → Create or replace a workflow's hosted chat and deploy its saved draft. Requires workspace Admin access. Omitted fields use defaults; customization exceptions are described on thei… requestBody.content.application/json.schema.properties.customizations.description: Presentation overrides. Omitted fields take platform defaults. → Presentation overrides. Omitted `primaryColor` and `welcomeMessage` use platform defaults; an omitted or empty `imageUrl` keeps the existing avatar. An empty `welcomeMessage` keep… requestBody.content.application/json.schema.properties.customizations.properties.imageUrl.description: Avatar image shown beside assistant messages. → Avatar image shown beside assistant messages. On replace, omission or an empty string keeps the existing avatar. 2 request/response media example set(s) now expose the owner's existing examples to the API renderer. Preserved: Compared operationId replaceWorkflowChatDeployment, PUT /api/v2/workflows/{workflowId}/deployments/chat, security and x-sim-operation with baseline; identifiers, route and credential schemes match. Recursive prose/default/example mappings retained in final-review-api-comparison.json; 10 distinct changed field mappings were inspected for this operation. Operation-level request/response structure, parameters, required fields, defaults and status declarations are identical after removing prose/examples; referenced component changes were reviewed separately. | +| `deleteWorkflowChatDeployment` — `DELETE /api/v2/workflows/{workflowId}/deployments/chat` | corrected | Named required workspace Admin role separately from OAuth scope and credential-kind restrictions. | Verified improvement. Summary: Delete Workflow Chat Deployment → Delete workflow chat deployment; sentence case matches the editorial guide. description: Remove a workflow's hosted chat and release its URL identifier. The workflow API deployment remains active; use Undeploy Workflow to stop it. Workspace API keys return `403`; use … → Remove the hosted chat and release its URL identifier with workspace Admin access. The workflow API deployment remains active; use Undeploy workflow to stop it. Workspace API keys… responses.503.description: A required service is temporarily unavailable. `Retry-After` carries the seconds to wait; treat it as a floor and add jitter. The header is omitted when `error.details.code` is `A… → A required service is temporarily unavailable. When present, `Retry-After` gives the minimum seconds to wait; add jitter before retrying. Check operation-specific guidance before … 1 request/response media example set(s) now expose the owner's existing examples to the API renderer. Preserved: Compared operationId deleteWorkflowChatDeployment, DELETE /api/v2/workflows/{workflowId}/deployments/chat, security and x-sim-operation with baseline; identifiers, route and credential schemes match. Recursive prose/default/example mappings retained in final-review-api-comparison.json; 4 distinct changed field mappings were inspected for this operation. Operation-level request/response structure, parameters, required fields, defaults and status declarations are identical after removing prose/examples; referenced component changes were reviewed separately. | +| `executeWorkflowV2` — `POST /api/v2/workflows/{workflowId}/execute` | corrected | Named Accept:application/x-ndjson with synchronous flags, final frame data, separate SSE, and ambiguous enqueue reconciliation. Kept undeployed-copy, same-workflow source state, trigger shutdown, and pending-rollback consequences close to their actions. | Verified improvement. Summary: Execute Workflow → Execute workflow; sentence case matches the editorial guide. description: Execute a deployment or use `run.source: "manual"` for the draft. Manual runs require personal or OAuth write access and reject async. Public deployments allow anonymous sync or s… → Run the active deployment, or set `run.source: "manual"` to run the saved draft. Deployed execution requires workspace read access and OAuth `api:write` scope or an API key; publi… requestBody.content.application/json.schema.properties.async.description: Queue the run and return a 202 receipt when true. Requires an OAuth access token or API key, cannot be combined with `stream`, and rejects all streaming and output-shaping options… → Queue the run and return a 202 receipt. Requires an API key or OAuth access token and a deployed run source. Cannot stream, select outputs, enable thinking/tool events, or include… requestBody.content.application/json.schema.properties.run.oneOf[1].properties.entry.oneOf[1].properties.sourceRunId.description: Run ID supplying upstream block results when starting from a selected block. → Run in this workflow whose persisted execution state supplies upstream block results. Missing or expired state returns 404. 3 request/response media example set(s) now expose the owner's existing examples to the API renderer. Preserved: Compared operationId executeWorkflowV2, POST /api/v2/workflows/{workflowId}/execute, security and x-sim-operation with baseline; identifiers, route and credential schemes match. Recursive prose/default/example mappings retained in final-review-api-comparison.json; 10 distinct changed field mappings were inspected for this operation. Operation-level request/response structure, parameters, required fields, defaults and status declarations are identical after removing prose/examples; referenced component changes were reviewed separately. | +| `listWorkflowRunsV2` — `GET /api/v2/workflows/{workflowId}/runs` | corrected | Documented permission-driven null output/files/cost and independent output selection. Root corrected billing-mode/default retention and protected-pause wording in openapi/shared.ts. Included human and time pauses; root corrected the shared pauseKind/resumeAt waiting-reason description. | Verified improvement. Summary: List Workflow Runs → List workflow runs; sentence case matches the editorial guide. description: List recorded runs of a workflow with filtering and opaque cursor pagination. Expired runs are permanently deleted. Retention is 30 days from run start on Free, unlimited on Pro a… → List recorded workflow runs with workspace read access, filters, and cursor pagination. Cost can be hidden by organization permission groups. Expired runs are permanently deleted … responses.200.content.application/json.schema.properties.data.items.properties.cost.description: Credit cost, or null when unavailable. → Credits consumed, or null when unavailable or hidden by organization permission groups. responses.200.content.application/json.schema.properties.data.items.properties.status.description: Current or terminal run status. `redacting` is transient, reported while a finished run's output is being scrubbed. `paused` means the run is waiting to be resumed — either held a… → Current or terminal run status. `redacting` is transient, reported while a finished run's output is being scrubbed. `paused` means the run is waiting at a human or time pause, or … 1 request/response media example set(s) now expose the owner's existing examples to the API renderer. Preserved: Compared operationId listWorkflowRunsV2, GET /api/v2/workflows/{workflowId}/runs, security and x-sim-operation with baseline; identifiers, route and credential schemes match. Recursive prose/default/example mappings retained in final-review-api-comparison.json; 7 distinct changed field mappings were inspected for this operation. Operation-level request/response structure, parameters, required fields, defaults and status declarations are identical after removing prose/examples; referenced component changes were reviewed separately. | +| `getWorkflowRunV2` — `GET /api/v2/workflows/{workflowId}/runs/{runId}` | corrected | Documented permission-driven null output/files/cost and independent output selection. Included human and time pauses; root corrected the shared pauseKind/resumeAt waiting-reason description. | Verified improvement. Summary: Get Workflow Run → Get workflow run; sentence case matches the editorial guide. description: Get current run state with optional final and block outputs. With `includeOutput`, `files` includes download paths; `includeFileBase64` inlines file bytes and returns `413` with t… → Read current run state with workspace read access. Request final output and files with `includeOutput`, or block outputs with `selectedOutputs`. Organization permission groups can… responses.200.content.application/json.schema.properties.data.properties.blockOutputs.description: Outputs of the blocks named by `selectedOutputs`, or null when none were requested. Gated by `selectedOutputs` alone — `includeOutput` governs `output` only. → Selected block outputs, or null when none were requested or execution data is hidden by organization permission groups. `selectedOutputs` controls these independently of `includeO… responses.200.content.application/json.schema.properties.data.properties.cost.description: Credit cost, or null when unavailable. → Credits consumed, or null when unavailable or hidden by organization permission groups. 1 request/response media example set(s) now expose the owner's existing examples to the API renderer. Preserved: Compared operationId getWorkflowRunV2, GET /api/v2/workflows/{workflowId}/runs/{runId}, security and x-sim-operation with baseline; identifiers, route and credential schemes match. Recursive prose/default/example mappings retained in final-review-api-comparison.json; 11 distinct changed field mappings were inspected for this operation. Operation-level request/response structure, parameters, required fields, defaults and status declarations are identical after removing prose/examples; referenced component changes were reviewed separately. | +| `downloadWorkflowRunFileV2` — `GET /api/v2/workflows/{workflowId}/runs/{runId}/files/{fileId}` | corrected | Documented permission-driven null output/files/cost and independent output selection. Root corrected billing-mode/default retention and protected-pause wording in openapi/shared.ts. | Verified improvement. Summary: Download Workflow Run File → Download workflow run file; sentence case matches the editorial guide. description: Download one run-produced file by ID. Downloads record an audit event. Expired runs are permanently deleted. Retention is 30 days from run start on Free, unlimited on Pro and Team… → Download one run-produced file by its reported ID with workspace read access. Downloads record an audit event. Expired runs are permanently deleted by retention cleanup. Sim Cloud… responses.503.description: A required service is temporarily unavailable. `Retry-After` carries the seconds to wait; treat it as a floor and add jitter. The header is omitted when `error.details.code` is `A… → A required service is temporarily unavailable. When present, `Retry-After` gives the minimum seconds to wait; add jitter before retrying. Check operation-specific guidance before … Preserved: Compared operationId downloadWorkflowRunFileV2, GET /api/v2/workflows/{workflowId}/runs/{runId}/files/{fileId}, security and x-sim-operation with baseline; identifiers, route and credential schemes match. Recursive prose/default/example mappings retained in final-review-api-comparison.json; 4 distinct changed field mappings were inspected for this operation. Operation-level request/response structure, parameters, required fields, defaults and status declarations are identical after removing prose/examples; referenced component changes were reviewed separately. | +| `resumeWorkflowRunV2` — `POST /api/v2/workflows/{workflowId}/runs/{runId}/resume` | rewritten | Copy standardized; no operation-specific discrepancy found. | Verified improvement. Summary: Resume Workflow Run → Resume workflow run; sentence case matches the editorial guide. description: Resume one human-in-the-loop pause. The resumed attempt receives a new run ID and returns either a synchronous result or a queue receipt. OAuth scope: `api:write`. → Resume one human-in-the-loop pause with workspace write access. The resumed attempt receives a new run ID and returns a synchronous result or queue receipt. A run that originally … responses.503.description: A required service is temporarily unavailable. `Retry-After` carries the seconds to wait; treat it as a floor and add jitter. The header is omitted when `error.details.code` is `A… → A required service is temporarily unavailable. When present, `Retry-After` gives the minimum seconds to wait; add jitter before retrying. Check operation-specific guidance before … 3 request/response media example set(s) now expose the owner's existing examples to the API renderer. Preserved: Compared operationId resumeWorkflowRunV2, POST /api/v2/workflows/{workflowId}/runs/{runId}/resume, security and x-sim-operation with baseline; identifiers, route and credential schemes match. Recursive prose/default/example mappings retained in final-review-api-comparison.json; 7 distinct changed field mappings were inspected for this operation. Operation-level request/response structure, parameters, required fields, defaults and status declarations are identical after removing prose/examples; referenced component changes were reviewed separately. | +| `cancelRunV2` — `POST /api/v2/workflows/{workflowId}/runs/{runId}/cancel` | rewritten | Copy standardized; no operation-specific discrepancy found. | Verified improvement. Summary: Cancel Workflow Run → Cancel workflow run; sentence case matches the editorial guide. description: Request cancellation of a running, queued, or paused workflow run. Cancelling a run already in a terminal state is a `200` no-op answered with `success: false` and an `already_*` … → Request cancellation of a running, queued, or paused workflow run with workspace write access. Cancellation is best effort; inspect the outcome flags and `reason`. A terminal run … responses.503.description: A required service is temporarily unavailable. `Retry-After` carries the seconds to wait; treat it as a floor and add jitter. The header is omitted when `error.details.code` is `A… → A required service is temporarily unavailable. When present, `Retry-After` gives the minimum seconds to wait; add jitter before retrying. Check operation-specific guidance before … 1 request/response media example set(s) now expose the owner's existing examples to the API renderer. Preserved: Compared operationId cancelRunV2, POST /api/v2/workflows/{workflowId}/runs/{runId}/cancel, security and x-sim-operation with baseline; identifiers, route and credential schemes match. Recursive prose/default/example mappings retained in final-review-api-comparison.json; 5 distinct changed field mappings were inspected for this operation. Operation-level request/response structure, parameters, required fields, defaults and status declarations are identical after removing prose/examples; referenced component changes were reviewed separately. | +| `listWorkflowsFolders` — `GET /api/v2/workflows/folders` | rewritten | Copy standardized; no operation-specific discrepancy found. | Verified improvement. Summary: List Workflow Folders → List workflow folders; sentence case matches the editorial guide. description: List workflow folders in a workspace. Returns the complete set in one page; `nextCursor` is always null. Workspace folder trees exceeding 10,000 folders return `413`. OAuth scope:… → List workflow folders with workspace read access, optional parent/name filters, and sorting. Returns one page; `nextCursor` is always null. Workspace folder trees exceeding 10,000… parameters[3].description: Field used to sort the result. Sorting by `name` is case-sensitive and follows the storage collation, so do not rely on a case-insensitive order. → Field used to sort the result. Do not rely on case-insensitive ordering when sorting by `name`. parameters[3].schema.description: Field used to sort the result. Sorting by `name` is case-sensitive and follows the storage collation, so do not rely on a case-insensitive order. → Field used to sort the result. Do not rely on case-insensitive ordering when sorting by `name`. 1 request/response media example set(s) now expose the owner's existing examples to the API renderer. Preserved: Compared operationId listWorkflowsFolders, GET /api/v2/workflows/folders, security and x-sim-operation with baseline; identifiers, route and credential schemes match. Recursive prose/default/example mappings retained in final-review-api-comparison.json; 7 distinct changed field mappings were inspected for this operation. Operation-level request/response structure, parameters, required fields, defaults and status declarations are identical after removing prose/examples; referenced component changes were reviewed separately. | +| `createWorkflowsFolder` — `POST /api/v2/workflows/folders` | rewritten | Copy standardized; no operation-specific discrepancy found. | Verified improvement. Summary: Create Workflow Folder → Create workflow folder; sentence case matches the editorial guide. description: Create a workflow folder in a workspace. Workspace folder trees exceeding 10,000 folders return `413`. OAuth scope: `api:write`. → Create a workflow folder at a non-root path with workspace write access. Workspace folder trees exceeding 10,000 folders return `413`. OAuth scope: `api:write`. responses.503.description: A required service is temporarily unavailable. `Retry-After` carries the seconds to wait; treat it as a floor and add jitter. The header is omitted when `error.details.code` is `A… → A required service is temporarily unavailable. When present, `Retry-After` gives the minimum seconds to wait; add jitter before retrying. Check operation-specific guidance before … 2 request/response media example set(s) now expose the owner's existing examples to the API renderer. Preserved: Compared operationId createWorkflowsFolder, POST /api/v2/workflows/folders, security and x-sim-operation with baseline; identifiers, route and credential schemes match. Recursive prose/default/example mappings retained in final-review-api-comparison.json; 6 distinct changed field mappings were inspected for this operation. Operation-level request/response structure, parameters, required fields, defaults and status declarations are identical after removing prose/examples; referenced component changes were reviewed separately. | +| `relocateWorkflowsFolder` — `PATCH /api/v2/workflows/folders` | rewritten | Copy standardized; no operation-specific discrepancy found. | Verified improvement. Summary: Rename or Move Workflow Folder → Rename or move workflow folder; sentence case matches the editorial guide. description: Rename or move a workflow folder and update all descendant paths. Workspace folder trees exceeding 10,000 folders return `413`. OAuth scope: `api:write`. → Rename or move a workflow folder and update descendant paths with workspace write access. An existing destination receives the folder as a child; otherwise the destination is its … responses.503.description: A required service is temporarily unavailable. `Retry-After` carries the seconds to wait; treat it as a floor and add jitter. The header is omitted when `error.details.code` is `A… → A required service is temporarily unavailable. When present, `Retry-After` gives the minimum seconds to wait; add jitter before retrying. Check operation-specific guidance before … 2 request/response media example set(s) now expose the owner's existing examples to the API renderer. Preserved: Compared operationId relocateWorkflowsFolder, PATCH /api/v2/workflows/folders, security and x-sim-operation with baseline; identifiers, route and credential schemes match. Recursive prose/default/example mappings retained in final-review-api-comparison.json; 6 distinct changed field mappings were inspected for this operation. Operation-level request/response structure, parameters, required fields, defaults and status declarations are identical after removing prose/examples; referenced component changes were reviewed separately. | +| `deleteWorkflowsFolder` — `DELETE /api/v2/workflows/folders` | corrected | Root corrected recursive folder wording in v2/shared.ts. | Verified improvement. Summary: Delete Workflow Folder → Delete workflow folder; sentence case matches the editorial guide. description: Archive an empty workflow folder, or set `recursive=true` to archive its subfolders and workflows. Use Restore Workflow to recover workflows. OAuth scope: `api:write`. → Archive an empty workflow folder with workspace write access. `recursive=true` also archives its subfolders and workflows, stopping the archived workflows' triggers and hosted sur… parameters[2].description: Delete the folder's nested files and folders too. An empty folder deletes either way; a non-empty one needs this. The listed spellings are the whole accepted vocabulary and are ca… → Delete the folder's contents and nested folders too. Required for a non-empty folder. Only the listed case-sensitive spellings are accepted. parameters[2].schema.description: Delete the folder's nested files and folders too. An empty folder deletes either way; a non-empty one needs this. The listed spellings are the whole accepted vocabulary and are ca… → Delete the folder's contents and nested folders too. Required for a non-empty folder. Only the listed case-sensitive spellings are accepted. 1 request/response media example set(s) now expose the owner's existing examples to the API renderer. Preserved: Compared operationId deleteWorkflowsFolder, DELETE /api/v2/workflows/folders, security and x-sim-operation with baseline; identifiers, route and credential schemes match. Recursive prose/default/example mappings retained in final-review-api-comparison.json; 7 distinct changed field mappings were inspected for this operation. Operation-level request/response structure, parameters, required fields, defaults and status declarations are identical after removing prose/examples; referenced component changes were reviewed separately. | +| `previewWorkspaceFork` — `POST /api/v2/workspaces/{workspaceId}/fork/preview` | corrected | Named current/source/both-side/target Admin access and qualified feature gate by billing mode rather than hosting location. Restored exact-preview choice matching and identical-request retry behavior on fields and apply intros. Replaced mechanical body/result text with operation-specific descriptions and human schema titles, preserving stable IDs. | Verified improvement. Summary: Preview Workspace Fork → Preview workspace fork; sentence case matches the editorial guide. description: Preview the deployed workflows and explicitly selected resources that a new workspace fork would copy. The result is read-only and supplies the fingerprint required by Fork Worksp… → Preview deployed workflows and explicitly selected resources for a new child workspace. Requires source workspace Admin access and permission to create a workspace in its organiza… requestBody.content.application/json.schema.description: The body for this operation. → Optional child name and explicitly selected resource copies. requestBody.description: The body for this operation. → Optional child name and explicitly selected resource copies. Preserved: Compared operationId previewWorkspaceFork, POST /api/v2/workspaces/{workspaceId}/fork/preview, security and x-sim-operation with baseline; identifiers, route and credential schemes match. Recursive prose/default/example mappings retained in final-review-api-comparison.json; 9 distinct changed field mappings were inspected for this operation. Operation-level request/response structure, parameters, required fields, defaults and status declarations are identical after removing prose/examples; referenced component changes were reviewed separately. | +| `forkWorkspace` — `POST /api/v2/workspaces/{workspaceId}/fork` | corrected | Added syntax-valid root examples; import example also passes the portable-workflow parser. Preview hashes are explicitly illustrative. Named current/source/both-side/target Admin access and qualified feature gate by billing mode rather than hosting location. Restored exact-preview choice matching and identical-request retry behavior on fields and apply intros. Replaced mechanical body/result text with operation-specific descriptions and human schema titles, preserving stable IDs. Root added and rendered a validated response example with the correct workspace operation kind rather than the shared import enum default. | Verified improvement. Summary: Fork Workspace → Fork workspace; sentence case matches the editorial guide. description: Create a child workspace with undeployed workflow drafts. Requires the reviewed preview fingerprint and a stable request ID. Identical retries return the same operation; reuse wit… → Create a child workspace with undeployed drafts of the source's deployed workflows. Requires source workspace Admin access and permission to create a workspace in its organization… requestBody.content.application/json.schema.description: The body for this operation. → Child name and copy choices, with the actual preview fingerprint and a stable request ID. requestBody.content.application/json.schema.properties.previewFingerprint.description: Fingerprint of the reviewed preview and its choices. → Fingerprint returned by a preview with the same choices. A changed plan returns 409; preview again. The example hash is illustrative; use the actual preview value. 4 request/response media example set(s) now expose the owner's existing examples to the API renderer. Preserved: Compared operationId forkWorkspace, POST /api/v2/workspaces/{workspaceId}/fork, security and x-sim-operation with baseline; identifiers, route and credential schemes match. Recursive prose/default/example mappings retained in final-review-api-comparison.json; 21 distinct changed field mappings were inspected for this operation. Operation-level request/response structure, parameters, required fields, defaults and status declarations are identical after removing prose/examples; referenced component changes were reviewed separately. | +| `previewWorkspacePush` — `POST /api/v2/workspaces/{workspaceId}/fork/push/preview` | corrected | Named current/source/both-side/target Admin access and qualified feature gate by billing mode rather than hosting location. Named create/replace/archive actions, draft overwrite and deleted-source archival, preserving undeployed-source targets. Restored exact-preview choice matching and identical-request retry behavior on fields and apply intros. Replaced mechanical body/result text with operation-specific descriptions and human schema titles, preserving stable IDs. | Verified improvement. Summary: Preview Workspace Push → Preview workspace push; sentence case matches the editorial guide. description: Preview deployed source workflows replacing mapped targets along a direct fork edge. Push sends the current workspace to the other; pull brings the other into the current workspac… → Preview changes from this workspace into the other workspace along a direct fork edge. Requires Admin access to both workspaces. The plan lists workflows to create, replace, or ar… requestBody.content.application/json.schema.description: The body for this operation. → Other workspace and proposed source-to-target sync choices. requestBody.content.application/json.schema.properties.dependentValues.description: Destination-dependent choices keyed by source workflow, block, and field identities. → Destination-specific choices addressed by source workflow ID, source block ID, and field key. Omission keeps saved overrides; an explicit empty array clears them. Preserved: Compared operationId previewWorkspacePush, POST /api/v2/workspaces/{workspaceId}/fork/push/preview, security and x-sim-operation with baseline; identifiers, route and credential schemes match. Recursive prose/default/example mappings retained in final-review-api-comparison.json; 12 distinct changed field mappings were inspected for this operation. Operation-level request/response structure, parameters, required fields, defaults and status declarations are identical after removing prose/examples; referenced component changes were reviewed separately. | +| `pushWorkspace` — `POST /api/v2/workspaces/{workspaceId}/fork/push` | corrected | Added syntax-valid root examples; import example also passes the portable-workflow parser. Preview hashes are explicitly illustrative. Named current/source/both-side/target Admin access and qualified feature gate by billing mode rather than hosting location. Named create/replace/archive actions, draft overwrite and deleted-source archival, preserving undeployed-source targets. Restored exact-preview choice matching and identical-request retry behavior on fields and apply intros. Replaced mechanical body/result text with operation-specific descriptions and human schema titles, preserving stable IDs. | Verified improvement. Summary: Push Workspace → Push workspace; sentence case matches the editorial guide. description: Apply a reviewed push or pull with inline mappings in one transaction. Requires confirmation, the preview fingerprint, and a stable request ID. Unresolved or changed plans return … → Apply a reviewed sync from this workspace into the other workspace along a direct fork edge. Requires Admin access to both workspaces. Creates unmatched deployed workflows, overwr… requestBody.content.application/json.schema.description: The body for this operation. → Confirmed current-to-other choices, actual preview fingerprint, and stable request ID. requestBody.content.application/json.schema.properties.confirm.description: Explicit acknowledgement that sync replaces target workflows. → Confirm replacement of mapped target drafts and archival of mapped targets whose sources were deleted or archived. 4 request/response media example set(s) now expose the owner's existing examples to the API renderer. Preserved: Compared operationId pushWorkspace, POST /api/v2/workspaces/{workspaceId}/fork/push, security and x-sim-operation with baseline; identifiers, route and credential schemes match. Recursive prose/default/example mappings retained in final-review-api-comparison.json; 24 distinct changed field mappings were inspected for this operation. Operation-level request/response structure, parameters, required fields, defaults and status declarations are identical after removing prose/examples; referenced component changes were reviewed separately. | +| `previewWorkspacePull` — `POST /api/v2/workspaces/{workspaceId}/fork/pull/preview` | corrected | Named current/source/both-side/target Admin access and qualified feature gate by billing mode rather than hosting location. Named create/replace/archive actions, draft overwrite and deleted-source archival, preserving undeployed-source targets. Restored exact-preview choice matching and identical-request retry behavior on fields and apply intros. Replaced mechanical body/result text with operation-specific descriptions and human schema titles, preserving stable IDs. | Verified improvement. Summary: Preview Workspace Pull → Preview workspace pull; sentence case matches the editorial guide. description: Preview deployed source workflows replacing mapped targets along a direct fork edge. Push sends the current workspace to the other; pull brings the other into the current workspac… → Preview changes from the other workspace into this workspace along a direct fork edge. Requires Admin access to both workspaces. The plan lists workflows to create, replace, or ar… requestBody.content.application/json.schema.description: The body for this operation. → Other workspace and proposed source-to-target sync choices. requestBody.content.application/json.schema.properties.dependentValues.description: Destination-dependent choices keyed by source workflow, block, and field identities. → Destination-specific choices addressed by source workflow ID, source block ID, and field key. Omission keeps saved overrides; an explicit empty array clears them. Preserved: Compared operationId previewWorkspacePull, POST /api/v2/workspaces/{workspaceId}/fork/pull/preview, security and x-sim-operation with baseline; identifiers, route and credential schemes match. Recursive prose/default/example mappings retained in final-review-api-comparison.json; 12 distinct changed field mappings were inspected for this operation. Operation-level request/response structure, parameters, required fields, defaults and status declarations are identical after removing prose/examples; referenced component changes were reviewed separately. | +| `pullWorkspace` — `POST /api/v2/workspaces/{workspaceId}/fork/pull` | corrected | Added syntax-valid root examples; import example also passes the portable-workflow parser. Preview hashes are explicitly illustrative. Named current/source/both-side/target Admin access and qualified feature gate by billing mode rather than hosting location. Named create/replace/archive actions, draft overwrite and deleted-source archival, preserving undeployed-source targets. Restored exact-preview choice matching and identical-request retry behavior on fields and apply intros. Replaced mechanical body/result text with operation-specific descriptions and human schema titles, preserving stable IDs. | Verified improvement. Summary: Pull Workspace → Pull workspace; sentence case matches the editorial guide. description: Apply a reviewed push or pull with inline mappings in one transaction. Requires confirmation, the preview fingerprint, and a stable request ID. Unresolved or changed plans return … → Apply a reviewed sync from the other workspace into this workspace along a direct fork edge. Requires Admin access to both workspaces. Creates unmatched deployed workflows, overwr… requestBody.content.application/json.schema.description: The body for this operation. → Confirmed other-to-current choices, actual preview fingerprint, and stable request ID. requestBody.content.application/json.schema.properties.confirm.description: Explicit acknowledgement that sync replaces target workflows. → Confirm replacement of mapped target drafts and archival of mapped targets whose sources were deleted or archived. 4 request/response media example set(s) now expose the owner's existing examples to the API renderer. Preserved: Compared operationId pullWorkspace, POST /api/v2/workspaces/{workspaceId}/fork/pull, security and x-sim-operation with baseline; identifiers, route and credential schemes match. Recursive prose/default/example mappings retained in final-review-api-comparison.json; 24 distinct changed field mappings were inspected for this operation. Operation-level request/response structure, parameters, required fields, defaults and status declarations are identical after removing prose/examples; referenced component changes were reviewed separately. | +| `getWorkspaceForkAvailability` — `GET /api/v2/workspaces/{workspaceId}/fork/availability` | corrected | Named current/source/both-side/target Admin access and qualified feature gate by billing mode rather than hosting location. Replaced mechanical body/result text with operation-specific descriptions and human schema titles, preserving stable IDs. | Verified improvement. Summary: Get Workspace Fork Availability → Get workspace fork availability; sentence case matches the editorial guide. description: Inspect workspace fork information and copyable resources. Lineage does not grant access to the other workspace; fork creation requires source admin and sync requires admin on bot… → Check whether workspace forking is enabled for this deployment and workspace plan. Requires workspace Admin access. Returns `available: false` when the feature gate is unmet. Bill… responses.200.content.application/json.schema.description: The response for this operation. → Whether forking is enabled for this deployment and workspace plan. responses.200.description: The workspace operation result. → Whether forking is enabled for this deployment and workspace plan. Preserved: Compared operationId getWorkspaceForkAvailability, GET /api/v2/workspaces/{workspaceId}/fork/availability, security and x-sim-operation with baseline; identifiers, route and credential schemes match. Recursive prose/default/example mappings retained in final-review-api-comparison.json; 6 distinct changed field mappings were inspected for this operation. Operation-level request/response structure, parameters, required fields, defaults and status declarations are identical after removing prose/examples; referenced component changes were reviewed separately. | +| `getWorkspaceForkLineage` — `GET /api/v2/workspaces/{workspaceId}/fork/lineage` | corrected | Named current/source/both-side/target Admin access and qualified feature gate by billing mode rather than hosting location. Replaced mechanical body/result text with operation-specific descriptions and human schema titles, preserving stable IDs. | Verified improvement. Summary: Get Workspace Fork Lineage → Get workspace fork lineage; sentence case matches the editorial guide. description: Inspect workspace fork information and copyable resources. Lineage does not grant access to the other workspace; fork creation requires source admin and sync requires admin on bot… → Read this workspace and its direct parent, or `parent: null` when it has no active parent. Requires workspace Admin access. The relationship does not grant access to the parent. B… responses.200.content.application/json.schema.description: The response for this operation. → Current workspace and its active direct parent, when present. responses.200.description: The workspace operation result. → Current workspace and its active direct parent, when present. Preserved: Compared operationId getWorkspaceForkLineage, GET /api/v2/workspaces/{workspaceId}/fork/lineage, security and x-sim-operation with baseline; identifiers, route and credential schemes match. Recursive prose/default/example mappings retained in final-review-api-comparison.json; 6 distinct changed field mappings were inspected for this operation. Operation-level request/response structure, parameters, required fields, defaults and status declarations are identical after removing prose/examples; referenced component changes were reviewed separately. | +| `listWorkspaceForkChildren` — `GET /api/v2/workspaces/{workspaceId}/fork/children` | corrected | Named current/source/both-side/target Admin access and qualified feature gate by billing mode rather than hosting location. Replaced mechanical body/result text with operation-specific descriptions and human schema titles, preserving stable IDs. | Verified improvement. Summary: List Workspace Fork Children → List workspace fork children; sentence case matches the editorial guide. description: Inspect workspace fork information and copyable resources. Lineage does not grant access to the other workspace; fork creation requires source admin and sync requires admin on bot… → List this workspace's active direct children, newest first, with cursor pagination. Requires workspace Admin access. A fork relationship does not grant access to a child workspace… responses.200.content.application/json.schema.description: The response for this operation. → A page of active direct child workspaces. responses.200.content.application/json.schema.properties.data.items.description: The ListWorkspaceForkChildrenResult result. → An active direct child workspace. Preserved: Compared operationId listWorkspaceForkChildren, GET /api/v2/workspaces/{workspaceId}/fork/children, security and x-sim-operation with baseline; identifiers, route and credential schemes match. Recursive prose/default/example mappings retained in final-review-api-comparison.json; 8 distinct changed field mappings were inspected for this operation. Operation-level request/response structure, parameters, required fields, defaults and status declarations are identical after removing prose/examples; referenced component changes were reviewed separately. | +| `listWorkspaceForkResources` — `GET /api/v2/workspaces/{workspaceId}/fork/resources` | corrected | Named current/source/both-side/target Admin access and qualified feature gate by billing mode rather than hosting location. Replaced mechanical body/result text with operation-specific descriptions and human schema titles, preserving stable IDs. | Verified improvement. Summary: List Workspace Fork Resources → List workspace fork resources; sentence case matches the editorial guide. description: Inspect workspace fork information and copyable resources. Lineage does not grant access to the other workspace; fork creation requires source admin and sync requires admin on bot… → List copyable resources of one kind in this workspace with cursor pagination. Requires workspace Admin access. Fork creation uses file IDs; sync copy choices use file storage keys… parameters[3].description: Resource or operation kind. → Kind of source resource to list for copy selection. parameters[3].schema.description: Resource or operation kind. → Kind of source resource to list for copy selection. Preserved: Compared operationId listWorkspaceForkResources, GET /api/v2/workspaces/{workspaceId}/fork/resources, security and x-sim-operation with baseline; identifiers, route and credential schemes match. Recursive prose/default/example mappings retained in final-review-api-comparison.json; 10 distinct changed field mappings were inspected for this operation. Operation-level request/response structure, parameters, required fields, defaults and status declarations are identical after removing prose/examples; referenced component changes were reviewed separately. | +| `getWorkspaceForkMappings` — `GET /api/v2/workspaces/{workspaceId}/fork/mappings` | corrected | Named current/source/both-side/target Admin access and qualified feature gate by billing mode rather than hosting location. Replaced mechanical body/result text with operation-specific descriptions and human schema titles, preserving stable IDs. | Verified improvement. Summary: Get Workspace Fork Mappings → Get workspace fork mappings; sentence case matches the editorial guide. description: Read persisted mappings in the requested source-to-target direction. Candidate discovery uses the destination resource and selector listing operations. Workspace API keys return `… → Read persisted resource mappings in the requested source-to-target direction along a direct fork edge. Requires Admin access to both workspaces. Discover candidates with destinati… responses.200.content.application/json.schema.description: The response for this operation. → A page of persisted source-to-target mapping entries. responses.200.content.application/json.schema.properties.data.items.description: The GetWorkspaceForkMappingsResult result. → A saved directional mapping entry. Preserved: Compared operationId getWorkspaceForkMappings, GET /api/v2/workspaces/{workspaceId}/fork/mappings, security and x-sim-operation with baseline; identifiers, route and credential schemes match. Recursive prose/default/example mappings retained in final-review-api-comparison.json; 8 distinct changed field mappings were inspected for this operation. Operation-level request/response structure, parameters, required fields, defaults and status declarations are identical after removing prose/examples; referenced component changes were reviewed separately. | +| `updateWorkspaceForkMappings` — `PUT /api/v2/workspaces/{workspaceId}/fork/mappings` | corrected | Named current/source/both-side/target Admin access and qualified feature gate by billing mode rather than hosting location. Replaced mechanical body/result text with operation-specific descriptions and human schema titles, preserving stable IDs. | Verified improvement. Summary: Update Workspace Fork Mappings → Update workspace fork mappings; sentence case matches the editorial guide. description: Update edge mappings after validating destination resource membership and credential provider compatibility. Push addresses current-to-other mappings; pull addresses other-to-curr… → Update mappings along a direct fork edge with Admin access to both workspaces. Destination resource membership and credential provider compatibility are validated. Push maps curre… requestBody.content.application/json.schema.description: The body for this operation. → Other workspace, direction, and mapping entries to update. requestBody.content.application/json.schema.properties.mappings.description: Mappings keyed by resource type and source identifier. → Mapping entries addressed by resource type and `sourceId`. `targetId: null` clears a mapping. Preserved: Compared operationId updateWorkspaceForkMappings, PUT /api/v2/workspaces/{workspaceId}/fork/mappings, security and x-sim-operation with baseline; identifiers, route and credential schemes match. Recursive prose/default/example mappings retained in final-review-api-comparison.json; 9 distinct changed field mappings were inspected for this operation. Operation-level request/response structure, parameters, required fields, defaults and status declarations are identical after removing prose/examples; referenced component changes were reviewed separately. | +| `rollbackWorkspaceFork` — `POST /api/v2/workspaces/{workspaceId}/fork/rollback` | corrected | Named current/source/both-side/target Admin access and qualified feature gate by billing mode rather than hosting location. Replaced mechanical body/result text with operation-specific descriptions and human schema titles, preserving stable IDs. Kept undeployed-copy, same-workflow source state, trigger shutdown, and pending-rollback consequences close to their actions. | Verified improvement. Summary: Rollback Workspace Fork → Rollback workspace fork; sentence case matches the editorial guide. description: Restore the latest sync into this workspace using its prior deployed versions. Requires target admin. It does not restore arbitrary drafts or remove every copied resource. Pending… → Restore the latest sync into this workspace from the named other workspace using prior deployed versions. Requires target workspace Admin access. A newer sync from another fork ed… requestBody.content.application/json.schema.description: The body for this operation. → Other workspace whose latest inbound sync should be undone. requestBody.description: The body for this operation. → Other workspace whose latest inbound sync should be undone. Preserved: Compared operationId rollbackWorkspaceFork, POST /api/v2/workspaces/{workspaceId}/fork/rollback, security and x-sim-operation with baseline; identifiers, route and credential schemes match. Recursive prose/default/example mappings retained in final-review-api-comparison.json; 8 distinct changed field mappings were inspected for this operation. Operation-level request/response structure, parameters, required fields, defaults and status declarations are identical after removing prose/examples; referenced component changes were reviewed separately. | +| `unlinkWorkspaceFork` — `POST /api/v2/workspaces/{workspaceId}/fork/unlink` | corrected | Named current/source/both-side/target Admin access and qualified feature gate by billing mode rather than hosting location. Replaced mechanical body/result text with operation-specific descriptions and human schema titles, preserving stable IDs. | Verified improvement. Summary: Unlink Workspace Fork → Unlink workspace fork; sentence case matches the editorial guide. description: Remove the direct fork relationship and its mappings. Requires admin on the acting workspace. Existing workflow and resource content remains available. Workspace API keys return `… → Remove the direct fork relationship and its mappings with Admin access to the acting workspace. Existing workflows and resources remain available. Billing-enabled deployments requ… requestBody.content.application/json.schema.description: The body for this operation. → Other workspace on the direct fork edge to remove. requestBody.description: The body for this operation. → Other workspace on the direct fork edge to remove. Preserved: Compared operationId unlinkWorkspaceFork, POST /api/v2/workspaces/{workspaceId}/fork/unlink, security and x-sim-operation with baseline; identifiers, route and credential schemes match. Recursive prose/default/example mappings retained in final-review-api-comparison.json; 8 distinct changed field mappings were inspected for this operation. Operation-level request/response structure, parameters, required fields, defaults and status declarations are identical after removing prose/examples; referenced component changes were reviewed separately. | +| `updateWorkspaceForkExclusions` — `PUT /api/v2/workspaces/{workspaceId}/fork/exclusions` | corrected | Named current/source/both-side/target Admin access and qualified feature gate by billing mode rather than hosting location. Replaced mechanical body/result text with operation-specific descriptions and human schema titles, preserving stable IDs. | Verified improvement. Summary: Update Workspace Fork Exclusions → Update workspace fork exclusions; sentence case matches the editorial guide. description: Include or exclude selected workflows from fork sync. Excluded workflows are skipped as sources and targets. Missing, archived, and unchanged workflow IDs are skipped. Workspace A… → Include or exclude selected workflows from fork sync with workspace Admin access. Excluded workflows are skipped as sources and targets. Missing, archived, and unchanged workflow … requestBody.content.application/json.schema.description: The body for this operation. → Workflow IDs and whether to exclude them from sync. requestBody.description: The body for this operation. → Workflow IDs and whether to exclude them from sync. Preserved: Compared operationId updateWorkspaceForkExclusions, PUT /api/v2/workspaces/{workspaceId}/fork/exclusions, security and x-sim-operation with baseline; identifiers, route and credential schemes match. Recursive prose/default/example mappings retained in final-review-api-comparison.json; 8 distinct changed field mappings were inspected for this operation. Operation-level request/response structure, parameters, required fields, defaults and status declarations are identical after removing prose/examples; referenced component changes were reviewed separately. | +| `previewWorkflowImport` — `POST /api/v2/workflows/import/preview` | corrected | Restored exact-preview choice matching and identical-request retry behavior on fields and apply intros. Replaced mechanical body/result text with operation-specific descriptions and human schema titles, preserving stable IDs. | Verified improvement. Summary: Preview Workflow Import → Preview workflow import; sentence case matches the editorial guide. description: Validate destination mappings and dependent choices without creating a workflow. Returns unresolved fields, discovery instructions, and a fingerprint required by mapped import. No… → Validate destination mappings and configuration with workspace write access, without creating a workflow. The result reports readiness, unresolved fields, discovery instructions, … requestBody.content.application/json.schema.properties.dependentValues.description: Destination-dependent choices keyed by source workflow, block, and field identities. → Destination-specific values addressed by the source block ID and field key, before imported IDs are regenerated. requestBody.content.application/json.schema.properties.mappings.description: Mappings keyed by resource type and source identifier. → Mapping entries addressed by resource kind and source identifier. 1 request/response media example set(s) now expose the owner's existing examples to the API renderer. Preserved: Compared operationId previewWorkflowImport, POST /api/v2/workflows/import/preview, security and x-sim-operation with baseline; identifiers, route and credential schemes match. Recursive prose/default/example mappings retained in final-review-api-comparison.json; 11 distinct changed field mappings were inspected for this operation. Operation-level request/response structure, parameters, required fields, defaults and status declarations are identical after removing prose/examples; referenced component changes were reviewed separately. | +| `listSelector` — `POST /api/v2/selectors/list` | corrected | Documented selector cursor scope/restart, data:null, truncation and bounded verification. Replaced mechanical body/result text with operation-specific descriptions and human schema titles, preserving stable IDs. | Verified improvement. Summary: List Selector Options → List selector options; sentence case matches the editorial guide. description: List workspace-scoped configuration choices using the selector key and dependencies from an import or sync preview. Missing OAuth connections require human authorization before pr… → List authorized workspace configuration choices using the selector key and context from an import or sync preview. Requires workspace read access. Missing OAuth connections requir… requestBody.content.application/json.schema.description: The body for this operation. → Workspace, registered selector key, context, and optional search/cursor. requestBody.content.application/json.schema.properties.cursor.description: Opaque continuation cursor returned by the preceding page. → Cursor returned by the preceding page. Keep `workspaceId`, `selectorKey`, `context`, and `search` unchanged; only `limit` may change. Restart without a cursor after a changed-page… Preserved: Compared operationId listSelector, POST /api/v2/selectors/list, security and x-sim-operation with baseline; identifiers, route and credential schemes match. Recursive prose/default/example mappings retained in final-review-api-comparison.json; 13 distinct changed field mappings were inspected for this operation. Operation-level request/response structure, parameters, required fields, defaults and status declarations are identical after removing prose/examples; referenced component changes were reviewed separately. | +| `getSelector` — `POST /api/v2/selectors/get` | corrected | Documented selector cursor scope/restart, data:null, truncation and bounded verification. Replaced mechanical body/result text with operation-specific descriptions and human schema titles, preserving stable IDs. | Verified improvement. Summary: Get Selector Option → Get selector option; sentence case matches the editorial guide. description: Resolve a workspace configuration option by its provider identifier and declared dependencies. Workspace API keys return `403`; use a personal API key or scoped OAuth token. OAuth… → Get an authorized configuration choice by provider ID and declared context with workspace read access. Returns `data: null` when the option is absent from complete results. Trunca… requestBody.content.application/json.schema.description: The body for this operation. → Workspace, registered selector key, context, and provider option ID. requestBody.content.application/json.schema.properties.id.description: Resource identifier. → Provider option ID to resolve with the same selector and declared context. Preserved: Compared operationId getSelector, POST /api/v2/selectors/get, security and x-sim-operation with baseline; identifiers, route and credential schemes match. Recursive prose/default/example mappings retained in final-review-api-comparison.json; 10 distinct changed field mappings were inspected for this operation. Operation-level request/response structure, parameters, required fields, defaults and status declarations are identical after removing prose/examples; referenced component changes were reviewed separately. | +| `getWorkspaceOperation` — `GET /api/v2/workspaces/{workspaceId}/operations/{operationId}` | rewritten | Replaced mechanical body/result text with operation-specific descriptions and human schema titles, preserving stable IDs. | Verified improvement. Summary: Get Workspace Operation → Get workspace operation; sentence case matches the editorial guide. description: Read a committed operation, copy progress, exact deployment readiness, and structured issues. A failed follow-up does not mean the business transaction was rolled back. OAuth scop… → Read a committed operation and refresh its copy progress, exact admitted deployment readiness, and structured issues with workspace read access. `applied: true` means the transact… responses.200.content.application/json.schema.description: The response for this operation. → Refreshed commit, copy progress, and exact deployment readiness. responses.200.content.application/json.schema.properties.data.properties.copyProgress.properties.status.description: Current operation or deployment outcome. → Background resource-copy status. Preserved: Compared operationId getWorkspaceOperation, GET /api/v2/workspaces/{workspaceId}/operations/{operationId}, security and x-sim-operation with baseline; identifiers, route and credential schemes match. Recursive prose/default/example mappings retained in final-review-api-comparison.json; 13 distinct changed field mappings were inspected for this operation. Operation-level request/response structure, parameters, required fields, defaults and status declarations are identical after removing prose/examples; referenced component changes were reviewed separately. | +| `listWorkspaceOperations` — `GET /api/v2/workspaces/{workspaceId}/operations` | rewritten | Replaced mechanical body/result text with operation-specific descriptions and human schema titles, preserving stable IDs. | Verified improvement. Summary: List Workspace Operations → List workspace operations; sentence case matches the editorial guide. description: Page committed operations newest first. Filter by the original request ID to reconcile an uncertain mutation response. OAuth scope: `api:read`. → List stored operation receipts newest first with workspace read access. Filter by the original `requestId` to reconcile an uncertain mutation response. Read an individual operatio… parameters[3].description: Stable client request ID for reconciliation and identical retries. → Find an uncertain mutation by the original client request ID; keep the same filter while paging. parameters[3].schema.description: Stable client request ID for reconciliation and identical retries. → Find an uncertain mutation by the original client request ID; keep the same filter while paging. Preserved: Compared operationId listWorkspaceOperations, GET /api/v2/workspaces/{workspaceId}/operations, security and x-sim-operation with baseline; identifiers, route and credential schemes match. Recursive prose/default/example mappings retained in final-review-api-comparison.json; 17 distinct changed field mappings were inspected for this operation. Operation-level request/response structure, parameters, required fields, defaults and status declarations are identical after removing prose/examples; referenced component changes were reviewed separately. | + +### API workspace operations (108) + +| Page or operation | Result | Changes | Final comparison and preservation | +| --- | --- | --- | --- | +| `getBillingStatus` — `GET /api/v2/billing/status` | rewritten | Copy standardized; no operation-specific discrepancy found. | Verified improvement. Summary: Get Billing Status → Get billing status; sentence case matches the editorial guide. parameters[0].description: Workspace whose payer should be resolved. A workspace API key is pinned to its own workspace: any other id answers `404 Workspace not found`, which is also what an id that does no… → Workspace whose payer to report. A workspace API key is bound to its own workspace; a different or unknown ID returns `404 Workspace not found`. Omit for account billing when usin… parameters[0].schema.description: Workspace whose payer should be resolved. A workspace API key is pinned to its own workspace: any other id answers `404 Workspace not found`, which is also what an id that does no… → Workspace whose payer to report. A workspace API key is bound to its own workspace; a different or unknown ID returns `404 Workspace not found`. Omit for account billing when usin… responses.200.content.application/json.schema.properties.data.properties.credits.anyOf[0].properties.used.description: Credits consumed so far. The counter is reset by Stripe invoice webhooks, so on a paid plan it covers the current billing period; on the free plan nothing resets it and the value … → Credits consumed during the current billing period on a paid plan, or over the account’s lifetime on Free. 1 request/response media example set(s) now expose the owner's existing examples to the API renderer. Preserved: Compared operationId getBillingStatus, GET /api/v2/billing/status, security and x-sim-operation with baseline; identifiers, route and credential schemes match. Recursive prose/default/example mappings retained in final-review-api-comparison.json; 9 distinct changed field mappings were inspected for this operation. Operation-level request/response structure, parameters, required fields, defaults and status declarations are identical after removing prose/examples; referenced component changes were reviewed separately. | +| `listBillingLogs` — `GET /api/v2/billing/logs` | rewritten | Copy standardized; no operation-specific discrepancy found. Review correction: mothership_block remains the distinct Agent-block source. | Verified improvement. Summary: List Billing Logs → List billing logs; sentence case matches the editorial guide. parameters[3].description: Only include usage events recorded at or after this UTC ISO 8601 timestamp, e.g. `2026-08-06T00:00:00Z`. Requires `period=custom`. A date without a time, or a timestamp carrying a… → Include events at or after this UTC ISO 8601 timestamp, for example `2026-08-06T00:00:00Z`. Required with `period=custom`. Date-only values, UTC offsets instead of `Z`, and year `… parameters[3].schema.description: Only include usage events recorded at or after this UTC ISO 8601 timestamp, e.g. `2026-08-06T00:00:00Z`. Requires `period=custom`. A date without a time, or a timestamp carrying a… → Include events at or after this UTC ISO 8601 timestamp, for example `2026-08-06T00:00:00Z`. Required with `period=custom`. Date-only values, UTC offsets instead of `Z`, and year `… parameters[4].description: Only include usage events recorded at or before this UTC ISO 8601 timestamp, e.g. `2026-08-06T00:00:00Z`. Requires `period=custom`, and defaults to now when omitted. A date withou… → Include events at or before this UTC ISO 8601 timestamp, for example `2026-08-06T00:00:00Z`. Allowed only with `period=custom`; omission defaults to now. Date-only values, UTC off… 1 request/response media example set(s) now expose the owner's existing examples to the API renderer. Preserved: Compared operationId listBillingLogs, GET /api/v2/billing/logs, security and x-sim-operation with baseline; identifiers, route and credential schemes match. Recursive prose/default/example mappings retained in final-review-api-comparison.json; 9 distinct changed field mappings were inspected for this operation. Operation-level request/response structure, parameters, required fields, defaults and status declarations are identical after removing prose/examples; referenced component changes were reviewed separately. | +| `listWorkspaces` — `GET /api/v2/workspaces` | corrected | Active credential-filtered 25-item default; fix sort rationale. Shared name-sort rationale corrected by root; local sort fields/defaults preserved. | Verified improvement. Summary: List Workspaces → List workspaces; sentence case matches the editorial guide. description: List active workspaces available to the calling credential with opaque cursor pagination. A personal API key or OAuth token sees accessible workspaces that permit user-held API cr… → List active workspaces available to the calling credential. Personal API keys and OAuth tokens see accessible workspaces that permit user-held API credentials; a workspace API key… parameters[0].description: Field used to sort the result. Sorting by `name` is case-sensitive and follows the storage collation, so do not rely on a case-insensitive order. → Field used to sort the result. Do not rely on case-insensitive ordering when sorting by `name`. parameters[0].schema.description: Field used to sort the result. Sorting by `name` is case-sensitive and follows the storage collation, so do not rely on a case-insensitive order. → Field used to sort the result. Do not rely on case-insensitive ordering when sorting by `name`. 1 request/response media example set(s) now expose the owner's existing examples to the API renderer. Preserved: Compared operationId listWorkspaces, GET /api/v2/workspaces, security and x-sim-operation with baseline; identifiers, route and credential schemes match. Recursive prose/default/example mappings retained in final-review-api-comparison.json; 9 distinct changed field mappings were inspected for this operation. Operation-level request/response structure, parameters, required fields, defaults and status declarations are identical after removing prose/examples; referenced component changes were reviewed separately. | +| `getWorkspace` — `GET /api/v2/workspaces/{workspaceId}` | rewritten | Copy standardized; no operation-specific discrepancy found. | Verified improvement. Summary: Get Workspace → Get workspace; sentence case matches the editorial guide. description: Get metadata for an accessible workspace. OAuth scope: `api:read`. → Get metadata for a workspace the calling credential can access. Requires workspace read access. OAuth scope: `api:read`. responses.200.content.application/json.schema.description: Public metadata for one workspace. → Metadata for one workspace. responses.200.description: Public workspace metadata. → Workspace metadata. 1 request/response media example set(s) now expose the owner's existing examples to the API renderer. Preserved: Compared operationId getWorkspace, GET /api/v2/workspaces/{workspaceId}, security and x-sim-operation with baseline; identifiers, route and credential schemes match. Recursive prose/default/example mappings retained in final-review-api-comparison.json; 6 distinct changed field mappings were inspected for this operation. Operation-level request/response structure, parameters, required fields, defaults and status declarations are identical after removing prose/examples; referenced component changes were reviewed separately. | +| `listWorkspaceMembers` — `GET /api/v2/workspaces/{workspaceId}/members` | rewritten | Copy standardized; no operation-specific discrepancy found. | Verified improvement. Summary: List Workspace Members → List workspace members; sentence case matches the editorial guide. description: List workspace members by email, including explicit grants and inherited organization admin access. Each member includes a stable user ID for member administration. OAuth scope: `… → List effective workspace members, ordered by email, including explicit grants and inherited organization Admin access. Use each member’s `userId` for member administration. Requir… responses.200.content.application/json.schema.properties.nextCursor.description: Opaque cursor for the next page. Send it back as `cursor`; `null` means there is nothing further to fetch. Never construct one yourself. → Opaque cursor for the next page. Send it back as `cursor`; `null` means there are no more pages. Do not construct a cursor yourself. responses.503.description: A required service is temporarily unavailable. `Retry-After` carries the seconds to wait; treat it as a floor and add jitter. The header is omitted when `error.details.code` is `A… → A required service is temporarily unavailable. When present, `Retry-After` gives the minimum seconds to wait; add jitter before retrying. Check operation-specific guidance before … 1 request/response media example set(s) now expose the owner's existing examples to the API renderer. Preserved: Compared operationId listWorkspaceMembers, GET /api/v2/workspaces/{workspaceId}/members, security and x-sim-operation with baseline; identifiers, route and credential schemes match. Recursive prose/default/example mappings retained in final-review-api-comparison.json; 5 distinct changed field mappings were inspected for this operation. Operation-level request/response structure, parameters, required fields, defaults and status declarations are identical after removing prose/examples; referenced component changes were reviewed separately. | +| `listMcpServers` — `GET /api/v2/mcp-servers` | rewritten | Copy standardized; no operation-specific discrepancy found. Review correction: re-registration resets connection state only when connection inputs change. | Verified improvement. Summary: List MCP Servers → List MCP servers; sentence case matches the editorial guide. description: List MCP servers registered in a workspace, excluding request-header values and OAuth secrets. Connection metadata remains at registration defaults until List MCP Server Tools per… → List external MCP servers registered in the workspace. Request-header values and OAuth secrets are omitted. Connection metadata remains at registration defaults until List MCP ser… parameters[2].description: Field used to sort the result. Sorting by `name` is case-sensitive and follows the storage collation, so do not rely on a case-insensitive order. → Field used to sort the result. Do not rely on case-insensitive ordering when sorting by `name`. parameters[2].schema.description: Field used to sort the result. Sorting by `name` is case-sensitive and follows the storage collation, so do not rely on a case-insensitive order. → Field used to sort the result. Do not rely on case-insensitive ordering when sorting by `name`. 1 request/response media example set(s) now expose the owner's existing examples to the API renderer. Preserved: Compared operationId listMcpServers, GET /api/v2/mcp-servers, security and x-sim-operation with baseline; identifiers, route and credential schemes match. Recursive prose/default/example mappings retained in final-review-api-comparison.json; 8 distinct changed field mappings were inspected for this operation. Operation-level request/response structure, parameters, required fields, defaults and status declarations are identical after removing prose/examples; referenced component changes were reviewed separately. | +| `createMcpServer` — `POST /api/v2/mcp-servers` | rewritten | Copy standardized; no operation-specific discrepancy found. Review correction: probe outcomes include OAuth, unauthenticated success and header fallback. | Verified improvement. Summary: Create MCP Server → Create MCP server; sentence case matches the editorial guide. description: Register an external MCP server without connecting to it. A duplicate URL returns `409`; use Update MCP Server to change the existing registration. The server remains disconnected… → Register an external MCP server without establishing a tool connection; registration may probe its authentication method. A duplicate URL returns `409`; use Update MCP server to c… requestBody.content.application/json.schema.properties.authType.description: Authentication method. When omitted, and no `headers` are sent, registration probes the endpoint once to classify it, falling back to `headers` when the probe fails or the server … → Authentication method. If omitted without `headers`, registration probes once for OAuth protected-resource metadata (RFC 9728), otherwise falling back to `headers`. Set this field… responses.201.content.application/json.schema.properties.data.properties.connectionStatus.description: Result of the most recent connection attempt. Registration and re-registration establish no connection — the auth-type probe they may send does not count as one — so a server begi… → Result of the most recent tool connection attempt. Registration and re-registration set `disconnected`; their authentication probes do not establish a tool connection. Tool discov… 2 request/response media example set(s) now expose the owner's existing examples to the API renderer. Preserved: Compared operationId createMcpServer, POST /api/v2/mcp-servers, security and x-sim-operation with baseline; identifiers, route and credential schemes match. Recursive prose/default/example mappings retained in final-review-api-comparison.json; 7 distinct changed field mappings were inspected for this operation. Operation-level request/response structure, parameters, required fields, defaults and status declarations are identical after removing prose/examples; referenced component changes were reviewed separately. | +| `getMcpServer` — `GET /api/v2/mcp-servers/{mcpServerId}` | rewritten | Copy standardized; no operation-specific discrepancy found. Review correction: re-registration resets connection state only when connection inputs change. | Verified improvement. Summary: Get MCP Server → Get MCP server; sentence case matches the editorial guide. description: Get one MCP server by identifier. Request-header values and OAuth client secrets are never returned. OAuth scope: `api:read`. → Get a registered external MCP server. Request-header values and OAuth client secrets are omitted. Requires workspace read access. OAuth scope: `api:read`. responses.200.content.application/json.schema.properties.data.properties.connectionStatus.description: Result of the most recent connection attempt. Registration and re-registration establish no connection — the auth-type probe they may send does not count as one — so a server begi… → Result of the most recent tool connection attempt. Registration and re-registration set `disconnected`; their authentication probes do not establish a tool connection. Tool discov… responses.503.description: A required service is temporarily unavailable. `Retry-After` carries the seconds to wait; treat it as a floor and add jitter. The header is omitted when `error.details.code` is `A… → A required service is temporarily unavailable. When present, `Retry-After` gives the minimum seconds to wait; add jitter before retrying. Check operation-specific guidance before … 1 request/response media example set(s) now expose the owner's existing examples to the API renderer. Preserved: Compared operationId getMcpServer, GET /api/v2/mcp-servers/{mcpServerId}, security and x-sim-operation with baseline; identifiers, route and credential schemes match. Recursive prose/default/example mappings retained in final-review-api-comparison.json; 5 distinct changed field mappings were inspected for this operation. Operation-level request/response structure, parameters, required fields, defaults and status declarations are identical after removing prose/examples; referenced component changes were reviewed separately. | +| `updateMcpServer` — `PATCH /api/v2/mcp-servers/{mcpServerId}` | rewritten | Copy standardized; no operation-specific discrepancy found. | Verified improvement. Summary: Update MCP Server → Update MCP server; sentence case matches the editorial guide. description: Update an MCP server's supplied fields. Omitted fields remain unchanged unless the field specifies otherwise. Authentication changes revoke the stored OAuth grant and reset connec… → Update an external MCP server. Omitted fields remain unchanged unless a field specifies otherwise. Authentication changes revoke its stored OAuth grant and reset connection metada… requestBody.content.application/json.schema.properties.authType.description: Authentication method. When omitted, and no `headers` are sent, registration probes the endpoint once to classify it, falling back to `headers` when the probe fails or the server … → Authentication method. If omitted without `headers`, registration probes once for OAuth protected-resource metadata (RFC 9728), otherwise falling back to `headers`. Set this field… responses.200.content.application/json.schema.properties.data.properties.connectionStatus.description: Result of the most recent connection attempt. Registration and re-registration establish no connection — the auth-type probe they may send does not count as one — so a server begi… → Result of the most recent tool connection attempt. Registration and re-registration set `disconnected`; their authentication probes do not establish a tool connection. Tool discov… 2 request/response media example set(s) now expose the owner's existing examples to the API renderer. Preserved: Compared operationId updateMcpServer, PATCH /api/v2/mcp-servers/{mcpServerId}, security and x-sim-operation with baseline; identifiers, route and credential schemes match. Recursive prose/default/example mappings retained in final-review-api-comparison.json; 7 distinct changed field mappings were inspected for this operation. Operation-level request/response structure, parameters, required fields, defaults and status declarations are identical after removing prose/examples; referenced component changes were reviewed separately. | +| `deleteMcpServer` — `DELETE /api/v2/mcp-servers/{mcpServerId}` | rewritten | Copy standardized; no operation-specific discrepancy found. | Verified improvement. Summary: Delete MCP Server → Delete MCP server; sentence case matches the editorial guide. description: Remove an MCP server and revoke its OAuth tokens. Workflows retain blocks that referenced the server's tools, but those tools can no longer be called. OAuth scope: `api:write`. → Remove an external MCP server and revoke its OAuth tokens. Workflow blocks retain references to its tools, but those tools can no longer be called. Requires workspace write access… responses.503.description: A required service is temporarily unavailable. `Retry-After` carries the seconds to wait; treat it as a floor and add jitter. The header is omitted when `error.details.code` is `A… → A required service is temporarily unavailable. When present, `Retry-After` gives the minimum seconds to wait; add jitter before retrying. Check operation-specific guidance before … 1 request/response media example set(s) now expose the owner's existing examples to the API renderer. Preserved: Compared operationId deleteMcpServer, DELETE /api/v2/mcp-servers/{mcpServerId}, security and x-sim-operation with baseline; identifiers, route and credential schemes match. Recursive prose/default/example mappings retained in final-review-api-comparison.json; 4 distinct changed field mappings were inspected for this operation. Operation-level request/response structure, parameters, required fields, defaults and status declarations are identical after removing prose/examples; referenced component changes were reviewed separately. | +| `listMcpServerTools` — `GET /api/v2/mcp-servers/{mcpServerId}/tools` | corrected | Partial inventory, disabled/managed states need explicit qualifications. | Verified improvement. Summary: List MCP Server Tools → List MCP server tools; sentence case matches the editorial guide. description: Discover up to 1,000 tools within 5 MB, connect to the server, and update connection metadata. Results are unpaginated. Invalid OAuth returns `409` with `MCP_SERVER_REAUTHORIZATIO… → Discover tools on an enabled external MCP server and update connection metadata. Discovery is bounded by 1,000 tools, 5 MiB, 50 upstream pages, and 60 seconds; limits or later-pag… responses.200.content.application/json.schema.description: Tools exposed by the MCP server. → Tools discovered so far. Limits or later-page failures can leave the inventory incomplete; the response has no truncation indicator or pagination. responses.200.content.application/json.schema.properties.nextCursor.description: Always `null` — this list has no `cursor` or `limit` param and returns its whole bounded set in one page. Present so the list can gain pages later without a shape change. → Always `null`. This list has no `cursor` or `limit` parameters; see the operation for inventory limits. 1 request/response media example set(s) now expose the owner's existing examples to the API renderer. Preserved: Compared operationId listMcpServerTools, GET /api/v2/mcp-servers/{mcpServerId}/tools, security and x-sim-operation with baseline; identifiers, route and credential schemes match. Recursive prose/default/example mappings retained in final-review-api-comparison.json; 7 distinct changed field mappings were inspected for this operation. Operation-level request/response structure, parameters, required fields, defaults and status declarations are identical after removing prose/examples; referenced component changes were reviewed separately. | +| `listSkills` — `GET /api/v2/skills` | corrected | Bodies omitted/built-ins IDs/epochs verified; fix sort rationale. Shared name-sort rationale corrected by root; local sort fields/defaults preserved. | Verified improvement. Summary: List Skills → List skills; sentence case matches the editorial guide. description: List workspace and built-in skills with cursor pagination. Built-in skills are read-only. The list omits skill bodies; use Get Skill to read content. OAuth scope: `api:read`. → List workspace and built-in skills with cursor pagination. Built-in skills are read-only. Skill bodies are omitted; use Get skill to read content. Requires workspace read access. … parameters[2].description: Field used to sort the result. Sorting by `name` is case-sensitive and follows the storage collation, so do not rely on a case-insensitive order. → Field used to sort the result. Do not rely on case-insensitive ordering when sorting by `name`. parameters[2].schema.description: Field used to sort the result. Sorting by `name` is case-sensitive and follows the storage collation, so do not rely on a case-insensitive order. → Field used to sort the result. Do not rely on case-insensitive ordering when sorting by `name`. 1 request/response media example set(s) now expose the owner's existing examples to the API renderer. Preserved: Compared operationId listSkills, GET /api/v2/skills, security and x-sim-operation with baseline; identifiers, route and credential schemes match. Recursive prose/default/example mappings retained in final-review-api-comparison.json; 7 distinct changed field mappings were inspected for this operation. Operation-level request/response structure, parameters, required fields, defaults and status declarations are identical after removing prose/examples; referenced component changes were reviewed separately. | +| `createSkill` — `POST /api/v2/skills` | rewritten | Copy standardized; no operation-specific discrepancy found. | Verified improvement. Summary: Create Skill → Create skill; sentence case matches the editorial guide. description: Create one skill in a workspace. Its kebab-case name must be unique and cannot be reserved by a built-in skill. Workspace API keys return `403`; use a personal API key or scoped O… → Create a workspace skill with a unique kebab-case name that is not reserved by a built-in skill. Requires workspace write access. Workspace API keys return `403`; use a personal A… responses.503.description: A required service is temporarily unavailable. `Retry-After` carries the seconds to wait; treat it as a floor and add jitter. The header is omitted when `error.details.code` is `A… → A required service is temporarily unavailable. When present, `Retry-After` gives the minimum seconds to wait; add jitter before retrying. Check operation-specific guidance before … 2 request/response media example set(s) now expose the owner's existing examples to the API renderer. Preserved: Compared operationId createSkill, POST /api/v2/skills, security and x-sim-operation with baseline; identifiers, route and credential schemes match. Recursive prose/default/example mappings retained in final-review-api-comparison.json; 5 distinct changed field mappings were inspected for this operation. Operation-level request/response structure, parameters, required fields, defaults and status declarations are identical after removing prose/examples; referenced component changes were reviewed separately. | +| `getSkill` — `GET /api/v2/skills/{skillId}` | rewritten | Copy standardized; no operation-specific discrepancy found. | Verified improvement. Summary: Get Skill → Get skill; sentence case matches the editorial guide. description: Get one workspace or built-in skill, including its full content. Built-in skills are marked read-only. OAuth scope: `api:read`. → Get a workspace or built-in skill, including its full instructions. Built-in skills are read-only. Requires workspace read access. OAuth scope: `api:read`. responses.503.description: A required service is temporarily unavailable. `Retry-After` carries the seconds to wait; treat it as a floor and add jitter. The header is omitted when `error.details.code` is `A… → A required service is temporarily unavailable. When present, `Retry-After` gives the minimum seconds to wait; add jitter before retrying. Check operation-specific guidance before … 1 request/response media example set(s) now expose the owner's existing examples to the API renderer. Preserved: Compared operationId getSkill, GET /api/v2/skills/{skillId}, security and x-sim-operation with baseline; identifiers, route and credential schemes match. Recursive prose/default/example mappings retained in final-review-api-comparison.json; 4 distinct changed field mappings were inspected for this operation. Operation-level request/response structure, parameters, required fields, defaults and status declarations are identical after removing prose/examples; referenced component changes were reviewed separately. | +| `updateSkill` — `PATCH /api/v2/skills/{skillId}` | corrected | Omission correct; missing editor requirement. | Verified improvement. Summary: Update Skill → Update skill; sentence case matches the editorial guide. description: Update a workspace skill. Omitted fields remain unchanged. Built-in skills are read-only. Workspace API keys return `403`; use a personal API key or scoped OAuth token. OAuth scop… → Update a workspace skill. Omitted fields remain unchanged. Requires skill editor or workspace Admin access; workspace write access alone does not grant editor access. Built-in ski… responses.503.description: A required service is temporarily unavailable. `Retry-After` carries the seconds to wait; treat it as a floor and add jitter. The header is omitted when `error.details.code` is `A… → A required service is temporarily unavailable. When present, `Retry-After` gives the minimum seconds to wait; add jitter before retrying. Check operation-specific guidance before … 2 request/response media example set(s) now expose the owner's existing examples to the API renderer. Preserved: Compared operationId updateSkill, PATCH /api/v2/skills/{skillId}, security and x-sim-operation with baseline; identifiers, route and credential schemes match. Recursive prose/default/example mappings retained in final-review-api-comparison.json; 5 distinct changed field mappings were inspected for this operation. Operation-level request/response structure, parameters, required fields, defaults and status declarations are identical after removing prose/examples; referenced component changes were reviewed separately. | +| `deleteSkill` — `DELETE /api/v2/skills/{skillId}` | corrected | Built-in refusal verified; missing editor requirement. | Verified improvement. Summary: Delete Skill → Delete skill; sentence case matches the editorial guide. description: Delete a workspace skill. Built-in skills are read-only and cannot be deleted. Workspace API keys return `403`; use a personal API key or scoped OAuth token. OAuth scope: `api:wri… → Delete a workspace skill. Requires skill editor or workspace Admin access. Built-in skills cannot be deleted. Workspace API keys return `403`; use a personal API key or scoped OAu… responses.503.description: A required service is temporarily unavailable. `Retry-After` carries the seconds to wait; treat it as a floor and add jitter. The header is omitted when `error.details.code` is `A… → A required service is temporarily unavailable. When present, `Retry-After` gives the minimum seconds to wait; add jitter before retrying. Check operation-specific guidance before … 1 request/response media example set(s) now expose the owner's existing examples to the API renderer. Preserved: Compared operationId deleteSkill, DELETE /api/v2/skills/{skillId}, security and x-sim-operation with baseline; identifiers, route and credential schemes match. Recursive prose/default/example mappings retained in final-review-api-comparison.json; 4 distinct changed field mappings were inspected for this operation. Operation-level request/response structure, parameters, required fields, defaults and status declarations are identical after removing prose/examples; referenced component changes were reviewed separately. | +| `listSkillEditors` — `GET /api/v2/skills/{skillId}/editors` | corrected | Built-in empty result and in-memory ordering need explicit copy. Shared name-sort rationale corrected by root; local sort fields/defaults preserved. | Verified improvement. Summary: List Skill Editors → List skill editors; sentence case matches the editorial guide. description: List skill editors and workspace administrators with cursor pagination. OAuth scope: `api:read`. → List explicit skill editors and workspace Admins with cursor pagination. Built-in skills return an empty list. Requires workspace read access. OAuth scope: `api:read`. parameters[2].description: Field used to sort the result. Sorting by `name` is case-sensitive and follows the storage collation, so do not rely on a case-insensitive order. → Field used to sort the result. Do not rely on case-insensitive ordering when sorting by `name`. parameters[2].schema.description: Field used to sort the result. Sorting by `name` is case-sensitive and follows the storage collation, so do not rely on a case-insensitive order. → Field used to sort the result. Do not rely on case-insensitive ordering when sorting by `name`. 1 request/response media example set(s) now expose the owner's existing examples to the API renderer. Preserved: Compared operationId listSkillEditors, GET /api/v2/skills/{skillId}/editors, security and x-sim-operation with baseline; identifiers, route and credential schemes match. Recursive prose/default/example mappings retained in final-review-api-comparison.json; 8 distinct changed field mappings were inspected for this operation. Operation-level request/response structure, parameters, required fields, defaults and status declarations are identical after removing prose/examples; referenced component changes were reviewed separately. | +| `grantSkillEditor` — `POST /api/v2/skills/{skillId}/editors` | rewritten | Copy standardized; no operation-specific discrepancy found. | Verified improvement. Summary: Grant Skill Editor → Grant skill editor; sentence case matches the editorial guide. description: Grant skill editor access to a workspace member by email. Requires an existing editor or workspace admin; admins already have access and cannot receive explicit grants. Existing g… → Grant skill editor access to a current workspace member by email. Requires an existing skill editor or workspace Admin. Workspace Admins already have derived access and cannot rec… responses.200.content.application/json.schema.description: Public identity fields for the editor. → Identity fields for the editor. responses.201.content.application/json.schema.description: Public identity fields for the editor. → Identity fields for the editor. 3 request/response media example set(s) now expose the owner's existing examples to the API renderer. Preserved: Compared operationId grantSkillEditor, POST /api/v2/skills/{skillId}/editors, security and x-sim-operation with baseline; identifiers, route and credential schemes match. Recursive prose/default/example mappings retained in final-review-api-comparison.json; 8 distinct changed field mappings were inspected for this operation. Operation-level request/response structure, parameters, required fields, defaults and status declarations are identical after removing prose/examples; referenced component changes were reviewed separately. | +| `revokeSkillEditor` — `DELETE /api/v2/skills/{skillId}/editors` | rewritten | Copy standardized; no operation-specific discrepancy found. | Verified improvement. Summary: Revoke Skill Editor → Revoke skill editor; sentence case matches the editorial guide. description: Revoke an explicit editor grant by email. The caller must already be a skill editor or workspace administrator. Workspace administrators have derived access that cannot be revoked… → Revoke an explicit skill editor grant by email. Requires an existing skill editor or workspace Admin. Workspace Admins have derived access that cannot be revoked. Workspace API ke… responses.503.description: A required service is temporarily unavailable. `Retry-After` carries the seconds to wait; treat it as a floor and add jitter. The header is omitted when `error.details.code` is `A… → A required service is temporarily unavailable. When present, `Retry-After` gives the minimum seconds to wait; add jitter before retrying. Check operation-specific guidance before … 1 request/response media example set(s) now expose the owner's existing examples to the API renderer. Preserved: Compared operationId revokeSkillEditor, DELETE /api/v2/skills/{skillId}/editors, security and x-sim-operation with baseline; identifiers, route and credential schemes match. Recursive prose/default/example mappings retained in final-review-api-comparison.json; 4 distinct changed field mappings were inspected for this operation. Operation-level request/response structure, parameters, required fields, defaults and status declarations are identical after removing prose/examples; referenced component changes were reviewed separately. | +| `listCustomTools` — `GET /api/v2/custom-tools` | rewritten | Copy standardized; no operation-specific discrepancy found. | Verified improvement. Summary: List Custom Tools → List custom tools; sentence case matches the editorial guide. description: List code-backed custom tools in a workspace with cursor pagination. OAuth scope: `api:read`. → List code-backed custom tools in the workspace with cursor pagination. Each entry includes its declaration and implementation. Requires workspace read access. OAuth scope: `api:re… responses.200.content.application/json.schema.properties.nextCursor.description: Opaque cursor for the next page. Send it back as `cursor`; `null` means there is nothing further to fetch. Never construct one yourself. → Opaque cursor for the next page. Send it back as `cursor`; `null` means there are no more pages. Do not construct a cursor yourself. responses.503.description: A required service is temporarily unavailable. `Retry-After` carries the seconds to wait; treat it as a floor and add jitter. The header is omitted when `error.details.code` is `A… → A required service is temporarily unavailable. When present, `Retry-After` gives the minimum seconds to wait; add jitter before retrying. Check operation-specific guidance before … 1 request/response media example set(s) now expose the owner's existing examples to the API renderer. Preserved: Compared operationId listCustomTools, GET /api/v2/custom-tools, security and x-sim-operation with baseline; identifiers, route and credential schemes match. Recursive prose/default/example mappings retained in final-review-api-comparison.json; 5 distinct changed field mappings were inspected for this operation. Operation-level request/response structure, parameters, required fields, defaults and status declarations are identical after removing prose/examples; referenced component changes were reviewed separately. | +| `createCustomTool` — `POST /api/v2/custom-tools` | rewritten | Copy standardized; no operation-specific discrepancy found. | Verified improvement. Summary: Create Custom Tool → Create custom tool; sentence case matches the editorial guide. description: Create a code-backed custom tool in a workspace. Its title must be unique because tools resolve by title at call time. OAuth scope: `api:write`. → Create a code-backed custom tool. Its title must be unique within the workspace because tools resolve by title at call time. Requires workspace write access. OAuth scope: `api:wri… responses.503.description: A required service is temporarily unavailable. `Retry-After` carries the seconds to wait; treat it as a floor and add jitter. The header is omitted when `error.details.code` is `A… → A required service is temporarily unavailable. When present, `Retry-After` gives the minimum seconds to wait; add jitter before retrying. Check operation-specific guidance before … 2 request/response media example set(s) now expose the owner's existing examples to the API renderer. Preserved: Compared operationId createCustomTool, POST /api/v2/custom-tools, security and x-sim-operation with baseline; identifiers, route and credential schemes match. Recursive prose/default/example mappings retained in final-review-api-comparison.json; 5 distinct changed field mappings were inspected for this operation. Operation-level request/response structure, parameters, required fields, defaults and status declarations are identical after removing prose/examples; referenced component changes were reviewed separately. | +| `getCustomTool` — `GET /api/v2/custom-tools/{customToolId}` | rewritten | Copy standardized; no operation-specific discrepancy found. | Verified improvement. Summary: Get Custom Tool → Get custom tool; sentence case matches the editorial guide. description: Get one custom tool by identifier, scoped to its workspace. OAuth scope: `api:read`. → Get a custom tool’s declaration and code by identifier, scoped to its workspace. Requires workspace read access. OAuth scope: `api:read`. responses.503.description: A required service is temporarily unavailable. `Retry-After` carries the seconds to wait; treat it as a floor and add jitter. The header is omitted when `error.details.code` is `A… → A required service is temporarily unavailable. When present, `Retry-After` gives the minimum seconds to wait; add jitter before retrying. Check operation-specific guidance before … 1 request/response media example set(s) now expose the owner's existing examples to the API renderer. Preserved: Compared operationId getCustomTool, GET /api/v2/custom-tools/{customToolId}, security and x-sim-operation with baseline; identifiers, route and credential schemes match. Recursive prose/default/example mappings retained in final-review-api-comparison.json; 4 distinct changed field mappings were inspected for this operation. Operation-level request/response structure, parameters, required fields, defaults and status declarations are identical after removing prose/examples; referenced component changes were reviewed separately. | +| `updateCustomTool` — `PATCH /api/v2/custom-tools/{customToolId}` | rewritten | Copy standardized; no operation-specific discrepancy found. | Verified improvement. Summary: Update Custom Tool → Update custom tool; sentence case matches the editorial guide. description: Update a custom tool. Omitted fields remain unchanged; titles must remain unique within the workspace. OAuth scope: `api:write`. → Update a custom tool. Omitted fields remain unchanged; supplied schemas and code replace the stored versions. Titles must remain unique within the workspace. Requires workspace wr… responses.503.description: A required service is temporarily unavailable. `Retry-After` carries the seconds to wait; treat it as a floor and add jitter. The header is omitted when `error.details.code` is `A… → A required service is temporarily unavailable. When present, `Retry-After` gives the minimum seconds to wait; add jitter before retrying. Check operation-specific guidance before … 2 request/response media example set(s) now expose the owner's existing examples to the API renderer. Preserved: Compared operationId updateCustomTool, PATCH /api/v2/custom-tools/{customToolId}, security and x-sim-operation with baseline; identifiers, route and credential schemes match. Recursive prose/default/example mappings retained in final-review-api-comparison.json; 5 distinct changed field mappings were inspected for this operation. Operation-level request/response structure, parameters, required fields, defaults and status declarations are identical after removing prose/examples; referenced component changes were reviewed separately. | +| `deleteCustomTool` — `DELETE /api/v2/custom-tools/{customToolId}` | rewritten | Copy standardized; no operation-specific discrepancy found. | Verified improvement. Summary: Delete Custom Tool → Delete custom tool; sentence case matches the editorial guide. description: Delete a custom tool. Agent blocks retain their configuration but can no longer call the deleted tool. OAuth scope: `api:write`. → Delete a custom tool. Agent blocks retain their configuration but can no longer call the deleted tool. Requires workspace write access. OAuth scope: `api:write`. responses.503.description: A required service is temporarily unavailable. `Retry-After` carries the seconds to wait; treat it as a floor and add jitter. The header is omitted when `error.details.code` is `A… → A required service is temporarily unavailable. When present, `Retry-After` gives the minimum seconds to wait; add jitter before retrying. Check operation-specific guidance before … 1 request/response media example set(s) now expose the owner's existing examples to the API renderer. Preserved: Compared operationId deleteCustomTool, DELETE /api/v2/custom-tools/{customToolId}, security and x-sim-operation with baseline; identifiers, route and credential schemes match. Recursive prose/default/example mappings retained in final-review-api-comparison.json; 4 distinct changed field mappings were inspected for this operation. Operation-level request/response structure, parameters, required fields, defaults and status declarations are identical after removing prose/examples; referenced component changes were reviewed separately. | +| `listSandboxes` — `GET /api/v2/sandboxes` | rewritten | Copy standardized; no operation-specific discrepancy found. | Verified improvement. Summary: List Sandboxes → List sandboxes; sentence case matches the editorial guide. description: List reusable dependency environments for Function blocks, including language packages, managed CLIs, and system packages. Sandboxes remain visible after a plan downgrade. OAuth s… → List reusable dependency environments for Function blocks, including language packages, managed CLIs, and system packages. Requires workspace read access. Existing sandboxes remai… parameters[2].description: Field used to sort the result. Sorting by `name` is case-sensitive and follows the storage collation, so do not rely on a case-insensitive order. → Field used to sort the result. Do not rely on case-insensitive ordering when sorting by `name`. parameters[2].schema.description: Field used to sort the result. Sorting by `name` is case-sensitive and follows the storage collation, so do not rely on a case-insensitive order. → Field used to sort the result. Do not rely on case-insensitive ordering when sorting by `name`. 1 request/response media example set(s) now expose the owner's existing examples to the API renderer. Preserved: Compared operationId listSandboxes, GET /api/v2/sandboxes, security and x-sim-operation with baseline; identifiers, route and credential schemes match. Recursive prose/default/example mappings retained in final-review-api-comparison.json; 7 distinct changed field mappings were inspected for this operation. Operation-level request/response structure, parameters, required fields, defaults and status declarations are identical after removing prose/examples; referenced component changes were reviewed separately. | +| `createSandbox` — `POST /api/v2/sandboxes` | corrected | Build state/rate budget correct; deployment entitlement qualification. | Verified improvement. Summary: Create Sandbox → Create sandbox; sentence case matches the editorial guide. description: Create a uniquely named dependency environment. If a build is needed, track readiness with `buildStatus`; null means no build is required. Invalid dependencies return `400` with f… → Create a uniquely named dependency environment. Requires workspace Admin access and a configured remote Function runtime. With billing enabled, Max or Enterprise is required unles… responses.503.description: A required service is temporarily unavailable. `Retry-After` carries the seconds to wait; treat it as a floor and add jitter. The header is omitted when `error.details.code` is `A… → A required service is temporarily unavailable. When present, `Retry-After` gives the minimum seconds to wait; add jitter before retrying. Check operation-specific guidance before … 2 request/response media example set(s) now expose the owner's existing examples to the API renderer. Preserved: Compared operationId createSandbox, POST /api/v2/sandboxes, security and x-sim-operation with baseline; identifiers, route and credential schemes match. Recursive prose/default/example mappings retained in final-review-api-comparison.json; 5 distinct changed field mappings were inspected for this operation. Operation-level request/response structure, parameters, required fields, defaults and status declarations are identical after removing prose/examples; referenced component changes were reviewed separately. | +| `getSandbox` — `GET /api/v2/sandboxes/{sandboxId}` | rewritten | Copy standardized; no operation-specific discrepancy found. | Verified improvement. Summary: Get Sandbox → Get sandbox; sentence case matches the editorial guide. description: Get one sandbox by identifier, scoped to its workspace, including its current build state and any build failure. OAuth scope: `api:read`. → Get a sandbox’s dependency configuration, current build state, and any build failure. Requires workspace read access. OAuth scope: `api:read`. responses.503.description: A required service is temporarily unavailable. `Retry-After` carries the seconds to wait; treat it as a floor and add jitter. The header is omitted when `error.details.code` is `A… → A required service is temporarily unavailable. When present, `Retry-After` gives the minimum seconds to wait; add jitter before retrying. Check operation-specific guidance before … 1 request/response media example set(s) now expose the owner's existing examples to the API renderer. Preserved: Compared operationId getSandbox, GET /api/v2/sandboxes/{sandboxId}, security and x-sim-operation with baseline; identifiers, route and credential schemes match. Recursive prose/default/example mappings retained in final-review-api-comparison.json; 4 distinct changed field mappings were inspected for this operation. Operation-level request/response structure, parameters, required fields, defaults and status declarations are identical after removing prose/examples; referenced component changes were reviewed separately. | +| `updateSandbox` — `PATCH /api/v2/sandboxes/{sandboxId}` | corrected | List replacement/spec retry/build state correct; deployment qualification. | Verified improvement. Summary: Update Sandbox → Update sandbox; sentence case matches the editorial guide. description: Update a sandbox, preserving omitted fields and replacing supplied lists. Dependency changes may start a build; resending a failed specification retries its build. `buildStatus: n… → Update a sandbox; omitted fields stay unchanged and supplied lists replace their contents. Dependency changes may start a build; resending a failed specification retries it. `buil… responses.503.description: A required service is temporarily unavailable. `Retry-After` carries the seconds to wait; treat it as a floor and add jitter. The header is omitted when `error.details.code` is `A… → A required service is temporarily unavailable. When present, `Retry-After` gives the minimum seconds to wait; add jitter before retrying. Check operation-specific guidance before … 2 request/response media example set(s) now expose the owner's existing examples to the API renderer. Preserved: Compared operationId updateSandbox, PATCH /api/v2/sandboxes/{sandboxId}, security and x-sim-operation with baseline; identifiers, route and credential schemes match. Recursive prose/default/example mappings retained in final-review-api-comparison.json; 5 distinct changed field mappings were inspected for this operation. Operation-level request/response structure, parameters, required fields, defaults and status declarations are identical after removing prose/examples; referenced component changes were reviewed separately. | +| `deleteSandbox` — `DELETE /api/v2/sandboxes/{sandboxId}` | corrected | Dependent Function failure correct; deployment qualification. | Verified improvement. Summary: Delete Sandbox → Delete sandbox; sentence case matches the editorial guide. description: Delete a sandbox. Function blocks using it fail until reconfigured. Requires workspace admin access on Max or Enterprise. Workspace API keys return `403`; use a personal API key o… → Delete a sandbox. Function blocks using it fail until reconfigured. Requires workspace Admin access and sandbox entitlement: with billing enabled, Max or Enterprise is required un… responses.503.description: A required service is temporarily unavailable. `Retry-After` carries the seconds to wait; treat it as a floor and add jitter. The header is omitted when `error.details.code` is `A… → A required service is temporarily unavailable. When present, `Retry-After` gives the minimum seconds to wait; add jitter before retrying. Check operation-specific guidance before … 1 request/response media example set(s) now expose the owner's existing examples to the API renderer. Preserved: Compared operationId deleteSandbox, DELETE /api/v2/sandboxes/{sandboxId}, security and x-sim-operation with baseline; identifiers, route and credential schemes match. Recursive prose/default/example mappings retained in final-review-api-comparison.json; 4 distinct changed field mappings were inspected for this operation. Operation-level request/response structure, parameters, required fields, defaults and status declarations are identical after removing prose/examples; referenced component changes were reviewed separately. | +| `listCredentials` — `GET /api/v2/credentials` | rewritten | Copy standardized; no operation-specific discrepancy found. | Verified improvement. Summary: List Credentials → List credentials; sentence case matches the editorial guide. description: List OAuth and service-account connections visible to the caller. Secret material is never returned. OAuth scope: `api:read`. → List OAuth and service-account connections visible to the caller. Requires workspace read access. Stored tokens, keys, and service-account payloads are omitted. OAuth scope: `api:… responses.200.content.application/json.schema.properties.nextCursor.description: Opaque cursor for the next page. Send it back as `cursor`; `null` means there is nothing further to fetch. Never construct one yourself. → Opaque cursor for the next page. Send it back as `cursor`; `null` means there are no more pages. Do not construct a cursor yourself. responses.503.description: A required service is temporarily unavailable. `Retry-After` carries the seconds to wait; treat it as a floor and add jitter. The header is omitted when `error.details.code` is `A… → A required service is temporarily unavailable. When present, `Retry-After` gives the minimum seconds to wait; add jitter before retrying. Check operation-specific guidance before … 1 request/response media example set(s) now expose the owner's existing examples to the API renderer. Preserved: Compared operationId listCredentials, GET /api/v2/credentials, security and x-sim-operation with baseline; identifiers, route and credential schemes match. Recursive prose/default/example mappings retained in final-review-api-comparison.json; 5 distinct changed field mappings were inspected for this operation. Operation-level request/response structure, parameters, required fields, defaults and status declarations are identical after removing prose/examples; referenced component changes were reviewed separately. | +| `createServiceAccountCredential` — `POST /api/v2/credentials` | corrected | Provider verification/dedup status correct; emitted default body invalid. Existing valid encoded service-account body retained; root owns publishing metadata examples in shared generator. | Verified improvement. Summary: Create Service-Account Credential → Create service-account credential; sentence case matches the editorial guide. description: Verify and store a service-account credential using the fields from List Credential Providers, encoded as a JSON object string in `credentials`. Secrets are never returned. A matc… → Verify and store a service-account credential. Use the fields from List credential providers, encoded as a JSON object string in `credentials`. Requires workspace write access. A … responses.503.description: A required service is temporarily unavailable. `Retry-After` carries the seconds to wait; treat it as a floor and add jitter. The header is omitted when `error.details.code` is `A… → A required service is temporarily unavailable. When present, `Retry-After` gives the minimum seconds to wait; add jitter before retrying. Check operation-specific guidance before … 3 request/response media example set(s) now expose the owner's existing examples to the API renderer. Preserved: Compared operationId createServiceAccountCredential, POST /api/v2/credentials, security and x-sim-operation with baseline; identifiers, route and credential schemes match. Recursive prose/default/example mappings retained in final-review-api-comparison.json; 6 distinct changed field mappings were inspected for this operation. Operation-level request/response structure, parameters, required fields, defaults and status declarations are identical after removing prose/examples; referenced component changes were reviewed separately. | +| `listCredentialProviders` — `GET /api/v2/credentials/providers` | rewritten | Copy standardized; no operation-specific discrepancy found. | Verified improvement. Summary: List Credential Providers → List credential providers; sentence case matches the editorial guide. description: List OAuth and service-account connection methods and their availability. OAuth options provide provider IDs for browser connections; service-account methods declare required fiel… → List OAuth and service-account connection methods and their availability. OAuth options provide provider IDs for browser connections; service-account methods declare required fiel… responses.200.content.application/json.schema.properties.nextCursor.description: Always `null` — this list has no `cursor` or `limit` param and returns its whole bounded set in one page. Present so the list can gain pages later without a shape change. → Always `null`. This list has no `cursor` or `limit` parameters; see the operation for inventory limits. responses.503.description: A required service is temporarily unavailable. `Retry-After` carries the seconds to wait; treat it as a floor and add jitter. The header is omitted when `error.details.code` is `A… → A required service is temporarily unavailable. When present, `Retry-After` gives the minimum seconds to wait; add jitter before retrying. Check operation-specific guidance before … 1 request/response media example set(s) now expose the owner's existing examples to the API renderer. Preserved: Compared operationId listCredentialProviders, GET /api/v2/credentials/providers, security and x-sim-operation with baseline; identifiers, route and credential schemes match. Recursive prose/default/example mappings retained in final-review-api-comparison.json; 5 distinct changed field mappings were inspected for this operation. Operation-level request/response structure, parameters, required fields, defaults and status declarations are identical after removing prose/examples; referenced component changes were reviewed separately. | +| `createCredentialConnection` — `POST /api/v2/credentials/connections` | corrected | Correct acting-user browser flow; body intro contradicts QuickBooks/scope. Required workspaceId and QuickBooks oauthClientConfig documented; valid new, reconnect, and QuickBooks body examples supplied. | Verified improvement. Summary: Create Credential Connection → Create credential connection; sentence case matches the editorial guide. description: Create a short-lived browser URL for connecting an OAuth provider or reconnecting an existing OAuth credential. Open the URL, sign in as the authenticated user, complete provider … → Create a short-lived browser URL to connect an OAuth provider or reconnect a credential. Requires workspace write access; reconnecting also requires credential Admin access. Open … requestBody.content.application/json.schema.description: For a new connection, provide providerId and displayName. For a reconnect, provide only credentialId; the existing display name is preserved. → Provide workspaceId for every flow. For a new connection, send providerId and displayName; for a reconnect, send credentialId and retain the existing name. QuickBooks also require… requestBody.description: For a new connection, provide providerId and displayName. For a reconnect, provide only credentialId; the existing display name is preserved. → Provide workspaceId for every flow. For a new connection, send providerId and displayName; for a reconnect, send credentialId and retain the existing name. QuickBooks also require… 3 request/response media example set(s) now expose the owner's existing examples to the API renderer. Preserved: Compared operationId createCredentialConnection, POST /api/v2/credentials/connections, security and x-sim-operation with baseline; identifiers, route and credential schemes match. Recursive prose/default/example mappings retained in final-review-api-comparison.json; 8 distinct changed field mappings were inspected for this operation. Operation-level request/response structure, parameters, required fields, defaults and status declarations are identical after removing prose/examples; referenced component changes were reviewed separately. | +| `deleteCredential` — `DELETE /api/v2/credentials/{credentialId}` | rewritten | Copy standardized; no operation-specific discrepancy found. | Verified improvement. Summary: Disconnect Credential → Disconnect credential; sentence case matches the editorial guide. description: Disconnect an OAuth or service-account credential and clear its stored workflow, deployment, paused-run, knowledge-connector, and webhook references. Credential admin access is re… → Disconnect an OAuth or service-account credential and clear its stored workflow, deployment, paused-run, knowledge-connector, and webhook references. Requires credential Admin acc… responses.503.description: A required service is temporarily unavailable. `Retry-After` carries the seconds to wait; treat it as a floor and add jitter. The header is omitted when `error.details.code` is `A… → A required service is temporarily unavailable. When present, `Retry-After` gives the minimum seconds to wait; add jitter before retrying. Check operation-specific guidance before … 1 request/response media example set(s) now expose the owner's existing examples to the API renderer. Preserved: Compared operationId deleteCredential, DELETE /api/v2/credentials/{credentialId}, security and x-sim-operation with baseline; identifiers, route and credential schemes match. Recursive prose/default/example mappings retained in final-review-api-comparison.json; 4 distinct changed field mappings were inspected for this operation. Operation-level request/response structure, parameters, required fields, defaults and status declarations are identical after removing prose/examples; referenced component changes were reviewed separately. | +| `updateCredential` — `PATCH /api/v2/credentials/{credentialId}` | corrected | Metadata supports OAuth; secret replacement/required fields contradict copy. Partial metadata distinguished from provider-secret replacement; metadata-only and complete Zoom rotation examples supplied. | Verified improvement. Summary: Update Credential → Update credential; sentence case matches the editorial guide. description: Rename a service-account credential or rotate its secret fields, preserving omitted values and the credential ID. Requires credential admin access. Provider rejection preserves th… → Rename an OAuth or service-account credential, change its description, or rotate a service-account secret. Omitted metadata remains unchanged. Rotation requires the provider’s req… requestBody.content.application/json.schema.description: Replacement display metadata and the write-only fields declared by provider discovery. → Metadata fields to change, or the complete required fields for a service-account secret rotation. Use List credential providers for the selected provider’s fields. requestBody.description: Replacement display metadata and the write-only fields declared by provider discovery. → Metadata fields to change, or the complete required fields for a service-account secret rotation. Use List credential providers for the selected provider’s fields. 2 request/response media example set(s) now expose the owner's existing examples to the API renderer. Preserved: Compared operationId updateCredential, PATCH /api/v2/credentials/{credentialId}, security and x-sim-operation with baseline; identifiers, route and credential schemes match. Recursive prose/default/example mappings retained in final-review-api-comparison.json; 8 distinct changed field mappings were inspected for this operation. Operation-level request/response structure, parameters, required fields, defaults and status declarations are identical after removing prose/examples; referenced component changes were reviewed separately. | +| `listSecrets` — `GET /api/v2/secrets` | rewritten | Copy standardized; no operation-specific discrepancy found. | Verified improvement. Summary: List Secrets → List secrets; sentence case matches the editorial guide. description: List workspace and caller-owned personal secrets with cursor pagination. Only workspace secrets marked `unredacted` include values; all other entries contain metadata only. Worksp… → List workspace secrets visible to the caller and caller-owned personal secrets. Only workspace secrets marked `unredacted` can include values; every other entry contains metadata … parameters[3].description: Field used to sort the result. Sorting by `name` is case-sensitive and follows the storage collation, so do not rely on a case-insensitive order. → Field used to sort the result. Do not rely on case-insensitive ordering when sorting by `name`. parameters[3].schema.description: Field used to sort the result. Sorting by `name` is case-sensitive and follows the storage collation, so do not rely on a case-insensitive order. → Field used to sort the result. Do not rely on case-insensitive ordering when sorting by `name`. 1 request/response media example set(s) now expose the owner's existing examples to the API renderer. Preserved: Compared operationId listSecrets, GET /api/v2/secrets, security and x-sim-operation with baseline; identifiers, route and credential schemes match. Recursive prose/default/example mappings retained in final-review-api-comparison.json; 7 distinct changed field mappings were inspected for this operation. Operation-level request/response structure, parameters, required fields, defaults and status declarations are identical after removing prose/examples; referenced component changes were reviewed separately. | +| `setSecret` — `PUT /api/v2/secrets/{name}` | corrected | Value-less existing workspace metadata/201 creation correct; missing resource authority. | Verified improvement. Summary: Set Secret → Set secret; sentence case matches the editorial guide. description: Create or replace a workspace or personal secret without returning its value. For existing workspace secrets, omit `value` to update metadata only; this returns `404` if absent. P… → Create or replace a workspace or caller-owned personal secret. New workspace secrets require workspace write access; existing ones require workspace Admin or secret Admin access. … requestBody.content.application/json.schema.properties.value.description: Write-only secret value. It is never returned. Omit it on a workspace secret to change description or unredacted alone, leaving the stored value untouched; the secret must already… → Secret value, omitted from the Set secret response. For an existing workspace secret, omit it to change only `description` or `unredacted`. Personal secrets always require a value… responses.503.description: A required service is temporarily unavailable. `Retry-After` carries the seconds to wait; treat it as a floor and add jitter. The header is omitted when `error.details.code` is `A… → A required service is temporarily unavailable. When present, `Retry-After` gives the minimum seconds to wait; add jitter before retrying. Check operation-specific guidance before … 3 request/response media example set(s) now expose the owner's existing examples to the API renderer. Preserved: Compared operationId setSecret, PUT /api/v2/secrets/{name}, security and x-sim-operation with baseline; identifiers, route and credential schemes match. Recursive prose/default/example mappings retained in final-review-api-comparison.json; 7 distinct changed field mappings were inspected for this operation. Operation-level request/response structure, parameters, required fields, defaults and status declarations are identical after removing prose/examples; referenced component changes were reviewed separately. | +| `deleteSecret` — `DELETE /api/v2/secrets/{name}` | corrected | User-global deletion scope correct; missing resource authority. | Verified improvement. Summary: Delete Secret → Delete secret; sentence case matches the editorial guide. description: Delete a workspace or caller-owned personal secret without reading or returning its stored value. Workspace API keys return `403`; use a personal API key or scoped OAuth token. OA… → Delete a workspace or caller-owned personal secret without returning its value. Workspace secrets require workspace Admin or secret Admin access. Deleting a personal secret remove… responses.503.description: A required service is temporarily unavailable. `Retry-After` carries the seconds to wait; treat it as a floor and add jitter. The header is omitted when `error.details.code` is `A… → A required service is temporarily unavailable. When present, `Retry-After` gives the minimum seconds to wait; add jitter before retrying. Check operation-specific guidance before … 1 request/response media example set(s) now expose the owner's existing examples to the API renderer. Preserved: Compared operationId deleteSecret, DELETE /api/v2/secrets/{name}, security and x-sim-operation with baseline; identifiers, route and credential schemes match. Recursive prose/default/example mappings retained in final-review-api-comparison.json; 4 distinct changed field mappings were inspected for this operation. Operation-level request/response structure, parameters, required fields, defaults and status declarations are identical after removing prose/examples; referenced component changes were reviewed separately. | +| `getApiMeta` — `GET /api/v2/meta` | rewritten | Reviewed; accurate details retained under the shared reference standard. | Verified improvement. Summary: Get API Capabilities → Get API status; sentence case matches the editorial guide. description: Get whether v2 is available, what kind of API credential is calling, and when it expires. Requires a valid API key or OAuth access token. OAuth scope: `api:read`. → Get the calling credential’s type and expiry. Requires a valid API key or OAuth access token. `v2Enabled` is true whenever this endpoint is served; the response does not enumerate… responses.200.content.application/json.schema.properties.data.properties.keyType.description: Whether the calling credential is a personal API key carrying the full authority of its owner across their workspaces, a key scoped to one workspace, or an OAuth access token acti… → Calling credential kind: a personal API key acting for its owner, a key bound to one workspace, or an OAuth access token acting for its user within granted scopes. Resource permis… responses.503.description: A required service is temporarily unavailable. `Retry-After` carries the seconds to wait; treat it as a floor and add jitter. The header is omitted when `error.details.code` is `A… → A required service is temporarily unavailable. When present, `Retry-After` gives the minimum seconds to wait; add jitter before retrying. Check operation-specific guidance before … 1 request/response media example set(s) now expose the owner's existing examples to the API renderer. Preserved: Compared operationId getApiMeta, GET /api/v2/meta, security and x-sim-operation with baseline; identifiers, route and credential schemes match. Recursive prose/default/example mappings retained in final-review-api-comparison.json; 5 distinct changed field mappings were inspected for this operation. Operation-level request/response structure, parameters, required fields, defaults and status declarations are identical after removing prose/examples; referenced component changes were reviewed separately. | +| `listWorkflowMcpServers` — `GET /api/v2/workflow-mcp-servers` | corrected | 2,000-name cap also undercounts toolCount. | Verified improvement. Summary: List Workflow MCP Servers → List workflow MCP servers; sentence case matches the editorial guide. description: List MCP servers that expose deployed workflows to external clients. Use List MCP Servers for external servers Sim calls. Tool names share a 2,000-name page limit; inspect `toolNa… → List MCP servers that expose deployed workflows to external clients. Use List MCP servers for external servers Sim calls. Requires workspace read access. Tool names share a 2,000-… parameters[0].description: Workspace whose published MCP servers to list. → Workspace whose workflow MCP servers to list. parameters[0].schema.description: Workspace whose published MCP servers to list. → Workspace whose workflow MCP servers to list. 1 request/response media example set(s) now expose the owner's existing examples to the API renderer. Preserved: Compared operationId listWorkflowMcpServers, GET /api/v2/workflow-mcp-servers, security and x-sim-operation with baseline; identifiers, route and credential schemes match. Recursive prose/default/example mappings retained in final-review-api-comparison.json; 16 distinct changed field mappings were inspected for this operation. Operation-level request/response structure, parameters, required fields, defaults and status declarations are identical after removing prose/examples; referenced component changes were reviewed separately. | +| `createWorkflowMcpServer` — `POST /api/v2/workflow-mcp-servers` | corrected | Public execution consequence/deployed inputs correct; add admin role. | Verified improvement. Summary: Create Workflow MCP Server → Create workflow MCP server; sentence case matches the editorial guide. description: Create an MCP server that exposes deployed workflows as tools. Every supplied workflow must already be deployed. With `isPublic: true`, anyone with the server URL can execute its … → Create an MCP server exposing deployed workflows as tools. Every supplied workflow must already be deployed. With `isPublic: true`, anyone holding the server URL can execute its w… requestBody.content.application/json.schema.description: A new workspace-published MCP server and the workflows it exposes. → A new workflow MCP server and deployed workflows to expose as tools. requestBody.content.application/json.schema.properties.isPublic.description: Whether the server answers MCP clients without a Sim API key. Defaults to false — a public server executes the workflows it publishes for anyone holding its URL. → Whether the server accepts MCP clients without a Sim API key. Defaults to false; a public server lets anyone holding its URL execute the workflows it exposes. 2 request/response media example set(s) now expose the owner's existing examples to the API renderer. Preserved: Compared operationId createWorkflowMcpServer, POST /api/v2/workflow-mcp-servers, security and x-sim-operation with baseline; identifiers, route and credential schemes match. Recursive prose/default/example mappings retained in final-review-api-comparison.json; 13 distinct changed field mappings were inspected for this operation. Operation-level request/response structure, parameters, required fields, defaults and status declarations are identical after removing prose/examples; referenced component changes were reviewed separately. | +| `getWorkflowMcpServer` — `GET /api/v2/workflow-mcp-servers/{serverId}` | rewritten | Reviewed; accurate details retained under the shared reference standard. | Verified improvement. Summary: Get Workflow MCP Server → Get workflow MCP server; sentence case matches the editorial guide. description: Get a published workflow MCP server's metadata and client endpoint. Use List Workflow MCP Tools for its tool inventory. Workspace API keys return `403`; use a personal API key or … → Get a workflow MCP server’s metadata and client endpoint. Use List workflow MCP tools for its inventory. Requires workspace read access. Workspace API keys return `403`; use a per… responses.200.content.application/json.schema.description: A single published MCP server. → One workflow MCP server and its client endpoint. responses.200.content.application/json.schema.properties.data.properties.mcpServerUrl.description: Endpoint an MCP client connects to. Published here so callers never build it. → MCP client endpoint. Use this returned URL instead of constructing one. 1 request/response media example set(s) now expose the owner's existing examples to the API renderer. Preserved: Compared operationId getWorkflowMcpServer, GET /api/v2/workflow-mcp-servers/{serverId}, security and x-sim-operation with baseline; identifiers, route and credential schemes match. Recursive prose/default/example mappings retained in final-review-api-comparison.json; 6 distinct changed field mappings were inspected for this operation. Operation-level request/response structure, parameters, required fields, defaults and status declarations are identical after removing prose/examples; referenced component changes were reviewed separately. | +| `updateWorkflowMcpServer` — `PATCH /api/v2/workflow-mcp-servers/{serverId}` | corrected | Partial fields/null/public effect correct; admin role and patch label. | Verified improvement. Summary: Update Workflow MCP Server → Update workflow MCP server; sentence case matches the editorial guide. description: Update a workflow MCP server's name, description, or public access. Omitted fields remain unchanged; `description: null` clears the description. Publish or unpublish tools separat… → Update a workflow MCP server’s name, description, or public access. Omitted fields stay unchanged; `description: null` clears the description. With `isPublic: true`, anyone holdin… requestBody.content.application/json.schema.description: Merge-patch body for a published MCP server. → Server fields to change. Omitted fields remain unchanged; `description: null` clears the description. requestBody.description: Merge-patch body for a published MCP server. → Server fields to change. Omitted fields remain unchanged; `description: null` clears the description. 2 request/response media example set(s) now expose the owner's existing examples to the API renderer. Preserved: Compared operationId updateWorkflowMcpServer, PATCH /api/v2/workflow-mcp-servers/{serverId}, security and x-sim-operation with baseline; identifiers, route and credential schemes match. Recursive prose/default/example mappings retained in final-review-api-comparison.json; 8 distinct changed field mappings were inspected for this operation. Operation-level request/response structure, parameters, required fields, defaults and status declarations are identical after removing prose/examples; referenced component changes were reviewed separately. | +| `deleteWorkflowMcpServer` — `DELETE /api/v2/workflow-mcp-servers/{serverId}` | corrected | Underlying workflow API remains deployed; add admin role/Deploy terminology. | Verified improvement. Summary: Delete Workflow MCP Server → Delete workflow MCP server; sentence case matches the editorial guide. description: Delete a workflow MCP server and stop serving its tools. The underlying workflows remain deployed and executable through the workflow API. Workspace API keys return `403`; use a p… → Delete a workflow MCP server and stop serving its tools. Its workflows remain deployed and executable through the workflow API. Requires workspace Admin access. Workspace API keys… responses.200.content.application/json.schema.description: Acknowledgement that the MCP server was unpublished. → Acknowledgement that the workflow MCP server was deleted. responses.200.content.application/json.schema.properties.data.properties.deleted.description: Whether the server was unpublished. → Whether the workflow MCP server was deleted. 1 request/response media example set(s) now expose the owner's existing examples to the API renderer. Preserved: Compared operationId deleteWorkflowMcpServer, DELETE /api/v2/workflow-mcp-servers/{serverId}, security and x-sim-operation with baseline; identifiers, route and credential schemes match. Recursive prose/default/example mappings retained in final-review-api-comparison.json; 8 distinct changed field mappings were inspected for this operation. Operation-level request/response structure, parameters, required fields, defaults and status declarations are identical after removing prose/examples; referenced component changes were reviewed separately. | +| `listWorkflowMcpTools` — `GET /api/v2/workflow-mcp-servers/{serverId}/tools` | rewritten | Reviewed; accurate details retained under the shared reference standard. | Verified improvement. Summary: List Workflow MCP Tools → List workflow MCP tools; sentence case matches the editorial guide. description: List published tools ordered by name, including the `workflowId` used to delete each registration. Undeploying a workflow makes its registrations `inactive`; redeploying reactivat… → List tool registrations ordered by name, including the `workflowId` used to remove each registration. Undeploying a workflow makes its registrations `inactive`; redeploying reacti… responses.200.content.application/json.schema.description: The tools a published MCP server exposes. → A bounded inventory of tool registrations on the workflow MCP server. responses.200.content.application/json.schema.properties.data.items.description: A tool a server publishes, as returned by a read. Archived registrations are included with `status: "inactive"`. → A tool registration on a workflow MCP server. Archived registrations are included with `status: "inactive"`. 1 request/response media example set(s) now expose the owner's existing examples to the API renderer. Preserved: Compared operationId listWorkflowMcpTools, GET /api/v2/workflow-mcp-servers/{serverId}/tools, security and x-sim-operation with baseline; identifiers, route and credential schemes match. Recursive prose/default/example mappings retained in final-review-api-comparison.json; 11 distinct changed field mappings were inspected for this operation. Operation-level request/response structure, parameters, required fields, defaults and status declarations are identical after removing prose/examples; referenced component changes were reviewed separately. | +| `deployWorkflowMcpTool` — `POST /api/v2/workflow-mcp-servers/{serverId}/tools` | corrected | Per-workflow replacement, deployed schema, overrides and 200/updated verified; admin role. | Verified improvement. Summary: Publish Workflow As MCP Tool → Deploy workflow as MCP tool; sentence case matches the editorial guide. description: Publish a deployed workflow as an MCP tool using its deployed input schema. Each server has at most one tool per workflow; repeating the call replaces that tool and returns `200` … → Deploy a workflow as an MCP tool using its deployed input schema. The workflow must already be deployed. Each server has at most one tool per workflow; repeating the call replaces… requestBody.content.application/json.schema.description: The workflow to publish and the tool metadata MCP clients see. → The deployed workflow and tool metadata presented to MCP clients. requestBody.content.application/json.schema.properties.workflowId.description: Deployed workflow to publish. The workflow must already be deployed. → Workflow to expose as an MCP tool. It must already be deployed. 2 request/response media example set(s) now expose the owner's existing examples to the API renderer. Preserved: Compared operationId deployWorkflowMcpTool, POST /api/v2/workflow-mcp-servers/{serverId}/tools, security and x-sim-operation with baseline; identifiers, route and credential schemes match. Recursive prose/default/example mappings retained in final-review-api-comparison.json; 12 distinct changed field mappings were inspected for this operation. Operation-level request/response structure, parameters, required fields, defaults and status declarations are identical after removing prose/examples; referenced component changes were reviewed separately. | +| `undeployWorkflowMcpTool` — `DELETE /api/v2/workflow-mcp-servers/{serverId}/tools/{workflowId}` | corrected | Workflow API remains active; add admin role/Undeploy terminology. | Verified improvement. Summary: Unpublish Workflow MCP Tool → Undeploy workflow MCP tool; sentence case matches the editorial guide. description: Unpublish an MCP tool by its workflow ID. The workflow's API deployment remains active. Workspace API keys return `403`; use a personal API key or scoped OAuth token. OAuth scope:… → Remove an MCP tool registration by its workflow ID. The workflow’s API deployment remains active. Requires workspace Admin access. Workspace API keys return `403`; use a personal … parameters[1].description: Workflow published as a tool on this server. → Workflow registered as an MCP tool on this server. parameters[1].schema.description: Workflow published as a tool on this server. → Workflow registered as an MCP tool on this server. 1 request/response media example set(s) now expose the owner's existing examples to the API renderer. Preserved: Compared operationId undeployWorkflowMcpTool, DELETE /api/v2/workflow-mcp-servers/{serverId}/tools/{workflowId}, security and x-sim-operation with baseline; identifiers, route and credential schemes match. Recursive prose/default/example mappings retained in final-review-api-comparison.json; 7 distinct changed field mappings were inspected for this operation. Operation-level request/response structure, parameters, required fields, defaults and status declarations are identical after removing prose/examples; referenced component changes were reviewed separately. | +| `listBlocks` — `GET /api/v2/blocks` | corrected | Visible registry/source/preview/sunset/capability rules verified; sort rationale. Shared name-sort rationale corrected by root; local sort fields/defaults preserved. | Verified improvement. Summary: List Blocks → List blocks; sentence case matches the editorial guide. parameters[6].description: Field used to sort the result. Sorting by `name` is case-sensitive and follows the storage collation, so do not rely on a case-insensitive order. → Field used to sort the result. Do not rely on case-insensitive ordering when sorting by `name`. parameters[6].schema.description: Field used to sort the result. Sorting by `name` is case-sensitive and follows the storage collation, so do not rely on a case-insensitive order. → Field used to sort the result. Do not rely on case-insensitive ordering when sorting by `name`. responses.200.content.application/json.schema.properties.nextCursor.description: Opaque cursor for the next page. Send it back as `cursor`; `null` means there is nothing further to fetch. Never construct one yourself. → Opaque cursor for the next page. Send it back as `cursor`; `null` means there are no more pages. Do not construct a cursor yourself. 1 request/response media example set(s) now expose the owner's existing examples to the API renderer. Preserved: Compared operationId listBlocks, GET /api/v2/blocks, security and x-sim-operation with baseline; identifiers, route and credential schemes match. Recursive prose/default/example mappings retained in final-review-api-comparison.json; 7 distinct changed field mappings were inspected for this operation. Operation-level request/response structure, parameters, required fields, defaults and status declarations are identical after removing prose/examples; referenced component changes were reviewed separately. | +| `getBlock` — `GET /api/v2/blocks/{blockId}` | corrected | Resolved visible version/hidden 404/field projection verified; direct-input context. | Verified improvement. Summary: Get Block → Get block; sentence case matches the editorial guide. parameters[0].description: Block type identifier. An unversioned base type resolves to the newest version, and the response echoes the resolved id. → Block type identifier. An unversioned base type resolves to the newest visible version. The response echoes the resolved ID. parameters[0].schema.description: Block type identifier. An unversioned base type resolves to the newest version, and the response echoes the resolved id. → Block type identifier. An unversioned base type resolves to the newest visible version. The response echoes the resolved ID. responses.200.content.application/json.schema.properties.data.properties.operations.additionalProperties.properties.inputs.additionalProperties.properties.visibility.description: Who may supply the value: `user-or-llm`, `user-only`, `llm-only`, or `hidden`. → Source of the value in a workflow or Agent block: `user-or-llm`, `user-only`, `llm-only`, or `hidden`. A direct Run tool caller may supply non-hidden parameters; Sim supplies hidd… 1 request/response media example set(s) now expose the owner's existing examples to the API renderer. Preserved: Compared operationId getBlock, GET /api/v2/blocks/{blockId}, security and x-sim-operation with baseline; identifiers, route and credential schemes match. Recursive prose/default/example mappings retained in final-review-api-comparison.json; 40 distinct changed field mappings were inspected for this operation. Operation-level request/response structure, parameters, required fields, defaults and status declarations are identical after removing prose/examples; referenced component changes were reviewed separately. Optional reactiveCondition fields are upstream source changes already present in origin/staging; their requiredType/watchFields shape is preserved. | +| `listTools` — `GET /api/v2/tools` | corrected | Visible block-exposed built-ins/hosting/filter rules verified; sort rationale. Shared name-sort rationale corrected by root; local sort fields/defaults preserved. | Verified improvement. Summary: List Tools → List tools; sentence case matches the editorial guide. parameters[4].description: Field used to sort the result. Sorting by `name` is case-sensitive and follows the storage collation, so do not rely on a case-insensitive order. → Field used to sort the result. Do not rely on case-insensitive ordering when sorting by `name`. parameters[4].schema.description: Field used to sort the result. Sorting by `name` is case-sensitive and follows the storage collation, so do not rely on a case-insensitive order. → Field used to sort the result. Do not rely on case-insensitive ordering when sorting by `name`. responses.200.content.application/json.schema.properties.data.items.properties.hostedApiKey.description: Whether Sim supplies the API key on THIS deployment: `always`, `conditional` (only for some parameter combinations), or `none` (bring your own). Self-hosted deployments supply no … → API-key hosting on this deployment: `always`, `conditional` for some parameter combinations, or `none` when the caller must supply a key. Self-hosted deployments report `none` for… 1 request/response media example set(s) now expose the owner's existing examples to the API renderer. Preserved: Compared operationId listTools, GET /api/v2/tools, security and x-sim-operation with baseline; identifiers, route and credential schemes match. Recursive prose/default/example mappings retained in final-review-api-comparison.json; 8 distinct changed field mappings were inspected for this operation. Operation-level request/response structure, parameters, required fields, defaults and status declarations are identical after removing prose/examples; referenced component changes were reviewed separately. | +| `getTool` — `GET /api/v2/tools/{toolId}` | corrected | Exact visible ID vs newest visible resolution needs correction. | Verified improvement. Summary: Get Tool → Get tool; sentence case matches the editorial guide. description: Get a built-in tool's parameters and outputs. Registered IDs resolve exactly; other names resolve to the newest family version. The returned `id` identifies the resolved tool. Hid… → Get a built-in tool’s parameters and outputs. An exact visible ID is retained; an unversioned name resolves to the newest visible family version. The returned `id` identifies that… parameters[0].description: Tool identifier. An unversioned name resolves to the newest version, and the response echoes the resolved id. → Tool identifier. An exact visible ID is retained; an unversioned name resolves to the newest visible family version. The response echoes the resolved ID. parameters[0].schema.description: Tool identifier. An unversioned name resolves to the newest version, and the response echoes the resolved id. → Tool identifier. An exact visible ID is retained; an unversioned name resolves to the newest visible family version. The response echoes the resolved ID. 1 request/response media example set(s) now expose the owner's existing examples to the API renderer. Preserved: Compared operationId getTool, GET /api/v2/tools/{toolId}, security and x-sim-operation with baseline; identifiers, route and credential schemes match. Recursive prose/default/example mappings retained in final-review-api-comparison.json; 8 distinct changed field mappings were inspected for this operation. Operation-level request/response structure, parameters, required fields, defaults and status declarations are identical after removing prose/examples; referenced component changes were reviewed separately. | +| `executeTool` — `POST /api/v2/tools/{toolId}/execute` | corrected | 200 failed outcome/hosted billing correct; direct-input/credential caveats. | Verified improvement. Summary: Run Tool → Run tool; sentence case matches the editorial guide. description: Run a built-in tool using published parameter IDs. Sim resolves `credentialId`, hosted keys, and whole-value `{{VAR_NAME}}` references for `user-only` parameters; other values pas… → Run a built-in tool using published parameter IDs. Requires workspace read access. Sim resolves `credentialId`, hosted keys, and whole-value `{{VAR_NAME}}` references in `user-onl… parameters[0].description: Tool identifier. An unversioned name resolves to the newest version, and the response echoes the resolved id. → Tool identifier. An exact visible ID is retained; an unversioned name resolves to the newest visible family version. The response echoes the resolved ID. parameters[0].schema.description: Tool identifier. An unversioned name resolves to the newest version, and the response echoes the resolved id. → Tool identifier. An exact visible ID is retained; an unversioned name resolves to the newest visible family version. The response echoes the resolved ID. 2 request/response media example set(s) now expose the owner's existing examples to the API renderer. Preserved: Compared operationId executeTool, POST /api/v2/tools/{toolId}/execute, security and x-sim-operation with baseline; identifiers, route and credential schemes match. Recursive prose/default/example mappings retained in final-review-api-comparison.json; 12 distinct changed field mappings were inspected for this operation. Operation-level request/response structure, parameters, required fields, defaults and status declarations are identical after removing prose/examples; referenced component changes were reviewed separately. | +| `listConnectorTypes` — `GET /api/v2/connector-types` | corrected | Projection/25 default/canonical keys correct; workspace filter statement false. | Verified improvement. Summary: List Connector Types → List connector types; sentence case matches the editorial guide. description: List knowledge-base connector types with opaque cursors, defaulting to 25 summaries per page: identifier, name, description, and auth mode. `detail=full` adds accepted source conf… → List connector types from the deployment’s knowledge-base connector registry. Requires workspace read access and Knowledge Base access; workspace integration allowlists and reveal… parameters[0].description: Workspace whose integration allowlist, revealed preview blocks, and deployed custom blocks decide what this catalog contains. → Workspace used to authorize Knowledge Base access to the deployment’s connector-type registry. Workspace integration allowlists and revealed preview blocks do not filter this cata… parameters[0].schema.description: Workspace whose integration allowlist, revealed preview blocks, and deployed custom blocks decide what this catalog contains. → Workspace used to authorize Knowledge Base access to the deployment’s connector-type registry. Workspace integration allowlists and revealed preview blocks do not filter this cata… 1 request/response media example set(s) now expose the owner's existing examples to the API renderer. Complete Google Drive summary/full examples now match current canonical meta and exact public projection: auth/drive, seven fields, google.drive picker, folderId manual input, typed tags, false incremental-sync flag, and exact UI labels. Preserved: Compared operationId listConnectorTypes, GET /api/v2/connector-types, security and x-sim-operation with baseline; identifiers, route and credential schemes match. Recursive prose/default/example mappings retained in final-review-api-comparison.json; 8 distinct changed field mappings were inspected for this operation. Operation-level request/response structure, parameters, required fields, defaults and status declarations are identical after removing prose/examples; referenced component changes were reviewed separately. Generated full media example equals final-connector-example.json exactly; public response envelope/schema unchanged. | +| `listPermissionGroups` — `GET /api/v2/organizations/{organizationId}/permission-groups` | corrected | Schema, operation policy and current response verified; clarify generic labels. | Verified improvement. Summary: List Permission Groups → List permission groups; sentence case matches the editorial guide. parameters[2].description: Field used to sort the result. Sorting by `name` is case-sensitive and follows the storage collation, so do not rely on a case-insensitive order. → Field used to sort the result. Do not rely on case-insensitive ordering when sorting by `name`. parameters[2].schema.description: Field used to sort the result. Sorting by `name` is case-sensitive and follows the storage collation, so do not rely on a case-insensitive order. → Field used to sort the result. Do not rely on case-insensitive ordering when sorting by `name`. responses.200.content.application/json.schema.description: List Permission Groups result. → A page of permission groups with resolved settings. 1 request/response media example set(s) now expose the owner's existing examples to the API renderer. Preserved: Compared operationId listPermissionGroups, GET /api/v2/organizations/{organizationId}/permission-groups, security and x-sim-operation with baseline; identifiers, route and credential schemes match. Recursive prose/default/example mappings retained in final-review-api-comparison.json; 13 distinct changed field mappings were inspected for this operation. Operation-level request/response structure, parameters, required fields, defaults and status declarations are identical after removing prose/examples; referenced component changes were reviewed separately. | +| `createPermissionGroup` — `POST /api/v2/organizations/{organizationId}/permission-groups` | corrected | Schema, operation policy and current response verified; clarify generic labels. | Verified improvement. Summary: Create Permission Group → Create permission group; sentence case matches the editorial guide. requestBody.content.application/json.schema.description: Create Permission Group inputs. → Group name, initial restrictions, and default or workspace-specific scope. requestBody.content.application/json.schema.properties.config.properties.hideDeployChatbot.description: Prevent publishing a workflow as a chat. → Prevent deploying a workflow as a chat. requestBody.description: Create Permission Group inputs. → Group name, initial restrictions, and default or workspace-specific scope. 2 request/response media example set(s) now expose the owner's existing examples to the API renderer. Preserved: Compared operationId createPermissionGroup, POST /api/v2/organizations/{organizationId}/permission-groups, security and x-sim-operation with baseline; identifiers, route and credential schemes match. Recursive prose/default/example mappings retained in final-review-api-comparison.json; 13 distinct changed field mappings were inspected for this operation. Operation-level request/response structure, parameters, required fields, defaults and status declarations are identical after removing prose/examples; referenced component changes were reviewed separately. | +| `getPermissionGroup` — `GET /api/v2/organizations/{organizationId}/permission-groups/{groupId}` | corrected | Schema, operation policy and current response verified; clarify generic labels. | Verified improvement. Summary: Get Permission Group → Get permission group; sentence case matches the editorial guide. responses.200.content.application/json.schema.description: Get Permission Group result. → The group, its resolved settings, and workspace scope. responses.200.content.application/json.schema.properties.data.properties.config.properties.hideDeployChatbot.description: Prevent publishing a workflow as a chat. → Prevent deploying a workflow as a chat. responses.200.content.application/json.schema.properties.data.properties.isDefault.description: Whether this is the organization default, which applies to everyone across all its workspaces regardless of member assignments. → Whether this is the organization fallback group. It governs a human caller with no applicable workspace-specific group; its own membership assignments do not limit its audience. O… 1 request/response media example set(s) now expose the owner's existing examples to the API renderer. Preserved: Compared operationId getPermissionGroup, GET /api/v2/organizations/{organizationId}/permission-groups/{groupId}, security and x-sim-operation with baseline; identifiers, route and credential schemes match. Recursive prose/default/example mappings retained in final-review-api-comparison.json; 9 distinct changed field mappings were inspected for this operation. Operation-level request/response structure, parameters, required fields, defaults and status declarations are identical after removing prose/examples; referenced component changes were reviewed separately. | +| `updatePermissionGroup` — `PATCH /api/v2/organizations/{organizationId}/permission-groups/{groupId}` | corrected | Schema, operation policy and current response verified; clarify generic labels. | Verified improvement. Summary: Update Permission Group → Update permission group; sentence case matches the editorial guide. requestBody.content.application/json.schema.description: Update Permission Group inputs. → Group fields and restriction keys to change; supplied lists replace their contents. requestBody.content.application/json.schema.properties.config.properties.hideDeployChatbot.description: Prevent publishing a workflow as a chat. → Prevent deploying a workflow as a chat. requestBody.description: Update Permission Group inputs. → Group fields and restriction keys to change; supplied lists replace their contents. 2 request/response media example set(s) now expose the owner's existing examples to the API renderer. Preserved: Compared operationId updatePermissionGroup, PATCH /api/v2/organizations/{organizationId}/permission-groups/{groupId}, security and x-sim-operation with baseline; identifiers, route and credential schemes match. Recursive prose/default/example mappings retained in final-review-api-comparison.json; 13 distinct changed field mappings were inspected for this operation. Operation-level request/response structure, parameters, required fields, defaults and status declarations are identical after removing prose/examples; referenced component changes were reviewed separately. | +| `deletePermissionGroup` — `DELETE /api/v2/organizations/{organizationId}/permission-groups/{groupId}` | rewritten | Reviewed; accurate details retained under the shared reference standard. | Verified improvement. Summary: Delete Permission Group → Delete permission group; sentence case matches the editorial guide. responses.200.content.application/json.schema.description: Delete Permission Group result. → Acknowledgement that the group and its assignments were deleted. responses.200.description: Delete Permission Group result. → Acknowledgement that the group and its assignments were deleted. responses.503.description: A required service is temporarily unavailable. `Retry-After` carries the seconds to wait; treat it as a floor and add jitter. The header is omitted when `error.details.code` is `A… → A required service is temporarily unavailable. When present, `Retry-After` gives the minimum seconds to wait; add jitter before retrying. Check operation-specific guidance before … 1 request/response media example set(s) now expose the owner's existing examples to the API renderer. Preserved: Compared operationId deletePermissionGroup, DELETE /api/v2/organizations/{organizationId}/permission-groups/{groupId}, security and x-sim-operation with baseline; identifiers, route and credential schemes match. Recursive prose/default/example mappings retained in final-review-api-comparison.json; 6 distinct changed field mappings were inspected for this operation. Operation-level request/response structure, parameters, required fields, defaults and status declarations are identical after removing prose/examples; referenced component changes were reviewed separately. | +| `listPermissionGroupMembers` — `GET /api/v2/organizations/{organizationId}/permission-groups/{groupId}/members` | rewritten | Reviewed; accurate details retained under the shared reference standard. | Verified improvement. Summary: List Permission Group Members → List permission group members; sentence case matches the editorial guide. responses.200.content.application/json.schema.description: List Permission Group Members result. → A page of explicit group membership assignments. responses.200.content.application/json.schema.properties.nextCursor.description: Opaque cursor for the next page. Send it back as `cursor`; `null` means there is nothing further to fetch. Never construct one yourself. → Opaque cursor for the next page. Send it back as `cursor`; `null` means there are no more pages. Do not construct a cursor yourself. responses.200.description: List Permission Group Members result. → A page of explicit group membership assignments. 1 request/response media example set(s) now expose the owner's existing examples to the API renderer. Preserved: Compared operationId listPermissionGroupMembers, GET /api/v2/organizations/{organizationId}/permission-groups/{groupId}/members, security and x-sim-operation with baseline; identifiers, route and credential schemes match. Recursive prose/default/example mappings retained in final-review-api-comparison.json; 7 distinct changed field mappings were inspected for this operation. Operation-level request/response structure, parameters, required fields, defaults and status declarations are identical after removing prose/examples; referenced component changes were reviewed separately. | +| `addPermissionGroupMember` — `POST /api/v2/organizations/{organizationId}/permission-groups/{groupId}/members` | rewritten | Reviewed; accurate details retained under the shared reference standard. | Verified improvement. Summary: Add Permission Group Member → Add permission group member; sentence case matches the editorial guide. requestBody.content.application/json.schema.description: Add Permission Group Member inputs. → The organization member to assign to this group. requestBody.description: Add Permission Group Member inputs. → The organization member to assign to this group. responses.201.content.application/json.schema.description: Add Permission Group Member result. → The new explicit membership assignment. 2 request/response media example set(s) now expose the owner's existing examples to the API renderer. Preserved: Compared operationId addPermissionGroupMember, POST /api/v2/organizations/{organizationId}/permission-groups/{groupId}/members, security and x-sim-operation with baseline; identifiers, route and credential schemes match. Recursive prose/default/example mappings retained in final-review-api-comparison.json; 9 distinct changed field mappings were inspected for this operation. Operation-level request/response structure, parameters, required fields, defaults and status declarations are identical after removing prose/examples; referenced component changes were reviewed separately. | +| `removePermissionGroupMember` — `DELETE /api/v2/organizations/{organizationId}/permission-groups/{groupId}/members/{userId}` | rewritten | Reviewed; accurate details retained under the shared reference standard. | Verified improvement. Summary: Remove Permission Group Member → Remove permission group member; sentence case matches the editorial guide. responses.200.content.application/json.schema.description: Remove Permission Group Member result. → Acknowledgement that the explicit assignment was removed. responses.200.description: Remove Permission Group Member result. → Acknowledgement that the explicit assignment was removed. responses.503.description: A required service is temporarily unavailable. `Retry-After` carries the seconds to wait; treat it as a floor and add jitter. The header is omitted when `error.details.code` is `A… → A required service is temporarily unavailable. When present, `Retry-After` gives the minimum seconds to wait; add jitter before retrying. Check operation-specific guidance before … 1 request/response media example set(s) now expose the owner's existing examples to the API renderer. Preserved: Compared operationId removePermissionGroupMember, DELETE /api/v2/organizations/{organizationId}/permission-groups/{groupId}/members/{userId}, security and x-sim-operation with baseline; identifiers, route and credential schemes match. Recursive prose/default/example mappings retained in final-review-api-comparison.json; 6 distinct changed field mappings were inspected for this operation. Operation-level request/response structure, parameters, required fields, defaults and status declarations are identical after removing prose/examples; referenced component changes were reviewed separately. | +| `bulkAddPermissionGroupMembers` — `POST /api/v2/organizations/{organizationId}/permission-groups/{groupId}/members/bulk` | rewritten | Reviewed; accurate details retained under the shared reference standard. | Verified improvement. Summary: Bulk Add Permission Group Members → Bulk add permission group members; sentence case matches the editorial guide. requestBody.content.application/json.schema.description: Bulk Add Permission Group Members inputs. → Selected organization members or the entire current organization roster. requestBody.description: Bulk Add Permission Group Members inputs. → Selected organization members or the entire current organization roster. responses.200.content.application/json.schema.description: Bulk Add Permission Group Members result. → Counts of added members and existing assignments skipped. 2 request/response media example set(s) now expose the owner's existing examples to the API renderer. Preserved: Compared operationId bulkAddPermissionGroupMembers, POST /api/v2/organizations/{organizationId}/permission-groups/{groupId}/members/bulk, security and x-sim-operation with baseline; identifiers, route and credential schemes match. Recursive prose/default/example mappings retained in final-review-api-comparison.json; 9 distinct changed field mappings were inspected for this operation. Operation-level request/response structure, parameters, required fields, defaults and status declarations are identical after removing prose/examples; referenced component changes were reviewed separately. | +| `listOrganizations` — `GET /api/v2/organizations` | rewritten | Reviewed; accurate details retained under the shared reference standard. | Verified improvement. Summary: List Organizations → List organizations; sentence case matches the editorial guide. parameters[1].description: Field used to sort the result. Sorting by `name` is case-sensitive and follows the storage collation, so do not rely on a case-insensitive order. → Field used to sort the result. Do not rely on case-insensitive ordering when sorting by `name`. parameters[1].schema.description: Field used to sort the result. Sorting by `name` is case-sensitive and follows the storage collation, so do not rely on a case-insensitive order. → Field used to sort the result. Do not rely on case-insensitive ordering when sorting by `name`. responses.200.content.application/json.schema.description: List Organizations result. → A page of organizations and the acting user’s role in each. 1 request/response media example set(s) now expose the owner's existing examples to the API renderer. Preserved: Compared operationId listOrganizations, GET /api/v2/organizations, security and x-sim-operation with baseline; identifiers, route and credential schemes match. Recursive prose/default/example mappings retained in final-review-api-comparison.json; 8 distinct changed field mappings were inspected for this operation. Operation-level request/response structure, parameters, required fields, defaults and status declarations are identical after removing prose/examples; referenced component changes were reviewed separately. | +| `getOrganization` — `GET /api/v2/organizations/{organizationId}` | rewritten | Reviewed; accurate details retained under the shared reference standard. Review correction: params metadata now says Organization identifier. | Verified improvement. Summary: Get Organization → Get organization; sentence case matches the editorial guide. responses.200.content.application/json.schema.description: Get Organization result. → Organization metadata and the acting user’s role. responses.200.description: Get Organization result. → Organization metadata and the acting user’s role. responses.503.description: A required service is temporarily unavailable. `Retry-After` carries the seconds to wait; treat it as a floor and add jitter. The header is omitted when `error.details.code` is `A… → A required service is temporarily unavailable. When present, `Retry-After` gives the minimum seconds to wait; add jitter before retrying. Check operation-specific guidance before … 1 request/response media example set(s) now expose the owner's existing examples to the API renderer. Preserved: Compared operationId getOrganization, GET /api/v2/organizations/{organizationId}, security and x-sim-operation with baseline; identifiers, route and credential schemes match. Recursive prose/default/example mappings retained in final-review-api-comparison.json; 5 distinct changed field mappings were inspected for this operation. Operation-level request/response structure, parameters, required fields, defaults and status declarations are identical after removing prose/examples; referenced component changes were reviewed separately. | +| `listOrganizationWorkspaces` — `GET /api/v2/organizations/{organizationId}/workspaces` | rewritten | Reviewed; accurate details retained under the shared reference standard. Review correction: params metadata now says Organization identifier. | Verified improvement. Summary: List Organization Workspaces → List organization workspaces; sentence case matches the editorial guide. description: List active workspaces owned by the organization. Requires organization administrator access; does not require Access Control. Workspace API keys return `403`; use a personal API … → List active workspaces owned by the organization. Requires organization Admin access; does not require Access Control. Workspace API keys return `403`; use a personal API key or s… parameters[2].description: Field used to sort the result. Sorting by `name` is case-sensitive and follows the storage collation, so do not rely on a case-insensitive order. → Field used to sort the result. Do not rely on case-insensitive ordering when sorting by `name`. parameters[2].schema.description: Field used to sort the result. Sorting by `name` is case-sensitive and follows the storage collation, so do not rely on a case-insensitive order. → Field used to sort the result. Do not rely on case-insensitive ordering when sorting by `name`. 1 request/response media example set(s) now expose the owner's existing examples to the API renderer. Preserved: Compared operationId listOrganizationWorkspaces, GET /api/v2/organizations/{organizationId}/workspaces, security and x-sim-operation with baseline; identifiers, route and credential schemes match. Recursive prose/default/example mappings retained in final-review-api-comparison.json; 9 distinct changed field mappings were inspected for this operation. Operation-level request/response structure, parameters, required fields, defaults and status declarations are identical after removing prose/examples; referenced component changes were reviewed separately. | +| `listOrganizationMembers` — `GET /api/v2/organizations/{organizationId}/members` | rewritten | Reviewed; accurate details retained under the shared reference standard. Review correction: params metadata now says Organization identifier. | Verified improvement. Summary: List Organization Members → List organization members; sentence case matches the editorial guide. parameters[2].description: Field used to sort the result. Sorting by `name` is case-sensitive and follows the storage collation, so do not rely on a case-insensitive order. → Field used to sort the result. Do not rely on case-insensitive ordering when sorting by `name`. parameters[2].schema.description: Field used to sort the result. Sorting by `name` is case-sensitive and follows the storage collation, so do not rely on a case-insensitive order. → Field used to sort the result. Do not rely on case-insensitive ordering when sorting by `name`. responses.200.content.application/json.schema.description: List Organization Members result. → A page of organization members and their organization roles. 1 request/response media example set(s) now expose the owner's existing examples to the API renderer. Preserved: Compared operationId listOrganizationMembers, GET /api/v2/organizations/{organizationId}/members, security and x-sim-operation with baseline; identifiers, route and credential schemes match. Recursive prose/default/example mappings retained in final-review-api-comparison.json; 8 distinct changed field mappings were inspected for this operation. Operation-level request/response structure, parameters, required fields, defaults and status declarations are identical after removing prose/examples; referenced component changes were reviewed separately. | +| `updateOrganizationMember` — `PATCH /api/v2/organizations/{organizationId}/members/{userId}` | rewritten | Reviewed; accurate details retained under the shared reference standard. | Verified improvement. Summary: Update Organization Member → Update organization member; sentence case matches the editorial guide. description: Change a member’s organization role. Requires organization administrator access. The owner’s role and memberships managed by an identity provider cannot be changed here. Workspace… → Change a member’s organization role. Requires organization Admin access. The owner’s role and memberships managed by an identity provider cannot be changed here. Workspace API key… requestBody.content.application/json.schema.description: Update Organization Member input. → The new organization role for this member. requestBody.description: Update Organization Member input. → The new organization role for this member. 2 request/response media example set(s) now expose the owner's existing examples to the API renderer. Preserved: Compared operationId updateOrganizationMember, PATCH /api/v2/organizations/{organizationId}/members/{userId}, security and x-sim-operation with baseline; identifiers, route and credential schemes match. Recursive prose/default/example mappings retained in final-review-api-comparison.json; 9 distinct changed field mappings were inspected for this operation. Operation-level request/response structure, parameters, required fields, defaults and status declarations are identical after removing prose/examples; referenced component changes were reviewed separately. | +| `removeOrganizationMember` — `DELETE /api/v2/organizations/{organizationId}/members/{userId}` | rewritten | Reviewed; accurate details retained under the shared reference standard. | Verified improvement. Summary: Remove Organization Member → Remove organization member; sentence case matches the editorial guide. responses.200.content.application/json.schema.description: Remove Organization Member result. → Acknowledgement that organization access was removed. responses.200.description: Remove Organization Member result. → Acknowledgement that organization access was removed. responses.503.description: A required service is temporarily unavailable. `Retry-After` carries the seconds to wait; treat it as a floor and add jitter. The header is omitted when `error.details.code` is `A… → A required service is temporarily unavailable. When present, `Retry-After` gives the minimum seconds to wait; add jitter before retrying. Check operation-specific guidance before … 1 request/response media example set(s) now expose the owner's existing examples to the API renderer. Preserved: Compared operationId removeOrganizationMember, DELETE /api/v2/organizations/{organizationId}/members/{userId}, security and x-sim-operation with baseline; identifiers, route and credential schemes match. Recursive prose/default/example mappings retained in final-review-api-comparison.json; 5 distinct changed field mappings were inspected for this operation. Operation-level request/response structure, parameters, required fields, defaults and status declarations are identical after removing prose/examples; referenced component changes were reviewed separately. | +| `listOrganizationInvitations` — `GET /api/v2/organizations/{organizationId}/invitations` | rewritten | Reviewed; accurate details retained under the shared reference standard. Review correction: params metadata now says Organization identifier. | Verified improvement. Summary: List Organization Invitations → List organization invitations; sentence case matches the editorial guide. description: List invitations owned by the organization, including invitations with workspace grants. Requires organization administrator access. Expired invitations are reported without modif… → List invitations owned by the organization, including invitations with workspace grants. Requires organization Admin access. Expired invitations are reported without modifying the… responses.200.content.application/json.schema.description: List Organization Invitations result. → A page of invitations, including their current status. responses.200.content.application/json.schema.properties.nextCursor.description: Opaque cursor for the next page. Send it back as `cursor`; `null` means there is nothing further to fetch. Never construct one yourself. → Opaque cursor for the next page. Send it back as `cursor`; `null` means there are no more pages. Do not construct a cursor yourself. 1 request/response media example set(s) now expose the owner's existing examples to the API renderer. Preserved: Compared operationId listOrganizationInvitations, GET /api/v2/organizations/{organizationId}/invitations, security and x-sim-operation with baseline; identifiers, route and credential schemes match. Recursive prose/default/example mappings retained in final-review-api-comparison.json; 7 distinct changed field mappings were inspected for this operation. Operation-level request/response structure, parameters, required fields, defaults and status declarations are identical after removing prose/examples; referenced component changes were reviewed separately. | +| `createOrganizationInvitation` — `POST /api/v2/organizations/{organizationId}/invitations` | corrected | Billing qualification and already-in-an-organization conflicts missing. Review correction: params metadata now says Organization identifier. | Verified improvement. Summary: Create Organization Invitation → Create organization invitation; sentence case matches the editorial guide. description: Email an invitation to join the organization as a member or administrator. Requires organization administrator access, invitations enabled, and an available seat on an eligible pl… → Email an invitation to join the organization as a member or Admin. Requires organization Admin access and invitations enabled; an eligible plan and available seat are required whe… requestBody.content.application/json.schema.description: Create Organization Invitation input. → Invitee email and organization role to offer. requestBody.description: Create Organization Invitation input. → Invitee email and organization role to offer. 2 request/response media example set(s) now expose the owner's existing examples to the API renderer. Preserved: Compared operationId createOrganizationInvitation, POST /api/v2/organizations/{organizationId}/invitations, security and x-sim-operation with baseline; identifiers, route and credential schemes match. Recursive prose/default/example mappings retained in final-review-api-comparison.json; 9 distinct changed field mappings were inspected for this operation. Operation-level request/response structure, parameters, required fields, defaults and status declarations are identical after removing prose/examples; referenced component changes were reviewed separately. | +| `getOrganizationInvitation` — `GET /api/v2/organizations/{organizationId}/invitations/{invitationId}` | rewritten | Reviewed; accurate details retained under the shared reference standard. | Verified improvement. Summary: Get Organization Invitation → Get organization invitation; sentence case matches the editorial guide. description: Get an invitation owned by the organization. Requires organization administrator access. Use List Organization Invitation Workspaces to inspect its workspace grants. The response … → Get an invitation owned by the organization. Requires organization Admin access. Use List organization invitation workspaces to inspect its workspace grants. The response excludes… responses.200.content.application/json.schema.description: Get Organization Invitation result. → Invitation metadata without its acceptance token. responses.200.description: Get Organization Invitation result. → Invitation metadata without its acceptance token. 1 request/response media example set(s) now expose the owner's existing examples to the API renderer. Preserved: Compared operationId getOrganizationInvitation, GET /api/v2/organizations/{organizationId}/invitations/{invitationId}, security and x-sim-operation with baseline; identifiers, route and credential schemes match. Recursive prose/default/example mappings retained in final-review-api-comparison.json; 6 distinct changed field mappings were inspected for this operation. Operation-level request/response structure, parameters, required fields, defaults and status declarations are identical after removing prose/examples; referenced component changes were reviewed separately. | +| `revokeOrganizationInvitation` — `DELETE /api/v2/organizations/{organizationId}/invitations/{invitationId}` | rewritten | Reviewed; accurate details retained under the shared reference standard. | Verified improvement. Summary: Revoke Organization Invitation → Revoke organization invitation; sentence case matches the editorial guide. description: Cancel an unexpired pending invitation and all its workspace grants so it can no longer be accepted. Requires organization administrator access. This does not remove a person who … → Cancel an unexpired pending invitation and all its workspace grants so it can no longer be accepted. Requires organization Admin access. This does not remove a person who already … responses.200.content.application/json.schema.description: Revoke Organization Invitation result. → Acknowledgement that the pending invitation was cancelled. responses.200.description: Revoke Organization Invitation result. → Acknowledgement that the pending invitation was cancelled. 1 request/response media example set(s) now expose the owner's existing examples to the API renderer. Preserved: Compared operationId revokeOrganizationInvitation, DELETE /api/v2/organizations/{organizationId}/invitations/{invitationId}, security and x-sim-operation with baseline; identifiers, route and credential schemes match. Recursive prose/default/example mappings retained in final-review-api-comparison.json; 6 distinct changed field mappings were inspected for this operation. Operation-level request/response structure, parameters, required fields, defaults and status declarations are identical after removing prose/examples; referenced component changes were reviewed separately. | +| `listOrganizationInvitationWorkspaces` — `GET /api/v2/organizations/{organizationId}/invitations/{invitationId}/workspaces` | rewritten | Reviewed; accurate details retained under the shared reference standard. | Verified improvement. Summary: List Organization Invitation Workspaces → List organization invitation workspaces; sentence case matches the editorial guide. description: List workspace grants attached to an invitation of any status. Includes archived workspaces still owned by the organization; workspaces moved to another organization are omitted. … → List workspace grants attached to an invitation of any status. Includes archived workspaces still owned by the organization; workspaces moved to another organization are omitted. … parameters[3].description: Field used to sort the result. Sorting by `name` is case-sensitive and follows the storage collation, so do not rely on a case-insensitive order. → Field used to sort the result. Do not rely on case-insensitive ordering when sorting by `name`. parameters[3].schema.description: Field used to sort the result. Sorting by `name` is case-sensitive and follows the storage collation, so do not rely on a case-insensitive order. → Field used to sort the result. Do not rely on case-insensitive ordering when sorting by `name`. 1 request/response media example set(s) now expose the owner's existing examples to the API renderer. Preserved: Compared operationId listOrganizationInvitationWorkspaces, GET /api/v2/organizations/{organizationId}/invitations/{invitationId}/workspaces, security and x-sim-operation with baseline; identifiers, route and credential schemes match. Recursive prose/default/example mappings retained in final-review-api-comparison.json; 7 distinct changed field mappings were inspected for this operation. Operation-level request/response structure, parameters, required fields, defaults and status declarations are identical after removing prose/examples; referenced component changes were reviewed separately. | +| `resendOrganizationInvitation` — `POST /api/v2/organizations/{organizationId}/invitations/{invitationId}/resend` | rewritten | Reviewed; accurate details retained under the shared reference standard. | Verified improvement. Summary: Resend Organization Invitation → Resend organization invitation; sentence case matches the editorial guide. description: Email an unexpired pending invitation again, renew its expiry, and replace its previous acceptance link. Requires organization administrator access and current invitation eligibil… → Email an unexpired pending invitation again, renew its expiry, and replace its previous acceptance link. Requires organization Admin access and current invitation eligibility. Ret… requestBody.content.application/json.schema.description: Resend Organization Invitation input. → An empty JSON object; the pending invitation supplies the recipient and role. requestBody.description: Resend Organization Invitation input. → An empty JSON object; the pending invitation supplies the recipient and role. 2 request/response media example set(s) now expose the owner's existing examples to the API renderer. Preserved: Compared operationId resendOrganizationInvitation, POST /api/v2/organizations/{organizationId}/invitations/{invitationId}/resend, security and x-sim-operation with baseline; identifiers, route and credential schemes match. Recursive prose/default/example mappings retained in final-review-api-comparison.json; 9 distinct changed field mappings were inspected for this operation. Operation-level request/response structure, parameters, required fields, defaults and status declarations are identical after removing prose/examples; referenced component changes were reviewed separately. | +| `listSsoProviders` — `GET /api/v2/organizations/{organizationId}/sso/providers` | rewritten | Reviewed; accurate details retained under the shared reference standard. Review correction: query metadata now says Sorting and pagination controls. | Verified improvement. Summary: List SSO Providers → List SSO providers; sentence case matches the editorial guide. description: List identity providers owned by the organization. Requires organization administrator access. OIDC client secrets are redacted and SAML private keys are omitted. Workspace API ke… → List identity providers owned by the organization. Requires organization Admin access. OIDC client secrets are redacted and SAML private keys are omitted. Workspace API keys retur… responses.200.content.application/json.schema.description: List SSO Providers result. → A page of identity providers with redacted configuration. responses.200.content.application/json.schema.properties.nextCursor.description: Opaque cursor for the next page. Send it back as `cursor`; `null` means there is nothing further to fetch. Never construct one yourself. → Opaque cursor for the next page. Send it back as `cursor`; `null` means there are no more pages. Do not construct a cursor yourself. Preserved: Compared operationId listSsoProviders, GET /api/v2/organizations/{organizationId}/sso/providers, security and x-sim-operation with baseline; identifiers, route and credential schemes match. Recursive prose/default/example mappings retained in final-review-api-comparison.json; 6 distinct changed field mappings were inspected for this operation. Operation-level request/response structure, parameters, required fields, defaults and status declarations are identical after removing prose/examples; referenced component changes were reviewed separately. | +| `saveSsoProvider` — `POST /api/v2/organizations/{organizationId}/sso/providers` | rewritten | Reviewed; accurate details retained under the shared reference standard. Review correction: query metadata now says No query parameters. Review correction: save returns provider ID, protocol and creation state, not configuration. | Verified improvement. Summary: Save SSO Provider → Save SSO provider; sentence case matches the editorial guide. description: Create or update an organization identity provider’s configuration on a verified domain. Requires organization administrator access and SSO entitlement. Existing providers return … → Create or update an organization identity provider’s configuration on a verified domain. Requires organization Admin access and SSO entitlement. Existing providers return 200; cre… requestBody.content.application/json.schema.description: Configuration accepted by Save SSO Provider. → Provider protocol, verified domain, and identity-provider configuration. Omission behavior is field-specific. requestBody.description: Configuration accepted by Save SSO Provider. → Provider protocol, verified domain, and identity-provider configuration. Omission behavior is field-specific. Preserved: Compared operationId saveSsoProvider, POST /api/v2/organizations/{organizationId}/sso/providers, security and x-sim-operation with baseline; identifiers, route and credential schemes match. Recursive prose/default/example mappings retained in final-review-api-comparison.json; 9 distinct changed field mappings were inspected for this operation. Operation-level request/response structure, parameters, required fields, defaults and status declarations are identical after removing prose/examples; referenced component changes were reviewed separately. | +| `getSsoProvider` — `GET /api/v2/organizations/{organizationId}/sso/providers/{providerId}` | rewritten | Reviewed; accurate details retained under the shared reference standard. Review correction: query metadata now says No query parameters. | Verified improvement. Summary: Get SSO Provider → Get SSO provider; sentence case matches the editorial guide. description: Get an identity provider owned by the organization. Requires organization administrator access. OIDC client secrets are redacted and SAML private keys are omitted. Workspace API k… → Get an identity provider owned by the organization. Requires organization Admin access. OIDC client secrets are redacted and SAML private keys are omitted. Workspace API keys retu… responses.200.content.application/json.schema.description: Get SSO Provider result. → The identity provider with redacted configuration. responses.200.description: Get SSO Provider result. → The identity provider with redacted configuration. Preserved: Compared operationId getSsoProvider, GET /api/v2/organizations/{organizationId}/sso/providers/{providerId}, security and x-sim-operation with baseline; identifiers, route and credential schemes match. Recursive prose/default/example mappings retained in final-review-api-comparison.json; 5 distinct changed field mappings were inspected for this operation. Operation-level request/response structure, parameters, required fields, defaults and status declarations are identical after removing prose/examples; referenced component changes were reviewed separately. | +| `deleteSsoProvider` — `DELETE /api/v2/organizations/{organizationId}/sso/providers/{providerId}` | corrected | No membership/session deletion; qualify fallback if provider remains. Review correction: query metadata now says No query parameters. | Verified improvement. Summary: Delete SSO Provider → Delete SSO provider; sentence case matches the editorial guide. description: Remove an identity provider and clear its primary selection. Requires organization administrator access. Existing accounts, memberships, and sessions remain; sign-in falls back to… → Remove an identity provider and clear its primary selection. Requires organization Admin access. Existing accounts, memberships, and sessions remain. Domain sign-in falls back to … responses.200.content.application/json.schema.description: Delete SSO Provider result. → Acknowledgement that the identity provider was removed. responses.200.description: Delete SSO Provider result. → Acknowledgement that the identity provider was removed. Preserved: Compared operationId deleteSsoProvider, DELETE /api/v2/organizations/{organizationId}/sso/providers/{providerId}, security and x-sim-operation with baseline; identifiers, route and credential schemes match. Recursive prose/default/example mappings retained in final-review-api-comparison.json; 5 distinct changed field mappings were inspected for this operation. Operation-level request/response structure, parameters, required fields, defaults and status declarations are identical after removing prose/examples; referenced component changes were reviewed separately. | +| `setPrimarySsoProvider` — `POST /api/v2/organizations/{organizationId}/sso/providers/{providerId}/primary` | rewritten | Reviewed; accurate details retained under the shared reference standard. Review correction: query metadata now says No query parameters. | Verified improvement. Summary: Set Primary SSO Provider → Set primary SSO provider; sentence case matches the editorial guide. description: Make a verified organization provider handle sign-in for its domain. Requires organization administrator access. Other providers remain available for testing and later switching. … → Make a verified organization provider handle sign-in for its domain. Requires organization Admin access. Other providers remain available for testing and later switching. Workspac… requestBody.content.application/json.schema.description: Configuration accepted by Set Primary SSO Provider. → An empty JSON object; the path identifies the provider to make primary. requestBody.description: Configuration accepted by Set Primary SSO Provider. → An empty JSON object; the path identifies the provider to make primary. Preserved: Compared operationId setPrimarySsoProvider, POST /api/v2/organizations/{organizationId}/sso/providers/{providerId}/primary, security and x-sim-operation with baseline; identifiers, route and credential schemes match. Recursive prose/default/example mappings retained in final-review-api-comparison.json; 7 distinct changed field mappings were inspected for this operation. Operation-level request/response structure, parameters, required fields, defaults and status declarations are identical after removing prose/examples; referenced component changes were reviewed separately. | +| `getSsoPolicy` — `GET /api/v2/organizations/{organizationId}/sso/policy` | rewritten | Reviewed; accurate details retained under the shared reference standard. Review correction: query metadata now says No query parameters. | Verified improvement. Summary: Get SSO Policy → Get SSO policy; sentence case matches the editorial guide. responses.200.content.application/json.schema.description: Get SSO Policy result. → The stored SSO requirement and its effective enforcement state. responses.200.description: Get SSO Policy result. → The stored SSO requirement and its effective enforcement state. responses.503.description: A required service is temporarily unavailable. `Retry-After` carries the seconds to wait; treat it as a floor and add jitter. The header is omitted when `error.details.code` is `A… → A required service is temporarily unavailable. When present, `Retry-After` gives the minimum seconds to wait; add jitter before retrying. Check operation-specific guidance before … Preserved: Compared operationId getSsoPolicy, GET /api/v2/organizations/{organizationId}/sso/policy, security and x-sim-operation with baseline; identifiers, route and credential schemes match. Recursive prose/default/example mappings retained in final-review-api-comparison.json; 4 distinct changed field mappings were inspected for this operation. Operation-level request/response structure, parameters, required fields, defaults and status declarations are identical after removing prose/examples; referenced component changes were reviewed separately. | +| `updateSsoPolicy` — `PATCH /api/v2/organizations/{organizationId}/sso/policy` | rewritten | Reviewed; accurate details retained under the shared reference standard. Review correction: query metadata now says No query parameters. | Verified improvement. Summary: Update SSO Policy → Update SSO policy; sentence case matches the editorial guide. description: Require or stop requiring SSO on future sign-ins. Requires organization administrator access. Enabling requires SSO entitlement and a verified provider; disabling remains availabl… → Require or stop requiring SSO on future sign-ins. Requires organization Admin access. Enabling requires SSO entitlement and a verified provider; disabling remains available after … requestBody.content.application/json.schema.description: Configuration accepted by Update SSO Policy. → Whether future sign-ins must use SSO. requestBody.description: Configuration accepted by Update SSO Policy. → Whether future sign-ins must use SSO. Preserved: Compared operationId updateSsoPolicy, PATCH /api/v2/organizations/{organizationId}/sso/policy, security and x-sim-operation with baseline; identifiers, route and credential schemes match. Recursive prose/default/example mappings retained in final-review-api-comparison.json; 7 distinct changed field mappings were inspected for this operation. Operation-level request/response structure, parameters, required fields, defaults and status declarations are identical after removing prose/examples; referenced component changes were reviewed separately. | +| `listOrganizationDomains` — `GET /api/v2/organizations/{organizationId}/domains` | rewritten | Reviewed; accurate details retained under the shared reference standard. Review correction: query metadata now says Sorting and pagination controls. | Verified improvement. Summary: List Organization Domains → List organization domains; sentence case matches the editorial guide. responses.200.content.application/json.schema.description: List Organization Domains result. → A page of domain claims; pending challenges are limited to Admins. responses.200.content.application/json.schema.properties.nextCursor.description: Opaque cursor for the next page. Send it back as `cursor`; `null` means there is nothing further to fetch. Never construct one yourself. → Opaque cursor for the next page. Send it back as `cursor`; `null` means there are no more pages. Do not construct a cursor yourself. responses.200.description: List Organization Domains result. → A page of domain claims; pending challenges are limited to Admins. Preserved: Compared operationId listOrganizationDomains, GET /api/v2/organizations/{organizationId}/domains, security and x-sim-operation with baseline; identifiers, route and credential schemes match. Recursive prose/default/example mappings retained in final-review-api-comparison.json; 5 distinct changed field mappings were inspected for this operation. Operation-level request/response structure, parameters, required fields, defaults and status declarations are identical after removing prose/examples; referenced component changes were reviewed separately. | +| `addOrganizationDomain` — `POST /api/v2/organizations/{organizationId}/domains` | corrected | Existing claim 200/new 201/cross-org conflict correct; missing 25 cap. Review correction: query metadata now says No query parameters. | Verified improvement. Summary: Add Organization Domain → Add organization domain; sentence case matches the editorial guide. description: Claim a domain and receive its DNS TXT challenge. Requires organization administrator access and Enterprise domain entitlement. An existing claim returns 200; a new claim returns … → Claim a domain and receive its DNS TXT challenge. Requires organization Admin access and, when billing is enabled, Enterprise domain entitlement. An organization can claim at most… requestBody.content.application/json.schema.description: Configuration accepted by Add Organization Domain. → The domain to claim and verify. requestBody.description: Configuration accepted by Add Organization Domain. → The domain to claim and verify. Preserved: Compared operationId addOrganizationDomain, POST /api/v2/organizations/{organizationId}/domains, security and x-sim-operation with baseline; identifiers, route and credential schemes match. Recursive prose/default/example mappings retained in final-review-api-comparison.json; 9 distinct changed field mappings were inspected for this operation. Operation-level request/response structure, parameters, required fields, defaults and status declarations are identical after removing prose/examples; referenced component changes were reviewed separately. | +| `verifyOrganizationDomain` — `POST /api/v2/organizations/{organizationId}/domains/{domainId}/verify` | corrected | Already-verified unchanged/domain trust correct; deployment qualification. Review correction: query metadata now says No query parameters. | Verified improvement. Summary: Verify Organization Domain → Verify organization domain; sentence case matches the editorial guide. description: Verify domain ownership through the published DNS TXT challenge and grant domain trust to matching organization providers. Requires organization administrator access and Enterpris… → Verify domain ownership through its DNS TXT challenge and grant domain trust to matching organization providers. Requires organization Admin access and, when billing is enabled, E… requestBody.content.application/json.schema.description: Configuration accepted by Verify Organization Domain. → An empty JSON object; verification uses the claim’s current DNS challenge. requestBody.description: Configuration accepted by Verify Organization Domain. → An empty JSON object; verification uses the claim’s current DNS challenge. Preserved: Compared operationId verifyOrganizationDomain, POST /api/v2/organizations/{organizationId}/domains/{domainId}/verify, security and x-sim-operation with baseline; identifiers, route and credential schemes match. Recursive prose/default/example mappings retained in final-review-api-comparison.json; 7 distinct changed field mappings were inspected for this operation. Operation-level request/response structure, parameters, required fields, defaults and status declarations are identical after removing prose/examples; referenced component changes were reviewed separately. | +| `removeOrganizationDomain` — `DELETE /api/v2/organizations/{organizationId}/domains/{domainId}` | corrected | Domain trust revoked/accounts retained correct; deployment qualification. Review correction: query metadata now says No query parameters. | Verified improvement. Summary: Remove Organization Domain → Remove organization domain; sentence case matches the editorial guide. description: Remove a domain claim and revoke verified sign-in authority from matching organization providers. Requires organization administrator access and Enterprise domain entitlement. Exi… → Remove a domain claim and revoke verified sign-in authority from matching organization providers. Requires organization Admin access and, when billing is enabled, Enterprise domai… responses.200.content.application/json.schema.description: Remove Organization Domain result. → Acknowledgement that the domain claim was removed. responses.200.description: Remove Organization Domain result. → Acknowledgement that the domain claim was removed. Preserved: Compared operationId removeOrganizationDomain, DELETE /api/v2/organizations/{organizationId}/domains/{domainId}, security and x-sim-operation with baseline; identifiers, route and credential schemes match. Recursive prose/default/example mappings retained in final-review-api-comparison.json; 5 distinct changed field mappings were inspected for this operation. Operation-level request/response structure, parameters, required fields, defaults and status declarations are identical after removing prose/examples; referenced component changes were reviewed separately. | +| `listCredentialMembers` — `GET /api/v2/credentials/{credentialId}/members` | corrected | Grant states/inherited admins correct; remove irrelevant session behavior. Review correction: caller authentication differs from target credential type; integrations.manage is named explicitly. | Verified improvement. Summary: List Credential Members → List credential members; sentence case matches the editorial guide. description: List explicit credential grants, including revoked grants, and inherited workspace administrator access. Requires workspace read access and the integrations.manage capability. Per… → List explicit credential grants, including revoked grants, and inherited workspace Admin access. This endpoint supports OAuth and service-account credentials. Requires workspace r… parameters[4].description: Field used to sort the result. Sorting by `name` is case-sensitive and follows the storage collation, so do not rely on a case-insensitive order. → Field used to sort the result. Do not rely on case-insensitive ordering when sorting by `name`. parameters[4].schema.description: Field used to sort the result. Sorting by `name` is case-sensitive and follows the storage collation, so do not rely on a case-insensitive order. → Field used to sort the result. Do not rely on case-insensitive ordering when sorting by `name`. Preserved: Compared operationId listCredentialMembers, GET /api/v2/credentials/{credentialId}/members, security and x-sim-operation with baseline; identifiers, route and credential schemes match. Recursive prose/default/example mappings retained in final-review-api-comparison.json; 8 distinct changed field mappings were inspected for this operation. Operation-level request/response structure, parameters, required fields, defaults and status declarations are identical after removing prose/examples; referenced component changes were reviewed separately. | +| `upsertCredentialMember` — `POST /api/v2/credentials/{credentialId}/members` | rewritten | Reviewed; accurate details retained under the shared reference standard. Review correction: integrations.manage is named explicitly. | Verified improvement. Summary: Upsert Credential Member → Upsert credential member; sentence case matches the editorial guide. description: Grant or change an existing workspace member’s credential role. Requires credential administrator access and the integrations.manage capability. Revoked grants become active again… → Grant or change a current workspace member’s credential role. Requires credential Admin access and permission to manage integration connections. Revoked grants become active again… requestBody.content.application/json.schema.description: Configuration accepted by Upsert Credential Member. → The current workspace member and credential role to grant. requestBody.description: Configuration accepted by Upsert Credential Member. → The current workspace member and credential role to grant. Preserved: Compared operationId upsertCredentialMember, POST /api/v2/credentials/{credentialId}/members, security and x-sim-operation with baseline; identifiers, route and credential schemes match. Recursive prose/default/example mappings retained in final-review-api-comparison.json; 9 distinct changed field mappings were inspected for this operation. Operation-level request/response structure, parameters, required fields, defaults and status declarations are identical after removing prose/examples; referenced component changes were reviewed separately. | +| `removeCredentialMember` — `DELETE /api/v2/credentials/{credentialId}/members/{userId}` | rewritten | Reviewed; accurate details retained under the shared reference standard. Review correction: integrations.manage is named explicitly. | Verified improvement. Summary: Remove Credential Member → Remove credential member; sentence case matches the editorial guide. description: Revoke an active explicit credential grant. Requires credential administrator access and the integrations.manage capability. Inherited workspace administrators cannot be removed; … → Revoke an active explicit credential grant. Requires credential Admin access and permission to manage integration connections. Inherited workspace Admins cannot be removed; an abs… responses.200.content.application/json.schema.description: Remove Credential Member result. → Acknowledgement that the explicit credential grant was revoked. responses.200.description: Remove Credential Member result. → Acknowledgement that the explicit credential grant was revoked. Preserved: Compared operationId removeCredentialMember, DELETE /api/v2/credentials/{credentialId}/members/{userId}, security and x-sim-operation with baseline; identifiers, route and credential schemes match. Recursive prose/default/example mappings retained in final-review-api-comparison.json; 5 distinct changed field mappings were inspected for this operation. Operation-level request/response structure, parameters, required fields, defaults and status declarations are identical after removing prose/examples; referenced component changes were reviewed separately. | +| `getWorkspacePermissionConfig` — `GET /api/v2/workspaces/{workspaceId}/permission-config` | rewritten | Registry-generated hideDeployChatbot publishing wording is outside owned contract sources; source registry left untouched. | Verified improvement. Summary: Get Workspace Permission Config → Get workspace permission config; sentence case matches the editorial guide. responses.200.content.application/json.schema.properties.data.properties.config.anyOf[0].properties.hideDeployChatbot.description: Prevent publishing a workflow as a chat. → Prevent deploying a workflow as a chat. responses.503.description: A required service is temporarily unavailable. `Retry-After` carries the seconds to wait; treat it as a floor and add jitter. The header is omitted when `error.details.code` is `A… → A required service is temporarily unavailable. When present, `Retry-After` gives the minimum seconds to wait; add jitter before retrying. Check operation-specific guidance before … 1 request/response media example set(s) now expose the owner's existing examples to the API renderer. Preserved: Compared operationId getWorkspacePermissionConfig, GET /api/v2/workspaces/{workspaceId}/permission-config, security and x-sim-operation with baseline; identifiers, route and credential schemes match. Recursive prose/default/example mappings retained in final-review-api-comparison.json; 4 distinct changed field mappings were inspected for this operation. Operation-level request/response structure, parameters, required fields, defaults and status declarations are identical after removing prose/examples; referenced component changes were reviewed separately. | +| `createWorkspaceInvitations` — `POST /api/v2/workspaces/{workspaceId}/invitations` | rewritten | Copy standardized; no operation-specific discrepancy found. | Verified improvement. Summary: Create Workspace Invitations → Create workspace invitations; sentence case matches the editorial guide. description: Invite people to a workspace or grant access immediately to existing organization members. Requires workspace administrator access and current invitation eligibility; organization… → Invite people to a workspace or grant access immediately to existing organization members. Requires workspace Admin access and current invitation eligibility; invitations offering… responses.503.description: A required service is temporarily unavailable. `Retry-After` carries the seconds to wait; treat it as a floor and add jitter. The header is omitted when `error.details.code` is `A… → A required service is temporarily unavailable. When present, `Retry-After` gives the minimum seconds to wait; add jitter before retrying. Check operation-specific guidance before … 2 request/response media example set(s) now expose the owner's existing examples to the API renderer. Preserved: Compared operationId createWorkspaceInvitations, POST /api/v2/workspaces/{workspaceId}/invitations, security and x-sim-operation with baseline; identifiers, route and credential schemes match. Recursive prose/default/example mappings retained in final-review-api-comparison.json; 5 distinct changed field mappings were inspected for this operation. Operation-level request/response structure, parameters, required fields, defaults and status declarations are identical after removing prose/examples; referenced component changes were reviewed separately. | +| `getOrganizationMemberUsageLimit` — `GET /api/v2/organizations/{organizationId}/members/{userId}/usage-limit` | rewritten | Reviewed; accurate details retained under the shared reference standard. Review correction: query metadata now says No query parameters. | Verified improvement. Summary: Get Organization Member Credit Limit → Get organization member credit limit; sentence case matches the editorial guide. description: Read a person’s credit cap and credits consumed in the organization billing period. Hosted only. The userId identifies an organization member or external collaborator with workspa… → Read a person’s credit cap and credits consumed in the organization billing period. Hosted deployments only. The `userId` identifies an organization member or external collaborato… responses.200.content.application/json.schema.description: Get Organization Member Credit Limit result. → The person’s current credit cap and billing-period consumption. responses.200.description: Get Organization Member Credit Limit result. → The person’s current credit cap and billing-period consumption. 1 request/response media example set(s) now expose the owner's existing examples to the API renderer. Preserved: Compared operationId getOrganizationMemberUsageLimit, GET /api/v2/organizations/{organizationId}/members/{userId}/usage-limit, security and x-sim-operation with baseline; identifiers, route and credential schemes match. Recursive prose/default/example mappings retained in final-review-api-comparison.json; 6 distinct changed field mappings were inspected for this operation. Operation-level request/response structure, parameters, required fields, defaults and status declarations are identical after removing prose/examples; referenced component changes were reviewed separately. | +| `updateOrganizationMemberUsageLimit` — `PATCH /api/v2/organizations/{organizationId}/members/{userId}/usage-limit` | rewritten | Reviewed; accurate details retained under the shared reference standard. Review correction: query metadata now says No query parameters. | Verified improvement. Summary: Update Organization Member Credit Limit → Update organization member credit limit; sentence case matches the editorial guide. description: Set or clear a person’s credit cap. Hosted only. The userId must identify an organization member or external collaborator with workspace access in this organization. The cap is a … → Set or clear a person’s credit cap. Hosted deployments only. The `userId` must identify an organization member or external collaborator with workspace access in this organization.… responses.200.content.application/json.schema.description: Update Organization Member Credit Limit result. → The saved credit cap, or null when the cap was cleared. responses.200.description: Update Organization Member Credit Limit result. → The saved credit cap, or null when the cap was cleared. 2 request/response media example set(s) now expose the owner's existing examples to the API renderer. Preserved: Compared operationId updateOrganizationMemberUsageLimit, PATCH /api/v2/organizations/{organizationId}/members/{userId}/usage-limit, security and x-sim-operation with baseline; identifiers, route and credential schemes match. Recursive prose/default/example mappings retained in final-review-api-comparison.json; 7 distinct changed field mappings were inspected for this operation. Operation-level request/response structure, parameters, required fields, defaults and status declarations are identical after removing prose/examples; referenced component changes were reviewed separately. | +| `getOrganizationUsageSummary` — `GET /api/v2/organizations/{organizationId}/usage/summary` | rewritten | Reviewed; accurate details retained under the shared reference standard. Review correction: query metadata now says Reporting window and optional workspace filter. Review correction: params metadata now says Organization identifier. | Verified improvement. Summary: Get Organization Usage Summary → Get organization usage summary; sentence case matches the editorial guide. description: Read pooled credits, a usage series, and an exact previous-period comparison when available. Requires organization administrator access and Usage Monitoring (Enterprise on hosted;… → Read pooled credits, a usage series, and an exact previous-period comparison when available. Requires organization Admin access and Usage Monitoring: Enterprise when billing is en… responses.200.content.application/json.schema.description: Get Organization Usage Summary result. → Reporting bounds, pooled credits, and chronological usage buckets. responses.200.description: Get Organization Usage Summary result. → Reporting bounds, pooled credits, and chronological usage buckets. 1 request/response media example set(s) now expose the owner's existing examples to the API renderer. Preserved: Compared operationId getOrganizationUsageSummary, GET /api/v2/organizations/{organizationId}/usage/summary, security and x-sim-operation with baseline; identifiers, route and credential schemes match. Recursive prose/default/example mappings retained in final-review-api-comparison.json; 6 distinct changed field mappings were inspected for this operation. Operation-level request/response structure, parameters, required fields, defaults and status declarations are identical after removing prose/examples; referenced component changes were reviewed separately. | +| `getOrganizationUsageBreakdown` — `GET /api/v2/organizations/{organizationId}/usage/breakdown` | rewritten | Reviewed; accurate details retained under the shared reference standard. Review correction: query metadata now says Reporting window, optional workspace filter, grouping dimension, and result limit. Review correction: params metadata now says Organization identifier. | Verified improvement. Summary: Get Organization Usage Breakdown → Get organization usage breakdown; sentence case matches the editorial guide. description: Read ranked organization usage by member, workspace, workflow, model, BYOK provider, or source. Requires organization administrator access and Usage Monitoring. Omitted usage is s… → Read ranked usage by member, workspace, workflow, model, BYOK provider, or source. Requires organization Admin access and Usage Monitoring. `other` summarizes groups omitted by th… responses.200.content.application/json.schema.description: Get Organization Usage Breakdown result. → Ranked usage groups and the combined remainder. responses.200.description: Get Organization Usage Breakdown result. → Ranked usage groups and the combined remainder. 1 request/response media example set(s) now expose the owner's existing examples to the API renderer. Preserved: Compared operationId getOrganizationUsageBreakdown, GET /api/v2/organizations/{organizationId}/usage/breakdown, security and x-sim-operation with baseline; identifiers, route and credential schemes match. Recursive prose/default/example mappings retained in final-review-api-comparison.json; 6 distinct changed field mappings were inspected for this operation. Operation-level request/response structure, parameters, required fields, defaults and status declarations are identical after removing prose/examples; referenced component changes were reviewed separately. | +| `listOrganizationUsageEvents` — `GET /api/v2/organizations/{organizationId}/usage/events` | rewritten | Reviewed; accurate details retained under the shared reference standard. Review correction: query metadata now says Reporting window, source filter, sorting, and pagination. Review correction: params metadata now says Organization identifier. | Verified improvement. Summary: List Organization Usage Events → List organization usage events; sentence case matches the editorial guide. description: Page through usage events, including zero-cost reporting. Requires organization administrator access and Usage Monitoring. Defaults to 30 days. Cursors retain the initial reportin… → List usage events, including zero-cost activity. Requires organization Admin access and Usage Monitoring. Defaults to 30 days. Cursors retain the initial reporting window; keep fi… responses.200.content.application/json.schema.description: List Organization Usage Events result. → A page of usage events, including zero-cost activity. responses.200.content.application/json.schema.properties.nextCursor.description: Opaque cursor for the next page. Send it back as `cursor`; `null` means there is nothing further to fetch. Never construct one yourself. → Opaque cursor for the next page. Send it back as `cursor`; `null` means there are no more pages. Do not construct a cursor yourself. 1 request/response media example set(s) now expose the owner's existing examples to the API renderer. Preserved: Compared operationId listOrganizationUsageEvents, GET /api/v2/organizations/{organizationId}/usage/events, security and x-sim-operation with baseline; identifiers, route and credential schemes match. Recursive prose/default/example mappings retained in final-review-api-comparison.json; 7 distinct changed field mappings were inspected for this operation. Operation-level request/response structure, parameters, required fields, defaults and status declarations are identical after removing prose/examples; referenced component changes were reviewed separately. | +| `discoverWorkspaceAccessRequests` — `GET /api/v2/workspaces/{workspaceId}/access-requests/discovery` | rewritten | Reviewed; accurate details retained under the shared reference standard. Review correction: params metadata now says Workspace identifier. | Verified improvement. Summary: Discover Workspace Access Requests → Discover workspace access requests; sentence case matches the editorial guide. responses.200.content.application/json.schema.description: Discover Workspace Access Requests result. → A page of access targets and the acting user’s current access state. responses.200.content.application/json.schema.properties.nextCursor.description: Opaque cursor for the next page. Send it back as `cursor`; `null` means there is nothing further to fetch. Never construct one yourself. → Opaque cursor for the next page. Send it back as `cursor`; `null` means there are no more pages. Do not construct a cursor yourself. responses.200.description: Discover Workspace Access Requests result. → A page of access targets and the acting user’s current access state. 1 request/response media example set(s) now expose the owner's existing examples to the API renderer. Preserved: Compared operationId discoverWorkspaceAccessRequests, GET /api/v2/workspaces/{workspaceId}/access-requests/discovery, security and x-sim-operation with baseline; identifiers, route and credential schemes match. Recursive prose/default/example mappings retained in final-review-api-comparison.json; 6 distinct changed field mappings were inspected for this operation. Operation-level request/response structure, parameters, required fields, defaults and status declarations are identical after removing prose/examples; referenced component changes were reviewed separately. | +| `listMyWorkspaceAccessRequests` — `GET /api/v2/workspaces/{workspaceId}/access-requests` | rewritten | Reviewed; accurate details retained under the shared reference standard. Review correction: params metadata now says Workspace identifier. | Verified improvement. Summary: List My Workspace Access Requests → List my workspace access requests; sentence case matches the editorial guide. responses.200.content.application/json.schema.description: List My Workspace Access Requests result. → A page of the acting user’s workspace and member-credit requests. responses.200.content.application/json.schema.properties.nextCursor.description: Opaque cursor for the next page. Send it back as `cursor`; `null` means there is nothing further to fetch. Never construct one yourself. → Opaque cursor for the next page. Send it back as `cursor`; `null` means there are no more pages. Do not construct a cursor yourself. responses.200.description: List My Workspace Access Requests result. → A page of the acting user’s workspace and member-credit requests. 1 request/response media example set(s) now expose the owner's existing examples to the API renderer. Preserved: Compared operationId listMyWorkspaceAccessRequests, GET /api/v2/workspaces/{workspaceId}/access-requests, security and x-sim-operation with baseline; identifiers, route and credential schemes match. Recursive prose/default/example mappings retained in final-review-api-comparison.json; 6 distinct changed field mappings were inspected for this operation. Operation-level request/response structure, parameters, required fields, defaults and status declarations are identical after removing prose/examples; referenced component changes were reviewed separately. | +| `createWorkspaceAccessRequest` — `POST /api/v2/workspaces/{workspaceId}/access-requests` | corrected | Pending reuse/closed/group-wide effect correct; missing org/enablement/caps. Review correction: query metadata now says No query parameters. Review correction: params metadata now says Workspace identifier. | Verified improvement. Summary: Create Workspace Access Request → Create workspace access request; sentence case matches the editorial guide. description: Request access for the acting user using a target from discovery. Returns an existing matching pending request when applicable; the result may be closed if access is already avail… → Request access using a target from Discover workspace access requests. Requires access to an organization-owned workspace with requests enabled; external collaborators use their w… requestBody.content.application/json.schema.description: Inputs for this operation. → A discovered access target and an optional reason for the request. requestBody.description: Inputs for this operation. → A discovered access target and an optional reason for the request. 2 request/response media example set(s) now expose the owner's existing examples to the API renderer. Preserved: Compared operationId createWorkspaceAccessRequest, POST /api/v2/workspaces/{workspaceId}/access-requests, security and x-sim-operation with baseline; identifiers, route and credential schemes match. Recursive prose/default/example mappings retained in final-review-api-comparison.json; 9 distinct changed field mappings were inspected for this operation. Operation-level request/response structure, parameters, required fields, defaults and status declarations are identical after removing prose/examples; referenced component changes were reviewed separately. | +| `cancelWorkspaceAccessRequest` — `POST /api/v2/workspaces/{workspaceId}/access-requests/{requestId}/cancel` | rewritten | Reviewed; accurate details retained under the shared reference standard. Review correction: query metadata now says No query parameters. | Verified improvement. Summary: Cancel Workspace Access Request → Cancel workspace access request; sentence case matches the editorial guide. responses.200.content.application/json.schema.description: Cancel Workspace Access Request result. → The cancelled request, or the unchanged request if already resolved. responses.200.description: Cancel Workspace Access Request result. → The cancelled request, or the unchanged request if already resolved. responses.503.description: A required service is temporarily unavailable. `Retry-After` carries the seconds to wait; treat it as a floor and add jitter. The header is omitted when `error.details.code` is `A… → A required service is temporarily unavailable. When present, `Retry-After` gives the minimum seconds to wait; add jitter before retrying. Check operation-specific guidance before … 1 request/response media example set(s) now expose the owner's existing examples to the API renderer. Preserved: Compared operationId cancelWorkspaceAccessRequest, POST /api/v2/workspaces/{workspaceId}/access-requests/{requestId}/cancel, security and x-sim-operation with baseline; identifiers, route and credential schemes match. Recursive prose/default/example mappings retained in final-review-api-comparison.json; 5 distinct changed field mappings were inspected for this operation. Operation-level request/response structure, parameters, required fields, defaults and status declarations are identical after removing prose/examples; referenced component changes were reviewed separately. | +| `discoverOrganizationAccessRequests` — `GET /api/v2/organizations/{organizationId}/access-requests/discovery` | rewritten | Reviewed; accurate details retained under the shared reference standard. Review correction: params metadata now says Organization identifier. | Verified improvement. Summary: Discover Organization Access Requests → Discover organization access requests; sentence case matches the editorial guide. responses.200.content.application/json.schema.description: Discover Organization Access Requests result. → A page of access targets and the acting user’s current access state. responses.200.content.application/json.schema.properties.nextCursor.description: Opaque cursor for the next page. Send it back as `cursor`; `null` means there is nothing further to fetch. Never construct one yourself. → Opaque cursor for the next page. Send it back as `cursor`; `null` means there are no more pages. Do not construct a cursor yourself. responses.200.description: Discover Organization Access Requests result. → A page of access targets and the acting user’s current access state. 1 request/response media example set(s) now expose the owner's existing examples to the API renderer. Preserved: Compared operationId discoverOrganizationAccessRequests, GET /api/v2/organizations/{organizationId}/access-requests/discovery, security and x-sim-operation with baseline; identifiers, route and credential schemes match. Recursive prose/default/example mappings retained in final-review-api-comparison.json; 6 distinct changed field mappings were inspected for this operation. Operation-level request/response structure, parameters, required fields, defaults and status declarations are identical after removing prose/examples; referenced component changes were reviewed separately. | +| `listMyOrganizationAccessRequests` — `GET /api/v2/organizations/{organizationId}/access-requests/mine` | rewritten | Reviewed; accurate details retained under the shared reference standard. Review correction: params metadata now says Organization identifier. | Verified improvement. Summary: List My Organization Access Requests → List my organization access requests; sentence case matches the editorial guide. responses.200.content.application/json.schema.description: List My Organization Access Requests result. → A page of the acting user’s organization and member-credit requests. responses.200.content.application/json.schema.properties.nextCursor.description: Opaque cursor for the next page. Send it back as `cursor`; `null` means there is nothing further to fetch. Never construct one yourself. → Opaque cursor for the next page. Send it back as `cursor`; `null` means there are no more pages. Do not construct a cursor yourself. responses.200.description: List My Organization Access Requests result. → A page of the acting user’s organization and member-credit requests. 1 request/response media example set(s) now expose the owner's existing examples to the API renderer. Preserved: Compared operationId listMyOrganizationAccessRequests, GET /api/v2/organizations/{organizationId}/access-requests/mine, security and x-sim-operation with baseline; identifiers, route and credential schemes match. Recursive prose/default/example mappings retained in final-review-api-comparison.json; 7 distinct changed field mappings were inspected for this operation. Operation-level request/response structure, parameters, required fields, defaults and status declarations are identical after removing prose/examples; referenced component changes were reviewed separately. | +| `createOrganizationAccessRequest` — `POST /api/v2/organizations/{organizationId}/access-requests` | corrected | Pending reuse/group effect correct; missing enablement/submission caps. Review correction: query metadata now says No query parameters. Review correction: params metadata now says Organization identifier. | Verified improvement. Summary: Create Organization Access Request → Create organization access request; sentence case matches the editorial guide. description: Request access for the acting user using a target from discovery. Returns an existing matching pending request when applicable; the result may be closed if access is already avail… → Request access using a target from Discover organization access requests. Requires organization membership and requests enabled. Each requester can have 100 pending requests and s… requestBody.content.application/json.schema.description: Inputs for this operation. → A discovered access target and an optional reason for the request. requestBody.description: Inputs for this operation. → A discovered access target and an optional reason for the request. 2 request/response media example set(s) now expose the owner's existing examples to the API renderer. Preserved: Compared operationId createOrganizationAccessRequest, POST /api/v2/organizations/{organizationId}/access-requests, security and x-sim-operation with baseline; identifiers, route and credential schemes match. Recursive prose/default/example mappings retained in final-review-api-comparison.json; 9 distinct changed field mappings were inspected for this operation. Operation-level request/response structure, parameters, required fields, defaults and status declarations are identical after removing prose/examples; referenced component changes were reviewed separately. | +| `listOrganizationAccessRequests` — `GET /api/v2/organizations/{organizationId}/access-requests` | rewritten | Reviewed; accurate details retained under the shared reference standard. Review correction: params metadata now says Organization identifier. | Verified improvement. Summary: List Organization Access Requests → List organization access requests; sentence case matches the editorial guide. description: List requests across the organization for administrator review. Includes requests from organization members and external workspace collaborators; history remains available while r… → List requests across the organization for administrator review. Includes requests from organization members and external workspace collaborators; history remains available while r… responses.200.content.application/json.schema.description: List Organization Access Requests result. → A page of requests across the organization for Admin review. responses.200.content.application/json.schema.properties.nextCursor.description: Opaque cursor for the next page. Send it back as `cursor`; `null` means there is nothing further to fetch. Never construct one yourself. → Opaque cursor for the next page. Send it back as `cursor`; `null` means there are no more pages. Do not construct a cursor yourself. 1 request/response media example set(s) now expose the owner's existing examples to the API renderer. Preserved: Compared operationId listOrganizationAccessRequests, GET /api/v2/organizations/{organizationId}/access-requests, security and x-sim-operation with baseline; identifiers, route and credential schemes match. Recursive prose/default/example mappings retained in final-review-api-comparison.json; 7 distinct changed field mappings were inspected for this operation. Operation-level request/response structure, parameters, required fields, defaults and status declarations are identical after removing prose/examples; referenced component changes were reviewed separately. | +| `cancelOrganizationAccessRequest` — `POST /api/v2/organizations/{organizationId}/access-requests/{requestId}/cancel` | rewritten | Reviewed; accurate details retained under the shared reference standard. Review correction: query metadata now says No query parameters. | Verified improvement. Summary: Cancel Organization Access Request → Cancel organization access request; sentence case matches the editorial guide. responses.200.content.application/json.schema.description: Cancel Organization Access Request result. → The cancelled request, or the unchanged request if already resolved. responses.200.description: Cancel Organization Access Request result. → The cancelled request, or the unchanged request if already resolved. responses.503.description: A required service is temporarily unavailable. `Retry-After` carries the seconds to wait; treat it as a floor and add jitter. The header is omitted when `error.details.code` is `A… → A required service is temporarily unavailable. When present, `Retry-After` gives the minimum seconds to wait; add jitter before retrying. Check operation-specific guidance before … 1 request/response media example set(s) now expose the owner's existing examples to the API renderer. Preserved: Compared operationId cancelOrganizationAccessRequest, POST /api/v2/organizations/{organizationId}/access-requests/{requestId}/cancel, security and x-sim-operation with baseline; identifiers, route and credential schemes match. Recursive prose/default/example mappings retained in final-review-api-comparison.json; 5 distinct changed field mappings were inspected for this operation. Operation-level request/response structure, parameters, required fields, defaults and status declarations are identical after removing prose/examples; referenced component changes were reviewed separately. | +| `previewOrganizationAccessRequest` — `GET /api/v2/organizations/{organizationId}/access-requests/{requestId}/preview` | rewritten | Reviewed; accurate details retained under the shared reference standard. Review correction: query metadata now says No query parameters. | Verified improvement. Summary: Preview Organization Access Request → Preview organization access request; sentence case matches the editorial guide. description: Preview the current permission changes, affected group and audience, or member credit cap. Review canApply, changes, impact, and fingerprint before resolving. Permission changes a… → Preview the current permission changes, affected group and audience, or member credit cap. Review `canApply`, `changes`, `impact`, and `fingerprint` before resolving. Permission c… responses.200.content.application/json.schema.description: Preview Organization Access Request result. → The proposed group or credit-cap change, affected audience, and fingerprint. responses.200.description: Preview Organization Access Request result. → The proposed group or credit-cap change, affected audience, and fingerprint. 1 request/response media example set(s) now expose the owner's existing examples to the API renderer. Preserved: Compared operationId previewOrganizationAccessRequest, GET /api/v2/organizations/{organizationId}/access-requests/{requestId}/preview, security and x-sim-operation with baseline; identifiers, route and credential schemes match. Recursive prose/default/example mappings retained in final-review-api-comparison.json; 6 distinct changed field mappings were inspected for this operation. Operation-level request/response structure, parameters, required fields, defaults and status declarations are identical after removing prose/examples; referenced component changes were reviewed separately. | +| `resolveOrganizationAccessRequest` — `POST /api/v2/organizations/{organizationId}/access-requests/{requestId}/resolve` | rewritten | Reviewed; accurate details retained under the shared reference standard. Review correction: query metadata now says No query parameters. | Verified improvement. Summary: Resolve Organization Access Request → Resolve organization access request; sentence case matches the editorial guide. description: Apply a reviewed request or decline it with a reason. Applying requires the preview fingerprint; changed policy or membership returns a conflict. Credit requests also require a hi… → Apply a reviewed request or decline it with a reason. Applying requires the preview fingerprint; changed policy or membership returns a conflict. Credit requests also require a hi… requestBody.content.application/json.schema.description: Inputs for this operation. → Apply the reviewed fingerprint, with a higher credit cap when applicable, or decline with a reason. requestBody.description: Inputs for this operation. → Apply the reviewed fingerprint, with a higher credit cap when applicable, or decline with a reason. 2 request/response media example set(s) now expose the owner's existing examples to the API renderer. Preserved: Compared operationId resolveOrganizationAccessRequest, POST /api/v2/organizations/{organizationId}/access-requests/{requestId}/resolve, security and x-sim-operation with baseline; identifiers, route and credential schemes match. Recursive prose/default/example mappings retained in final-review-api-comparison.json; 9 distinct changed field mappings were inspected for this operation. Operation-level request/response structure, parameters, required fields, defaults and status declarations are identical after removing prose/examples; referenced component changes were reviewed separately. | +| `getOrganizationAccessRequestSettings` — `GET /api/v2/organizations/{organizationId}/access-requests/settings` | rewritten | Reviewed; accurate details retained under the shared reference standard. Review correction: query metadata now says No query parameters. Review correction: params metadata now says Organization identifier. | Verified improvement. Summary: Get Organization Access Request Settings → Get organization access request settings; sentence case matches the editorial guide. description: Get whether the organization allows new access requests and approvals. This preference does not enable features unavailable in the deployment or subscription. Requires organizatio… → Get whether the organization allows new access requests and approvals. This preference does not enable features unavailable in the deployment or subscription. Requires organizatio… responses.200.content.application/json.schema.description: Get Organization Access Request Settings result. → Whether new requests and approvals are allowed. responses.200.description: Get Organization Access Request Settings result. → Whether new requests and approvals are allowed. 1 request/response media example set(s) now expose the owner's existing examples to the API renderer. Preserved: Compared operationId getOrganizationAccessRequestSettings, GET /api/v2/organizations/{organizationId}/access-requests/settings, security and x-sim-operation with baseline; identifiers, route and credential schemes match. Recursive prose/default/example mappings retained in final-review-api-comparison.json; 6 distinct changed field mappings were inspected for this operation. Operation-level request/response structure, parameters, required fields, defaults and status declarations are identical after removing prose/examples; referenced component changes were reviewed separately. | +| `updateOrganizationAccessRequestSettings` — `PATCH /api/v2/organizations/{organizationId}/access-requests/settings` | rewritten | Reviewed; accurate details retained under the shared reference standard. Review correction: query metadata now says No query parameters. Review correction: params metadata now says Organization identifier. | Verified improvement. Summary: Update Organization Access Request Settings → Update organization access request settings; sentence case matches the editorial guide. description: Allow or pause new access requests and approvals. Pausing preserves history, cancellation, and decline, and does not revoke previously granted access. Requires organization admini… → Allow or pause new access requests and approvals. Pausing preserves history, cancellation, and decline, and does not revoke previously granted access. Requires organization Admin … requestBody.content.application/json.schema.description: Inputs for this operation. → Whether new requests and approvals are allowed. requestBody.description: Inputs for this operation. → Whether new requests and approvals are allowed. 2 request/response media example set(s) now expose the owner's existing examples to the API renderer. Preserved: Compared operationId updateOrganizationAccessRequestSettings, PATCH /api/v2/organizations/{organizationId}/access-requests/settings, security and x-sim-operation with baseline; identifiers, route and credential schemes match. Recursive prose/default/example mappings retained in final-review-api-comparison.json; 9 distinct changed field mappings were inspected for this operation. Operation-level request/response structure, parameters, required fields, defaults and status declarations are identical after removing prose/examples; referenced component changes were reviewed separately. | + +### CLI reference (28) + +| Page or operation | Result | Changes | Final comparison and preservation | +| --- | --- | --- | --- | +| [cli/audit-logs.mdx](content/docs/cli/audit-logs.mdx) | generated | Corrected organization selection wording and inherited audit-action date bounds Added organization Admin/owner and enterprise eligibility before commands Put list before get and linked authentication/permission guidance | Verified improvement. Page purpose: Manage audit logs — every subcommand, argument, and flag → Read organization audit actions and filter by actor, resource, workspace, or time.. Commands are grouped in resource/lifecycle order, retain generated options and examples, and link applicable canonical API requests/responses. Onward references and compatible heading anchors support direct lookup without changing invocation syntax. Preserved: Compared 2 baseline and 2 current command invocations; no command, argument, option syntax, alias, or required flag was removed. Command confirmations and field descriptions were read alongside current source; conditional labels match existing schema/confirmation requirements. | +| [cli/billing.mdx](content/docs/cli/billing.mdx) | generated | Replaced Copilot prose with Sim agent/Chat while preserving source enums Kept credential-dependent usage visibility and linked Costs Surfaced server defaults and API schemas | Verified improvement. Page purpose: Manage billing — every subcommand, argument, and flag → Read billing status, credit usage, and storage usage.. Commands are grouped in resource/lifecycle order, retain generated options and examples, and link applicable canonical API requests/responses. Onward references and compatible heading anchors support direct lookup without changing invocation syntax. Fresh residual source-copy findings corrected by parent and present in current generated page: FR-CLI-02. Preserved: Compared 2 baseline and 2 current command invocations; no command, argument, option syntax, alias, or required flag was removed. Command confirmations and field descriptions were read alongside current source; conditional labels match existing schema/confirmation requirements. | +| [cli/blocks.mdx](content/docs/cli/blocks.mdx) | generated | Replaced Manage metadata with workspace catalog purpose Put list before get and kept visibility/version/sunset constraints Surfaced sort defaults and API schemas | Verified improvement. Page purpose: Manage blocks — every subcommand, argument, and flag → Inspect workflow blocks, integration blocks, and triggers available to the workspace.. Commands are grouped in resource/lifecycle order, retain generated options and examples, and link applicable canonical API requests/responses. Preserved: Compared 2 baseline and 2 current command invocations; no command, argument, option syntax, alias, or required flag was removed. Command confirmations and field descriptions were read alongside current source; conditional labels match existing schema/confirmation requirements. | +| [cli/chat-deployments.mdx](content/docs/cli/chat-deployments.mdx) | generated | Clarified read-only collection purpose Linked creation/update to workflow chat section Surfaced sort defaults and API schemas | Verified improvement. Page purpose: Manage chat deployments — every subcommand, argument, and flag → List workflow chat deployments in the workspace.. Commands are grouped in resource/lifecycle order, retain generated options and examples, and link applicable canonical API requests/responses. Onward references and compatible heading anchors support direct lookup without changing invocation syntax. Preserved: Compared 1 baseline and 1 current command invocations; no command, argument, option syntax, alias, or required flag was removed. Command confirmations and field descriptions were read alongside current source; conditional labels match existing schema/confirmation requirements. | +| [cli/cli.mdx](content/docs/cli/cli.mdx) | generated | Renamed page to Command search without changing route Included local query privacy, five-result cap, and terminal-help examples Preserved original command heading anchor | Verified improvement. Page purpose: Discover commands in this CLI — every subcommand, argument, and flag → Find a command by describing the task you want to perform.. Commands are grouped in resource/lifecycle order, retain generated options and examples, and link applicable canonical API requests/responses. Onward references and compatible heading anchors support direct lookup without changing invocation syntax. Preserved: Compared 1 baseline and 1 current command invocations; no command, argument, option syntax, alias, or required flag was removed. Command confirmations and field descriptions were read alongside current source; conditional labels match existing schema/confirmation requirements. | +| [cli/commands.mdx](content/docs/cli/commands.mdx) | generated | Replaced universal resource-syntax claim with resource-specific syntax Clarified global-option applicability, telemetry text, export format, help/version Rewrote group summaries and added Chat stream/output/conversation examples Preserved global-options anchor and all root commands | Verified improvement. Page purpose: Global options, and every sim command group → Find command groups, global options, and login, configuration, and Chat commands.. Commands are grouped in resource/lifecycle order, retain generated options and examples, and link applicable canonical API requests/responses. Onward references and compatible heading anchors support direct lookup without changing invocation syntax. Fresh residual source-copy findings corrected by parent and present in current generated page: FR-CLI-01. Preserved: Compared 7 baseline and 7 current command invocations; no command, argument, option syntax, alias, or required flag was removed. Command confirmations and field descriptions were read alongside current source; conditional labels match existing schema/confirmation requirements. | +| [cli/connector-types.mdx](content/docs/cli/connector-types.mdx) | generated | Explained connector/auth/source-schema discovery Linked full-detail inspection to connector creation Kept complete projection, cursor and default detail behavior | Verified improvement. Page purpose: Manage connector types — every subcommand, argument, and flag → Discover knowledge connectors and their authentication and source-configuration schemas.. Commands are grouped in resource/lifecycle order, retain generated options and examples, and link applicable canonical API requests/responses. Onward references and compatible heading anchors support direct lookup without changing invocation syntax. Preserved: Compared 1 baseline and 1 current command invocations; no command, argument, option syntax, alias, or required flag was removed. Command confirmations and field descriptions were read alongside current source; conditional labels match existing schema/confirmation requirements. | +| [cli/credentials.mdx](content/docs/cli/credentials.mdx) | generated | Grouped discovery/connections, member grants, and disconnect lifecycle Added provider schema discovery and human OAuth-link authorization Kept all provider fields, required IDs, write-only/null limitations, and grants Linked each published operation to its API request and response schemas | Verified improvement. Page purpose: Manage credentials — every subcommand, argument, and flag → Discover providers, connect accounts, and manage credential access.. Commands are grouped in resource/lifecycle order, retain generated options and examples, and link applicable canonical API requests/responses. Onward references and compatible heading anchors support direct lookup without changing invocation syntax. Preserved: Compared 10 baseline and 10 current command invocations; no command, argument, option syntax, alias, or required flag was removed. Command confirmations and field descriptions were read alongside current source; conditional labels match existing schema/confirmation requirements. | +| [cli/custom-tools.mdx](content/docs/cli/custom-tools.mdx) | generated | Added concrete code-backed tool purpose and CRUD lifecycle order Preserved complete function-schema examples and sandbox fact Linked canonical request/response schemas | Verified improvement. Page purpose: Manage custom tools — every subcommand, argument, and flag → Create and manage code-backed tools that agents can call.. Commands are grouped in resource/lifecycle order, retain generated options and examples, and link applicable canonical API requests/responses. Onward references and compatible heading anchors support direct lookup without changing invocation syntax. Preserved: Compared 5 baseline and 5 current command invocations; no command, argument, option syntax, alias, or required flag was removed. Command confirmations and field descriptions were read alongside current source; conditional labels match existing schema/confirmation requirements. | +| [cli/files.mdx](content/docs/cli/files.mdx) | generated | Grouped browsing, content, editing, sharing, versions, archive/restore, and folders Fixed VFS/secret-reference inline code rendering and preserved revision/version guards Changed oversized-content guidance to sim files upload Surfaced archive/version/delete consequences and whole-sharing configuration rules Review correction: inline content help preserves the separate request and decoded-file limits. | Verified improvement. Page purpose: Manage files — every subcommand, argument, and flag → Browse workspace files, read or write content, manage versions, and configure sharing.. Commands are grouped in resource/lifecycle order, retain generated options and examples, and link applicable canonical API requests/responses. Onward references and compatible heading anchors support direct lookup without changing invocation syntax. Fresh residual source-copy findings corrected by parent and present in current generated page: FR-CLI-03. Preserved: Compared 30 baseline and 30 current command invocations; no command, argument, option syntax, alias, or required flag was removed. Command confirmations and field descriptions were read alongside current source; conditional labels match existing schema/confirmation requirements. | +| [cli/knowledge.mdx](content/docs/cli/knowledge.mdx) | generated | Grouped knowledge bases before search/export, documents, chunks, tags, connectors and folders Fixed tag-filter/secret-reference code rendering Kept typed slots, reranking billing/fallback, search modes, sync states and upload tags Linked JSON flags to canonical API schemas | Verified improvement. Page purpose: Manage knowledge — every subcommand, argument, and flag → Manage knowledge bases, indexed documents, search, tags, and connector syncs.. Commands are grouped in resource/lifecycle order, retain generated options and examples, and link applicable canonical API requests/responses. Onward references and compatible heading anchors support direct lookup without changing invocation syntax. Fresh residual source-copy findings corrected by parent and present in current generated page: FR-CLI-07. Preserved: Compared 44 baseline and 44 current command invocations; no command, argument, option syntax, alias, or required flag was removed. Command confirmations and field descriptions were read alongside current source; conditional labels match existing schema/confirmation requirements. | +| [cli/logs.mdx](content/docs/cli/logs.mdx) | generated | Added run-diagnostics purpose and browse-before-detail order Included follow JSONL/YAML streaming, stderr, first-seen status and examples Preserved filter limits, severity/status distinctions, job restrictions and bucket behavior | Verified improvement. Page purpose: Manage logs — every subcommand, argument, and flag → Read run diagnostics, follow new runs, and summarize failures and latency.. Commands are grouped in resource/lifecycle order, retain generated options and examples, and link applicable canonical API requests/responses. Onward references and compatible heading anchors support direct lookup without changing invocation syntax. Preserved: Compared 4 baseline and 4 current command invocations; no command, argument, option syntax, alias, or required flag was removed. Command confirmations and field descriptions were read alongside current source; conditional labels match existing schema/confirmation requirements. | +| [cli/mcp-servers.mdx](content/docs/cli/mcp-servers.mdx) | generated | Defined external MCP connection direction and linked reverse workflow-serving surface Fixed secret-reference inline code and sentence-case acronym title Grouped connections, tool discovery, and removal Kept immutable URL, auth autodetection, header replacement, refresh and OAuth invalidation | Verified improvement. Page purpose: Manage mcp servers — every subcommand, argument, and flag → Connect external Model Context Protocol (MCP) servers so workflows can use their tools.. Commands are grouped in resource/lifecycle order, retain generated options and examples, and link applicable canonical API requests/responses. Onward references and compatible heading anchors support direct lookup without changing invocation syntax. Preserved: Compared 6 baseline and 6 current command invocations; no command, argument, option syntax, alias, or required flag was removed. Command confirmations and field descriptions were read alongside current source; conditional labels match existing schema/confirmation requirements. | +| [cli/meta.mdx](content/docs/cli/meta.mdx) | generated | Renamed title to API capabilities with concrete metadata purpose Removed unused CommandTable import Kept sim meta status unchanged and linked authentication | Verified improvement. Page purpose: Manage meta — every subcommand, argument, and flag → Inspect API availability and the calling credential’s type and expiry.. Commands are grouped in resource/lifecycle order, retain generated options and examples, and link applicable canonical API requests/responses. Onward references and compatible heading anchors support direct lookup without changing invocation syntax. Fresh residual source-copy findings corrected by parent and present in current generated page: FR-CLI-01. Preserved: Compared 1 baseline and 1 current command invocations; no command, argument, option syntax, alias, or required flag was removed. Command confirmations and field descriptions were read alongside current source; conditional labels match existing schema/confirmation requirements. | +| [cli/organizations.mdx](content/docs/cli/organizations.mdx) | generated | Grouped organization reads, membership/caps, invitations, usage, access requests, domains and SSO Surfaced conditional required fields and OIDC/SAML requirements Kept previews/fingerprints, window bounds, credit units, verified domains and session caveats Added canonical API schema links instead of a second config schema | Verified improvement. Page purpose: Manage organizations — every subcommand, argument, and flag → Manage organization membership, invitations, usage, access requests, and SSO.. Commands are grouped in resource/lifecycle order, retain generated options and examples, and link applicable canonical API requests/responses. Onward references and compatible heading anchors support direct lookup without changing invocation syntax. Preserved: Compared 37 baseline and 37 current command invocations; no command, argument, option syntax, alias, or required flag was removed. Command confirmations and field descriptions were read alongside current source; conditional labels match existing schema/confirmation requirements. No→Conditional labels clarify existing conditional requirements; command usage and option syntax remain identical. | +| [cli/permission-groups.mdx](content/docs/cli/permission-groups.mdx) | generated | Grouped configuration before member assignments and deletion Explained replacement arrays and supported config-schema lookup Kept default/non-default group, inactive workspace lists, and conditional requirements | Verified improvement. Page purpose: Manage permission groups — every subcommand, argument, and flag → Manage organization permission groups, their configuration, and member assignments.. Commands are grouped in resource/lifecycle order, retain generated options and examples, and link applicable canonical API requests/responses. Onward references and compatible heading anchors support direct lookup without changing invocation syntax. Preserved: Compared 9 baseline and 9 current command invocations; no command, argument, option syntax, alias, or required flag was removed. Command confirmations and field descriptions were read alongside current source; conditional labels match existing schema/confirmation requirements. No→Conditional labels clarify existing conditional requirements; command usage and option syntax remain identical. | +| [cli/profiles.mdx](content/docs/cli/profiles.mdx) | generated | Explained shared stored login and noninteractive workspace requirement Kept both profiles/profile spellings and command syntax Linked configuration/authentication | Verified improvement. Page purpose: List profiles or add a workspace profile that shares a stored login — every subcommand, argument, and flag → List profiles and add a workspace profile that shares a stored login.. Commands are grouped in resource/lifecycle order, retain generated options and examples, and link applicable canonical API requests/responses. Onward references and compatible heading anchors support direct lookup without changing invocation syntax. Preserved: Compared 2 baseline and 2 current command invocations; no command, argument, option syntax, alias, or required flag was removed. Command confirmations and field descriptions were read alongside current source; conditional labels match existing schema/confirmation requirements. | +| [cli/reference.mdx](content/docs/cli/reference.mdx) | generated | Retained all 318 exact command headings, signatures, flags, arguments and aliases Included group purpose/access notes, confirmation consequences and command help Fixed inline code and preserved pipe/backslash round trips Added defaults, API schema links and self-contained output/help/version rules Kept the complete single-fetch machine reference rather than replacing it with guides Rebase delta: scoped raw .mdx availability to authored guides and CLI pages; generated API operations expose OpenAPI JSON. Review correction: inline content help preserves the separate request and decoded-file limits. | Verified improvement. Page purpose: Every sim command, argument, and flag on a single page → Every sim command, argument, and flag on a single page. Commands are grouped in resource/lifecycle order, retain generated options and examples, and link applicable canonical API requests/responses. Fresh residual source-copy findings corrected by parent and present in current generated page: FR-CLI-01, FR-CLI-02, FR-CLI-03, FR-CLI-04, FR-CLI-05, FR-CLI-06, FR-CLI-07, FR-CLI-08, FR-CLI-09. Preserved: Compared 318 baseline and 318 current command invocations; no command, argument, option syntax, alias, or required flag was removed. Command confirmations and field descriptions were read alongside current source; conditional labels match existing schema/confirmation requirements. No→Conditional labels clarify existing conditional requirements; command usage and option syntax remain identical. | +| [cli/sandboxes.mdx](content/docs/cli/sandboxes.mdx) | generated | Added Function-dependency purpose and CRUD lifecycle order Surfaced deletion consequence and schema links Kept manifest parsing, language revalidation, list replacement, package/CLI bounds | Verified improvement. Page purpose: Manage sandboxes — every subcommand, argument, and flag → Manage reusable dependency sets for Function blocks.. Commands are grouped in resource/lifecycle order, retain generated options and examples, and link applicable canonical API requests/responses. Onward references and compatible heading anchors support direct lookup without changing invocation syntax. Preserved: Compared 5 baseline and 5 current command invocations; no command, argument, option syntax, alias, or required flag was removed. Command confirmations and field descriptions were read alongside current source; conditional labels match existing schema/confirmation requirements. | +| [cli/secrets.mdx](content/docs/cli/secrets.mdx) | generated | Explained personal/workspace ownership and actual visible-value list behavior Included private terminal input versus metadata-only workspace edits and unattended value input Kept redaction/plaintext consequences and exact file/stdin/newline semantics | Verified improvement. Page purpose: Manage secrets — every subcommand, argument, and flag → Set and manage workspace or personal secrets.. Commands are grouped in resource/lifecycle order, retain generated options and examples, and link applicable canonical API requests/responses. Onward references and compatible heading anchors support direct lookup without changing invocation syntax. Preserved: Compared 3 baseline and 3 current command invocations; no command, argument, option syntax, alias, or required flag was removed. Command confirmations and field descriptions were read alongside current source; conditional labels match existing schema/confirmation requirements. | +| [cli/selectors.mdx](content/docs/cli/selectors.mdx) | generated | Defined option-source purpose and declared-dependency OAuth boundary Put list before get and linked published schema lookup Retained the exhaustive selector-key enum in both command entries for complete lookup | Verified improvement. Page purpose: Manage selectors — every subcommand, argument, and flag → Discover destination options for registered fields, such as calendars, channels, and tables.. Commands are grouped in resource/lifecycle order, retain generated options and examples, and link applicable canonical API requests/responses. Preserved: Compared 2 baseline and 2 current command invocations; no command, argument, option syntax, alias, or required flag was removed. Command confirmations and field descriptions were read alongside current source; conditional labels match existing schema/confirmation requirements. | +| [cli/skills.mdx](content/docs/cli/skills.mdx) | generated | Grouped instruction resources, editor grants, and deletion Kept built-in identifiers, reserved/kebab names, current-member constraints and literal content flags Linked agent skill guide and operation schemas | Verified improvement. Page purpose: Manage skills — every subcommand, argument, and flag → Create reusable agent instructions and manage their editors.. Commands are grouped in resource/lifecycle order, retain generated options and examples, and link applicable canonical API requests/responses. Onward references and compatible heading anchors support direct lookup without changing invocation syntax. Preserved: Compared 8 baseline and 8 current command invocations; no command, argument, option syntax, alias, or required flag was removed. Command confirmations and field descriptions were read alongside current source; conditional labels match existing schema/confirmation requirements. | +| [cli/tables.mdx](content/docs/cli/tables.mdx) | generated | Grouped tables before rows/query, columns, views, producers/runs, imports/exports and folders Surfaced dispatch-versus-import cancellation and destructive replace timing Fixed local/workspace source exclusivity and workspace-file name requirement Preserved all filter/schema/producer/upsert examples, row caps and run-state limits Linked canonical request and response schemas | Verified improvement. Page purpose: Manage tables — every subcommand, argument, and flag → Manage tables, rows, schemas, views, enrichment runs, imports, and exports.. Commands are grouped in resource/lifecycle order, retain generated options and examples, and link applicable canonical API requests/responses. Onward references and compatible heading anchors support direct lookup without changing invocation syntax. Fresh residual source-copy findings corrected by parent and present in current generated page: FR-CLI-04, FR-CLI-08. Preserved: Compared 54 baseline and 54 current command invocations; no command, argument, option syntax, alias, or required flag was removed. Command confirmations and field descriptions were read alongside current source; conditional labels match existing schema/confirmation requirements. No→Conditional labels clarify existing conditional requirements; command usage and option syntax remain identical. | +| [cli/telemetry.mdx](content/docs/cli/telemetry.mdx) | generated | Qualified enable as a saved preference subject to environment/build gates Documented fixed text output and linked usage-data details Preserved previous status/enable anchors and removed unused table import | Verified improvement. Page purpose: Control anonymous usage reporting — every subcommand, argument, and flag → Inspect and change this machine’s anonymous usage-reporting preference.. Commands are grouped in resource/lifecycle order, retain generated options and examples, and link applicable canonical API requests/responses. Onward references and compatible heading anchors support direct lookup without changing invocation syntax. Preserved: Compared 3 baseline and 3 current command invocations; no command, argument, option syntax, alias, or required flag was removed. Command confirmations and field descriptions were read alongside current source; conditional labels match existing schema/confirmation requirements. | +| [cli/tools.mdx](content/docs/cli/tools.mdx) | generated | Added parameter-inspection purpose and list/get/execute order Fixed literal toolId inline code rendering Kept OAuth credential requirements, hosted-key filters and full result schema lookup | Verified improvement. Page purpose: Manage tools — every subcommand, argument, and flag → Find built-in tools, inspect their parameters, and run them.. Commands are grouped in resource/lifecycle order, retain generated options and examples, and link applicable canonical API requests/responses. Preserved: Compared 3 baseline and 3 current command invocations; no command, argument, option syntax, alias, or required flag was removed. Command confirmations and field descriptions were read alongside current source; conditional labels match existing schema/confirmation requirements. | +| [cli/workflow-mcp-servers.mdx](content/docs/cli/workflow-mcp-servers.mdx) | generated | Defined serving Sim workflows versus connecting external tools Grouped server lifecycle, workflow tools, and deletion Kept public defaults, URL exposure, deployed workflow requirement and name normalization Preserved publish/unpublish heading anchors while inheriting deployment terminology | Verified improvement. Page purpose: Manage workflow mcp servers — every subcommand, argument, and flag → Serve deployed workflows as tools for Model Context Protocol (MCP) clients.. Commands are grouped in resource/lifecycle order, retain generated options and examples, and link applicable canonical API requests/responses. Onward references and compatible heading anchors support direct lookup without changing invocation syntax. Preserved: Compared 8 baseline and 8 current command invocations; no command, argument, option syntax, alias, or required flag was removed. Command confirmations and field descriptions were read alongside current source; conditional labels match existing schema/confirmation requirements. | +| [cli/workflows.mdx](content/docs/cli/workflows.mdx) | generated | Grouped resource lifecycle, drafts, deployments/versions, runs, Chat, import/export and folders Surfaced complete chat replacement and default-public access before invocation Corrected human-pause wait behavior and explicit exit codes Included export literal-secret inspection and successful paused-cancel recovery limits Preserved operations, selected output, manual/deployed state, one-shot run IDs, stream and file caps Kept changed wait/chat anchors and all exact command spellings | Verified improvement. Page purpose: Manage workflows — every subcommand, argument, and flag → Build, deploy, run, and inspect workflows from the terminal.. Commands are grouped in resource/lifecycle order, retain generated options and examples, and link applicable canonical API requests/responses. Onward references and compatible heading anchors support direct lookup without changing invocation syntax. Fresh residual source-copy findings corrected by parent and present in current generated page: FR-CLI-05, FR-CLI-06, FR-CLI-09. Preserved: Compared 42 baseline and 42 current command invocations; no command, argument, option syntax, alias, or required flag was removed. Command confirmations and field descriptions were read alongside current source; conditional labels match existing schema/confirmation requirements. No→Conditional labels clarify existing conditional requirements; command usage and option syntax remain identical. | +| [cli/workspaces.mdx](content/docs/cli/workspaces.mdx) | generated | Grouped access, requests, fork review/lineage, mappings, push/pull previews, operation status and recovery Shortened wait heading while preserving original anchor and exit/reconciliation facts Kept explicit copy choices, stable retry IDs/fingerprints, trigger mappings and invitation partial results Linked workflow-sync guide and canonical operation schemas | Verified improvement. Page purpose: Manage workspaces — every subcommand, argument, and flag → Read workspace access and manage reviewed fork, push, and pull operations.. Commands are grouped in resource/lifecycle order, retain generated options and examples, and link applicable canonical API requests/responses. Onward references and compatible heading anchors support direct lookup without changing invocation syntax. Preserved: Compared 27 baseline and 27 current command invocations; no command, argument, option syntax, alias, or required flag was removed. Command confirmations and field descriptions were read alongside current source; conditional labels match existing schema/confirmation requirements. | + +### Self hosting setup (10) + +| Page or operation | Result | Changes | Final comparison and preservation | +| --- | --- | --- | --- | +| [platform/self-hosting/authentication.mdx](content/docs/platform/self-hosting/authentication.mdx) | rewritten | Ordered origins, login methods, registration controls, SSO, proxy trust, OAuth server, and verification. Corrected effective email verification, email OTP allowlists, domain bans, public MCP registration/scope families, native callback boundary, and anonymous-session wording. Preserved client registration command, fixed token lifetimes, revocation, permission-group scope, shared secret requirements, and inbound anchors. | Verified improvement. Corrects verification with missing provider and emailOTP gates; distinguishes human OAuth authorization from provider integrations and current public registration support. Verified late fix: SSO setup now names Settings → Organization → Single sign-on while preserving both feature flags, organization-scoped and unscoped provider registration, and organization setup links. Preserved: All login callbacks/flags/sharedsecrets, signupblock/allow/MXcontrols, trustproxy, disabledauth consequences, OAuth1h/30day/rotation/revocation, registration/client/redirect/PKCE scripts and upgrade sequencing retained. | +| [platform/self-hosting/desktop.mdx](content/docs/platform/self-hosting/desktop.mdx) | rewritten | Moved server/TLS prerequisites and install/connect before update/feed internals. Corrected ability to repoint Local builds while preserving baked identity and update eligibility. Preserved URL validation, state clearing/refusal, recovery, channels/feed fallback, CLI probe semantics, packaging/signing/notarization variables. | Verified improvement. Puts exactorigin/TLS requirements before install; corrects Local identity staying fixed rather than inability to repoint and scopes update fallback. Preserved: Both endpoints/statuses/channels/repositories5mincache/GitHubquotas, install/CLIprobes/discovery, stateclearing/recovery, allbuild/sign/notarization/env/filepath options and update eligibility retained. | +| [platform/self-hosting/docker.mdx](content/docs/platform/self-hosting/docker.mdx) | rewritten | Added Compose 2.24+/Node compatibility prerequisites and manual checkout path. Kept the complete new-install secret/password script, key retention, credential interpolation, cron behavior, and image pinning. Added local-upload durability at the production step and host/container proxy distinctions. Moved FAQ material into backup, scheduler, Redis, credentials, and lifecycle sections; retained every sim-setup mode/command consequence. Corrected Caddy buffering explanation and documented host-gateway use for external Ollama. Review correction: Caddy allowance does not raise the Next.js proxy buffer. | Verified improvement. Adds runtime/Compose prerequisites, durable local upload warning, recreation semantics, provider reachability and streamedproxy qualification. Preserved: Complete6service/defaultports/memory, full5secret+DBenvcreation, URLsafecredentials/persistedPostgres, Caddyexample, OllamaCPU/GPUsetup, LMStudioauth, every CLIaction/destruction scope, backup/restore-T and update instructions remain. | +| [platform/self-hosting/email.mdx](content/docs/platform/self-hosting/email.mdx) | rewritten | Preserved five providers and fallback order while making apply/recreate and delivery checks explicit. Corrected inline, existing-Secret, and ESO credential paths. Added Gmail API/delegation prerequisites, qualified paid/trial sending limits, and placed INFO logging prerequisites with verification. Kept SMTP TLS/EHLO, SES region/sandbox, sender aliases, and troubleshooting; removed unsupported provider preferences. Used shared authored tabs with padded mixed content, wrapped prose, visible horizontal scrolling, and mobile touch targets. | Verified improvement. Adds provider delivery checks, effective verification boundary, exact secretmode injection and actual uppercaseINFO logging prerequisite. Preserved: All5providerenv/config/authsettings/fallbackorder, SMTPportsEHLO, GoogleRelayvsDWDfullsetup, SESsandbox, Azurelinkedidentity, senderaliases/quotas, alltroubleshooting preserved with a concise provider-first flow. | +| [platform/self-hosting/environment-variables.mdx](content/docs/platform/self-hosting/environment-variables.mdx) | rewritten | Reordered the reference by deployment settings, model/knowledge configuration, optional capabilities, limits, and observability. Preserved field names, defaults, egress exclusions, sandbox readiness, numbered keys, vector pairings, and inherited Helm null-removal instructions. Corrected deployment-wide database schedule cap, billing-disabled plan-counter scope, opt-in retention, worker isolation, API-key plaintext compatibility, Gemini 3-or-later eligibility, and model-specific width fallback. Qualified Azure API-version selection and separated app/source-checkout .env from Compose-derived values. Review correction: configured body defaults differ from effective request caps. | Verified improvement. Groups actual deployment config, corrections for independent limits/timeouts, worker execution, storage durability, feature overrides and effective embedding default. Verified late fix: The literal FREE_STORAGE_LIMIT_GB key and suggested value5 are preserved; its human-readable quota unit is corrected from GB to GiB. Preserved: All required/optionalkeys, AI/model/provider/OCR, codeexecutionbroker/remoteimage settings, Chat/PII, storage7providerparameters, networklimits, allfreeoptins/nullremoval/Helmreuserecovery and full.env example remain. Removed provenance note is not a configuration variable and remains in canonical Security guide. | +| [platform/self-hosting/index.mdx](content/docs/platform/self-hosting/index.mdx) | rewritten | Replaced the drifting manual quick-start script with the setup wizard and Docker owner. Separated resource examples from enforced requirements and operational defaults. Placed key/file durability, public origin, email, scheduler, and verification before optional dependencies. Qualified enterprise behavior by billing mode and retained local embedding/remote image prerequisites. | Verified improvement. Reorders deployment choice, supported wizard, production hazards and dependencies; sizing becomes examples rather than user-count guarantees. Verified late fix: Quick start now places Bun and Node.js20 or newer before bunx sim-setup, alongside the preserved Docker and Compose2.24.0 prerequisites. Wizard output, manual setup links and production safeguards remain. Preserved: All deployment choices, resource examples, enterprise/org prerequisites, model/embedding/Chat/OAuth/remote dependencies and next steps retained. Removed raw5secret quickstart replaced by wizard plus full Docker manual setup. | +| [platform/self-hosting/integrations-oauth.mdx](content/docs/platform/self-hosting/integrations-oauth.mdx) | rewritten | Created canonical Google, Microsoft, and Atlassian console setup sections for Search crosslinks. Preserved full Google Search member scopes/callbacks, all Microsoft resource scopes, full Confluence/Jira member scopes, API permissions/consent/distribution and reconnection distinctions. Added Intune, Ramp, and QuickBooks per-connection configuration; kept all prior provider exceptions/flows and hosted-only key constraints. Kept the complete GitHub App setup at its inbound anchor and removed both screenshots, retaining the correct six-permission table. Folded duplicate FAQ into setup/provider/troubleshooting sections and corrected Kubernetes secret modes. Used shared authored tabs with padded mixed content, wrapped prose, visible horizontal scrolling, and mobile touch targets. | Verified improvement. Adds complete Google/Microsoft/Atlassian member grants and distinction from Search service accounts; corrects secret-store deployment setup and scope-update/reconnect procedure. Verified late fix: GitHub App replacement now uses Credential Groups → Integrations → Update configurations. The migration affects existing provider options, preserves option IDs and retains all reconnect and secret handling consequences. Preserved: All original provider IDs/envcredentials/callbacks, GitHubAppsettings/readpermissions5variablesPEMrefresh/privateboundaries, Bitbucketexactpermissions,7providerextras, alternateInstagram/Shopify/Trelloflows, hostedkeycatalog/limits and nativeSlack requirements retained; current Ramp/Intune/QuickBooks added. Screenshots removed with full GitHub fields intact. | +| [platform/self-hosting/kubernetes.mdx](content/docs/platform/self-hosting/kubernetes.mdx) | rewritten | Pinned published chart 1.11.8/appVersion v0.9.17 without claiming a live installation test or latest status. Replaced partial public-origin snippet with complete same-host/split-host routing, allowed origin and TLS Secret instructions. Separated inline, existing-Secret and ESO branches; documented env versus envDefaults and retained all core credentials. Labeled legacy ingress-nginx defaults and annotations honestly; did not choose/provision a controller or invent Gateway API support. Pinned cloud example source v0.9.17 and required review of certificate/IAM/storage/project placeholders; preserved database-name and key-loss upgrade caveats. Corrected cosign reference syntax and qualified registry mirroring of verification artifacts. | Verified improvement. Provides full3secretmode setup, working dual port-forward/public socket/TLS examples, same-releasepinnings, verification and safe retained-secret upgrades; scopes ingress retirement. Preserved: Every original OCI/classicrepo/cosign/attestation/cloud6domainoverride/ExternalDB/redis/migrations/cron/backupconversion/PVC consequence retained; code snippets now complete and pinned instead of abstract v1.2.3. | +| [platform/self-hosting/platforms.mdx](content/docs/platform/self-hosting/platforms.mdx) | rewritten | Converted unsupported Railway template guarantees into concrete verification steps and exposed five-minute cron limits. Replaced the production convenience-script recommendation with official Docker installation and plugin prerequisites. Clarified provider-specific cloud placeholders and extension availability/activation. Labeled external DATABASE_URL scope and explained production Compose overrides. | Verified improvement. Removes unsupported live-template assumptions and adds minute-scheduler gap, maintained ingress requirement and externalDSN Compose limitation. Preserved: Railway/VPS/EKS/AKS/GKE/database providers, pgvector requirement, TLS/ManagedCertificate, resource sizing and externalDatabase setup remain; Railway badge replaced by usable linked template. | +| [platform/self-hosting/verify.mdx](content/docs/platform/self-hosting/verify.mdx) | rewritten | Preserved all 12 checks and doctor file/journal/live-probe limitations, then separated core and feature checks. Corrected cloud/local multipart thresholds and cross-replica proof claims. Added namespace-consistent commands, avoided printing a Redis credential, and checked actual job success rather than schedules alone. Preserved credential restore checks, uppercase INFO logging/no-op behavior, and upgrade subset. | Verified improvement. Replaces presence-only health guarantees with actual data/recipient/completion results and crosspod requirement; corrects multipart localvscloud thresholds. Preserved: All12checks/failureactions, doctor5groups/repairlimits/journal/skippedprobes, domains, infra/Composecommands, loglevel and postupgrade/postrestore OAuth-key checks retained. | + +### Self hosting operations (12) + +| Page or operation | Result | Changes | Final comparison and preservation | +| --- | --- | --- | --- | +| [platform/self-hosting/architecture.mdx](content/docs/platform/self-hosting/architecture.mdx) | rewritten | Rewrote the service/state/request-path overview and removed the duplicated FAQ. Corrected local JavaScript to Node child workers; kept shared container resources and remote/Trigger.dev distinctions. Preserved ephemeral-upload and secret-loss warnings; distinguished 50 MiB cloud and 8 MiB local PUT thresholds. Added scoped optional Chat-service/database/migration inventory without claiming universal packaging availability. | Verified improvement. Leads with actual services and state; replaces vague stateless labels with the state each service holds, and tables make request paths easier to inspect. Corrects local JavaScript execution to Node child workers sharing the app container memory budget; adds local 8 MiB and cloud 50 MiB transfer thresholds, upload-session persistence, and the separate optional Chat database. Integrates both original FAQ answers at their owners and links the scheduler cleanup gap without repeating the whole job inventory. Preserved: All nine service images, ports, required/optional distinctions, shared Better Auth session setup, realtime Redis prerequisite, migrations lifecycle, PostgreSQL/pgvector requirement, and state backup inventory remain. Local-upload loss and cross-replica visibility warnings, independent ENCRYPTION_KEY backup and recovery, signed browser uploads/CORS, proxied downloads, workflow and cron request paths, and ingress streaming/WebSocket needs remain. Renamed cron heading has no remaining inbound repository reference; existing where-state-lives anchor remains. | +| [platform/self-hosting/background-jobs.mdx](content/docs/platform/self-hosting/background-jobs.mdx) | rewritten | Moved authentication, deployment setup, customization, and verification before the complete shipped job table. Documented an operator-owned authenticated upload-session cleanup job; runtime/scheduler files unchanged. Corrected published cron customization to a mounted crontab or custom image. Corrected deployment-wide database schedule capacity, inline/external Secret differences, default/job-specific deadlines, and stale schedule vs 401 diagnostics. Preserved all shipped schedules, endpoints, billing/SCIM distinctions and accepted-vs-completed response behavior. | Verified improvement. Puts authenticated setup and verification before the full lookup inventory; separates stale scheduling/controller failures from 401 authentication and accepted-versus-completed work. Replaces ineffective repository-crontab editing with a real mount/custom image procedure and persists CRON_SECRET in the app/scheduler environment. Adds the missing operator-owned cleanup-tasks job and corrects scheduled concurrency to the database queue-wide cap; explains Kubernetes and request retry/deadline budgets in a table. Preserved: Every original shipped job, endpoint, cron expression, polling/subscription distinction, per-job disabling procedure, secret generation/auth syntax, supercronic logging/termination behavior, and two-minute product verification path remain. The original 202 caveat, Trigger.dev-only concurrency settings, Kubernetes history/TTL/default retry limits, outbox deadline exception, and memory headroom consequence remain. Renamed the-jobs heading has no remaining inbound repository reference; #concurrency remains. | +| [platform/self-hosting/networking.mdx](content/docs/platform/self-hosting/networking.mdx) | rewritten | Moved optional second-ingress/Chat-service routing after core proxy and cloud setup. Added required GKE annotation, cleared unsupported controller field, and qualified certificate provisioning time. Labelled ingress-nginx as retired legacy guidance while keeping standalone Nginx and existing-install annotations. Corrected Azure timeout to 20 seconds and distinguished ALB idle timeout from fixed connection lifetime. Preserved full proxy/transport/NO_PROXY/escape-hatch matrix and reduced large explanatory callouts. Used shared authored tabs with padded mixed content, wrapped prose, visible horizontal scrolling, and mobile touch targets. Review correction: external proxy, Next.js buffer and route body caps are independent layers. | Verified improvement. Corrects GKE ingress class selection, certificate provisioning/verification, Azure backend timeout (20 seconds), and ALB idle timeout semantics; labels retired ingress-nginx configuration as existing-install reference. Preserves complete proxy and egress lookup detail while giving internal NO_PROXY destinations their own section; moves optional ingress/service routing after the main setup. Uses authored tabs and binary request-size units; quotes shell placeholders so readers do not accidentally invoke redirection syntax. Preserved: Both topology variants and all URL/origin keys; full Caddy, Nginx, Traefik, GKE BackendConfig/Service annotation, ManagedCertificate, ALB, and internal ingress examples remain. All request-size keys/defaults, local/cloud upload transport distinction, Bun/Node proxy behavior, per-SDK transport rows, every NO_PROXY example, and the HTTP-only publicly routable per-request proxy restriction remain. Chart-dropped Service annotations, reapplication after Service recreation, TLS/DNS prerequisites, optional copilot host sharing, and WebSocket/SSE timeout/buffering consequences remain. Renamed headings have no remaining inbound repository references. | +| [platform/self-hosting/object-storage.mdx](content/docs/platform/self-hosting/object-storage.mdx) | rewritten | Moved deployment application steps after all provider setup; corrected backend activation keys. Made the AWS bucket loop handle us-east-1 correctly and preserved all IAM/CORS/bucket fallback details. Added private Azure container creation and a fallback table; kept both credential forms and full CORS headers. Fixed GCS JSON formatting and preserved explicit signed-upload headers, ADC/signBlob permissions and bucket fallbacks. Removed unsupported blanket compatibility/wildcard/MinIO assertions, preserving provider examples and operator verification requirements. Documented missing shipped upload cleanup scheduling and linked the authenticated operator-owned procedure. Used shared authored tabs with padded mixed content, wrapped prose, visible horizontal scrolling, and mobile touch targets. | Verified improvement. Corrects activation predicates, cloud upload/proxied download wording, AWS us-east-1 creation syntax, Azure connection-string shell quoting, and uncertain S3-compatible provider guarantees. Adds the missing Azure container creation procedure and presents fallback behavior in a table. Moves Apply after every provider setup and identifies unscheduled cleanup-tasks with an actual operator procedure link, keeping final-object expiration warnings visible. Preserved: All local path/durability/replica warnings; explicit STORAGE_PROVIDER and precedence/fail-fast behavior; S3, Azure, and GCS purpose-specific bucket/container variables and fallback exceptions remain. All eight AWS/GCS purpose buckets, exact CORS policies and signed metadata/create-only headers, IAM policy/actions, role/IRSA and ADC/inline-key choices, self signBlob permission, provider endpoint/path-style examples and browser reachability/CSP warnings remain. Apply/recreation instructions, preservation of existing local bytes, provider multipart lifecycle/24-hour session/seven-day Azure window, no final-object expiration, and upload/reload/provider-object verification remain. Renamed headings have no current inbound references. | +| [platform/self-hosting/observability.mdx](content/docs/platform/self-hosting/observability.mdx) | rewritten | Added deployment monitoring/privacy purpose and moved alerts before telemetry setup. Consolidated tracing warnings into the full two-change Helm configuration. Replaced incomplete PII snippet with a scoped policy/network setup link to Security and Data retention. Documented opt-in Chat content capture and distinguished collection, relay, server spans, log records, browser preference and Trigger.dev telemetry. Corrected Redis outage logging and retained health/probe/metrics/OTLP/CloudWatch limits. | Verified improvement. Adds an operator-oriented opening and makes log-redaction policy activation and verification link explicit rather than equating a deployed PII service with masking. Replaces categorical telemetry confidentiality promises with actual default instrumentation and optional message-capture behavior, and states that collection disabling does not disable the relay. Combines the two Helm tracing changes in one complete example; distinguishes successful scheduler requests from completed work and acknowledges Redis connection errors. Preserved: Both health endpoint shapes, liveness-only limitation, full app/realtime probe budgets, LOG_LEVEL commissioning advice, logs commands/request IDs/product Logs distinction, no stock metrics endpoint, CloudWatch self-hosting scope, and every alert remain. Server/browser defaults, privacy preference, three OTLP signals and log metadata, Trigger.dev distinction/all-or-none Grafana variables, endpoint/sampling precedence, mothership service name, Jaeger OTLP port, and collector setup remain. | +| [platform/self-hosting/redis.mdx](content/docs/platform/self-hosting/redis.mdx) | rewritten | Separated managed-service guidance from Compose/Helm deployment tabs. Qualified managed service clustering compatibility and sizing/failover assumptions; updated Azure retirement advice. Scoped TLS server-name override to app IPv4 and recommended certificate-matching DNS for app/realtime. Kept fallback/persistence/secret/egress details; verification no longer prints credential-bearing URLs. Used shared authored tabs with padded mixed content, wrapped prose, visible horizontal scrolling, and mobile touch targets. | Verified improvement. Replaces universal managed-service/HA sizing assurances with measured estimates and compatible single-endpoint cluster-policy requirements, including Azure retirement guidance. Correctly scopes TLS server-name override to app IPv4 literals and recommends certificate-matching DNS for both app and realtime. Verification checks URL presence without disclosing credentials and separates a bundled redis-cli ping from testing external connectivity/cross-pod behavior. Preserved: All seven fallback matrix entries; pairing-only Redis requirement vs OAuth; cross-pod collaboration/live-event prerequisite; in-flight streaming/cancellation loss vs committed-data preservation remain. Both Redis/TLS URL forms, Compose external override, Helm auto-managed suppression, Secret envFrom precedence, nonpersistent 512 MiB bundle, external egress rule, private endpoint/auth/TLS recommendations, SNI example and cross-replica functional check remain. Managed Redis tab content is promoted to a normal section, preserving the three cloud choices. Renamed verifying heading has no current inbound repository reference. | +| [platform/self-hosting/reference-architectures.mdx](content/docs/platform/self-hosting/reference-architectures.mdx) | rewritten | Put cloud provisioning and secrets before sizing; retained IaC, identity, network and placeholder-secret prerequisites. Qualified chart minimum vs supported cloud Kubernetes releases and selected StorageClass/provisioner requirements. Labelled legacy AKS ingress-nginx and Azure Cache recommendations without choosing unsupported replacements. Narrowed ALB certificate warning and allowed supported GKE certificate coexistence/migration. Updated chart example to reconciled published 1.11.8/v0.9.17 and explained appVersion vs explicit pins; added Related docs. Used shared authored tabs with padded mixed content, wrapped prose, visible horizontal scrolling, and mobile touch targets. | Verified improvement. Leads with the operator/chart provisioning boundary; removes unsupported Kubernetes support, EKS StorageClass, throughput, and blanket certificate claims. Updates Azure ingress and managed Redis recommendations and clarifies ALB certificate requirements and GKE mixed-certificate migration support. Corrects version pinning: a pinned chart selects its appVersion when image tags are empty, while explicit tags/digests override. Distinguishes published chart metadata from checkout metadata. Preserved: Complete evaluation/production component matrix, local durability, remote Function/Pi image requirements, default database volume, managed-datastore egress warning, per-cloud infrastructure/identity/timeouts, and optional GPU prerequisites remain. All three secret-delivery strategies, complete existing Secret keys and shadowing, ESO mapping failure, requests/limits, full Terraform helm_release example including six sensitive values, placeholder-secret warning, and onward install/security/verification links remain. | +| [platform/self-hosting/sandboxes.mdx](content/docs/platform/self-hosting/sandboxes.mdx) | rewritten | Rewrote as execution decision, build/verify, deploy, UI readiness, promotion/rollback and separate-image procedure. Preserved E2B-first Daytona parity requirement and all immutable identifiers, scopes, commands and manifest variables. Added checkout/dependency prerequisites, quoted shell placeholders and removed duplicated Daytona build command. Kept 422/503 conditions, billing-disabled entitlement and browser/server distinction; retained shell/Function/document/Pi separation. Used shared authored tabs with padded mixed content, wrapped prose, visible horizontal scrolling, and mobile touch targets. | Verified improvement. Reorders build, verify, configure, enable controls, and promote/rollback so the accepted E2B manifest exists before Daytona consumes it. Quotes shell placeholders and declares checkout/dependency prerequisites, keeps explicit selected-provider verification, and separates public UI assertion from server readiness. Summarizes local/remote execution paths in a table and adds Pi image distinction without overstating local worker isolation. Preserved: Local JavaScript exceptions, selected sandbox 503 and file-path 422 distinctions, Python fail-closed behavior, entitlement/master-switch/browser flags and visible Settings behavior remain. Both full build commands, API-key scopes, immutable image formats, positive monotonic E2B generations, accepted E2B parity manifest capture and Daytona baseline verification, --generation/--base-template, and higher-generation rollback requirement remain. Public Chat run_function/run_code shell image versus workflow function_execute Function image and separate shell/Function/document/Pi contracts remain. Renamed heading anchors have no remaining inbound repository reference. | +| [platform/self-hosting/scaling.mdx](content/docs/platform/self-hosting/scaling.mdx) | rewritten | Put prerequisites and measurements before scaling settings; removed unsupported observed-memory guarantee. Corrected Node child workers and deployment-wide scheduled-run cap. Added main/subpool ceilings and actual 30-primary app budget; excluded HTTP-only cron pods from independent database counts. Qualified pooling compatibility and linked direct migration DSN; preserved replica overrides/lag and PDB/HPA behavior. Separated billing-disabled plan limits from fixed safety/admission controls and labelled sizing/topology illustrative. | Verified improvement. Puts Redis and shared-storage prerequisites before scale examples and replaces unverified workload benchmarks with measurements/defaults and clearly labelled estimates. Corrects connection budgeting to sum all active main/subpools rather than charging cron pods for direct database pools; preserves per-role read-replica limits and warns about session locks/direct migrator connections. Corrects scheduled concurrency to a shared database cap; qualifies billing-disabled plan limits versus fixed security controls and removes a false 100-user throughput guarantee. Preserved: All component scaling behavior, full replicas/resources and HPA examples, metrics-server requirement, omitted replicas under HPA, PDB/shared-HPA caveat, scale-down interruption warning, and realtime disable example remain. External database two-flag requirement and app.env.DATABASE_URL override caveat; all read-replica keys/fallback/lag; all sizing values; concurrency settings; limit opt-ins/timeouts; full topology/secrets/password/ESO/PDB example remain. | +| [platform/self-hosting/security.mdx](content/docs/platform/self-hosting/security.mdx) | rewritten | Moved the pre-launch checklist, signup restrictions, and proxy trust before detailed hardening. Folded repeated FAQ answers into their owners, kept all referenced anchors, and preserved key-loss/rotation and Compose password recovery. Corrected API-key storage wording and local Node-worker boundary; removed unsupported provider isolation ranking/universal SSRF guarantee. Added both inbound and outbound app self-call rules plus stored PII Logs policy and verification; kept fail-closed behavior. Kept allowlist/provenance/redirect/metadata/response-cap exceptions and GPU restricted-profile exception; condensed secret modes and validation rules. | Verified improvement. Puts checklist/access/prerequisites first; integrates duplicate FAQ answers; preserves scoped request provenance while removing the false guarantee for arbitrary sandbox network traffic. Corrects local code worker isolation, stored API-key rotation effects, immutable provider readiness errors, restricted-profile GPU exception, and broad egress override semantics. Adds stored log-redaction policy activation, both directions of app self-call NetworkPolicy, and a concrete masking check; labels timing/memory as measured rather than guaranteed. Final recheck: states that the chart default ingress peer permits any source on listed ports when ingress is enabled, and distinguishes original-key restoration from unrecoverable key loss. Preserved: All five secrets, same-session secret requirement, independent encryption backup, all three delivery strategies and shadowing/mapping consequences, ingress/egress rules, metadata-layer distinctions, optional unisolated workloads, restricted-profile exceptions and writable-root choices remain. All six egress provenance classes, exact allowlist examples/validation/limits, loopback/port/HTTP/Cloud distinctions, legacy compatibility cases, redirect statuses/header/body behavior, 100 MiB response limit and unbounded SSE exception remain. Local-worker security warning, all broker ceilings, PII failure marker/internal URL, historical default Compose password/public-port warning, SQL password rotation and loopback/SSH example, and every checklist item remain. Renamed optional-Chat-policy heading has no inbound repository references. | +| [platform/self-hosting/troubleshooting.mdx](content/docs/platform/self-hosting/troubleshooting.mdx) | rewritten | Reordered all existing symptoms by deployment, auth/network, models/files, scheduler, restore, and source-only Windows lifecycle. Corrected scheduler-vs-auth diagnostics, Redis TLS scope, host alias behavior, private-host allowlist example and proxy owner links. Kept every diagnostic command and embedding/model exception; preserved encryption recovery and TLS-verification warning. Qualified CA-chain guidance and preserved UNABLE_TO_GET_ISSUER_CERT; normalized headings and Bun invocation. | Verified improvement. Reorders every symptom into deployment, login, network, model/storage, scheduler, restore, and source-only recovery order; replaces assumptions with diagnostic interpretation. Corrects shipped Linux host alias, Redis IPv4/app-only SNI scope, stale CronJob diagnosis, TLS chain/bundle caveats and cloud MiB completion threshold. Avoids deleting browser state before collecting errors and replaces printenv Redis credential exposure with presence checks. Preserved: All 23 original symptom families remain, including doctor modes/flags/exit status, database/migrations/pgvector/Kubernetes readiness/image/PVC, realtime/proxy/buffering/disconnects, Redis, TLS trust, private destinations, Ollama/LM Studio auth/prefix/URL/env propagation, CORS, embeddings width/recreation, schedules/polls/Teams, restored credentials, and Windows WSL/LF. Full Compose/Helm command examples, exact settings/env/error/status names, PostgreSQL verification and migration restart, HTTP in-pod secret expansion, original encryption-key recovery, and help links remain. Linux host-IP fallback remains available in the custom-container LM Studio guidance; shipped alias works across hosts. Renamed symptom headings have no current inbound repository references. | +| [platform/self-hosting/upgrades.mdx](content/docs/platform/self-hosting/upgrades.mdx) | rewritten | Moved the upgrade procedure and rollback before advanced migration mechanics. Updated reconciled published release/chart examples and documented pinned SIM_VERSION behavior before update. Corrected SQL retry budget to 20 minutes; retained 30-minute advisory acquisition, session checks, lock/statement timeouts and connection-error retries. Separated migration DSN delivery modes and kept pooled/direct connection hazards and init-container failure recovery. Preserved all backup/rehearsal/CLI install-kind/pinning/Ollama profile/restore data-loss steps; qualified application-only rollback and password-history inference. Used shared authored tabs with padded mixed content, wrapped prose, visible horizontal scrolling, and mobile touch targets. | Verified improvement. Improves rollback safety: additive migrations alone no longer prove older-app compatibility; puts write-loss and stopped-writer consequences before restore steps. Corrects image/chart pin coupling and actual published version, migration retry budget, pin updates before sim-setup update, shell placeholders, helm-diff prerequisite and persisted-database password diagnosis. Keeps operator procedure concise and moves advanced migration mechanics into a lookup section. Final recheck: restores the concise direct MIGRATION_DATABASE_URL prerequisite before upgrade commands, including Helm/Compose delivery constraints and #migration-environment link. Preserved: All three aligned images and independent cron pin, tag/digest examples, five-step release/backup/rehearsal/apply/verify procedure, snapshots/pg_dump database names, full Helm/Compose/source/Ollama upgrade modes/profile commands, managed-file protection and maintenance downtime remain. Both rollback modes and all writer stopping/restore/old release/secret/verification consequences, all five migration failure diagnoses and do-not-skip-journal warning remain. Complete forward-only SQL/data migration behavior, replica serialization, 30-minute/5-second acquisition, direct DSN/backend PID guard, Helm/Compose propagation, SQLSTATE 55P03/20-minute retries, once-only scripts and 10 transient startup retries remain. Renamed how-migrations-run heading has no current inbound references. | + +### Workflow core (16) + +| Page or operation | Result | Changes | Final comparison and preservation | +| --- | --- | --- | --- | +| [workflows/connections.mdx](content/docs/workflows/connections.mdx) | rewritten | Clarified execution edges versus references, period/whitespace normalization and skipped/missing output behavior Corrected Agent toolCalls list/count and qualified normal API and structured Agent output shapes Replaced nonexistent Router content with context, selectedRoute and reasoning; kept model, tokens and selectedPath. Used shared authored tabs with padded mixed content, wrapped prose, visible horizontal scrolling, and mobile touch targets. Marked output examples as abbreviated; qualified optional Function files, bounded stdout, Agent metadata collisions, and Evaluator fallback scores. | Verified improvement. Separates execution dependencies from value tags and distinguishes unknown names, invalid fields, and known skipped blocks. Corrects Agent toolCalls to list/count, Router fields, and abbreviated optional outputs; adds structured metadata collisions, bounded Function stdout, and Evaluator zero-score qualification. Preserved: Retains normalized names, case-sensitive paths, nested objects, multiple array indices, picker/drag interaction, mixed text and typed Function references, all six complete output examples, and numeric-conversion caution. The existing connections video remains. Its appearance/playback was not assumed verified; no stale-media claim is used. | +| [workflows/data-flow.mdx](content/docs/workflows/data-flow.mdx) | rewritten | Kept one classify/reply preview and OutputBundle; removed repeated preview Explained last terminal completion, selected blockOutputs projection and v2 Response envelope | Verified improvement. Explains that references select data while edges ensure availability, including active-path joins and skipped-block resolution. Adds completion-order-dependent default workflow output, deliberate final blocks, selectedOutputs projection, and the v2 envelope distinction. Preserved: Retains the complete Classify/Reply workflow and typed OutputBundle; removes only the duplicate highlighted rendering. All six original data kinds, file metadata, per-block output names, reshaping guidance, picker behavior, and Logs navigation remain. Table row nesting and Function result are more explicit. | +| [workflows/how-it-runs.mdx](content/docs/workflows/how-it-runs.mdx) | rewritten | Preserved four distinct corrected shared previews and dependency/error-port rules Added shared Parallel state and non-2xx API error path; labeled timeout defaults and billing-disabled behavior | Verified improvement. Qualifies handled versus unhandled failures and successful API status outputs instead of implying all failures stop runs. Corrects shared workflow variables inside Parallel and labels execution durations as billing-enabled defaults, with billing-disabled self-hosted configuration and admission/log limitations. Preserved: All four distinct previews remain: independent work, join, routing, and error/success ports. All nodes, displayed settings, and edges were read. Retains dependency readiness, active-path joins, first matching branches, Loop/Parallel nesting, call-chain limit, 5/50/90-minute and Enterprise seven-day limits, timeout consequence, and batching recovery. | +| [workflows/index.mdx](content/docs/workflows/index.mdx) | rewritten | Reduced five repeated previews to one structured classification example Preserved #blocks/#triggers, trigger taxonomy including Sim events and block/tool distinction Added explicit terminal-result/v2 envelope and draft/live boundaries | Verified improvement. Leads with one actual structured-classification example and concrete trigger/block/tool/connection/output definitions instead of five repetitions of the same preview. Adds Sim Workspace Events to trigger taxonomy and clarifies default terminal output, v2 Response behavior, and draft/live Update semantics. Preserved: Retains the classify use case, block/tool distinction, deterministic rule/code versus model behavior, fan-out answer, all trigger families, data-flow navigation, and stable #blocks/#triggers/#how-it-runs/#next IDs. The remaining preview explicitly requests category/urgency in a complete JSON Schema rather than implying ordinary content magically becomes named fields. | +| [workflows/variables.mdx](content/docs/workflows/variables.mdx) | rewritten | Replaced isolated Parallel scope with shared run-scoped variables Kept types, initial reset, literal/reference assignment and Function arithmetic distinction Qualified secret grants, personal ownership/current UI nuance, Unredacted and exact protection scope | Verified improvement. Replaces false per-Parallel-variable isolation and universal workspace visibility with shared run state and authorization/grant-aware secret access. Distinguishes reserved reference prefixes, unknown/skipped references, arithmetic versus assignment, and protected versus Unredacted secret projection. Preserved: Retains all five types and initial-value examples, panel procedure, normalized/nested references, per-run reset, same-name workspace precedence, string placeholder coercions, and OAuth/account guidance. The exact execution-log protection owner is linked at the point of use. Settings first-character constraint is explicitly scoped to the Settings UI; broader v2 secret character policy is not falsely narrowed. | +| [workflows/deployment/agent-events.mdx](content/docs/workflows/deployment/agent-events.mdx) | rewritten | Consolidated negotiation/policy rules and preserved all frame, reset, abort, reconnect and memory distinctions Added separate chat-outputs-v1 capability; replaced unsafe reference parser with body/blockId checks and terminal handling Kept generated Agent table as linked support owner | Verified improvement. Consolidates independent negotiation and exposure policies, correct UI labels, authenticated API example, structured chat-output capability, and terminal/nonterminal distinctions. The full reference parser now guards HTTP/body/block IDs, handles terminal success/error immediately, separates answer/thinking/output buffers, and cancels/releases its reader. Preserved: Retains every frame class, JSON DONE sentinel, chunk resets and interleaving, answer cadence, public tool-metadata limits, stripped reasoning timing, abort/cancel distinctions, live-only reconnect behavior, editor policy, and durable memory boundaries. All Bash and TypeScript examples and all table frames reviewed in full. Detailed provider/model coverage is preserved in the linked generated Agent support region; compact family qualifications remain locally. | +| [workflows/deployment/api.mdx](content/docs/workflows/deployment/api.mdx) | rewritten | Reorganized authenticated task and sync/SSE/async behavior, preserving language/request/polling examples Corrected token-stream header/reset requirement, v2 Response/error envelope and public/async/manual restrictions Preserved opaque large refs, statuses, retention, retry/reconciliation and key guidance Root standardized the exact Sim API keys settings label and added transient redacting status to polling guidance. Used shared authored tabs with padded mixed content, wrapped prose, visible horizontal scrolling, and mobile touch targets. | Verified improvement. Orders deployment/authentication before requests and explains sync run-resource failure statuses, SSE negotiation, NDJSON heartbeats, async restrictions, manual draft policy, and one-shot run-ID reconciliation. Corrects v2 Response/status/envelope claims, structured capacity errors, transient redacting status, named selectors, and raw-SSE example purpose. Preserved: All cURL/Python/TypeScript sync and stream examples, thinking/tool example, async receipt/polling/completed output, full large-value reference, status table, timeout cap, retention, rate headers, and compromised-key recovery remain. Version/update/rollback/undeploy facts and all three legacy v1 examples are moved to linked Deployment; exact timeout default table is in linked How workflows run; key lifecycle stays linked to Authentication. Public access, description, and output picker procedures remain locally. | +| [workflows/deployment/chat.mdx](content/docs/workflows/deployment/chat.mdx) | rewritten | Made Agent Memory explicit; latest input/conversationId/files are actual message payload Preserved creation/output/access/share/embed/file/OTP examples and input limit Distinguished hosted OTP resend countdown from server limits and broadened 403 diagnosis Used shared authored tabs with padded mixed content, wrapped prose, visible horizontal scrolling, and mobile touch targets. | Verified improvement. Corrects automatic full-conversation claims with latest-message/files/conversationId payload and explicit Agent Memory setup. Adds deployment role/capability, live/reset protocol, independent events and structured outputs, working cookie-jar OTP requests, exact encoded-file units, and broader 403 diagnosis. Preserved: Retains all launch fields/default greeting/output choices/access modes/slug rules, password/email/SSO procedure, direct link, complete iframe, cURL/TypeScript submission, file example, OTP flow, input cap, and troubleshooting. The focused allowed-email screenshot remains and was visually inspected. Removed broad launch/output screenshots duplicate the complete written controls; old unsupported voice/full-history language is not treated as a useful current guarantee. | +| [workflows/deployment/index.mdx](content/docs/workflows/deployment/index.mdx) | rewritten | Made this the canonical Admin/deploy/update/version/compare/load/promote/undeploy owner Moved full v1 deploy/undeploy/rollback examples from API guide here Clarified definition snapshot versus mutable resources and successful live-state verification | Verified improvement. Makes deployment the canonical role/prerequisite/version/task owner and adds actual comparison, draft replacement warning, promotion verification, and undeploy consequences. Moves complete legacy deployment API examples here and qualifies active snapshots versus separately mutable resource contents and explicit manual draft API. Preserved: Retains snapshot/version/live definition, numbering/actor/date, Update toolbar, Rename/description/Promote/Load actions, common active deployment, API/chat/MCP links, and complete v2 input call. All deploy/undeploy/rollback commands from the old API page are present with optional deploy body and specific-version guidance. Update screenshot was inspected and matches the stated control. | +| [workflows/deployment/mcp.mdx](content/docs/workflows/deployment/mcp.mdx) | rewritten | Corrected Admin-only management and separated invocation auth Preserved server/tool lifecycle, parameter defaults/overrides and live snapshot behavior Replaced old bridge configurations with official Cursor/Codex/Claude Code/VS Code HTTP examples and verified Claude Desktop remote headers flow | Verified improvement. Corrects workflow-MCP management to Admin with no workspace-key access, separating authenticated invocation from management. Replaces outdated bridges/interpolation/CLI flags with direct HTTP Cursor, Codex, Claude Code, Claude connector, and VS Code examples and primary documentation. Preserved: Retains server creation/details/URL/tool lifecycle, public/private headers, optional initial workflows, tool name/description fallbacks, parameter descriptions/overrides/redeployment, client picker/install link, tool/server deletion consequences, and live snapshot behavior. All JSON/TOML/Bash configurations were read in full. Removed screenshots/videos duplicate complete step procedures; remote videos were not declared stale from an uninspected appearance. | +| [workflows/triggers/rss.mdx](content/docs/workflows/triggers/rss.mdx) | rewritten | Corrected 500 identifiers, subscription creation boundary, per-poll 25/backlog and no-date cases Removed impossible feed.language reference; preserved bounded item/feed outputs and actual failure/backoff behavior Moved FAQ facts into visible behavior sections | Verified improvement. Corrects 500-identifier retention and subscription-creation date boundary, no-date exceptions, 25-per-poll eligible backlog, admission-refusal retries, and limited feed projection. Makes backoff/Retry-After, auto-disable/reset, 10 MiB fetch limit, self-hosted poller, and verification visible outside FAQs. Preserved: Retains feed-only setup/no connected account, RSS/Atom support, normal minute cadence, item/feed/convenience/timestamp outputs, all supported item fields, per-item runs, duplicate prevention, 25 selection order, and 100 failures/recovery. The impossible feed.language example is replaced with feed.description. A concrete release-summary procedure replaces generic lists; monitoring/podcasts use the same preserved per-item mechanism. | +| [workflows/triggers/schedule.mdx](content/docs/workflows/triggers/schedule.mdx) | rewritten | Used exact settings, valid minute examples, cron alignment and browser timezone/UTC fallback Preserved deployment/registration, multiple blocks, 100-failure and five-minute 429 defer behavior Linked required self-hosted scheduler and removed stale disabled screenshot | Verified improvement. Corrects elapsed-timer/1–1440-minute implication to valid cron minute steps, browser timezone initialization and UTC stored-value fallback. Adds exact controls, next-run/log verification, queued-versus-running distinctions, external scheduler prerequisite, and non-429 admission failures. Preserved: Retains all six modes, hourly minute bounds, all three cron examples, deploy/update/undeploy registration lifecycle, multiple independent schedules, 100 failures/badge reactivation/success reset, and five-minute 429 deferral. Removed disabled screenshot adds no procedure beyond named badge action. Longer intervals are supported through Hourly/Daily/Custom rather than misleading invalid minute steps. | +| [workflows/triggers/sim.mdx](content/docs/workflows/triggers/sim.mdx) | rewritten | Added actual setup/defaults for all events and run-backed conditions Separated No Activity poller/deployed scope, null payload fields and per-source inactivity cooldown Preserved billing/rate/fire-and-forget/recursion and deployment snapshot constraints | Verified improvement. Adds exact default event/threshold settings and complete wire payload example rather than UI-only event descriptions. Separates No Activity poller, deployed/unarchived scope, never-run behavior, and per-source cooldown from run-backed one-hour subscription cooldown. Preserved: Retains all four plain events and seven rules, workspace filters/self-exclusion, rate minimum five, duration/cost units, truncation, run versus triggeringRun fields, deployment version, fire-and-forget/billing/rate policy, anti-recursion, and redeployment requirement. Adds explicit null-inapplicable fields and self-hosted background-job link. Removed tab/list duplication loses no payload fields. | +| [workflows/triggers/start.mdx](content/docs/workflows/triggers/start.mdx) | rewritten | Corrected public API nested input and built-in outputs supplied outside Chat Added descriptions and trusted advanced run metadata with reserved field constraints Preserved defaults/coercion/files/editor priority/mock payloads; distinguished v2 explicit entry selection Used shared authored tabs with padded mixed content, wrapped prose, visible horizontal scrolling, and mobile touch targets. | Verified improvement. Corrects API fields to nested input and chat payload to latest message/files/conversation ID instead of arbitrary launch context or chat-only built-ins. Adds trusted run metadata, reserved fields, valid primitive coercion, and explicit v2 manual entry/mock selection constraints. Preserved: Retains all types/file inputs, defaults for absent/null but not empty string, editor form/upload ordering, normalized references, multiple triggers/editor priority, mock payload testing, and early validation advice. All three surface tabs and the full request example were read. Old screenshot is redundant with complete visible field table; legacy output fields remain described when supplied by other execution surfaces. | +| [workflows/triggers/table.mdx](content/docs/workflows/triggers/table.mdx) | rewritten | Added deleted-row event; removed nonexistent either option and used exact field labels/defaults Clarified name-keyed rawRow/mapped row, previousRow/deletes, watched columns and direct fire-and-forget behavior | Verified improvement. Adds deleted-row events and correct one-event-per-trigger choice, exact UI fields, default Inserted/header mapping, and same-workspace selection. Corrects rawRow as name-keyed projection and delete previousRow semantics; distinguishes committed mutation from follow-up workflow success. Preserved: Retains all nine references, optional watched-column filtering, table identity/headers/timestamp, mapping toggle, and insert/update use cases. Current hero now uses Event/Watch Columns and a configured Row Updated example. Verification includes a real row event and Logs; missing row fields are qualified. | +| [workflows/triggers/webhook.mdx](content/docs/workflows/triggers/webhook.mdx) | rewritten | Corrected stable identifier dedup, optional methods and filtered exposed headers with defaults Separated acknowledgement from completed response; preserved deploy/verification/token/port/payload conditions Added authenticated/idempotent curl verification and service-trigger ownership link | Verified improvement. Corrects authentication-on/default Bearer versus exclusive custom header, optional accepted methods, filtered opt-in headers, and scalar stable-ID deduplication. Separates queued receipt/custom acknowledgement from workflow completion and setup verification; provides authenticated, repeatable dedup/auth rejection examples. Preserved: Retains generated URL/deploy requirement, optional named input/file shape, payload references, headers/query/method conditions, configurable response, validation warning, rate limits/no auto-disable, and integration-trigger navigation. Complete curl retains test userId/event and adds a stable key/token. Removed service-specific Slack video is redundant/different-service scope; provider procedure remains linked rather than declared visually stale. | + +### Enterprise governance (8) + +| Page or operation | Result | Changes | Final comparison and preservation | +| --- | --- | --- | --- | +| [platform/enterprise/access-control.mdx](content/docs/platform/enterprise/access-control.mdx) | rewritten | Renamed visible title to Permission groups, retained route, and ordered availability, creation, scope, provider/block/platform references, enforcement, deployment, and related docs. Corrected default fallback versus stacked restrictions, empty SCIM explicit groups, human principal versus workspace-key authority, trace/cost projection, and remembered tool approval. Added Agent default, Knowledge Base Export, Project Issues checklist semantics, current Create group/row/Save navigation, and master/explicit flag precedence. Preserved all platform capabilities, auth/connector allowlists, one-group assignment conflicts, immediate scope/member mutations, external membership scope, start_trigger exemption, existing-workflow failure, and environment allowlist intersection. | Verified improvement. Clarifies one-group fallback rather than intersection, SCIM empty explicit groups, actual actor policies and workspace API-key authority; adds Project Issues and Agent default. Preserved: All permission categories, provider/model and block/tool lists, organization-only rows, conflict behavior, save/immediate scope distinction, external members, instance allowlist and existing-workflow recovery retained. Screenshots replaced by full control/reference tables. | +| [platform/enterprise/audit-logs.mdx](content/docs/platform/enterprise/audit-logs.mdx) | rewritten | Ordered role/entitlement, viewer, export, versioned API, event semantics, limitations, operator API, and related docs. Corrected historical workspace scope and departed/external-actor defaults; labelled v1 compatibility alongside v2. Preserved v1 fields, response, personal-admin key requirement, workspace-key refusal, cursor/limit, event categories, anonymous/operator attribution, best-effort exception, and tamper limits. Preserved 10,000-row/64 MiB export bounds and truncation, sensitive CSV fields, deployment-admin headers, all-instance scope, offset defaults and max250. Focused source check corrected viewer to resource-type/date filters plus workspace deep-link chip; search also matches actions/actors/resources, not an invented actor picker. | Verified improvement. Separates current/departed actors, CSV/JSON sensitive fields, representative events and best-effort persistence; adds supportedv2 navigation without silently alteringv1 contract. Preserved: Fullv1 request/response/query/rate-pagination example retained including USD limits; all event families, export10000/64MiB caps, admin offset API differences, scopes/keys and tamper limits preserved. Screenshot replaced with named viewer controls and columns. | +| [platform/enterprise/custom-blocks.mdx](content/docs/platform/enterprise/custom-blocks.mdx) | rewritten | Moved source-admin and organization/feature prerequisites before Workspace settings publication procedure. Added Required input overrides, exact field/output caps and reserved names, current Save, and latest-deployment interface behavior. Corrected Disable/Delete/source-undeploy effects on existing placements; API publication enabled flag is distinguished from disabling a canvas block. Preserved source-owner delegated/personal authority, source-workspace variables/billing, curated output boundary, child logs, default-off consumer tracing, future-only policy changes, opaque failure reference, and fixed source. | Verified improvement. Corrects deletion and disabling to leave broken placements; source access, billing and consumer trace boundaries now precise. Preserved: All input/output/presentation/trace controls, latest deployment, fixed source, required outputs, admin role, source-owner credentials and failure reference retained; useful toolbar screenshot remains. | +| [platform/enterprise/data-drains.mdx](content/docs/platform/enterprise/data-drains.mdx) | rewritten | Ordered create/test/run procedure, source/schema boundaries, seven destination references, delivery bounds, retention pairing, rotation/deletion, and operator scheduling. Corrected Create drain/New drain/Create actions, Every hour/day labels, detail-page last10 run fields, and API-only destination locators. Corrected BigQuery best-effort deduplication, local Snowflake guard, S3 path-style/public HTTPS and probe cleanup; preserved provider fields/auth/object paths and webhook headers/signature/retries. Preserved source IDs/wire values, all-history backfill, five-minute window, mutable Chat snapshot behavior, exact caps, partial acceptance/replay, stored PII policy, encrypted credential omission/replacement, external lifecycle, and deletion effects. Separated UI recreate from API credential rotation; preserved CRON_SECRET, disabled404/no-op behavior, optional Trigger.dev, and bounded two-job database runner; changed doctor invocation to bunx. Clarified powers-of1024 source bounds and BigQuery 10 MiB request guard from owning source instead of old ambiguous MB wording. | Verified improvement. Introduces concrete verify procedure, exact binary/decimal bounds, incomplete-export and rotation/cursor consequences; avoids CDC and dedup guarantees. Verified late fix: Cloud destinations require public addresses and HTTPS. Self-hosted S3-compatible endpoints may be approved private or named loopback destinations but remain HTTPS-only; self-hosted webhooks may use HTTP only where configuredEndpoint policy allows it. Metadata refusal, pinned address, signed S3 target behavior, authentication, retry, deduplication and source bounds remain. Preserved: All5 source wireIDs,7 destinations with auth/schema/permissions/objectlayout, complete HMAC headers, at-least-once checkpoints, stability window, retry schedule, source/limit caps,20/25min bounds, deletion and retention consequences retained. | +| [platform/enterprise/data-retention.mdx](content/docs/platform/enterprise/data-retention.mdx) | rewritten | Moved exact Cloud/Enterprise/billing-disabled default table before organization/override configuration. Preserved all UI periods and 24-43,800-hour API bounds, independent field inheritance/null/Forever, whole-policy PII replacement, removal fallback, and irreversible shortening. Corrected file-version coalescing and protected current+9 previous floor, 500 superseded ceiling and Free99 previous cleanup; kept API-only field. Added startedAt log age, active paused-run protection, logical versus physical cleanup, stage-selection prerequisite, failed redaction behavior, and text-only/non-retrospective scope. Preserved resource families, Task age basis, exact entity/language options, output recognizer exclusions, patterns/tokens/max20, and computation warning. Preserved four CRON_SECRET endpoints, missing shipped schedules, explicit/master enablement, optional inline cleanup, PII service Helm naming/manual-value precedence and Compose prerequisite. | Verified improvement. Replaces false no-deletion defaults with scoped plan windows and independently distinguishes age expiry, count caps, active pauses and logical/physical cleanup; adds fail-closed PII behavior. Verified late fix: Current paid default row explicitly covers Pro and Max, including Teams. Execution/job logs and task cleanup have no default age expiry; soft-deleted resources use 90 days and previous file versions use 180 days. Free, Enterprise, self-hosted, override, count-cap and cleanup qualifications are preserved. Preserved: Every retention option/APIhours, override inherit/null semantics,3PIIstages/all language/entity/pattern coverage, restore cautions,4unscheduledcron endpoints,PII deployment methods preserved.2functional screenshots remain. | +| [platform/enterprise/forks.mdx](content/docs/platform/enterprise/forks.mdx) | rewritten | Replaced repeated per-resource scenarios with direct-edge model, availability/roles, fork and sync procedures, policy, resource reference, recovery, and troubleshooting. Corrected billing-mode entitlement, no extra rollout prerequisite, membership/Project/personal-key snapshot, drafts/background-copy state, and copied chat deployment requirement. Preserved map/copy precedence, saved versus current-review choices, required dependents, full sync and exclusions, source-deleted archive versus undeploy, canonical folder scopes, and literal-secret caveat. Added trigger URL review, target custom-block mapping, exact preview/fingerprint/request-ID retry rules, applied versus completed receipts and deployment readiness. Preserved lineage-wide forward-only default, copy-arrival checked state, resource/OAuth/secret/KB distinctions, public API flag effects, history/key/memory exclusions and archived-chat suppression. Corrected rollback archive/undeploy, prior-deployment reactivation/pending recovery, copied-resource retention, skipped hard-deletions, and permanent one-sided disconnect/Project subtree split. | Verified improvement. Corrects live-chat, native-target/archive and rollback guarantees, adds actual preview/requestId/followup protocol, trigger adoption and memberships. Preserved: Every resource category, directedge/admin matrix, copy/map/dependent scope, unsynced checkboxes, lineage-wide forward-onlydefault, concrete files/example, connector gap/reconnect, background activity and destructive consequences retained.2screenshots locate clearedrefs and dependent field. | +| [platform/enterprise/usage-tracking.mdx](content/docs/platform/enterprise/usage-tracking.mdx) | rewritten | Ordered owner/admin and entitlement, exact period/credit units, tabs, activity definitions, source attribution/reconciliation, BYOK, export/API and operator configuration. Corrected Export/All events labels, conditional audit-log Open logs link, exact100,000-event cap and four-decimal precision. Resolved legacy mothership_block/visible Agent block attribution to current Sim Chat workflow block; ordinary Agent model calls stay Workflow. Preserved distinct retained Activity metrics/status denominators/first start continuation counting, ownership/history effects, ledger separation, all source rows, nonadditive views, and No workspace attribution. Removed unsupported Chat benchmarking and blanket BYOK non-recording claim; qualified verified workflow-model coverage and separated Logs USD from Billing/run-resource credits. Added organization summary/breakdown/event API links and retained 92-day UI bound, timezone edge bars, current-period consumption versus invoice distinction. | Verified improvement. Corrects ordinaryAgent attribution vs SimChat block label, credits/USD/rounding and invoice distinction; adds actual100000CSVcap and supported org APIs. Preserved: Every metric denominator/duration/retained-history boundary, period/timezone/92days,5tabs/sources/workspace example, own-key exclusion, No workspace, combinedChat surfaces and export columns preserved. | +| [platform/enterprise/whitelabeling.mdx](content/docs/platform/enterprise/whitelabeling.mdx) | rewritten | Ordered organization scope/entitlement, current Save procedure/fields/verification, fallback, instance variables, Helm asset serving and related docs. Corrected external authorized workspace viewers to host-organization branding and removed instant-all-open-tab propagation guarantee. Preserved logo/wordmark formats/5 MiB/64-char limits, loading fallback, four hex colors, email/URL validation, saved-field precedence, and public-surface differences. Preserved every environment variable, billing-disabled default/explicit off, no-organization instance baseline, favicon/custom CSS/background distinctions, brand-detection variables, and files/binaryFiles mount layout. Removed unverified .sidebar CSS selector and described current same-origin CSS/content-policy requirement. | Verified improvement. Corrects scope for authorized external members, refresh/fallback and shell-safe quoted hex examples; separates instance/public UI exceptions. Preserved: Every identity/color/linkfield/5MiB/64character bound, all instance envkeys, favicon/CSS/background distinctions, brandingConfigMap text/binary examples and same-origin CSP restrictions retained. | + +### Search (21) + +| Page or operation | Result | Changes | Final comparison and preservation | +| --- | --- | --- | --- | +| [search/coda.mdx](content/docs/search/coda.mdx) | rewritten | Ordered connection, queries/reads, service boundary, and troubleshooting. Retained separate personal MCP/REST service credentials, Enterprise org-admin requirement, opened-doc picker/manual IDs, exact-doc checks, REST title-only compatibility/email match, read allowlist, URI compatibility, and limited date coverage. | Verified improvement. Moves shortest personal setup before query/access detail; clearly separates personal MCP grant from REST service boundary. Preserved: Both modes, every-reader connection, Superhuman login, fixed read allowlist, both URI schemes, limited recency coverage, legacy title-only/email-match path, token rotation and Enterprise org-admin prerequisite retained. All six troubleshooting intentions remain; primary API links and separate KB REST owner remain. No media existed. | +| [search/confluence.mdx](content/docs/search/confluence.mdx) | rewritten | Moved service-token scopes before service setup while preserving #using-a-service-account for three inbound consumers. Retained Cloud-only adapter, member grants, all thirteen service scopes, spaces/type/label OR behavior, missing-space denial, four-site cap, native cursor, attachment/OCR exclusion, and token/app recovery. Linked canonical Atlassian member OAuth console steps/full scopes while retaining callback, variable names, distribution and saved-configuration/reconnect consequences. Rebase delta: retained staging all-terms overflow relevance ranking, partial/no-cursor result, native-CQL pagination and ranking-failure fallback. | Verified improvement. Moves service scopes before central-source instructions; delegates repeated full OAuth setup to verified canonical owner. Adds accurate upstream relevance-page/no-cursor/fallback behavior without treating provider order as exhaustive. Preserved: Cloud-only and personal-plus-service checks, all13 service scopes, explicit spaces/All/manual keys, labels OR, source status/type/readability, four-sites CQL and attachment/OCR exclusion retained. Original exact callback/environment keys, distribution, read:me/offline_access, provider configuration and reconnect requirements remain locally or in linked Atlassian setup. | +| [search/connect-your-account.mdx](content/docs/search/connect-your-account.mdx) | rewritten | Made connect and verify the first task; grouped provider exceptions and recovery. Retained separate Google grants, personal-vs-service boundary, GitLab identity rules, connection requests not invitations, workflow disconnection consequences, and scope/rate-limit troubleshooting. | Verified improvement. Turns connect into connect-and-verify and names exceptions rather than generic indexing recovery. Preserved: Invitation/SSO/verified identity, popup recovery, not-configured/missing provider, no initial indexing, all seven provider exception rows, separate Google grants, GitLab no-personal connection, reconnect/disconnect shared-workflow consequence and connection-request-not-invitation retained. Generic Secrets Manage secrets label correct; original missing-results checks retained. | +| [search/fireflies.mdx](content/docs/search/fireflies.mdx) | rewritten | Ordered connect, plain keyword/date queries, transcript evidence, and limits. Retained personal MCP vs KB key, fixed endpoint, 255-character query, exclusive meeting-date bound, absent modification times, 49-result lookahead/cursor, stable tool/JSON/scope behavior, ongoing speech snapshot, generated-summary distinction, truncation and failures. | Verified improvement. Uses Connect→queries/dates→evidence order and reduces repeated permission prose. Preserved: Fixed official endpoint/personal OAuth, separate KB key,255character keyword,scope all,dates/exclusive end/no modification time,49meetings+probe,numeric continuation, speaker/timestamp/summary distinction, ongoing snapshot and visible limits retained. Read-only schema/grant checks, plans/quotas and explicit failures retained; no media existed. | +| [search/generic-secrets.mdx](content/docs/search/generic-secrets.mdx) | rewritten | Ordered source mode, use, and removal; clarified names-only discovery and code environment mounting. Retained admin/member editor access, Build/Plan-only mount, selected-mode isolation, same-name organization precedence, and deletion of both secret sets. | Verified improvement. Puts destructive source removal in its own section after usage instead of burying it in the setup paragraph. Preserved: Organization and Member modes, admin/member editor paths and view/use split, mode switch, deletion consequence, names-only mounts through run_code/run_function,org-before-workspace precedence and Build/Plan-only boundary retained. Source is explicitly distinct from documents, provider connections and workspace secrets. | +| [search/github.mdx](content/docs/search/github.mdx) | rewritten | Ordered connection, repository setup, discussion queries, access/changes, and troubleshooting. Retained exact native qualifiers, per-repository App boundary, independent member authorization, default branch/code-only filters, 100-repo discovery, discussion categories/caps/links/review context, provider access freshness, and unsupported hosts. Clarified explicit commits kind; retained #add-a-repository and canonical self-hosted App link. | Verified improvement. Leads with platform/mode boundaries and organizes exact PR query examples before management/troubleshooting. Preserved: Default branch, first100 repositories, explicit scopes, repo-per-App-source, owner approval, personal grant once/org, stable identities/code filters, all four PR query examples, comments/reviews/history caveat,3×50+120000/category and source offsets retained. All seven recovery checks and separate indexed KB link preserved; enterprise hosts excluded and explicit commits kind clarified. | +| [search/gitlab.mdx](content/docs/search/gitlab.mdx) | corrected | Removed the obsolete restored indexed Search exception. Preserved instance-admin vs non-admin CSV strategies, 17.4 admin requirement, PAT scopes, self-managed host protections, every filter, CSV headers/examples/limits/dedupe/conflicts/inherited membership, confidential restrictions and fail-closed authorization. Grouped request access checks separately from current permission updates and PAT rotation, preserving blank-token retention and invalid/stale-update behavior. | Verified improvement. Puts administrator-versus-CSV decision and server requirements before project setup; compresses duplicates without losing its detailed authorization contract. Preserved: Self-managed17.4admin path,read_api/admin_mode,nonadmin alternative,verified email/no personalgrant,all six resource filters, both exact CSV templates and headerless option,4MiB/100000rows/10MiBrequest,dedupe/conflict/grant semantics, confidential exclusion and rotation retained. All seven failure/recovery rows preserved; legacy restoration mention removed because live backend legacy toggle was removed upstream, ordinary KB remains linked. | +| [search/gmail.mdx](content/docs/search/gmail.mdx) | corrected | Corrected reads to matching anchor plus up to seven recent independently authorized conversation messages, with final fresh source checks. Added actual per-message/MIME bounds and notices; retained same-mailbox delegation, active Workspace/customer/user checks, label names/OR, rolling dates/query/category restrictions, message-vs-UI matching and attachment exclusion. Moved common Google member OAuth console/scopes to canonical owner while retaining exact callback, API/variables, separate delegation scopes and reconnect instructions. | Verified improvement. Adds source-backed upstream independently authorized conversation context; points repetitive Google app setup/scopes to complete canonical owner. Preserved: All setup/delegation scopes,primary Users/empty restriction, labels OR/names,rollingwindow,query exact candidate, default exclusions,INBOX same-mailbox example, API/UI differences and attachments exclusion retained. Personal callback/google-email,client vars,broad workflow scopes,reconnect/providerconfiguration and union service-account owner link retained. | +| [search/google-calendar.mdx](content/docs/search/google-calendar.mdx) | rewritten | Ordered connection, service prerequisite/configuration, event details, recovery, and member OAuth. Retained all three service/picker scopes, personal identity and same-member delegation, primary alias/shared-calendar checks, active customer/user restrictions, cancellation/window checks, service ±30-day default, recurrence/timezone/attendee/privacy behavior. Linked common Google member OAuth setup/full scopes; retained callback, API/variables and grant distinction; stated bounded 20-calendar traversal. | Verified improvement. Separates member setup, delegation prerequisites and source-specific restrictions; removes repeated generic OAuth procedure only after canonical owner contains it. Preserved: All three delegation scopes,picker-needs-calendar.readonly,activeDirectory/customer/Users,same-user primaryalias/sharedIDs,30day rolling default,recurrence/timezone/attendees/privateview,attachment/recording exclusion and all five recovery checks retained. Callback/calendar,client vars,broad personal calendar scope and separate grants/reconnect configuration retained. | +| [search/google-drive.mdx](content/docs/search/google-drive.mdx) | corrected | Corrected supported reads to include bounded downloadable PDF/DOCX text; preserved no OCR and metadata-only unsupported binary formats. Preserved Sheet bounds, parser size/page/expanded limits, comment/reply provenance and caps, source checks, selected folders/descendants, six-user verification and external-reader fallback/partial coverage. Retained full service scope/three-source union and saved Meet document distinctions; linked common Google member console/scopes to canonical owner. Added verified Sheets API enablement for member-grant Sheet reads and targeted recovery; preserved shared-service-account inbound anchor. | Verified improvement. Adds verified upstream complete bounded PDF/DOCX extraction and needed Sheets API prerequisite; groups readable content and discussions before service setup. Preserved: Member/service intersection,Docs/Sheets/Slides,text,20sheets1000rows52cols,comment metadata/replies/3×20/120000partial/offsets, no global comment index,all4service scopes,sixusers/fallbackpartial,folderancestry/type,shared-account scopeunion and Meet saved Docs query retained. Original full member OAuth setup/scopes lives in canonical Google owner; exact local callback/vars/reconnect remain. No useful media lost. | +| [search/google-meet.mdx](content/docs/search/google-meet.mdx) | rewritten | Led with recent finalized transcript/note-link purpose and separated reader tasks from self-hosted setup. Retained transcript vs smart-note metadata/no body, explicit kinds/space scope, three-conference/five-artifact cap, unsupported query/date fields, complete-or-fail reads, 30-day retention, transcription prerequisite, and no audio reconstruction. Kept Drive/Calendar alternatives and disconnection consequences; moved full member scopes/consent steps to canonical Google guide and retained API/callback/variables/sensitive-scope prerequisite. | Verified improvement. Adds a purpose/decision opening and clear native field table before transcript scope/retention. Preserved: No service account,exact callback and sensitive member scopes,threeconferences/fiveartifacts,transcript versus smart_notesmetadata,space/projectscope,unsupported filters/exclusive start dates,complete-only attributed reads,30dayretention and Drive/Calendaralternatives retained. Disconnect/shared-workflow consequence,reconnect/approval/window recovery,support email and verification guidance retained. | +| [search/granola.mdx](content/docs/search/granola.mdx) | rewritten | Ordered active-workspace connection, focused query/date behavior, and source evidence/plan limits. Retained official personal endpoint, semantic search, conditional last-30-day/custom listing and UUID scope, no verified continuation, ten-meeting source-note cap, generated answer references, private/summary notes vs transcript quotes, truncation and paid/admin controls. | Verified improvement. Orders setup, query syntax/date options and source evidence cleanly; removes repetition while keeping limits visible. Preserved: Officialendpoint/personalmanagedgrant,activeworkspace,focusedsemanticexamples,presetlast30day/customrange fallback,meetingUUIDcapability,nocontinuation,no inventeddates,10meeting hydration,generatedansweronlyforreferences,notesversustranscripts and plan/admin restrictions retained. Fixed read tools/current schema/grant and explicit formats retained; no media existed. | +| [search/hubspot.mdx](content/docs/search/hubspot.mdx) | rewritten | Separated connection/query/record reads from self-hosted setup and recovery. Retained four CRM kinds/default property lexical search, returned custom properties, no activities/notes/associations, modification dates/cursor, unsupported ownership/pipeline/lifecycle/custom objects/aggregates and read-only access. Preserved dedicated MCP client env vars, exact callback, fixed regional endpoint handling and grant replacement/reconnect consequence. | Verified improvement. Makes setup and native CRM kinds explicit; places dedicated server app/callback in a concrete operator section. Preserved: Fourkinds/all4default,lexical searchableproperty keywords,custompropertyreads/noactivitiesorassociations,modificationdates/continuation/queryless sort,boundedtotals/ownershippipelineunsupported,permissionplanquotas and read-only action boundary retained. Dedicated vars/server/regionalredirect/exactcallback,reconnectregistration and primary setup retained. | +| [search/index.mdx](content/docs/search/index.mdx) | corrected | Reordered purpose, first source, modes, provider catalog, access, and related guides. Qualified catalog availability and Zoom enablement; retained member/service/GitHub/GitLab differences, current checks, provider freshness, invitations, privacy, and KB separation. Replaced agent Assistant language with Sim and retired the legacy-index heading. Final navigation gate: the section overview is linked by the folder index; removed its duplicate explicit child entry from meta.json while retaining all routes and child order. | Verified improvement. Turns long live Search overview into shortest verified start, consistent mode/source tables and distinct access/freshness section. Preserved: All17 provider links/modes,GenericSecrets modes and exclusion,source/account distinction,GitLabexception,serviceintersection,GmailINBOXexample,removal,membership/privateconversations,providerfreshness/partialcoverage and access verification steps retained. CredentialGroups separateworkflowgrant and KB indexing remain explicit; obsolete legacy toggle prose removed under upstream live-only change. | +| [search/jira.mdx](content/docs/search/jira.mdx) | rewritten | Ordered connect, JQL/reads, recovery, and operator setup. Retained Cloud/member-only modes, four-site cap, native site cursor, issue security/app access, bounded comments, no attachment/index path, and broader shared workflow OAuth. Moved complete Atlassian console/scopes to canonical owner while preserving Jira callback/variables, Service Management/Assets scope requirement, distribution and saved-config/reconnect consequences. | Verified improvement. Leads with Cloud-only/personal mode and verification, puts supported JQL/site behavior before recovery. Preserved: Every setup/noindexing/sourcepermission issue,four-sites/nativespecificsitecursor,JQLperquery,commentsbounds/attachmentsexclusion and six troubleshooting rows retained. Exactcallback/vars/fullJiraServiceManagementAssets/read:me/offline_access/Distribution requirements retained in local prerequisite and linked complete owner. | +| [search/linear.mdx](content/docs/search/linear.mdx) | rewritten | Ordered connection/query examples, project/date/pagination controls, and discussion limits. Retained read scope, full-text/vector and comments/archived flags, project UUID vs team/name, modification dates/default relevance, queryless date listing/cursor, 150-comment/120000-character caps, incomplete coverage, unsupported standalone docs/updates and operation-specific 30/minute quota. | Verified improvement. Adds shortest connect-and-search flow and separates projects/dates/pagination from discussion limits. Preserved: Readscope,issuekey/phraseexamples,nativefulltext+vector,comments/archived,projectUUID,date-only/updated sorting/cursor,150comments/120000notice,standaloneproject exclusion and30requests/min retained. All primary schema/filter/pagination links remain, no media existed. | +| [search/lucid.mdx](content/docs/search/lucid.mdx) | rewritten | Ordered connection, title/scoped text search, folders, and structured reads. Retained plan/FedRAMP/account boundary, query requirements and 400/200-character caps, no title continuation/ten candidates, modification-date candidate sorting, folder-page/nonrecursive behavior and native product/document scope. Preserved structured graph/revision complete-read behavior, eight-region/512-KiB cap and Sim-specific rendered/OCR/comments/Lucidscale exclusions despite broader provider tools. | Verified improvement. Adds purpose and separates title/document-text/browse/complete graph paths; distinguishes Sim-supported tools from broader provider server tools. Preserved: Readonlyallplans/FedRAMPexception/noappkey,accountboundary,productkinds,UUID/URLliteraltext,400/200chars/nooperators/10candidates/noquerycursor,modificationpageordering,nestedfolderpaging,no recursive scan/shortcuts and8regions512KiBversion-complete read retained. Images/linksasreferences/OCR/comments/Lucidscale unsupported and primarysetup/accessrules remain. | +| [search/mcp.mdx](content/docs/search/mcp.mdx) | corrected | Added 1–10 batched document reads, independent errors/rate cost, no batch offsets, and individual continuation. Added queryless sort/date listings and explicit browse; retained all schema/response limits, opaque IDs, citations, OAuth/organization access, revocation, and client network prerequisites. Made Codex OAuth login explicit; framed client table as common setups, avoiding an exhaustive list that omitted Devin. Documented four native queries per account and queryIndex-bound cursor continuation from the canonical schema. | Verified improvement. Turns tools/limits into useful tables and adds source-backed batch reads/native multi-query continuation while retaining personal OAuth access. Preserved: Allfiveclientprocedures,scope/opaqueIDs/citationURLs,search/read/chat/privateconversation,topK20/1–50/query2000/readdefault3/cap8/documentID4000/question8192/response1MiB and explicit providererror/partial/retry behavior retained. RevokeAuthorizedapps/existingreturnedcontent,organizationURLscope and separation from workspace/workflow MCP retained; remote client requirements are linked. | +| [search/notion.mdx](content/docs/search/notion.mdx) | rewritten | Ordered personal connection, conditional tools/queries, sidebar browse, and read coverage. Retained separate MCP vs REST, Notion-only filtering, current schema/plan-dependent AI/keyword/page/date support, ten-page timestamp checks/no invented timestamps, recent-view list meaning, conditional pagination and subtree omissions. Qualified authenticated server capability rather than claiming consolidated/new provider filters already supported by Sim. | Verified improvement. Groups current capability discovery and dates before browse/read sections; avoids promising plan-dependent server tools universally. Preserved: PersonalMCPdistinctworkflowREST/notitlefallback,shortfocusedexamples,AIorfallbackkeywords,Notion-onlyresults,pagescopeifadvertised,10readtimestampverify,localdate/noinventedtime/date-onlylimitations,sidebarprivate/shared/favorites/recentvisits and advertisedpagination retained. Fixedreadallowlist/exactfetchcurrentgrant,incompletesubtrees/refine/OpenNotion and primarysetup/tools remain. | +| [search/slack.mdx](content/docs/search/slack.mdx) | rewritten | Led with source grant vs bot connection; ordered source setup, retrieval, bot use, deployment, and recovery. Retained member token/current scopes, DMs/channel/file boundaries, semantic/date sort/cursors, thread/preview/retention behavior, personal membership/invitations, private answers/Stop, generated full manifest and three callbacks, event reachability and app eligibility. Qualified slash commands by installed app availability because handlers are present but generated manifest registration was not independently established. | Verified improvement. Leads with personal source versus bot distinction; qualifies slash command availability rather than promising every installed app exposes them. Preserved: Memberonly/realtime/nochannelindex,ownusergrant,allchannel/DM/fileaccess,semanticsversusdatekeyword/cursor,preview-onlyfiles,botDM/mention/query/connect/Home/Stop/privatechannelanswers and separate source/bot disconnect retained. Generatedmanifestnetwork/publicHTTPS/exactthreecallbacks/fullscope-not-subset/scopedreconnect/eligibility and allsevenrecoverychecks retained. | +| [search/zoom.mdx](content/docs/search/zoom.mdx) | corrected | Added organization/deployment rollout prerequisite, default-off behavior, self-hosted ZOOM_SEARCH and org-targeted AppConfig option; retained non-destructive disable semantics. Ordered connect, occurrence search/reads, dedicated operator OAuth, and disconnect/recovery. Retained UUID vs recurring ID, exclusive meeting dates/cursor/same query, ten-candidate cap, unsupported filters, generated-summary/notes distinction, artifact settings/licenses/processing/access, explicit limits/failures and no recording download/transcription. Kept dedicated General user-managed client/env vars/two scopes/callback/allowlist/endpoint/PKCE/auth method and distribution guidance; attributed 15-minute lifetime to official Meetings API rather than asserting authenticated MCP acceptance. | Verified improvement. Qualifies gated rollout before setup; moves dedicated operator setup after query/evidence behavior and bounds continuation claims to official API evidence. Preserved: Dedicated app/workflowgrant separation,all connection/adminapproval steps,plainquery/actualstart/exclusiveend/UUIDkind,10candidates/noaggregate newest-oldest,transcript/summary/note distinction/noaudioreconstruction,unsupportedfilters and all disconnect/datahandling/recovery steps retained. Readscopes,fixedendpoint/2toolallowlist,PKCE/client_secret_basic,exactcallbackbothfields and internal/external/beta app distribution links remain. | + +### Platform (6) + +| Page or operation | Result | Changes | Final comparison and preservation | +| --- | --- | --- | --- | +| [platform/connected-accounts.mdx](content/docs/platform/connected-accounts.mdx) | rewritten | Reordered availability, Integrations/People/Access setup, runtime references, revocation and troubleshooting. Updated current labels and selected integration-type versus All integrations grants, future integration inclusion, 1,000-workspace bound and migration-review error. Preserved provider prerequisites, verified invitation binding, different provider email, account versus MCP IDs, paging and legacy block replacement. | Verified improvement. Current Integrations/People/Access labels and explicit all-versus-selected integration grants replace obsolete whole-pool allowlist setup. Preserves exposure warning while accurately limiting it to allowed integration types; adds grant ceiling and migration-review recovery. Preserved: Full Slack/Fireflies/Granola/HubSpot/Databricks setup details and Databricks cancellation/secret-preservation/reconnect rules retained. Invitee verification/binding, provider-email distinction, contributor nonmembership, current Chat scope, in-flight consequences, exact Find cardinality, 100-item paging and legacy block migration remain. | +| [platform/costs.mdx](content/docs/platform/costs.mdx) | rewritten | Renamed to Credits, billing and limits; scoped defaults to Cloud and separated billing-disabled configuration. Retained credit conversion, run/model/tool/sandbox costs, all unusual hosted-tool units, BYOK scopes/inheritance/rotation/lapse, allowances/annual arithmetic, refresh, balances, caps, overage, threshold, concurrency/storage/duration and monitoring. Corrected Parallel search mode and Distance Matrix units; added TypeSafe, Nebius, Kie and TinyFish. Replaced obsolete Model Breakdown with current Overview ledger rows, total and available tokens. Removed fixed 1.1x, unsupported self-service purchase procedure/terms and unverified deployed-voice pricing. Qualified legacy usage helper as account/key-owner USD with storage; linked v2 Billing Status and retained Logs USD versus Billing/run credits. Preserved bring-your-own-key-byok, concurrent-executions and run-time-limits anchors. Used shared authored tabs with padded mixed content, wrapped prose, visible horizontal scrolling, and mobile touch targets. | Verified improvement. Scopes credits to billable Cloud/UI units and distinguishes USD Logs contracts; adds sandbox/base-child-charge policy and separate block/provider limits. Corrects current hosted-tool pricing modes, per-element Distance Matrix pricing, API payer versus workspace account, billing-disabled enforcement and unsupported purchased-credit/deployed-voice procedures. Replaces asserted Max workspace cap with live controls/pricing qualification; strengthens BYOK per-provider exclusive pool/actor scope and organization lapse consequences. Preserved: Every original hosted-tool rate category and BYOK provider catalog retained with new providers; tables replace long one-provider tab set without deleting pricing detail. Preserves monthly/annual rates, weekly refresh arithmetic, seat pooling, on-demand/spend controls, threshold example, concurrency/rate/storage/runtime tables, key encryption/rotation/deletion and Pi exposure warning. Formula retained with correctly named USD/credits components and sandbox term. Legacy usage endpoint/auth/units/rate field meanings remain; recommended v2 monitoring has direct API-owner links. Removed obsolete model-breakdown screenshot and unsupported checkout/deployed-voice claims; retained concrete billing math and threshold examples. | +| [platform/credentials.mdx](content/docs/platform/credentials.mdx) | rewritten | Reordered scope/grants/management, syntax/runtime identity, Details/Visibility/usage, complete canonical protection algorithm, Chat mounting and headless policies. Preserved every distinct original log/span/model projection boundary, real functional store/response/stream/callback distinction, exact case-sensitive match, scanner forms and false positives/negatives, injected binding non-persistence, transformed/fragmented/network limits, Unredacted public-link/future-log/equal-value conflict, usage and trigger actor rules. Clarified personal ownership/no admin inheritance/current writer restriction versus existing active grant resolution. Retained useful masked editor and corrected picker source/alt; removed obsolete personal details and redundant inserted-reference image. Replaced Copilot and saved-task modal wording with Chat/Sim, current Sim Chat and Inbox policies and deployed schedules. Integrated unique FAQ answers and added source-current Logs-versus-References usage views; retained execution-log-protection anchor. | Verified improvement. Corrects workspace use/reveal grants, personal-secret non-inheritance and existing grant nuance; organizes runtime identity and protection into explicit actor/surface boundaries. Replaces unsupported Scheduled Tasks secret-modal claim with current workflow Schedule setup; adds References versus recorded usage distinction. Preserved: Full .env parser forms, inline save/delete consequences, namespace precedence, all original direct-read languages and recognition exceptions, exact/transformed protection limits, opt-out disclosure and future-run effects remain. Owner departure/suspension and unauthenticated public execution retain explicit personal-namespace consequences. All useful FAQ answers are folded into management/resolution/protection sections. Kept Secrets editor and reference-picker captures; viewed secret-resolved.png independently and current alt accurately names the open picker. Removed duplicate dropdown/detail screenshots without claiming them stale. | +| [platform/organization.mdx](content/docs/platform/organization.mdx) | rewritten | Removed nonexistent folder colors and five hypothetical visual TODOs. Added concrete named tree and source-current Create folder/Rename/Lock/Delete actions. Retained drag order/reparent, Admin lock authority/inheritance and otherwise authorized execution while locked. Corrected Archive to Delete/Recently deleted and effective retention. Distinguished navigation/naming from workspace access and ownership. | Verified improvement. Replaces unsupported folder archiving/color instructions with current delete/recovery controls, Admin lock access and inherited-lock behavior. Task order uses concrete naming/nesting and drag examples without placeholder visual comments or decorative cards. Preserved: Retains shallow hierarchy, category/action names, ordering, drag-to-nest, lock scope, and folder-versus-workspace choice. Original color instructions are not useful current controls: folder item has no color handler; current menu supplies create/rename/duplicate/export/delete/lock. No real media was removed; original VISUAL comments were placeholders. | +| [platform/permissions.mdx](content/docs/platform/permissions.mdx) | rewritten | Consolidated repeated role tables/lists/scenarios and11 FAQs into an authority and membership lifecycle guide. Separated Read deployed API execution, Write manual Run/edit/delete and Admin deploy, with per-secret authority. Corrected organization-only membership versus workspace grants and current invitation labels. Preserved seat/eligibility/combined pending invite/scoped revoke/accept preview/owned workspace migration/removal consequences with billing-mode scope. Clarified fixed Owner, inherited organization administrator removal protection and protected billing-account fallback. Documented human permission-group empty inherit versus explicit/SCIM behavior and independent workspace-key operation policy. | Verified improvement. Separates draft Write from deployed API Read role floor; replaces blanket Write secret-management and inherited-personal access statements with resource grant rules. Distinguishes organization-only invitations, workspace grants, billing mode, one-org membership, and explicit/inheritance-mode groups. Preserved: Preserves locked inherited roles, three levels of authority, seats/external eligibility, invitation merging/scoped revocation, archived workspace migration, owner removal fallback, credential access and member-removal consequences. Detailed duplicated role bullets become a role/action matrix; meaningful FAQ consequences are retained under joining/removal/credential/group sections. Remote invitation video was removed because the full labeled procedure now covers it; no stale-media claim. Joining-an-organization and credential-access anchors remain; plan limits moved to linked Costs owner that contains those limits and their live configuration qualification. | +| [platform/workspaces.mdx](content/docs/platform/workspaces.mdx) | rewritten | Replaced repeated resource subsections with linked resource inventory and workspace decision. Separated integration tools from credential connections/grants and Owner from permission tiers. Corrected authorized workspace switching versus relocation, personal ownership and billing-mode creation rules. Retained draft/deployed/promotion/rollback and explicit sharing boundaries. Removed hypothetical visuals/Scheduled Tasks and unsupported customer handoff ownership claim. Reordered platform/meta.json: workspaces, organization, permissions, credentials, connected-accounts, costs; slugs unchanged. | Verified improvement. Separates workspace roles, credential grants, organization ownership, deployments and explicit sharing. Corrects owner to fixed Admin, personal-secret non-inheritance, archived-workspace joining consequence and billing-disabled scope. Preserved: Retains every resource category, three workspace roles, personal/organization distinction, internal/external joining consequences, and deployment promotion/rollback. Reference links replace decorative cards and placeholder visuals while keeping owners for membership/limits/credentials. | + +### Enterprise identity (9) + +| Page or operation | Result | Changes | Final comparison and preservation | +| --- | --- | --- | --- | +| [platform/enterprise/index.mdx](content/docs/platform/enterprise/index.mdx) | rewritten | Task-oriented feature directory; Cloud and billing-disabled self-hosted scope made explicit. Detailed invitation-disabled setup moved to self-hosted enterprise. | Verified improvement. Separates Cloud subscription from billing-disabled self-hosted flags and organization-owned workspace requirements. Preserved: All enterprise capabilities and shortest navigation retained; administrator-key details moved to linked self-hosted guide, which includes requests and actor requirements. | +| [platform/enterprise/self-hosted.mdx](content/docs/platform/enterprise/self-hosted.mdx) | rewritten | Operator order: enable flags, choose organization model, verify, schedules and reference. Backfill specifies an existing owner account; Admin API key configured on application and caller. Workspace move includes fresh UUID operationId, same-ID retries, progress read and follow-up inspection. Corrected in-process data drains and direct SCIM cron; added SCIM schedule. Preserved all feature flags/defaults, organization APIs, invitation-disabled behavior, retention opt-in/schedules, Sandbox readiness and local Node worker scope. Used shared authored tabs with padded mixed content, wrapped prose, visible horizontal scrolling, and mobile touch targets. | Verified improvement. Corrects missing application-side admin-secret setup, required idempotent workspace move operationId and follow-up state; backfill owner prerequisites now explicit. Preserved: Every feature flag/browser twin, inherited defaults, organization models, API/SQL/curl examples, deletion consequences, sandbox readiness, inline jobs and separately scheduled retention preserved and corrected. | +| [platform/enterprise/sso.mdx](content/docs/platform/enterprise/sso.mdx) | rewritten | Removed redundant FAQ component; folded access, linking, owner recovery, offboarding and editing into visible sections. Kept all five protocol/provider guides, exact fields, callback formats, advanced options, flags and scripts. Updated current Okta/Google paths, globally unique provider examples and conditional provider-switch behavior. Added script organization binding/existing-account/DB prerequisites, direct-registration trust and one-provider deregistration ID. Replaced issuer-origin authenticity implication with matching-issuer launch constraint. Used shared authored tabs with padded mixed content, wrapped prose, visible horizontal scrolling, and mobile touch targets. Preserved the five provider anchors on native tab panels; bookmarked provider links select their tab without duplicate headings. | Verified improvement. Places provider setup before verify, then membership/linking and recovery; corrects source registration organization binding and all-provider deletion hazard. Preserved: All5 full provider configurations and URLs retained; global ID, issuer/claim mapping, callback override, discovery, existing account linking, seats/invitations/external grants, owner recovery, unsolicited SAML refusal, primary/test/provider switching and self-hosted scripts retained. OIDC form screenshot removed; every visible field and control remains explained in text/tables. | +| [platform/enterprise/scim/index.mdx](content/docs/platform/enterprise/scim/index.mdx) | rewritten | Defined SCIM and split prerequisites from normal behavior. Folded all eight FAQ answers into lifecycle, identity matching, seats, managed access, disable/recovery and deployment sections. Kept suspension/removal/session/key/seat ownership distinctions and permanent explicit permission-group membership; empty mapped groups apply to nobody. Reduced duplicated Okta/Entra setup to guide links and exact credential/lifecycle distinctions; retained OneLogin/JumpCloud setup. Corrected scheduler dependency; preserved rollout/rollback and 0325 baseline warning, protocol filters and limits. SCIM metadata title/order reviewed and retained unchanged. Used shared authored tabs with padded mixed content, wrapped prose, visible horizontal scrolling, and mobile touch targets. | Verified improvement. Provides exact decimal byte limit and a direct SCIM cron route independent of Trigger.dev; lifecycle, grants and rollout warnings precede consequences. Preserved: All4 provider configurations, complete protocol/filter/resource/attribute rules, token overlap, member seats/owner conflicts, managed baseline, explicit permission membership, JIT override, disable recovery and migration warning preserved. Provisioning screenshot removed with controls and procedure fully described. | +| [platform/enterprise/scim/okta.mdx](content/docs/platform/enterprise/scim/okta.mdx) | rewritten | Current creation-experience table and official custom-app route separated from evaluation-only Header Auth Test App recipe. Qualified first-party production policy conflict without claiming OIN publication/certification. Preserved Bearer prefix mismatch, password exclusion, account/group lifecycle tests, assignment-vs-push group distinction, offboarding order, token rotation and troubleshooting. | Verified improvement. Corrects Classic-only OIDC limitation, differentiates newer wizard support, evaluation templates and supported custom production setup. Preserved: All3 meaningful screenshots preserved and freshly visually inspected. Full header syntax, custom field differences, verified-domain usernames, user+group lifecycle tests, separate assignment/push groups, offboarding order,2-token overlap and troubleshooting retained. | +| [platform/enterprise/scim/entra.mdx](content/docs/platform/enterprise/scim/entra.mdx) | rewritten | Numbered account and group verification procedures; user/group naming kept scoped. Converted soft-delete/permanent-delete/unassignment distinction to lifecycle table. Retained current/legacy UI, Free/P1 licensing, UPN/work-mail fallback, five-member on-demand limit, scheduled-only disable/delete tests, normal cycle timing, watermark resets, token rotation and troubleshooting. | Verified improvement. Separates deactivation from permanent organization removal and orders connection, test assignment, lifecycle, group access and scheduled cycles. Preserved: All3 screenshots retained, scope screenshot freshly inspected. Fields, mappings, Free/P1 distinctions,40-minute cycles,30-day permanent deletion, on-demand5, token rotation, watermark restart and troubleshooting retained. | +| [platform/enterprise/verified-domains.mdx](content/docs/platform/enterprise/verified-domains.mdx) | rewritten | Moved removal and migration FAQ details into visible sections; removed duplicated prerequisite and FAQ headings. Kept exact TXT host/value, zone suffix pitfall, propagation/persistent verification, one-org/subdomain scope, public DNS endpoints/ports, bypass trust and recovery, image/chart/digest requirements. | Verified improvement. Puts domain authority and bypass trust consequences before DNS/verification actions; limits deletion to future sign-in. Preserved: TXT host/value, subdomain independence, uniqueness, migrated trust, public DNS resolvers, restricted-network bypass, chart image precedence, Cloud exception and all troubleshooting retained. | +| [platform/enterprise/security.mdx](content/docs/platform/enterprise/security.mdx) | rewritten | Made session-policies page canonical for controls/defaults; retained concise navigation. Converted outbound coverage/exclusions to table without expanding support; kept fail-closed behavior and allowlist-every-address requirement. | Verified improvement. Session, revocation, dedicated egress and PII actions consolidated into task-first rows, with defaults and failures scoped. Preserved: All security policy ranges/defaults and Save/Discard behavior retained in linked Session policies; dedicated HTTPS IPv4 port443 and unsupported egress surfaces remain. | +| [platform/enterprise/session-policies.mdx](content/docs/platform/enterprise/session-policies.mdx) | rewritten | Moved all FAQ facts into settings, enforcement and revocation sections. Added Save/Discard, integer ranges and distinction between optional limits and default sliding expiry. Qualified policy loosening as no immediate expiry extension; later refresh/new sign-in applies current policy. Clarified current-session exemption and caller’s other-device revocation; kept API/workflow exclusions. Qualified pending-edit claim to already synced changes. | Verified improvement. Clarifies refreshed policy limits, tighter versus looser expiry, and preserved current session. Preserved: 1–8760h max and48–8760h idle,30day/24hour defaults, one-minute policy caching, unsynced work warning and save/discard steps retained. | + +### Orientation (6) + +| Page or operation | Result | Changes | Final comparison and preservation | +| --- | --- | --- | --- | +| [index.mdx](content/docs/index.mdx) | corrected | Replaced duplicate card overview with canonical Introduction/Getting started pointer and redirect stub. Retained routing behavior; root owns source/LLM handling. | Verified improvement. Removes duplicate narrative from a redirect-only URL and sends readers to the actual introduction/tutorial owners. Preserved: Original build modes/models/integrations/resource and permission concepts are retained in Introduction and the linked topic/navigation owners; no operational example existed here. No media/FAQ lost; page path and redirect destination remain. | +| [introduction/index.mdx](content/docs/introduction/index.mdx) | rewritten | Reorganized into build-method table, workspace-resource table, models/integrations, deployment choices, and related docs. Qualified Chat availability and local-model network requirements; scoped MCP to server-exposed tools. Folded licensing and self-hosting FAQ facts into deployment section; removed promotional repetition and comparison superlatives. | Verified improvement. Organizes methods/resources/models/deployment choices into concise useful tables; removes sidebar-anatomy and fastest/clearest/all-model claims. Qualifies Chat/network/local models and MCP-exposed tools rather than promising offline or arbitrary-service universals. Preserved: Visual/Chat/API methods, mixed authoring, resources and four application domains preserved in method/resource/integration prose. Removed exhaustive provider list delegated to actual integration catalog; installed platform/source license facts and Docker/Kubernetes/local model facts remain. Removed image/video generic builder examples add no unique prerequisite; two FAQs folded into deployment/license section. | +| [getting-started/index.mdx](content/docs/getting-started/index.mdx) | rewritten | Added workspace/model/tool prerequisites and scoped hosted-vs-own credential explanation. Made seven-step tutorial runnable: create/rename workflow, add/connect Agent, exact System/User messages, configure search tools, locate workflow test chat, inspect run, configure and verify schema. Replaced fictional answer-bearing test profiles with an identifiable research prompt and source inspection. Included complete person JSON schema and updated System prompt; root output references match schema fields. Removed hard-coded model/time claims, prevalence claims, internal metrics comment, and stale Gmail screenshot; kept concrete recovery steps. | Verified improvement. Runnable seven-step guide adds permission/model/tool prerequisites, connection checks, exact Messages, tool setup and genuine research prompt. Adds complete schema, root output references, logs verification and malformed JSON fallback; replaces answer-bearing fictional profiles and unsupported default/time claims. Preserved: Start→Agent people research, Exa/Linkup tools, content test, generated-or-manual structured schema, downstream location/profession/education and missing-key/reference recovery retained. Removed videos/screenshots are replaced by complete named controls and copyable schema/prompt; original warnings have a concrete recovery section. | +| [desktop/index.mdx](content/docs/desktop/index.mdx) | rewritten | Reordered download/requirements before installation, then capability/privacy guidance, current settings, shortcuts, and updates. Qualified installer cache/version/feed behavior and signing; preserved universal build, macOS 12, Applications eligibility, separate browser/app sessions, certificate rejection, GitHub requirements, notification exclusions, updater modes and fallback. Corrected optional launch at login and enabled Browser/Terminal defaults. Documented Full file access off, prevent-sleep on, Passwords and Google search-suggestion transmission. Scoped read-only to selected-folder filesystem tools; described import/browser staging and separate OS-user shell privileges with conditional approval behavior. Retained #keyboard-shortcuts and added accurate focused-terminal Cmd+R/focused-browser Cmd+L distinctions. Added deployment/device-gated native Mac app control: macOS 14, per-Mac off default, exact legacy UI label, manual Accessibility/Screen Recording setup, per-app grants, and foreground/compatibility limits. Documented conditional Stop shortcut, inability to undo delivered app input, Revoke/Off, sign-out/deployment reset, protected permission surfaces, and possible screenshot/content transmission. | Verified improvement. Moves requirements/server choice before sign-in; qualifies updater selection/caching/signing. Corrects launch-at-login and browser/terminal defaults, local file import/staging/transmission, shell permissions and grants. Accurately adds gated macOS 14 native control alongside macOS 12 general app minimum. Preserved: All original installation/session/download/custom-origin/GitHub/TLS requirements, notifications exclusions, Control Center, shortcuts/settings and updater/manual/fallback behaviors retained. Inspected browser screenshot retained; meaningful Applications/privacy callouts remain; removed always-newest/no-file-staging claims are contradicted by owners. | +| [quick-reference/index.mdx](content/docs/quick-reference/index.mdx) | rewritten | Replaced eight HTML Preview tables with plain two-column Task/How Markdown tables. Preserved 59 supported prior action intentions; removed only unavailable handle orientation. Corrected import/invite/run/rename/manual-selector/test-chat/Logs-output/version/secret locations and labels. Added admin, partial-run, singleton, draft/live and export-sharing boundaries where needed. Uses browser find for text lookup; no new runtime search component. Removed all ActionMedia usages and imports; root owns shared component/asset cleanup. | Verified improvement. Replaces 3-column media tables with readable Task/How lookup retaining supported operations and correcting labels. Adds Admin/lock/singleton/partial-run/draft-live/export scopes where needed. Preserved: All 59 supported original action intentions retained across workspace/workflow/folders/blocks/connections/panels/run-inspect/deployment/variables. Removed Toggle Handles has no exposed current menu action; retained undo infrastructure does not prove a user control exists. Removed 49 media instances contain no unique action requirement missing from corresponding text; Mod meaning and full shortcuts link remain. | +| [keyboard-shortcuts/index.mdx](content/docs/keyboard-shortcuts/index.mdx) | rewritten | Reordered workspace navigation before workflow actions/pointer controls and table groups. Corrected add-Agent block scope, Sim change acceptance name, workflow-console scope and editable-field caveats. Preserved existing keyboard/pointer actions and table shortcuts; added current select-all, fill-down and table find controls. Qualified Shift+Enter required-field form, boolean Enter/F2 behavior, row editor, table permissions and locks. Preserved /desktop#keyboard-shortcuts links. | Verified improvement. Groups workspace navigation before builder/table surfaces; distinguishes focused/editable-field scope. Corrects adding Agent block, Sim change terminology and workflow console, and adds real table find/select-all/fill-down/form/boolean behavior. Preserved: Every original keyboard/pointer action intention retained; Desktop #keyboard-shortcuts link preserved. Mod callout folded into opening; tables are compact scoped groups without generic warning repetition. | + +### Chat (8) + +| Page or operation | Result | Changes | Final comparison and preservation | +| --- | --- | --- | --- | +| [chat/files.mdx](content/docs/chat/files.mdx) | rewritten | Separated chat-private attachments, saved workspace Files, and temporary workbench outputs/SIM_OUTPUT_DIR. Corrected Attach file control, supported-reader boundary, ZIP extraction, watched text versus generated binary outputs, and type-dependent viewer modes. Preserved distinct document/CSV/code/digest/postmortem/email, PPTX, image reference, chart/diagram and calculation examples; named binary formats with availability qualification. Preserved deliberate private uploads; qualified stored-file model reads/previews/share links and withheld mounts that prevent code execution. | Verified improvement. Fixes contradictory automatic workspace-save claim; separates private uploads, saved Files, temporary workbench and model preview admission. Keeps generation examples concrete and format support qualified; adds blocked requested mounts without claiming every known-secret byte cannot enter code. Preserved: All four attachment processing examples, six text deliverables, five presentation scenarios, banner/reference/social image examples, three charts, JSON/p95/timestamp/dedup computations retained. Diagram generation/reference variation moved into chart/diagram section; FAQ workflow reuse/types/calculations folded into body. Removed example screenshots/videos contain no unique required parameter or procedure omitted from the written tasks. | +| [chat/index.mdx](content/docs/chat/index.mdx) | rewritten | Replaced promotional introduction with capabilities, New chat/Build/Search/Plan instructions, scope, resources and progress controls. Added Mailer navigation and corrected recurring work, generic delegation, per-chat queue/Send now, tool approval and configured runtime/usage limits. Qualified Plan by deployment capability and effective platform administrator with Super admin mode; distinguished organization Admin and organization Build workspace-creation permission. Added loaded-message Find controls, progressive older history/failure boundary, 500-match limit, and native activity/Stop link to canonical Desktop procedure. Qualified Chat model delivery separately from access and tool approval: stored content can be masked or withheld. | Verified improvement. Replaces command-center/no-configuration/universal workspace/hour-limit promises with actual start/mode/access steps. Adds scoped Plan, org Build, queue/Send now, Find windows/cap and content gate without promising rollout. Preserved: All original task categories, named workflow/table prompts, four substantial build/research/recurring/contract examples, +/@/drag contexts and resizable/draggable/closeable panel facts retained. FAQ scope/runtime/queue/context information now lives beside relevant tasks; remote videos/TODOs removed with complete text controls. | +| [chat/knowledge.mdx](content/docs/chat/knowledge.mdx) | rewritten | Organized create, ingest/process, search, sync, workflow retrieval/ingestion, management. Preserved PDF/text/URL/multiple-document requests, source categories and inventory/removal examples. Corrected completed+enabled processing requirement, guarded source removal, explicit retrieval configuration and Knowledge Create/Upsert Document names. Added restricted private knowledge graphs in organization settings, exact New graph/Create and activate/Make active controls, personal organization scope, reserved Default/name limit, and new-chat versus existing-chat bindings. Qualified masked or omitted indexed documents/passages/tag values without changing ordinary workflow retrieval or UI access. | Verified improvement. Corrects immediate availability, universal workflow access and every-run connector deletion assertions. Adds concrete retrieval/write paths, processing verification, current private graph gate and Chat per-item admission. Preserved: Every create/ingest/search/manage example intention and all source categories retained. FAQ supported formats, workflow attachment and programmatic writes folded into processing and workflow section using actual Knowledge Create/Upsert Document names. Remote generic KB video/TODO removed; no unique setup fact lost. | +| [chat/mailer.mdx](content/docs/chat/mailer.mdx) | rewritten | Moved Cloud Max/Enterprise active billing and workspace Admin prerequisites before setup; qualified self-hosted availability without inventing the hosted email domain. Added member-role/external read-only/raw-secret boundaries, default All secrets and Selected secrets controls, and noninteractive execution. Preserved prefix/address replacement, sender labels, attachments/email examples, 10 MiB hard limit, statuses, failed/complete navigation and thread continuation. Corrected completed-agent-work versus delivered-reply receipt, partial attachment failure, displayed body-preview search and same-workspace live conversation condition. | Verified improvement. Adds Admin/plan/services/member-versus-email-only access prerequisites before enabling inbox. Corrects attachment failure handling, search preview scope, completed-versus-email-delivery and same-workspace continuation. Preserved: Three email examples, generated/custom prefix, address replacement, allowed senders, status lifecycle, continue-in-Chat and 10 MiB attachment fact retained. Only meaningful address-replacement Callout retained; domain FAQ folded into displayed deployment address instruction. | +| [chat/research.mdx](content/docs/chat/research.mdx) | rewritten | Organized focused questions, saved reports, then source access/freshness. Preserved every distinct company/market/technical/release/authentication/compliance/battle-card scenario while removing exhaustive-completeness promises. Kept public hosted access, Desktop signed-in browser, workspace Files output, current-source dates/citations and connected-source permissions. | Verified improvement. Turns any/every/full-report promises into scoped research, citations/date checks and explicit unknown evidence. Moves complete FAQ access/freshness/saved report facts into source-access and report sections. Preserved: All seven original question domains and five saved-report scenarios preserved, including releases, company hiring, competitive market, auth, compliance and battle card. Saved Files/resource panel/slide reuse and Desktop signed-in browser remain qualified by tool availability; remote decorative video/TODO removed. | +| [chat/tables.mdx](content/docs/chat/tables.mdx) | rewritten | Organized create/import, query/compute, row mutation/deletion, export, workflow configuration. Preserved schema/CSV/errors/prospects/enrichment, count/range/error-frequency/duplicates/fit/conversion, bulk-update and filtered/full export scenarios. Corrected createdAt system field, table selection requirement, nonpersistent combination of multiple tables, export completion and access/limit distinctions. Qualified admitted row/selection completeness, database totals/cursors, CSV completeness, and committed writes with withheld returned rows. | Verified improvement. Corrects table-name-only workflow configuration claim and system timestamp syntax. Adds per-row admission versus DB totals/cursors, incomplete generated CSV warning and committed write-withheld-result consequence. Preserved: Five table creation, six queries, single/bulk write, delete/full-filtered export, and multi-table combination/plan-limits FAQ facts retained. Original screenshot summary intent remains covered by query/summary prose; no schema/mutation input lost. | +| [chat/tasks.mdx](content/docs/chat/tasks.mdx) | rewritten | Rewrote obsolete saved-prompt cron Jobs as deployed workflows with Schedule triggers; preserved all daily/weekly/monthly/hourly funding/prospect/error/report use cases and relevant log/manage outcomes. Separated one-time watches/timers from recurring workflows, including 24-hour timer maximum and stop-watch versus workflow cancellation. Preserved Slack/email/GitHub/HubSpot/HTTP actions, account setup/ownership, secrets syntax/scope, MCP server lifecycle and distinct custom-tool scenarios. Added configured approval/results, real external effects, schedule activation/redeployment/timezone, service-specific Google scopes and current Chat server attachment. Added inspect-before-retry consequence when an external action finishes but its returned result is withheld. | Verified improvement. Replaces obsolete saved-prompt Jobs with deployed Schedule workflows while preserving recurring task intentions. Separates timers/watches from recurring work, acting credential scope, service-specific authorization and settled result versus external action. Preserved: All seven daily/weekly/six-hour/monthly/funding/enrichment/error scenarios and log/change/stop tasks preserved through supported schedule model. Five direct service actions, Google/Slack/GitHub connections, all secret names/references, MCP add/update/list/remove and four custom-tool examples retained. FAQ external undo, account inventory and ENV syntax folded into owners; obsolete Jobs video and TODO/callout repetition removed. | +| [chat/workflows.mdx](content/docs/chat/workflows.mdx) | rewritten | Reordered creation, draft edits/variables, running/logs/debugging, deployment/restoration, and organization/deletion. Preserved all distinct workflow scenarios, exact variable syntax, input examples, logs, API key creation, nested folder moves and deletion consequences. Corrected configured endpoint host, adding an MCP tool to a server, draft versus active state, rollback versus restore, and live/background evidence. | Verified improvement. Clarifies draft versus deployment, explicit run source, access, external-effect testing and successful serving verification. Separates restoring draft from rolling live deployment and corrects MCP workflow tool deployment. Preserved: Five creation, three edit, three run, three log, two debug, variable, API/chat/MCP deploy, rollback, folder/move/rename/delete intentions retained. All three FAQ effects folded into their lifecycle sections; old generic motion embeds/TODOs removed without missing a required control. | + +### API guides (5) + +| Page or operation | Result | Changes | Final comparison and preservation | +| --- | --- | --- | --- | +| [api-reference/authentication.mdx](content/docs/api-reference/authentication.mdx) | rewritten | Separated credential identity/current access from workspace-key management and operation policies; retained workspace payer/member attribution and personal/OAuth restrictions. Retained verified one-time key display/create/revoke instructions and exact Sim API keys label; qualified encryption and modern/legacy prefixes by API_ENCRYPTION_KEY. Kept API-key versus OAuth headers, scope table, method-independent scopes, account grant versus login revocation and API-key logout caveat. Replaced duplicate three-language request with curl and canonical Getting started/SDK links; folded repeated credential-safety text. | Verified improvement. Distinguishes acting identity, current role/policy, operation-specific workspace-key access, and payer instead of the baseline vague permissions table. Corrects API-key Bearer misuse, optional encryption/legacy prefix, OAuth scope/grant and logout behavior; removes duplicate HTTP language samples while linking complete versions. Preserved: Retains key creation/revocation/one-time display, X-API-Key, server-side credentials, modern prefix and OAuth scopes. Complete HTTP examples still exist in Getting started; OAuth/profile detail remains in CLI authentication. | +| [api-reference/getting-started.mdx](content/docs/api-reference/getting-started.mdx) | rewritten | Separated Cloud/self-host origins, active deployment prerequisites, manual draft access, HTTP result versus in-band run failures, and request versus execution rate policies. Added checked env-backed direct requests, all current wait/terminal/pause states, async mode compatibility and client/server timeout distinction. Preserved one-shot X-Run-Id409 behavior and uncertain-run reconciliation; fixed pagination with required workspaceId and URL-encoded returned cursor. Preserved resource/list/error shapes, strict undeclared-field behavior and validation details while distinguishing OAuth401, usage402, conflict409 and USD/credits. Kept substantial first-call Steps/language Tabs; removed routine status/billing callouts. API navigation moves advanced workflow-sync after SDKs under API guides. Used shared authored tabs with padded mixed content, wrapped prose, visible horizontal scrolling, and mobile touch targets. | Verified improvement. Examples now define environment prerequisites and handle HTTP and in-band run failures; manual draft execution is distinguished from the active deployment. Explains actual status/pause/redaction, async option compatibility, one-shot run-ID recovery, endpoint-specific units, and bound cursor queries. Preserved: Retains origin/OpenAPI URL, API-key creation, ID lookup, deployment, three HTTP languages, async run/status URL, envelopes, strict unknown-field validation, pagination and Retry-After. | +| [api-reference/python.mdx](content/docs/api-reference/python.mdx) | rewritten | Retained every public method signature/default and complete return-field reference, added forced-sync method and missing retry timeout parameter. Replaced repeated Quick Start/Basic/Steps/env tabs with env-backed context manager; retained sequential multiple-workflow, file-like upload, async polling, retry/status/usage examples. Explained Python failed result versus exception, completed/paused/cancelled states, metadata units and unset logs/traces; preserved 0.2.x migration and mixed legacy/v2 helpers. Fixed usage requestsPerMinute/maxBurst fields and account/key-owner USD scope; Python storage omission explicit; corrected v2 reset milliseconds with legacy-unit caveat. Replaced broken SDK streaming example and done-event parser with raw HTTP SSE inspection and canonical framing/forwarding instructions; preserved Flask backend authentication, event preservation, status/timeout/cleanup concerns. Added redacting to polling and local wait deadline, distinguished client/server timeouts, output selectors, run fields/files/permissions and opaque large-value references. | Verified improvement. Replaces the misleading async/streaming/readiness claims with blocking HTTP, SDK-vs-HTTP streaming limits and failed/paused/cancelled result behavior. Keeps full method and return reference while consolidating repeated examples; corrects retry/reset units and usage shape. Preserved: Retains Python/requests requirements, context management/close, method options/defaults, types, baseURL, file inputs, async polling, retry, usage helpers and Apache-2.0 link. Legacy status/jobs and SDK migration remain explicit; runnable examples replace duplicate/incorrect samples. | +| [api-reference/typescript.mdx](content/docs/api-reference/typescript.mdx) | rewritten | Retained all public method signatures/options and complete declared/runtime return fields, added forced-sync convenience and LargeValueRef/legacyJob status distinctions. Used Bun install and Node18+ ESM requirement, scoped automatic globalFile conversion to Node20+, fixed Buffer-to-BlobPart typing using Uint8Array. Explained failed-run rejection versus cancelled/paused resolution and exact-state run lookup; async polling waits through runtime redacting without widening SDK types. Fixed legacy USD usage fields/storage, v2 reset-millisecond example, client wait versus server cap, rate-only retries and unsafe-retry recovery. Replaced broken SDK streaming and stale done-frame example with raw HTTP stream, terminal/reset handling, chunk boundaries and canonical protocol client links. Folded duplicate initialization/Steps/environment tabs into one setup, preserved backend helper and Express/Next.js POST/auth/input-size/status responsibilities; retained file formats and actual upload example. | Verified improvement. Corrects Node minimum/global File availability, failed-run rejection, paused success, absent synchronous status, unsupported SDK streaming, and timeout-without-abort. Preserves complete declarations and options while reducing repeated implementations; corrects retries/usage/reset units and shows HTTP framing. Preserved: Retains constructor and methods, options/defaults, types, setter/helpers, file and URL objects, server/backend authorization, async polling, retry, usage, legacy compatibility and license link. | +| [api-reference/workflow-sync.mdx](content/docs/api-reference/workflow-sync.mdx) | rewritten | Reorganized prerequisites/import/fork/sync/verification/recovery and moved advanced navigation; retained every command/endpoint relationship and scope/role distinction. Made billing-enabled Enterprise versus billing-disabled deployment gate explicit; qualified export sanitization and kept unresolved env values/provenance non-authority. Retained source kind mappings, flat occurrence bindings/encodings/positions, null/required binding rules, dependentValues and selector scope/context/partial/restart bounds. Preserved fork drafts/explicit copies, push/pull direction/direct edge, mapping read/write projection, omitted/replaced/cleared saved choices and trigger URL adoption. Preserved request-ID/fingerprint apply commands, atomic import/idMap/plain-import exception, receipt workspace ownership, committed-follow-up failure and exact deployment readiness. Kept uncertainty reconciliation/stale preview recovery, rollback draft/copy limitations, unlink/exclusions; moved contributor harness details to existing canonical repository README link. | Verified improvement. Puts permissions and deployment gates before mutation steps; separates export/import, fork, direction-relative sync, receipt/recovery, and rollback consequences. Corrects confidentiality guarantees and adds selector bounds, fingerprint/retry safeguards, copy identity differences and exact deployment readiness. Preserved: Retains CLI↔HTTP map, all import/sync payload shapes, source IDs, nested occurrences/encodings, destination selectors, trigger adoption, request IDs, receipts and retry recovery. Contributor harness detail moved to a linked canonical README that contains Bun/Docker/PostgreSQL17/fixtures/migration boundary. | + +### Knowledgebase (7) + +| Page or operation | Result | Changes | Final comparison and preservation | +| --- | --- | --- | --- | +| [knowledgebase/chunking-strategies.mdx](content/docs/knowledgebase/chunking-strategies.mdx) | rewritten | Replaced repeated Advanced warnings and cross-library comparisons with settings, actual Auto routing, strategy behavior, record examples, and troubleshooting. Corrected minimum range to 1–2,000 characters; explained approximate token sizes, per-strategy minimum filtering, overlap behavior, and oversized records. Preserved strict Regex checkbox label, delimiter/segment distinction, normalization, positive lookaround, 500-character pattern limit, unsupported syntax, and no-split behavior. Documented v2 configuration updates including strategy/options, whole-object replacement, defaults on omission, and no automatic rebuild of existing chunks. | Verified improvement. Corrects automatic JSON detection, one-record guarantees, exact token counts and globally enforced minimum sizes; distinguishes each splitter behavior. Adds strict Regex semantics, normalization, unsupported patterns and replacement-versus-merge configuration consequences. Preserved: All six strategies, default sizes/overlap, strategy tradeoffs, JSONL example and Q&A boundary example retained. Original re-create-base advice preserved for UI; API update is distinguished and existing chunks are not falsely said to rebuild. FAQ advice now has explicit record-boundary sections; no unique useful media lost. | +| [knowledgebase/connectors.mdx](content/docs/knowledgebase/connectors.mdx) | rewritten | Reorganized into connection methods, setup, verification, actions/history, exclusions, sync recovery, Confluence constraints, and catalog. Kept credential kinds/scopes/configuration examples and whole-value secret snapshot/rotation behavior; replaced unverified provider account-menu directions with verified credential requirements. Added Live every 5 minutes and scoped sub-hourly plan gating to hosted billed workspaces; preserved permission refresh and manual-only freshness consequences. Corrected action-menu labels, Pending status, paused/resume behavior, one-minute healthy-sync cooldown, latest-ten history wording, and workspace versus permission-aware removal consequences. Preserved source-retirement cases with their actual default/selected-scope exceptions, incomplete-listing protection, partial failures, backoff, and ten-failure disable behavior. Kept Confluence formats/scope, legacy conversion guidance, image types/floor/GIF behavior, key prerequisites, configurable default image cap, billing/retry/re-enable behavior. Added Otter and Plane; removed a hardcoded connector count. | Verified improvement. Separates indexed KB connections from live Search, source permissions from Workspace access and setup from completed indexing. Adds lifecycle consequences, credential snapshot rotation, one-minute successful manual-sync cooldown and Confluence attachments behavior. Preserved: Original provider credential kinds, GitLab/project requirements, concrete source filters, metadata pool, sync schedule/manual run, Documents/Sync History/Settings actions and keep/remove document choices preserved. Steps retain the genuine sequential setup; unrelated videos/callouts replaced by named controls and scope statements. Five original token-generation locations identified as a preservation gap and sent to root with current primary URLs. | +| [knowledgebase/debugging-retrieval.mdx](content/docs/knowledgebase/debugging-retrieval.mdx) | rewritten | Organized diagnosis as read output, processing, enabled/access state, filters, stored content, relevance, and duplicates. Removed unsupported universal similarity thresholds and described rank/rankScore/similarity/rerankerScore separately. Preserved raw processing statuses, separate Skipped outcome, Retry and replacement guidance, async wait/poll behavior, connector visibility, and duplicate analysis. Corrected reranker fallback to retain retrieval ordering; preserved completed hosted-key search-unit and BYOK distinction. | Verified improvement. Places completed/enabled/included/readable checks before ranking tweaks, distinguishes accepted upload/sync from finished indexing and isolates source-access failures. Removes misleading similarity cutoff and universal chunk-size advice; keeps returned Hybrid/reranker/recency order and explains cost/fallback. Preserved: No-results, irrelevant passages, duplicates, exact terms, tags, candidate count, reranking, overlap and chunk sizing all retained as diagnosis steps. Original error recovery examples preserved with valid operational qualifications; generic tip/FAQ material is folded into the relevant diagnosis. No unique operational media removed. | +| [knowledgebase/export-import.mdx](content/docs/knowledgebase/export-import.mdx) | rewritten | Kept Export as the task/title and preserved stable path, ZIP tree, exact HTTP/CLI commands, vectors default, base64 float32 representation, manifest version and fields. Placed role/capability/OAuth/key access and workspace-readable archive scope before download steps. Clarified active/included scope, completed chunk eligibility, omitted empty documents, disabled flags, and all archive exclusions. Preserved 2,000-row preflight/413 and added verified bundle chunk/content format bounds; kept governance/audit and Search-index distinction. | Verified improvement. Puts export access/scope before commands; corrects personal-versus-workspace-readable scope, processing file/chunk inclusion and format ceilings. Adds portability model/dimension caveat, excluded ACL/credentials/provenance and CLI overwrite rule. Preserved: .simkb.zip, vectors default/opt-out, UI/API/CLI paths, manifest/files/chunks tree, float32 base64 encoding and connector-to-plain-document behavior retained. Original import absence remains clear from page purpose; archive source IDs/flags/counts and audit facts retained. Removed callouts/FAQ restated vectors/scope facts now explained at the decision point. | +| [knowledgebase/index.mdx](content/docs/knowledgebase/index.mdx) | rewritten | Added shortest supported UI path using New base/New documents and explained upload acceptance versus processing completion. Listed actual accepted file extensions and 100 MiB/file, 20-file/action, 500 MiB/action limits. Replaced merge/split/any-document editing promise with current uploaded-document actions and connector read-only behavior. Qualified repository embedding default, kept model/dimension lifetime and query-only multi-base compatibility rule, and retained single-base block scope. Aligned six Related docs Cards with metadata order and added Export. | Verified improvement. Turns overview into create/upload/verify/retrieve flow with actual supported upload formats, limits and OCR prerequisites. Qualifies completion/access and embedding compatibility, keeps separate live Search catalog. Preserved: Original embedding/chunk concept, upload/connectors choice, inspection/editing, Knowledge→Agent composition and related owners retained. Defaults and self-hosted embedding controls preserved with model/dimension compatibility across query searches; tag-only exception added. Decorative media and general FAQ are replaced by complete named controls, format table and processing section. | +| [knowledgebase/tags.mdx](content/docs/knowledgebase/tags.mdx) | rewritten | Preserved definition/value distinction and all 17 slots (7 Text/5 Number/2 Date/3 Boolean), current UI operators, AND behavior, variable references, date/Boolean/number formats, and connector metadata examples. Added verified Text 512-character and name 100-character bounds with case-insensitive uniqueness/matching. Corrected tag sorting promise to filtering, API rename versus base-modal controls, destructive delete-value consequence, and setup-only metadata choices without automatic slot freeing. Kept tags-only retrieval separate from query retrieval and avoided cheapest/most-precise guarantees. | Verified improvement. Defines metadata definition versus document value, exact typed capacity and destructive deletion before controls. Corrects case-insensitive names/matching, literal operator behavior, AND filters, tag-only no-embedding and connector metadata lifecycle. Preserved: All17 slots and all text/number/date/boolean UI operators retained, including between inclusive bounds and missing-value exclusion. Header Tags location and inspected screenshot retained; Add Tag/Tag Name/Type/Create Tag and document Tags panel remain. Original connector metadata, capacity allocation and filter examples retained; FAQ folded into capacity/operator/query sections. | +| [knowledgebase/using-in-workflows.mdx](content/docs/knowledgebase/using-in-workflows.mdx) | rewritten | Started with minimum working query/Agent example, followed by query/tag inputs, outputs, advanced modes, and reranking. Corrected Automatic default and workspace policy, query-visible scope, topK default/range, and tag-only mode/cost behavior. Preserved #retrieval-mode, references, citation fields, Hybrid exact identifiers, and no extra keyword model call. Added rank/rankScore/rerankerScore semantics and recency/order guidance; made OutputBundle count match its one displayed result. Preserved reranker model/key prerequisite and added advanced candidate count, four-times default/cap, completed-call billing, and retrieval-order fallback. | Verified improvement. Provides exact Search/Knowledge Base/Search Query→Agent recipe and names output fields/ranking semantics. Adds retrieval modes, recency policy and candidate/fallback/metering behavior without universal similarity-order promises. Preserved: Original refund semantic example, /, default10/max100, tag-only/query/tag combination and AND filters retained. Shared workflow preview and OutputBundle remain; original source/document/chunk/metadata/query/count fields preserved. Rerank switch/model/self-hosted Cohere key and cost implications retained with actual no-result/tag-only skip behavior. | + +### Agents (5) + +| Page or operation | Result | Changes | Final comparison and preservation | +| --- | --- | --- | --- | +| [agents/index.mdx](content/docs/agents/index.mdx) | rewritten | Scoped definition to workflow agents; replaced repeated feature essays with task setup, capability table and canonical references. Kept corrected shared minimal-agent preview, successful root structured fields, file input, knowledge tool and conversation-ID memory boundaries. Added the overview to owned section navigation without changing slugs. Root retained automatic non-root overview linking rather than duplicating index in metadata; meaningful navigation guard caught the proposed duplicate. | Verified improvement. Replaces conceptual/promotional repetition and hardcoded model default with minimum configuration and capability table. Adds preview structured score binding, files/model/access boundaries and explicit conversation memory. Preserved: Start/Agent/prompt, content output/run details, all four tool sources, rubric, knowledge, memory, structured tier/Condition intention and fixed-vs-model decision preserved. Lead-score workflow preview retained; knowledge/deal-comparison use remains covered by linked knowledge owner and capability purpose. | +| [agents/choosing.mdx](content/docs/agents/choosing.mdx) | rewritten | Led with who decides execution and an early comparison table; explained custom tools/MCP/workflows as kinds of Agent tools. Qualified Force by model support and execution success, custom API account requirements, and team-owned MCP servers. Preserved one complete lead example, fixed Workflow block versus workflow-as-tool distinction, child draft/deployed context and on-demand skills. | Verified improvement. Moves who-decides decision and six-choice mapping first; distinguishes fixed attempt from successful execution. Corrects Force as model-supported request, not guaranteed call/success; adds API credentials and child draft/deployed context. Preserved: Lead scorer enrichment/reshape/Sheets logging/Search/email/Deep Enrich/rubric examples and all six feature categories preserved. Multiple redundant highlighted previews and callout/VISUAL comments consolidated into one preview and corresponding task prose. | +| [agents/custom-tools.mdx](content/docs/agents/custom-tools.mdx) | rewritten | Matched Add tool, stacked Schema/Code and Agent picker controls; retained generation capability. Retained canonical function-calling JSON schema, supplied named inputs and params object, safe optional input default, async HTTP/secret example and return semantics. Replaced Node/Buffer/crypto promises with isolated JavaScript, fetch-method, package and filesystem limits; distinguished direct Function tool and block. Corrected deletion role to Write/Admin and warned about saved-definition references; preserved search, secret syntax/visibility/exact-match projection and transformed-value caveats. Folded all three FAQ answers into runtime/secrets/Agent sections and replaced Steps with numbered setup. | Verified improvement. Corrects Schema/Code sections, Add tool control, params/optional bindings and isolated VM capabilities. Weather example now escapes city, handles optional units and HTTP failure; role table matches current Write deletion policy. Preserved: Full function schema and weather return fields retained; async/fetch/secrets reuse and standalone Function distinction remain. Original security/encoded-value limitations, generation controls, search/edit/delete facts and FAQ information folded into runtime/secrets/access sections. | +| [agents/mcp.mdx](content/docs/agents/mcp.mdx) | rewritten | Matched Add server, save-time test, edit Test connection, Authorize, remote Streamable HTTP and optional OAuth client controls; corrected preliminary audit Connect label using current source. Preserved secret substitution and masking limits, acting/execution-actor OAuth identities, explicitly authorized managed connections and credential grants. Preserved dynamic plain-ID/name configuration, all three access policies, empty-selection semantics, saved legacy normalization, exact case-sensitive names, execution checks and arguments caveat. Preserved standalone List/Run fields, outputs, 1–100/default100 paging, server/managed ID resolution and JSON argument behavior. Added client discovery caps 50pages/1000tools/5MiB/60seconds, partial-versus-complete runtime behavior, five-minute cache/two-minute probe cache, matching draft-only Refresh, current-schema errors and recovery. Corrected registration delete Write/Admin and destination Admin permissions; kept separate external registrations/workflow deployment/Sim workspace/Search MCP directions and self-hosted exact domain-versus-egress/OAuth-origin distinction. | Verified improvement. Adds working OAuth registration sequence, server JSON scope, acting-user/managed identity and independent permissions. Clarifies discovery cache/partial inventory/budgets, draft refresh versus live snapshot, operations access and standalone outputs. Preserved: Every original remote registration field/secret/network boundary, Agent/dynamic/exact-name access mode and standalone list/run/pagination fact retained. Per-workspace registration, disableMcpTools and server-offline FAQ folded into registration/permissions/troubleshoot. Removed generic settings/screenshots/video are replaced with exact named controls; no unique required setup field removed. | +| [agents/skills.mdx](content/docs/agents/skills.mdx) | rewritten | Led with reusable guidance and Agent on-demand versus Chat-tag behavior; preserved available_skills/load_skill/skill_name details and model compatibility. Preserved Integrations/Skills/Add to Sim, curated suggestions, search, create/edit/share/delete, all name/description/content limits and complete valid SKILL.md example. Specified 5MiB ZIP/shallowest SKILL.md selection and simple frontmatter-only/name-description-body import; explicitly excluded bundled scripts/references/assets/other metadata. Preserved creator/explicit Read-role editor/derived Admin access and sharing, qualified use by organization policy, corrected unconditional execution guarantee. Merged repeated generic best-practice lists and two FAQs into focused authoring and activation verification; retained 500-line recommendation as guidance. | Verified improvement. Moves first use and activation before authoring, clarifies model availability and voluntary load versus explicit Chat tag. Adds exact field/ZIP/import bounds and separates editors from runtime organization restrictions. Preserved: Skill discovery/activation/load_skill runtime, Integrations Skills/editor sharing/Admin rights, curated service skill, direct Chat tag, Markdown structure/testing intentions and under500line guidance preserved. SQL illustration replaced by complete lead-scoring SKILL.md with activation/steps/output/edge conditions; original unsupported universal always-executes guarantee removed. Add-skill screenshot retained; tab screenshot removed after task controls made explicit. | + +### CLI guides (8) + +| Page or operation | Result | Changes | Final comparison and preservation | +| --- | --- | --- | --- | +| [cli/authentication.mdx](content/docs/cli/authentication.mdx) | rewritten | Organized method selection, approval, remote pairing, workspace selection, verification, CI, multi-profile login, self-hosting, storage/refresh, and revocation by task. Retained OAuth-only flags, explicit-method refusal, platform pairing upgrade boundary, callback/container limits, lifetime/refresh locking/replay details, shared-profile restrictions, file permissions, and OAuth versus API-key logout effects. Corrected whoami recovery and current Sim API keys label; added HTTPS and issuer-bound endpoint prerequisites; changed install step in Actions to Bun. | Verified improvement. Orders method choice, approval, remote terminals, workspace selection, verification, CI and revocation by task. Corrects whoami recovery, issuer/HTTPS restrictions and shared-profile/refresh claims; keeps permanent-key/OAuth differences. Preserved: Retains every login option, scopes/callback/remote restrictions, approval-code warnings, 0600 storage, one-hour/fixed30-day lifetimes, refresh locking/replay, CI, profile and logout behavior. | +| [cli/configuration.mdx](content/docs/cli/configuration.mdx) | rewritten | Reorganized profiles, persistent defaults, independent precedence, files/shared authentication, workspace selection, environment controls, updates, and repair. Retained INI section rules, direct auth_profile restrictions, source precedence, file overrides, picker cap and ephemeral-value refusals, all-workspaces exceptions, update channels/install identity/locks/registry/cache/deadlines, and accurate Node proxy thresholds. Replaced rejected global-output repair with SIM_OUTPUT environment override; made table selection explicit for profile asterisk. | Verified improvement. Clarifies independent precedence, shared authentication restrictions, no global setting persistence, explicit profile existence and environment override repair. Qualifies notice caching and per-request timeout instead of baseline guarantees; retains updater/proxy/registry boundaries. Preserved: Retains profile/config/credential syntax, every variable and setting, workspace picker cap, all-workspaces rules, update managers/channels/ownership/timeouts and registry privacy. | +| [cli/index.mdx](content/docs/cli/index.mdx) | rewritten | Rebuilt the first-run sequence with Bun installation, explicit workspace selection, verified settings, table listing, and deployed/manual execution. Scoped command shape to resources, retained singular/knowledge aliases and nested help, added task search and complete resource-group discovery. Aligned table transcript with --output table; preserved npm/pnpm compatibility and same-package-manager upgrade facts in prose. | Verified improvement. Makes installation→sign-in→workspace→verification→first workflow a usable numbered sequence and uses Bun installation. Expands the resource map and points to local-vs-Chat scope and command discovery; final meta entry reports status, not nonexistent limits. Preserved: Retains Node20, global/temporary installation, OAuth/pairing, profiles/workspace flags, JSON/table output, deployment/manual run, aliases/help and all original command groups. | +| [cli/output.mdx](content/docs/cli/output.mdx) | rewritten | Separated raw machine values/envelopes from formatted display output and stdout/stderr. Retained text empty/unclipped/sanitized behavior, trace details, cursor shape, Chat streaming, exports and raw download exceptions. Added fixed-text telemetry and structured save receipt; pinned JSON export and explicitly stated import does not accept YAML; preserved actual command-specific monetary units. | Verified improvement. Explains unwrapped resources versus data/nextCursor list envelopes, raw-vs-display values and stderr exceptions. Corrects telemetry/export/raw-download behavior and pins JSON for round-trip imports instead of implying YAML imports work. Preserved: Retains all four formats, selection/defaults, timestamps/sizes/booleans, clipping/text nulls, trace output, profiles/config/chat/export/file exceptions. | +| [cli/scripting.mdx](content/docs/cli/scripting.mdx) | rewritten | Reorganized unattended setup, file/list/leading-at inputs, predicates, pagination, command-specific failure tables, async waits, output selection, destructive effects, folders, organization requests/invitations, and nightly automation. Retained all predicate operators/sort syntax, memory/page/cursor controls, caps versus pagination, per-person zero/null credit behavior, permissions impact/fingerprint review, partial invitation commits, folder ref/direct-child behavior, and select-output limits. Added JSON byte bounds and embedded no-stdin boundary; corrected stderr/verification/pagination promises; included operation-wait exits and robust async nightly status handling without executing examples. | Verified improvement. Puts shell prerequisites first; differentiates pagination limit0 from destructive filter caps and separates all outcome-specific exit tables. Retains exact filter/list/folder/sync syntax while correcting run failure/paused handling, stderr format, stdin/embedded boundaries and safe nightly recovery. Preserved: Retains @file/@-/@@ escaping, list syntax, all predicate operators/sort, pagination/cursors/memory, confirmations, organization access/requests/caps/invitations, async waits, selected outputs, folders and end-to-end Bash recipe. | +| [cli/troubleshooting.mdx](content/docs/cli/troubleshooting.mdx) | rewritten | Kept every original error class with short remedies and canonical links. Corrected output repair and whoami refusal advice; added issuer mismatch, refresh ambiguity, HTTPS/redirect/proxy, truncation versus server caps, output-file receipts/force, uncertain sync reconciliation, and sanitized issue reporting. Used Bun update fallback while retaining existing-manager, prerelease-channel, project-local, npm/pnpm/Yarn Classic compatibility facts. | Verified improvement. Starts with concrete version/profile verification and corrects wrong-workspace/auth-retry guidance. Adds refresh/issuer/redirect/proxy, server truncation, YAML-import and uncertain-operation recovery; fixes old claim docs track every installed release. Preserved: Retains wrong target, 401, connectivity, JSON quoting, table clipping, binary output, settings repair, updates, stderr notice and sanitized issue reporting recovery. | +| [cli/usage-data.mdx](content/docs/cli/usage-data.mdx) | rewritten | Led with immediate opt-out and exact precedence before the complete event inventory. Retained flags versus values, runtime/CI/agent/endpoint-kind fields, random IDs/session timing, separate sender/no API key, first-notice exclusion, request attribution, and build-controlled self-hosting behavior. Corrected telemetry state deletion to include saved preference reset; stated event exclusions and fixed-text output; qualified downstream account/location/project claims to observable client behavior. | Verified improvement. Qualifies reporting by build destination and excludes nonexecuted/help/first-notice events; separates anonymous event fields from API attribution. Explains setting reset after deleting state, environment priority and network IP-derived location without promising no network data. Preserved: Retains complete event/omission lists, device/session identity, 30-minute grouping, localstate, telemetry opt-outs, firstnotice, self-hosted/build-time destinations and detached delivery. | +| [cli/workflow-sync.mdx](content/docs/cli/workflow-sync.mdx) | rewritten | Organized access/gates, portable export inspection, resource/field bindings, dependent selector choices, exact preview/apply, fork/sync direction, mapping/copy identities, saved values, trigger URL choices, rollback limits, receipts/waits and uncertain retries. Retained every original concrete mapping/binding/value form, CLI versus HTTP envelope distinction, empty-mapping receipt requirements, source identities, copy opt-in and credential/secret exclusion, source versus destination discovery, direct edge/both-admin scope, exclusions, source deletion versus undeployment, receipt workspaces, list snapshots versus refreshed reads, request-ID replay/conflicts, and commit versus readiness distinction. Scoped fork entitlement to billing mode; pinned JSON export, added payload inspection/literal-value caveat, and moved contributor harness context to the existing API guide's contributor reference while retaining destination-provider validation. | Verified improvement. Organizes prerequisites→exact preview/apply→verification and gives deployment/auth gates, confidentiality qualifications and stable-request recovery. Clarifies source identities vs transient targets, envelope differences, mapping projection, selectors/copy/trigger choices and operation wait outcomes. Preserved: Retains all CLI flags/payloads, same-choices/fingerprint, plain vs mapped import, draft-only fork, direction-relative sync, copies/mappings, deployment readiness, rollback/unlink, requestIDs and contributor harness link. | + +### Files (5) + +| Page or operation | Result | Changes | Final comparison and preservation | +| --- | --- | --- | --- | +| [files/index.mdx](content/docs/files/index.mdx) | rewritten | Added Upload/New file/New folder, viewer capabilities, organization actions, Download, private access, Share/Unshare modes and governance prerequisites. Separated persistent workspace Files, execution artifacts, private Chat attachments and knowledge-base ingestion. Linked archive and retention limits without promising instant physical deletion. | Verified improvement. Turns a sparse conceptual landing page into a usable upload/create/view/organize/share guide with roles and lifecycle. Adds supported viewers, upload ceiling and rendered-download distinction; removes any-workflow/universal-shared-content promises. Preserved: Original contract/report/file-versus-table-versus-KB decisions and workflow read/produce use cases retained. Original onward navigation preserved; private Chat attachment and execution-artifact distinction added. No baseline media or unique FAQ lost. | +| [files/editor.mdx](content/docs/files/editor.mdx) | rewritten | Preserved formatting marks, heading/quote/divider syntax, lists, shortcuts, tables, code/Mermaid and image editing. Corrected slash-menu trigger, fixed headers, disabled column resizing/merged cells, Markdown normalization and source preservation. Explained 262,144-character rich-edit threshold, source fallback and 50 MiB text-editor ceiling. Documented visible-snapshot export versus saving, and Markdown/image ZIP exports. Review correction: the 50 MiB source preview limit differs from the 10 MiB whole-request save cap. | Verified improvement. Corrects exact-round-trip and universal-rich-edit claims; makes fixed headers, disabled resizing, source fallback and 262,144-character/50 MiB limits explicit. Formatting shortcuts and insertion rules are compact task/reference sections rather than decorative cards/callouts. Preserved: All original text/list/code/Mermaid/link/image functions retained; source preservation and unsupported constructs remain explained. Removed rendered-example screenshot adds no unique control procedure; original formatting/code/table/image facts are in text. Original slash-menu anchor retained as custom ID; links to generation and workflow reuse retained. | +| [files/generating.mdx](content/docs/files/generating.mdx) | rewritten | Separated generated text, binary UserFile and persisted workspace file. Added complete visible Write recipes, exactly-one-source input, source file copy, folder-scoped suffixing, overwrite and Append. Preserved id/name/size/url and added version/revision precondition distinction. Explained /tmp/sim/outputs automatic workflow exports, per-call Chat SIM_OUTPUT_DIR workspace export and separate hidden Function tool persistence. Replaced direct public URL/never-bytes claims with authenticated workspace/run-file download and optional inline output guidance. | Verified improvement. Adds binary File input, overwrite scope, version versus revision preconditions, execution artifacts versus persistent Files, and authenticated API references. Corrects MIME-label-as-rendering and every-workflow-access guarantees without removing generation use cases. Preserved: Agent summary, Function CSV/text, ElevenLabs audio, images, output-object reuse, deduplicated naming and append all retained. Removed generic callout/card and non-rendered VISUAL comments folded into content/persistence/reference sections; useful MIME and saved-file identity facts remain. Generation/where-file-goes/next stable anchors retained with custom IDs. | +| [files/passing-files.mdx](content/docs/files/passing-files.mdx) | rewritten | Documented UserFile key/context, optional base64/version, opaque identifiers, display-field omissions and distinct upload/run-file DTOs. Preserved indexed/full-object/property references and scoped compatibility instead of universal conversion claims. Replaced both invalid curls with v2 input wrapper and accepted type/data/name/mime descriptors. Base64 example contains semantically valid text bytes. Added Files/file[] entry prerequisite, deployed-state scope, stored-reference authorization, session serve versus authenticated run/workspace downloads, required workspaceId query, run lifecycle and inline base64 constraints. Folded unique FAQ facts into visible input/limit sections; retained file-capable block/storage examples and concrete separate limits. Used shared authored tabs with padded mixed content, wrapped prose, visible horizontal scrolling, and mobile touch targets. | Verified improvement. Replaces invalid v2 top-level document requests with strict input-wrapper file[] descriptors and valid text base64. Separates UserFile versus API input versus projected run-download shapes and session URL versus X-API-Key download. Replaces automatic-format/base64 universals with receiving-block format limits and a scoped numeric limit table. Preserved: Original arrays/index/name/full-object/content references, Base64/URL alternatives, stored-reference reuse, all integration categories and Start files compatibility preserved. Both FAQ facts (no universal limit and incoming files processing) folded into File limits and API input sections. Original API anchor IDs retained; authored tabs replace direct Fumadocs imports. | +| [files/using-in-workflows.mdx](content/docs/files/using-in-workflows.mdx) | rewritten | Rebuilt practical report.pdf → Agent → summary.md steps using preview aliases file and agent. Preserved Read/Get Content/Fetch/Write/Append outputs as common paths and linked the complete current operation reference. Corrected unsupported automatic Agent text fallback; named attachment prerequisite and Get Content text path. Preserved optional save/append, dynamic recursive folder selection, authenticated Fetch, extracted-text versus raw-byte Function helpers. Explained /tmp/sim/inputs and /tmp/sim/outputs, special indexed .path mount reference and local JavaScript helper scope. | Verified improvement. Makes a runnable Read→Agent→Write recipe whose named references agree with its shared preview. Corrects File operation count, attachment support, text-only extraction, binary Write, URL persistence, and indexed .path mount semantics. Preserved: PDF summary, email/image attachment, JSON/CSV deterministic Function processing, fetch headers, optional persistence and append use cases preserved. Original five common operations preserved as common paths rather than claiming exhaustive inventory; useful callout/VISUAL intentions are in concrete instructions. All original reading/processing/writing/composing anchors retained as custom IDs. | + +### Tables (3) + +| Page or operation | Result | Changes | Final comparison and preservation | +| --- | --- | --- | --- | +| [tables/index.mdx](content/docs/tables/index.mdx) | rewritten | Moved creation before the type reference; added Expiration and all eight types in picker order, safe conversions and invalid-write distinctions. Preserved Currency relabeling, formula boundary, count/default/byte budgets, atomic row writes and local undo; folded FAQ into behavior. Distinguished configurable 400 KiB row-data default from the fixed 1,000-column ceiling. | Verified improvement. Moves create/edit before the type lookup; adds accurate coercion/API distinction instead of claiming every invalid editor/workflow input errors. Adds current Expiration type and scheduled cleanup/lock consequence; distinguishes individual atomic row writes from multi-step workflow transactions. Preserved: Every original type/example, currency relabel-without-conversion, spreadsheet paste/filter/sort,Table block/group/API choices and all four FAQ facts retained in substantive sections. Original table overview screenshot retained; formulas,undo/API exclusion and plan/deployment ceilings remain visible. JSON any-value and date-time support correct original overly narrow examples; units now match byte constants. | +| [tables/using-in-workflows.mdx](content/docs/tables/using-in-workflows.mdx) | rewritten | Corrected row.data result and references, quoted JSON writes, first-page totalCount, unique/Conflict Column upsert prerequisites and overlapping-run consequences. Preserved all ten operations, valid shared preview and nested OutputBundle, all/any predicates, projection/sort, batch1000/unlimited filtered updates, cursor termination and surface-specific byte/default limits. | Verified improvement. Makes complete valid-JSON classify loop recipe with real row.data/loop.currentItem references and explicit schema prerequisite. Corrects first-versus-cursor totalCount and numeric coercion, adds unique Conflict Column and unlimited filtered update semantics. Preserves pagination by nextCursor and adds overlap/atomic-claim warning at the point of the queue-like status example. Preserved: All ten original operation intentions,leads fields,shared preview/OutputBundle,all/any nested predicate,order/projection,built-in fields and Insert JSON retained. Original midrun pricing lookup,sequential individual classification,bulk same-patch,unlimited read5MiB/early pages,cursor termination and Logs inspection retained. Original invalidflatrows/unquotedJSJSON examples corrected rather than cut; generic type callout facts folded into current schema/coercion paragraph. | +| [tables/workflow-columns.mdx](content/docs/tables/workflow-columns.mdx) | rewritten | Moved deployed-workflow prerequisite and setup ahead of behavior; corrected Show additional fields → Workflow inputs current navigation. Corrected full row context, Boolean dependencies, filtered/manual/incomplete controls, auto-run default/re-arm/cancellation, current states and non-guaranteed coordination; preserved output progress, cascade/retry/use-case distinctions. | Verified improvement. Replaces long screenshot-driven narrative with exact current deployed-workflow setup and inputs/output distinction. Corrects mappings-as-access-restriction,false/empty dependencies,attempt-sticky auto behavior,rearm/restartcost,filtered run scopes and atomic-concurrency guarantee. Adds Waiting versus Pending and No output semantics, including downstream no-match waiting. Preserved: Original Enrichments versus Workflow choice,CompanyDomain→CompanyInfo→LeadScore cascade,input/outputconfiguration,manualactions,auto-run/dependencies,statebadges and View execution/Re-run cell recovery preserved. Inspected all six baseline local PNGs independently: new-column-menu,configure-workflow,column-mapping,cell-menu,row-trace,table-groups. Their named setup/trace facts are covered in text; obsolete Add column inputs instruction is corrected to Show additional fields→Workflow inputs. Lost Stop all control found during fresh image review and restored by root. Completed values are retained on cancellation. | + +### Logs (3) + +| Page or operation | Result | Changes | Final comparison and preservation | +| --- | --- | --- | --- | +| [logs-debugging/index.mdx](content/docs/logs-debugging/index.mdx) | rewritten | Separated backward-debugging steps from interface reference; corrected handled-error behavior, trace sections, access qualifications, visible trigger labels and retention. Preserved the six failure cases, resolved references, rerun comparison, and named Troubleshoot in Chat. | Verified improvement. Separates backward failure investigation from interface lookup and corrects handled-error, access/protection, active trace sections, and Chat troubleshooting claims. Replaces false every-run/universal exact-value/archive guarantees with recorded/access-aware logs and effective retention. Preserved: Retains all six investigation steps and all six common failures, named resolved inputs/output/data-flow links, metadata/duration/credits and rerun comparison. Meaningful trace screenshot remains and was visually inspected. Console/snapshot facts moved to the locally linked Run logs reference, and complete secret protections stay in the linked Credentials owner. | +| [logs-debugging/logging.mdx](content/docs/logs-debugging/logging.mdx) | rewritten | Corrected run-ID search, structured filters, stable snapshot refresh, current trace sections, ledger itemization, access and snapshot availability, and effective retention without an archive promise. Folded unique FAQ fields into the reference; delegated full secret protection detail to Credentials. | Verified improvement. Corrects full-text/live-mode claims to execution-ID search, supported structured filters and stable list refresh controls. Adds current access/itemized ledger and unavailable-snapshot boundaries, effective retention and cleanup versus archive. Preserved: Retains all columns/filters/cost units, console active/timing/tree input-output controls, identifiers/copy/data/file details, snapshot structure/config/connections and migrated Logged State Not Found. Complete status:error workflow:"Support" duration:>5s example and screenshot inspected; useful FAQ protection facts are in linked Credentials, and debugging/task reference separation remains coherent. | +| [logs-debugging/alerts.mdx](content/docs/logs-debugging/alerts.mdx) | rewritten | Kept verified event, threshold, credit, cooldown, rate minimum and recursion boundaries; added delivery/access prerequisites, verification and troubleshooting. Limited the one-hour rule to run-backed alerts and documented No Activity per-workflow max(one hour, inactivity window) cooldown. | Verified improvement. Adds concrete deployment/delivery/access prerequisites, separate verification and troubleshooting rather than mixing setup with success claims. Corrects No Activity per-workflow max(onehour,inactivity) cooldown while preserving plain versus run-backed rule distinction. Preserved: Retains complete three-consecutive-failures Slack setup, reference message, workspace/source filtering, event/rule choices/credit units/five-run minimum, anti-self/anti-recursion and delivery failure diagnosis. The full text example is unchanged and a named workspaceevent trigger is specified; exact defaults/output details are available in the linked current Sim event reference. | + +### MCP (3) + +| Page or operation | Result | Changes | Final comparison and preservation | +| --- | --- | --- | --- | +| [mcp/authentication.mdx](content/docs/mcp/authentication.mdx) | rewritten | Qualified one-hour access token and fixed 30-day offline refresh grant; removed unsupported renewal and full-access generalizations. Preserved scopes, server audience, revocation consequences, both key forms and examples; distinguished personal/workspace policy and default expiration, exact policy labels and environment interpolation. | Verified improvement. Adds fixed one-hour/30-day OAuth lifetimes and offline_access, actual permission-policy labels and resource-scope boundaries. Qualifies UI-created key default expiry, self-hosted URLs and Cursor environment interpolation. Preserved: Both key client examples, headers/Bearer alternatives, personal/workspace scope, read/write OAuth scopes, audience, revoke/no-undo and organization restrictions retained. Key warning remains concrete; removed most-apps-full-access speculation adds no operational loss. | +| [mcp/overview.mdx](content/docs/mcp/overview.mdx) | rewritten | Qualified supported JSON API coverage, credential scope and client-controlled approvals; linked canonical request limitations. Moved network prerequisites before connection; preserved all five client tabs and both deployment URLs, corrected Claude navigation and DCR strategy. Used shared authored tabs with padded mixed content, wrapped prose, visible horizontal scrolling, and mobile touch targets. | Verified improvement. Qualifies supported JSON operations rather than promising entire API, scopes connection credential and app-controlled approvals. Puts self-hosted/network prerequisites before client tabs; updates current Claude Customize and automatic registration labels. Preserved: Cloud/self-hosted server URLs, all five complete client examples, read/workflow/failure/table prompts and three separate MCP surfaces retained. Hosted-Claude versus local-client reachability Callout folded into prerequisite prose; authored tabs preserve configuration examples. | +| [mcp/tools.mdx](content/docs/mcp/tools.mdx) | rewritten | Preserved four tool names, request fields, API result/error formats and binary/multipart/streaming exclusions. Corrected read bodies and method-independent tool classification; added catalog 25/100 bounds, declared-header rules, conditional resource paging, and post-write 1MiB size-error recovery. | Verified improvement. Adds catalog-search defaults/max/no-cursor distinction and permission-based read/write classification. Corrects read JSON body support, forbidden header overrides and post-execution result-size consequences. Preserved: All four tool names and table-row request slots/example, envelope/errors, API parity,1MiB/no-stream/no-binary and async poll guidance retained. Additional queryRows POST/read body example makes previously misleading write-only body row usable. | + +## Qualified claims and separate product issues + +- A repository default or flag does not prove the deployed Cloud value. Pricing, plan caps and rollout claims remain linked/qualified where live evidence is unavailable. The Max concurrent-run value conflicts with public pricing; the copy does not choose an unverified number. +- External Chat worker evidence is the read-only staging snapshot `3aec2a03379d175264c26481d25f85647297ee32`. No live worker deployment was authenticated or changed. +- Provider console procedures and client syntax were checked against primary sources. No provider account, live OAuth grant, infrastructure installation, license entitlement or production data operation was exercised. +- Uninspected remote media is unverified, not declared stale. Redundant media can be removed when written instructions preserve its purpose. +- Project file ownership, storage and realtime foundations are present in the latest staging snapshot, but the corresponding Project Files routes/editor callbacks are absent. Future Project docs must distinguish organization retention from workspace overrides. No usable Project Files surface is claimed in this rewrite. +- Separate implementation observations include missing shipped upload-session cleanup scheduling, permissive schedule validation versus the cron parser, Redis-unavailable row coordination fallback, partial MCP discovery without a completeness flag, and SDK streaming limitations. Copy describes current supported behavior; this pass does not silently change these systems. + +## Validation + +- **Coverage**: 484/484 entries independently compared across 22 sections, with no missing or duplicate assignments and zero remaining identified copy issues. Scope: 153 authored entries, 28 CLI references, and 303 API operations; 306 integration MDX pages excluded from edits. +- **Rebase**: Rebased onto origin/staging at 9058427155 after reviewing all 20 intervening commits. The additional export-prefix cleanup does not change documented workspace behavior. +- **Generation**: Seven OpenAPI documents, 28 CLI reference pages, CLI API, MCP catalog, v2 route table, and Agent streaming region are current. All 303 API operation identities and 318 CLI command/option shapes preserved. +- **API inputs and examples**: 22 canonical contract files reviewed: 19 editorial-stripped ASTs match staging; three differences are documented description-only helpers. All 135 rendered JSON request bodies validate, and all 135 curl samples pass bash syntax. The baseline’s 17 invalid bodies were reproduced and corrected. +- **Generator boundary**: The actual 1,057,209-byte resources input reproduced the old successful empty-format result. The formatter now has explicit 16 MiB bounds, preserves complete parsed JSON (1,027,061 formatted bytes), and rejects oversized input; independently inspected. +- **MDX and links**: All 790 runtime entries compiled/exported. All 1,988 internal links and 97 preserved inbound anchors pass, including excluded integrations and application references. +- **Repository gates**: Root lint (26 tasks), type-check (26 tasks), check:audits (60 audits), test (20 workspace tasks plus script tests), and applicable block-registry checks against origin/staging passed. Full app run: 3,378 files, 37,636 passed, and 12 skipped. Existing warnings in two unchanged tests remain. The initial docs audit added, edited, or removed no tests; the later picker-selector follow-up is recorded below. +- **CLI discovery**: Existing tests reproduced a real search regression when the word spent was removed. Help now retains credits spent without the inaccurate this-period claim; all 17 search tests and the complete CLI suite pass. +- **Production build**: Final apps/docs build passed after the source and layout corrections, generating 1,588 static outputs and full Markdown. A dummy loopback DATABASE_URL was used; no database or authenticated product request was exercised. +- **HTTP checks**: 1,631/1,631 pass: 789 HTML routes, 789 per-page Markdown routes, 37 local assets, root/missing-route/noindex checks, full Markdown byte equality and API-operation exclusion, CLI.mdx, OpenAPI JSON, negotiated Markdown/Vary Accept, and integration landing backlinks. +- **Rendered checks**: All 483 readable in-scope routes inspected at 320px with zero prose or root overflow. All 20 authored-tab pages checked across 101 states (81 selections). Mixed panels retain 16px padding, code-only panels fill the frame, and narrow tab targets reach 44px. Intentional code/table/tab-strip scrolling retained. +- **Responsive navigation**: MCP and generated API checked at 320, 390, 639, 640, 767, 768, 1023, 1024, 1279, 1280, and 1536px. Titles clear actual chrome by 24/32/56px with no empty API TOC row. Drawer faces are 30px, mobile targets 44px, and the aligned 101px header passes at 320/700px. All four section links close the drawer; Escape restores Open Sidebar focus. Native modal keeps other page controls inert; keyboard boundaries may enter browser chrome. A later API tablet header-span defect was reproduced and corrected; fresh checks additionally assert full header width at 768–1023px and right-aligned controls at 768px. +- **SSO accessibility and bookmarks**: Explicit native controls reciprocally link all five panels. End/ArrowLeft/Home select and scroll tabs correctly. All five bookmarks pass at 320/768/1536px (15 states), selecting the requested provider with tabs 16.8px below sticky chrome. The pre-fix covered bookmark offset was reproduced. +- **Colors and preview**: All five HTTP method badges checked in light and dark themes; minimum computed contrast is 8.43:1. Inline prose code matches Sim Chat at normal weight, inherited font size and 1px/4px padding in both themes; fenced samples and classed API/schema code keep their own chrome. Dark appearance restored and temporary viewport reset; a verified production API preview remains available. +- **Cleanup**: 111 newly unused original assets removed (15,187,771 bytes), with repository consumer proof. Unused ActionMedia and three workflow previews removed. Authored callouts 234→117, FAQ 58→0 with useful answers moved, media 178→23, and placeholders 36→0. Shared integration assets retained. +- **Evidence**: Detailed local evidence in /tmp/sim-docs-copy-audit includes exact final-comparison/rewrite ledgers, source qualifications, rebase reviews, parity proofs, formatter reproduction, HTTP/render reports and screenshots. The committed audit retains every page’s final comparison and preservation findings. +- **Ship cleanup**: Eight read-only cleanup passes found no React state/effect/memo/callback/query/URL/design issue. Three comment improvements place conditional-write documentation on its owner and shorten redundant reranking/retention notes. That cleanup pass changed no tests. Public hygiene review cleared all 335 regex hits as synthetic examples, documented limits, public references, or repository measurements. +- **Review corrections**: PR review triage corrected 13 findings and aligned three stale convention findings with sentence case; four findings were disproved against owners and real rendering/help output. A complete 303-operation sweep checked 539 canonical input slices and corrected 33 parameter/query metadata claims plus eight empty-query clarity descriptions. MCP probe/reset, hosting, billing source, credential capability, SSO save result, log/connector examples, numeric preview, and Pi color are corrected at their owners. Related request-cap guides distinguish configured caps, decoded-file limits, and effective request limits. +- **Review-round validation**: All regenerated references, eight cleanup passes, root lint, 60 audits, 26 type-check tasks, block-registry checks, five sibling test files (36 tests), and the complete 20-workspace test run pass. App: 3,378 files, 37,636 passed, 12 skipped. Production docs build passed; 135 request examples and 135 curl samples validate. All 1,631 HTTP/Markdown/asset checks pass again. API headers fill mobile/tablet widths across 12 breakpoints, MCP clears its TOC at 320/768/1023px, and the temporary viewport is reset. Deployed Vercel preview is login-protected; content verification uses the local production build. +- **Review-round UI validation**: Both later review findings are corrected: distinct Show/Hide array-item action labels and the canonical Pi canvas sentence with its repository field. Auth labels render without nested code pills, preserve keyboard selection, and keep 30px visible faces with 44px targets. Response headings align with the shared ChipSelect, and its 96px menu aligns to the trigger within 1px at 320/390/768/1023/1280px. Response and request-example pickers retain accessible labels and selection callbacks. Property filters use scoped dependency selectors, including body-portaled schema popovers; focus has no outward ring, narrow inputs fit their frame, and coarse-pointer mobile fields use the shared 44px/16px treatment. +- **Review-round control coverage**: All 303 response menus preserve all 2,919 status choices in canonical order. All 22 choices across eight multi-example request pages produce distinct, nonempty code samples. Seventeen selected response states across list and execution pages show exactly their matching open schema. Matching and empty-result filtering, nested-schema Enter navigation, and Escape focus restoration pass. Fresh final 320px checks cover all 789 routes, including unchanged integrations, with zero root, prose or visible filter-input overflow; intentional code/table/tab/canvas scrolling is retained. All 1,631 HTTP/Markdown/asset checks pass after the final production build. +- **Review-round repository gates**: The final UI changes pass eight cleanup passes, root lint (26 tasks), 60 audits, type-check (26 tasks), block-registry checks, all three docs test files (seven tests), and root tests (20 successful workspace tasks plus script tests; 19 unchanged workspace results reused). An earlier run failed on worker startup/termination and a teardown timeout; all eight affected files then passed (68 tests), and the complete rerun with two workers passed 3,378 app files, 37,636 tests, and 12 skips. No tests or timeout configuration were changed to suppress those failures. Final production docs build generates 1,588 outputs. +- **Accessibility follow-up**: Request-example and response-status trigger names now include the selected value. Browser accessibility trees confirm changed selections announce Request example 3 and status 413 while callbacks, options and styles remain unchanged. Eight cleanup passes are clean. The later tablet TOC warning was independently disproved from compiled CSS: important utilities-layer declarations win over the unlayered important ID rule; fresh 320/768/1023px computations reserve 40px, with tablet headings 32px below the TOC. Full tests and production-build validation for this labels-only follow-up run in CI under the latest user instruction. The earlier all-page and control render proofs still describe the unchanged visual implementation. Normal docs dev startup adds the installed Next.js guidance to AGENTS.md; that standard section is retained alongside the authored editorial instructions. +- **Open-menu accessibility and hydration**: The shared ChipSelect now exposes single choices as menuitemradio with aria-checked from its existing controlled value, matching the main app reasoning-effort picker. Radix keyboard handling, callbacks, row chrome and the multi-select checkbox branch are unchanged; consumer, role-selector and eight cleanup reviews found no behavioral regression. The pre-fix accessibility tree exposed plain menu items; final keyboard checks show exactly one checked choice, its state follows selection, and Escape restores trigger focus. All 22 request examples pass again at 320px with distinct code and correct checked state; response 200/413/503 checked states, schemas, 96px menu width and alignment pass. Docs pickers are nonmodal to avoid applying aria-hidden to the lazily hydrating search footer: the warning was reproduced, then three fresh-page menu checks passed with no warning or hidden siblings. One synthetic interaction before navigation focus settled was repeated after the page settled; no data action occurred. Full final tests and builds run in CI. +- **Picker-test compatibility**: CI reproduced eight failures in four existing tests whose single-choice helpers queried the old menuitem role. Parallel test-audit review retained their shell-quoting, explicit integration-grant, scheduling and unsaved-draft assertions and changed only those helpers to menuitemradio. The existing mobile E2E settings-navigation locator received the same one-line adaptation; ordinary action and ChipDropdown locators remain unchanged. No tests, assertions or production seams were added or removed. Final full suites and mobile E2E run in CI; local regeneration, lint, 60 audits, 26 type-check tasks and block-registry checks pass. diff --git a/apps/docs/EDITORIAL_GUIDE.md b/apps/docs/EDITORIAL_GUIDE.md new file mode 100644 index 00000000000..50c5b39d3ca --- /dev/null +++ b/apps/docs/EDITORIAL_GUIDE.md @@ -0,0 +1,87 @@ +# Documentation editorial guide + +Use this guide with [Sim's product language](../../.claude/rules/constitution.md). Documentation explains how the current product works. Each page should help a reader complete a task, understand a decision, or look up a contract. + +## Voice and terminology + +- Lead with one or two sentences explaining the task or behavior. Use active voice, short sentences, concrete examples, and imperative steps. +- Remove promotional adjectives, repeated introductions, generic benefits, and unsupported guarantees. Prefer “Deploy the workflow” to “Unlock the power of automation.” +- Name the actor when access matters: member, workspace Admin, organization owner, personal API-key caller, or workspace API key. A workspace role, OAuth scope, resource grant, and permission-group restriction are different controls. +- Use **Sim** for the conversational agent, **Chat** for its surface, and **workflow builder** for the visual editor. Workflow terminology is appropriate when documenting the Workflows module. Preserve literal command names, protocol identifiers, environment keys, and compatibility fields. +- Use sentence case for titles, descriptions, headings, navigation labels, and API summaries. Preserve product names and acronyms such as API, MCP, OAuth, and SSO. Define unfamiliar terms on introductory pages. +- Match visible UI labels exactly and format them in **bold**. Format commands, paths, fields, statuses, and literal values as `code`. Keep code examples copyable. +- Use KiB, MiB, and GiB for limits defined in powers of 1024. Identify whether a number is a default, a hard limit, a configurable setting, or an illustrative example. + +## Page organization + +Use the order appropriate to the page. These are ordering rules, not a requirement to add empty sections. + +| Page type | Order | +| --- | --- | +| Overview | Purpose → when to use it and supported capabilities → shortest path to use → important boundaries → related docs | +| Task guide | Result → actual prerequisites → numbered steps with examples at the relevant step → verify the result → limits or troubleshooting → related docs | +| Concept | Purpose or decision → behavior and example → boundaries and edge cases → related docs | +| Block reference | Purpose → minimum working example → settings and inputs → outputs → behavior, limits, and errors → distinct additional examples → related docs | +| Operator guide | Deployment scope → prerequisites → supported setup → verification → operational and security consequences → troubleshooting or reference → related docs | +| Command or API reference | Purpose and access → invocation or request example → inputs and defaults → outputs and statuses → consequences, errors, and limits → related references | + +Group large references by resource and lifecycle. Keep comprehensive machine references when they serve a separate lookup purpose. Keep prerequisites before the action they govern and destructive consequences before the command or control that triggers them. + +Prefer concrete headings such as “Create a connection,” “Outputs,” or “Handle failed requests” over “Overview,” “Advanced features,” and “Best practices.” End onward navigation under **Related docs**, after substantive content. + +## Preserve useful information + +Shorten by removing repetition and organizing facts. There is no universal word limit. + +Keep exact syntax, required fields, permissions, defaults, unsupported cases, resource limits, billing behavior, security boundaries, failure effects, and recovery procedures. Distinguish Cloud from self-hosted deployments and billing-enabled behavior from billing-disabled behavior. Distinguish drafts from deployed versions and an accepted operation from completed background work. + +Verify claims against the current owning implementation and visible controls. Use current primary documentation for external services. A repository default does not prove the live hosted configuration. If sources disagree, qualify the statement and record the unresolved conflict in the audit rather than choosing an unsupported guarantee. + +Give repeated detail one canonical owner: + +| Detail | Canonical owner | +| --- | --- | +| Setup requirements and procedures | The relevant task or operator guide | +| Feature behavior, outputs, and limits | The feature or block reference | +| Roles, resource grants, and membership | Permissions and the specific resource guide | +| Permission-group resolution | Enterprise permission groups | +| Effective retention and cleanup | Enterprise data retention | +| Credits, metering, and billing distinctions | Costs | +| API authentication and envelopes | API getting started and authentication | +| Streaming frames and protocol | Workflow streaming guide | +| CLI options and command consequences | Generated command reference | + +A link replaces repeated detail only after the owner contains it. Keep a concise prerequisite or consequence at the point where the reader needs it. + +## Components and media + +- Fold useful FAQ answers into the section they explain. Keep a separate FAQ only for questions that cannot be organized coherently elsewhere. +- Use a callout for a specific prerequisite or a non-obvious security, data-loss, or operational risk that deserves interruption. Use ordinary prose or a table for normal explanation. Keep important limits visible. +- Use Markdown lists and tables for simple procedures and reference data. Use tabs for distinct configurations and Steps for substantial sequential procedures. +- Match inline code to Sim Chat: normal-weight monospace text, tight padding, and the existing borderless filled surface tokens. Scope the treatment to prose code; preserve fenced examples, API route bars, schema controls, and selector labels. +- Use shared `ChipSelect` controls for API response and request-example pickers, with accessible names that include the current value, checked radio semantics for single choices, and menus aligned to their triggers. Keep docs pickers nonmodal so they do not hide lazily hydrating siblings. Keep response headings free of inherited extra margins. Scope dependency filter styling to `data-object-search-input`, including schema popovers portaled to the body; focus stays inside the field, and touch fields retain the shared target and text sizes. +- Import authored tabs from `@/components/ui/tabs`. Mixed panels retain a content inset; only a single code fence fills the frame. Keep long tab lists horizontally scrollable and long prose references wrapped. For bookmarked panels, use explicit native `TabsList`/`TabsTrigger` controls with `aria-controls` matching each panel ID; changing a panel ID alone leaves the generated control pointing at a nonexistent element. +- Keep a screenshot when it locates a difficult control or shows a meaningful result. Keep a video when motion explains behavior that text or a static example cannot. Remove decorative, redundant, misleading, or non-rendering media. +- Inspect media before describing it as stale. Uninspected remote media is unverified; it may still be removed when the written procedure fully covers its purpose. Do not fabricate replacement captures. +- Remove imports, components, preview definitions, local styling, and assets made unused by an edit after checking all consumers, including integration pages. + +## Links and generated sources + +Preserve page paths and stable operation IDs. Before renaming a heading, check inbound links from all docs and application code. Preserve a referenced anchor with a custom heading ID such as `## New heading [#existing-anchor]`. Check links from integration pages even when their copy is outside the editing scope. + +Edit generated prose at its owner, then regenerate: + +| Output | Owner | Command from the repository root | +| --- | --- | --- | +| OpenAPI documents and operation pages | `apps/sim/lib/api/contracts/v2/**`, OpenAPI metadata, and `scripts/openapi/generator.ts` | `bun run generate:openapi` | +| CLI API inputs | Generated OpenAPI and CLI contract overrides | `bun run generate:cli-api` | +| CLI reference pages and navigation | Command tree, CLI metadata, and `scripts/generate-cli-docs.ts` | `bun run generate:cli-docs` | +| MCP operation catalog | Authorized operation definitions and generated OpenAPI | `bun run generate:mcp-operations` | +| v2 route table | Canonical route definitions | `bun run generate:v2-route-table` | +| Marked Agent streaming table | Streaming protocol metadata and `scripts/sync-agent-stream-docs.ts` | `bun run generate:agent-stream-docs` | + +Do not hand-edit generated pages, JSON specifications, or marked generated regions. Preserve all argument, option, schema, authentication, and confirmation detail. CLI descriptions also feed command discovery; run the existing search-ranking checks after changing help copy. Validate rendered request examples against their canonical input contracts; schema validity alone may still leave a semantic error such as an invalid serialized workflow. + +## Review checklist + +Read the complete page and its examples. Check every useful fact against the original before cutting or moving it. Confirm the opening, order, terminology, headings, and component choices follow this guide. Compile MDX, check internal links and anchors, regenerate affected references, and inspect representative rendered pages on desktop and a narrow viewport. Run the repository's required validation gates for source changes. diff --git a/apps/docs/README.md b/apps/docs/README.md index 4bdd01e9e6d..f29f2d48930 100644 --- a/apps/docs/README.md +++ b/apps/docs/README.md @@ -1,23 +1,27 @@ -# docs +# Sim documentation -This is a Next.js application generated with -[Create Fumadocs](https://github.com/fuma-nama/fumadocs). +The documentation site uses Next.js and Fumadocs. Read the [editorial guide](EDITORIAL_GUIDE.md) before changing copy or page organization. The [copy audit](COPY_AUDIT.md) records the complete page inventory, accuracy corrections, and validation. -Run development server: +## Develop + +From this directory: ```bash bun run dev ``` -Open http://localhost:3000 with your browser to see the result. +Open `http://localhost:3001`. Build the site with `bun run build` and run the built server with `bun run start`. + +## Content owners + +- Authored pages and navigation: `content/docs/**` and each section's `meta.json`. +- API operation pages: generated `openapi*.json`, owned by `apps/sim/lib/api/contracts/v2/**` and `scripts/openapi/generator.ts`. +- CLI reference pages: generated from the command tree by `scripts/generate-cli-docs.ts`. +- Interactive workflow examples: `components/workflow-preview/**`. +- Local media: `public/static/**`. Videos resolved through `getAssetUrl` may be hosted remotely. -## Learn More +Use the owner and generation commands listed in the editorial guide. Do not hand-edit generated reference pages. The build also generates `llms-full.txt` from the current content. -To learn more about Next.js and Fumadocs, take a look at the following -resources: +## Validate -- [Next.js Documentation](https://nextjs.org/docs) - learn about Next.js - features and API. -- [Learn Next.js](https://nextjs.org/learn) - an interactive Next.js tutorial. -- [Fumadocs](https://fumadocs.vercel.app) - learn about Fumadocs -- [Bun Documentation](https://bun.sh/docs) - learn about Bun features and API +From the repository root, run the required lint, type, audit, and test gates in the development guidelines. From this directory, `bun run type-check` compiles MDX and checks the docs workspace, and `bun run build` validates the production site. Inspect affected page types on desktop and a narrow viewport, and check internal links and existing anchors after heading changes. diff --git a/apps/docs/app/[[...slug]]/page.tsx b/apps/docs/app/[[...slug]]/page.tsx index 689c7b0a69e..5c31e9a89d8 100644 --- a/apps/docs/app/[[...slug]]/page.tsx +++ b/apps/docs/app/[[...slug]]/page.tsx @@ -1,5 +1,12 @@ import type React from 'react' import { Children, cloneElement, isValidElement } from 'react' +import { + chipFieldSurfaceClass, + chipFieldTextClass, + chipGeometryClass, + chipHoverSurfaceClass, + cn, +} from '@sim/emcn' import { highlight } from 'fumadocs-core/highlight' import { findNeighbour } from 'fumadocs-core/page-tree' import type { ApiPageProps } from 'fumadocs-openapi/ui' @@ -26,7 +33,7 @@ import { DOCS_BASE_URL } from '@/lib/urls' const BASE_URL = DOCS_BASE_URL /** - * Most pages close with a `## Next` / `## Next steps` grid of onward links. + * Pages close with related-documentation links or legacy next-step links. * That heading is navigation, not content, so it is kept out of the table of * contents — the ToC should say what the page covers, not where to go after it. * The heading itself still renders above the cards. @@ -34,7 +41,15 @@ const BASE_URL = DOCS_BASE_URL * Matched on the slug rather than the rendered title because a ToC title is a * `ReactNode`; the trailing group tolerates the slugger's dedupe suffix. */ -const ONWARD_NAV_SLUG = /^#next(-steps)?(-\d+)?$/i +const ONWARD_NAV_SLUG = /^#(?:next(?:-steps)?|related-docs)(?:-\d+)?$/i + +const AUTH_SCHEME_LABELS: Record = { + apiKey: 'API key', + oauthBearer: 'OAuth access token', +} + +const DOCS_BODY_CLASS_NAME = + '[overflow-wrap:anywhere] [&_:not(pre)>code:not([class])]:rounded! [&_:not(pre)>code:not([class])]:px-1! [&_:not(pre)>code:not([class])]:py-px! [&_:not(pre)>code:not([class])]:font-normal! [&_:not(pre)>code:not([class])]:text-[var(--text-primary)]! [&_:not(pre)>code:not([class])]:[font-size:inherit]! [&_:not(pre)>code:not([class])]:bg-[var(--surface-5)]! dark:[&_:not(pre)>code:not([class])]:bg-[var(--surface-4)]!' function isContentHeading(item: { url: string }): boolean { return !ONWARD_NAV_SLUG.test(item.url) @@ -55,19 +70,42 @@ async function ApiCodeBlock({ lang, code }: { lang: string; code: string }) { } interface ApiSlotElementProps extends React.HTMLAttributes { - items?: unknown[] + items?: Array<{ value: string; label: React.ReactNode }> } /** Labels Fumadocs auth selectors while retaining their selection state and content. */ function labelAuthSelectors(node: React.ReactNode): React.ReactNode { + if (typeof node === 'string') return AUTH_SCHEME_LABELS[node] ?? node if (!isValidElement(node)) return node const props = node.props const children = props.children === undefined ? undefined : Children.map(props.children, labelAuthSelectors) + if (node.type === 'code') { + return {children} + } + if (Array.isArray(props.items)) { - return cloneElement(node, { 'aria-label': 'Authentication method' }, children) + return cloneElement( + node, + { + 'aria-label': 'Authentication method', + className: cn( + props.className, + chipGeometryClass, + chipFieldSurfaceClass, + chipFieldTextClass, + chipHoverSurfaceClass, + 'relative shrink-0 py-0 focus:ring-0 focus-visible:bg-[var(--surface-hover)] before:absolute before:inset-x-0 before:-inset-y-[7px] before:content-[""]' + ), + items: props.items.map((item) => ({ + ...item, + label: labelAuthSelectors(item.label), + })), + }, + children + ) } return children === undefined ? node : cloneElement(node, undefined, children) } @@ -89,22 +127,30 @@ const APIPage = createAPIPage(openapi, { content: { renderOperationLayout: (slots) => { return ( -
-
+
+
{slots.header} {slots.description} {slots.apiPlayground} {slots.authSchemes && ( -
{labelAuthSelectors(slots.authSchemes)}
+
+ {labelAuthSelectors(slots.authSchemes)} +

+ Request examples use an API key. For OAuth, replace the X-API-Key{' '} + header with Authorization: Bearer YOUR_ACCESS_TOKEN. +

+
)} +
+
+ {slots.apiExample} +
+
{slots.parameters} {slots.body &&
{slots.body}
} {slots.responses} {slots.callbacks}
-
- {slots.apiExample} -
) }, @@ -196,6 +242,7 @@ export default async function Page(props: { params: Promise<{ slug?: string[] }> breadcrumb={breadcrumbs} />
- + @@ -267,7 +314,7 @@ export default async function Page(props: { params: Promise<{ slug?: string[] }>
- + {integrationLandingPage && (

{INTEGRATION_LANDING_LABEL}{' '} diff --git a/apps/docs/app/layout.tsx b/apps/docs/app/layout.tsx index 121e03e48ed..3fbe2958a6e 100644 --- a/apps/docs/app/layout.tsx +++ b/apps/docs/app/layout.tsx @@ -1,5 +1,5 @@ import type { ReactNode } from 'react' -import { INTEGRATION_REACH } from '@sim/deployment-config/integration-claims' +import { defaultTranslations as openApiTranslations } from 'fumadocs-openapi/i18n' import { DocsLayout } from 'fumadocs-ui/layouts/docs' import { SidebarProvider, SidebarTrigger, useSidebar } from 'fumadocs-ui/layouts/docs/slots/sidebar' import { RootProvider } from 'fumadocs-ui/provider/next' @@ -22,13 +22,46 @@ const inter = Inter({ display: 'swap', }) -const DOCS_DESCRIPTION = `Documentation for Sim — the open-source AI workspace where teams build, deploy, and manage AI agents. Connect ${INTEGRATION_REACH} and every major LLM.` +const DOCUMENTATION_DESCRIPTION = + 'Guides and API references for Sim, the open-source AI workspace. Learn how to use Chat, build workflows, manage data, and operate your deployment.' + +const OPENAPI_TRANSLATIONS = { + ...openApiTranslations, + titleRequestTabs: 'Request examples', + queryParameters: 'Query parameters', + pathParameters: 'Path parameters', + headerParameters: 'Header parameters', + cookieParameters: 'Cookie parameters', + titleRequestBody: 'Request body', + titleResponseBody: 'Response body', + typeScriptDefinitions: 'TypeScript definitions', + schemaMultipleOf: 'Multiple of', + closeJsonEditor: 'Close JSON editor', + openJsonEditor: 'Open JSON editor', + accessToken: 'Access token', + statusBadRequest: 'Bad request', + statusNotFound: 'Not found', + statusInternalServerError: 'Internal server error', + statusClientError: 'Client error', + resourceOwnerPassword: 'Resource owner password flow', + clientCredentials: 'Client credentials', + deviceAuthorization: 'Device authorization', + clientSecret: 'Client secret', + serverUrlFieldPlaceholder: 'Enter value', + schemaShowArray: 'Show array item', + schemaHideArray: 'Hide array item', + schemaFilterPropertiesPlaceholder: 'Filter properties', + playgroundShowProperty: 'Show property', + playgroundPropertyPlaceholder: 'Enter property name', + playgroundNewItem: 'New item', + playgroundRemoveItem: 'Remove item', +} const structuredData = { '@context': 'https://schema.org', '@type': 'WebSite', name: 'Sim Documentation', - description: DOCS_DESCRIPTION, + description: DOCUMENTATION_DESCRIPTION, url: DOCS_BASE_URL, publisher: { '@type': 'Organization', @@ -53,14 +86,17 @@ export default function RootLayout({ children }: { children: ReactNode }) { dangerouslySetInnerHTML={{ __html: serializeJsonLd(structuredData) }} /> - + - + #nd-subnav]:flex! md:max-lg:[&>#nd-subnav]:col-[main-start/toc-end]! max-xl:has-[>[data-toc-popover]]:[--fd-toc-popover-height:40px]! max-xl:[&>[data-toc-popover]]:block! [--text-muted:var(--text-secondary)] [--color-fd-muted-foreground:var(--text-secondary)]', }} > {children} @@ -118,10 +154,10 @@ export const viewport: Viewport = { export const metadata = { metadataBase: new URL(DOCS_BASE_URL), title: { - default: 'Sim Documentation — The AI Workspace for Teams', + default: 'Sim documentation', template: '%s | Sim Docs', }, - description: DOCS_DESCRIPTION, + description: DOCUMENTATION_DESCRIPTION, applicationName: 'Sim Docs', generator: 'Next.js', referrer: 'origin-when-cross-origin' as const, @@ -166,8 +202,8 @@ export const metadata = { locale: 'en_US', url: DOCS_BASE_URL, siteName: 'Sim Documentation', - title: 'Sim Documentation — The AI Workspace for Teams', - description: DOCS_DESCRIPTION, + title: 'Sim documentation', + description: DOCUMENTATION_DESCRIPTION, images: [ { url: `${DOCS_BASE_URL}/api/og?title=Sim%20Documentation`, @@ -179,8 +215,8 @@ export const metadata = { }, twitter: { card: 'summary_large_image', - title: 'Sim Documentation — The AI Workspace for Teams', - description: DOCS_DESCRIPTION, + title: 'Sim documentation', + description: DOCUMENTATION_DESCRIPTION, creator: '@simdotai', site: '@simdotai', images: [`${DOCS_BASE_URL}/api/og?title=Sim%20Documentation`], diff --git a/apps/docs/components/docs-layout/docs-sidebar.tsx b/apps/docs/components/docs-layout/docs-sidebar.tsx index 1c8b890b6c7..252cdb604a1 100644 --- a/apps/docs/components/docs-layout/docs-sidebar.tsx +++ b/apps/docs/components/docs-layout/docs-sidebar.tsx @@ -13,6 +13,7 @@ import { SidebarItem, SidebarSeparator, } from '@/components/docs-layout/sidebar-components' +import { DOCS_SECTIONS, getDocsSection } from '@/lib/navigation' import { cn } from '@/lib/utils' interface SidebarTreeProps { @@ -67,6 +68,7 @@ export function DocsSidebar() { const dialogRef = useRef(null) const { open, setOpen } = useSidebar() const mobile = useMediaQuery('(width < 1024px)') + const section = getDocsSection(usePathname()) useEffect(() => { const dialog = dialogRef.current @@ -91,25 +93,34 @@ export function DocsSidebar() { }} className='fixed inset-y-0 right-0 left-auto m-0 h-dvh max-h-none w-[85%] max-w-[380px] border-[var(--border)] border-l bg-[var(--surface-1)] p-0 text-[var(--text-body)] backdrop:bg-black/30 backdrop:backdrop-blur-xs open:flex open:flex-col' > -

- Documentation - setOpen(false)} /> +
+
+ Documentation + setOpen(false)} + /> +
+
+ {DOCS_SECTIONS.map((item) => ( + setOpen(false)} + > + {item.compactLabel} + + ))} +
-
- {[ - ['Docs', '/introduction'], - ['API Reference', '/api-reference/getting-started'], - ['CLI', '/cli'], - ['MCP', '/mcp/overview'], - ].map(([label, href]) => ( - setOpen(false)}> - {label} - - ))} -
{open && } ) diff --git a/apps/docs/components/docs-layout/page-header.tsx b/apps/docs/components/docs-layout/page-header.tsx index 9b3b3b20195..a883bdc1431 100644 --- a/apps/docs/components/docs-layout/page-header.tsx +++ b/apps/docs/components/docs-layout/page-header.tsx @@ -10,7 +10,7 @@ interface PageHeaderProps { export function PageHeader({ title, children, className }: PageHeaderProps) { return ( -
+
{title} diff --git a/apps/docs/components/footer/footer.tsx b/apps/docs/components/footer/footer.tsx index 40ada5d217d..73d2d8d490f 100644 --- a/apps/docs/components/footer/footer.tsx +++ b/apps/docs/components/footer/footer.tsx @@ -28,7 +28,7 @@ const PRODUCT_LINKS: FooterItem[] = [ { label: 'Tables', href: '/tables' }, { label: 'MCP', href: '/agents/mcp' }, { label: 'API', href: '/api-reference/getting-started' }, - { label: 'Self Hosting', href: '/platform/self-hosting' }, + { label: 'Self-hosting', href: '/platform/self-hosting' }, { label: 'Status', href: 'https://status.sim.ai', external: true }, ] @@ -42,7 +42,7 @@ const RESOURCES_LINKS: FooterItem[] = [ /** Top model providers — mirrors the landing footer's top 7 catalog providers. */ const MODEL_LINKS: FooterItem[] = [ - { label: 'All Models', href: `${SIM_SITE_URL}/models`, external: true }, + { label: 'All models', href: `${SIM_SITE_URL}/models`, external: true }, { label: 'OpenAI', href: `${SIM_SITE_URL}/models/openai`, external: true }, { label: 'Anthropic', href: `${SIM_SITE_URL}/models/anthropic`, external: true }, { label: 'Google', href: `${SIM_SITE_URL}/models/google`, external: true }, @@ -57,7 +57,7 @@ const BLOCK_LINKS: FooterItem[] = [ { label: 'Router', href: '/workflows/blocks/router' }, { label: 'Function', href: '/workflows/blocks/function' }, { label: 'Condition', href: '/workflows/blocks/condition' }, - { label: 'API Block', href: '/workflows/blocks/api' }, + { label: 'API', href: '/workflows/blocks/api' }, { label: 'Workflow', href: '/workflows/blocks/workflow' }, { label: 'Parallel', href: '/workflows/blocks/parallel' }, { label: 'Guardrails', href: '/workflows/blocks/guardrails' }, @@ -66,7 +66,7 @@ const BLOCK_LINKS: FooterItem[] = [ ] const INTEGRATION_LINKS: FooterItem[] = [ - { label: 'All Integrations', href: `${SIM_SITE_URL}/integrations`, external: true }, + { label: 'All integrations', href: `${SIM_SITE_URL}/integrations`, external: true }, { label: 'Slack', href: '/integrations/slack' }, { label: 'GitHub', href: '/integrations/github' }, { label: 'Gmail', href: '/integrations/gmail' }, @@ -98,8 +98,8 @@ const SOCIAL_LINKS: FooterItem[] = [ ] const LEGAL_LINKS: FooterItem[] = [ - { label: 'Terms of Service', href: `${SIM_SITE_URL}/terms`, external: true }, - { label: 'Privacy Policy', href: `${SIM_SITE_URL}/privacy`, external: true }, + { label: 'Terms of service', href: `${SIM_SITE_URL}/terms`, external: true }, + { label: 'Privacy policy', href: `${SIM_SITE_URL}/privacy`, external: true }, ] function FooterColumn({ title, items }: { title: string; items: FooterItem[] }) { diff --git a/apps/docs/components/navbar/navbar.tsx b/apps/docs/components/navbar/navbar.tsx index e918b9983ed..c10139356ca 100644 --- a/apps/docs/components/navbar/navbar.tsx +++ b/apps/docs/components/navbar/navbar.tsx @@ -6,55 +6,12 @@ import { usePathname } from 'next/navigation' import { SearchTrigger } from '@/components/ui/search-trigger' import { SimWordmark } from '@/components/ui/sim-logo' import { ThemeToggle } from '@/components/ui/theme-toggle' +import { DOCS_SECTIONS, getDocsSection } from '@/lib/navigation' import { SIM_SITE_URL } from '@/lib/urls' import { cn } from '@/lib/utils' -/** - * Sections that own a tab, in reading order: the main docs, then the three - * reference surfaces. `Documentation` matches by exclusion, so - * every section listed here is one it must not claim. - */ -const SECTION_TABS = ['api-reference', 'cli', 'mcp'] as const - -/** - * Whether a pathname is inside a section, matched on its first path segment. - * - * A substring or suffix test is wrong: `/integrations/clickup` contains `/cli`, - * and `/agents/mcp` ends with `/mcp`, and both belong to Documentation. - */ -function isInSection(pathname: string, section: string): boolean { - return pathname === `/${section}` || pathname.startsWith(`/${section}/`) -} - -const NAV_TABS = [ - { - label: 'Documentation', - href: '/introduction', - match: (p: string) => !SECTION_TABS.some((section) => isInSection(p, section)), - external: false, - }, - { - label: 'API Reference', - href: '/api-reference/getting-started', - match: (p: string) => isInSection(p, 'api-reference'), - external: false, - }, - { - label: 'CLI', - href: '/cli', - match: (p: string) => isInSection(p, 'cli'), - external: false, - }, - { - label: 'MCP', - href: '/mcp/overview', - match: (p: string) => isInSection(p, 'mcp'), - external: false, - }, -] as const - export function Navbar() { - const pathname = usePathname() + const section = getDocsSection(usePathname()) return (
@@ -90,19 +47,18 @@ export function Navbar() { paddingLeft: 'calc(var(--sidebar-offset) + var(--nav-inset))', }} > - {NAV_TABS.map((tab) => { - const isActive = !tab.external && tab.match(pathname) + {DOCS_SECTIONS.map((tab) => { + const isActive = section === tab.slug return ( {/* Invisible bold text reserves width to prevent layout shift */} diff --git a/apps/docs/components/ui/action-media.tsx b/apps/docs/components/ui/action-media.tsx deleted file mode 100644 index 79d47f5477a..00000000000 --- a/apps/docs/components/ui/action-media.tsx +++ /dev/null @@ -1,84 +0,0 @@ -'use client' - -import { useRef, useState } from 'react' -import { Lightbox } from '@sim/emcn' -import { cn, getAssetUrl } from '@/lib/utils' - -interface ActionImageProps { - src: string - alt: string - enableLightbox?: boolean -} - -interface ActionVideoProps { - src: string - alt: string - enableLightbox?: boolean -} - -export function ActionImage({ src, alt, enableLightbox = true }: ActionImageProps) { - const image = ( - {alt} - ) - - if (!enableLightbox) return image - - return ( - - - - ) -} - -export function ActionVideo({ src, alt, enableLightbox = true }: ActionVideoProps) { - const videoRef = useRef(null) - const [startTime, setStartTime] = useState(0) - const resolvedSrc = getAssetUrl(src) - - const openLightbox = () => { - setStartTime(videoRef.current?.currentTime ?? 0) - } - - const video = ( - - ) - - if (!enableLightbox) return video - - return ( - - - - ) -} diff --git a/apps/docs/components/ui/api-example-selector.tsx b/apps/docs/components/ui/api-example-selector.tsx index 7f517ceba88..d3c8eb0f52a 100644 --- a/apps/docs/components/ui/api-example-selector.tsx +++ b/apps/docs/components/ui/api-example-selector.tsx @@ -1,15 +1,7 @@ 'use client' import type { ComponentProps } from 'react' -import { useId } from 'react' -import { - ChipChevronDown, - chipFieldSurfaceClass, - chipFieldTextClass, - chipGeometryClass, - chipHoverSurfaceClass, - cn, -} from '@sim/emcn' +import { ChipSelect } from '@sim/emcn' import type { APIPageClientOptions } from 'fumadocs-openapi/ui/client' type FumadocsAPIExampleSelector = NonNullable< @@ -19,8 +11,6 @@ type FumadocsAPIExampleSelector = NonNullable< interface APIExampleSelectorProps extends ComponentProps {} export function APIExampleSelector({ items, value, onValueChange }: APIExampleSelectorProps) { - const id = useId() - if (items.length <= 1) return null const selectedValue = value ?? items[0].id @@ -28,34 +18,16 @@ export function APIExampleSelector({ items, value, onValueChange }: APIExampleSe return (
- -
- - -
+ ({ value: item.id, label: item.name }))} + fullWidth + align='start' + dropdownWidth='trigger' + /> {selectedItem?.description && (

{selectedItem.description}

)} diff --git a/apps/docs/components/ui/response-section.tsx b/apps/docs/components/ui/response-section.tsx index 9637b27b7a7..43e42e1d9bc 100644 --- a/apps/docs/components/ui/response-section.tsx +++ b/apps/docs/components/ui/response-section.tsx @@ -1,21 +1,13 @@ 'use client' -import { useEffect, useId, useRef, useState } from 'react' -import { - ChipChevronDown, - chipFieldSurfaceClass, - chipFieldTextClass, - chipGeometryClass, - chipHoverSurfaceClass, - cn, -} from '@sim/emcn' +import { useEffect, useRef, useState } from 'react' +import { ChipSelect } from '@sim/emcn' interface ResponseSectionProps { children: React.ReactNode } export function ResponseSection({ children }: ResponseSectionProps) { - const id = useId() const containerRef = useRef(null) const [statusCodes, setStatusCodes] = useState([]) const [selectedCode, setSelectedCode] = useState('') @@ -96,33 +88,19 @@ export function ResponseSection({ children }: ResponseSectionProps) { return (
{statusCodes.length > 0 && ( -
-

Response

-
-
- - - -
+
+

Response

+
+ ({ label: code, value: code }))} + align='end' + dropdownWidth={96} + contentClassName='min-w-0' + /> application/json
diff --git a/apps/docs/components/ui/tabs.tsx b/apps/docs/components/ui/tabs.tsx new file mode 100644 index 00000000000..6f92e1f6c28 --- /dev/null +++ b/apps/docs/components/ui/tabs.tsx @@ -0,0 +1,37 @@ +import { cn } from '@sim/emcn' +import { + Tab as FumadocsTab, + type TabProps as FumadocsTabProps, + Tabs as FumadocsTabs, + type TabsProps as FumadocsTabsProps, +} from 'fumadocs-ui/components/tabs' + +interface TabsProps extends FumadocsTabsProps {} + +interface TabProps extends FumadocsTabProps {} + +/** Keeps the dependency's selection and keyboard behavior with platform tab tokens. */ +export function Tabs({ className, ...props }: TabsProps) { + return ( + [role=tablist]>button]:font-normal! max-sm:[&>[role=tablist]>button]:min-h-11 [&>[role=tablist]]:min-w-0 [&>[role=tablist]]:[scrollbar-width:thin]! max-sm:[&>[role=tablist]]:min-h-14', + className + )} + /> + ) +} + +/** Only a panel containing a single code fence can omit its content inset. */ +export function Tab({ className, ...props }: TabProps) { + return ( + figure:only-child]:p-0!', + className + )} + /> + ) +} diff --git a/apps/docs/components/workflow-preview/block-display-workflows.ts b/apps/docs/components/workflow-preview/block-display-workflows.ts index 23e1a609d5a..75898672210 100644 --- a/apps/docs/components/workflow-preview/block-display-workflows.ts +++ b/apps/docs/components/workflow-preview/block-display-workflows.ts @@ -34,7 +34,7 @@ export const BLOCK_DISPLAY_WORKFLOWS: Record = { position: { x: 0, y: 0 }, rows: [ { title: 'Messages', value: '-' }, - { title: 'Model', value: 'claude-sonnet-4-6' }, + { title: 'Model', value: 'claude-sonnet-5-5' }, { title: 'Files', value: '-' }, { title: 'Tools', value: '-' }, { title: 'Skills', value: '-' }, @@ -135,7 +135,7 @@ export const BLOCK_DISPLAY_WORKFLOWS: Record = { rows: [ { title: 'Evaluation Metrics', value: '-' }, { title: 'Content', value: '-' }, - { title: 'Model', value: 'claude-sonnet-4-6' }, + { title: 'Model', value: 'claude-sonnet-5-5' }, ], }, ], @@ -219,7 +219,7 @@ export const BLOCK_DISPLAY_WORKFLOWS: Record = { position: { x: 0, y: 0 }, rows: [ { title: 'Context', value: '-' }, - { title: 'Model', value: 'claude-sonnet-4-6' }, + { title: 'Model', value: 'claude-sonnet-5-5' }, ], branches: [{ id: 'route 1', label: 'route 1' }], }, @@ -302,14 +302,14 @@ export const BLOCK_DISPLAY_WORKFLOWS: Record = { { id: 'workflow', name: 'Workflow', - type: 'workflow', + type: 'workflow_input', typeLabel: 'Workflow', sentence: ['Run', { subBlockId: 'Select Workflow', noun: 'workflow' }], bgColor: '#6366F1', position: { x: 0, y: 0 }, rows: [ { title: 'Select Workflow', value: '-' }, - { title: 'Input Variable', value: '-' }, + { title: 'Inputs', value: '-' }, ], }, ], @@ -317,12 +317,12 @@ export const BLOCK_DISPLAY_WORKFLOWS: Record = { }, human_in_the_loop: { id: 'human_in_the_loop', - name: 'Human in the Loop', + name: 'Human', blocks: [ { id: 'human_in_the_loop', - name: 'Human in the Loop', - type: 'human_in_the_loop', + name: 'Human', + type: 'human_in_the_loop_v2', typeLabel: 'Human', sentence: ['Pause execution until a human responds'], bgColor: '#10B981', @@ -336,6 +336,51 @@ export const BLOCK_DISPLAY_WORKFLOWS: Record = { ], edges: [], }, + pi: { + id: 'pi', + name: 'Pi Coding Agent', + blocks: [ + { + id: 'pi', + name: 'Pi coding agent', + type: 'pi', + typeLabel: 'Pi Coding Agent', + bgColor: '#000000', + position: { + x: 0, + y: 0, + }, + rows: [ + { + title: 'Mode', + value: 'Plan', + }, + { + title: 'Task', + value: 'Plan a repository change', + }, + { + title: 'Repository Name', + value: 'my-repo', + }, + { + title: 'Model', + value: 'claude-sonnet-4-6', + }, + ], + sentence: [ + 'Run', + { subBlockId: 'Task', noun: 'task' }, + 'on', + { subBlockId: 'Repository Name' }, + ', in', + { subBlockId: 'Mode' }, + 'mode', + ], + }, + ], + edges: [], + }, schedule: { id: 'schedule', name: 'Schedule', @@ -415,7 +460,7 @@ export const BLOCK_DISPLAY_WORKFLOWS: Record = { typeLabel: 'Table', sentence: [ 'Run on', - { subBlockId: 'Event type', noun: 'event' }, + { subBlockId: 'Event', noun: 'event' }, 'in', { subBlockId: 'Table', noun: 'table' }, ], @@ -424,8 +469,8 @@ export const BLOCK_DISPLAY_WORKFLOWS: Record = { hideTargetHandle: true, rows: [ { title: 'Table', value: '-' }, - { title: 'Event type', value: 'Row updated' }, - { title: 'Watch columns', value: '-' }, + { title: 'Event', value: 'Row Updated' }, + { title: 'Watch Columns', value: '-' }, ], }, ], diff --git a/apps/docs/components/workflow-preview/examples.ts b/apps/docs/components/workflow-preview/examples.ts index 779b470acb7..21864d4b529 100644 --- a/apps/docs/components/workflow-preview/examples.ts +++ b/apps/docs/components/workflow-preview/examples.ts @@ -34,8 +34,16 @@ export const CLASSIFY_WORKFLOW: PreviewWorkflow = { bgColor: '#33C482', position: { x: 340, y: 0 }, rows: [ - { title: 'Model', value: 'claude-sonnet-4-6' }, - { title: 'Messages', value: 'Classify ' }, + { title: 'Model', value: 'claude-sonnet-5-5' }, + { + title: 'Messages', + value: 'Classify into sales, support, or billing and low or high urgency.', + }, + { + title: 'Response Format', + value: + '{"name":"message_classification","schema":{"type":"object","properties":{"category":{"type":"string","enum":["sales","support","billing"]},"urgency":{"type":"string","enum":["low","high"]}},"required":["category","urgency"],"additionalProperties":false}}', + }, ], }, ], @@ -76,7 +84,7 @@ export const CLASSIFY_REPLY_WORKFLOW: PreviewWorkflow = { bgColor: '#33C482', position: { x: 330, y: 0 }, rows: [ - { title: 'Model', value: 'claude-sonnet-4-6' }, + { title: 'Model', value: 'claude-sonnet-5-5' }, { title: 'Messages', value: 'Classify ' }, ], }, @@ -94,7 +102,7 @@ export const CLASSIFY_REPLY_WORKFLOW: PreviewWorkflow = { bgColor: '#33C482', position: { x: 660, y: 0 }, rows: [ - { title: 'Model', value: 'claude-sonnet-4-6' }, + { title: 'Model', value: 'claude-sonnet-5-5' }, { title: 'Messages', value: 'Draft a reply for ' }, ], }, @@ -156,7 +164,7 @@ export const SUPPORT_KB_WORKFLOW: PreviewWorkflow = { bgColor: '#33C482', position: { x: 660, y: 0 }, rows: [ - { title: 'Model', value: 'claude-sonnet-4-6' }, + { title: 'Model', value: 'claude-sonnet-5-5' }, { title: 'Messages', value: 'Answer from ' }, ], }, @@ -197,7 +205,7 @@ export const TABLE_ENRICH_WORKFLOW: PreviewWorkflow = { }, { id: 'loop', - name: 'Loop', + name: 'Process leads', type: 'loop', typeLabel: 'Loop', bgColor: '#FAFAF9', @@ -223,8 +231,12 @@ export const TABLE_ENRICH_WORKFLOW: PreviewWorkflow = { position: { x: 70, y: 85 }, parentId: 'loop', rows: [ - { title: 'Messages', value: 'Classify ' }, - { title: 'Response Format', value: '{ "category": "string", "score": "number" }' }, + { title: 'Messages', value: 'Classify ' }, + { + title: 'Response Format', + value: + '{"name":"lead_classification","schema":{"type":"object","properties":{"category":{"type":"string"},"score":{"type":"number"}},"required":["category","score"],"additionalProperties":false}}', + }, ], }, { @@ -247,7 +259,7 @@ export const TABLE_ENRICH_WORKFLOW: PreviewWorkflow = { { title: 'Row Data', value: - '{ "category": , "score": , "status": "processed" }', + '{ "category": "", "score": "", "status": "processed" }', }, ], }, @@ -276,7 +288,7 @@ export const API_FETCH_WORKFLOW: PreviewWorkflow = { bgColor: '#2FB3FF', position: { x: 0, y: 0 }, hideTargetHandle: true, - rows: [{ title: 'Input', value: 'City' }], + rows: [{ title: 'Input', value: 'User ID' }], }, { id: 'api', @@ -293,7 +305,7 @@ export const API_FETCH_WORKFLOW: PreviewWorkflow = { position: { x: 330, y: 0 }, rows: [ { title: 'Method', value: 'GET' }, - { title: 'URL', value: 'api.weather.com/' }, + { title: 'URL', value: 'https://api.example.com/users/' }, ], }, { @@ -310,7 +322,7 @@ export const API_FETCH_WORKFLOW: PreviewWorkflow = { bgColor: '#33C482', position: { x: 660, y: 0 }, rows: [ - { title: 'Model', value: 'claude-sonnet-4-6' }, + { title: 'Model', value: 'claude-sonnet-5-5' }, { title: 'Messages', value: 'Summarize ' }, ], }, @@ -414,7 +426,14 @@ export const CONDITION_MODERATE_WORKFLOW: PreviewWorkflow = { ], bgColor: '#33C482', position: { x: 0, y: 60 }, - rows: [{ title: 'Messages', value: 'Score toxicity of ' }], + rows: [ + { title: 'Messages', value: 'Score toxicity of from 0 to 1.' }, + { + title: 'Response Format', + value: + '{"name":"moderation","schema":{"type":"object","properties":{"toxicity":{"type":"number","minimum":0,"maximum":1}},"required":["toxicity"],"additionalProperties":false}}', + }, + ], }, { id: 'condition', @@ -437,7 +456,7 @@ export const CONDITION_MODERATE_WORKFLOW: PreviewWorkflow = { sentence: ['Run', { subBlockId: 'Code', noun: 'code' }], bgColor: '#FF402F', position: { x: 700, y: 0 }, - rows: [{ title: 'Code', value: "throw 'blocked'" }], + rows: [{ title: 'Code', value: 'throw new Error("Content blocked")' }], }, { id: 'publish', @@ -467,77 +486,6 @@ export const CONDITION_MODERATE_WORKFLOW: PreviewWorkflow = { ], } -/** Condition example: branch onboarding on the account tier. */ -export const CONDITION_ONBOARD_WORKFLOW: PreviewWorkflow = { - id: 'condition-onboard', - name: 'Branch onboarding', - blocks: [ - { - id: 'plan', - name: 'Plan', - type: 'function', - typeLabel: 'Function', - sentence: ['Run', { subBlockId: 'Code', noun: 'code' }], - bgColor: '#FF402F', - position: { x: 0, y: 60 }, - rows: [{ title: 'Code', value: 'return ' }], - }, - { - id: 'condition', - name: 'Condition', - type: 'condition', - typeLabel: 'Condition', - bgColor: '#FF752F', - position: { x: 330, y: 60 }, - rows: [], - branches: [ - { id: 'condition-if', label: 'If', value: " === 'enterprise'" }, - { id: 'condition-else', label: 'else' }, - ], - }, - { - id: 'guided', - name: 'Guided setup', - type: 'agent', - typeLabel: 'Agent', - sentence: [ - 'Prompt', - { subBlockId: 'Model', noun: 'model' }, - 'with', - { subBlockId: 'Messages' }, - ], - bgColor: '#33C482', - position: { x: 700, y: 0 }, - rows: [{ title: 'Messages', value: 'Walk through SSO and SCIM' }], - }, - { - id: 'quickstart', - name: 'Quick start', - type: 'agent', - typeLabel: 'Agent', - sentence: [ - 'Prompt', - { subBlockId: 'Model', noun: 'model' }, - 'with', - { subBlockId: 'Messages' }, - ], - bgColor: '#33C482', - position: { x: 700, y: 140 }, - rows: [{ title: 'Messages', value: 'Send the 2-minute setup' }], - }, - ], - edges: [ - { id: 'plan-condition', source: 'plan', target: 'condition' }, - { id: 'condition-guided', source: 'condition', target: 'guided', sourceHandle: 'condition-if' }, - { - id: 'condition-quickstart', - source: 'condition', - target: 'quickstart', - sourceHandle: 'condition-else', - }, - ], -} - /** Function example: reshape an API response into the field a later block needs. */ export const FUNCTION_RESHAPE_WORKFLOW: PreviewWorkflow = { id: 'function-reshape', @@ -552,7 +500,7 @@ export const FUNCTION_RESHAPE_WORKFLOW: PreviewWorkflow = { bgColor: '#2FB3FF', position: { x: 0, y: 0 }, hideTargetHandle: true, - rows: [{ title: 'Input', value: 'User ID' }], + rows: [{ title: 'Input', value: 'Team ID' }], }, { id: 'api', @@ -569,7 +517,7 @@ export const FUNCTION_RESHAPE_WORKFLOW: PreviewWorkflow = { position: { x: 320, y: 0 }, rows: [ { title: 'Method', value: 'GET' }, - { title: 'URL', value: 'api.example.com/users/' }, + { title: 'URL', value: 'https://api.example.com/teams//users' }, ], }, { @@ -582,7 +530,11 @@ export const FUNCTION_RESHAPE_WORKFLOW: PreviewWorkflow = { position: { x: 640, y: 0 }, rows: [ { title: 'Language', value: 'JavaScript' }, - { title: 'Code', value: 'return .profile' }, + { + title: 'Code', + value: + 'const data = ;\nreturn data.items.filter((item) => item.active).map((item) => item.id);', + }, ], }, ], @@ -592,10 +544,10 @@ export const FUNCTION_RESHAPE_WORKFLOW: PreviewWorkflow = { ], } -/** Function example: validate and clean input before writing it. */ +/** Function example: normalize input before writing it. */ export const FUNCTION_VALIDATE_WORKFLOW: PreviewWorkflow = { id: 'function-validate', - name: 'Validate before write', + name: 'Normalize before write', blocks: [ { id: 'start', @@ -618,7 +570,11 @@ export const FUNCTION_VALIDATE_WORKFLOW: PreviewWorkflow = { position: { x: 320, y: 0 }, rows: [ { title: 'Language', value: 'JavaScript' }, - { title: 'Code', value: 'return sanitize()' }, + { + title: 'Code', + value: + 'return { name: String().trim(), email: String().trim().toLowerCase() };', + }, ], }, { @@ -638,6 +594,7 @@ export const FUNCTION_VALIDATE_WORKFLOW: PreviewWorkflow = { position: { x: 640, y: 0 }, rows: [ { title: 'Method', value: 'POST' }, + { title: 'URL', value: 'https://api.example.com/contacts' }, { title: 'Body', value: '' }, ], }, @@ -673,7 +630,7 @@ export const ROUTER_TRIAGE_WORKFLOW: PreviewWorkflow = { position: { x: 320, y: 95 }, rows: [ { title: 'Context', value: '' }, - { title: 'Model', value: 'claude-sonnet-4-6' }, + { title: 'Model', value: 'claude-sonnet-5-5' }, ], branches: [ { id: 'router-sales', label: 'Sales' }, @@ -780,7 +737,7 @@ export const RESPONSE_API_WORKFLOW: PreviewWorkflow = { bgColor: '#2F55FF', position: { x: 640, y: 0 }, rows: [ - { title: 'Data', value: '{ "answer": }' }, + { title: 'Data', value: '{ "answer": "" }' }, { title: 'Status', value: '200' }, ], }, @@ -823,22 +780,28 @@ export const ROUTER_CLASSIFY_WORKFLOW: PreviewWorkflow = { { id: 'product', name: 'Product', - type: 'workflow', + type: 'workflow_input', typeLabel: 'Workflow', sentence: ['Run', { subBlockId: 'Workflow', noun: 'workflow' }], bgColor: '#6366F1', position: { x: 700, y: 0 }, - rows: [{ title: 'Workflow', value: 'product-intake' }], + rows: [ + { title: 'Workflow', value: 'product-intake' }, + { title: 'Inputs', value: 'input = ' }, + ], }, { id: 'bug', name: 'Bug report', - type: 'workflow', + type: 'workflow_input', typeLabel: 'Workflow', sentence: ['Run', { subBlockId: 'Workflow', noun: 'workflow' }], bgColor: '#6366F1', position: { x: 700, y: 140 }, - rows: [{ title: 'Workflow', value: 'bug-triage' }], + rows: [ + { title: 'Workflow', value: 'bug-triage' }, + { title: 'Inputs', value: 'input = ' }, + ], }, ], edges: [ @@ -848,130 +811,6 @@ export const ROUTER_CLASSIFY_WORKFLOW: PreviewWorkflow = { ], } -/** Router example: qualify a lead into sales or self-serve. */ -export const ROUTER_LEAD_WORKFLOW: PreviewWorkflow = { - id: 'router-lead', - name: 'Qualify a lead', - blocks: [ - { - id: 'start', - name: 'Start', - type: 'start_trigger', - typeLabel: 'Start', - sentence: ['Start the workflow', 'with', { subBlockId: 'Input' }], - bgColor: '#2FB3FF', - position: { x: 0, y: 50 }, - hideTargetHandle: true, - rows: [{ title: 'Input', value: 'Lead' }], - }, - { - id: 'router', - name: 'Router', - type: 'router', - typeLabel: 'Router', - bgColor: '#28C43F', - position: { x: 320, y: 50 }, - rows: [{ title: 'Context', value: '' }], - branches: [ - { id: 'router-enterprise', label: 'Enterprise' }, - { id: 'router-selfserve', label: 'Self-serve' }, - ], - }, - { - id: 'enterprise', - name: 'Enterprise', - type: 'agent', - typeLabel: 'Agent', - sentence: [ - 'Prompt', - { subBlockId: 'Model', noun: 'model' }, - 'with', - { subBlockId: 'Messages' }, - ], - bgColor: '#33C482', - position: { x: 700, y: 0 }, - rows: [{ title: 'Messages', value: 'Book a sales call' }], - }, - { - id: 'selfserve', - name: 'Self-serve', - type: 'workflow', - typeLabel: 'Workflow', - sentence: ['Run', { subBlockId: 'Workflow', noun: 'workflow' }], - bgColor: '#6366F1', - position: { x: 700, y: 140 }, - rows: [{ title: 'Workflow', value: 'onboarding' }], - }, - ], - edges: [ - { id: 'start-router', source: 'start', target: 'router' }, - { - id: 'router-enterprise', - source: 'router', - target: 'enterprise', - sourceHandle: 'router-enterprise', - }, - { - id: 'router-selfserve', - source: 'router', - target: 'selfserve', - sourceHandle: 'router-selfserve', - }, - ], -} - -/** Response example: acknowledge a webhook after processing it. */ -export const RESPONSE_WEBHOOK_WORKFLOW: PreviewWorkflow = { - id: 'response-webhook', - name: 'Acknowledge a webhook', - blocks: [ - { - id: 'webhook', - name: 'Webhook', - type: 'webhook', - typeLabel: 'Webhook', - triggerMode: true, - sentence: ['Run when an HTTP request arrives'], - bgColor: '#10B981', - position: { x: 0, y: 0 }, - hideTargetHandle: true, - rows: [{ title: 'Format', value: 'JSON' }], - }, - { - id: 'process', - name: 'Process', - type: 'function', - typeLabel: 'Function', - sentence: ['Run', { subBlockId: 'Code', noun: 'code' }], - bgColor: '#FF402F', - position: { x: 320, y: 0 }, - rows: [{ title: 'Code', value: 'save()' }], - }, - { - id: 'ack', - name: 'Response', - type: 'response', - typeLabel: 'Response', - sentence: [ - 'Return', - { subBlockId: 'Data', noun: 'response' }, - 'with status', - { subBlockId: 'Status' }, - ], - bgColor: '#2F55FF', - position: { x: 640, y: 0 }, - rows: [ - { title: 'Data', value: '{ "received": true }' }, - { title: 'Status', value: '200' }, - ], - }, - ], - edges: [ - { id: 'webhook-process', source: 'webhook', target: 'process' }, - { id: 'process-ack', source: 'process', target: 'ack' }, - ], -} - /** Response example: return a different status on each branch. */ export const RESPONSE_ERROR_WORKFLOW: PreviewWorkflow = { id: 'response-error', @@ -1003,7 +842,7 @@ export const RESPONSE_ERROR_WORKFLOW: PreviewWorkflow = { }, { id: 'ok', - name: 'Response', + name: 'Success response', type: 'response', typeLabel: 'Response', sentence: [ @@ -1018,7 +857,7 @@ export const RESPONSE_ERROR_WORKFLOW: PreviewWorkflow = { }, { id: 'bad', - name: 'Response', + name: 'Invalid response', type: 'response', typeLabel: 'Response', sentence: [ @@ -1042,50 +881,133 @@ export const RESPONSE_ERROR_WORKFLOW: PreviewWorkflow = { /** Variables example: count retries across attempts. */ export const VARIABLES_RETRY_WORKFLOW: PreviewWorkflow = { id: 'variables-retry', - name: 'Count retries', + name: 'Count retry attempts', blocks: [ { - id: 'api', - name: 'API', + id: 'attempts', + name: 'Retry attempts', + type: 'loop', + typeLabel: 'Loop', + bgColor: '#FAFAF9', + position: { + x: 300, + y: 0, + }, + rows: [ + { + title: 'Loop Type', + value: 'While Loop', + }, + { + title: 'While Condition', + value: ' < 3', + }, + ], + size: { + width: 1060, + height: 450, + }, + }, + { + id: 'attempt', + name: 'Attempt', type: 'api', typeLabel: 'API', - sentence: [ - 'Send', - { subBlockId: 'Method', noun: 'method' }, - 'request to', - { subBlockId: 'URL', noun: 'URL' }, - ], bgColor: '#2F55FF', - position: { x: 0, y: 0 }, - rows: [{ title: 'Method', value: 'GET' }], + position: { + x: 70, + y: 90, + }, + rows: [ + { + title: 'Method', + value: 'GET', + }, + { + title: 'URL', + value: 'https://api.example.com/job', + }, + ], + parentId: 'attempts', }, { - id: 'vars', - name: 'Variables', + id: 'done', + name: 'Finish retries', type: 'variables', typeLabel: 'Variables', - sentence: ['Set', { subBlockId: 'Set', noun: 'variables' }], bgColor: '#8B5CF6', - position: { x: 320, y: 0 }, - rows: [{ title: 'Set', value: 'retryCount + 1' }], + position: { + x: 700, + y: 30, + }, + rows: [ + { + title: 'Variable Assignments', + value: 'retryCount = 3', + }, + ], + parentId: 'attempts', }, { - id: 'condition', - name: 'Condition', - type: 'condition', - typeLabel: 'Condition', - bgColor: '#FF752F', - position: { x: 640, y: 0 }, - rows: [], - branches: [ - { id: 'condition-if', label: 'If', value: ' < 3' }, - { id: 'condition-else', label: 'else' }, + id: 'increment', + name: 'Increment', + type: 'function', + typeLabel: 'Function', + bgColor: '#FF402F', + position: { + x: 380, + y: 230, + }, + rows: [ + { + title: 'Code', + value: 'return + 1;', + }, + ], + parentId: 'attempts', + }, + { + id: 'assign', + name: 'Update counter', + type: 'variables', + typeLabel: 'Variables', + bgColor: '#8B5CF6', + position: { + x: 700, + y: 230, + }, + rows: [ + { + title: 'Variable Assignments', + value: 'retryCount = ', + }, ], + parentId: 'attempts', }, ], edges: [ - { id: 'api-vars', source: 'api', target: 'vars' }, - { id: 'vars-condition', source: 'vars', target: 'condition' }, + { + id: 'attempts-attempt', + source: 'attempts', + target: 'attempt', + sourceHandle: 'loop-start-source', + }, + { + id: 'attempt-done', + source: 'attempt', + target: 'done', + }, + { + id: 'attempt-increment', + source: 'attempt', + target: 'increment', + sourceHandle: 'error', + }, + { + id: 'increment-assign', + source: 'increment', + target: 'assign', + }, ], } @@ -1107,7 +1029,10 @@ export const VARIABLES_CONFIG_WORKFLOW: PreviewWorkflow = { ], bgColor: '#2F55FF', position: { x: 0, y: 0 }, - rows: [{ title: 'URL', value: 'api.example.com/profile' }], + rows: [ + { title: 'URL', value: 'https://api.example.com/profile' }, + { title: 'Method', value: 'GET' }, + ], }, { id: 'vars', @@ -1117,7 +1042,7 @@ export const VARIABLES_CONFIG_WORKFLOW: PreviewWorkflow = { sentence: ['Set', { subBlockId: 'Set', noun: 'variables' }], bgColor: '#8B5CF6', position: { x: 320, y: 0 }, - rows: [{ title: 'Set', value: 'userId, userTier' }], + rows: [{ title: 'Set', value: 'userId = , userTier = ' }], }, { id: 'agent', @@ -1227,6 +1152,7 @@ export const WAIT_FOLLOWUP_WORKFLOW: PreviewWorkflow = { rows: [ { title: 'Amount', value: '2' }, { title: 'Unit', value: 'Days' }, + { title: 'Async', value: 'On' }, ], }, { @@ -1286,7 +1212,7 @@ export const EVALUATOR_GATE_WORKFLOW: PreviewWorkflow = { position: { x: 320, y: 0 }, rows: [ { title: 'Metrics', value: 'Accuracy, Clarity' }, - { title: 'Model', value: 'claude-sonnet-4-6' }, + { title: 'Model', value: 'claude-sonnet-5-5' }, ], }, { @@ -1309,7 +1235,7 @@ export const EVALUATOR_GATE_WORKFLOW: PreviewWorkflow = { ], } -/** Credential example: select one Google account and reuse it across blocks. */ +/** Credential example: select one Slack account and reuse it across compatible actions. */ export const CREDENTIAL_SHARE_WORKFLOW: PreviewWorkflow = { id: 'credential-share', name: 'Share a credential', @@ -1324,14 +1250,14 @@ export const CREDENTIAL_SHARE_WORKFLOW: PreviewWorkflow = { position: { x: 0, y: 100 }, rows: [ { title: 'Operation', value: 'Select Credential' }, - { title: 'Account', value: 'Google' }, + { title: 'Account', value: 'Slack' }, ], }, { - id: 'gmail', - name: 'Gmail', - type: 'gmail', - typeLabel: 'Gmail', + id: 'send', + name: 'Send message', + type: 'slack', + typeLabel: 'Slack', isIntegration: true, sentence: ['Use account', { subBlockId: 'Account', noun: 'account' }], bgColor: '#FFFFFF', @@ -1339,10 +1265,10 @@ export const CREDENTIAL_SHARE_WORKFLOW: PreviewWorkflow = { rows: [{ title: 'Account', value: '' }], }, { - id: 'drive', - name: 'Drive', - type: 'google_drive', - typeLabel: 'Google Drive', + id: 'read', + name: 'Read channel', + type: 'slack', + typeLabel: 'Slack', isIntegration: true, sentence: ['Use account', { subBlockId: 'Account', noun: 'account' }], bgColor: '#FFFFFF', @@ -1350,10 +1276,10 @@ export const CREDENTIAL_SHARE_WORKFLOW: PreviewWorkflow = { rows: [{ title: 'Account', value: '' }], }, { - id: 'calendar', - name: 'Calendar', - type: 'google_calendar', - typeLabel: 'Google Calendar', + id: 'reply', + name: 'Reply', + type: 'slack', + typeLabel: 'Slack', isIntegration: true, sentence: ['Use account', { subBlockId: 'Account', noun: 'account' }], bgColor: '#FFFFFF', @@ -1362,75 +1288,150 @@ export const CREDENTIAL_SHARE_WORKFLOW: PreviewWorkflow = { }, ], edges: [ - { id: 'credential-gmail', source: 'credential', target: 'gmail' }, - { id: 'credential-drive', source: 'credential', target: 'drive' }, - { id: 'credential-calendar', source: 'credential', target: 'calendar' }, + { id: 'credential-gmail', source: 'credential', target: 'send' }, + { id: 'credential-drive', source: 'credential', target: 'read' }, + { id: 'credential-calendar', source: 'credential', target: 'reply' }, ], } /** Credential example: pick a production or staging account at runtime. */ export const CREDENTIAL_ROUTE_WORKFLOW: PreviewWorkflow = { id: 'credential-route', - name: 'Route to an account', + name: 'Choose a Slack account', blocks: [ - { - id: 'pick', - name: 'Pick account', - type: 'agent', - typeLabel: 'Agent', - sentence: [ - 'Prompt', - { subBlockId: 'Model', noun: 'model' }, - 'with', - { subBlockId: 'Messages' }, - ], - bgColor: '#33C482', - position: { x: 0, y: 60 }, - rows: [{ title: 'Messages', value: 'Production or staging?' }], - }, { id: 'condition', - name: 'Condition', + name: 'Choose account', type: 'condition', typeLabel: 'Condition', bgColor: '#FF752F', - position: { x: 330, y: 60 }, + position: { + x: 300, + y: 60, + }, rows: [], branches: [ - { id: 'condition-if', label: 'If', value: " === 'prod'" }, - { id: 'condition-else', label: 'else' }, + { + id: 'condition-if', + label: 'If', + value: " === 'prod'", + }, + { + id: 'condition-else', + label: 'else', + }, ], }, { id: 'prod', - name: 'Credential', + name: 'Production account', type: 'credential', typeLabel: 'Credential', - sentence: ['Select an OAuth credential', 'for', { subBlockId: 'Account' }], bgColor: '#6366F1', - position: { x: 700, y: 0 }, - rows: [{ title: 'Account', value: 'Prod Slack' }], + position: { + x: 610, + y: 0, + }, + rows: [ + { + title: 'Operation', + value: 'Select Credential', + }, + { + title: 'Credential', + value: 'Prod Slack', + }, + ], }, { id: 'staging', - name: 'Credential', + name: 'Staging account', type: 'credential', typeLabel: 'Credential', - sentence: ['Select an OAuth credential', 'for', { subBlockId: 'Account' }], bgColor: '#6366F1', - position: { x: 700, y: 140 }, - rows: [{ title: 'Account', value: 'Staging Slack' }], + position: { + x: 610, + y: 180, + }, + rows: [ + { + title: 'Operation', + value: 'Select Credential', + }, + { + title: 'Credential', + value: 'Staging Slack', + }, + ], + }, + { + id: 'postprod', + name: 'Production message', + type: 'slack', + typeLabel: 'Slack', + bgColor: '#FFFFFF', + position: { + x: 930, + y: 0, + }, + rows: [ + { + title: 'Operation', + value: 'Send Message', + }, + { + title: 'Credential', + value: '', + }, + ], + isIntegration: true, + }, + { + id: 'poststaging', + name: 'Staging message', + type: 'slack', + typeLabel: 'Slack', + bgColor: '#FFFFFF', + position: { + x: 930, + y: 180, + }, + rows: [ + { + title: 'Operation', + value: 'Send Message', + }, + { + title: 'Credential', + value: '', + }, + ], + isIntegration: true, }, ], edges: [ - { id: 'pick-condition', source: 'pick', target: 'condition' }, - { id: 'condition-prod', source: 'condition', target: 'prod', sourceHandle: 'condition-if' }, + { + id: 'condition-prod', + source: 'condition', + target: 'prod', + sourceHandle: 'condition-if', + }, { id: 'condition-staging', source: 'condition', target: 'staging', sourceHandle: 'condition-else', }, + { + id: 'prod-postprod', + source: 'prod', + target: 'postprod', + }, + { + id: 'staging-poststaging', + source: 'staging', + target: 'poststaging', + }, ], } @@ -1467,7 +1468,10 @@ export const GUARDRAILS_JSON_WORKFLOW: PreviewWorkflow = { sentence: ['Validate content using', { subBlockId: 'Validation', noun: 'validation type' }], bgColor: '#3D642D', position: { x: 320, y: 0 }, - rows: [{ title: 'Validation', value: 'Valid JSON' }], + rows: [ + { title: 'Content to Validate', value: '' }, + { title: 'Validation', value: 'Valid JSON' }, + ], }, { ...GUARDRAILS_GATE, @@ -1477,10 +1481,37 @@ export const GUARDRAILS_JSON_WORKFLOW: PreviewWorkflow = { { id: 'condition-else', label: 'else' }, ], }, + { + id: 'parse', + name: 'Parse', + type: 'function', + typeLabel: 'Function', + sentence: ['Run', { subBlockId: 'Code', noun: 'code' }], + bgColor: '#FF402F', + position: { x: 960, y: -60 }, + rows: [{ title: 'Code', value: 'return JSON.parse();' }], + }, + { + id: 'reject', + name: 'Reject', + type: 'function', + typeLabel: 'Function', + sentence: ['Run', { subBlockId: 'Code', noun: 'code' }], + bgColor: '#FF402F', + position: { x: 960, y: 140 }, + rows: [{ title: 'Code', value: 'return { valid: false, error: };' }], + }, ], edges: [ { id: 'start-guardrails', source: 'start', target: 'guardrails' }, { id: 'guardrails-condition', source: 'guardrails', target: 'condition' }, + { id: 'condition-parse', source: 'condition', target: 'parse', sourceHandle: 'condition-if' }, + { + id: 'condition-reject', + source: 'condition', + target: 'reject', + sourceHandle: 'condition-else', + }, ], } @@ -1504,8 +1535,10 @@ export const GUARDRAILS_HALLUCINATION_WORKFLOW: PreviewWorkflow = { bgColor: '#3D642D', position: { x: 320, y: 0 }, rows: [ + { title: 'Content to Validate', value: '' }, { title: 'Validation', value: 'Hallucination' }, { title: 'Knowledge Base', value: 'docs' }, + { title: 'Model', value: 'claude-sonnet-5-5' }, ], }, { @@ -1548,8 +1581,9 @@ export const GUARDRAILS_PII_WORKFLOW: PreviewWorkflow = { bgColor: '#3D642D', position: { x: 320, y: 0 }, rows: [ + { title: 'Content to Validate', value: '' }, { title: 'Validation', value: 'PII Detection' }, - { title: 'Action', value: 'Block' }, + { title: 'Action', value: 'Block Request' }, ], }, { @@ -1570,34 +1604,67 @@ export const GUARDRAILS_PII_WORKFLOW: PreviewWorkflow = { /** HITL example: a human approves AI content before it ships. */ export const HITL_APPROVAL_WORKFLOW: PreviewWorkflow = { id: 'hitl-approval', - name: 'Approve before publish', + name: 'Approve before publishing', blocks: [ { id: 'draft', name: 'Draft', type: 'agent', typeLabel: 'Agent', - sentence: [ - 'Prompt', - { subBlockId: 'Model', noun: 'model' }, - 'with', - { subBlockId: 'Messages' }, - ], bgColor: '#33C482', - position: { x: 0, y: 0 }, - rows: [{ title: 'Messages', value: 'Write the post' }], + position: { + x: 0, + y: 70, + }, + rows: [ + { + title: 'Messages', + value: 'Write the post', + }, + ], }, { id: 'approve', - name: 'Human in the Loop', - type: 'human_in_the_loop', + name: 'Approval', + type: 'human_in_the_loop_v2', typeLabel: 'Human', - sentence: ['Pause execution until a human responds'], bgColor: '#10B981', - position: { x: 300, y: 0 }, + position: { + x: 300, + y: 70, + }, rows: [ - { title: 'Display', value: '' }, - { title: 'Resume', value: 'approved' }, + { + title: 'Display Data', + value: '', + }, + { + title: 'Resume Form', + value: 'approved (boolean)', + }, + ], + }, + { + id: 'check', + name: 'Check approval', + type: 'condition', + typeLabel: 'Condition', + bgColor: '#FF752F', + position: { + x: 620, + y: 70, + }, + rows: [], + branches: [ + { + id: 'condition-if', + label: 'If', + value: ' === true', + }, + { + id: 'condition-else', + label: 'else', + }, ], }, { @@ -1605,20 +1672,63 @@ export const HITL_APPROVAL_WORKFLOW: PreviewWorkflow = { name: 'Publish', type: 'api', typeLabel: 'API', - sentence: [ - 'Send', - { subBlockId: 'Method', noun: 'method' }, - 'request to', - { subBlockId: 'URL', noun: 'URL' }, - ], bgColor: '#2F55FF', - position: { x: 640, y: 0 }, - rows: [{ title: 'Method', value: 'POST' }], + position: { + x: 950, + y: 0, + }, + rows: [ + { + title: 'Method', + value: 'POST', + }, + { + title: 'Body', + value: '{"content":""}', + }, + ], + }, + { + id: 'reject', + name: 'Rejected', + type: 'function', + typeLabel: 'Function', + bgColor: '#FF402F', + position: { + x: 950, + y: 180, + }, + rows: [ + { + title: 'Code', + value: 'return { approved: false };', + }, + ], }, ], edges: [ - { id: 'draft-approve', source: 'draft', target: 'approve' }, - { id: 'approve-publish', source: 'approve', target: 'publish' }, + { + id: 'draft-approve', + source: 'draft', + target: 'approve', + }, + { + id: 'approve-check', + source: 'approve', + target: 'check', + }, + { + id: 'check-publish', + source: 'check', + target: 'publish', + sourceHandle: 'condition-if', + }, + { + id: 'check-reject', + source: 'check', + target: 'reject', + sourceHandle: 'condition-else', + }, ], } @@ -1628,55 +1738,202 @@ export const HITL_MULTISTAGE_WORKFLOW: PreviewWorkflow = { name: 'Two-stage approval', blocks: [ { - id: 'agent', - name: 'Agent', + id: 'draft', + name: 'Draft', type: 'agent', typeLabel: 'Agent', - sentence: [ - 'Prompt', - { subBlockId: 'Model', noun: 'model' }, - 'with', - { subBlockId: 'Messages' }, - ], bgColor: '#33C482', - position: { x: 0, y: 0 }, - rows: [{ title: 'Messages', value: 'Draft the change' }], + position: { + x: 0, + y: 70, + }, + rows: [ + { + title: 'Messages', + value: 'Write the post', + }, + ], }, { id: 'manager', name: 'Manager', - type: 'human_in_the_loop', + type: 'human_in_the_loop_v2', typeLabel: 'Human', - sentence: ['Pause execution until a human responds'], bgColor: '#10B981', - position: { x: 280, y: 0 }, - rows: [{ title: 'Resume', value: 'approved' }], + position: { + x: 300, + y: 90, + }, + rows: [ + { + title: 'Display Data', + value: '', + }, + { + title: 'Resume Form', + value: 'approved (boolean)', + }, + ], + }, + { + id: 'managergate', + name: 'Check manager', + type: 'condition', + typeLabel: 'Condition', + bgColor: '#FF752F', + position: { + x: 620, + y: 90, + }, + rows: [], + branches: [ + { + id: 'condition-if', + label: 'If', + value: ' === true', + }, + { + id: 'condition-else', + label: 'else', + }, + ], }, { id: 'director', name: 'Director', - type: 'human_in_the_loop', + type: 'human_in_the_loop_v2', typeLabel: 'Human', - sentence: ['Pause execution until a human responds'], bgColor: '#10B981', - position: { x: 580, y: 0 }, - rows: [{ title: 'Resume', value: 'approved' }], + position: { + x: 950, + y: 0, + }, + rows: [ + { + title: 'Display Data', + value: '', + }, + { + title: 'Resume Form', + value: 'approved (boolean)', + }, + ], + }, + { + id: 'directorgate', + name: 'Check director', + type: 'condition', + typeLabel: 'Condition', + bgColor: '#FF752F', + position: { + x: 1280, + y: 0, + }, + rows: [], + branches: [ + { + id: 'condition-if', + label: 'If', + value: ' === true', + }, + { + id: 'condition-else', + label: 'else', + }, + ], }, { id: 'execute', name: 'Execute', type: 'function', typeLabel: 'Function', - sentence: ['Run', { subBlockId: 'Code', noun: 'code' }], bgColor: '#FF402F', - position: { x: 880, y: 0 }, - rows: [{ title: 'Code', value: 'apply()' }], + position: { + x: 1610, + y: -80, + }, + rows: [ + { + title: 'Code', + value: 'return { approved: true, content: };', + }, + ], + }, + { + id: 'managerreject', + name: 'Manager rejected', + type: 'function', + typeLabel: 'Function', + bgColor: '#FF402F', + position: { + x: 950, + y: 230, + }, + rows: [ + { + title: 'Code', + value: 'return { approved: false, reviewer: "manager" };', + }, + ], + }, + { + id: 'directorreject', + name: 'Director rejected', + type: 'function', + typeLabel: 'Function', + bgColor: '#FF402F', + position: { + x: 1610, + y: 100, + }, + rows: [ + { + title: 'Code', + value: 'return { approved: false, reviewer: "director" };', + }, + ], }, ], edges: [ - { id: 'agent-manager', source: 'agent', target: 'manager' }, - { id: 'manager-director', source: 'manager', target: 'director' }, - { id: 'director-execute', source: 'director', target: 'execute' }, + { + id: 'draft-manager', + source: 'draft', + target: 'manager', + }, + { + id: 'manager-managergate', + source: 'manager', + target: 'managergate', + }, + { + id: 'managergate-director', + source: 'managergate', + target: 'director', + sourceHandle: 'condition-if', + }, + { + id: 'managergate-managerreject', + source: 'managergate', + target: 'managerreject', + sourceHandle: 'condition-else', + }, + { + id: 'director-directorgate', + source: 'director', + target: 'directorgate', + }, + { + id: 'directorgate-execute', + source: 'directorgate', + target: 'execute', + sourceHandle: 'condition-if', + }, + { + id: 'directorgate-directorreject', + source: 'directorgate', + target: 'directorreject', + sourceHandle: 'condition-else', + }, ], } @@ -1702,13 +1959,16 @@ export const HITL_VALIDATE_WORKFLOW: PreviewWorkflow = { }, { id: 'validate', - name: 'Human in the Loop', - type: 'human_in_the_loop', + name: 'Review data', + type: 'human_in_the_loop_v2', typeLabel: 'Human', sentence: ['Pause execution until a human responds'], bgColor: '#10B981', position: { x: 300, y: 0 }, - rows: [{ title: 'Display', value: '' }], + rows: [ + { title: 'Display Data', value: '' }, + { title: 'Resume Form', value: 'corrected (object)' }, + ], }, { id: 'process', @@ -1718,7 +1978,7 @@ export const HITL_VALIDATE_WORKFLOW: PreviewWorkflow = { sentence: ['Run', { subBlockId: 'Code', noun: 'code' }], bgColor: '#FF402F', position: { x: 640, y: 0 }, - rows: [{ title: 'Code', value: 'process()' }], + rows: [{ title: 'Code', value: 'return ;' }], }, ], edges: [ @@ -1755,7 +2015,7 @@ export const WEBHOOK_NOTIFY_WORKFLOW: PreviewWorkflow = { sentence: ['Run', { subBlockId: 'Code', noun: 'code' }], bgColor: '#FF402F', position: { x: 320, y: 0 }, - rows: [{ title: 'Code', value: 'toSlackBlocks()' }], + rows: [{ title: 'Code', value: 'return { text: };' }], }, { id: 'webhook', @@ -1770,7 +2030,10 @@ export const WEBHOOK_NOTIFY_WORKFLOW: PreviewWorkflow = { ], bgColor: '#10B981', position: { x: 640, y: 0 }, - rows: [{ title: 'URL', value: 'hooks.slack.com/…' }], + rows: [ + { title: 'URL', value: 'https://hooks.slack.com/services/YOUR/WEBHOOK/SECRET' }, + { title: 'Payload', value: '' }, + ], }, ], edges: [ @@ -1821,12 +2084,17 @@ export const WEBHOOK_TRIGGER_WORKFLOW: PreviewWorkflow = { ], bgColor: '#10B981', position: { x: 640, y: 0 }, - rows: [{ title: 'URL', value: 'api.partner.com/hook' }], + rows: [{ title: 'URL', value: 'https://api.example.com/hook' }], }, ], edges: [ { id: 'start-condition', source: 'start', target: 'condition' }, - { id: 'condition-webhook', source: 'condition', target: 'webhook' }, + { + id: 'condition-webhook', + source: 'condition', + target: 'webhook', + sourceHandle: 'condition-if', + }, ], } @@ -1849,19 +2117,19 @@ export const WORKFLOW_CALL_WORKFLOW: PreviewWorkflow = { { id: 'child', name: 'Workflow', - type: 'workflow', + type: 'workflow_input', typeLabel: 'Workflow', sentence: [ 'Run', { subBlockId: 'Workflow', noun: 'workflow' }, ', passing', - { subBlockId: 'Input' }, + { subBlockId: 'Inputs' }, ], bgColor: '#6366F1', position: { x: 320, y: 0 }, rows: [ { title: 'Workflow', value: 'enrich-lead' }, - { title: 'Input', value: '' }, + { title: 'Inputs', value: 'input = ' }, ], }, { @@ -1900,17 +2168,20 @@ export const LOOP_WORKFLOW: PreviewWorkflow = { bgColor: '#2FB3FF', position: { x: 0, y: 95 }, hideTargetHandle: true, - rows: [{ title: 'Input', value: 'Reviews' }], + rows: [{ title: 'Input', value: 'reviews (array)' }], }, { id: 'loop', - name: 'Loop', + name: 'Process Reviews', type: 'loop', typeLabel: 'Loop', bgColor: '#FAFAF9', position: { x: 340, y: 30 }, size: { width: 480, height: 300 }, - rows: [], + rows: [ + { title: 'Loop Type', value: 'For Each' }, + { title: 'Collection Items', value: '' }, + ], }, { id: 'score', @@ -1941,7 +2212,7 @@ export const LOOP_WORKFLOW: PreviewWorkflow = { ], bgColor: '#33C482', position: { x: 910, y: 95 }, - rows: [{ title: 'Messages', value: 'Summarize ' }], + rows: [{ title: 'Messages', value: 'Summarize ' }], }, ], edges: [ @@ -1965,17 +2236,21 @@ export const PARALLEL_WORKFLOW: PreviewWorkflow = { bgColor: '#2FB3FF', position: { x: 0, y: 95 }, hideTargetHandle: true, - rows: [{ title: 'Input', value: 'Tasks' }], + rows: [{ title: 'Input', value: 'tasks (array)' }], }, { id: 'parallel', - name: 'Parallel', + name: 'Process Tasks', type: 'parallel', typeLabel: 'Parallel', bgColor: '#1D1C1A', position: { x: 340, y: 30 }, size: { width: 480, height: 300 }, - rows: [], + rows: [ + { title: 'Parallel Type', value: 'Parallel Each' }, + { title: 'Parallel Items', value: '' }, + { title: 'Parallel Batch Size', value: '20' }, + ], }, { id: 'call', @@ -1991,7 +2266,7 @@ export const PARALLEL_WORKFLOW: PreviewWorkflow = { bgColor: '#2F55FF', position: { x: 150, y: 64 }, parentId: 'parallel', - rows: [{ title: 'URL', value: '/tasks/' }], + rows: [{ title: 'URL', value: 'https://api.example.com/tasks/' }], }, { id: 'aggregate', @@ -2001,7 +2276,12 @@ export const PARALLEL_WORKFLOW: PreviewWorkflow = { sentence: ['Run', { subBlockId: 'Code', noun: 'code' }], bgColor: '#FF402F', position: { x: 910, y: 95 }, - rows: [{ title: 'Code', value: 'merge()' }], + rows: [ + { + title: 'Code', + value: 'return .flat().map((output) => output.data);', + }, + ], }, ], edges: [ @@ -2034,7 +2314,7 @@ export const BUILD_AGENT_WORKFLOW: PreviewWorkflow = { }, { id: 'agent', - name: 'Score lead', + name: 'Agent', type: 'agent', typeLabel: 'Agent', sentence: [ @@ -2048,8 +2328,13 @@ export const BUILD_AGENT_WORKFLOW: PreviewWorkflow = { bgColor: '#33C482', position: { x: 320, y: 0 }, rows: [ - { title: 'Messages', value: 'Score ' }, - { title: 'Model', value: 'claude-sonnet-4-6' }, + { title: 'Messages', value: 'Score from 0 to 100.' }, + { + title: 'Response Format', + value: + '{"name":"lead_score","schema":{"type":"object","properties":{"score":{"type":"number","minimum":0,"maximum":100}},"required":["score"],"additionalProperties":false}}', + }, + { title: 'Model', value: 'claude-sonnet-5-5' }, ], tools: [ { type: 'knowledge', name: 'Knowledge', bgColor: '#00B0B0' }, @@ -2083,7 +2368,7 @@ export const FILE_SUMMARY_WORKFLOW: PreviewWorkflow = { name: 'File', type: 'file', typeLabel: 'File', - sentence: ['Parse', { subBlockId: 'File', noun: 'file' }], + sentence: ['Read', { subBlockId: 'File', noun: 'file' }], bgColor: '#40916C', position: { x: 0, y: 0 }, rows: [ @@ -2111,7 +2396,7 @@ export const FILE_SUMMARY_WORKFLOW: PreviewWorkflow = { }, { id: 'write', - name: 'File', + name: 'Save summary', type: 'file', typeLabel: 'File', sentence: ['Create', { subBlockId: 'File Name', noun: 'file name' }], @@ -2120,6 +2405,7 @@ export const FILE_SUMMARY_WORKFLOW: PreviewWorkflow = { rows: [ { title: 'Operation', value: 'Write' }, { title: 'File Name', value: 'summary.md' }, + { title: 'Content', value: '' }, ], }, ], @@ -2131,8 +2417,8 @@ export const FILE_SUMMARY_WORKFLOW: PreviewWorkflow = { /** * The running example of the choosing guide: a lead scorer combining a - * workflow-as-tool (enrich), a deterministic Function, an Agent with tools, - * and a deterministic Google Sheets append. + * fixed Workflow step (Enrich), a Function, an Agent with tools, + * and a fixed Google Sheets append. */ export const LEAD_SCORER_WORKFLOW: PreviewWorkflow = { id: 'lead-scorer', @@ -2152,12 +2438,15 @@ export const LEAD_SCORER_WORKFLOW: PreviewWorkflow = { { id: 'enrich', name: 'Enrich', - type: 'workflow', + type: 'workflow_input', typeLabel: 'Workflow', sentence: ['Run', { subBlockId: 'Workflow', noun: 'workflow' }], bgColor: '#6366F1', position: { x: 290, y: 0 }, - rows: [{ title: 'Workflow', value: 'enrich-lead' }], + rows: [ + { title: 'Workflow', value: 'enrich-lead' }, + { title: 'Inputs', value: 'input = ' }, + ], }, { id: 'reshape', @@ -2167,7 +2456,13 @@ export const LEAD_SCORER_WORKFLOW: PreviewWorkflow = { sentence: ['Run', { subBlockId: 'Code', noun: 'code' }], bgColor: '#FF402F', position: { x: 580, y: 0 }, - rows: [{ title: 'Code', value: 'return fields()' }], + rows: [ + { + title: 'Code', + value: + 'const lead = ; return { company: lead.company, domain: lead.domain };', + }, + ], }, { id: 'score', @@ -2185,14 +2480,19 @@ export const LEAD_SCORER_WORKFLOW: PreviewWorkflow = { bgColor: '#33C482', position: { x: 870, y: 0 }, rows: [ - { title: 'Messages', value: 'Score ' }, - { title: 'Model', value: 'claude-sonnet-4-6' }, + { title: 'Messages', value: 'Score from 0 to 100.' }, + { + title: 'Response Format', + value: + '{"name":"lead_score","schema":{"type":"object","properties":{"score":{"type":"number","minimum":0,"maximum":100}},"required":["score"],"additionalProperties":false}}', + }, + { title: 'Model', value: 'claude-sonnet-5-5' }, ], tools: [ { type: 'exa', name: 'Search', bgColor: '#1F40ED' }, { type: 'gmail', name: 'Send Email', bgColor: '#E0E0E0' }, { type: 'hubspot', name: 'CRM', bgColor: '#FF7A59' }, - { type: 'workflow', name: 'Deep Enrich', bgColor: '#6366F1' }, + { type: 'workflow_input', name: 'Deep Enrich', bgColor: '#6366F1' }, ], }, { @@ -2242,7 +2542,7 @@ export const CONCURRENCY_WORKFLOW: PreviewWorkflow = { sentence: ['Prompt', { subBlockId: 'Model', noun: 'model' }], bgColor: '#33C482', position: { x: 360, y: 0 }, - rows: [{ title: 'Model', value: 'claude-sonnet-4-6' }], + rows: [{ title: 'Model', value: 'claude-sonnet-5-5' }], }, { id: 'research', @@ -2252,7 +2552,7 @@ export const CONCURRENCY_WORKFLOW: PreviewWorkflow = { sentence: ['Prompt', { subBlockId: 'Model', noun: 'model' }], bgColor: '#33C482', position: { x: 360, y: 150 }, - rows: [{ title: 'Model', value: 'claude-sonnet-4-6' }], + rows: [{ title: 'Model', value: 'claude-sonnet-5-5' }], }, ], edges: [ @@ -2288,7 +2588,7 @@ export const COMBINATION_WORKFLOW: PreviewWorkflow = { sentence: ['Prompt', { subBlockId: 'Model', noun: 'model' }], bgColor: '#33C482', position: { x: 360, y: 0 }, - rows: [{ title: 'Model', value: 'claude-sonnet-4-6' }], + rows: [{ title: 'Model', value: 'claude-sonnet-5-5' }], }, { id: 'research', @@ -2298,7 +2598,7 @@ export const COMBINATION_WORKFLOW: PreviewWorkflow = { sentence: ['Prompt', { subBlockId: 'Model', noun: 'model' }], bgColor: '#33C482', position: { x: 360, y: 150 }, - rows: [{ title: 'Model', value: 'claude-sonnet-4-6' }], + rows: [{ title: 'Model', value: 'claude-sonnet-5-5' }], }, { id: 'combine', @@ -2310,7 +2610,11 @@ export const COMBINATION_WORKFLOW: PreviewWorkflow = { position: { x: 720, y: 75 }, rows: [ { title: 'Language', value: 'JavaScript' }, - { title: 'Code', value: 'merge(, )' }, + { + title: 'Code', + value: + 'return { support: , research: };', + }, ], }, ], @@ -2339,7 +2643,7 @@ export const ROUTING_WORKFLOW: PreviewWorkflow = { bgColor: '#2FB3FF', position: { x: 0, y: 140 }, hideTargetHandle: true, - rows: [{ title: 'Input', value: 'Message' }], + rows: [{ title: 'Input', value: 'message (string), type (string)' }], }, { id: 'condition', @@ -2375,7 +2679,7 @@ export const ROUTING_WORKFLOW: PreviewWorkflow = { sentence: ['Prompt', { subBlockId: 'Model', noun: 'model' }], bgColor: '#33C482', position: { x: 740, y: 280 }, - rows: [{ title: 'Model', value: 'claude-sonnet-4-6' }], + rows: [{ title: 'Model', value: 'claude-sonnet-5-5' }], }, { id: 'sales', @@ -2385,7 +2689,7 @@ export const ROUTING_WORKFLOW: PreviewWorkflow = { sentence: ['Prompt', { subBlockId: 'Model', noun: 'model' }], bgColor: '#33C482', position: { x: 1120, y: -60 }, - rows: [{ title: 'Model', value: 'claude-sonnet-4-6' }], + rows: [{ title: 'Model', value: 'claude-sonnet-5-5' }], }, { id: 'support', @@ -2395,7 +2699,7 @@ export const ROUTING_WORKFLOW: PreviewWorkflow = { sentence: ['Prompt', { subBlockId: 'Model', noun: 'model' }], bgColor: '#33C482', position: { x: 1120, y: 90 }, - rows: [{ title: 'Model', value: 'claude-sonnet-4-6' }], + rows: [{ title: 'Model', value: 'claude-sonnet-5-5' }], }, ], edges: [ @@ -2447,7 +2751,7 @@ export const ERROR_PATH_WORKFLOW: PreviewWorkflow = { sentence: ['Run', { subBlockId: 'Code', noun: 'code' }], bgColor: '#FF402F', position: { x: 720, y: 0 }, - rows: [{ title: 'Code', value: 'return ok' }], + rows: [{ title: 'Code', value: 'return "ok";' }], }, { id: 'handleError', @@ -2457,7 +2761,7 @@ export const ERROR_PATH_WORKFLOW: PreviewWorkflow = { sentence: ['Run', { subBlockId: 'Code', noun: 'code' }], bgColor: '#FF402F', position: { x: 720, y: 170 }, - rows: [{ title: 'Code', value: 'return recovered' }], + rows: [{ title: 'Code', value: 'return "recovered";' }], }, ], edges: [ diff --git a/apps/docs/components/workflow-preview/index.ts b/apps/docs/components/workflow-preview/index.ts index a5eaac685ea..ad8703d50d4 100644 --- a/apps/docs/components/workflow-preview/index.ts +++ b/apps/docs/components/workflow-preview/index.ts @@ -7,7 +7,6 @@ export { COMBINATION_WORKFLOW, CONCURRENCY_WORKFLOW, CONDITION_MODERATE_WORKFLOW, - CONDITION_ONBOARD_WORKFLOW, CONDITION_ROUTE_WORKFLOW, CREDENTIAL_ROUTE_WORKFLOW, CREDENTIAL_SHARE_WORKFLOW, @@ -27,9 +26,7 @@ export { PARALLEL_WORKFLOW, RESPONSE_API_WORKFLOW, RESPONSE_ERROR_WORKFLOW, - RESPONSE_WEBHOOK_WORKFLOW, ROUTER_CLASSIFY_WORKFLOW, - ROUTER_LEAD_WORKFLOW, ROUTER_TRIAGE_WORKFLOW, ROUTING_WORKFLOW, SUPPORT_KB_WORKFLOW, diff --git a/apps/docs/content/docs/agents/choosing.mdx b/apps/docs/content/docs/agents/choosing.mdx index 55cb9017ad2..830a03f1879 100644 --- a/apps/docs/content/docs/agents/choosing.mdx +++ b/apps/docs/content/docs/agents/choosing.mdx @@ -1,78 +1,81 @@ --- title: Choosing what to use -description: Pick between a deterministic block, an agent tool, a custom tool, an MCP server, a workflow-as-tool, and a skill. +description: Choose fixed workflow steps, Agent tools, reusable code, MCP connections, workflows as tools, or skills. --- -import { Callout } from 'fumadocs-ui/components/callout' import { WorkflowPreview, LEAD_SCORER_WORKFLOW } from '@/components/workflow-preview' -When you build an agent, several features overlap: a deterministic block and an agent tool can run the same integration, and a custom tool, an MCP tool, and a workflow-as-tool can all give an agent the same action. This page lays out the differences so you pick the right one. They vary along three lines: whether the action is **deterministic** (always runs) or **model-decided** (an agent chooses), whether it lives in one workflow or is **reusable** across your workspace, and whether it comes from Sim or an **external** provider. +Start with who should decide to run an action. Put it on the workflow path when it must be attempted at that point. Give it to an **Agent** block as a tool when the model should decide whether and when to call it. -The running example is a workflow that scores inbound sales leads. It reads a new lead, enriches it, decides on a score, logs the result, and notifies the team. Each option below builds part of it: +Then choose how to provide the action or instructions: - +| Choice | Use it for | Configure it in | +| --- | --- | --- | +| Fixed workflow block | A required step on a workflow path | The workflow builder | +| Agent tool | An action the model chooses during a run | The Agent block's **Tools** input | +| Custom tool | Reusable JavaScript with a parameter schema | Workspace **Custom tools** settings, then the Agent tool list | +| External MCP server | A toolset provided by a service or your own server | Workspace **MCP tools** settings, then the Agent tool list | +| Workflow as a tool | A reusable procedure with several steps | A separate workflow, then the Agent tool list | +| Skill | Reusable instructions for how to do the work | **Integrations → Skills**, then the Agent's **Skills** input or Chat | -{/* VISUAL: decision tree. Always happens? → deterministic block. Else agent chooses? → agent tool. Reuse across workspace? → custom tool. External toolset? → MCP. Whole workflow? → workflow-as-tool. Reusable instructions? → skill. */} +Custom tools, MCP operations, and workflows as tools are all ways to give an Agent callable actions. A skill supplies instructions for using those capabilities. -## Deterministic block +## Fixed workflow block -A **block** is a single step that runs at a fixed point on the path, with no model deciding whether to. It always runs when the workflow reaches it. Use one when the action must happen every time: an API call, a data transform, a branch. +A block runs when the workflow reaches it. Use a fixed step for an API request, transformation, branch, or record that belongs on that path. The step can still fail; fixed execution does not guarantee a successful result. -In the lead scorer, a [Google Sheets](/integrations) block always appends the scored lead to a tracking sheet, and a [Function](/workflows/blocks/function) block always reshapes the enrichment response into the fields the next step expects. The block runs at that point in the graph; an execution error can still stop it. +This lead-scoring workflow enriches a lead, reshapes the data, scores it, and appends the score to a sheet: - + -Most steps in a workflow are blocks. Reach for the kinds below only when you want a model to decide, or you want to reuse something. +The **Workflow** block runs enrichment before scoring. The **Function** block reshapes its result. The **Google Sheets** block records a score whenever execution reaches that step. ## Agent tool -An **agent tool** is an action you hand to an [Agent](/workflows/blocks/agent) block. The agent reads the task and decides whether and when to call it. The same catalog of [integrations](/integrations) that exist as standalone blocks can also be attached to an agent as tools. +An Agent tool is an action the model can call while it works. Eligible integrations from the [catalog](/integrations) can run as standalone blocks or as tools attached to an Agent. -In the lead scorer, the Agent has a Search tool and a Send Email tool. For a lead with a thin profile it runs Search to gather context; for a strong lead it calls Send Email. A thin, obvious lead might trigger neither. The agent chooses per run. +In the lead scorer, the Agent has Search and Send Email tools. It can search when a profile is incomplete or send an email when the task calls for outreach. A run may use either tool, both, or neither. - +Each tool's **Permission Mode** controls how it is offered: -Each tool carries a `usageControl` setting. **Auto** lets the model decide (the default). **Force** makes the agent call the tool every run, for actions that should never be skipped, like always logging the decision. **None** removes the tool from that agent. +- **Auto** lets the model decide whether to call it. +- **Force** requests a call on models that support forced tool use. +- **None** hides the tool from the model without deleting its configuration. - -A block and an agent tool can be the same underlying integration. The difference is who decides. A block runs because the path reached it. An agent tool runs because the agent chose it. - +Force does not guarantee success. Use a separate block for an action that must be attempted on the workflow path, such as recording the scoring result. See the [Agent reference](/workflows/blocks/agent) for models and runtime permission modes. ## Custom tool -A **custom tool** is a tool you define once with an object schema and a JavaScript function body, then reuse across your workspace. It needs no external account. Use one when you have logic that several agents or workflows would otherwise duplicate. +A [custom tool](/agents/custom-tools) combines an object parameter schema with a JavaScript function body. Save it once in the workspace, then attach it to Agents that need it. -In the lead scorer, a `normalizeCompanyDomain` custom tool cleans a raw website into a canonical domain. The same tool serves the lead scorer, a deduplication workflow, and a reporting agent. Define it in the workspace, then pick it from any Agent block's tool list. +For example, `normalize_company_domain` can clean a website value before a lead scorer, deduplication agent, or reporting agent uses it. Pure transformations need no external account. Code that calls an API may need that service's credentials. -## MCP server +Custom tools use the isolated JavaScript runtime. For a fixed code step or code requiring a supported remote sandbox, use [Function](/workflows/blocks/function). -**MCP** (Model Context Protocol) is a standard for connecting an external tool provider. Connect an [MCP server](/agents/mcp) and its tools appear in the agent's tool list as a set. Use it to bring in a complete toolset that Sim does not provide natively, rather than wiring each action by hand. +## External MCP server -In the lead scorer, your CRM vendor ships an MCP server. After you connect it once, the agent can read accounts and update records through the vendor's own tools. The difference from a custom tool is who maintains it: a custom tool is code you wrote, while an MCP server is a toolbox someone else maintains. +MCP, the Model Context Protocol, connects an external provider's tools to Sim. Register an [MCP server](/agents/mcp), authorize its connection, and select the operations the Agent may use. -## Workflow-as-tool +For example, a CRM server can expose account lookup and record updates. The provider maintains those operations, or your team can run its own MCP server. Choose this path when an existing server provides the toolset you need. -A **workflow-as-tool** is a whole workflow handed to an agent as one callable tool. You pick the workflow in the [Agent](/workflows/blocks/agent) block's tool list; the agent decides when to call it and supplies the inputs, which arrive at the child's [Start](/workflows/triggers/start) trigger, and the child's result comes back as the tool's output. Use it when a multi-step procedure should be at the agent's disposal, not on the path. +## Workflow as a tool -In the lead scorer, the agent has a `Deep Enrich` workflow as a tool — its own five-step procedure. For a thin lead, the agent calls it to fill out the profile before scoring; for a complete lead, it never runs. The agent weighs a whole procedure the same way it weighs a single action. +Attach another workflow through the Agent's tool list to make a multi-step procedure callable. The Agent supplies inputs to the child's [Start trigger](/workflows/triggers/start) and receives the child's output. - -A workflow can also run as a fixed step: the [Workflow](/workflows/blocks/workflow) block calls a child workflow because the path reached it. Same child workflow, same Start trigger — the difference, as with blocks and agent tools, is who decides. The Enrich step in the diagram is that deterministic case. - +The lead scorer has a **Deep Enrich** workflow as a tool. The Agent can call that procedure for an incomplete lead and skip it for a complete profile. The separate **Enrich** step in the diagram is the fixed case: a [Workflow block](/workflows/blocks/workflow) calls its child when the path reaches it. - +Child state follows the parent's execution context: draft runs use draft child state; deployed runs use deployed child state. See the Workflow reference for input mapping, permissions, outputs, and errors. ## Skill -A **skill** is reusable instructions, a written playbook an agent can follow. Each skill has a short name and description that are always visible to the agent, plus a longer body the agent loads only when it decides the skill applies. Use one to capture how something should be done, separate from the tools that do it. +A [skill](/agents/skills) is reusable Markdown guidance, such as a scoring rubric or writing style guide. A workflow Agent sees the selected skill's name and description, then calls `load_skill` when it decides the full instructions are relevant. In Chat, tagging a skill includes its instructions in the request. + +For example, `lead-scoring-rubric` can define score bands and disqualifiers. It tells the agent how to assess a lead; tools still perform searches, updates, and other actions. -In the lead scorer, a `lead-scoring-rubric` skill spells out the bands and disqualifiers. The agent sees the skill's name and description on every run, and when a lead is ambiguous it loads the full rubric and applies it. The distinction is simple: a tool is an action the agent takes, and a skill is guidance the agent reads. Manage skills in your [workspace](/agents/skills). +## Related docs -| Feature | Who decides it runs | Where it lives | How you author it | -| --- | --- | --- | --- | -| **Block** | The path | The workflow | Drag in and configure | -| **Agent tool** | The agent | On the Agent block | Pick from the integrations | -| **Custom tool** | The agent | The workspace | Write the code once | -| **MCP server** | The agent | An external server | Connect it | -| **Workflow-as-tool** | The agent | Its own workflow | Build it, then pick it in the tool list | -| **Skill** | The agent | The workspace | Write the instructions | +- [Agents](/agents) +- [Agent block reference](/workflows/blocks/agent) +- [Custom tools](/agents/custom-tools) +- [Using MCP tools](/agents/mcp) +- [Agent skills](/agents/skills) diff --git a/apps/docs/content/docs/agents/custom-tools.mdx b/apps/docs/content/docs/agents/custom-tools.mdx index b40d49165a6..4f1f010f748 100644 --- a/apps/docs/content/docs/agents/custom-tools.mdx +++ b/apps/docs/content/docs/agents/custom-tools.mdx @@ -1,38 +1,28 @@ --- -title: Custom Tools -description: Create your own tools with JavaScript code and use them in Agent blocks +title: Custom tools +description: Define reusable JavaScript tools with parameter schemas and attach them to Agent blocks. --- import { Callout } from 'fumadocs-ui/components/callout' -import { Step, Steps } from 'fumadocs-ui/components/steps' -import { FAQ } from '@/components/ui/faq' -Custom tools let you write your own JavaScript functions and make them available as callable tools in Agent blocks. This is useful when you need functionality that isn't covered by Sim's built-in integrations — for example, calling an internal API, performing a custom calculation, or transforming data in a specific way. +A custom tool combines a parameter schema with a JavaScript function body. Save the definition in your workspace, then give it to an **Agent** block as an action the model can call. -## How Custom Tools Work +Use custom tools for calculations, transformations, or API requests that several agents share. Use a [Function block](/workflows/blocks/function) for a fixed code step on a workflow path. -A custom tool has two parts: +## Create a custom tool -1. **Schema** — A JSON definition describing the tool's name, description, and parameters (using the OpenAI function-calling format). This tells the AI agent what the tool does and what inputs it expects. -2. **Code** — A JavaScript function body that runs when the agent calls the tool. Parameters defined in the schema are available as variables in your code. +You need **Write** or **Admin** access to the workspace. -When an Agent block has access to a custom tool, the AI model decides when to call it based on the schema description and the conversation context — just like built-in tools. +1. Open **Settings → Custom tools** and select **Add tool**. +2. Enter the function-calling definition in **Schema**. +3. Write the JavaScript function body in **Code**. +4. Select **Save**. -## Creating a Custom Tool - - - - -### Open Custom Tools settings - -Navigate to **Settings → Custom Tools** in your workspace and click **Add**. - - - +Schema and Code are sections on the same page. Each has a generation control that can draft content from a description; review the generated schema and code before saving. ### Define the schema -In the **Schema** tab, define your tool using JSON in the OpenAI function-calling format: +The schema tells the model what the tool does and which inputs it accepts. Use the function-calling format below, with `function.parameters.type` set to `object`: ```json { @@ -45,12 +35,12 @@ In the **Schema** tab, define your tool using JSON in the OpenAI function-callin "properties": { "city": { "type": "string", - "description": "The city name" + "description": "The city name, optionally including a country code" }, "units": { "type": "string", "enum": ["celsius", "fahrenheit"], - "description": "Temperature units" + "description": "Temperature units; defaults to celsius when omitted" } }, "required": ["city"] @@ -59,104 +49,94 @@ In the **Schema** tab, define your tool using JSON in the OpenAI function-callin } ``` - - You can use the AI wand button to generate a schema from a natural language description of what the tool should do. - - - - +Function names must contain 1–64 letters, digits, underscores, or hyphens. Describe when to call the tool and mark required inputs in the schema. ### Write the code -Switch to the **Code** tab and write the JavaScript function body. Parameters from your schema are available directly as variables: +The code runs as an async function body. Supplied parameters with valid JavaScript names are available by name, such as `city`. All inputs are also available through `params`. Read optional inputs through `params`, because an omitted parameter may have no named variable. + +This example requires an OpenWeather API key saved as `OPENWEATHER_API_KEY` under **Settings → Secrets**. It handles the optional units input and returns the weather fields the agent needs: ```javascript +const apiKey = {{OPENWEATHER_API_KEY}}; +const requestedUnits = params.units ?? 'celsius'; +const apiUnits = requestedUnits === 'celsius' ? 'metric' : 'imperial'; const response = await fetch( - `https://api.openweathermap.org/data/2.5/weather?q=${city}&units=${units === 'celsius' ? 'metric' : 'imperial'}&appid={{OPENWEATHER_API_KEY}}` + `https://api.openweathermap.org/data/2.5/weather?q=${encodeURIComponent(city)}&units=${apiUnits}&appid=${apiKey}` ); -const data = await response.json(); +if (!response.ok) { + throw new Error(`Weather request failed: ${response.status}`); +} +const data = await response.json(); return { temperature: data.main.temp, + units: requestedUnits, description: data.weather[0].description, humidity: data.main.humidity }; ``` -For a secret used as a complete JavaScript expression, prefer the unquoted form, such as `const apiKey = {{OPENWEATHER_API_KEY}};`. Quoted and embedded forms remain supported, including the placeholder embedded in the URL above, `"Bearer {{KEY}}"`, template literals, and JavaScript regex literals. The value is bound separately when the tool executes rather than pasted into its source, so its exact string contents are preserved. +The return value becomes the tool result available to the agent. The [OpenWeather API reference](https://openweathermap.org/api/current) describes its inputs and responses. - - You can also use the AI wand to generate code from a description. Environment variables are referenced with `{{KEY}}` syntax. - - - - - -### Save - -Click **Save** to create the tool. It's now available to use in any Agent block across your workspace. - - - +## Attach the tool to an Agent -## Using Custom Tools in Workflows +1. Open an **Agent** block with a model that supports tools. +2. In **Tools**, select **Add tool...**. +3. Find the saved definition under **Custom Tools** and select it. +4. Run a task that needs the tool and inspect the Agent's tool calls. -Once created, custom tools appear alongside built-in tools when configuring an Agent block: +The model chooses whether to call it based on its schema and the task, subject to the tool's **Permission Mode**. See [Agent tools](/workflows/blocks/agent) for Auto, Force, and None. -1. Open an Agent block -2. Click **Add Tools** -3. Find your custom tool in the tool list -4. The agent will call the tool when it determines it's relevant to the task +## JavaScript runtime -## Code Environment +Custom tools run in an isolated JavaScript VM, including when a workflow has a remote sandbox configured. -### Available Features +| Capability | Behavior | +| --- | --- | +| Async code | Use `await` directly and `return` the result. | +| Inputs | Read supplied inputs by valid JavaScript name or through `params`; use `params` for optional or non-identifier keys. | +| HTTP requests | `fetch()` returns status, headers, and `.json()` or `.text()`. Requests must satisfy the deployment's network policy. | +| Secrets | Use `{{KEY}}` placeholders to bind saved secrets at execution time. | +| File content | Pass content as an input or use supported scoped `sim.files` helpers to read an authorized file. See the [Function file reference](/workflows/blocks/function#files). | -- **Async/await** — Your code runs in an async context, so you can use `await` directly -- **fetch()** — Make HTTP requests to external APIs -- **Node.js built-ins** — Access to `crypto`, `Buffer`, and other standard modules -- **Environment variables** — Use `{{KEY}}` syntax to bind secrets at execution time without placing plaintext in source code +Node module loading, external packages, and a sandbox filesystem are unavailable. Do not use `require`, `process`, `Buffer`, Node crypto, or package imports such as axios or lodash. The custom-tool fetch response does not support `.blob()` or `.arrayBuffer()`. -### Limitations +The separate **Function** tool supports additional runtimes and configured file inputs/outputs. Its controls differ from a saved custom tool and from the standalone Function block; see [Function](/workflows/blocks/function). -- **No npm packages** — External libraries like `axios` or `lodash` are not available. Use built-in APIs instead -- **Parameters by name** — Schema parameters are available directly as variables (e.g., `city`), not via a `params` object +## Use secrets -### Returning Results - -Return a value from your code to send it back to the agent: +For a secret used as a complete JavaScript expression, use an unquoted placeholder: ```javascript -const result = await fetch(`https://api.example.com/data?q=${query}`); -const data = await result.json(); -return data; +const apiKey = {{MY_API_KEY}}; ``` -The returned value becomes the tool output that the agent sees and can use in its response. +Quoted and embedded forms are also supported, including `"Bearer {{KEY}}"`, template literals, and JavaScript regex literals. Sim binds the value separately from the source, preserving its string contents. -## Managing Custom Tools + +Exact recognized secret values are masked in the trace copy and replaced before a tool result reaches the Agent model, unless the secret's visibility setting exempts it. Encoded or transformed values can escape that protection. Runtime operations still receive the real secret. Do not return or print secrets; see [Execution log protection](/platform/credentials#execution-log-protection) for the full scope and limits. + -From **Settings → Custom Tools** you can: +## Manage tools and access -- **Search** tools by name, function name, or description -- **Edit** any tool's schema or code -- **Delete** tools that are no longer needed +Under **Settings → Custom tools**, search by tool name, function name, or description. Open a definition to edit its schema or code. - Deleting a custom tool removes it from all Agent blocks that reference it. Make sure no active workflows depend on the tool before deleting. +Deleting a saved tool removes its definition and can break Agents that reference it. Review dependent workflows and remove or replace their bindings before deleting the tool. -## Permissions +| Action | Required workspace role | +| --- | --- | +| View tools | Read, Write, or Admin | +| Create, edit, or delete tools | Write or Admin | + +Organization permission groups can restrict custom-tool use. See [Permission groups](/platform/enterprise/access-control) for how restrictions apply. -| Action | Required Permission | -|--------|-------------------| -| View custom tools | **Read**, **Write**, or **Admin** | -| Create or edit tools | **Write** or **Admin** | -| Delete tools | **Admin** | +## Related docs - +- [Choosing what to use](/agents/choosing) +- [Agent block reference](/workflows/blocks/agent) +- [Function](/workflows/blocks/function) +- [Secrets](/platform/credentials) diff --git a/apps/docs/content/docs/agents/index.mdx b/apps/docs/content/docs/agents/index.mdx index 2fe27a3073c..206d0719786 100644 --- a/apps/docs/content/docs/agents/index.mdx +++ b/apps/docs/content/docs/agents/index.mdx @@ -1,63 +1,46 @@ --- title: Agents -description: An agent is a workflow that reasons and acts, built around Agent blocks and the features you give them. +description: Build workflow agents with models, tools, reusable instructions, and your data. --- -import { Callout } from 'fumadocs-ui/components/callout' -import { Card } from 'fumadocs-ui/components/card' import { WorkflowPreview, BUILD_AGENT_WORKFLOW } from '@/components/workflow-preview' -An **agent** is a [workflow](/workflows) that reasons and acts on its own. It reads an input, decides what to do, and carries it out, calling tools and using your data along the way. You build a custom agent in Sim by composing a workflow whose thinking runs through one or more [Agent blocks](/workflows/blocks/agent). +Build a workflow agent by connecting one or more **Agent** blocks to the steps it needs. Each Agent block sends messages to a model, lets it call configured tools, and returns a result for later blocks. -An **Agent block** is the reasoning step inside that workflow: a model reads the values available to it, decides, and returns a result that later blocks read by reference. A simple agent is a single Agent block; a larger one wires several together with other blocks. The Agent block is where the model thinks; the rest of the workflow is what it acts on and through. +## Build a workflow agent - - -The example throughout is an agent that scores inbound sales leads. - -## The Agent block - -You set up the reasoning step by giving the Agent block a **model** and a **prompt**. The model is the LLM that powers it; you pick one from the available providers, and the default is `claude-sonnet-5-5`. The prompt is a system message that defines who the agent is and how it should behave, plus a user message that carries the input, usually a reference like ``. - -When it runs, the Agent block reasons, calls any tools it needs, and stores its result under its own name. By default that result is free text in `content`, read by a later block as ``, alongside run details like the model used, token counts, tool calls, and cost. Every setting and output field is in the [Agent block reference](/workflows/blocks/agent). - -## What you give an agent - -On its own, an Agent block can only reason and write text. You extend it so it can act, follow your rules, use your data, remember, and return results other blocks can rely on. Each feature maps to something you'd want an agent to do. +A simple agent reads an input, scores it, and returns the score: -### Take an action: tools - -To let an agent do something in the world, give it **tools**. A tool is an action the agent can call, like sending an email, searching the web, updating a CRM record, or running another workflow. You attach tools to the Agent block, and the agent decides which to call for the task in front of it. In the lead scorer, the agent has a search tool to gather context on a thin profile and an email tool to reach out to a strong lead. - -Tools come from a few places: - -- **[Integrations](/integrations)** are the catalog of external services: Gmail, Slack, Airtable, Linear, and hundreds more. -- **[Custom tools](/agents/custom-tools)** are tools you define once with a schema and a snippet of code, then reuse. -- **[MCP tools](/agents/mcp)** come from an external provider you connect through the Model Context Protocol. -- **[Workflow-as-tool](/workflows)** makes another workflow callable, so the agent runs a whole procedure as one step. - - -The same integration can run two ways. As a [block](/workflows#blocks) it runs because the path reached it. As an agent tool it runs because the agent chose it. Per-tool usage controls (force a tool, or disable one) are in the [Agent block reference](/workflows/blocks/agent). - - -### Follow a procedure: skills + -To give an agent instructions it can follow, write a [skill](/agents/skills). A skill is a reusable playbook with a short name and description the agent always sees, plus a longer body it loads only when the skill applies. In the lead scorer, a `lead-scoring-rubric` skill spells out the bands and disqualifiers, and the agent reads the full rubric only when a lead is ambiguous. A tool is an action the agent takes; a skill is guidance it reads. +1. Add an [Agent block](/workflows/blocks/agent) after a [Start trigger](/workflows/triggers/start). +2. Select a **Model**. In **Messages**, use a system message for the task and rules, and a user message for the input, such as ``. +3. Add the tools or context the task needs, then run the workflow and inspect the result. -### Use your documents: knowledge +Without **Response Format**, later blocks read the answer as ``. Model, token, tool-call, and cost details are also available. The example requests a structured score, so its Response block reads `` after successful JSON parsing. See the [Agent reference](/workflows/blocks/agent) for model selection, settings, and outputs. -To let an agent answer from your own content, connect a [knowledge base](/knowledgebase). The agent searches it and grounds its answers in what it finds, instead of relying only on the model's general training. Give the lead scorer a knowledge base of past deals and it can compare a new lead against ones you've closed before. +## Add capabilities -### Remember across runs: memory +| Need | Configure | +| --- | --- | +| Take an action | Attach integration tools, [custom tools](/agents/custom-tools), [MCP tools](/agents/mcp), or another workflow as a tool. The model decides which available tools to call. | +| Follow a reusable procedure | Select [skills](/agents/skills), such as a lead-scoring rubric. The agent sees their names and descriptions, then loads instructions when they apply. | +| Answer from your documents | Add the [Knowledge](/integrations/knowledge) tool and select the knowledge base to search. | +| Read a file | Use the Agent block's **Files** input with a model that supports the file type. | +| Remember earlier runs | Configure [memory](/workflows/blocks/agent#memory) and a conversation ID. The memory mode controls which history reaches the model. | +| Return fields for later blocks | Set **Response Format** to request a JSON shape, then reference successful structured fields directly, such as ``. Provider support and malformed-output behavior vary. | -To let an agent reuse information from one run to the next, give it [memory](/workflows/blocks/agent#memory), which stores and recalls values keyed to a conversation. Without it, each run starts fresh; with it, an agent in a chat carries what was said earlier into later messages. +Tools and skills need a compatible model and the required workspace, credential, and organization access. Adding a skill supplies instructions; adding a tool gives the model an action it can call. -### Return a usable result: structured output +## Choose where an action runs -To make an agent's result something later blocks can act on, give it a **structured output**: a typed object you define instead of free text. In the lead scorer, the agent returns `{ score, tier, reason }`, and a later [Condition](/workflows/blocks/condition) block reads `` to branch. See [how blocks pass data](/workflows/data-flow) for reading fields. +Use a separate workflow block when an action must be attempted whenever that path runs. Attach it as an Agent tool when the model should decide whether it is needed. For example, a lead-scoring agent might search for missing company information, while a Google Sheets block records every score that reaches it. -## Choosing what to use +The same integration can serve either role. See [Choosing what to use](/agents/choosing) for the differences among fixed steps, Agent tools, custom tools, MCP connections, workflows as tools, and skills. -Start with one Agent block and a prompt, then add only what the task needs: a tool when the agent should act, a skill when it needs written guidance, a knowledge base when it should answer from your documents, memory when it should remember, and a structured output when a later block has to read its result. +## Related docs - +- [Agent block reference](/workflows/blocks/agent) +- [Choosing what to use](/agents/choosing) +- [How blocks pass data](/workflows/data-flow) +- [Chat](/chat) diff --git a/apps/docs/content/docs/agents/mcp.mdx b/apps/docs/content/docs/agents/mcp.mdx index 60cce667fe1..685761f7b50 100644 --- a/apps/docs/content/docs/agents/mcp.mdx +++ b/apps/docs/content/docs/agents/mcp.mdx @@ -1,206 +1,149 @@ --- title: Using MCP tools -description: Connect external tools and services using the Model Context Protocol +description: Connect external MCP servers and control which operations your workflow agents can call. --- -import { Image } from '@/components/ui/image' -import { Video } from '@/components/ui/video' import { Callout } from 'fumadocs-ui/components/callout' -The Model Context Protocol ([MCP](https://modelcontextprotocol.com/)) is an open standard for connecting AI to external tools and data. Add an MCP server to your workspace and its tools become available to your agents — a way to integrate services Sim doesn't have a built-in integration for. +MCP, the [Model Context Protocol](https://modelcontextprotocol.io/docs/getting-started/intro), connects AI applications to external tools. Register a remote server in your workspace, authorize its connection, and give its operations to an **Agent** block or run them through an **MCP** block. - - To use your Sim workspace from Claude, Codex, or Cursor, connect the - [Sim MCP server](/mcp/overview). - +Registrations are workspace-scoped. Add a separate registration in each workspace that needs the server. To connect an external app to Sim itself, use the [Sim MCP server](/mcp/overview), [workflow deployment MCP](/workflows/deployment/mcp), or [Search MCP](/search/mcp). -## Adding an MCP Server as a Tool - -MCP servers provide collections of tools that your agents can use. - -
- -
- -To add one: - -1. Navigate to **Settings → MCP Tools** - -
- MCP Tools settings page -
- -2. Click **Add** to open the configuration modal -3. Enter a **Server Name** and **Server URL** -4. Add any required **Headers** (e.g. API keys) -5. Click **Add MCP** to save - -
- Add New MCP Server modal -
- - -You can also configure MCP servers directly from the toolbar in an Agent block for quick setup. - +## Add a server -### Server Configuration Options +You need **Write** or **Admin** access. Sim supports remote **Streamable HTTP** servers; a local stdio command is not a supported registration. -| Field | Description | -|-------|-------------| -| **Name** | Display name for the server | -| **URL** | The MCP server endpoint | -| **Transport** | Currently supports `streamable-http` | -| **Headers** | Key-value pairs for authentication or custom headers | -| **Timeout** | Connection timeout in milliseconds (default: 30,000) | +1. Open **Settings → MCP tools** and select **Add server**. You can also select **Add MCP Server** in an Agent's **Tools** menu. +2. Enter the **Server Name** and **Server URL**. +3. Add authentication **Headers** if the provider requires them. Use saved secret references for sensitive values. +4. If the provider requires an OAuth client that cannot be registered automatically, open **Advanced settings** and enter its **Client ID** and **Client Secret**. +5. Select **Add server**. Sim tests the connection before saving. +6. For OAuth authentication, select **Authorize** on the saved server and complete browser sign-in. -### Environment Variables in Configuration +Open the server detail to inspect **Tools**, including parameter names, types, and required flags. A successful connection can expose no tools. When editing a registration, use **Test connection** to check connectivity. -Server URLs and headers support environment variable substitution using `{{VAR_NAME}}` syntax. This keeps sensitive values like API keys out of the server configuration. +The registration uses `streamable-http` and defaults to a 30,000 ms connection timeout. These are configuration values rather than selectable controls in the form. Each connection attempt is capped at 60,000 ms. OAuth requires HTTPS outside loopback development. -``` +**Edit JSON** accepts a remote configuration with a named `mcpServers` entry containing `url` and optional `headers`, or a configuration containing `url` directly. If several entries are present, it reads the first. It does not import a desktop client's executable command configuration. + +### Secrets in URLs and headers + +URLs and headers support `{{VAR_NAME}}` substitution from available saved secrets. Type `{{` in either field to open the secret picker: + +```text URL: https://api.example.com/mcp Authorization: Bearer {{MCP_API_TOKEN}} ``` -When you type `{{` in the URL or header fields, a dropdown appears showing available workspace environment variables. +When a secret is successfully substituted, Sim masks exact recognized values in stored MCP tool-call traces unless the secret's visibility setting exempts them. The real credentials are used for the provider request. See [Execution log protection](/platform/credentials#execution-log-protection) for model projection, visibility exceptions, and encoded or transformed values. -When a saved secret is successfully substituted this way, exact occurrences of its value are masked in stored MCP tool-call traces. The real URL or header value still reaches the MCP server unchanged. See [Execution log protection](/platform/credentials#execution-log-protection) for the exact scope and limitations. +### Connection identity -### Testing and Validation +Ordinary OAuth registrations use the acting user's OAuth connection. Unattended workflow runs use the run's trusted execution actor. Each member who needs an ordinary OAuth connection may need to authorize their own account. -Click **Test Connection** before saving to verify the server is reachable and discover available tools. The test response shows the number of tools found and the protocol version. +A managed connection uses the explicitly selected [Credential Group connection](/platform/connected-accounts) and its access grants. Servers managed by Connected accounts are configured there. -After saving, each server displays its available tools with parameter names, types, and required flags. If a server's tools change (e.g., after a server update), click **Refresh** to fetch the latest schemas. This automatically updates any agent blocks using those tools. + +MCP calls use the authorized connection's headers or OAuth credential. Review its operations before giving them to an Agent, and restrict access where needed. Allowing a generic operation such as `execute_sql` does not restrict the SQL it can run. + + +## Add tools to an Agent -Tool validation badges appear on servers with issues — for example, if a tool was removed from the server but is still referenced in a workflow. Click the badge to see which workflows are affected. +1. Open an **Agent** block with a model that supports tools. +2. Under **Tools**, select **Add tool...**. +3. In **MCP Servers**, open the configured server. +4. Select individual tools, or select **Configure operations access** to attach the server with an access policy. -### Domain Allowlisting +Individual tools expose their argument fields. The Agent chooses when to call the tools and supplies model-controlled inputs. Per-tool **Permission Mode** and current workspace, credential, and organization authorization still apply. -Self-hosted deployments can restrict which MCP server domains are allowed by setting the `ALLOWED_MCP_DOMAINS` environment variable (comma-separated list). When set, only servers on approved domains can be added. When unset, all domains are allowed. +### Dynamic server attachment -This governs which domains may be used. It is separate from where those domains are allowed to resolve: an MCP server on a private address is reached by naming it in `EGRESS_ALLOWED_HOSTS` or `EGRESS_ALLOWED_IP_RANGES`, described in [Security](/platform/self-hosting/security#the-ssrf-boundary). Both checks apply. +Select **MCP Server (Advanced)** to supply a server or managed-connection ID directly, or reference an upstream value. The **Tool IDs** field accepts literal exact operation names, such as `search_docs`, without a Sim server prefix. These fields use plain inputs rather than server or operation catalog pickers. -The allowlist covers the server URL itself. If the server requires OAuth, any endpoint its metadata names on a *different* origin than the server you configured is treated as content rather than as configuration, so that one has to be publicly routable. Endpoints on the server's own origin keep the server's reachability. +Operation names in **Tool IDs** are configuration, not model arguments or upstream references. The policy applies to whichever authorized connection the server reference resolves to at runtime. + +### Operations access -## Using MCP Tools in Agents +| Mode | Behavior | +| --- | --- | +| **Only selected** | Allows the selected exact operation names. An empty selection allows nothing; newly discovered names stay excluded. | +| **All except selected** | Denies the selected exact names. An empty selection allows everything otherwise permitted. Denied names remain saved if they temporarily disappear. | +| **All permitted** | Allows every operation available to the authorized credential. | -Once MCP servers are configured, their tools become available within your agent blocks: +New restricted attachments start with an empty explicit selection. Existing saved configurations retain their prior access through normalization, subject to current authorization. -
- Using MCP Tool in Agent Block -
+The policy is saved on the Agent attachment. Discovery filters the tools offered to the model, and execution checks the resolved server, connection, and policy again before calling the provider. Names are case-sensitive. The policy can narrow credential access; it cannot grant access the credential lacks. -1. Open an **Agent** block -2. In the **Tools** section, click **Add tool…** -3. Under **MCP Servers**, click a server to see its tools +Missing or forbidden operations, invalid connection scopes, unverifiable schemas, and malformed arguments fail the call. An Agent attachment with no permitted operations fails clearly. Operation restrictions match names; they do not inspect arguments. -
- MCP tools list for a selected server -
+## Run or list operations with an MCP block -4. Select individual tools, or choose **Configure operations access** for a dynamic server attachment -5. The agent can now access these tools during execution +Use an **MCP** block for explicit execution or authorized operation discovery. Select its **Action**: - -If you haven't configured a server yet, click **Add MCP Server** at the top of the dropdown to open the setup modal without leaving the block. - +- **Run operation** executes one exact operation name. Configured operations show generated argument fields. If the name resolves at runtime, supply a JSON arguments object; Sim validates it against the discovered schema before execution. +- **List operations** returns authorized operation names, descriptions, and input schemas without executing provider operations. **Search operations** filters names and descriptions. **Page size** accepts 1–100 and defaults to 100; it and **Cursor** are advanced fields. -## Standalone MCP Block +In Basic mode, select a configured connection under **MCP Server** and a discovered **Operation**. In Advanced mode, enter literal IDs/names or references. A runtime server reference requires JSON arguments. Listing hides the operation and argument fields. -Use the MCP block to discover operations or run one operation with explicit inputs: +**MCP Server** accepts one shared-server ID or managed-connection ID. Sim resolves a managed connection's parent server and verifies workspace and credential access. Both actions use the same identifier. The standalone block runs its specified operation and has no separate Agent attachment policy. -
- Standalone MCP Tool Block -
+### Outputs and pagination -Choose an **Action**: +| Output | Meaning | +| --- | --- | +| `serverId` | The supplied server or managed-connection ID | +| `operations` | Listed operations with `name`, `description`, and `inputSchema` | +| `nextCursor` | Cursor for the next list page, or `null` | +| `hasMore` | Whether more authorized operations remain in the discovered inventory | +| `content` | The MCP content array returned by a run operation | -- **List operations** discovers authorized operation names, descriptions, and input schemas without executing provider operations. Filter by name or description, set a page size from 1 to 100, and pass `nextCursor` into the next request while `hasMore` is true. An authorized list can be empty. -- **Run operation** executes one exact operation name. Configured operations keep their generated argument fields. For an operation name resolved at runtime, supply a JSON arguments object; Sim validates it against the operation's discovered schema before execution. +While `hasMore` is true, pass `nextCursor` into **Cursor** on the next list request. An authorized list can be empty. This pagination does not bypass the discovery limits below. -**MCP Server** takes one shared-server ID or managed-connection ID. Sim resolves a managed connection's parent server internally and verifies workspace and credential access. Both actions accept the same ID; List operations returns that ID as `serverId`, alongside the discovered `operations` and pagination metadata. +## Refresh and troubleshoot -The standalone block's Basic fields select a configured connection and discovered operation. Advanced fields accept literal IDs/names or upstream references. A runtime server reference requires JSON arguments. Listing hides the operation and argument fields. +Use **Refresh** on the server detail to fetch current schemas. Matching individual MCP bindings in draft Agent blocks receive updated schemas and server metadata. Removed operations remain referenced and can fail; review validation badges to see affected workflows. Deploy an updated draft when the deployed version needs those changes. Dynamic attachments discover authorized tools when they run. -### Operations access +Discovery normally uses a five-minute cache. Failed server probes can be cached for two minutes; Refresh forces a retry. A cached or partially discovered inventory does not prove the provider has no other operations. -The **MCP Server (Advanced)** Agent attachment takes a server/connection ID or upstream reference in a plain input. Its **Tool IDs** field accepts exact MCP tool names, such as `search_docs`, entered directly. These are the names returned by List operations, without a Sim server prefix. Neither field uses a server or operation catalog picker. +### Discovery limits -Agent attachments have three access modes: +Client discovery follows the provider's `tools/list` pages within these bounds: -| Mode | Behavior | +| Budget | Hard limit | | --- | --- | -| **Only selected** | Allows only selected exact operation names. An empty selection allows nothing. Newly discovered names stay excluded. | -| **All except selected** | Denies selected exact names. An empty selection allows everything otherwise permitted. Denied names stay saved if they temporarily disappear. | -| **All permitted** | Allows every operation available to the authorized credential. | +| Pages | 50 | +| Aggregated tools | 1,000 | +| Combined tool payload | 5 MiB | +| Aggregate discovery time | 60 seconds | -New restricted configurations start with an empty explicit selection. Existing saved workflows retain their prior access through normalization, while current organization and credential authorization still apply. +Repeated provider cursors also stop discovery. Settings discovery may return a partial inventory after a bound or later-page failure. Runtime discovery requires completion and fails if the inventory is truncated. The standalone block's page size applies after this discovery and authorization. -Operation restrictions are saved in workflow state on the Agent attachment. Tool IDs are literal configuration, not upstream references or model arguments. An operation must be available to the resolved, authorized connection and permitted by the saved restriction. The standalone block runs its explicitly specified operation and has no separate access policy. +If a call fails, check the server's connectivity, authorization, current schema, and saved access policy. An Agent can receive the tool error and respond or try another action; a standalone block uses the workflow's configured error handling. Verify the provider's state before repeating an operation that may have side effects. -Discovery filters the tools exposed to the Agent. Execution checks the actual server, connection, and saved restriction again before calling the provider. Missing or forbidden operations, unverifiable schemas, malformed arguments, and incorrect connection scopes fail the call. An Agent attachment with no permitted operations fails clearly. +## Permissions -Policies match exact, case-sensitive MCP tool names on whichever authorized connection resolves at runtime. They do not inspect operation arguments: allowing a generic `execute_sql` operation does not limit which SQL it can execute. +| Action | Required workspace role | +| --- | --- | +| View, discover, or execute available MCP operations | Read, Write, or Admin | +| Register, edit, refresh, or delete external servers | Write or Admin | +| Change a registered server's destination host or path | Admin | -## When to Use MCP Tool vs Agent +Adding or changing a workflow's tools also requires workflow edit access. Credential grants and organization permission-group restrictions apply separately. On Enterprise-entitled workspaces, a workspace Admin can configure `disableMcpTools` through [permission groups](/platform/enterprise/access-control). -| Feature | **Agent with MCP tools** | **MCP Tool block** | -|---|---|---| -| **Execution** | AI decides which tools to call | Deterministic — runs the tool you pick | -| **Parameters** | AI chooses at runtime | You set them explicitly | -| **Best for** | Dynamic, conversational flows | Structured, repeatable steps | -| **Reasoning** | Handles complex multi-step logic | One tool, one call | +These permissions govern external server registrations. [Workflow MCP deployment](/workflows/deployment/mcp) has its own management and invocation requirements. -## Permission Requirements +## Self-hosted network policy -MCP functionality requires specific workspace permissions: +Set `ALLOWED_MCP_DOMAINS` to a comma-separated list of exact approved hostnames to restrict server domains. When unset, there is no domain allowlist restriction. -| Action | Required Permission | -|--------|-------------------| -| Create or update MCP servers | **Write** or **Admin** | -| Delete MCP servers | **Admin** | -| Use MCP tools in agents | **Write** or **Admin** | -| View available MCP tools | **Read**, **Write**, or **Admin** | -| Execute MCP Tool blocks | **Read**, **Write**, or **Admin** | +Domain approval and network reachability are separate checks. Private-address servers also need `EGRESS_ALLOWED_HOSTS` or `EGRESS_ALLOWED_IP_RANGES`; see [the SSRF boundary](/platform/self-hosting/security#the-ssrf-boundary). - -MCP servers run with the permissions of the user who configured them — only connect servers you trust, and review a server's tools before handing them to agents. - +The domain allowlist applies to the configured server URL. For OAuth, an endpoint on that server's origin retains its reachability. An endpoint named by metadata on a different origin is treated as fetched content and must be publicly routable under the egress policy. -import { FAQ } from '@/components/ui/faq' +## Related docs - +- [Choosing what to use](/agents/choosing) +- [Connected accounts](/platform/connected-accounts) +- [Sim MCP server](/mcp/overview) +- [Workflow deployment MCP](/workflows/deployment/mcp) +- [Search MCP](/search/mcp) diff --git a/apps/docs/content/docs/agents/skills.mdx b/apps/docs/content/docs/agents/skills.mdx index 5690219d80a..fa11c0d4ce4 100644 --- a/apps/docs/content/docs/agents/skills.mdx +++ b/apps/docs/content/docs/agents/skills.mdx @@ -1,149 +1,114 @@ --- title: Agent skills -description: Reusable instruction packages your agents load on demand, managed from the Skills tab. +description: Write reusable instructions for workflow Agents to load on demand or select them directly in Chat. --- import { Callout } from 'fumadocs-ui/components/callout' import { Image } from '@/components/ui/image' -Agent Skills are reusable packages of instructions that give your AI agents specialized capabilities. Based on the open [Agent Skills](https://agentskills.io) format, skills let you capture domain expertise, workflows, and best practices that agents can load on demand. +A skill is reusable Markdown guidance, such as a scoring rubric, support procedure, or writing style guide. Sim workspace skills use the name, description, and instructions from the open [Agent Skills format](https://agentskills.io/specification). -## How Skills Work +Skills supply guidance. Tools perform actions, and each action still requires its normal access and configuration. -Skills use **progressive disclosure** to keep agent context lean: +## Use a skill in an Agent -1. **Discovery** — Only skill names and descriptions are included in the agent's system prompt (~50-100 tokens each) -2. **Activation** — When the agent decides a skill is relevant, it calls the `load_skill` tool to load the full instructions into context -3. **Execution** — The agent follows the loaded instructions to complete the task +1. Open an **Agent** block with a model that supports tools and skills. +2. In **Skills**, select **Add skill...** and choose the skills it should have available. +3. Run a task that matches a selected skill, then inspect the Agent's tool calls. -## Creating Skills +The Agent Skills menu with Add skill and Create Skill controls -Skills live on the **Integrations** page: click **Integrations** in the workspace sidebar, then switch to the **Skills** tab. It lists every skill in the workspace, searchable by name. Click a skill to open its detail page, where you edit, share, and delete it. +Selected skills appear as cards that you can open or remove. Editing depends on your access to the skill. -![The Skills tab on the Integrations page](/static/skills/skills-tab.png) +At runtime, the Agent's system prompt includes an `` section with the selected names and descriptions. Sim adds a `load_skill` tool with a `skill_name` input. When the model calls it, the full instructions return as a tool response. Selecting a skill makes it available; the model decides whether to load it. -Click **+ Add to Sim** to open the skill create page, which takes three fields: +This uses standard tool calling across compatible models. Deep-research and evaluation models do not expose the ordinary Agent Tools and Skills controls. -| Field | Description | -|-------|-------------| -| **Name** | A kebab-case identifier (e.g. `sql-expert`, `code-reviewer`). Max 64 characters. | -| **Description** | A short explanation of what the skill does and when to use it. This is what the agent reads to decide whether to activate the skill. Max 1024 characters. | -| **Content** | The full skill instructions in markdown. This is loaded when the agent activates the skill. | +## Use a skill in Chat - - The description is critical — it's the only thing the agent sees before deciding to load a skill. Be specific about when and why the skill should be used. - - -### Importing skills - -Bring in an existing skill in the open [SKILL.md](https://agentskills.io/specification) format two ways: +Type `/` in the Chat message box to open the skills menu. Select a skill or keep typing to filter by name. The selected skill appears as a tag, such as `/format-markdown`. -- **Import** — the **Import** action on the create page takes a `.md` file with YAML frontmatter, or a `.zip` containing a `SKILL.md`. -- **Paste content** — paste the `SKILL.md` straight into **Content**. The frontmatter carries the `name` and `description`; the markdown body is the content. +Tagging a skill includes its full instructions in the request. Sim can use them immediately, without deciding to load them through a tool first. Instructions guide the response; they do not guarantee compliance or grant additional access. -Integration pages suggest **curated skills** for their service — open one (HubSpot, for example) and add a suggested skill with one click. +## Create a workspace skill -### Writing Good Skill Content +You need **Write** or **Admin** workspace access to create a skill. -Skill content follows the same conventions as [SKILL.md files](https://agentskills.io/specification): - -```markdown -# SQL Expert - -## When to use this skill -Use when the user asks you to write, optimize, or debug SQL queries. - -## Instructions -1. Always ask which database engine (PostgreSQL, MySQL, SQLite) -2. Use CTEs over subqueries for readability -3. Add index recommendations when relevant -4. Explain query plans for optimization requests - -## Common Patterns -... -``` +1. Open **Integrations** in the workspace sidebar and select **Skills**. +2. Select **Add to Sim**. +3. Enter **Name**, **Description**, and **Content**, then save. -**Recommended structure:** -- **When to use** — Specific triggers and scenarios -- **Instructions** — Step-by-step guidance with numbered lists -- **Examples** — Input/output samples showing expected behavior -- **Common Patterns** — Reusable approaches for frequent tasks -- **Edge Cases** — Gotchas and special considerations +| Field | Requirements | +| --- | --- | +| **Name** | A workspace-unique kebab-case identifier, such as `lead-scoring-rubric`; 1–64 lowercase letters, digits, and hyphens, with no leading, trailing, or consecutive hyphens. | +| **Description** | Explain what the skill does and when to use it; required, up to 1,024 characters. | +| **Content** | Full Markdown instructions; required, up to 50,000 characters. | -Keep skills focused and under 500 lines. If a skill grows too large, split it into multiple specialized skills. +Search the Skills tab by name or description. Open a skill's detail page to edit it, share editor access, or delete it. Built-in skills are read-only templates; workspace skills have the editor controls described below. Integration pages can also suggest curated skills for their service, which you can add from that page. -## Skill Editors +### Write instructions -Everyone in the workspace sees and uses every skill — including members who join later. Nobody needs to be added to a skill to use it. +Keep the task and activation conditions specific. Include the steps, expected output, and edge cases that the agent needs. Keep task-specific input in the Agent block's messages. -Each skill has an explicit **editors** list. Editors can edit the skill, delete it, and manage the editors list. Workspace admins can always do this too — they are editors of every skill automatically and cannot be removed from the list. Whoever creates a skill becomes an editor. +For example, this skill defines how to score an inbound lead: -Open a skill from the Skills tab to manage it. The detail page has the editable fields, a **Share** action for adding editors from your workspace members, and the **Skill Editors** list at the bottom. - - - The editors list controls who can edit a skill — it never affects who can see, use, or run it. A workflow that references a skill always executes it, no matter who runs the workflow. Treat skill content as shared team instructions, not as a secret. - - -## Using Skills in Chat +```markdown +--- +name: lead-scoring-rubric +description: Score inbound sales leads using company fit and stated intent. Use when qualifying a lead or explaining its score. +--- -Skills work in Chat too. Type `/` in the message box to open the skills menu, then pick a skill — or keep typing to filter by name. The skill appears in your message as a tag, e.g. `/format-markdown`. +# Lead scoring rubric -Tagging a skill loads its full instructions into the conversation, so Sim follows them for that request — no waiting for Sim to decide the skill is relevant on its own. +1. Read the lead's company, role, use case, and stated timeline. +2. Check the configured company-fit criteria. Identify missing evidence. +3. Use available research tools only when more evidence is needed. +4. Assign a score from 0 to 100 and a tier: high, medium, or low. +5. Explain the factors behind the score. Do not invent missing facts. -## Adding Skills to an Agent +Return the score, tier, reason, and any missing information. +Do not send outreach unless the task authorizes it. +``` -Open any **Agent** block and find the **Skills** dropdown below the tools section. Select the skills you want the agent to have access to. +The tool and response-format configuration belongs on the Agent block. Mentioning a tool or asking for fields in a skill does not create that configuration. -Add Skill +Keep skills focused. The Agent Skills specification recommends keeping the main instructions under 500 lines; this is guidance, while Sim's content limit is 50,000 characters. For large workspace instructions, split them into separate skills that can be selected independently. -Selected skills appear as cards that you can click to edit or remove. +### Import instructions -### What Happens at Runtime +Select **Import** on the create page to choose a `.md` file or a `.zip` containing `SKILL.md`. ZIP files have a 5 MiB size limit. If the archive contains several matching files, Sim selects the shallowest `SKILL.md`. -When the workflow runs: +Use simple single-line `name:` and `description:` frontmatter values followed by the Markdown body. Sim imports those three fields. Bundled scripts, reference files, assets, and other frontmatter metadata are not imported. Adapt instructions that depend on those files before using the skill. -1. The agent's system prompt includes an `` section listing each skill's name and description -2. A `load_skill` tool is automatically added to the agent's available tools -3. When the agent determines a skill is relevant to the current task, it calls `load_skill` with the skill name -4. The full skill content is returned as a tool response, giving the agent detailed instructions +You can also paste a complete `SKILL.md` into **Content**. When it contains a `name` frontmatter field, Sim fills Name and Description from the frontmatter and uses the Markdown body as Content. Review all fields before saving. -This works across all supported LLM providers — the `load_skill` tool uses standard tool-calling, so no provider-specific configuration is needed. +## Editors and access -## When to use a skill +Workspace members can see and use workspace skills without being added as editors, subject to organization restrictions. New members receive the same use access. -Use a skill for reusable procedures or knowledge shared across agents, such as a company style guide or a debugging checklist. Keep task-specific instructions in the Agent block. +Each workspace skill has an explicit editors list: -## Best Practices +- The creator becomes an editor. +- Editors can edit, delete, and manage the editors list while they retain workspace access, including editors with the Read workspace role. +- Workspace Admins are editors automatically and cannot be removed from that derived access. -**Writing Effective Descriptions** -- **Be specific and keyword-rich** — Instead of "Helps with SQL", write "Write optimized SQL queries for PostgreSQL, MySQL, and SQLite, including index recommendations and query plan analysis" -- **Include activation triggers** — Mention specific words or phrases that should prompt the skill (e.g., "Use when the user mentions PDFs, forms, or document extraction") -- **Keep it under 200 words** — Agents scan descriptions quickly; make every word count +Open the skill detail and use **Share** to add workspace members as editors. The **Skill Editors** list shows who can change it. -**Skill Scope and Organization** -- **One skill per domain** — A focused `sql-expert` skill works better than a broad `database-everything` skill -- **Limit to 5-10 skills per agent** — More skills = more decision overhead; start small and add as needed -- **Split large skills** — If a skill exceeds 500 lines, break it into focused sub-skills + +The editors list controls changes to a skill, not who can load its instructions. Treat skill content as shared team instructions, not as a secret. Organization restrictions can still block skill use during a workflow run. + -**Content Structure** -- **Use markdown formatting** — Headers, lists, and code blocks help agents parse and follow instructions -- **Provide examples** — Show input/output pairs so agents understand expected behavior -- **Be explicit about edge cases** — Don't assume agents will infer special handling +On Enterprise-entitled workspaces, a workspace Admin can configure `disableSkills` in [permission groups](/platform/enterprise/access-control). The restriction applies separately from the skill's editors list. -**Testing and Iteration** -- **Test activation** — Run your workflow and verify the agent loads the skill when expected -- **Check for false positives** — Make sure skills aren't activating when they shouldn't -- **Refine descriptions** — If a skill isn't loading when needed, add more keywords to the description +## Verify activation -## Learn More +Run a representative task and inspect whether the Agent called `load_skill`. If it did not load the intended skill, make the description's task and conditions clearer. Also check the selected model, skill selection, and organization access. -- [Agent Skills specification](https://agentskills.io) — The open format for portable agent skills -- [Example skills](https://github.com/anthropics/skills) — Browse community skill examples -- [Best practices](https://agentskills.io/what-are-skills) — Writing effective skills +Test the resulting behavior as well as loading: instructions can be available while the model still produces an unsuitable answer. -import { FAQ } from '@/components/ui/faq' +## Related docs - +- [Choosing what to use](/agents/choosing) +- [Agent block reference](/workflows/blocks/agent) +- [Agent Skills specification](https://agentskills.io/specification) +- [Community skill examples](https://github.com/anthropics/skills) diff --git a/apps/docs/content/docs/api-reference/authentication.mdx b/apps/docs/content/docs/api-reference/authentication.mdx index d43896f4ee4..68ff9898935 100644 --- a/apps/docs/content/docs/api-reference/authentication.mdx +++ b/apps/docs/content/docs/api-reference/authentication.mdx @@ -1,124 +1,88 @@ --- title: Authentication -description: Authenticate with API keys or delegated OAuth access tokens +description: Choose an API key or delegated OAuth token and understand its access. --- import { Callout } from 'fumadocs-ui/components/callout' -import { Tab, Tabs } from 'fumadocs-ui/components/tabs' -The Sim API accepts API keys and, when enabled by your deployment, OAuth access tokens. API keys support automation and the SDKs. OAuth lets the CLI and registered applications act on your behalf with permissions you approve. +Authenticate API requests with a Sim API key, or an OAuth access token when your deployment enables OAuth. The Python and TypeScript SDKs use API keys. The CLI and registered OAuth applications can act with the permissions you approve. -Sim supports two types of API keys — **personal keys** and **workspace keys** — each with different billing and access behaviors. +## Choose a key [#key-types] -## Key Types - -| Feature | **Personal Keys** | **Workspace Keys** | +| | Personal key | Workspace key | | --- | --- | --- | -| **Billing** | Workspace payer for workspace-hosted usage | Workspace payer | -| **Scope** | Across workspaces you have access to | Shared across the workspace | -| **Managed by** | Each user individually | Workspace admins | -| **Permissions** | Must be enabled at workspace level | Require admin permissions | - - - Personal keys identify the user making a request; they do not select who pays. - Hosted usage is billed to the workspace's organization or personal billing - account and, for organizations, is attributed to the actor's member cap. - Workspace admins can disable personal API key usage for their workspace. If - disabled, only workspace keys can be used. - +| Identity | The key owner | The workspace | +| Scope | Workspaces the owner can currently access | One workspace | +| Access | The owner's current role and applicable permission-group restrictions | Only operations that allow workspace keys; no admin access | +| Managed by | The account owner, subject to key-management policy | Workspace Admins, subject to key-management policy | +| Hosted usage payer | The workspace's billing account | The workspace's billing account | + +A personal key identifies the acting member; it does not choose who pays. Hosted workspace usage is billed to the workspace's organization or personal billing account. In an organization, usage attributed to a member counts toward that member's cap. See [Credits, billing and limits](/platform/costs). -## Generating API Keys +Workspace Admins can turn off **Allow personal API keys**. The workspace policy also blocks delegated OAuth access to that workspace. Permission groups can restrict personal-key and OAuth access further. Workspace keys do not inherit their creator's role or permission group; each endpoint's workspace-key policy determines whether they can call it. -To generate a personal key, open **Account settings** → **Sim API keys**. Workspace -administrators can create shared keys from **Workspace settings** → **Sim API keys**. +## Create and store a key [#generating-api-keys] + +1. Open **Account settings → Sim API keys** to create a personal key, or **Workspace settings → Sim API keys** to create a workspace key. +2. Select **Create API key**, enter a name, and create it. Workspace-key creation requires workspace **Admin** access and the applicable key-management permission. +3. Copy the key and store it in a server-side environment variable such as `SIM_API_KEY`. - API keys are only shown once when generated. Store your key securely — you will not be able to view it again. +Sim shows the complete key once, immediately after creation. Copy it before closing the dialog. If you lose it, create a replacement and delete the old key. -## Using API Keys - -Pass your API key in the `X-API-Key` header with every request. An API key is never accepted as `Authorization: Bearer`; that header is only for [OAuth access tokens](#oauth-access-tokens). - - - - ```bash - curl -X POST https://www.sim.ai/api/v2/workflows/{workflowId}/execute \ - -H "Content-Type: application/json" \ - -H "X-API-Key: YOUR_API_KEY" \ - -d '{"input": {}}' - ``` - - - ```typescript - const response = await fetch( - 'https://www.sim.ai/api/v2/workflows/{workflowId}/execute', - { - method: 'POST', - headers: { - 'Content-Type': 'application/json', - 'X-API-Key': process.env.SIM_API_KEY!, - }, - body: JSON.stringify({ input: {} }), - } - ) - ``` - - - ```python - import os - - import requests - - response = requests.post( - "https://www.sim.ai/api/v2/workflows/{workflowId}/execute", - headers={ - "Content-Type": "application/json", - "X-API-Key": os.environ["SIM_API_KEY"], - }, - json={"input": {}}, - ) - ``` - - - -## Where Keys Are Used - -API keys authenticate access to: - -- **Workflow execution** — run deployed workflows via the API -- **Logs API** — query workflow execution logs and metrics -- **MCP servers** — authenticate connections to deployed MCP servers -- **SDKs** — the [Python](/api-reference/python) and [TypeScript](/api-reference/typescript) SDKs use API keys for all operations +Delete a key from the same settings page to revoke it. Update applications that used it with a replacement key. + +## Send an API key [#using-api-keys] + +Send the key in `X-API-Key`. The v2 API accepts `Authorization: Bearer` only for [OAuth access tokens](#oauth-access-tokens), not API keys. For example, with `SIM_API_KEY` and `WORKFLOW_ID` set: + +```bash +curl --fail-with-body -X POST \ + "https://www.sim.ai/api/v2/workflows/$WORKFLOW_ID/execute" \ + -H "X-API-Key: $SIM_API_KEY" \ + -H 'Content-Type: application/json' \ + -d '{"input": {}}' +``` + +This runs the active deployment. Use your deployment's origin for self-hosted requests. [Getting started](/api-reference/getting-started) includes complete HTTP examples and response handling; [Python](/api-reference/python) and [TypeScript](/api-reference/typescript) show SDK calls. + +Keys authenticate workflow execution, logs, deployed MCP servers, and other API resources that accept their key type. See each endpoint for its required access. ## OAuth access tokens -Use `sim login` to authorize the CLI in your browser, or `sim login --read-only` to request read access. The CLI stores the login locally and refreshes access tokens automatically. See [CLI authentication](/cli/authentication) for profiles, sign-in, and sign-out. +Run `sim login` to authorize the CLI in your browser, or `sim login --read-only` to request read access. The CLI stores the login locally and refreshes its access token. See [CLI authentication](/cli/authentication) for profiles, sign-in, and sign-out. -Registered OAuth applications send access tokens in the `Authorization` header: +Registered applications send OAuth access tokens in `Authorization: Bearer`: ```bash -curl https://www.sim.ai/api/v2/workspaces \ - -H "Authorization: Bearer YOUR_ACCESS_TOKEN" +curl --fail-with-body 'https://www.sim.ai/api/v2/workspaces' \ + -H "Authorization: Bearer $SIM_ACCESS_TOKEN" ``` +Use `X-API-Key` for API keys and the Bearer header for OAuth access tokens. Send one credential scheme per request. + | Scope | Access | | --- | --- | | `api:read` | Read operations, including searches sent as POST requests | -| `api:write` | Includes `api:read`, plus mutations and execution, including operations that can start external work | +| `api:write` | Includes read access, mutations, and execution, including operations that start external work | | `offline_access` | Refresh tokens for continued access after the access token expires | -Scopes limit what an application may do; your current workspace membership and role still apply. Each endpoint documents its required scope. Some GET endpoints that perform external discovery require `api:write`, so HTTP method alone does not determine the permission. +Scopes limit the application's actions; your current workspace membership, role, credential access, and permission policies still apply. Each endpoint declares its required scope. Some GET endpoints that perform external discovery require `api:write`, so HTTP method alone does not determine access. -Manage grants in **Settings** → **General** → **Authorized apps**. Revoking an application signs out all of its logins. `sim logout` revokes the current CLI login and removes it from your machine. The Python and TypeScript SDKs currently use API keys; they do not manage OAuth sign-in or refresh tokens. +Manage grants in **Settings → General → Authorized apps**. Revoking an application revokes all its logins for your account. For an OAuth login, `sim logout` revokes the current login and removes it locally; the CLI reports if server revocation fails. Removing a locally stored API key does not revoke that key on the server. -## Security +The Python and TypeScript SDKs do not manage OAuth sign-in or token refresh. -- Keys use the `sk-sim-` prefix and are encrypted at rest -- Keys can be revoked at any time from the dashboard -- Use environment variables to store keys — never hardcode them in source code -- For browser-based applications, use a backend proxy to avoid exposing keys to the client +## Protect credentials [#security] - - Never expose your API key in client-side code. Use a server-side proxy to make authenticated requests on behalf of your frontend. - +Keep API keys and OAuth tokens on your server. A browser application should call an authenticated backend that checks which resources the caller may use before sending a Sim request. Do not put keys in client-side code or source control. + +Sim supports modern `sk-sim-` and legacy `sim_` API keys. On self-hosted deployments, stored API keys are encrypted when `API_ENCRYPTION_KEY` is configured; deployments without it retain the legacy plaintext storage behavior. Configure it using the [environment-variable reference](/platform/self-hosting/environment-variables). + +## Related docs + +- [API getting started](/api-reference/getting-started) +- [CLI authentication](/cli/authentication) +- [Permissions](/platform/permissions) +- [Python SDK](/api-reference/python) and [TypeScript SDK](/api-reference/typescript) diff --git a/apps/docs/content/docs/api-reference/getting-started.mdx b/apps/docs/content/docs/api-reference/getting-started.mdx index 256912d0499..07f511940df 100644 --- a/apps/docs/content/docs/api-reference/getting-started.mdx +++ b/apps/docs/content/docs/api-reference/getting-started.mdx @@ -1,124 +1,112 @@ --- -title: Getting Started -description: Base URL, OpenAPI specification, first API call, response format, error handling, and pagination +title: Getting started +description: Make a v2 API call, inspect its result, and handle pagination and errors. --- -import { Callout } from 'fumadocs-ui/components/callout' -import { Tab, Tabs } from 'fumadocs-ui/components/tabs' +import { Tab, Tabs } from '@/components/ui/tabs' import { Step, Steps } from 'fumadocs-ui/components/steps' -## Base URL - -All API requests are made to: - -``` -https://www.sim.ai -``` +Use the v2 API to run workflows and manage resources you can access. This guide makes a first call to a deployed workflow, then explains asynchronous execution, response envelopes, and pagination. -Every endpoint lives under `/api` on this origin, for example `https://www.sim.ai/api/v2/workflows/{workflowId}/execute`. There is no `api.sim.ai` host. +## Base URL -## OpenAPI specification +Sim Cloud uses `https://www.sim.ai`, with API paths under `/api/v2`. There is no `api.sim.ai` host. For self-hosted Sim, replace the origin with your deployment URL. -Download the [complete OpenAPI 3.1 specification](/openapi.json) as JSON for client generation, request validation, and API tooling. +Download the [OpenAPI 3.1 specification](/openapi.json) for client generation, request validation, and API tooling. -## Quick Start +## Run a deployed workflow [#quick-start] - -### Get your API key +### Create an API key -Open **Account settings** → **Sim API keys** to create a personal key, or **Workspace settings** → **Sim API keys** for a workspace key. These examples and the SDKs use API keys; the CLI also supports browser sign-in with `sim login`. See [Authentication](/api-reference/authentication) for key types and OAuth permissions. +Open **Account settings → Sim API keys** for a personal key, or **Workspace settings → Sim API keys** for a workspace key. Set `SIM_API_KEY` in your server environment. See [Authentication](/api-reference/authentication) for key types, access policies, and OAuth tokens. The CLI also supports browser sign-in with `sim login`. - -### Find your workflow ID +### Find the workflow ID -Open a workflow in the Sim editor. The workflow ID is in the URL: +Open the workflow in the workflow builder. Its URL contains the ID: -``` +```text https://www.sim.ai/workspace/{workspaceId}/w/{workflowId} ``` -You can also use the [List Workflows](/api-reference/workflows/listWorkflows) endpoint to get all workflow IDs in a workspace. +Set `WORKFLOW_ID` to that value. You can also use [List workflows](/api-reference/workflows/listWorkflows) to find IDs in a workspace. - -### Deploy your workflow +### Deploy the workflow -A workflow must be deployed before it can be executed via the API. Click the **Deploy** button in the editor toolbar, or use the dashboard to manage deployments. - +Open **Deploy** in the workflow builder and deploy the version you want to run. Deployment requires workspace **Admin** access and the applicable deployment permission. +These examples run the active deployment. Draft edits take effect after you deploy an update. V2 also supports explicit manual draft execution for personal-key or OAuth callers with write access; see [Execute workflow](/api-reference/workflows/executeWorkflowV2). + -### Make your first request +### Call and inspect the result + +Place named workflow input fields inside `input`. Replace the example input with fields your deployed trigger accepts. ```bash - curl -X POST https://www.sim.ai/api/v2/workflows/{workflowId}/execute \ - -H "Content-Type: application/json" \ - -H "X-API-Key: YOUR_API_KEY" \ + curl --fail-with-body -X POST \ + "https://www.sim.ai/api/v2/workflows/$WORKFLOW_ID/execute" \ + -H "X-API-Key: $SIM_API_KEY" \ + -H 'Content-Type: application/json' \ -d '{"input": {}}' ``` ```typescript - const response = await fetch( - `https://www.sim.ai/api/v2/workflows/${workflowId}/execute`, - { - method: 'POST', - headers: { - 'Content-Type': 'application/json', - 'X-API-Key': process.env.SIM_API_KEY!, - }, - body: JSON.stringify({ input: {} }), - } - ) - - const data = await response.json() - console.log(data.data.output) + const apiKey = process.env.SIM_API_KEY + const workflowId = process.env.WORKFLOW_ID + if (!apiKey || !workflowId) throw new Error('Set SIM_API_KEY and WORKFLOW_ID') + + const response = await fetch(`https://www.sim.ai/api/v2/workflows/${workflowId}/execute`, { + method: 'POST', + headers: { 'Content-Type': 'application/json', 'X-API-Key': apiKey }, + body: JSON.stringify({ input: {} }), + }) + if (!response.ok) throw new Error(`HTTP ${response.status}: ${await response.text()}`) + + const result = await response.json() + process.stdout.write(JSON.stringify({ status: result.data.status, output: result.data.output })) ``` ```python - import requests import os + import requests + workflow_id = os.environ["WORKFLOW_ID"] response = requests.post( f"https://www.sim.ai/api/v2/workflows/{workflow_id}/execute", - headers={ - "Content-Type": "application/json", - "X-API-Key": os.environ["SIM_API_KEY"], - }, + headers={"X-API-Key": os.environ["SIM_API_KEY"]}, json={"input": {}}, + timeout=30, ) - - data = response.json() - print(data["data"]["output"]) + response.raise_for_status() + result = response.json()["data"] + print(result["status"], result["output"]) ``` - +A successful HTTP request can contain a failed workflow run. Always inspect `data.status` and `data.error`. A client timeout limits how long your application waits; it does not extend the server's execution limit or prove no run started. + -## Sync vs Async Execution - -By default, workflow executions are **synchronous** — the API blocks until the workflow completes and returns the result directly. +## Synchronous and asynchronous execution [#sync-vs-async-execution] -For long-running workflows, use **asynchronous execution** by passing `async: true`: +The default waits for the workflow to settle and returns a run resource. For a long-running deployed workflow, set `async: true` to receive HTTP `202` with a run ID: ```bash -curl -X POST https://www.sim.ai/api/v2/workflows/{workflowId}/execute \ - -H "Content-Type: application/json" \ - -H "X-API-Key: YOUR_API_KEY" \ +curl --fail-with-body -X POST \ + "https://www.sim.ai/api/v2/workflows/$WORKFLOW_ID/execute" \ + -H "X-API-Key: $SIM_API_KEY" \ + -H 'Content-Type: application/json' \ -d '{"input": {}, "async": true}' ``` -Keyed callers can optionally provide `X-Run-Id: my-run-123` to choose the run ID. Run IDs cannot be reused; a duplicate returns `409`. - -This returns immediately with a `runId` and `statusUrl`: - ```json { "data": { @@ -128,20 +116,33 @@ This returns immediately with a `runId` and `statusUrl`: } ``` -Poll the run status endpoint until the status is terminal: +Async requires an API key or OAuth token. It cannot be combined with streaming, manual draft execution, or output-shaping options. An optional integer `executionTimeoutSeconds` from `1` to `604800` can shorten the account's execution policy, but cannot extend it. See the [execution request](/api-reference/workflows/executeWorkflowV2) for compatible options. + +Set `RUN_ID` to the returned ID and poll with a delay: ```bash -curl https://www.sim.ai/api/v2/workflows/{workflowId}/runs/{runId}?includeOutput=true \ - -H "X-API-Key: YOUR_API_KEY" +curl --fail-with-body \ + "https://www.sim.ai/api/v2/workflows/$WORKFLOW_ID/runs/$RUN_ID?includeOutput=true" \ + -H "X-API-Key: $SIM_API_KEY" ``` - - Execution status transitions follow: `queued` → `running` → `completed`, `failed`, `cancelled`, or `paused`. The `data.output` field is populated for completed executions when `includeOutput=true`. - +| Status | Action | +| --- | --- | +| `queued`, `pending`, `running`, `redacting` | Continue polling; `redacting` is a transient output-redaction state | +| `completed` | Read `data.output` when `includeOutput=true` | +| `failed` | Inspect `data.error` | +| `cancelled` | Stop polling | +| `paused` | Inspect pause details and the resume condition; the workflow has not completed | -## Response Format +Runs need not pass through every state. A human pause requires submitted input; a time pause can resume automatically. See [Get workflow run](/api-reference/workflow-runs/getWorkflowRunV2) and the effective [data retention policy](/platform/enterprise/data-retention). -Successful v2 responses wrap the run resource in `data`: +Authenticated callers can send `X-Run-Id` to choose a run ID. It is a one-shot claim: reuse returns `409`, not the original response. After an uncertain enqueue or lost response, reconcile the original run ID before starting another run. A missing record does not by itself prove that no work started. + +For SSE tokens or a synchronous NDJSON response with heartbeats, see [API streaming](/workflows/deployment/api#streaming). + +## Response format + +Single-resource v2 JSON responses wrap the resource in `data`. For example, a synchronous execution returns: ```json { @@ -150,15 +151,22 @@ Successful v2 responses wrap the run resource in `data`: "workflowId": "{workflowId}", "status": "completed", "output": { "result": "Hello, world!" }, + "blockOutputs": null, "error": null, + "startedAt": "2026-10-13T12:00:00.000Z", + "endedAt": "2026-10-13T12:00:00.842Z", "durationMs": 842 } } ``` -## Error Handling +List responses use `data` as an array and include `nextCursor` when applicable. Streams and binary downloads have their own response formats. + +Cost units are endpoint-specific: Logs APIs report USD; Billing and workflow-run resources report credits. Read the field description before combining amounts. -The API uses standard HTTP status codes. v2 errors include a stable code and human-readable message: +## Handle failed requests [#error-handling] + +Rejected v2 requests use HTTP error status codes and a stable code/message envelope: ```json { @@ -169,19 +177,23 @@ The API uses standard HTTP status codes. v2 errors include a stable code and hum } ``` -| Status | Meaning | What to do | +| Status | Meaning | Action | | --- | --- | --- | -| `400` | Invalid request parameters | Check the `details` array for specific field errors | -| `401` | Missing or invalid API key | Verify your `X-API-Key` header | -| `403` | Access denied | Check you have permission for this resource | -| `404` | Resource not found | Verify the ID exists and belongs to your workspace | -| `429` | Rate limit exceeded | Wait for the duration in the `Retry-After` header | +| `400` | Invalid request | Check the published schema and `error.details`, when present | +| `401` | Missing, invalid, or expired credential | Check the API key or OAuth token and its header | +| `402` | Usage limit exceeded | Inspect billing status and account policy | +| `403` | Access denied | Check role, scope, resource access, and permission policies | +| `404` | Resource not found or concealed | Check the ID and selected workspace | +| `409` | State, preview, or run-ID conflict | Follow the endpoint's conflict/reconciliation procedure | +| `429` | Rate or capacity limit | Honor `Retry-After` before retrying an admitted-safe request | + +Other statuses and endpoint-specific recovery are documented in each reference. `error.details` may be a validation-issue array or an object with additional context. An execution that started and failed instead returns a run resource with `status: "failed"`. ### Unrecognized fields are rejected -Every v2 endpoint validates the request against its published schema — path parameters, query string, and body — and answers `400` for any field it does not declare. A misspelled parameter is an error rather than a silent no-op, so `?limt=20` fails instead of quietly returning an unbounded list. +V2 validates path parameters, query strings, and bodies against the published schema. Unknown fields return `400`; for example, `?limt=20` is an error. The rule also applies to endpoints with no query parameters: omit tracking tags, cache busters, and other undeclared fields. -This holds for endpoints that declare no query parameters at all. Do not append tracking tags, cache busters, or other extra parameters to a v2 URL; send only what the endpoint documents. +A validation error can look like: ```json { @@ -195,28 +207,40 @@ This holds for endpoints that declare no query parameters at all. Do not append } ``` - - Use [Get Billing Status](/api-reference/billing/getBillingStatus) to inspect current credit and storage usage. - +## Pagination -## Rate Limits +Paginated list endpoints, including workflows, logs, and audit logs, return an opaque `nextCursor`. Keep the workspace, filters, and sort choices the same when requesting the next page. A missing or `null` cursor means there is no next page. -Rate limits depend on your subscription plan and apply separately to synchronous and asynchronous executions. +This example requires `WORKSPACE_ID`, `SIM_API_KEY`, and `jq`: -When rate limited, the API returns a `429` response with a `Retry-After` header indicating how many seconds to wait before retrying. +```bash +PAGE=$(curl --silent --show-error --fail-with-body --get \ + 'https://www.sim.ai/api/v2/logs' \ + -H "X-API-Key: $SIM_API_KEY" \ + --data-urlencode "workspaceId=$WORKSPACE_ID" \ + --data-urlencode 'limit=20') + +CURSOR=$(printf '%s' "$PAGE" | jq -r '.nextCursor // empty') +if [ -n "$CURSOR" ]; then + curl --fail-with-body --get 'https://www.sim.ai/api/v2/logs' \ + -H "X-API-Key: $SIM_API_KEY" \ + --data-urlencode "workspaceId=$WORKSPACE_ID" \ + --data-urlencode 'limit=20' \ + --data-urlencode "cursor=$CURSOR" +fi +``` -## Pagination +Some endpoints return an unpaginated bounded inventory or a provider-specific partial result. Follow that endpoint's pagination and truncation fields. -List endpoints (workflows, logs, audit logs) use **cursor-based pagination**: +## Rate limits -```bash -# First page -curl "https://www.sim.ai/api/v2/logs?limit=20" \ - -H "X-API-Key: YOUR_API_KEY" +V2 request limits apply to the credential and its user or workspace. Workflow execution also applies separate synchronous/asynchronous execution buckets, quota, and concurrency policy. Plan and deployment configuration determine the effective limits. -# Next page — use the nextCursor from the previous response -curl "https://www.sim.ai/api/v2/logs?limit=20&cursor=abc123" \ - -H "X-API-Key: YOUR_API_KEY" -``` +A rate-limited request returns `429`; `Retry-After` gives seconds to wait. Inspect [Billing status](/api-reference/billing/getBillingStatus) for a workspace's current credits and storage. Async mode does not bypass admission or usage limits. + +## Related docs -The response includes a `nextCursor` field. When `nextCursor` is absent or `null`, you have reached the last page. +- [Authentication](/api-reference/authentication) +- [Python SDK](/api-reference/python) and [TypeScript SDK](/api-reference/typescript) +- [Execute workflow](/api-reference/workflows/executeWorkflowV2) +- [Workflow imports and workspace sync](/api-reference/workflow-sync) diff --git a/apps/docs/content/docs/api-reference/meta.json b/apps/docs/content/docs/api-reference/meta.json index 1d043f0872f..b39dcada178 100644 --- a/apps/docs/content/docs/api-reference/meta.json +++ b/apps/docs/content/docs/api-reference/meta.json @@ -5,10 +5,11 @@ "---Getting Started---", "getting-started", "authentication", - "workflow-sync", "---SDKs---", "python", "typescript", + "---API guides---", + "workflow-sync", "---Endpoints---", "(generated)/workflows", "(generated)/workflow-runs", diff --git a/apps/docs/content/docs/api-reference/python.mdx b/apps/docs/content/docs/api-reference/python.mdx index 39aa0ed719f..632a5089019 100644 --- a/apps/docs/content/docs/api-reference/python.mdx +++ b/apps/docs/content/docs/api-reference/python.mdx @@ -1,768 +1,402 @@ --- title: Python +description: Execute deployed workflows from Python, poll runs, and handle SDK results. --- import { Callout } from 'fumadocs-ui/components/callout' -import { Step, Steps } from 'fumadocs-ui/components/steps' -import { Tab, Tabs } from 'fumadocs-ui/components/tabs' -Use the Python SDK to execute workflows from Python applications. +Use `SimStudioClient` to execute deployed workflows from a Python application. It supports synchronous requests, server-queued asynchronous runs, rate-limit retries, and file-like inputs. Its HTTP methods are blocking; asynchronous execution does not make it an `asyncio` client. - - The Python SDK supports Python 3.8+ with async execution support, retry helpers with exponential backoff, and usage tracking. - - -## Installation +## Install and configure [#installation] -Install the SDK using pip: +The package requires Python `3.8+` and `requests>=2.25.0`: ```bash pip install simstudio-sdk ``` -## Quick Start - -Here's a simple example to get you started: +Create a key in **Account settings → Sim API keys**, or use a workspace key if your administrator requires one. Keep it on your server as `SIM_API_KEY`. Set `WORKFLOW_ID` to a deployed workflow you can access. See [Authentication](/api-reference/authentication) for key types and permissions. -```python -from simstudio import SimStudioClient +### Server compatibility -# Initialize the client -client = SimStudioClient( - api_key="your-api-key-here", - base_url="https://www.sim.ai" # optional, defaults to https://www.sim.ai -) - -# Execute a workflow -try: - result = client.execute_workflow("workflow-id") - print("Workflow executed successfully:", result) -except Exception as error: - print("Workflow execution failed:", error) -``` +SDK `0.2.x` executes and polls through `/api/v2`. Your deployment must serve `POST /api/v2/workflows/{workflowId}/execute`; the SDK does not fall back when that route is unavailable. Upgrade an older self-hosted server, or intentionally retain `simstudio-sdk<0.2` for its legacy execution endpoints. -## API Reference +The default origin is `https://www.sim.ai`. Set `base_url` to your self-hosted deployment's origin. Versions before `0.2.1` defaulted to `https://sim.ai`; set the `www` origin explicitly when using an older SDK against Sim Cloud to avoid redirects. -### SimStudioClient +## Run a workflow [#quick-start] -#### Constructor +Use a context manager to close the HTTP session automatically: ```python -SimStudioClient(api_key: str, base_url: str = "https://www.sim.ai") -``` - -**Parameters:** -- `api_key` (str): Your Sim API key -- `base_url` (str, optional): Base URL for the Sim API (defaults to `https://www.sim.ai`; versions before 0.2.1 default to `https://sim.ai`, which redirects to `https://www.sim.ai`, so set the `www` host explicitly on older versions) - -#### Methods - -##### execute_workflow() - -Execute a workflow with optional input data. +import os +from simstudio import SimStudioClient, SimStudioError -```python -result = client.execute_workflow( - "workflow-id", - input={"message": "Hello, world!"}, - timeout=30.0 # 30 seconds -) +with SimStudioClient( + api_key=os.environ["SIM_API_KEY"], + base_url=os.getenv("SIM_BASE_URL", "https://www.sim.ai"), +) as client: + try: + result = client.execute_workflow_sync( + os.environ["WORKFLOW_ID"], + input={"message": "Process this data"}, + timeout=30.0, + ) + if result.status == "completed": + print(result.output) + print("Duration in ms:", result.total_duration) + elif result.status == "paused": + print("The workflow is waiting to resume.") + else: + print(result.status, result.error) + except SimStudioError as error: + print(error.code, error.status, str(error)) + raise ``` -**Parameters:** -- `workflow_id` (str): The ID of the workflow to execute -- `input` (dict, optional): Input data to pass to the workflow -- `timeout` (float, optional): Timeout in seconds (default: 30.0) -- `stream` (bool, optional): Enable streaming responses (default: False) -- `selected_outputs` (list[str], optional): Block outputs to stream in `blockName.attribute` format (e.g., `["agent1.content"]`) -- `async_execution` (bool, optional): Execute asynchronously (default: False) -- `execution_timeout_seconds` (int, optional): Optional server-side async execution cap from 1 to 604800 seconds. Requires `async_execution=True` and cannot extend the account policy. +Replace `message` with an input field defined by your deployed trigger. The SDK runs the active deployment; it does not select manual draft execution. -**Returns:** `WorkflowExecutionResult | AsyncExecutionResult` +A failed synchronous workflow returns normally with `status="failed"`, `success=False`, and `error` set. A cancelled run also returns `success=False`, often without an error. `success=True` means `completed` **or** `paused`; a pause is unfinished work. HTTP, authentication, and client timeout errors raise `SimStudioError`. This differs from the TypeScript SDK, which throws for a failed synchronous run. -When `async_execution=True`, returns immediately with a `run_id` and `status_url` for polling. Otherwise, waits for completion. +## Start an asynchronous run [#async-workflow-execution] -##### get_workflow_status() - -Get the status of a workflow (deployment status, etc.). +Queue a deployed run and poll its `run_id`. The initial `success=True` confirms acceptance, not completion: ```python -status = client.get_workflow_status("workflow-id") -print("Is deployed:", status.is_deployed) -``` - -**Parameters:** -- `workflow_id` (str): The ID of the workflow +import os +import time +from simstudio import AsyncExecutionResult, SimStudioClient -**Returns:** `WorkflowStatus` +waiting = {"queued", "pending", "running", "redacting"} +workflow_id = os.environ["WORKFLOW_ID"] -##### validate_workflow() +with SimStudioClient(api_key=os.environ["SIM_API_KEY"]) as client: + result = client.execute_workflow( + workflow_id, + input={"message": "Process this dataset"}, + async_execution=True, + execution_timeout_seconds=3600, + ) + if not isinstance(result, AsyncExecutionResult): + raise RuntimeError("Expected an asynchronous run receipt") -Validate that a workflow is ready for execution. + deadline = time.monotonic() + 300 + while True: + run = client.get_workflow_run(workflow_id, result.run_id, include_output=True) + if run["status"] not in waiting: + break + if time.monotonic() >= deadline: + raise TimeoutError(f"Stop waiting locally; run {result.run_id} may still be active") + time.sleep(2) -```python -is_ready = client.validate_workflow("workflow-id") -if is_ready: - # Workflow is deployed and ready - pass + if run["status"] == "completed": + print(run["output"]) + elif run["status"] == "paused": + print("Resume condition:", run["paused"]) + else: + print(run["status"], run["error"]) ``` -**Parameters:** -- `workflow_id` (str): The ID of the workflow - -**Returns:** `bool` - -##### get_workflow_run() +The five-minute polling deadline is an application choice; it does not cancel the run. A time pause can resume automatically, while a human pause requires input. Resume can create another run attempt. Use [Get workflow run](/api-reference/workflow-runs/getWorkflowRunV2) and the [resume endpoint](/api-reference/workflow-runs/resumeWorkflowRunV2) for the current state and resume behavior. -Get the status and optional outputs of a workflow execution. +Async submission cannot include `stream=True`, `selected_outputs`, or other output-shaping options. `execution_timeout_seconds` accepts an integer from `1` to `604800`, requires async execution, and only shortens the account policy. The HTTP `timeout` remains separate. -```python -status = client.get_workflow_run("workflow-id", "run-id", include_output=True) -print("Status:", status["status"]) # 'queued', 'running', 'completed', 'failed' -if status["status"] == "completed": - print("Output:", status["output"]) -``` - -**Parameters:** -- `workflow_id` (str): The workflow ID -- `run_id` (str): The run ID returned from async execution -- `include_output` (bool, optional): Include the final output for completed executions -- `selected_outputs` (list[str], optional): Block output selectors to include +## Handle errors and rate limits [#error-handling] -**Returns:** `Dict[str, Any]` +`SimStudioError(message, code=None, status=None)` exposes `code` and the HTTP `status` when available. A workflow failure returned in `WorkflowExecutionResult` must be handled separately from exceptions. -**Response fields:** -- `runId` (str): The run ID -- `workflowId` (str): The workflow ID -- `status` (str): One of `'queued'`, `'pending'`, `'running'`, `'paused'`, `'completed'`, `'failed'`, `'cancelled'` -- `startedAt` / `endedAt` (str): Execution timestamps -- `durationMs` (int, optional): Duration in milliseconds -- `output` (any, optional): The workflow output when requested for a completed execution -- `blockOutputs` (dict, optional): Requested block outputs -- `error` (dict, optional): Structured failure details with `code`, `message`, and optional `details` +| Code | Meaning | +| --- | --- | +| `UNAUTHORIZED` | Missing, invalid, or expired credential | +| `BAD_REQUEST` | V2 request validation failed | +| `TIMEOUT` | The client stopped waiting | +| `RATE_LIMIT_EXCEEDED` | SDK wrapper for an HTTP `429` | +| `USAGE_LIMIT_EXCEEDED` | Usage policy rejected the request or run | +| `INVALID_EXECUTION_TIMEOUT` | An unsupported or invalid async timeout option | +| `EXECUTION_ERROR` | Transport, parsing, or execution-request failure | +| `STATUS_ERROR`, `USAGE_ERROR` | A status or usage helper failed | -##### get_job_status() +Other server codes can pass through. V2 uses `BAD_REQUEST` for invalid JSON/request input, rather than the legacy `INVALID_JSON` branch. See [API errors](/api-reference/getting-started#error-handling). -Get the status of a job created through the legacy async execution endpoint. New integrations should use `get_workflow_run()` with the run ID instead. +`execute_with_retry` retries only rate-limit exceptions. Its defaults allow three retries after the initial attempt, with exponential delay and ±25% jitter. A supplied `Retry-After` takes precedence over the calculated delay; jitter applies to that wait too. ```python -status = client.get_job_status("legacy-job-id") -``` - -##### execute_with_retry() - -Execute a workflow with automatic retry on rate limit errors using exponential backoff. +import os +from simstudio import SimStudioClient -```python -result = client.execute_with_retry( - "workflow-id", - input={"message": "Hello"}, - timeout=30.0, - max_retries=3, # Maximum number of retries - initial_delay=1.0, # Initial delay in seconds - max_delay=30.0, # Maximum delay in seconds - backoff_multiplier=2.0 # Exponential backoff multiplier -) +with SimStudioClient(api_key=os.environ["SIM_API_KEY"]) as client: + result = client.execute_with_retry( + os.environ["WORKFLOW_ID"], + input={"message": "Process this"}, + timeout=30.0, + max_retries=3, + initial_delay=1.0, + max_delay=30.0, + backoff_multiplier=2.0, + ) + print(result) ``` -**Parameters:** -- `workflow_id` (str): The ID of the workflow to execute -- `input` (dict, optional): Input data to pass to the workflow -- `timeout` (float, optional): Timeout in seconds -- `stream` (bool, optional): Enable streaming responses -- `selected_outputs` (list, optional): Block outputs to stream -- `async_execution` (bool, optional): Execute asynchronously -- `max_retries` (int, optional): Maximum number of retries (default: 3) -- `initial_delay` (float, optional): Initial delay in seconds (default: 1.0) -- `max_delay` (float, optional): Maximum delay in seconds (default: 30.0) -- `backoff_multiplier` (float, optional): Backoff multiplier (default: 2.0) +`initial_delay` and `max_delay` are **seconds**. `RateLimitInfo.retry_after` is **milliseconds**. `max_delay` caps the calculated backoff, not a server-supplied wait. -**Returns:** `WorkflowExecutionResult | AsyncExecutionResult` - -The retry logic uses exponential backoff (1s → 2s → 4s → 8s...) with ±25% jitter to prevent thundering herd. If the API provides a `retry-after` header, it will be used instead. + +A client timeout or lost response does not prove the workflow never started. Avoid blindly repeating an execution that may have effects. For caller-chosen run IDs and reconciliation, use the raw v2 API described in [Getting started](/api-reference/getting-started#sync-vs-async-execution). + -##### get_rate_limit_info() +## Method reference [#api-reference] -Get the current rate limit information from the last API response. +### Constructor -```python -rate_limit_info = client.get_rate_limit_info() -if rate_limit_info: - print("Limit:", rate_limit_info.limit) - print("Remaining:", rate_limit_info.remaining) - print("Reset:", datetime.fromtimestamp(rate_limit_info.reset)) +```text +SimStudioClient(api_key: str, base_url: str = "https://www.sim.ai") ``` -**Returns:** `RateLimitInfo | None` +`api_key` is required. `base_url` is an origin, without an `/api` suffix; trailing slashes are removed. The client sends the key in `X-API-Key`. -##### get_usage_limits() +### Execute -Get current usage limits and quota information for your account. +```text +execute_workflow(workflow_id: str, input=None, *, timeout=30.0, + stream=None, selected_outputs=None, async_execution=None, + execution_timeout_seconds=None) -> WorkflowExecutionResult | AsyncExecutionResult -```python -limits = client.get_usage_limits() -print("Sync requests remaining:", limits.rate_limit["sync"]["remaining"]) -print("Async requests remaining:", limits.rate_limit["async"]["remaining"]) -print("Current period cost:", limits.usage["currentPeriodCost"]) -print("Plan:", limits.usage["plan"]) +execute_workflow_sync(workflow_id: str, input=None, *, timeout=30.0, + stream=None, selected_outputs=None) -> WorkflowExecutionResult + +execute_with_retry(workflow_id: str, input=None, *, timeout=30.0, + stream=None, selected_outputs=None, async_execution=None, + execution_timeout_seconds=None, max_retries=3, initial_delay=1.0, + max_delay=30.0, backoff_multiplier=2.0) + -> WorkflowExecutionResult | AsyncExecutionResult ``` -**Returns:** `UsageLimits` +All options after `*` are keyword-only. `execute_workflow_sync` forces `async_execution=False`; the retry method accepts the same execution options as `execute_workflow`. -**Response structure:** -```python -{ - "success": bool, - "rateLimit": { - "sync": { - "isLimited": bool, - "limit": int, - "remaining": int, - "resetAt": str - }, - "async": { - "isLimited": bool, - "limit": int, - "remaining": int, - "resetAt": str - }, - "authType": str # 'api' or 'manual' - }, - "usage": { - "currentPeriodCost": float, - "limit": float, - "plan": str # e.g., 'free', 'pro' - } -} -``` +| Parameter | Behavior and default | +| --- | --- | +| `workflow_id` | Deployed workflow ID | +| `input` | Optional value; a dictionary becomes the v2 `input` object, while a primitive or list becomes `{"input": value}` inside it; omitted/`None` becomes `{}` | +| `timeout` | Client HTTP timeout in seconds; default `30.0` | +| `async_execution` | Default omitted, so server execution is synchronous; `True` returns an async receipt | +| `execution_timeout_seconds` | Async-only integer cap, `1`–`604800`; cannot extend account policy | +| `selected_outputs` | Optional list of normalized block-name/path selectors such as `agent.content`; incompatible with async submission | +| `stream` | Defaults omitted/false; the current SDK parser cannot consume the SSE response when `True`; use raw HTTP below | +| `max_retries` | Retry count after the initial attempt; default `3` | +| `initial_delay`, `max_delay` | Calculated retry delay in seconds; defaults `1.0`, `30.0` | +| `backoff_multiplier` | Delay multiplier; default `2.0` | -##### set_api_key() +File-like objects nested in input are converted to base64. The current synchronous adapter does not expose v2 `blockOutputs`, even when `selected_outputs` is sent. Use a run read or raw HTTP when you need that map. -Update the API key. +### Read workflow deployment and runs -```python -client.set_api_key("new-api-key") +```text +get_workflow_status(workflow_id: str) -> WorkflowStatus +validate_workflow(workflow_id: str) -> bool +get_workflow_run(workflow_id: str, run_id: str, *, + include_output=None, selected_outputs=None) -> Dict[str, Any] +get_job_status(job_id: str) -> Dict[str, Any] ``` -##### set_base_url() - -Update the base URL. +`get_workflow_status` reads the legacy `/api/workflows/{id}/status` route. `validate_workflow` returns only its `is_deployed` flag; it returns `False` if the status request raises `SimStudioError`. It does not validate credentials, input, quota, or deployment readiness. Use the status method directly to distinguish a failed lookup from an undeployed workflow: ```python -client.set_base_url("https://my-custom-domain.com") +status = client.get_workflow_status("workflow-id") +print(status.is_deployed, status.needs_redeployment) ``` -##### close() +`get_workflow_run` reads and unwraps the v2 run resource. `include_output=True` includes final output for a completed run; default omitted/false. Run-read `selected_outputs` uses **block IDs**, as `blockId` or `blockId.path`, rather than block names. Selected block outputs are independent of `include_output`. -Close the underlying HTTP session. +`get_job_status` is for IDs created by legacy `0.1.x` async execution at `/api/jobs/{jobId}`. Use `get_workflow_run` for runs started by `0.2.x`. -```python -client.close() +### Read limits and update the client + +```text +get_rate_limit_info() -> RateLimitInfo | None +get_usage_limits() -> UsageLimits +set_api_key(api_key: str) -> None +set_base_url(base_url: str) -> None +close() -> None ``` -## Data Classes +`get_rate_limit_info` reads cached headers from the most recent response that supplied rate information. It does not make a request. `get_usage_limits` calls the legacy account helper; see its shape below. Setters change subsequent requests. `close` closes the HTTP session; a context manager calls it automatically. + +## Return objects [#data-classes] ### WorkflowExecutionResult -```python -@dataclass -class WorkflowExecutionResult: - success: bool - output: Optional[Any] = None - error: Optional[str] = None - logs: Optional[List[Any]] = None - metadata: Optional[Dict[str, Any]] = None - trace_spans: Optional[List[Any]] = None - total_duration: Optional[float] = None - status: Optional[str] = None -``` +| Field | Python type/default | Current behavior | +| --- | --- | --- | +| `success` | `bool`, required | `True` only for completed or paused | +| `status` | `Optional[str] = None` | Server status: completed, failed, paused, or cancelled | +| `output` | `Optional[Any] = None` | Workflow output, including any returned partial result | +| `error` | `Optional[str] = None` | Failure message, when present | +| `metadata` | `Optional[Dict[str, Any]] = None` | SDK-built `duration`, `runId`, `startTime`, `endTime`; duration is milliseconds | +| `total_duration` | `Optional[float] = None` | Duration in milliseconds | +| `logs`, `trace_spans` | `Optional[list] = None` | Compatibility fields; not populated by the v2 adapter | -`success` is `True` only for the `completed` and `paused` statuses. `status` carries the server's terminal status verbatim, so a cancelled run (`success=False`, `error=None`) is distinguishable from a failed one. +Nested oversized values may be `LargeValueRef` objects with `__simLargeValueRef`, `version`, `id`, `kind`, `size`, optional `key`, `executionId`, and `preview`. Their keys are opaque server pointers, not download URLs. See [large outputs](/workflows/deployment/api#oversized-outputs). ### AsyncExecutionResult -```python -@dataclass -class AsyncExecutionResult: - success: bool - run_id: str - status_url: str - message: str = "" - async_execution: bool = True -``` +| Field | Python type/default | +| --- | --- | +| `success` | `bool`, required; current accepted receipts set `True` | +| `run_id` | `str`, required | +| `status_url` | `str`, required | +| `message` | `str = ""`; current adapter sets `"Workflow execution queued"` | +| `async_execution` | `bool = True` | ### WorkflowStatus -```python -@dataclass -class WorkflowStatus: - is_deployed: bool - deployed_at: Optional[str] = None - needs_redeployment: bool = False -``` +| Field | Python type/default | +| --- | --- | +| `is_deployed` | `bool`, required | +| `deployed_at` | `Optional[str] = None` | +| `needs_redeployment` | `bool = False` | -### RateLimitInfo - -```python -@dataclass -class RateLimitInfo: - limit: int - remaining: int - reset: int - retry_after: Optional[int] = None -``` +### Run dictionary -### UsageLimits +`get_workflow_run` returns the server's `data` dictionary without changing camelCase keys: -```python -@dataclass -class UsageLimits: - success: bool - rate_limit: Dict[str, Any] - usage: Dict[str, Any] -``` +| Field | Shape | +| --- | --- | +| `runId`, `workflowId` | String identifiers | +| `status` | `queued`, `pending`, `running`, `redacting`, `paused`, `completed`, `failed`, or `cancelled` | +| `trigger` | String or `None` | +| `startedAt`, `endedAt` | ISO timestamps or `None`; queued runs report enqueue time as startedAt | +| `durationMs` | Number or `None` | +| `paused` | Pause details or `None`; use `pauseKind` and `resumeAt` to identify the resume condition | +| `cost` | `{"total": number}` in credits, or `None` when unavailable/withheld | +| `error` | Structured `code`/`message` failure, or `None` | +| `output` | Final output when requested for a completed run, otherwise `None` | +| `blockOutputs` | Selected block-ID/path outputs, or `None` | +| `files` | Produced-file metadata when output is requested/available, otherwise `None` | -### SimStudioError +Each file includes `id`, `name`, byte `size`, MIME `type`, `downloadPath`, and nullable `base64`. The SDK does not expose file-inlining options; download at the returned path with an authenticated raw HTTP request. Permission policies can withhold cost or recorded output fields. See [Get workflow run](/api-reference/workflow-runs/getWorkflowRunV2) for the full contract, functional-output permission conflict, and file limits. -```python -class SimStudioError(Exception): - def __init__(self, message: str, code: Optional[str] = None, status: Optional[int] = None): - super().__init__(message) - self.code = code - self.status = status -``` +### RateLimitInfo -**Common error codes:** -- `UNAUTHORIZED`: Invalid API key -- `TIMEOUT`: Request timed out -- `RATE_LIMIT_EXCEEDED`: Rate limit exceeded -- `USAGE_LIMIT_EXCEEDED`: Usage limit exceeded -- `EXECUTION_ERROR`: Workflow execution failed - -## Examples - -### Basic Workflow Execution - - - - Set up the SimStudioClient with your API key. - - - Check if the workflow is deployed and ready for execution. - - - Run the workflow with your input data. - - - Process the execution result and handle any errors. - - +Fields are `limit: int`, `remaining: int`, `reset: int`, and `retry_after: Optional[int] = None`. V2 ISO reset headers become epoch **milliseconds**. Integer reset headers from older endpoints retain their original epoch-seconds value. For a v2 response: ```python -import os -from simstudio import SimStudioClient - -client = SimStudioClient(api_key=os.getenv("SIM_API_KEY")) - -def run_workflow(): - try: - # Check if workflow is ready - is_ready = client.validate_workflow("my-workflow-id") - if not is_ready: - raise Exception("Workflow is not deployed or ready") - - # Execute the workflow - result = client.execute_workflow( - "my-workflow-id", - input={ - "message": "Process this data", - "user_id": "12345" - } - ) - - if result.success: - print("Output:", result.output) - print("Duration:", result.metadata.get("duration") if result.metadata else None) - else: - print("Workflow failed:", result.error) - - except Exception as error: - print("Error:", error) +from datetime import datetime, timezone -run_workflow() +rate = client.get_rate_limit_info() +if rate: + print(rate.remaining) + print(datetime.fromtimestamp(rate.reset / 1000, tz=timezone.utc)) ``` -### Error Handling +Use a known response surface when converting `reset`; use `resetAt` ISO strings from the usage helper when you need a format that is unambiguous across endpoints. -Handle different types of errors that may occur during workflow execution: - -```python -from simstudio import SimStudioClient, SimStudioError -import os +### UsageLimits -client = SimStudioClient(api_key=os.getenv("SIM_API_KEY")) +The dataclass contains `success: bool`, `rate_limit: Dict[str, Any]`, and `usage: Dict[str, Any]`: -def execute_with_error_handling(): - try: - result = client.execute_workflow("workflow-id") - return result - except SimStudioError as error: - if error.code == "UNAUTHORIZED": - print("Invalid API key") - elif error.code == "TIMEOUT": - print("Workflow execution timed out") - elif error.code == "USAGE_LIMIT_EXCEEDED": - print("Usage limit exceeded") - elif error.code == "INVALID_JSON": - print("Invalid JSON in request body") - else: - print(f"Workflow error: {error}") - raise - except Exception as error: - print(f"Unexpected error: {error}") - raise +```text +rate_limit: + sync / async: + isLimited: bool + requestsPerMinute: number + maxBurst: number + remaining: number + resetAt: ISO timestamp + authType: "api" or "manual" +usage: + currentPeriodCost: number (USD) + limit: number (USD) + plan: str ``` -### Context Manager Usage - -Use the client as a context manager to automatically handle resource cleanup: +`requestsPerMinute` is the refill rate; `maxBurst` is the bucket capacity. There is no `rate_limit["sync"]["limit"]` field. The Python dataclass does not expose the legacy route's `storage` result. ```python -from simstudio import SimStudioClient -import os - -# Using context manager to automatically close the session -with SimStudioClient(api_key=os.getenv("SIM_API_KEY")) as client: - result = client.execute_workflow("workflow-id") - print("Result:", result) -# Session is automatically closed here +limits = client.get_usage_limits() +print("Sync remaining:", limits.rate_limit["sync"]["remaining"]) +print("Resets at:", limits.rate_limit["sync"]["resetAt"]) +print("Period cost in USD:", limits.usage["currentPeriodCost"]) ``` -### Batch Workflow Execution - -Execute multiple workflows efficiently: - -```python -from simstudio import SimStudioClient -import os - -client = SimStudioClient(api_key=os.getenv("SIM_API_KEY")) - -def execute_workflows_batch(workflow_data_pairs): - """Execute multiple workflows with different input data.""" - results = [] - - for workflow_id, input_data in workflow_data_pairs: - try: - # Validate workflow before execution - if not client.validate_workflow(workflow_id): - print(f"Skipping {workflow_id}: not deployed") - continue - - result = client.execute_workflow(workflow_id, input_data) - results.append({ - "workflow_id": workflow_id, - "success": result.success, - "output": result.output, - "error": result.error - }) - - except Exception as error: - results.append({ - "workflow_id": workflow_id, - "success": False, - "error": str(error) - }) - - return results - -# Example usage -workflows = [ - ("workflow-1", {"type": "analysis", "data": "sample1"}), - ("workflow-2", {"type": "processing", "data": "sample2"}), -] - -results = execute_workflows_batch(workflows) -for result in results: - print(f"Workflow {result['workflow_id']}: {'Success' if result['success'] else 'Failed'}") -``` +This helper resolves account/key-owner usage and can differ from the payer for a selected workspace. For workspace credit and storage state, use [Get billing status](/api-reference/billing/getBillingStatus). Logs APIs also report USD; v2 Billing and run-resource amounts use credits. -### Async Workflow Execution +## File inputs -Execute workflows asynchronously for long-running tasks: +Include a binary file-like object under the input field your deployed trigger expects: ```python import os -import time from simstudio import SimStudioClient -client = SimStudioClient(api_key=os.getenv("SIM_API_KEY")) - -def execute_async(): - try: - # Start async execution - result = client.execute_workflow( - "workflow-id", - input={"data": "large dataset"}, - async_execution=True # Execute asynchronously +with SimStudioClient(api_key=os.environ["SIM_API_KEY"]) as client: + with open("document.pdf", "rb") as document: + result = client.execute_workflow_sync( + os.environ["WORKFLOW_ID"], + input={"documents": [document], "query": "Summarize this document"}, ) - - # Check if result is an async execution - if hasattr(result, 'async_execution') and result.async_execution: - print(f"Run ID: {result.run_id}") - print(f"Status endpoint: {result.status_url}") - - # Poll for completion - status = client.get_workflow_run( - "workflow-id", result.run_id, include_output=True - ) - - while status["status"] in ["queued", "pending", "running"]: - print(f"Current status: {status['status']}") - time.sleep(2) # Wait 2 seconds - status = client.get_workflow_run( - "workflow-id", result.run_id, include_output=True - ) - - if status["status"] == "completed": - print("Workflow completed!") - print(f"Output: {status['output']}") - print(f"Duration: {status['durationMs']}") - elif status["status"] == "paused": - print("Workflow is paused and waiting for input or resumption.") - elif status["status"] == "cancelled": - print("Workflow was cancelled.") - else: - print(f"Workflow failed: {status['error']}") - - except Exception as error: - print(f"Error: {error}") - -execute_async() + print(result.output) ``` -### Rate Limiting and Retry - -Handle rate limits automatically with exponential backoff: +The SDK reads and base64-encodes the bytes, retaining the file name and using its `content_type` attribute when available. Otherwise MIME type defaults to `application/octet-stream`. Validate upload size and content on your backend; the execute request has a 10 MiB JSON-body limit, including base64 overhead. -```python -import os -from simstudio import SimStudioClient, SimStudioError +## Execute several workflows [#batch-workflow-execution] -client = SimStudioClient(api_key=os.getenv("SIM_API_KEY")) +The client has no batch-execution method. A sequential loop makes one request per workflow and handles each result independently: -def execute_with_retry_handling(): +```python +for workflow_id, workflow_input in [ + ("workflow-1", {"message": "Analyze this"}), + ("workflow-2", {"message": "Summarize this"}), +]: try: - # Automatically retries on rate limit - result = client.execute_with_retry( - "workflow-id", - input={"message": "Process this"}, - max_retries=5, - initial_delay=1.0, - max_delay=60.0, - backoff_multiplier=2.0 - ) - - print(f"Success: {result}") + result = client.execute_workflow_sync(workflow_id, workflow_input) + print(workflow_id, result.status, result.output, result.error) except SimStudioError as error: - if error.code == "RATE_LIMIT_EXCEEDED": - print("Rate limit exceeded after all retries") - - # Check rate limit info - rate_limit_info = client.get_rate_limit_info() - if rate_limit_info: - from datetime import datetime - reset_time = datetime.fromtimestamp(rate_limit_info.reset) - print(f"Rate limit resets at: {reset_time}") - -execute_with_retry_handling() + print(workflow_id, error.code, str(error)) ``` -### Usage Monitoring +Use this inside the configured client context. A deployment-status precheck is optional and cannot guarantee the later run will succeed. -Monitor your account usage and limits: +## Stream through HTTP [#streaming-workflow-execution] -```python -import os -from simstudio import SimStudioClient - -client = SimStudioClient(api_key=os.getenv("SIM_API_KEY")) - -def check_usage(): - try: - limits = client.get_usage_limits() - - print("=== Rate Limits ===") - print("Sync requests:") - print(f" Limit: {limits.rate_limit['sync']['limit']}") - print(f" Remaining: {limits.rate_limit['sync']['remaining']}") - print(f" Resets at: {limits.rate_limit['sync']['resetAt']}") - print(f" Is limited: {limits.rate_limit['sync']['isLimited']}") - - print("\nAsync requests:") - print(f" Limit: {limits.rate_limit['async']['limit']}") - print(f" Remaining: {limits.rate_limit['async']['remaining']}") - print(f" Resets at: {limits.rate_limit['async']['resetAt']}") - print(f" Is limited: {limits.rate_limit['async']['isLimited']}") - - print("\n=== Usage ===") - print(f"Current period cost: ${limits.usage['currentPeriodCost']:.2f}") - print(f"Limit: ${limits.usage['limit']:.2f}") - print(f"Plan: {limits.usage['plan']}") - - percent_used = (limits.usage['currentPeriodCost'] / limits.usage['limit']) * 100 - print(f"Usage: {percent_used:.1f}%") - - if percent_used > 80: - print("⚠️ Warning: You are approaching your usage limit!") - - except Exception as error: - print(f"Error checking usage: {error}") - -check_usage() -``` - -### Streaming Workflow Execution - -Execute workflows with real-time streaming responses: +The current `0.2.x` SDK sends `stream=True` but then parses the response as JSON. It does not expose an SSE iterator; a valid SSE response fails that parser. Use raw HTTP for streaming: ```python -from simstudio import SimStudioClient import os - -client = SimStudioClient(api_key=os.getenv("SIM_API_KEY")) - -def execute_with_streaming(): - """Execute workflow with streaming enabled.""" - try: - # Enable streaming for specific block outputs - result = client.execute_workflow( - "workflow-id", - input={"message": "Count to five"}, - stream=True, - selected_outputs=["agent1.content"] # Use blockName.attribute format - ) - - print("Workflow result:", result) - except Exception as error: - print("Error:", error) - -execute_with_streaming() -``` - -The streaming response follows the Server-Sent Events (SSE) format: - -``` -data: {"blockId":"7b7735b9-19e5-4bd6-818b-46aae2596e9f","chunk":"One"} - -data: {"blockId":"7b7735b9-19e5-4bd6-818b-46aae2596e9f","chunk":", two"} - -data: {"event":"done","success":true,"output":{},"metadata":{"duration":610}} - -data: [DONE] -``` - -**Flask Streaming Example:** - -```python -from flask import Flask, Response, stream_with_context import requests -import json -import os -app = Flask(__name__) - -@app.route('/stream-workflow') -def stream_workflow(): - """Stream workflow execution to the client.""" - - def generate(): - response = requests.post( - 'https://www.sim.ai/api/v2/workflows/WORKFLOW_ID/execute', - headers={ - 'Content-Type': 'application/json', - 'X-API-Key': os.getenv('SIM_API_KEY') - }, - json={ - 'input': {'message': 'Generate a story'}, - 'stream': True, - 'selectedOutputs': ['agent1.content'] - }, - stream=True - ) - - for line in response.iter_lines(): - if line: - decoded_line = line.decode('utf-8') - if decoded_line.startswith('data: '): - data = decoded_line[6:] # Remove 'data: ' prefix - - if data == '[DONE]': - break - - try: - parsed = json.loads(data) - if 'chunk' in parsed: - yield f"data: {json.dumps(parsed)}\n\n" - elif parsed.get('event') == 'done': - yield f"data: {json.dumps(parsed)}\n\n" - print("Execution complete:", parsed.get('metadata')) - except json.JSONDecodeError: - pass - - return Response( - stream_with_context(generate()), - mimetype='text/event-stream' - ) - -if __name__ == '__main__': - app.run(debug=True) +workflow_id = os.environ["WORKFLOW_ID"] +with requests.post( + f"https://www.sim.ai/api/v2/workflows/{workflow_id}/execute", + headers={ + "X-API-Key": os.environ["SIM_API_KEY"], + "X-Sim-Stream-Protocol": "agent-events-v1", + }, + json={"input": {"message": "Count to five"}, "stream": True, + "selectedOutputs": ["agent.content"]}, + stream=True, + timeout=(10, 300), +) as response: + response.raise_for_status() + for line in response.iter_lines(): + if line: + print(line.decode("utf-8")) ``` -### Environment Configuration +This prints raw SSE. Applications must parse complete events: success ends with `{event:"final",data:...}`, failure ends with `{event:"error",...}`, then `[DONE]`. Preserve structured output and reset events; do not filter only for `chunk` or the obsolete `done` event. The protocol header enables live answer tokens and requires handling `chunk_reset`; reasoning/tool events require their separate flags. -Configure the client using environment variables: - - - - ```python - import os - from simstudio import SimStudioClient - - # Development configuration - client = SimStudioClient( - api_key=os.getenv("SIM_API_KEY"), - base_url=os.getenv("SIM_BASE_URL", "https://www.sim.ai") - ) - ``` - - - ```python - import os - from simstudio import SimStudioClient - - # Production configuration with error handling - api_key = os.getenv("SIM_API_KEY") - if not api_key: - raise ValueError("SIM_API_KEY environment variable is required") - - client = SimStudioClient( - api_key=api_key, - base_url=os.getenv("SIM_BASE_URL", "https://www.sim.ai") - ) - ``` - - +For Flask or another web backend, authenticate the caller and authorize the workflow before opening the upstream request. Forward all SSE bytes with `text/event-stream`, check upstream HTTP status before starting the downstream response, and close the upstream response if the caller disconnects. See [API streaming](/workflows/deployment/api#streaming) and the [reference client](/workflows/deployment/agent-events#reference-client) for framing and event handling. -## Getting Your API Key +## Upgrade from 0.1.x -Create a key in **Account settings → Sim API keys**, or use a workspace key if your administrator requires one. See [Authentication](/api-reference/authentication) for key types and permissions. Deploy the workflow before calling it through the SDK. Keep the key in a server-side environment variable. +`0.2.0` changed execution requests to `/api/v2`, nests named input under `input`, and sends async/timeout options in the body instead of `X-Execution-Mode` and `X-Execution-Timeout-Seconds` headers. -## Requirements +Replace `AsyncExecutionResult.job_id` with `run_id`; its old `execution_id` field is removed. Poll with `get_workflow_run(workflow_id, run_id)`, not `get_job_status`. Synchronous metadata is now SDK-built: use `metadata["runId"]` instead of the former `metadata["executionId"]`. Read `status` to distinguish failed and cancelled returns. Logs and trace spans are no longer populated by this adapter. -- Python 3.8+ -- requests >= 2.25.0 +Workflow status, legacy jobs, and account usage helpers still use their original routes. This SDK does not expose every v2 operation, manual execution, resume/cancel, caller-selected run headers, or NDJSON/agent-event streaming controls. -## License +## Related docs -Apache-2.0 +- [API authentication](/api-reference/authentication) +- [TypeScript SDK](/api-reference/typescript) +- [API getting started](/api-reference/getting-started) +- [Get workflow run](/api-reference/workflow-runs/getWorkflowRunV2) +- [Python package source and Apache-2.0 license](https://github.com/simstudioai/sim/tree/main/packages/python-sdk) diff --git a/apps/docs/content/docs/api-reference/typescript.mdx b/apps/docs/content/docs/api-reference/typescript.mdx index 9d4e9310bd3..9c23a8071ba 100644 --- a/apps/docs/content/docs/api-reference/typescript.mdx +++ b/apps/docs/content/docs/api-reference/typescript.mdx @@ -1,817 +1,428 @@ --- title: TypeScript +description: Execute deployed workflows from a server, poll runs, and handle SDK results. --- import { Callout } from 'fumadocs-ui/components/callout' -import { Step, Steps } from 'fumadocs-ui/components/steps' -import { Tab, Tabs } from 'fumadocs-ui/components/tabs' -Use the TypeScript SDK to execute workflows from server-side JavaScript or TypeScript. For browser applications, call the SDK through your authenticated backend. +Use `SimStudioClient` from server-side JavaScript or TypeScript to execute deployed workflows. It includes TypeScript declarations, server-queued async execution, rate-limit retries, and file-input conversion. Browser applications should call an authenticated backend that keeps the Sim key private. - - The TypeScript SDK provides full type safety, async execution support, retry helpers with exponential backoff, and usage tracking. - +## Install and configure [#installation] + +The ESM package requires Node.js `18+`: -## Installation +```bash +bun add simstudio-ts-sdk +``` -Install the SDK using your preferred package manager: +Create a key in **Account settings → Sim API keys**, or use a workspace key if your administrator requires one. Set `SIM_API_KEY` and `WORKFLOW_ID` in your server environment. Deploy the workflow you intend to call; SDK execution uses the active deployment. See [Authentication](/api-reference/authentication) for key types and permissions. - - - ```bash - npm install simstudio-ts-sdk - ``` - - - ```bash - yarn add simstudio-ts-sdk - ``` - - - ```bash - bun add simstudio-ts-sdk - ``` - - +### Server compatibility -## Quick Start +SDK `0.2.x` executes and polls through `/api/v2`. Your deployment must serve `POST /api/v2/workflows/{workflowId}/execute`; the client does not fall back when that route is absent. Upgrade an older self-hosted server, or intentionally retain a `0.1.x` SDK for legacy execution. -Here's a simple example to get you started: +The default `baseUrl` is `https://www.sim.ai`. Set it to your self-hosted deployment's origin. Versions before `0.2.1` defaulted to `https://sim.ai`; set the `www` origin explicitly when using an older SDK against Sim Cloud to avoid redirects. + +## Run a workflow [#quick-start] ```typescript -import { SimStudioClient } from 'simstudio-ts-sdk'; +import { SimStudioClient, SimStudioError } from 'simstudio-ts-sdk' + +const apiKey = process.env.SIM_API_KEY +const workflowId = process.env.WORKFLOW_ID +if (!apiKey || !workflowId) throw new Error('Set SIM_API_KEY and WORKFLOW_ID') -// Initialize the client const client = new SimStudioClient({ - apiKey: 'your-api-key-here', - baseUrl: 'https://www.sim.ai' // optional, defaults to https://www.sim.ai -}); + apiKey, + baseUrl: process.env.SIM_BASE_URL || 'https://www.sim.ai', +}) -// Execute a workflow try { - const result = await client.executeWorkflow('workflow-id'); - console.log('Workflow executed successfully:', result); + const result = await client.executeWorkflowSync(workflowId, { message: 'Process this data' }) + const runId = result.metadata?.runId + if (!result.success) { + process.stdout.write('The workflow was cancelled.\n') + } else if (runId) { + const run = await client.getWorkflowRun(workflowId, runId, { includeOutput: true }) + process.stdout.write(JSON.stringify({ status: run.status, output: run.output, paused: run.paused })) + } } catch (error) { - console.error('Workflow execution failed:', error); + if (error instanceof SimStudioError) { + process.stderr.write(`${error.code}: ${error.message}\n`) + } + throw error } ``` -## API Reference +Replace `message` with a field your deployed trigger accepts. A failed synchronous run rejects with `SimStudioError`, carrying the run's error code/message. A resolved `success:false` means cancellation. `success:true` means completed **or paused**, so it does not guarantee the workflow finished. The synchronous SDK result has no `status` field; use its `metadata.runId` with `getWorkflowRun` for the exact state. -### SimStudioClient +The Python SDK instead returns a failed synchronous result normally. Both SDKs throw for rejected HTTP requests and client/transport errors. -#### Constructor +## Start an asynchronous run [#async-workflow-execution] -```typescript -new SimStudioClient(config: SimStudioConfig) -``` - -**Configuration:** -- `config.apiKey` (string): Your Sim API key -- `config.baseUrl` (string, optional): Base URL for the Sim API (defaults to `https://www.sim.ai`; versions before 0.2.1 default to `https://sim.ai`, which redirects to `https://www.sim.ai`, so set the `www` host explicitly on older versions) - -#### Methods - -##### executeWorkflow() - -Execute a workflow with optional input data. +The receipt's `success:true` confirms acceptance, not completion. Poll the returned run ID: ```typescript -const result = await client.executeWorkflow('workflow-id', { message: 'Hello, world!' }, { - timeout: 30000 // 30 seconds -}); -``` - -**Parameters:** -- `workflowId` (string): The ID of the workflow to execute -- `input` (any, optional): Input data to pass to the workflow -- `options` (ExecutionOptions, optional): - - `timeout` (number): Timeout in milliseconds (default: 30000) - - `stream` (boolean): Enable streaming responses (default: false) - - `selectedOutputs` (string[]): Block outputs to stream in `blockName.attribute` format (e.g., `["agent1.content"]`) - - `async` (boolean): Execute asynchronously (default: false) - - `executionTimeoutSeconds` (number): Optional server-side async execution cap from 1 to 604800 seconds. Requires `async: true` and cannot extend the account policy. - -**Returns:** `Promise` - -When `async: true`, returns immediately with a `runId` and `statusUrl` for polling. Otherwise, waits for completion. - -##### getWorkflowStatus() - -Get the status of a workflow (deployment status, etc.). - -```typescript -const status = await client.getWorkflowStatus('workflow-id'); -console.log('Is deployed:', status.isDeployed); +import { setTimeout as delay } from 'node:timers/promises' +import { SimStudioClient } from 'simstudio-ts-sdk' + +const apiKey = process.env.SIM_API_KEY +const workflowId = process.env.WORKFLOW_ID +if (!apiKey || !workflowId) throw new Error('Set SIM_API_KEY and WORKFLOW_ID') +const client = new SimStudioClient({ apiKey }) +const waiting = new Set(['queued', 'pending', 'running', 'redacting']) + +const receipt = await client.executeWorkflow(workflowId, { message: 'Process this dataset' }, { + async: true, + executionTimeoutSeconds: 3600, +}) +if (!('async' in receipt) || !receipt.async) throw new Error('Expected an async run receipt') + +const deadline = Date.now() + 300_000 +let run = await client.getWorkflowRun(workflowId, receipt.runId, { includeOutput: true }) +while (waiting.has(run.status)) { + if (Date.now() >= deadline) { + throw new Error(`Stop waiting locally; run ${receipt.runId} may still be active`) + } + await delay(2000) + run = await client.getWorkflowRun(workflowId, receipt.runId, { includeOutput: true }) +} +process.stdout.write(JSON.stringify({ status: run.status, output: run.output, error: run.error, paused: run.paused })) ``` -**Parameters:** -- `workflowId` (string): The ID of the workflow - -**Returns:** `Promise` +The five-minute polling deadline is an application choice and does not cancel the run. Handle `completed`, `failed`, and `cancelled` separately. Inspect a `paused` run's resume condition: time pauses can resume automatically; human pauses require input. Resume can create another attempt. See [Get workflow run](/api-reference/workflow-runs/getWorkflowRunV2) and [Resume workflow run](/api-reference/workflow-runs/resumeWorkflowRunV2). -##### validateWorkflow() +Async submission rejects `stream:true`, `selectedOutputs`, and other output-shaping options. `executionTimeoutSeconds` accepts an integer from `1` to `604800` and requires `async:true`. The effective cap is the smaller of this value and the account policy. Client `timeout` is separate and uses milliseconds. -Validate that a workflow is ready for execution. +## Handle errors and retries [#error-handling] -```typescript -const isReady = await client.validateWorkflow('workflow-id'); -if (isReady) { - // Workflow is deployed and ready -} -``` - -**Parameters:** -- `workflowId` (string): The ID of the workflow +`new SimStudioError(message: string, code?: string, status?: number)` exposes a message, code, and HTTP status when available. An in-band failed run can throw without an HTTP error status. -**Returns:** `Promise` +| Code | Meaning | +| --- | --- | +| `UNAUTHORIZED` | Missing, invalid, or expired credential | +| `BAD_REQUEST` | V2 request validation failed | +| `TIMEOUT` | The client stopped waiting | +| `RATE_LIMIT_EXCEEDED` | SDK wrapper for HTTP `429` | +| `USAGE_LIMIT_EXCEEDED` | A usage policy rejected the request or run | +| `INVALID_EXECUTION_TIMEOUT` | An unsupported or invalid async timeout option | +| `EXECUTION_ERROR` | Transport, response parsing, or execution-request failure | +| `EXECUTION_FAILED` | Fallback code for a failed synchronous run | +| `STATUS_ERROR`, `USAGE_ERROR` | A status or usage helper failed | -##### getWorkflowRun() +Other server error codes pass through, including block/child execution failures. V2 reports malformed JSON/request input as `BAD_REQUEST`, rather than `INVALID_JSON`. See [API errors](/api-reference/getting-started#error-handling). -Get the status and optional outputs of a workflow run. +`executeWithRetry` retries only rate-limit exceptions. By default it makes an initial attempt and up to three retries, using exponential backoff and ±25% jitter: ```typescript -const status = await client.getWorkflowRun('workflow-id', 'run-id', { - includeOutput: true -}); -console.log('Status:', status.status); // 'queued', 'running', 'completed', 'failed' -if (status.status === 'completed') { - console.log('Output:', status.output); -} +const result = await client.executeWithRetry('workflow-id', { message: 'Process this' }, { + timeout: 30000, +}, { + maxRetries: 3, + initialDelay: 1000, + maxDelay: 30000, + backoffMultiplier: 2, +}) +process.stdout.write(JSON.stringify(result)) ``` -**Parameters:** -- `workflowId` (string): The workflow ID -- `runId` (string): The run ID returned from async execution -- `options.includeOutput` (boolean, optional): Include the final output for completed executions -- `options.selectedOutputs` (string[], optional): Block output selectors to include +All retry delays and `RateLimitInfo.retryAfter` use **milliseconds**. A supplied `Retry-After` takes precedence over calculated backoff; jitter still applies. `maxDelay` caps the calculated delay, not a server-supplied wait. -**Returns:** `Promise` - -**Response fields:** -- `runId` (string): The run ID -- `workflowId` (string): The workflow ID -- `status` (string): One of `'queued'`, `'pending'`, `'running'`, `'paused'`, `'completed'`, `'failed'`, `'cancelled'` -- `startedAt` / `endedAt` (string): Execution timestamps -- `durationMs` (number, nullable): Duration in milliseconds -- `output` (any, nullable): The workflow output when requested for a completed execution -- `blockOutputs` (object, nullable): Requested block outputs -- `error` (object, nullable): Structured failure details with `code`, `message`, and optional `details` + +A client timeout or lost response does not prove the run never started. The SDK's timeout stops waiting without aborting its fetch. Reconcile an uncertain execution before starting another run. Use raw v2 requests for caller-selected run IDs and [run-ID recovery](/api-reference/getting-started#sync-vs-async-execution). + -##### getJobStatus() +## Method reference [#api-reference] -Get the status of a job created through the legacy async execution endpoint. New integrations should use `getWorkflowRun()` with the run ID instead. +### Constructor -```typescript -const status = await client.getJobStatus('legacy-job-id'); +```text +new SimStudioClient(config: SimStudioConfig) ``` -##### executeWithRetry() +`SimStudioConfig` has required `apiKey:string` and optional `baseUrl:string`. Supply an origin without an `/api` suffix; the SDK removes trailing slashes and sends the key in `X-API-Key`. -Execute a workflow with automatic retry on rate limit errors using exponential backoff. +### Execute -```typescript -const result = await client.executeWithRetry('workflow-id', { message: 'Hello' }, { - timeout: 30000 -}, { - maxRetries: 3, // Maximum number of retries - initialDelay: 1000, // Initial delay in ms (1 second) - maxDelay: 30000, // Maximum delay in ms (30 seconds) - backoffMultiplier: 2 // Exponential backoff multiplier -}); +```text +executeWorkflow(workflowId: string, input?: any, options?: ExecutionOptions) + -> Promise +executeWorkflowSync(workflowId: string, input?: any, options?: SyncExecutionOptions) + -> Promise +executeWithRetry(workflowId: string, input?: any, options?: ExecutionOptions, + retryOptions?: RetryOptions) -> Promise ``` -**Parameters:** -- `workflowId` (string): The ID of the workflow to execute -- `input` (any, optional): Input data to pass to the workflow -- `options` (ExecutionOptions, optional): Same as `executeWorkflow()` -- `retryOptions` (RetryOptions, optional): - - `maxRetries` (number): Maximum number of retries (default: 3) - - `initialDelay` (number): Initial delay in ms (default: 1000) - - `maxDelay` (number): Maximum delay in ms (default: 30000) - - `backoffMultiplier` (number): Backoff multiplier (default: 2) +| `ExecutionOptions` field | Behavior and default | +| --- | --- | +| `timeout?:number` | Client wait in milliseconds; default `30000` | +| `async?:boolean` | Default omitted/false; true queues the active deployment | +| `executionTimeoutSeconds?:number` | Async-only integer cap, `1`–`604800`; cannot extend account policy | +| `selectedOutputs?:string[]` | Normalized block-name/path selectors such as `agent.content`; incompatible with async submission | +| `stream?:boolean` | Default omitted/false; the current SDK cannot parse SSE when true; use raw HTTP below | -**Returns:** `Promise` +An object input becomes the v2 `input` object. A primitive or array is wrapped as `{input:value}` inside it; omitted/null input becomes `{}`. Nested `File` objects are converted when the runtime provides global `File`. -The retry logic uses exponential backoff (1s → 2s → 4s → 8s...) with ±25% jitter to prevent thundering herd. If the API provides a `retry-after` header, it will be used instead. +`executeWorkflowSync` forces `async:false`. `SyncExecutionOptions` excludes `async` and `executionTimeoutSeconds`. `RetryOptions` has optional `maxRetries` (default `3`), `initialDelay` (`1000` ms), `maxDelay` (`30000` ms), and `backoffMultiplier` (`2`). -##### getRateLimitInfo() +The synchronous adapter does not expose v2 `blockOutputs`, even when `selectedOutputs` is supplied. Use a run read or raw HTTP when you need the selected-output map. -Get the current rate limit information from the last API response. +### Read deployment and runs -```typescript -const rateLimitInfo = client.getRateLimitInfo(); -if (rateLimitInfo) { - console.log('Limit:', rateLimitInfo.limit); - console.log('Remaining:', rateLimitInfo.remaining); - console.log('Reset:', new Date(rateLimitInfo.reset * 1000)); -} +```text +getWorkflowStatus(workflowId: string) -> Promise +validateWorkflow(workflowId: string) -> Promise +getWorkflowRun(workflowId: string, runId: string, options?: GetWorkflowRunOptions) + -> Promise +getJobStatus(taskId: string) -> Promise ``` -**Returns:** `RateLimitInfo | null` - -##### getUsageLimits() - -Get current usage limits and quota information for your account. +`getWorkflowStatus` reads the legacy `/api/workflows/{id}/status` route. `validateWorkflow` returns only `isDeployed`, and returns false if the status lookup fails. It does not verify credentials, inputs, quotas, or deployment readiness. Use the status method directly to distinguish a failed lookup from an undeployed workflow: ```typescript -const limits = await client.getUsageLimits(); -console.log('Sync requests remaining:', limits.rateLimit.sync.remaining); -console.log('Async requests remaining:', limits.rateLimit.async.remaining); -console.log('Current period cost:', limits.usage.currentPeriodCost); -console.log('Plan:', limits.usage.plan); +const deployment = await client.getWorkflowStatus('workflow-id') +process.stdout.write(JSON.stringify(deployment)) ``` -**Returns:** `Promise` +`GetWorkflowRunOptions` contains `includeOutput?:boolean` and `selectedOutputs?:string[]`. Output is omitted/null by default; request it with `includeOutput:true` for a completed run. Run-read selectors use **block IDs**, as `blockId` or `blockId.path`, instead of block names. Selected block outputs are independent of `includeOutput`. -**Response structure:** -```typescript -{ - success: boolean - rateLimit: { - sync: { - isLimited: boolean - limit: number - remaining: number - resetAt: string - } - async: { - isLimited: boolean - limit: number - remaining: number - resetAt: string - } - authType: string // 'api' or 'manual' - } - usage: { - currentPeriodCost: number - limit: number - plan: string // e.g., 'free', 'pro' - } -} -``` +`getJobStatus` polls IDs created by legacy `0.1.x` async execution at `/api/jobs/{taskId}`. Use `getWorkflowRun` for runs started by `0.2.x`. -##### setApiKey() +### Read limits and update the client -Update the API key. - -```typescript -client.setApiKey('new-api-key'); +```text +getRateLimitInfo() -> RateLimitInfo | null +getUsageLimits() -> Promise +setApiKey(apiKey: string) -> void +setBaseUrl(baseUrl: string) -> void ``` -##### setBaseUrl() +`getRateLimitInfo` reads cached headers from the most recent response that supplied rate information; it makes no request. `getUsageLimits` calls the legacy account helper. Setters affect subsequent requests. -Update the base URL. +## Return types [#types] -```typescript -client.setBaseUrl('https://my-custom-domain.com'); -``` - -## Types +The SDK supplies declarations for these types. Arbitrary workflow input/output and log fields are not schema-typed by the client. ### WorkflowExecutionResult -```typescript -interface WorkflowExecutionResult { - success: boolean; - output?: any; - error?: string; - logs?: any[]; - metadata?: { - duration?: number; - runId?: string; - [key: string]: any; - }; - traceSpans?: any[]; - totalDuration?: number; -} -``` +| Field | Declared type | Current adapter behavior | +| --- | --- | --- | +| `success` | `boolean` | True for completed/paused; false for cancelled; failed rejects | +| `executionId` | Optional `string` | V2 run ID | +| `output` | Optional `any` | Workflow output | +| `error` | Optional `string` | Returned message when present | +| `metadata` | Optional object | `duration`, `executionId`, `runId`, `startTime`, `endTime`; permits other keys | +| `totalDuration` | Optional `number` | Duration in milliseconds | +| `logs`, `traceSpans` | Optional `any[]` | Compatibility fields; not populated by the v2 adapter | + +Metadata's duration is an optional number in milliseconds; identifiers/timestamps are optional strings. The current synchronous type has no `status` property. ### AsyncExecutionResult -```typescript -interface AsyncExecutionResult { - success: boolean; - runId: string; - statusUrl: string; - message: string; - async: true; -} -``` +Fields are `success:boolean`, `runId:string`, `statusUrl:string`, `message:string`, and `async:true`. The adapter sets `success:true` and `message:'Workflow execution queued'` for a `202` receipt. ### WorkflowStatus -```typescript -interface WorkflowStatus { - isDeployed: boolean; - deployedAt?: string; - needsRedeployment: boolean; -} -``` - -### RateLimitInfo +Fields are `isDeployed:boolean`, optional `deployedAt:string`, `needsRedeployment:boolean`, and the optional compatibility field `isPublished:boolean`. The current status endpoint does not populate `isPublished`. -```typescript -interface RateLimitInfo { - limit: number; - remaining: number; - reset: number; - retryAfter?: number; -} -``` +### WorkflowRunStatus -### UsageLimits +The server resource returned by `getWorkflowRun` includes: -```typescript -interface UsageLimits { - success: boolean; - rateLimit: { - sync: { - isLimited: boolean; - limit: number; - remaining: number; - resetAt: string; - }; - async: { - isLimited: boolean; - limit: number; - remaining: number; - resetAt: string; - }; - authType: string; - }; - usage: { - currentPeriodCost: number; - limit: number; - plan: string; - }; -} -``` +| Field | Shape | +| --- | --- | +| `runId`, `workflowId` | Strings | +| `status` | queued, pending, running, redacting, paused, completed, failed, or cancelled | +| `trigger` | String or null | +| `startedAt`, `endedAt` | ISO timestamp or null; queued startedAt is enqueue time | +| `durationMs` | Number or null | +| `paused` | Pause-detail object or null; inspect `pauseKind` and `resumeAt` | +| `cost` | `{total:number}` in credits, or null when unavailable/withheld | +| `error` | `WorkflowExecutionError` with code/message and optional details, or null | +| `output` | Requested completed-run output, otherwise null | +| `blockOutputs` | Selected block-ID/path values, or null | +| `files` | Produced-file metadata when output is requested/available, otherwise null | -### SimStudioError +The `0.2.x` exported interface currently omits `redacting` and `files`, although the runtime returns the server object unchanged. The polling example uses a string set so it can wait through redaction without asserting an unsupported type. The interface declares `paused` and `blockOutputs` as nullable records, and the other fields with the nullability shown above. -```typescript -class SimStudioError extends Error { - code?: string; - status?: number; -} -``` +Files have `id`, `name`, byte `size`, MIME `type`, `downloadPath`, and nullable `base64`. The SDK exposes no file-inlining options; use the returned download path with an authenticated HTTP request. Permission policies can withhold costs or recorded outputs. See [Get workflow run](/api-reference/workflow-runs/getWorkflowRunV2) for the full contract, functional-output permission conflict, and file limits. -**Common error codes:** -- `UNAUTHORIZED`: Invalid API key -- `TIMEOUT`: Request timed out -- `RATE_LIMIT_EXCEEDED`: Rate limit exceeded -- `USAGE_LIMIT_EXCEEDED`: Usage limit exceeded -- `EXECUTION_ERROR`: Workflow execution failed - -## Examples - -### Basic Workflow Execution - - - - Set up the SimStudioClient with your API key. - - - Check if the workflow is deployed and ready for execution. - - - Run the workflow with your input data. - - - Process the execution result and handle any errors. - - +### JobStatusResult -```typescript -import { SimStudioClient } from 'simstudio-ts-sdk'; +The legacy type has `taskId:string`, `status:string`, optional `metadata:Record`, `output:unknown`, and `error:string`. It describes legacy job polling, not a v2 run receipt. -const client = new SimStudioClient({ - apiKey: process.env.SIM_API_KEY! -}); - -async function runWorkflow() { - try { - // Check if workflow is ready - const isReady = await client.validateWorkflow('my-workflow-id'); - if (!isReady) { - throw new Error('Workflow is not deployed or ready'); - } - - // Execute the workflow - const result = await client.executeWorkflow('my-workflow-id', { - message: 'Process this data', - userId: '12345' - }); - - if (result.success) { - console.log('Output:', result.output); - console.log('Duration:', result.metadata?.duration); - } else { - console.error('Workflow failed:', result.error); - } - } catch (error) { - console.error('Error:', error); - } -} +### LargeValueRef -runWorkflow(); -``` +Oversized nested output can contain a placeholder with required `__simLargeValueRef:true`, `version:1`, `id:string`, `kind:'array'|'object'|'string'|'json'`, and `size:number`. Optional fields are `key:string`, `executionId:string`, and `preview:unknown`. These storage keys are opaque server pointers, not download URLs. See [large outputs](/workflows/deployment/api#oversized-outputs). -### Error Handling +### RateLimitInfo -Handle different types of errors that may occur during workflow execution: +Fields are `limit:number`, `remaining:number`, `reset:number`, and optional `retryAfter:number`. V2 ISO reset headers become epoch **milliseconds**; older integer headers retain their epoch-seconds value. For v2: ```typescript -import { SimStudioClient, SimStudioError } from 'simstudio-ts-sdk'; - -const client = new SimStudioClient({ - apiKey: process.env.SIM_API_KEY! -}); - -async function executeWithErrorHandling() { - try { - const result = await client.executeWorkflow('workflow-id'); - return result; - } catch (error) { - if (error instanceof SimStudioError) { - switch (error.code) { - case 'UNAUTHORIZED': - console.error('Invalid API key'); - break; - case 'TIMEOUT': - console.error('Workflow execution timed out'); - break; - case 'USAGE_LIMIT_EXCEEDED': - console.error('Usage limit exceeded'); - break; - case 'INVALID_JSON': - console.error('Invalid JSON in request body'); - break; - default: - console.error('Workflow error:', error.message); - } - } else { - console.error('Unexpected error:', error); - } - throw error; - } +const rate = client.getRateLimitInfo() +if (rate) { + process.stdout.write(`${rate.remaining} remaining; reset ${new Date(rate.reset).toISOString()}\n`) } ``` -### Environment Configuration - -Configure the client using environment variables: - - - - ```typescript - import { SimStudioClient } from 'simstudio-ts-sdk'; - - // Development configuration - const apiKey = process.env.SIM_API_KEY; - if (!apiKey) { - throw new Error('SIM_API_KEY environment variable is required'); - } - - const client = new SimStudioClient({ - apiKey, - baseUrl: process.env.SIM_BASE_URL // optional - }); - ``` - - - ```typescript - import { SimStudioClient } from 'simstudio-ts-sdk'; - - // Production configuration with validation - const apiKey = process.env.SIM_API_KEY; - if (!apiKey) { - throw new Error('SIM_API_KEY environment variable is required'); - } - - const client = new SimStudioClient({ - apiKey, - baseUrl: process.env.SIM_BASE_URL || 'https://www.sim.ai' - }); - ``` - - - -### Node.js Express Integration - -Integrate with an Express.js server: +Use a known response surface when converting reset values. The usage helper's `resetAt` ISO strings avoid the mixed legacy units. -```typescript -import express from 'express'; -import { SimStudioClient } from 'simstudio-ts-sdk'; - -const app = express(); -const client = new SimStudioClient({ - apiKey: process.env.SIM_API_KEY! -}); - -app.use(express.json()); - -app.post('/execute-workflow', async (req, res) => { - try { - const { workflowId, input } = req.body; - - const result = await client.executeWorkflow(workflowId, input, { - timeout: 60000 - }); - - res.json({ - success: true, - data: result - }); - } catch (error) { - console.error('Workflow execution error:', error); - res.status(500).json({ - success: false, - error: error instanceof Error ? error.message : 'Unknown error' - }); - } -}); - -app.listen(3000, () => { - console.log('Server running on port 3000'); -}); -``` - -### Next.js API Route +### UsageLimits -Use with Next.js API routes: +```text +success: boolean +rateLimit: + sync / async: + isLimited: boolean + requestsPerMinute: number + maxBurst: number + remaining: number + resetAt: string (ISO timestamp) + authType: string (server values "api" or "manual") +usage: + currentPeriodCost: number (USD) + limit: number (USD) + plan: string +storage: + usedBytes: number + limitBytes: number + percentUsed: number +``` + +`requestsPerMinute` is the refill rate; `maxBurst` is the bucket capacity. There is no `rateLimit.sync.limit` field. ```typescript -// pages/api/workflow.ts -import { NextApiRequest, NextApiResponse } from 'next'; -import { SimStudioClient } from 'simstudio-ts-sdk'; - -const client = new SimStudioClient({ - apiKey: process.env.SIM_API_KEY! -}); - -export default async function handler( - req: NextApiRequest, - res: NextApiResponse -) { - if (req.method !== 'POST') { - return res.status(405).json({ error: 'Method not allowed' }); - } - - try { - const { workflowId, input } = req.body; - - const result = await client.executeWorkflow(workflowId, input, { - timeout: 30000 - }); - - res.status(200).json(result); - } catch (error) { - console.error('Error executing workflow:', error); - res.status(500).json({ - error: 'Failed to execute workflow' - }); - } -} +const limits = await client.getUsageLimits() +process.stdout.write(JSON.stringify({ + remaining: limits.rateLimit.sync.remaining, + resetAt: limits.rateLimit.sync.resetAt, + periodCostUSD: limits.usage.currentPeriodCost, + storageBytes: limits.storage.usedBytes, +})) ``` -### Browser Usage - -Keep the Sim API key on your server. A browser application should call an authenticated backend endpoint that checks which workflow the user can run, then calls the SDK. The [Next.js API Route](#nextjs-api-route) example shows where the server-side SDK call belongs; add your application authentication and authorization before executing a workflow. +This legacy helper resolves account/key-owner usage and can differ from the selected workspace's payer. Use [Get billing status](/api-reference/billing/getBillingStatus) for workspace credits/storage. Logs APIs also report USD; v2 Billing and run-resource amounts use credits. If calculating a usage percentage, handle a zero limit before dividing. -### File Upload +## File inputs [#file-upload] -File objects are automatically detected and converted to base64 format. Include them in your input under the field name matching your workflow's API trigger input format. +The SDK recursively converts global `File` objects to: -The SDK converts File objects to this format: ```typescript -{ +const inlineFile = { type: 'file', - data: 'data:mime/type;base64,base64data', - name: 'filename', - mime: 'mime/type' + data: 'data:application/pdf;base64,BASE64_BYTES', + name: 'document.pdf', + mime: 'application/pdf', } ``` -Alternatively, you can manually provide files using the URL format: +You can also supply a URL file: + ```typescript -{ +const urlFile = { type: 'url', - data: 'https://example.com/file.pdf', - name: 'file.pdf', - mime: 'application/pdf' + data: 'https://example.com/document.pdf', + name: 'document.pdf', + mime: 'application/pdf', } ``` -Run file uploads on your backend after authenticating the caller and validating the upload. For example, in Node.js: - -```typescript -import { SimStudioClient } from 'simstudio-ts-sdk'; -import { readFile } from 'node:fs/promises'; +Place files under the input field your deployed trigger expects. Run uploads on the backend after authenticating the caller and validating size/content. Base64 overhead counts toward the execute endpoint's 10 MiB JSON-body limit. -const client = new SimStudioClient({ apiKey: process.env.SIM_API_KEY! }); -const fileBuffer = await readFile('./document.pdf'); -const file = new File([fileBuffer], 'document.pdf', { type: 'application/pdf' }); +For automatic conversion, this example requires **Node.js 20+**, where `File` is global: -const result = await client.executeWorkflow('workflow-id', { +```typescript +import { readFile } from 'node:fs/promises' +import { SimStudioClient } from 'simstudio-ts-sdk' + +const apiKey = process.env.SIM_API_KEY +const workflowId = process.env.WORKFLOW_ID +if (!apiKey || !workflowId) throw new Error('Set SIM_API_KEY and WORKFLOW_ID') +const client = new SimStudioClient({ apiKey }) +const bytes = await readFile('./document.pdf') +const file = new File([new Uint8Array(bytes)], 'document.pdf', { type: 'application/pdf' }) +const result = await client.executeWorkflowSync(workflowId, { documents: [file], - query: 'Summarize this document' -}); + query: 'Summarize this document', +}) +process.stdout.write(JSON.stringify(result.output)) ``` +On Node.js 18, use a serialized base64/URL object. Importing `File` from `node:buffer` only in the caller does not satisfy the SDK's global-File detection. +## Use from a web backend [#browser-usage] +Keep the key on the server. Authenticate the application caller, resolve a workflow they may run, validate the input, and only then call the SDK. A trusted server key does not authorize every browser caller to run every workflow. -### Async Workflow Execution - -Execute workflows asynchronously for long-running tasks: +This helper is the SDK call to use after those checks: ```typescript -import { SimStudioClient, AsyncExecutionResult } from 'simstudio-ts-sdk'; - -const client = new SimStudioClient({ - apiKey: process.env.SIM_API_KEY! -}); - -async function executeAsync() { - try { - // Start async execution - const result = await client.executeWorkflow('workflow-id', { data: 'large dataset' }, { - async: true // Execute asynchronously - }); - - // Check if result is an async execution - if ('async' in result && result.async) { - console.log('Run ID:', result.runId); - console.log('Status endpoint:', result.statusUrl); - - // Poll for completion - let status = await client.getWorkflowRun('workflow-id', result.runId, { - includeOutput: true - }); - - while (status.status === 'queued' || status.status === 'pending' || status.status === 'running') { - console.log('Current status:', status.status); - await new Promise(resolve => setTimeout(resolve, 2000)); // Wait 2 seconds - status = await client.getWorkflowRun('workflow-id', result.runId, { - includeOutput: true - }); - } - - if (status.status === 'completed') { - console.log('Workflow completed!'); - console.log('Output:', status.output); - console.log('Duration:', status.durationMs); - } else if (status.status === 'paused') { - console.log('Workflow is paused and waiting for input or resumption.'); - } else if (status.status === 'cancelled') { - console.log('Workflow was cancelled.'); - } else { - console.error('Workflow failed:', status.error); - } - } - } catch (error) { - console.error('Error:', error); - } +async function executeAuthorizedWorkflow(workflowId: string, input: Record) { + return client.executeWorkflowSync(workflowId, input, { timeout: 60000 }) } - -executeAsync(); ``` -### Rate Limiting and Retry +### Express integration [#nodejs-express-integration] -Handle rate limits automatically with exponential backoff: +Call the helper from a POST handler after authentication and authorization middleware. Parse JSON with a request-size limit, map rejected SDK requests to an appropriate HTTP status, and preserve cancellation/paused state instead of wrapping every resolved result as completed success. -```typescript -import { SimStudioClient, SimStudioError } from 'simstudio-ts-sdk'; +### Next.js API route -const client = new SimStudioClient({ - apiKey: process.env.SIM_API_KEY! -}); - -async function executeWithRetryHandling() { - try { - // Automatically retries on rate limit - const result = await client.executeWithRetry('workflow-id', { message: 'Process this' }, {}, { - maxRetries: 5, - initialDelay: 1000, - maxDelay: 60000, - backoffMultiplier: 2 - }); - - console.log('Success:', result); - } catch (error) { - if (error instanceof SimStudioError && error.code === 'RATE_LIMIT_EXCEEDED') { - console.error('Rate limit exceeded after all retries'); - - // Check rate limit info - const rateLimitInfo = client.getRateLimitInfo(); - if (rateLimitInfo) { - console.log('Rate limit resets at:', new Date(rateLimitInfo.reset * 1000)); - } - } - } -} -``` +Call the same helper from an authenticated server route. In a Pages Router API handler, reject methods other than POST with `405`; in either router, authorize workflow selection before execution. Set the server's `SIM_API_KEY` environment variable and keep it out of browser bundles. -### Usage Monitoring +## Stream through HTTP [#streaming-workflow-execution] -Monitor your account usage and limits: +The current `0.2.x` SDK sends `stream:true` but unconditionally parses JSON. It has no SSE iterator/callback and cannot consume a valid SSE response. Use raw HTTP instead: ```typescript -import { SimStudioClient } from 'simstudio-ts-sdk'; - -const client = new SimStudioClient({ - apiKey: process.env.SIM_API_KEY! -}); - -async function checkUsage() { - try { - const limits = await client.getUsageLimits(); - - console.log('=== Rate Limits ==='); - console.log('Sync requests:'); - console.log(' Limit:', limits.rateLimit.sync.limit); - console.log(' Remaining:', limits.rateLimit.sync.remaining); - console.log(' Resets at:', limits.rateLimit.sync.resetAt); - console.log(' Is limited:', limits.rateLimit.sync.isLimited); - - console.log('\nAsync requests:'); - console.log(' Limit:', limits.rateLimit.async.limit); - console.log(' Remaining:', limits.rateLimit.async.remaining); - console.log(' Resets at:', limits.rateLimit.async.resetAt); - console.log(' Is limited:', limits.rateLimit.async.isLimited); - - console.log('\n=== Usage ==='); - console.log('Current period cost: $' + limits.usage.currentPeriodCost.toFixed(2)); - console.log('Limit: $' + limits.usage.limit.toFixed(2)); - console.log('Plan:', limits.usage.plan); - - const percentUsed = (limits.usage.currentPeriodCost / limits.usage.limit) * 100; - console.log('Usage: ' + percentUsed.toFixed(1) + '%'); - - if (percentUsed > 80) { - console.warn('⚠️ Warning: You are approaching your usage limit!'); - } - } catch (error) { - console.error('Error checking usage:', error); - } -} - -checkUsage(); -``` - -### Streaming Workflow Execution - -Execute workflows with real-time streaming responses: - -```typescript -import { SimStudioClient } from 'simstudio-ts-sdk'; - -const client = new SimStudioClient({ - apiKey: process.env.SIM_API_KEY! -}); - -async function executeWithStreaming() { - try { - // Enable streaming for specific block outputs - const result = await client.executeWorkflow('workflow-id', { message: 'Count to five' }, { - stream: true, - selectedOutputs: ['agent1.content'] // Use blockName.attribute format - }); - - console.log('Workflow result:', result); - } catch (error) { - console.error('Error:', error); +const apiKey = process.env.SIM_API_KEY +const workflowId = process.env.WORKFLOW_ID +if (!apiKey || !workflowId) throw new Error('Set SIM_API_KEY and WORKFLOW_ID') + +const response = await fetch(`https://www.sim.ai/api/v2/workflows/${workflowId}/execute`, { + method: 'POST', + headers: { + 'X-API-Key': apiKey, + 'Content-Type': 'application/json', + 'X-Sim-Stream-Protocol': 'agent-events-v1', + }, + body: JSON.stringify({ input: { message: 'Count to five' }, stream: true, + selectedOutputs: ['agent.content'] }), +}) +if (!response.ok) throw new Error(`HTTP ${response.status}: ${await response.text()}`) +if (!response.body) throw new Error('Missing SSE response body') + +const decoder = new TextDecoder() +const reader = response.body.getReader() +try { + while (true) { + const { done, value } = await reader.read() + if (done) break + process.stdout.write(decoder.decode(value, { stream: true })) } + process.stdout.write(decoder.decode()) +} finally { + reader.releaseLock() } ``` -The streaming response follows the Server-Sent Events (SSE) format: - -``` -data: {"blockId":"7b7735b9-19e5-4bd6-818b-46aae2596e9f","chunk":"One"} - -data: {"blockId":"7b7735b9-19e5-4bd6-818b-46aae2596e9f","chunk":", two"} - -data: {"event":"done","success":true,"output":{},"metadata":{"duration":610}} - -data: [DONE] -``` +This prints raw SSE; network chunks are not necessarily complete events. Success emits `{event:"final",data:...}`, failure emits `{event:"error",...}`, then `[DONE]`. Preserve output and reset events. The protocol header enables live answer tokens and requires `chunk_reset` handling; thinking/tool events require their separate flags. For browsers, have the authenticated backend forward the upstream stream, check HTTP status, and close/cancel it on disconnect. -For browser streaming, have your authenticated backend forward the Sim SSE response. Keep the Sim API key on the backend, check the upstream response status, and parse complete SSE events across network chunks. See [streaming responses](/workflows/deployment/api#streaming) for the event format. +See [API streaming](/workflows/deployment/api#streaming) and the [reference client](/workflows/deployment/agent-events#reference-client) for event parsing and protocol details. Synchronous NDJSON heartbeats are a separate transport selected by `Accept: application/x-ndjson`; the SDK has no option for that header. -## Getting Your API Key +## Upgrade from 0.1.x -Create a key in **Account settings → Sim API keys**, or use a workspace key if your administrator requires one. See [Authentication](/api-reference/authentication) for key types and permissions. Deploy the workflow before calling it through the SDK. Keep the key in a server-side environment variable. +`0.2.0` changed execution to `/api/v2`, nests named input under `input`, and puts async/timeout options in the body instead of `X-Execution-Mode` and `X-Execution-Timeout-Seconds` headers. -## Requirements +Replace `AsyncExecutionResult.jobId` with `runId`; its old `executionId` is removed. Poll with `getWorkflowRun(workflowId, runId)`, not `getJobStatus`. Failed synchronous runs now reject; move failure handling from a `!result.success` branch into `catch`. A resolved false result means cancellation; true also includes paused runs. -- Node.js 16+ -- TypeScript 5.0+ (for TypeScript projects) +Workflow status, legacy jobs, and account usage helpers still use their original routes. This SDK does not expose every v2 operation, manual draft execution, resume/cancel, caller-selected run headers, or NDJSON/agent-event streaming controls. -## License +## Related docs -Apache-2.0 +- [API authentication](/api-reference/authentication) +- [Python SDK](/api-reference/python) +- [API getting started](/api-reference/getting-started) +- [Get workflow run](/api-reference/workflow-runs/getWorkflowRunV2) +- [TypeScript package source and Apache-2.0 license](https://github.com/simstudioai/sim/tree/main/packages/ts-sdk) diff --git a/apps/docs/content/docs/api-reference/workflow-sync.mdx b/apps/docs/content/docs/api-reference/workflow-sync.mdx index dd0fe5249e0..37424406c96 100644 --- a/apps/docs/content/docs/api-reference/workflow-sync.mdx +++ b/apps/docs/content/docs/api-reference/workflow-sync.mdx @@ -1,51 +1,59 @@ --- title: Workflow imports and workspace sync -description: Use the v2 preview, mapping, apply, and operation-status protocol from an API or CLI client +description: Preview destination choices, apply imports or workspace sync, and reconcile their operations. --- -An automated client exports or inspects the source, previews destination choices, applies the reviewed request, and polls its operation. The [CLI workflow guide](/cli/workflow-sync) follows this same v2 protocol; the server owns authorization, remapping, atomic writes, and durable completion for both surfaces. +Import an exported workflow as a draft, or fork and synchronize workspaces through the v2 preview-and-apply protocol. Preview the destination bindings, apply those exact choices, then poll the returned operation to verify copies and deployment readiness. The [CLI workflow guide](/cli/workflow-sync) uses the same protocol. -## CLI and HTTP interfaces +## Choose the interface [#cli-and-http-interfaces] -Paths below are relative to `/api/v2`. `{workspaceId}` is the explicitly selected current workspace. +HTTP paths below are relative to `/api/v2`. `{workspaceId}` is the current workspace you explicitly selected. | CLI command | HTTP request | | --- | --- | -| `workflows export --include-references` | `GET /workflows/{workflowId}/export?includeReferences=true` | -| `workflows import-preview` / `workflows import` | `POST /workflows/import/preview` / `POST /workflows/import` | -| `workspaces fork-availability` / `lineage` | `GET /workspaces/{workspaceId}/fork/availability` / `.../fork/lineage` | -| `workspaces children` / `fork-resources` | `GET /workspaces/{workspaceId}/fork/children` / `.../fork/resources?kind=tables` | -| `workspaces fork-preview` / `fork` | `POST /workspaces/{workspaceId}/fork/preview` / `.../fork` | -| `workspaces push-preview` / `push --yes` | `POST /workspaces/{workspaceId}/fork/push/preview` / `.../fork/push` | -| `workspaces pull-preview` / `pull --yes` | `POST /workspaces/{workspaceId}/fork/pull/preview` / `.../fork/pull` | -| `workspaces mappings get` / `mappings update` | `GET` / `PUT /workspaces/{workspaceId}/fork/mappings` | -| `selectors list` / `selectors get` | `POST /selectors/list` / `POST /selectors/get` | -| `workspaces operations get ` / `operations wait ` | `GET /workspaces/{workspaceId}/operations/{operationId}`; wait polls this endpoint | -| `workspaces operations list` | `GET /workspaces/{workspaceId}/operations` | +| `sim workflows export --include-references` | `GET /workflows/{workflowId}/export?includeReferences=true` | +| `sim workflows import-preview` / `sim workflows import` | `POST /workflows/import/preview` / `POST /workflows/import` | +| `sim workspaces fork-availability` / `sim workspaces lineage` | `GET /workspaces/{workspaceId}/fork/availability` / `.../fork/lineage` | +| `sim workspaces children` / `sim workspaces fork-resources` | `GET /workspaces/{workspaceId}/fork/children` / `.../fork/resources?kind=tables` | +| `sim workspaces fork-preview` / `sim workspaces fork` | `POST /workspaces/{workspaceId}/fork/preview` / `.../fork` | +| `sim workspaces push-preview` / `sim workspaces push --yes` | `POST /workspaces/{workspaceId}/fork/push/preview` / `.../fork/push` | +| `sim workspaces pull-preview` / `sim workspaces pull --yes` | `POST /workspaces/{workspaceId}/fork/pull/preview` / `.../fork/pull` | +| `sim workspaces mappings get` / `sim workspaces mappings update` | `GET` / `PUT /workspaces/{workspaceId}/fork/mappings` | +| `sim selectors list` / `sim selectors get` | `POST /selectors/list` / `POST /selectors/get` | +| `sim workspaces operations get ` / `sim workspaces operations wait ` | `GET /workspaces/{workspaceId}/operations/{operationId}`; wait polls this endpoint | +| `sim workspaces operations list` | `GET /workspaces/{workspaceId}/operations` | -The generated [sync preview reference](/api-reference/workspace-sync/previewWorkspacePull) documents every field; its sidebar includes rollback, unlink, and exclusion endpoints. Children, resource discovery, mappings, and operations are paginated; follow `nextCursor` without changing the query's scope or filters. +The [sync reference](/api-reference/workspace-sync/previewWorkspacePull) documents fields and includes rollback, unlink, and exclusions. Children, resource discovery, mappings, and operations are paginated: follow `nextCursor` with the same scope and filters. -## Permissions +## Prerequisites and access [#permissions] -Send a personal API key in `X-API-Key`, or an OAuth access token in `Authorization: Bearer …`. Existing workspace policies, credential access, permission groups, Enterprise/self-hosting gates, and workspace creation limits still apply. +Set `BASE_URL` to your deployment origin, without `/api/v2`. Use a personal API key in `X-API-Key`, or an OAuth token in `Authorization: Bearer`. Examples use separate authorized source/destination keys where applicable. Replace all example resource IDs with IDs from your export and destination. | Operation | Required access | | --- | --- | | Export | Workflow read access | -| Import preview and apply | Destination write access; binding credentials also requires an acting user with credential access | -| Fork discovery, preview, and creation | Source workspace admin | -| Sync preview/apply and mapping read/update | Admin on both workspaces on a direct fork edge | -| Rollback / unlink | Target admin / acting-side admin, respectively | +| Import preview/apply | Destination write access; binding credentials also requires an acting user with credential access | +| Fork discovery, preview, creation | Source workspace Admin; creation policy must allow a new workspace | +| Sync preview/apply and mapping read/update | Admin on both workspaces on a direct parent/child fork edge | +| Rollback / unlink | Target Admin / acting-side Admin, respectively | | Selector discovery | Read access in the discovery workspace and access to the selected credential | | Operation get/list | Read access in the receipt workspace | -Workspace API keys can import where existing authoring policy allows, but cannot bind credentials, administer forks, or execute selectors. Do not substitute a key owner for an acting user. OAuth import/fork/sync previews require `api:write`, even though preview does not commit changes. Export, fork discovery, mapping reads, selectors, and operation reads use `api:read`. +Workspace keys can import where authoring policy allows, but cannot bind credentials, administer forks, or execute selectors. The key owner is not a substitute for an acting user. Workspace policies, permission groups, credential access, and workspace creation limits still apply. -## Portable imports +OAuth import/fork/sync previews require `api:write`, even though previews do not commit changes. Export, fork discovery, mapping reads, selectors, and operation reads use `api:read`. -Default exports remain sanitized. `includeReferences=true` adds a versioned manifest of registered resource IDs and source occurrences, including nested tools. It does not include secret values. Imported provenance and source IDs are labels; they never grant access to an alleged source workspace. +Forking and sync require the owning organization's Enterprise entitlement on billing-enabled deployments. On billing-disabled deployments, deployment configuration must enable forking. Check [Fork availability](/api-reference/workspace-sync/getWorkspaceForkAvailability) before starting. Imports, selector discovery, and operation reports have their own access rules and do not inherit the fork-specific gate. -Set `BASE_URL` to your deployment, and use an authorized key for each workspace. Raw HTTP returns `{ "data": ... }`; the CLI unwraps single-resource results. Extract the export payload before saving it: +## Import a portable workflow [#portable-imports] + +### Export and inspect the source + +Default exports clear registered credential fields and workspace bindings. `includeReferences=true` adds a versioned manifest of resource IDs and their source occurrences, including nested tools. The manifest contains identities, not secret values. Unresolved environment-variable references remain, and ordinary workflow variable values or literal configuration can remain in the full export. Inspect the payload before sharing it. + +Source IDs and imported provenance are labels; they do not grant access to an alleged source workspace. `includeWorkspaceBindings=true` can retain non-secret bindings for a same-workspace round trip; otherwise configure any required bindings reported by import. + +Raw HTTP wraps the result in `data`; the CLI unwraps a single resource. Extract that payload before saving it: ```sh curl -sS --fail-with-body \ @@ -54,7 +62,9 @@ curl -sS --fail-with-body \ | jq '.data' > workflow.json ``` -Save destination mappings as `import-mappings.json`, replacing the example IDs with manifest and destination resource IDs: +### Map destination resources + +Save `import-mappings.json`, using source IDs from the manifest and authorized destination IDs: ```json [ @@ -63,7 +73,9 @@ Save destination mappings as `import-mappings.json`, replacing the example IDs w ] ``` -`mappings` applies to every occurrence of a resource's `kind` and `sourceId`. For older exports, `bindings` can address individual registered occurrences. Its entries are flat objects, without `sourceId` or an `occurrence` wrapper: +`mappings` applies to every occurrence of a resource's `kind` and `sourceId`. Destination type, provider, and parent/child compatibility are validated. `targetId:null` requests clearing and cannot satisfy a required binding. Conflicting instructions for one occurrence are rejected. + +For older exports, `bindings` addresses individual registered occurrences. Entries are flat objects, without `sourceId` or an `occurrence` wrapper: ```json [ @@ -78,7 +90,9 @@ Save destination mappings as `import-mappings.json`, replacing the example IDs w ] ``` -A top-level field uses `valuePath: []`. Other registered encodings are `array`, `csv`, `files`, and `environment`; multi-value occurrences can include `positions`. Use the actual registered occurrence, rather than inventing paths. Conflicting instructions for one occurrence are rejected. `targetId: null` requests clearing; it cannot satisfy a required binding. Destination type, provider, and parent-child compatibility are validated. +A top-level field uses `valuePath:[]`. Other registered encodings are `array`, `csv`, `files`, and `environment`; multi-value occurrences can include `positions`. Use a returned registered occurrence rather than inventing a path. + +### Preview and complete configuration Build one request file and preview it: @@ -93,7 +107,7 @@ curl -sS --fail-with-body -H "X-API-Key: $DESTINATION_API_KEY" \ "$BASE_URL/api/v2/workflows/import/preview" > import-preview.json ``` -Inspect `data.unresolvedBindings`, `data.configuration`, `data.unresolvedConfiguration`, and `data.discovery`. Dependent choices use a different shape from bindings: +Inspect `data.unresolvedBindings`, `data.configuration`, `data.unresolvedConfiguration`, and `data.discovery`. Dependent configuration choices have a different shape from bindings: ```json [ @@ -101,7 +115,9 @@ Inspect `data.unresolvedBindings`, `data.configuration`, `data.unresolvedConfigu ] ``` -Add these as `dependentValues` to `import-request.json` and preview again. For a field with `multiSelect: true`, `value` is a comma-separated string of selected IDs. For credential-backed selectors, discover options in the import's destination workspace using the returned `selectorKey` and `context`: +Add them as `dependentValues` to the request and preview again. A `multiSelect:true` field uses a comma-separated string of selected IDs. + +For credential-backed selectors, use the import destination workspace and the preview's `selectorKey` and `context` to discover options: ```sh curl -sS --fail-with-body -H "X-API-Key: $DESTINATION_API_KEY" \ @@ -111,9 +127,13 @@ curl -sS --fail-with-body -H "X-API-Key: $DESTINATION_API_KEY" \ "$BASE_URL/api/v2/selectors/list" ``` -Selector lists return `{ "data": [...], "nextCursor": null, "truncated": false }`; check both pagination and truncation. Detail uses `/selectors/get` with the same scope/context and an `id`. MCP tools use `mcp.tools` with `mcpServerId`. A missing OAuth connection can require human authorization; changing a resource ID cannot create that connection. +Selector lists return `{ "data": [...], "nextCursor": null, "truncated": false }`; check pagination **and** truncation. Detail uses `/selectors/get` with the same workspace/key/context and an `id`. MCP tool discovery uses `mcp.tools` with `mcpServerId`. A missing OAuth connection can require human authorization; changing a resource ID cannot create the connection. + +Keep selector workspace, key, context, and search unchanged when paging. A changed provider page can return `409`, requiring discovery to restart. Detail can return `data:null` for a missing choice or `413` when verification exceeds provider bounds. See [List selector](/api-reference/workspace-sync/listSelector) and [Get selector](/api-reference/workspace-sync/getSelector). + +### Apply the reviewed import -When `data.ready` is true, save a stable request ID and apply the exact reviewed choices: +When `data.ready` is true, choose a stable `IMPORT_REQUEST_ID` for this mutation and retain it with the complete request. Apply the exact reviewed choices and fingerprint: ```sh jq --arg requestId "$IMPORT_REQUEST_ID" \ @@ -126,15 +146,34 @@ curl -sS --fail-with-body -H "X-API-Key: $DESTINATION_API_KEY" \ "$BASE_URL/api/v2/workflows/import" > import-result.json ``` -Mapped import creates a draft, its graph, variables, required inline custom tools, and receipt atomically. Remapping precedes graph ID regeneration; the result includes `idMap`. Plain imports without mapping options retain their earlier behavior and return no operation receipt. Supplying mapping options, even empty arrays, requires `requestId` and `previewFingerprint`. +Mapped import atomically creates the draft, graph, variables, required inline custom tools, and receipt. Remapping happens before graph ID regeneration; the result includes `idMap`. Plain imports without mapping options retain their earlier behavior and return no operation receipt. Supplying mapping options, even empty arrays, requires `requestId` and `previewFingerprint`. -## Fork and sync +Imported workflows remain drafts. Check reported configuration and deploy before using ordinary deployed execution. -Fork preview and apply share `{ "name": "Review environment", "copy": { "tables": ["source-table"] } }`. Apply adds `requestId` and the preview's fingerprint. Eligible deployed source workflows become child drafts; resource copies must be selected explicitly. +## Fork a workspace [#fork-and-sync] -Push sends deployed workflows from the current workspace to `otherWorkspaceId`. Pull sends them from `otherWorkspaceId` to the current workspace. Either endpoint works from either side of the direct parent/child edge. +Fork preview and apply start with the same choices: -For example, save this as `sync-request.json` for a pull into the workspace in the URL: +```json +{ + "name": "Review environment", + "copy": { "tables": ["source-table"] } +} +``` + +POST the request to `/workspaces/{workspaceId}/fork/preview`. Inspect its plan and fingerprint, then POST the same choices to `/workspaces/{workspaceId}/fork` with a stable `requestId` and the returned `previewFingerprint`. + +Eligible deployed source workflows become **child drafts**. Resources are copied only when selected explicitly. Fork creation uses `copy`; sync uses `copyResources`. Fork `copy.files` contains workspace file IDs, while sync `copyResources.files` contains storage keys. Credentials and secret values are not copied. Inspect destination configuration before deploying a fork's workflows. + +## Push or pull a sync + +Push sends deployed workflows from the current workspace to `otherWorkspaceId`. Pull brings them from `otherWorkspaceId` into the current workspace. Either endpoint can run from either side of a direct parent/child edge, with Admin access to both. + +Sync can create target workflows, replace mapped target workflows, and archive mapped targets whose source was deleted or archived. It schedules deployments of the admitted snapshots. An undeployed source alone does not archive its mapped target. Excluded workflows remain excluded; review target replacements and retiring trigger URLs before apply. + +### Select mappings and copies + +For a pull into the workspace in the URL, save `sync-request.json`: ```json { @@ -149,30 +188,31 @@ For example, save this as `sync-request.json` for a pull into the workspace in t } ``` -Sync mappings use edge `resourceType` names, such as `oauth_credential`, `service_account_credential`, `knowledge_base`, `custom_tool`, or `sandbox`; imports use `kind`, such as `credential`, `knowledge-base`, or `custom-tool`. Sync workflow identity is system-managed. Pick a knowledge document through its parent KB's dependent selector instead of writing a `knowledge_document` edge mapping. +Sync mappings use edge `resourceType` names such as `oauth_credential`, `service_account_credential`, `knowledge_base`, `custom_tool`, and `sandbox`. Imports instead use `kind` names such as `credential`, `knowledge-base`, and `custom-tool`. Workflow identity is system-managed. Choose a knowledge document through its parent knowledge base's dependent selector instead of writing a `knowledge_document` edge mapping. + +Mapping inspection requires `otherWorkspaceId` and `direction` query fields. Read rows include a storage `id`; writes accept only `resourceType`, `sourceId`, and `targetId`. Project a read page with `jq '[.data[] | {resourceType, sourceId, targetId}]'` before reusing it, and follow `nextCursor` for further pages. -Mapping inspection requires `otherWorkspaceId` and `direction` in its query. Read rows also contain a storage `id`; write requests accept only `resourceType`, `sourceId`, and `targetId`. Project a page with `jq '[.data[] | {resourceType, sourceId, targetId}]'` before reusing its mappings, and follow `nextCursor` to collect further pages. +Preview does not persist inline mappings. Apply saves them in the sync transaction. Dependent overrides use source workflow/block/field identities, including original nested-tool indices. Omitting `dependentValues` reuses saved choices; supplying it replaces choices for affected workflows, and `[]` clears them. Values in a target draft alone are not saved sync configuration. -Preview never saves inline mappings. Apply persists them with the sync transaction. Dependent overrides use source workflow/block/field identities, including original nested tool indices. Omission reuses saved choices; providing `dependentValues` replaces those choices for affected workflows, and `[]` clears them. Target draft values alone are not saved sync configuration. +`dropReferences` acknowledges references deleted in the source; it cannot discard live source resources. + +### Preview and inspect trigger choices ```sh curl -sS --fail-with-body -H "X-API-Key: $SIM_API_KEY" \ -H 'Content-Type: application/json' --data @sync-request.json \ "$BASE_URL/api/v2/workspaces/$CURRENT_WORKSPACE/fork/pull/preview" > sync-preview.json +``` -jq --arg requestId "$SYNC_REQUEST_ID" \ - --arg fingerprint "$(jq -er '.data.previewFingerprint' sync-preview.json)" \ - '. + {requestId: $requestId, previewFingerprint: $fingerprint, confirm: true}' \ - sync-request.json > sync-apply.json +Review `unresolvedBindings`, `configuration`, planned workflow actions, and retiring URLs. For selector discovery, use each configuration field's `discoveryWorkspaceId`: the source when its parent will be copied, the destination when mapped. Pass the returned context and preview any changed choices again. `ready:true` means the apply plan is ready, not that all destination deployments will be ready. -curl -sS --fail-with-body -H "X-API-Key: $SIM_API_KEY" \ - -H 'Content-Type: application/json' --data @sync-apply.json \ - "$BASE_URL/api/v2/workspaces/$CURRENT_WORKSPACE/fork/pull" > sync-result.json -``` +`triggerSlots` uses stable `sourceWorkflowId` and `sourceBlockId` identities and includes `ownPath`, `adoptablePaths`, and `defaultAdoptPath`: -Review `unresolvedBindings`, `configuration`, planned workflow actions, and retiring trigger URLs before apply. Use each configuration field's `discoveryWorkspaceId` for `/selectors/list` or `/selectors/get`: source when its parent will be copied, destination when mapped. Pass its returned context and re-preview any changed choices. A ready preview is not a deployment-readiness report. +- A slot with `ownPath` preserves that URL and accepts no override. +- An arriving trigger can adopt an offered retiring path, or request a new URL with `adoptPath:null`. +- Unknown identities, duplicate choices, or paths outside the slot's candidates are rejected. Candidates stay within the same target workflow and provider. -`triggerSlots` lists stable `sourceWorkflowId` and `sourceBlockId` identities, `ownPath`, `adoptablePaths`, and `defaultAdoptPath`. A slot with `ownPath` preserves that URL and accepts no override. For an arriving trigger, `triggerMappings` can select an offered retiring path or `null` to request a new URL. Include the same choices on preview and apply: +Include the same `triggerMappings` choices on preview and apply: ```json [ @@ -180,21 +220,32 @@ Review `unresolvedBindings`, `configuration`, planned workflow actions, and reti ] ``` -Unknown source identities, duplicate choices, and paths outside that slot's candidates are rejected. Adoption candidates stay within the same target workflow and provider; do not construct them from a different workflow's URL. +### Apply the sync -Copy selections use `copy` for fork creation and `copyResources` for sync. Fork `copy.files` contains workspace file IDs; sync `copyResources.files` contains storage keys. Credentials and secret values are not copied. `dropReferences` only acknowledges references deleted in the source; it cannot discard live source resources. +Choose a stable `SYNC_REQUEST_ID` and preserve the exact reviewed request: -Sync replaces eligible target workflows and schedules deployment of the admitted snapshots. Exclusions remain in effect. A deleted source can archive its mapped target; an undeployed source does not. Rollback restores the latest target sync's prior deployed versions, with no promise to restore arbitrary drafts or undo all resource copies. +```sh +jq --arg requestId "$SYNC_REQUEST_ID" \ + --arg fingerprint "$(jq -er '.data.previewFingerprint' sync-preview.json)" \ + '. + {requestId: $requestId, previewFingerprint: $fingerprint, confirm: true}' \ + sync-request.json > sync-apply.json -## Receipts, polling, and retries +curl -sS --fail-with-body -H "X-API-Key: $SIM_API_KEY" \ + -H 'Content-Type: application/json' --data @sync-apply.json \ + "$BASE_URL/api/v2/workspaces/$CURRENT_WORKSPACE/fork/pull" > sync-result.json +``` -Apply returns a single-resource envelope. This is an example completed sync report: +For push, use `/fork/push/preview` and `/fork/push` with the same direction-relative rules. `confirm:true` acknowledges target replacement. Changes to mappings or trigger choices require another preview before apply. + +## Verify operations and recover [#receipts-polling-and-retries] + +Apply returns a single-resource envelope. A completed sync report can look like: ```json { "data": { "operationId": "operation-id", - "requestId": "release-2026-09-09", + "requestId": "release-2026-10-13", "workspaceId": "current-workspace", "kind": "workspace_pull", "applied": true, @@ -215,7 +266,13 @@ Apply returns a single-resource envelope. This is an example completed sync repo } ``` -Always poll under the returned `workspaceId`. Import receipts belong to the destination. Fork-creation receipts belong to the source on which `/fork` ran. Push/pull receipts belong to the current workspace in the request URL, including a push that changes the other workspace. +Poll under the **returned** `workspaceId`: + +| Mutation | Receipt workspace | +| --- | --- | +| Import | Destination | +| Fork creation | Source workspace on which `/fork` ran | +| Push/pull | Current workspace in the request URL, including a push that changes the other workspace | ```sh OPERATION_ID=$(jq -er '.data.operationId' sync-result.json) @@ -225,14 +282,28 @@ curl -sS --fail-with-body -H "X-API-Key: $SIM_API_KEY" \ "$BASE_URL/api/v2/workspaces/$OPERATION_WORKSPACE/operations/$OPERATION_ID" ``` -Poll with a delay while `status` is `processing`. Terminal outcomes are `completed`, `completed_with_warnings`, `requires_configuration`, and `failed`. Inspect `issues`, `copyProgress`, `deployments[].ready`, `pendingComponents`, and `triggerUrlChanges`. `applied: true` remains true after a follow-up failure: the transaction committed. Completed imports and forks remain drafts; a completed sync requires checking its admitted deployment results before treating the destination as ready. +Poll with a delay while `status` is `processing`. Terminal outcomes are `completed`, `completed_with_warnings`, `requires_configuration`, and `failed`. Inspect `issues`, `copyProgress`, `deployments[].ready`, `pendingComponents`, and `triggerUrlChanges`. + +`applied:true` stays true after a follow-up failure: the transaction committed. Completed imports and forks remain drafts. For sync, check the **exact admitted deployments** in the receipt before treating the destination as ready. + +### Retry an uncertain response + +Request IDs deduplicate within the receipt workspace. Retain the complete apply request and original ID. Identical authorized retries return the original operation before preview-freshness checks. A changed payload under the same ID, stale preview, or blocked apply returns HTTP `409` with the v2 error envelope; other invalid input can return `400`. Follow-up failures appear on a committed operation. + +After an uncertain response, retry the identical request with its original ID, or query `GET /workspaces/{workspaceId}/operations?requestId=...`. Lists return `{ "data": [...], "nextCursor": ... }`; use operation get for refreshed copy/deployment status. + +If a stale preview is refused before commit, obtain a new preview and use a new request ID for the revised request. Do not replace a lost-response request with a fresh ID just to retry; that can create another mutation. -Request IDs deduplicate within the receipt workspace. Retain the complete apply request: identical authorized retries return the original operation before checking preview freshness. A changed payload under the same ID, a stale preview, or blocked apply returns HTTP `409` with `{ "error": { "code": "CONFLICT", "message": "...", "details": {} } }`. Other invalid inputs can return `400`; follow-up failures are reported on a committed operation. +## Rollback, unlink, and exclusions -After an uncertain response, retry the identical request with the original ID, or query `GET /workspaces/{workspaceId}/operations?requestId=...`. Lists return `{ "data": [...], "nextCursor": ... }`; use operation get for refreshed completion status. If a stale preview is refused before commit, obtain a new preview and use a new request ID for the revised request. Never replace a lost-response request with a fresh ID merely to retry. +[Rollback](/api-reference/workspace-sync/rollbackWorkspaceFork) restores the latest inbound sync's prior deployed versions. It can archive sync-created workflows and restore archived targets, but does not promise to restore arbitrary target drafts or undo all resource copies. Inspect `pendingActivations`; another rollback attempt may be needed to finish activation. -## What the test harness covers +[Unlink](/api-reference/workspace-sync/unlinkWorkspaceFork) removes the direct relationship and its mappings while retaining workspace content. [Exclusions](/api-reference/workspace-sync/updateWorkspaceForkExclusions) keep selected workflows out of later syncs. -Run `bun run test:workflow-sync` from the Sim repository with Bun, dependencies, and Docker available. It creates disposable PostgreSQL 17, exercises actual authorization, API-key authentication, v2 HTTP adapters, CLI subprocesses, graph/receipt transactions, locks, and deployment outbox workers, then removes the database. Tests cover concurrent retries, stale previews, atomic refusal, immutable deployment snapshots, exclusions, pagination, and copy-worker recovery. +## Related docs -External provider options and failures use controlled fixtures; the separate realtime process uses an authenticated loopback fixture. This validates the platform protocol rather than proving every provider account is connected. Verify provider authorization and destination deployment readiness in the environment you intend to use. Migration safety is checked separately from this fresh-schema harness. +- [CLI workflow sync](/cli/workflow-sync) +- [Workspace forking](/platform/enterprise/forks) +- [Import preview](/api-reference/workspace-sync/previewWorkflowImport) +- [Operation status](/api-reference/workspace-sync/getWorkspaceOperation) +- [Workflow-sync repository harness](https://github.com/simstudioai/sim/tree/main/apps/sim/lib/workspaces/__integration__) for `bun run test:workflow-sync`, disposable PostgreSQL, fixture boundaries, and contributor prerequisites diff --git a/apps/docs/content/docs/chat/files.mdx b/apps/docs/content/docs/chat/files.mdx index db82437d9d9..f49af135ef8 100644 --- a/apps/docs/content/docs/chat/files.mdx +++ b/apps/docs/content/docs/chat/files.mdx @@ -1,118 +1,113 @@ --- -title: Files & documents -description: Upload, create, edit, and generate files — documents, presentations, images, and more. +title: Files and documents +description: Process attachments and create or edit workspace documents, presentations, images, and charts. --- -import { Image } from '@/components/ui/image' -import { Video } from '@/components/ui/video' -import { FAQ } from '@/components/ui/faq' +Ask Sim to read an attachment, create a deliverable, or edit a workspace file. Name the output format and filename when you need a saved result. Supported generation and processing capabilities depend on your deployment. - +## Attach and save files [#uploading-files-to-the-workspace] -Describe a document, presentation, image, or visualization and Sim creates it — streaming the content live into the resource panel as it writes. Attach any file to your message and Sim reads it, processes it, and saves it to your workspace. +Drag a supported file into the input, paste it, or select **Attach file**. Chat supports images, PDFs, text and code files, JSON, XML, and other supported document formats. -## Uploading Files to the Workspace +Attachments are stored under `uploads/` and stay readable within the conversation. They do not automatically appear in workspace **Files** or workflow file listings. Ask Sim to save a copy when you need a workspace file: -Attach any file directly to your message in Chat — drag it into the input, paste it, or click the attachment icon. Sim reads the file as context and saves it to your workspace. +- "Summarize this document and extract the action items." Attach the document. +- "Create a table from this CSV." Attach the CSV. +- "Add this PDF to the Product Docs knowledge base." Attach the PDF. +- "Describe this design mockup and write code for the layout." Attach the image. +- "Save this attachment to workspace Files as source-data.json." -Use this to: -- Hand Sim a document and ask it to process, summarize, or extract data from it -- Upload a CSV and have it create a table from it -- Drop in a PDF and ask Sim to turn it into a knowledge base document -- Attach a design mockup and ask Sim to describe it or generate code from it +Sim can also download a file from an accessible URL: "Download the JSON at [URL] and save it as source-data.json." -An attached file is stored under `uploads/` and readable by Sim for the rest of the conversation, but it does not appear in the Files panel and is not listed for workflows. Ask Sim to save a copy into workspace Files if you need it there. Sim can also fetch a file directly from a URL and save it for you: "Download the JSON at [URL] and save it to the workspace." +A successful upload does not mean every format's contents have been parsed. For a file without a supported reader, Sim may need to process the original bytes with code. ZIP archives must be extracted before their contents can be read. -## Creating Documents +Direct uploads are deliberate input and are not automatically scanned for secrets. For stored files, Chat can mask tracked secret values or withhold content it cannot safely check. Your viewer can still open a file that Chat cannot read or receive as a rendered preview. Creating or returning a sharing link through Chat can also be refused. -Sim can write any text-based file — markdown, plain text, code files, CSV, JSON, or any other format: +## Create a text file [#creating-documents] -- "Write a technical spec for the new auth system as a markdown file" -- "Create a CSV of our test accounts with columns for name, email, and plan tier" -- "Write a Python script that calls our workflow API and processes the response" -- "Draft a postmortem for the outage last Tuesday and save it as a markdown file" -- "Write a personalized outbound email for Acme Corp based on their recent funding announcement" -- "Draft a weekly ops digest summarizing workflow run counts, errors, and top failures for the past 7 days" +Sim can write Markdown, plain text, code, CSV, and JSON files. Ask for the content and its destination: -Files are saved to your workspace and accessible from the Files panel in the sidebar. +- "Write a technical spec for the new auth system as auth-spec.md." +- "Create test-accounts.csv with name, email, and plan tier columns." +- "Write a Python script that calls our workflow API and processes the response." +- "Save a postmortem for last Tuesday's outage as outage-review.md." +- "Draft an outbound email for Acme Corp based on its recent funding announcement and save it as acme-email.md." +- "Save a weekly ops digest with run counts, errors, and top failures from the past seven days." -## Editing Existing Files +Saved workspace files appear in **Files** and can open in the resource panel. Text edits can appear as Sim writes; generated binary documents and media appear when their artifacts are ready. -Open a file using `@filename` or the **+** menu, then describe the change: +## Edit an existing file [#editing-existing-files] -- "Update the pricing section to reflect the new tiers" -- "Refactor this Python script to use async/await" -- "Add a section on error handling to this spec" -- "Rewrite the introduction of this report to be more concise" +Open the file with an `@`-mention or the **+** menu and describe the change: -## Presentations +- "Update the pricing section with these new tiers: [details]." +- "Refactor this Python script to use async/await." +- "Add error handling to this spec and shorten the introduction." -Chat resource panel showing a generated Mothership-Use-Cases.pptx file open with the title slide and first use case slide visible +Name the existing file when you want Sim to update it rather than create another copy. Editing requires the relevant file access. -Sim can generate `.pptx` files: +## Generate documents and presentations [#presentations] -- "Create a pitch deck for Q3 review — 8 slides covering growth, retention, and roadmap" -- "Turn this research report into a 10-slide presentation" -- "Build a deck that walks through our API onboarding flow" -- "Build a battle card deck for our top 3 competitors — one slide each covering positioning, pricing, and how we win" -- "Create an account plan for Acme Corp — their priorities, our solution fit, and proposed next steps" +Specify a binary format such as `.pptx`, `.docx`, `.pdf`, or `.xlsx` when you need it. Availability depends on the configured document and sandbox capabilities. A request for a document can otherwise be fulfilled as Markdown. -The file is saved to your workspace and can be downloaded. +For presentations, include the audience, slide count, and contents: -## Images +- "Create an eight-slide Q3 review as q3-review.pptx, covering growth, retention, and roadmap." +- "Turn this research report into a 10-slide presentation." +- "Create a deck explaining our API onboarding flow." +- "Create a battle card deck for our top three competitors, with positioning, pricing, and our strengths." +- "Create an Acme Corp account plan covering its priorities, our solution fit, and next steps." -Sim can generate images using AI, and can use an existing image as a reference to guide the output: +Ask Sim to save the final file to the workspace. Open it to review the content and layout, then download it from the resource panel or **Files**. -**Generating images:** -- "Generate a banner image for the new feature announcement — dark background, clean typography" -- "Create a diagram showing the data flow through our webhook pipeline" -- "Make a social card for the blog post with the title and author name" +## Generate or edit an image [#images] -**Using a reference image:** -- Attach an existing image to your message, then describe what you want: "Generate a new version of this banner with a blue color scheme instead of green" -- "Create a variation of this diagram with the boxes rearranged horizontally [attach image]" +Describe the subject, style, size or aspect ratio, and intended use: -Chat resource panel showing a generated hero image of a Mothership-branded blimp flying over San Francisco at golden hour, alongside the chat response linking the file +- "Generate a feature announcement banner with a dark background and clean typography." +- "Create a social card with this blog title and author name: [details]." -Generated images are saved as workspace files. +For a variation, attach an image or reference a workspace image: "Generate a version of this banner with a blue color scheme instead of green." Saved generated images appear in workspace **Files**. -## Charts and Visualizations +## Create charts and diagrams [#charts-and-visualizations] -Sim can generate charts and data visualizations from data you describe or reference: +Reference the data and name the chart you need: -- "Plot the workflow run counts from the metrics table as a bar chart grouped by week" -- "Create a line chart of token usage over the past 30 days from this data [paste data]" -- "Generate a pie chart showing the distribution of lead sources from the leads table" +- "Plot workflow run counts from the metrics table as a weekly bar chart." +- "Create a line chart of token usage over the past 30 days from this data: [data]." +- "Show the distribution of lead sources from the leads table as a pie chart." -Chat resource panel showing a generated chart file with bar charts for backend 5xx errors and error rate over time +Sim can also create diagrams from a description, such as the webhook pipeline's data flow or a horizontal version of an existing diagram. Ask for a code-based diagram when exact labels and structure matter. Save the chart or visualization as a file, then inspect it in the resource panel. -Visualizations are saved as files and rendered in the resource panel. +## Process data [#calculations-data-processing] -## Calculations & Data Processing +Sim can run code for calculations and one-off transformations: -For one-off calculations and data transformations, describe what you need and Sim runs it directly in the chat: +- "Extract records from this JSON where status is 'failed'." +- "Calculate p95 latency from these timing values: [values]." +- "Convert these Unix timestamps to ISO 8601." +- "Deduplicate this email list without case sensitivity." -- "Parse this JSON and extract all records where status is 'failed'" -- "Calculate the p95 latency from these timing values: [paste values]" -- "Convert these Unix timestamps to ISO 8601" -- "Deduplicate this list of emails, case-insensitive" +Results can be returned in the chat. Ask Sim to save a file when you need to reuse them. The Chat workbench holds temporary computation files while its session exists; those files become workspace files only when explicitly saved or exported. Code outputs written to the per-call `SIM_OUTPUT_DIR` are exported to workspace **Files**. -Results come back directly in the chat. Ask Sim to save the output as a file if you need it. +If a requested stored file, folder input, or table snapshot is withheld, the code does not run. Check the excluded-input report before trying again. Later calls without that input remain available. -## File Viewer Modes +## View and reuse files [#file-viewer-modes] -When a file opens in the resource panel, you can switch between three views: +The viewer depends on the file type and your access: - +| File | Viewing and editing | +| --- | --- | +| Markdown | Read and edit in place | +| Supported text with a rendered preview, such as HTML | Use **Edit Mode**, **Split Mode**, or **Preview Mode** when editing is allowed | +| Images, PDFs, and supported Office files | Open the format's preview | +| Unsupported files or files too large for an editor | Download the file or ask Sim to process it | -| Mode | What it shows | -|------|--------------| -| **Editor** | Raw editable text | -| **Preview** | Rendered output (markdown, HTML) | -| **Split** | Editor and preview side by side | +Workspace files can be read with a File block or passed as workflow inputs. A chat attachment must first be saved to workspace **Files** when the workflow needs a reusable workspace file. - +## Related docs + +- [Files](/files) +- [File editor](/files/editor) +- [Generating files](/files/generating) +- [Using files in workflows](/files/using-in-workflows) diff --git a/apps/docs/content/docs/chat/index.mdx b/apps/docs/content/docs/chat/index.mdx index c8ab0137ba5..9797b0edf05 100644 --- a/apps/docs/content/docs/chat/index.mdx +++ b/apps/docs/content/docs/chat/index.mdx @@ -1,71 +1,78 @@ --- title: Chat -description: Your AI command center. Talk to Sim — build and manage everything in natural language. +description: Build workflows, research sources, and manage workspace resources by talking to Sim. --- -import { Video } from '@/components/ui/video' -import { FAQ } from '@/components/ui/faq' +Use Chat to ask Sim to build and run workflows, research a topic, create files, query tables, and act through connected services. Name the resources and outcome you want; Sim can inspect the accessible workspace context needed for the request. - +## What you can do -Use Chat to build workflows, research a topic, generate files, query tables, schedule jobs, and act through connected integrations. Reference the workspace resources you want Sim to use. +| Task | Examples | +| --- | --- | +| [Workflows](/chat/workflows) | Build, edit, test, debug, deploy, and organize workflows | +| [Research](/chat/research) | Search web sources, read pages, and save cited reports | +| [Files and documents](/chat/files) | Process attachments; create or edit documents, presentations, images, and charts | +| [Tables](/chat/tables) | Create tables, query or update rows, and export data | +| [Actions and configuration](/chat/tasks) | Call connected services, set up recurring workflows, and manage credentials, secrets, and tools | +| [Knowledge bases](/chat/knowledge) | Add documents and connectors, search content, and configure workflow retrieval | +| [Sim Mailer](/chat/mailer) | Submit tasks by email to an enabled workspace inbox | -## What You Can Do +## Start a chat [#how-it-works] -| Area | What Sim can do | -|------|-----------------------| -| **[Workflows](/chat/workflows)** | Build, edit, run, debug, deploy, and organize workflows | -| **[Research](/chat/research)** | Search the web, read pages, crawl sites, produce research reports | -| **[Files & Documents](/chat/files)** | Upload, create, edit, and generate documents, presentations, and images | -| **[Tables](/chat/tables)** | Create, query, update, and export workspace tables | -| **[Automation & Configuration](/chat/tasks)** | Schedule jobs, take immediate actions, connect integrations, manage tools | -| **[Knowledge Bases](/chat/knowledge)** | Create knowledge bases, add documents, and query content in plain language | +1. Select **New chat** in the sidebar. +2. Choose **Build** for the workspace actions described in this section. Where available, **Search** answers questions from connected sources. +3. Describe the task, its inputs, and the result you want. -## How It Works +**Plan** helps research needs and develop a solution before implementation. It appears only for eligible platform administrators with **Super admin mode** enabled on a deployment that enables this capability. An organization Admin role alone does not enable it. -Sim can find workspace resources by name and inspect the details it needs. Reference a resource explicitly when you want to direct its attention: +For example: -- "Run the invoice workflow" -- "Add a row to the leads table" -- "Deploy the summarizer as a chat" +- "Build a lead enrichment workflow that scores inbound signups and writes the results to the leads table." +- "Research our top five competitors and save a battle card for each one." +- "Create a workflow that takes a contract PDF, extracts key terms, and emails a summary to legal." +- "Add a daily schedule to the prospect workflow and deploy it. At 8am America/New_York, find new high-fit prospects and post them to #outbound in Slack." -No configuration, no context-setting. Just describe what you want: +Chat can work across accessible resources. When you open Sim inside a workflow, that conversation is scoped to the workflow. In the organization view, **Build** requires permission to create organization workspaces; each action in an existing workspace still checks its access and enabled capabilities. Available actions depend on your role, connected accounts, workspace settings, and organization policy. Planning a solution does not by itself authorize deploying it or sending messages. -- "Build a lead enrichment workflow that scores inbound signups and writes the results to the leads table" -- "Research our top 5 competitors and save a battle card for each one" -- "Schedule a daily job that checks for new high-fit prospects and posts them to #outbound in Slack" -- "Create a workflow that takes a contract PDF, extracts the key terms, and emails a summary to legal" +## Add context [#adding-context] -For complex tasks, Sim delegates to specialized subagents automatically. You'll see them appear as collapsible sections in the chat while they work — building, researching, writing files, executing actions. +Use the **+** menu, type `@` followed by a resource name, or drag an item from the sidebar into the input. You can reference workflows, tables, files, knowledge bases, folders, and earlier chats. Naming a resource in a request also helps Sim find it: -{/* TODO: Screenshot of Chat showing a subagent section expanded mid-task — e.g., the Build or Research subagent actively working, with its collapsible header and steps visible in the thread. */} +- "Run the invoice workflow." +- "Add a row to the leads table." +- "Deploy the summarizer as a chat." -## Adding Context +Attach a supported file when Sim needs its contents. Attachments stay with the conversation; ask Sim to save a copy to workspace **Files** when teammates or workflows need it. See [files in Chat](/chat/files). -Bring any workspace object into the conversation via the **+** menu, `@`-mentions, or drag-and-drop from the sidebar. Sim also opens resources automatically when it creates or modifies them. +## Inspect progress and resources [#layout] - +The chat thread appears beside a resource panel. Workflows open in the workflow builder, tables in the table editor, knowledge bases in their management view, and files in a viewer appropriate to their type. Sim can open resources as it creates or modifies them. -{/* TODO: Screenshot of the resource panel with multiple tabs open — a workflow tab, a table tab, and a file tab — showing different resource types side by side. */} +Resize the panel, drag tabs to reorder them, and close tabs you no longer need. For larger requests, Sim may delegate parts of the work to other agents. Expand their activity in the chat to inspect progress. -| What to add | How it appears | -|-------------|---------------| -| **Workflow** | Interactive canvas in the resource panel | -| **Table** | Full table editor in the resource panel | -| **File** | File viewer with editor, split, and preview modes | -| **Knowledge Base** | Knowledge base management UI | -| **Folder** | Folder contents | -| **Past task** | A previous Chat conversation | +Messages in the same conversation queue while Sim is working. You can edit or remove a queued message, or use **Send now** to stop the current turn and send that message. Use **Stop generation** to stop the current response. -## Layout +### Find text in a conversation -Chat has two panes. On the left: the chat thread, where your messages and Sim's responses appear. On the right: the resource panel, where workflows, tables, files, and knowledge bases open as tabs. The panel is resizable; tabs are draggable and closeable. +With the chat pane focused, press **Cmd/Ctrl + F** to open **Find in chat**. Enter text, then use **Enter** or **Shift + Enter** to move between matches. Press **Escape** to close it. - +Find searches loaded user and assistant message text, excluding tool/activity cards and hidden reasoning. Older messages load progressively when you reopen a conversation. While that history is loading, or if loading fails, a missing match does not establish that the message is absent. Find keeps up to 500 matches, prioritizing recent messages; a `+` after the count indicates more matches. - +When native Mac app control is available in Sim Desktop, Chat also shows the active app/action and a **Stop** control. See [Computer Use](/desktop#native-mac-app-control) for device opt-in, app approvals, and macOS permissions. + +## Permissions and limits + +Reading a resource does not grant permission to edit or execute it. Workspace writes and runs require the relevant access, and organization policies can restrict individual capabilities. + +Chat can mask tracked secret values or withhold stored files, table rows, and knowledge content it cannot safely check before it reaches the model. This check is separate from workspace access and tool approval. A resource can remain available in your workspace even when its content is unavailable to Chat. + +When tool permissions require a decision, review the action and choose **Allow** or **Skip**. **Don't ask again** offers **For this chat** and **For every chat**, subject to policy. Approval does not expand your underlying resource access. + +Chat runs are subject to the deployment's configured runtime and usage limits. Split long work into steps; use a deployed workflow for recurring execution. Check the result and any remaining setup or failed actions before treating the task as complete. + +## Related docs + +- [Search](/search) +- [Permissions](/platform/permissions) +- [Credentials](/platform/credentials) +- [Costs](/platform/costs) diff --git a/apps/docs/content/docs/chat/knowledge.mdx b/apps/docs/content/docs/chat/knowledge.mdx index 2cafd69e439..bb31325bd12 100644 --- a/apps/docs/content/docs/chat/knowledge.mdx +++ b/apps/docs/content/docs/chat/knowledge.mdx @@ -1,83 +1,94 @@ --- title: Knowledge bases -description: Create, populate, and query knowledge bases from Chat. +description: Create knowledge bases, add documents or connectors, and search their content from Chat. --- -import { Video } from '@/components/ui/video' -import { FAQ } from '@/components/ui/faq' +Ask Sim to create a knowledge base, add source documents, or search existing content. Use a knowledge base for documents retrieved by meaning, such as support policies or product guides. Access and permitted operations follow workspace and organization policy. - +## Create a knowledge base [#creating-knowledge-bases] -Create a knowledge base, add documents to it, and query it in plain language — all through conversation. Knowledge bases you create in Chat are immediately available to Agent blocks in any workflow. +Name the base and describe the content it should hold: -## Creating Knowledge Bases +- "Create a Product Docs knowledge base for our product documentation." +- "Create a Support KB for support policies and troubleshooting guides." +- "Create a competitive intelligence knowledge base." +- "Create a knowledge base from our sales playbook and configure the outbound workflow to search it." +- "Create a customer success knowledge base for onboarding guides and case studies." -Describe the knowledge base and Sim creates it: +## Add and process documents [#adding-documents] -- "Create a knowledge base called 'Product Docs'" -- "Set up a knowledge base for our support team — call it 'Support KB'" -- "Create a competitive intelligence knowledge base" -- "Create a knowledge base from our sales playbook and attach it to the outbound agent workflow" -- "Set up a customer success knowledge base — I'll add our onboarding guides and past case studies to it" +Attach a supported file, paste text, or provide an accessible URL: -## Adding Documents +- "Add this PDF to Product Docs." Attach the PDF. +- "Add this text to Support KB as a new document: [content]." +- "Fetch [URL] and add its content to competitive intelligence." +- "Add these three case studies to the customer success knowledge base." Attach the files. -Add documents by attaching files to your message, pasting text, or pointing Sim at a URL: +PDFs, Markdown, plain text, and content fetched from web pages can be ingested. Sim can help process and index the documents. Content is searchable only after processing completes successfully and the document is enabled. -- "Add this PDF to the Product Docs knowledge base [attach file]" -- "Add the following text to the Support KB as a new document: [paste content]" -- "Fetch the page at [URL] and add it to the competitive intelligence knowledge base" -- "Add these three uploaded case studies to the customer success knowledge base" +Ask Sim to check the documents added by the request and report processing failures. A saved document or an accepted upload does not itself prove the content is indexed. If processing fails, inspect the error and retry after fixing the cause. -Sim processes and indexes each document automatically. Once indexed, the content is searchable by any Agent block that has the knowledge base attached. +Chat attachments stay with their conversation. Adding one to a knowledge base is a separate request; it does not automatically save a reusable workspace file. -{/* TODO: Screenshot of Sim confirming a document was added and indexed — showing the document name and its indexed status in the knowledge base. */} +## Search the content [#querying-knowledge-bases] -## Querying Knowledge Bases +Specify the knowledge base and question: -Ask Sim a question and it searches the specified knowledge base to answer: +- "What does Product Docs say about refunds?" +- "Search Support KB for SSO setup errors." +- "Compare Pro and Enterprise features using the product docs." +- "Find documents about [competitor]'s pricing in competitive intelligence." -- "What does the Product Docs knowledge base say about our refund policy?" -- "Search the Support KB for anything related to SSO setup errors" -- "What are the key differences between our Pro and Enterprise plans, based on the product docs?" -- "Find everything in the competitive intelligence knowledge base about [competitor]'s pricing" +Sim retrieves matching content to answer the question. Check that the returned evidence comes from the intended documents; a partial search or no matches does not establish that the base contains no relevant information. -## Connectors +Chat can mask tracked secret values or omit documents, passages, and tag values it cannot safely check, even when indexing and access checks pass. Document-list counts can still describe the underlying collection. Check the knowledge base directly when expected content is unavailable to Chat. -For knowledge bases that should stay current automatically, connectors sync content from external services on a schedule — no manual uploads needed. New content is added, changed content is re-processed, and deleted content is removed on every run. +## Keep sources updated [#connectors] -Connectors are usually configured in the knowledge base settings. Sim can also create, update, and sync them for you. Content becomes searchable after syncing and indexing, subject to the caller's access permissions. +Connectors sync documents from external services on a configured schedule. Ask Sim to create or update the connection, or run a sync, using an available credential and the source you want: -Use a [connector](/knowledgebase/connectors) to sync sources such as Notion, Google Drive, Slack, GitHub, or Confluence. +- "Sync the support page tree from Notion into Support KB." +- "Connect the onboarding folder in Google Drive to the customer success knowledge base." +- "Sync this GitHub repository's documentation into Product Docs." +- "Sync this Slack channel's history into Support KB." -Examples of what you can sync: +Supported sources also include cloud storage such as Dropbox and OneDrive, wikis and issue trackers such as Confluence and Jira, and CRM records such as HubSpot and Salesforce. See the [connector guide](/knowledgebase/connectors) for the current source list, setup requirements, and sync frequency options. -- **Notion** — sync a workspace, a database, or a specific page tree -- **Google Drive / Dropbox / OneDrive** — sync documents from cloud storage -- **GitHub** — sync a repository's markdown and code files -- **Slack** — sync channel history -- **Confluence / Jira** — sync your internal wiki or issue tracker -- **HubSpot / Salesforce** — sync CRM records into a searchable knowledge base +New and changed content becomes searchable after syncing and processing. Source removals are reconciled during sync; they are not guaranteed to disappear on every run. Check connector status and errors if the knowledge base appears out of date. Search remains subject to the caller's access permissions. -See [Connectors](/knowledgebase/connectors) for setup steps, sync frequency options, and managing connector status. +## Use a knowledge base in a workflow [#using-knowledge-bases-in-workflows] -## Managing Knowledge Bases +Ask Sim to configure one of these retrieval paths: -List, inspect, and clean up knowledge bases in plain language: +1. Add **Knowledge Search** to an Agent block's tools and select the knowledge base. +2. Add a Knowledge block before the Agent, select the base, and reference the search results in the Agent's prompt. -- "What knowledge bases are in this workspace?" -- "How many documents are in the Support KB?" -- "Remove the outdated pricing doc from the Product Docs knowledge base" -- "Delete the old-competitive-intel knowledge base" +The base must be accessible and its documents successfully indexed. Selecting a base does not grant access to documents withheld by policy. -## Using Knowledge Bases in Workflows +A workflow can also add documents through **Knowledge Create Document** or **Knowledge Upsert Document**. Configure the intended base and content, then verify that processing completes before relying on retrieval. -Knowledge bases created in Chat are immediately available to Agent blocks in any workflow. Attach a knowledge base to an Agent block and it will use semantic search to retrieve relevant content at runtime. +## Manage documents and bases [#managing-knowledge-bases] -See [Knowledge Base](/knowledgebase) for full details on document processing settings, search configuration, and connector syncing. +Ask Sim to inspect the inventory or remove specific content: - +- "List knowledge bases in this workspace." +- "How many documents are in Support KB?" +- "Remove the outdated pricing document from Product Docs." +- "Delete the old-competitive-intel knowledge base." + +Document deletion cannot be reversed by restoring the knowledge base. For connector-managed content, correct the source and sync it again rather than editing its indexed chunks. + +## Private knowledge graphs + +On deployments that enable this restricted capability, eligible platform administrators with **Super admin mode** enabled can open **Knowledge graphs** in organization settings. These private Chat memory graphs are separate from the workspace knowledge bases described above. + +Select **New graph**, enter a name, and choose **Create and activate**, or choose **Make active** beside an existing graph. Graph names can have 1–100 characters and cannot be `Default` in any capitalization. The **Default** graph preserves the original memory. + +Each graph is private to you in that organization. The active graph is selected for new chats in the organization and its workspaces; existing chats keep their original graph. Selecting or creating a graph keeps the other graphs and does not grant access to workspace knowledge-base documents. + +## Related docs + +- [Knowledge base](/knowledgebase) +- [Connectors](/knowledgebase/connectors) +- [Using knowledge bases in workflows](/knowledgebase/using-in-workflows) +- [Debugging retrieval](/knowledgebase/debugging-retrieval) diff --git a/apps/docs/content/docs/chat/mailer.mdx b/apps/docs/content/docs/chat/mailer.mdx index da33cc8738d..d9d017fe821 100644 --- a/apps/docs/content/docs/chat/mailer.mdx +++ b/apps/docs/content/docs/chat/mailer.mdx @@ -1,71 +1,96 @@ --- title: Sim Mailer -description: Send emails to your workspace and let Sim handle them as tasks. +description: Submit tasks by email to an enabled workspace inbox and follow the results in Chat. --- import { Callout } from 'fumadocs-ui/components/callout' -import { FAQ } from '@/components/ui/faq' -Sim Mailer gives your workspace a dedicated email address. Forward or send emails to it and Sim will process them as tasks — reading the subject, body, and any attachments, then replying to the thread with the result. +Sim Mailer gives an enabled workspace an email address. Send or forward a message to submit a task; its subject, body, and successfully prepared attachments become the prompt. Sim normally replies in the email thread with the result and a link to the conversation. -## Getting Started +## Requirements -1. Navigate to **Settings** → **Inbox** -2. Toggle the inbox on -3. Optionally choose a custom address prefix (e.g., `acme` → `acme@mothership.sim.ai`) -4. Copy your inbox address and start sending emails +A workspace **Admin** configures the inbox. On Sim Cloud, availability follows the workspace's Max or Enterprise plan and active billing, rather than the sender's individual plan. -If you skip the custom prefix, one is generated automatically. +On self-hosted deployments, availability depends on configured Chat and email services. `INBOX_ENABLED` or billing-disabled configuration can allow access, but the required Chat service key must still be configured. See [self-hosted environment variables](/platform/self-hosting/environment-variables). + +Members keep their own workspace permissions when submitting email tasks. An allowed external email sender can submit read-only tasks; allowlisting does not grant workspace membership, workflow execution, mutation access, or raw-secret access. + +## Enable the inbox [#getting-started] + +1. Open **Settings** → **Inbox**. +2. Switch the inbox to **On** and choose **Enable**. You can supply an **Email prefix** or leave it blank to generate one. +3. Copy the address shown under **Sim's email**. +4. Configure allowed senders and secret access before submitting tasks that need workspace context. +5. Send a test message, then inspect its status and conversation in **Inbox**. + +The prefix is customizable. The domain comes from the deployment's email configuration and is not selected in this control; use the address shown in **Inbox**. - Changing your address creates a new inbox. The old address stops working immediately. + Changing the address creates a new inbox. The old address stops accepting tasks immediately. Update any forwarding rules or saved contacts that use it. -## What You Can Send +Use **Off** to disable the inbox. Existing conversations and task history are preserved. + +## Configure allowed senders [#allowed-senders] + +Manage **Allowed senders** in **Settings** → **Inbox**: -Write your email like you would to a colleague. The subject and body become the task prompt. +- Workspace members are allowed by default. +- An Admin can add an external email address with an optional label, or remove it from the allowlist. -**Attachments are fully supported.** Images, PDFs, and documents (up to 10 MB each) are read by Sim and displayed inline in the conversation; images show as previews. +An external email sender is different from an external workspace member. The latter has access to Sim according to their workspace role without joining the organization; an email-only sender has no such membership. -| Good email | Why it works | -|------------|-------------| -| "Summarize the attached PDF and list action items" | Clear task with an attachment | -| "What's in this image?" with a photo attached | Sim reads and describes the image | -| "Draft a reply to this forwarded thread" | Uses the email body as context | +Emails from unauthorized senders are rejected. Automated senders, rate limits, or loss of plan entitlement can also prevent a task from being accepted. -## Allowed Senders +## Select secret access -Only authorized senders can create tasks. Emails from anyone else are automatically rejected. +Under **Secrets**, **Secret access** defaults to **All secrets**. Choose **Selected secrets** to restrict raw-secret mounts. With **Selected secrets**, choose the permitted names in the **Secrets** selector. Selecting none allows no raw-secret mounts. -- **Workspace members** are allowed by default — no setup needed -- **External senders** can be added manually with an optional label for easy identification +This setting narrows which secrets member tasks may mount; it does not grant access to secrets the sender cannot otherwise use. External email-only senders have no raw-secret access. Configure workflow credentials separately according to their access rules. -External senders are email addresses that can create inbox tasks. They are not the same as external workspace members, who have workspace access in Sim without joining your organization. +Mailer runs without an interactive approval card. Restrict allowed senders and secret access according to the actions members should be able to request; their underlying permissions and organization policies still apply. -Manage your allowed senders list in **Settings** → **Inbox** → **Allowed Senders**. +## Send a task [#what-you-can-send] -## Tracking Tasks +Write the subject and body as a specific request: -Every email becomes a task you can track in **Settings** → **Inbox**: +| Email | Context | +| --- | --- | +| "Summarize the attached PDF and list action items." | An attached source document | +| "What is shown in this image?" | An attached image | +| "Draft a reply to this forwarded thread." | The forwarded email body | -- **Search** by subject, sender, or body content -- **Filter** by status to find what you need -- **Click** any completed or failed task to jump to the full conversation +The per-attachment hard limit is **10 MiB**. Supported images, PDFs, and documents are attached to the Chat conversation; images can display as previews. If an attachment cannot be prepared, the conversation identifies it as unavailable and keeps any successfully prepared attachments. -### Task Statuses +Attachments stay with the conversation. Ask Sim to save a copy to workspace **Files** when you need a reusable workspace file, using a member account with the required write access. + +## Track tasks [#tracking-tasks] + +Open **Settings** → **Inbox** to inspect received messages: + +1. Use **Search tasks...** to match a subject, sender, or body preview in the displayed tasks. +2. Choose a status from **All statuses** to filter the list. +3. Select a completed or failed task with a linked chat to open its full conversation. + +### Task statuses | Status | Meaning | -|--------|---------| -| **Received** | Email accepted, queued for processing | -| **Processing** | Sim is actively working on it | -| **Completed** | Done — the result was sent as an email reply | -| **Failed** | Something went wrong during execution | -| **Rejected** | Email blocked (sender not allowed, automated sender, or rate limit exceeded) | +| --- | --- | +| **Received** | Accepted and queued for processing | +| **Processing** | Sim is working on the task | +| **Completed** | Sim finished the task successfully; the list badge reads **Complete** | +| **Failed** | The task encountered an execution error | +| **Rejected** | The message was blocked; inspect its rejection reason | + +A completed task does not prove an email reply was delivered. If a reply is missing, inspect the linked conversation and task result. Failed tasks can also have an email response describing the error. + +## Continue the conversation [#conversations] -## Conversations +A new email task creates a workspace conversation. You can continue it in Chat. Replies linked to an earlier email task continue its conversation when that chat is still available in the same workspace; otherwise, processing starts a new conversation. -Each email task creates a conversation in your workspace. You can continue the conversation in Chat, and any follow-up emails in the same thread are linked to the same conversation. +## Related docs - +- [Files and documents in Chat](/chat/files) +- [Permissions](/platform/permissions) +- [Credentials](/platform/credentials) +- [Costs](/platform/costs) diff --git a/apps/docs/content/docs/chat/research.mdx b/apps/docs/content/docs/chat/research.mdx index 2bb0bab87b3..22ce24c42c0 100644 --- a/apps/docs/content/docs/chat/research.mdx +++ b/apps/docs/content/docs/chat/research.mdx @@ -1,43 +1,46 @@ --- title: Research -description: Ask Sim to research anything — it searches, reads, and synthesizes from the web. +description: Research web sources and save answers or cited reports from Chat. --- -import { Video } from '@/components/ui/video' -import { FAQ } from '@/components/ui/faq' +Ask Sim to investigate a topic, read a URL, or compare sources. Specify the question, time range, and output you need. Web research is available when the deployment provides the required search or page-reading tools. - +## Ask a research question [#asking-questions] -Ask Sim to research anything and it figures out the best approach — searching the web, reading specific pages, crawling sites, looking up technical docs. Just describe what you want to know. +Include enough scope to identify useful sources: -## Asking Questions +- "What did Salesforce, HubSpot, and Gong ship in the past 30 days? Cite the product updates." +- "Find Acme Corp's public tech stack information, recent hires, and open engineering roles." +- "Research [competitor]'s press, product changes, and job postings from the past 90 days." +- "Check Anthropic's API documentation for its current rate limits." +- "Read [URL] and explain what changed in this release." +- "Check Stripe's documentation for webhook retries and idempotency handling." +- "Compare the main providers of AI for revenue operations and explain their differences." -Ask anything — about a company, a competitor, a market, a technical question, or a specific URL: +Sim can search web sources, read pages, and look up technical documentation. It returns an answer in the chat; ask for a saved file when you need a longer deliverable. -- "What did Salesforce, HubSpot, and Gong each ship in the past 30 days? Summarize the key product updates." -- "What's Acme Corp's tech stack, recent hires, and open engineering roles?" -- "Find everything published about [competitor] in the past 90 days — press, product changes, job postings." -- "What are the current rate limits on the Anthropic API?" -- "Read [URL] and tell me what changed in this release" -- "What does Stripe's API say about handling webhooks with idempotency keys?" -- "Who are the main players in AI-powered revenue operations, and how do they differentiate?" +## Save a report [#research-reports] -Sim returns an answer directly in the chat. For anything that needs a longer written output, ask it to save the result as a file. +Name the comparison criteria, intended audience, and destination. For example: -## Research Reports +- "Compare 10 AI sales development tools on pricing, features, positioning, and customer feedback. Save a cited competitive analysis as ai-sales-tools.md." +- "Map AI in healthcare diagnostics: major providers, funding, use cases, and the regulatory context. Save a report with sources and open questions." +- "Research how our top five competitors handle multi-tenant authentication. Compare public architecture details, pricing, and documented vulnerabilities." +- "Find public case studies on AI agents in financial compliance from the past two years. Summarize the reported outcomes and save a Markdown report." +- "Create a battle card for [competitor] covering positioning, pricing, strengths, weaknesses, and our differentiators." -When you need a structured, saved document rather than a chat answer, ask Sim to write it up. Sim searches, reads, and cross-references multiple sources until it has enough to produce a full report. The output is saved as a file in your workspace and opened in the resource panel. +Ask for citations and for missing or conflicting evidence to be identified. Sim can combine the findings into a workspace file and open it in the resource panel. Find the saved report later in **Files**, or ask Sim to turn it into a presentation. -{/* TODO: Screenshot of a completed research report open in the resource panel as a file — showing a structured markdown document with sections, findings, and citations. */} +## Check source access and freshness -- "Research the top 10 AI SDR tools — pricing, features, positioning, and what customers say. Save as a competitive analysis." -- "Do a full market landscape for AI in healthcare diagnostics — major players, funding, use cases, and regulatory environment." -- "Research how our top 5 competitors handle multi-tenant auth — pricing, architecture, and any known vulnerabilities. Write it up as a report." -- "Find every public case study on AI agents in financial compliance from the past 2 years. Summarize the key outcomes and save as a markdown file." -- "Build a battle card for [competitor] — their positioning, pricing, strengths, weaknesses, and how we win against them." +Hosted web research reads publicly accessible pages. In Sim Desktop, the built-in browser can also work with websites you sign in to when browser tools are available. A link to a private page does not itself give Sim access. - +For connected organizational sources such as Slack or Google Drive, use [Search](/search) or ask Sim to inspect those sources under your current permissions. + +Check the cited source and publication date when freshness matters. Search results can be incomplete; a report should distinguish what the sources establish from what remains unknown. Request a specific site or documentation page when that source is required. + +## Related docs + +- [Files and documents in Chat](/chat/files) +- [Search](/search) +- [Sim Desktop](/desktop) diff --git a/apps/docs/content/docs/chat/tables.mdx b/apps/docs/content/docs/chat/tables.mdx index 9862fd7568c..18ec2ddae24 100644 --- a/apps/docs/content/docs/chat/tables.mdx +++ b/apps/docs/content/docs/chat/tables.mdx @@ -1,59 +1,82 @@ --- title: Tables -description: Create, query, and manage workspace tables from Chat. +description: Create tables, query or update rows, and export data from Chat. --- -import { Image } from '@/components/ui/image' -import { FAQ } from '@/components/ui/faq' +Ask Sim to create a workspace table, inspect its data, or change rows. Reference the table by name or with an `@`-mention. Tables can open in Chat's resource panel for review. -Chat resource panel showing the pipeline_deals table with company, deal_owner, stage, and amount columns, alongside a chat summary of total pipeline value and breakdown by stage +Table reads, writes, creation, and exports follow your workspace access and organization policy. Storage and row limits depend on the plan and deployment configuration. -Create a table from a description or a CSV, query it in plain language, add or update rows, and export the results — all through conversation. Tables open in the resource panel as soon as they're created or referenced. +## Create or import a table [#creating-tables] -## Creating Tables +Describe the columns and types, or attach a CSV for Sim to import: -Describe the schema and Sim creates the table: +- "Create a leads table with name, email, company, status, and created date columns." +- "Create a table matching this CSV." Attach the file. +- "Create an errors table with message and workflow text columns, a timestamp date column, and a resolved boolean." +- "Create a prospects table with company, domain, employee count, industry, fit score, and last contacted date." +- "Create an enrichment results table for email, company, title, LinkedIn URL, and fit score." -- "Create a leads table with columns for name, email, company, status, and created date" -- "Create a table that matches the structure of this CSV [attach file]" -- "Set up an errors table with: id (text), message (text), workflow (text), timestamp (date), resolved (boolean)" -- "Create a prospect table for outbound — company, domain, employee count, industry, ICP score, and last contacted date" -- "Set up an enrichment results table to store output from the lead enrichment workflow: email, company, title, LinkedIn URL, fit score" +Inspect the schema and imported rows before using the table in an agent. Specify unique or required columns when the data needs those constraints. -## Querying Data +## Query data [#querying-data] -Ask questions about table contents in plain language: +Name the table, fields, filters, and time range: -- "How many rows in the leads table have status 'qualified'?" -- "Show me all records from the past 7 days where score is above 0.8" -- "What are the top 5 most common error messages in the failures table?" -- "Are there any duplicate emails in the contacts table?" -- "How many prospects have an ICP score above 0.75 and haven't been contacted in the past 30 days?" -- "What's the conversion rate from 'contacted' to 'meeting booked' in the pipeline table this month?" +- "How many leads have status 'qualified'?" +- "Show leads from the past seven days with score above 0.8." +- "List the five most common error messages in the failures table." +- "Find duplicate emails in the contacts table." +- "Count prospects with a fit score above 0.75 that have not been contacted in the past 30 days." +- "Calculate conversion from 'contacted' to 'meeting booked' in this month's pipeline data." -Sim translates the question into a structured query and returns the results. +Sim can query the matching rows and compute summaries. It can also read multiple tables and combine their results: describe the relationship, such as matching `company_id` between contacts and companies. This does not create a persistent join between the tables. -## Adding and Updating Rows +Chat can mask tracked secret values or omit rows and selected cells it cannot safely check. Matching-row totals and pagination cursors still describe the database query; a shorter response does not prove that every match was shown. Summaries based on returned rows can be incomplete. -Add individual rows, bulk-update based on a condition, or delete records — all in plain language: +Large reads may need pagination or an export. Name the subset you need instead of requesting every row when a filter can answer the question. -- "Add a row to the leads table: Acme Corp, jane@acme.com, status pending" -- "Mark all rows in the queue table as processed where created_at is before today" -- "Update the price column for all rows where tier is 'pro' to 49" -- "Delete all rows in the test_events table" +## Add or update rows [#adding-and-updating-rows] -## Exporting +Provide values by column name. For bulk changes, state the condition: -Export a full table or a filtered subset as a CSV. The file is saved to your workspace and can be downloaded or referenced in other workflows: +- "Add a leads row with company=Acme Corp, email=jane@acme.com, and status=pending." +- "Mark queue rows as processed where createdAt is before today." +- "Set price to 49 for rows where tier is 'pro'." -- "Export the leads table to a CSV" -- "Export all rows where status is 'closed' and save as a file" +`createdAt` is the built-in creation timestamp. Use the actual custom column name when you mean a separate date field. -## Using Tables in Workflows +Review the affected records and ask Sim to verify the updated values. Table writes can also trigger configured workflow automation. -Tables created in Chat are immediately available in workflows via the [Table tool](/integrations/table). Reference a table by name — no additional configuration needed. +A write can be saved even when its returned row is withheld from Chat. Inspect the table before repeating a change whose result could not be shown. - +### Delete rows + +Deleting rows removes their stored data. Identify the table and condition before asking for a destructive action: + +- "Delete all rows in the test_events table." +- "Delete contacts with status 'test' from the contacts table." + +Removing rows does not undo external actions previously performed by workflows using them. + +## Export data [#exporting] + +Export the whole table or a filtered subset as CSV: + +- "Export the leads table as leads.csv in workspace Files." +- "Export pipeline rows where status is 'closed' and save them as closed-deals.csv." + +Wait for the export to complete, then inspect its row count and download the file. A CSV created from rows returned to Chat can omit rows unavailable to Chat. Use the table's own export control when you need an authorized export of the stored data. A saved workspace CSV can be referenced by other workflows. + +## Use a table in a workflow [#using-tables-in-workflows] + +Ask Sim to configure a Table block or tool with the intended table and operation, or select the table in the workflow builder. The table must be available to the workflow's execution context; naming it in Chat does not replace the block's configuration. + +For per-row enrichment, ask Sim to connect a deployed workflow to table columns so its outputs populate each row. See [workflow columns](/tables/workflow-columns) for dependencies and execution behavior. + +## Related docs + +- [Tables](/tables) +- [Using tables in workflows](/tables/using-in-workflows) +- [Table integration](/integrations/table) +- [Files and documents in Chat](/chat/files) diff --git a/apps/docs/content/docs/chat/tasks.mdx b/apps/docs/content/docs/chat/tasks.mdx index 324731b9d2a..c34d2105677 100644 --- a/apps/docs/content/docs/chat/tasks.mdx +++ b/apps/docs/content/docs/chat/tasks.mdx @@ -1,129 +1,125 @@ --- -title: Automation & configuration -description: Schedule recurring jobs, take immediate actions, connect integrations, and configure your workspace. +title: Actions and configuration +description: Call connected services, schedule workflows, and manage credentials, secrets, and tools from Chat. --- -import { Callout } from 'fumadocs-ui/components/callout' -import { Video } from '@/components/ui/video' -import { FAQ } from '@/components/ui/faq' +Ask Sim to take an action through a connected service or configure the resources a workflow needs. Immediate service calls, recurring workflows, and one-time follow-ups have different execution paths. - +## Take an immediate action [#taking-direct-action] -Sim can act on your behalf right now — send a message, create an issue, call an API — or on a schedule, running a prompt automatically every hour, day, or week. It can also connect integrations, set environment variables, add MCP servers, and create custom tools. +For a one-off request, name the service, target, account, and contents. Sim can call the service without building a workflow: -## Scheduled Jobs +| Request | Action | +| --- | --- | +| "Send a Slack message to #eng saying the deploy finished." | Post through the selected Slack connection | +| "Email q3-report.pdf to jane@example.com." | Send through an available Gmail or Outlook connection | +| "Create a GitHub issue in [repo]: auth tokens do not rotate on logout." | Create the issue in that repository | +| "Add Acme Corp and ceo@acme.com to HubSpot." | Create the CRM record | +| "Call the webhook at [URL] with this JSON: [payload]." | Make the HTTP request | -A scheduled job is a saved Chat prompt that runs on a cron schedule. On each run, Sim reads the current workspace state and executes the job's prompt as if you had just sent it. +Actions use credentials available to the acting member and remain subject to workspace access and organization policy. If the required account is not connected, complete the connection flow before the action can run. -### Creating a Job +Review any tool approval card. Choose **Allow** to run the action or **Skip** to decline it. Reuse choices under **Don't ask again** depend on policy. Check the returned result before assuming the external service changed. -Describe the recurring task and how often it should run: +An action can finish while Chat withholds its returned result. Check the connected service or affected resource before repeating an action whose result could not be shown. -- "Every morning at 8am, check the leads table for new entries and post a summary to #sales in Slack" -- "Every Monday at 9am, pull last week's workflow run counts and write a report to the workspace" -- "Run the data sync workflow every 6 hours" -- "On the first of every month, export the billing table to CSV and email it to finance@example.com" -- "Every weekday at 7am, check for new funding announcements from companies in our ICP and post the top 5 to #market-intel in Slack" -- "Every Sunday night, run the lead enrichment workflow on all prospects added in the past week and update their scores in the table" -- "Daily at 6am, pull the previous day's workflow errors, summarize the top issues, and post to #eng-alerts" +Undo behavior depends on the service. Some records can be edited or deleted afterward; deleting a Chat conversation does not undo a sent email or other external action. -Sim sets the cron expression and stores the job prompt. The first run happens at the next scheduled time. +## Set up recurring work [#scheduled-jobs] -### Viewing Job Logs +Recurring execution uses a workflow with a Schedule trigger. Describe the work, cadence, and timezone, then ask Sim to build or update the workflow and deploy it: -- "Show me the last 5 runs of the weekly report job" -- "Did the sync job run successfully this morning?" -- "What did the Monday digest job do last week?" +- "Every morning at 8am America/New_York, summarize new leads and post to #sales in Slack. Build and deploy the workflow." +- "Every Monday at 9am Europe/London, save a report of last week's workflow run counts." +- "Add an every-six-hours schedule to the data sync workflow and deploy it." +- "On the first of each month at 9am America/Los_Angeles, export the billing table to CSV and email it to finance@example.com." +- "Every weekday at 7am America/New_York, find new funding announcements for companies matching our ideal customer profile and post five to #market-intel." +- "Every Sunday at 10pm America/New_York, enrich prospects added in the past week and update their scores." +- "Daily at 6am UTC, summarize the previous day's workflow errors and post the main issues to #eng-alerts." -Logs show run time, status (completed, failed), and a summary of what the agent did. +A Schedule trigger stores the timing configuration, including its cron expression and timezone. The deployed workflow defines what each run does; it can include Agent blocks for reasoning. -### Managing Jobs +Test the workflow with representative inputs and review its external effects before deployment. Confirm that the intended version is active and its schedule is ready. Scheduled runs use the active deployed version; changing the draft does not change recurring execution until redeployment. -- "Pause the morning summary job" -- "Change the sync job to run every 3 hours instead of 6" -- "Delete the onboarding digest job" -- "What scheduled jobs are currently active?" +### Inspect scheduled runs [#viewing-job-logs] -## Taking Direct Action +Ask Sim to read the workflow's logs: -For requests that should happen right now — without building a workflow — just ask. Sim acts immediately using the credentials connected to your workspace. +- "Show the last five scheduled runs of the weekly report workflow." +- "Did the sync workflow's scheduled run succeed this morning?" +- "What did the Monday digest workflow produce last week?" -{/* TODO: Screenshot of Chat showing the "Taking action" subagent label active during a direct action — e.g., posting to Slack or sending an email. Shows the subagent inline in the chat thread. */} +Logs identify the execution time, status, block outputs, and errors. If nothing ran, ask Sim to check the deployment and Schedule trigger as well as the logs. -| Request | What happens | -|---------|-------------| -| "Send a Slack message to #eng that the deploy finished" | Posts to Slack immediately | -| "Email the Q3 report to jane@example.com" | Sends via connected Gmail or Outlook | -| "Create a GitHub issue: auth tokens not rotating on logout" | Opens an issue in the specified repo | -| "Add a contact to HubSpot: Acme Corp, ceo@acme.com" | Creates the contact via HubSpot API | -| "Call the webhook at [URL] with this JSON payload" | Makes the HTTP request | +### Change or stop recurring work [#managing-jobs] -If an integration isn't connected, Sim walks you through connecting it. +Name the workflow and trigger you want to change: -## Connecting Integrations +- "Change the sync workflow from every six hours to every three hours, then deploy the change." +- "Remove the morning summary workflow's Schedule trigger and deploy the change." +- "List workflows with active Schedule triggers." -Sim can connect new OAuth integrations and API credentials on demand: +To stop all deployed entry points, ask to undeploy the workflow. That affects its other deployment surfaces too; removing one Schedule trigger is more specific. Stopping future scheduled starts does not cancel an execution already running. See [Schedule triggers](/workflows/triggers/schedule) for setup, disabled schedules, and self-hosted scheduler requirements. -- "Connect my Google account" -- "Add the Slack workspace for our team" -- "Set up GitHub with my personal access token" +## Follow up later -{/* TODO: Screenshot of Sim walking through connecting an integration — e.g., the Integration subagent active with an OAuth prompt or confirmation that a credential was connected. */} +Chat can watch a background workflow execution and continue when it finishes, or set a one-time timer for up to 24 hours: -Once connected, Sim can use the account for authorized actions. Configure a workflow to use the intended available credential. +- "Run the deployed invoice sync in the background and tell me when it finishes." +- "Remind me in 45 minutes to check the import results." - - Select the intended account when configuring each integration. Which credentials are available depends on their ownership, sharing settings, and workspace policy. See [credentials](/platform/credentials). - +Ask about the recorded status or stop a pending follow-up in the same chat. Stopping a watch cancels its notification; it does not cancel the workflow execution. Request workflow cancellation separately when that is what you intend. Timers are one-time follow-ups, not recurring schedules. -See [Credentials](/platform/credentials) for managing connected accounts. +## Connect an integration [#connecting-integrations] -## Environment Variables +Ask Sim to start the connection flow for the service you need: -Save API keys, connection strings, and configuration under **Secrets**, then reference them with `{{ENV_VAR}}`. Choose personal or workspace scope according to who should use the value. See [secrets](/workflows/variables#environment-variables). +- "Connect my Google account for Gmail." +- "Connect the Slack workspace for our team." +- "Set up GitHub with my personal access token." -- "Set the DATABASE_URL environment variable to 'postgres://...'" -- "Add an OPENAI_API_KEY environment variable" -- "Add a WEBHOOK_SECRET variable for the inbound webhook workflow" -- "Update the SCORING_API_URL variable to point to the new endpoint" -- "What environment variables are currently set?" +Complete OAuth authorization or enter the credential in the provided secure control. A Google connection for one service does not automatically authorize every Google service. -{/* TODO: Screenshot of Sim confirming an environment variable was set — e.g., a response message showing the variable name was saved. */} +Select the intended account for each action or workflow block. Available credentials depend on ownership, sharing, and workspace policy. Ask "Which integrations are connected?" or inspect **Integrations** to identify existing connections. -## MCP Servers +## Manage secrets [#environment-variables] -MCP (Model Context Protocol) servers expose tools from external services that Agent blocks can call inside workflows. Connecting an MCP server makes all of its tools available in the workflow editor's tool picker — no custom integration code required. +Save API keys, connection strings, and configuration under **Secrets**. Choose personal or workspace scope according to the intended execution and access: -Sim can add and manage MCP servers connected to your workspace: +- "Add an OPENAI_API_KEY secret for this workspace." +- "Set a personal DATABASE_URL connection string." +- "Add WEBHOOK_SECRET for the inbound webhook workflow." +- "Update SCORING_API_URL to [endpoint]." +- "List the configured environment variable names." -- "Add the Stripe MCP server using my API key" -- "Remove the old analytics MCP server" -- "What MCP servers are connected to this workspace?" -- "Update the endpoint for the internal tools MCP server to [URL]" +Provide secret values through the secure input when requested. Workflows reference environment variables with `{{ENV_VAR}}`; resolution depends on scope, grants, and execution context. See [workflow variables and secrets](/workflows/variables#environment-variables) for those rules. -Once added, MCP tools appear in the workflow editor's tool picker and can be called from any Agent block. +## Add an MCP server [#mcp-servers] -{/* TODO: Screenshot of Sim confirming an MCP server was added or updated — showing the server name and its status. */} +An MCP (Model Context Protocol) server exposes tools from another service. Ask Sim to add or manage an external server: -## Custom Tools +- "Add the internal tools MCP server at [URL] using its API key." +- "Update that server's endpoint to [URL]." +- "List the MCP servers connected to this workspace." +- "Remove the old analytics MCP server." -[Custom tools](/agents/custom-tools) combine a JSON parameter schema with a JavaScript function body. Use one for an internal API call, calculation, or reusable transformation, then add it to an Agent block's tools. +Available, permitted tools can be selected for Agent blocks in the workflow builder. To use a server's tools directly in Chat, attach the server to the conversation. Server connection, tool discovery, and policy must permit the operation. -Sim can build custom tools from a description: +## Create a custom tool [#custom-tools] -- "Create a custom tool that calls our internal scoring API at [URL] with a POST request and returns the score field" -- "Build a tool for our Zendesk instance that creates a ticket with a subject and body" -- "Create a tool that hits our internal enrichment API with a domain and returns company size, industry, and funding stage" -- "Add a tool that calls our CRM's REST API to look up a contact by email and return their account owner" +A custom tool combines a JSON parameter schema with a JavaScript function body. Describe its inputs, service call or calculation, and returned value: +- "Create a tool that POSTs to our scoring API at [URL] and returns the score field." +- "Create a Zendesk tool that opens a ticket with a subject and body." +- "Create an enrichment tool that takes a domain and returns company size, industry, and funding stage." +- "Create a CRM tool that looks up a contact by email and returns the account owner." +Add the resulting tool to an Agent block's tools and configure the credentials it needs. Verify it with an input appropriate for its external effects. -{/* TODO: Screenshot of Chat with the Custom Tool subagent active — showing it building a tool definition. */} +## Related docs - +- [Schedule triggers](/workflows/triggers/schedule) +- [Workflows in Chat](/chat/workflows) +- [Credentials](/platform/credentials) +- [MCP servers for agents](/agents/mcp) +- [Custom tools](/agents/custom-tools) diff --git a/apps/docs/content/docs/chat/workflows.mdx b/apps/docs/content/docs/chat/workflows.mdx index ec95fa219f2..c3e616e856f 100644 --- a/apps/docs/content/docs/chat/workflows.mdx +++ b/apps/docs/content/docs/chat/workflows.mdx @@ -1,116 +1,117 @@ --- title: Workflows -description: Create, edit, run, debug, deploy, and organize workflows from Chat. +description: Create, edit, run, debug, and deploy workflows from Chat. --- -import { Video } from '@/components/ui/video' -import { FAQ } from '@/components/ui/faq' +Ask Sim to build a workflow or change an existing one. Open the workflow in Chat's resource panel to inspect the result in the workflow builder. Creation, editing, execution, and deployment require the relevant workspace access. - +## Create a workflow [#creating-workflows] -Describe a workflow and Sim builds it. Reference an existing one by name and Sim edits it. No canvas navigation required — every change appears in the resource panel in real time. +Describe the trigger, inputs, processing steps, integrations, and expected output. For example: -## Creating Workflows +- "Build a workflow that takes a URL, reads the page, summarizes it with Claude, and sends the summary to a Slack channel." +- "Create a webhook workflow that extracts invoice data from a PDF and writes it to the billing table." +- "Build an outbound workflow: enrich a company name and domain, score the fit, and draft a personalized email." +- "Create a lead enrichment workflow that takes an email from a form submission, looks up the company, and writes the enriched record to the leads table." +- "When a new customer signs up, send a welcome email, create a HubSpot contact, and notify #new-customers in Slack." -Describe what the workflow should do — what triggers it, what it should do, which integrations it needs, and what it should return. Sim builds it and opens the canvas in the resource panel. +Sim can create the blocks and connections and help configure the required accounts. Inspect the workflow and resolve any missing credentials or inputs before running it. -- "Build a workflow that takes a URL, scrapes the page, summarizes it with Claude, and sends the summary to a Slack channel" -- "Create a workflow triggered by a webhook that extracts invoice data from a PDF and writes it to the billing table" -- "Build an outbound workflow: take a company name and domain, enrich it with firmographic data, score the fit, and draft a personalized cold email" -- "Create a lead enrichment workflow that takes an email from a form submission, looks up the company, and writes the enriched record to the leads table" -- "Build a customer onboarding workflow: when a new user signs up, send a welcome email, create a HubSpot contact, and post a notification to #new-customers in Slack" +## Edit the draft [#editing-workflows] -## Editing Workflows +Open the workflow with an `@`-mention or the **+** menu, then name the change: -{/* TODO: Screenshot of Chat with the Edit subagent active and a change applied to an open workflow — e.g., a new block added or a configuration updated, visible on the canvas in the resource panel. */} +- "Add a branch for confidence scores below 0.7." +- "Replace GPT-4o with Claude Opus 5 on the summarizer block." +- "Add a Slack notification containing the final output." -Open an existing workflow with `@workflow-name` or the **+** menu, then describe the change. Sim reads the current structure before modifying it — you don't need to explain what already exists. +Sim reads the existing structure before applying changes. Editing a deployed workflow changes its draft; the active deployment remains a snapshot until you successfully redeploy or activate another version. -- "Add a condition that routes to a different branch if the confidence score is below 0.7" -- "Replace the GPT-4o model with Claude Opus 5 on the summarizer block" -- "Add a Slack notification at the end that includes the output" +### Workflow variables -## Running Workflows +Workflow variables hold values available across that workflow's blocks at runtime: - +- "Set API_ENDPOINT on the sync workflow to 'https://api.example.com/v2'." +- "Set MAX_RETRIES on the pipeline workflow to 5." -Ask Sim to run a workflow and it handles the execution: +Reference them with ``. These are workflow values, distinct from personal or workspace secrets referenced with `{{ENV_VAR}}`. -- "Run the data sync workflow" -- "Run the invoice processor with this PDF [attach file]" -- "Test the lead scoring workflow with these inputs: name=Acme, score=0.4" +## Run a workflow [#running-workflows] -Execution streams back to the chat. The workflow in the resource panel shows live block-by-block state. +Specify whether you want to test the draft or run the deployed version, and provide the Start block's inputs: -## Reading Logs +- "Run the deployed data sync workflow." +- "Test the invoice processor draft with this PDF." Attach the file. +- "Test the lead scoring draft with name=Acme and score=0.4." -Sim can retrieve and interpret execution logs for any workflow in the workspace: +A live run in the workflow builder shows block-by-block progress. Background runs can be checked through their execution logs. Ask Sim for the outcome and the execution to inspect when a run finishes. -- "Show me the last 10 runs of the pipeline workflow" +Test runs can send messages, call APIs, and change data through connected services. Use inputs and accounts appropriate for those effects, and review any required tool approval before the run. + +## Read logs [#reading-logs] + +Ask about executions you can access: + +- "Show the last 10 runs of the pipeline workflow." - "Why did the invoice workflow fail yesterday?" - "What did the extractor block return in the most recent run?" -Logs include per-block execution state, outputs, errors, and timing. - -## Debugging +Logs include block execution state, outputs, errors, and timing. Name the workflow and run or time range so Sim can inspect the intended execution. -When a workflow fails, tell Sim to debug it: +### Debug a failure [#debugging] -- "Debug the last failed run of the content pipeline" -- "The summarizer block is returning empty output — figure out why" +Ask Sim to investigate and, when appropriate, fix the draft: -Sim reads the failure logs, identifies the cause, applies a fix, and can re-run to confirm. +- "Debug the last failed run of the content pipeline and test the fix." +- "The summarizer block returns empty output. Check its inputs and the last run's logs." -{/* TODO: Screenshot of the Debug subagent section in Chat showing it reading logs and applying a fix. */} +Inspect the proposed change and the verification result. A successful draft test does not update the deployed workflow. -## Deploying +## Deploy a workflow [#deploying] -Sim can deploy a workflow as any of the three deployment types: +Choose the interface callers need: -| Deployment type | What it creates | -|----------------|----------------| -| **API** | A REST endpoint at `https://www.sim.ai/api/v2/workflows/{id}/execute` | -| **Chat** | A hosted conversational interface with a shareable URL | -| **MCP tool** | An MCP server that exposes the workflow as a tool | +| Interface | Result | +| --- | --- | +| API | An execution endpoint at `/api/v2/workflows/{id}/execute` on your deployment's configured host | +| Chat | A conversational interface with a shareable URL and configured access settings | +| MCP tool | The workflow added as a tool on a workflow MCP server | -Ask: "Deploy the invoice workflow as an API and generate an API key." +For example: "Deploy the invoice workflow as an API and generate an API key." -Sim can also roll back: "Revert the billing workflow to the version from last Tuesday." +Review the returned deployment status and URL. A pending or failed deployment attempt does not prove the requested version is serving. API keys are shown once in a secure copy control; copy a new key when it is created. -See [API Deployment](/workflows/deployment/api) and [Chat Deployment](/workflows/deployment/chat) for full details on each deployment type. +Sim can also help configure reusable [custom blocks](/platform/enterprise/custom-blocks) where available. These appear in the workflow builder rather than creating another external endpoint. -## Organizing Workflows +### Restore or roll back a version -Sim can create and manage folders to keep your workspace organized. +Be explicit about the state you want to change: -**Folders:** -- "Create a folder called 'Data Pipelines'" -- "Move the invoice workflow into the billing folder" -- "Move the billing folder inside the finance folder" -- "Delete the old-experiments folder" +- "Restore last Tuesday's version of the billing workflow into the draft." +- "Roll the billing workflow's live deployment back to version 3." -**Renaming and moving:** -- "Rename the 'test_v2' workflow to 'lead-scorer'" -- "Move the summarizer workflow to the research folder" +Restoring the draft does not change what callers run. Rolling back the active deployment changes the serving version and leaves the draft separate. -{/* TODO: Screenshot showing Sim confirming a folder or workflow organization action — e.g., a message confirming "Moved 'invoice-processor' into 'billing' folder" with the resource panel showing the folder open. */} +## Organize workflows [#organizing-workflows] -## Workflow Variables +Ask Sim to create folders, move workflows or folders, and rename workflows: -Sim can set global variables on a workflow — values accessible across all blocks in that workflow at runtime: +- "Create a folder called 'Data Pipelines' and move the sync workflow into it." +- "Move the billing folder inside the finance folder." +- "Rename 'test_v2' to 'lead-scorer' and move it to the research folder." -- "Set the API_ENDPOINT variable on the sync workflow to 'https://api.example.com/v2'" -- "Update the MAX_RETRIES variable on the pipeline workflow to 5" +## Delete workflows [#deleting-workflows] -Variables set this way are available via `` syntax inside any block in the workflow. +Deleting a workflow removes it from the active workspace and disables its deployments. Its API, chat, and MCP entry points stop working. Identify the exact workflows or folder contents before deleting them: -## Deleting Workflows +- "Delete the old_api_prototype workflow." +- "Delete all workflows in the deprecated folder." +- "Delete the old-experiments folder and its contents." -- "Delete the old_api_prototype workflow" -- "Delete all workflows in the deprecated folder" +## Related docs - +- [Workflow variables](/workflows/variables) +- [API deployment](/workflows/deployment/api) +- [Chat deployment](/workflows/deployment/chat) +- [MCP deployment](/workflows/deployment/mcp) +- [Logs and debugging](/logs-debugging) diff --git a/apps/docs/content/docs/cli/audit-logs.mdx b/apps/docs/content/docs/cli/audit-logs.mdx index a03c7a7c136..688d5e6c240 100644 --- a/apps/docs/content/docs/cli/audit-logs.mdx +++ b/apps/docs/content/docs/cli/audit-logs.mdx @@ -1,22 +1,57 @@ --- -title: Audit Logs -description: Manage audit logs — every subcommand, argument, and flag +title: Audit logs +description: Read organization audit actions and filter by actor, resource, workspace, or time. --- import { CommandTable } from '@/components/ui/command-table' +Read organization audit actions and filter by actor, resource, workspace, or time. + +Requires an organization Admin or owner, an OAuth login or personal API key, and enabled enterprise audit access for the deployment. + `sim audit-logs` is also spelled `sim audit-log`. -Every command below also accepts the [global options](/cli/commands#global-options). +These commands accept the [global options](/cli/commands#global-options). + +## List audit logs + +OAuth login or personal API key required. + +```bash +sim audit-logs list [options] +``` + +**Options** + + + +| Option | Required | Description | +| --- | --- | --- | +| `--action ` | No | Filter by exact action name. | +| `--resource-type ` | No | Filter by resource type. Accepts a comma-separated set; members are trimmed and deduplicated, and member order affects neither the result nor the cursor. | +| `--resource-id ` | No | Filter by exact resource identifier. | +| `--start-date ` | No | Include audit entries created at or after this UTC ISO 8601 timestamp, such as `2026-08-06T00:00:00Z`. Dates without a time, timestamps with an offset instead of `Z`, and year `0000` are rejected. | +| `--end-date ` | No | Include audit entries created at or before this UTC ISO 8601 timestamp, such as `2026-08-06T00:00:00Z`. Dates without a time, timestamps with an offset instead of `Z`, and year `0000` are rejected. | +| `--include-departed` | No | Include actions by users who have left the organization. | +| `--no-include-departed` | No | Send --include-departed as false. | +| `--limit ` | No | Maximum items to return (0 for everything). Defaults to `100`. | +| `--cursor ` | No | Continue from nextCursor returned by a previous result. | +| `--organization ` | No | Organization whose audit trail to read; defaults to the caller’s organization. A caller that belongs to no organization, or names one it does not belong to, is refused with 403. | +| `--actor-email ` | No | Filter by actor email address. | +| `--all-workspaces` | No | Do not filter to the configured workspace (OAuth login or personal API key required for account-wide access). | + + + +API request and response schemas: [listAuditLogs](/api-reference/audit-logs/listAuditLogs). ## Get audit log +OAuth login or personal API key required. + ```bash sim audit-logs get [options] ``` -Get Audit Log (OAuth login or personal API key required) - **Arguments** @@ -33,35 +68,13 @@ Get Audit Log (OAuth login or personal API key required) | Option | Required | Description | | --- | --- | --- | -| `--organization ` | No | Organization ID; defaults to your only organization, and is required when your account belongs to more than one (OAuth login or personal API key required). | +| `--organization ` | No | Organization whose audit trail to read; defaults to the caller’s organization. A caller that belongs to no organization, or names one it does not belong to, is refused with 403. | -## List audit logs - -```bash -sim audit-logs list [options] -``` - -List Audit Logs (OAuth login or personal API key required) - -**Options** - - +API request and response schemas: [getAuditLog](/api-reference/audit-logs/getAuditLog). -| Option | Required | Description | -| --- | --- | --- | -| `--action ` | No | Filter by exact action name. | -| `--resource-type ` | No | Filter by resource type. Accepts a comma-separated set; members are trimmed and deduplicated, and member order affects neither the result nor the cursor. | -| `--resource-id ` | No | Filter by exact resource identifier. | -| `--start-date ` | No | Only include runs started at or after this UTC ISO 8601 timestamp, e.g. `2026-08-06T00:00:00Z`. A date without a time, or a timestamp carrying a UTC offset instead of `Z`, is rejected, as is year `0000`, which names no storable instant. | -| `--end-date ` | No | Only include runs started at or before this UTC ISO 8601 timestamp, e.g. `2026-08-06T00:00:00Z`. A date without a time, or a timestamp carrying a UTC offset instead of `Z`, is rejected, as is year `0000`, which names no storable instant. | -| `--include-departed` | No | Include actions by users who have left the organization. | -| `--no-include-departed` | No | Send --include-departed as false. | -| `--limit ` | No | Maximum items to return (0 for everything). Defaults to `100`. | -| `--cursor ` | No | Continue from nextCursor returned by a previous result. | -| `--organization ` | No | Organization ID; defaults to your only organization, and is required when your account belongs to more than one (OAuth login or personal API key required). | -| `--actor-email ` | No | Filter by actor email address. | -| `--all-workspaces` | No | Do not filter to the configured workspace (OAuth login or personal API key required for account-wide access). | +## Related docs - +- [Organization permissions](/platform/permissions) +- [Authentication](/cli/authentication) diff --git a/apps/docs/content/docs/cli/authentication.mdx b/apps/docs/content/docs/cli/authentication.mdx index e9c8afb91f1..e4d0cabf6dd 100644 --- a/apps/docs/content/docs/cli/authentication.mdx +++ b/apps/docs/content/docs/cli/authentication.mdx @@ -1,20 +1,11 @@ --- title: Authentication -description: Sign in from the terminal, authenticate CI with an API key, and keep several accounts side by side +description: Sign in locally, authenticate CI, and share a login across workspace profiles. --- import { Callout } from 'fumadocs-ui/components/callout' - -These settings apply to the CLI you install locally. When Sim runs a `sim` -command for you inside Chat, it uses your session identity — there is no profile, -no `sim login`, and no config file. - - -`sim login` signs you in through your browser. It prefers OAuth, which stores a -short-lived login that renews itself, and selects API-key pairing for remote -terminals or servers without OAuth support. In CI you supply an existing API -key through the environment instead. +Use `sim login` for a stored browser-approved login, or supply an existing API key for CI. These settings apply to the installed CLI. Commands Sim runs inside Chat use your session identity; local login and profile-management commands are unavailable. See [Configuration](/cli/configuration) for that boundary. ## Signing in @@ -22,28 +13,28 @@ key through the environment instead. sim login ``` -Choose a method explicitly when the credential type matters: +The CLI prefers OAuth on a local machine. SSH sessions and headless Linux terminals select API-key pairing; a server without OAuth also selects pairing when no method is specified. An unreachable server is an error, not a reason to fall back. + +| Method | Credential and requirements | +| --- | --- | +| OAuth | Short-lived access token with automatic renewal; requires server OAuth and a browser that can reach the CLI's loopback callback | +| API-key pairing | Permanent personal API key; approval can happen on another device, and the server must support `platform` API-key pairing | +| Existing API key | Supply `SIM_API_KEY`; no browser or stored login is required | + +Choose the method explicitly when the credential type matters: ```bash sim login --method oauth sim login --method api-key ``` -`--method oauth` requires a server with OAuth support and authentication enabled; -it never falls back to an API key. Explicit OAuth selection also overrides -SSH/headless detection; your browser still needs to reach the CLI's -local callback. `--method api-key` uses pairing-code approval to create a new -permanent API key. To supply an existing key, set `SIM_API_KEY` instead. +Explicit OAuth never falls back and overrides remote-session detection. Pairing creates a new key; use `SIM_API_KEY` to supply one you already have. Older deployments that issue only `copilot` keys must be upgraded: those keys cannot authenticate the platform CLI. OAuth discovery does not verify pairing compatibility. -API-key pairing requires a server that supports `platform` API keys. Upgrade -older deployments that only issue `copilot` keys before starting login; those -keys cannot authenticate the platform CLI. +### OAuth approval -OAuth login opens your browser on Sim's sign-in page, then on a consent page that -names the Sim CLI and what it will be able to do. Approve, and the browser hands -control back to the terminal: +The CLI opens Sim's sign-in page and then a consent page naming the Sim CLI and its requested access. Approve the request to return control to the terminal: -``` +```text Signing in to https://www.sim.ai as profile default https://www.sim.ai/api/auth/oauth2/authorize?client_id=sim-cli&… @@ -55,41 +46,35 @@ Waiting for you to approve in the browser… No default workspace. Set one with: sim configure --set-workspace ``` -This is the OAuth 2.0 authorization-code flow with PKCE and a loopback redirect, -aligned with current OAuth security guidance. The browser only ever carries a one-time code; -the tokens are exchanged over the terminal's own connection and written to -`~/.sim/credentials` with `0600` permissions. Access tokens last an hour and are -renewed automatically from a refresh token. The complete login has a fixed -30-day lifetime; after it expires, run `sim logout`, then sign in again. +The login uses an authorization code, Proof Key for Code Exchange (PKCE), and a loopback redirect. The browser returns a one-time code; the terminal exchanges it for tokens over its own connection. Tokens are stored in `~/.sim/credentials` with `0600` permissions. + +Access tokens last one hour. The refresh-token family has a fixed 30-day lifetime; renewal does not extend it. After expiry, log out and sign in again. -Only approve a consent page you reached by running `sim login` yourself. A -consent page that appears unprompted, or one you were sent a link to, is not -your login. +Only approve a consent request you reached by running `sim login` yourself. An unprompted consent page or a link sent by someone else does not belong to your login. -| Option | What it does | +| Option | Behavior | | --- | --- | -| `--method ` | `oauth` requires OAuth login; `api-key` creates a permanent key through pairing. Auto-selects when omitted | +| `--method ` | Choose `oauth` or `api-key`; auto-select when omitted | | `--no-browser` | Print the approval URL without opening it; works with either method | -| `--read-only` | Ask only for permission to read, never to change anything | -| `--callback-port ` | Pin the loopback callback port, primarily for an SSH session that forwards the same fixed port | -| `-y, --yes` | Overwrite an existing API-key profile without prompting | +| `--read-only` | Request OAuth read access; pairing cannot issue this credential | +| `--callback-port ` | Pin the OAuth loopback port, from 1 to 65535, for example for an SSH tunnel | +| `-y, --yes` | Confirm overwriting an existing stored API key | + +A profile holds one stored credential. Replacing an API key requires confirmation or `--yes`. An existing OAuth login must be revoked with `sim logout` before another login; `--yes` does not bypass this. ### Over SSH or in a container -OAuth login needs your browser to reach a listener on the machine running -`sim`. When it cannot — an SSH session, a dev container, a remote box — use the -API-key pairing flow. The CLI selects it automatically in an SSH session when -no method or callback port is specified: +OAuth needs the browser to reach a listener on the machine running `sim`. Use pairing when that connection is unavailable: ```bash sim login --method api-key --no-browser ``` -The terminal prints a pairing code and a URL you can open on any device: +The terminal prints a code and an approval URL you can open on another device: -``` +```text Signing in to https://www.sim.ai as profile default Pairing code: K7M2-P9XT @@ -103,30 +88,24 @@ Waiting for approval… ``` -Confirm the pairing code in the browser matches the one in your terminal before -approving. That check is what binds the approval to your terminal. +Compare the pairing code in the browser with your terminal before approving. This binds the approval to your terminal. Pairing creates a permanent personal key; revoke it in **Settings → Sim API keys** when you no longer need it. -The handoff issues a permanent personal API key rather than a renewing login, -so revoke it under **Settings → API keys** when you are done with that machine. -It also works when OAuth is unavailable or switched off, provided the server -supports platform API-key pairing. When `--method` is omitted, the CLI checks -OAuth availability and selects pairing if unavailable; that discovery does not -verify pairing compatibility. An explicit `--method oauth` fails in that case. - -`--read-only` and `--callback-port` belong to OAuth login and have no -meaning here, so combining either with the handoff stops the login rather than -storing a credential you did not ask for. If your SSH session forwards a port -from the remote loopback interface to the browser's machine, use -`--method oauth --callback-port ` with that port. An ordinary container port publication -cannot reach a listener bound to the container's own loopback interface; use -`--method api-key` there. +`--read-only` and `--callback-port` are OAuth-only. Combining either with pairing stops login instead of silently ignoring the option. + +For an SSH tunnel that forwards the remote loopback port to your browser's machine, choose OAuth and specify that same port: + +```bash +sim login --method oauth --callback-port 8765 --no-browser +``` + +Supplying a callback port also overrides automatic SSH detection. An ordinary container port publication cannot reach a listener bound to the container's own loopback interface; use pairing there unless you provide a working loopback route. ### Picking a workspace -A normal login can act across every workspace you belong to; `--read-only` -limits it to read operations. The profile's `workspace` setting only decides the default target. -Set it after signing in, or pass `--workspace` per command: +A personal login can act in accessible workspaces, subject to current roles, policies, and resource access. `--read-only` narrows OAuth scope; a default workspace only selects a target and does not narrow credential scope. + +After OAuth login, select a default or pass a workspace per command: ```bash sim workspaces list @@ -134,66 +113,39 @@ sim configure --set-workspace 2f6d0b1c-8a34-4d92-b7e5-31c8a0f45d67 sim workflows list --workspace 9b4c7e02-1d58-4f36-a0c9-6e2b85df413a ``` -With the pairing-code handoff you choose the default workspace on the approval -page instead. +Pairing sets the default workspace chosen on the approval page. -To target another workspace without a second login, add a workspace profile: +To reuse a stored login with another default workspace: ```bash sim profile add acme --workspace 7e2d9c14-6b83-4a55-8f01-c4d3e9a76b28 sim --profile acme whoami ``` -The new profile stores `auth_profile = default` and its own workspace. Omit -`--workspace` in an interactive terminal to choose from the workspaces your -login can access; scripts must provide the workspace ID explicitly. The picker -is capped at 1,000 entries and asks for an explicit ID above that. +The new profile references the active authentication profile through `auth_profile` and stores its own workspace. With the default login active, that reference is `auth_profile = default`. + +Omit `--workspace` in an interactive terminal to choose an accessible workspace. The picker is capped at 1,000 entries; scripts and larger inventories require an explicit ID. See [Configuration](/cli/configuration) for profile resolution. ## Checking who you are ```bash -sim whoami # resolved settings, plus a live check that they work -sim whoami --no-verify # resolved settings only, no request +sim whoami +sim whoami --no-verify ``` -Prints the resolved endpoint, workspace, and output format, which source each -value came from, and whether the profile holds an OAuth login or an API key, -then reads the configured workspace to prove the credential is accepted and can -reach it. - -It exits `0` when the check passes, `1` when the credentials are wrong, and `2` -when the check could not be made at all — no workspace to check against, or an -endpoint that did not answer. The split matters in CI: only `1` is fixed by -logging in again. - -## Signing out - -```bash -sim logout # sign out of Sim and remove the stored login -sim logout --all # remove the profile entirely, including its settings -``` +`whoami` reports the endpoint, credential type, workspace, output format, and where each setting came from. It checks authentication through API metadata when available, then reads the selected workspace to verify access. Older servers can fall back to the workspace check. -For an OAuth login, `sim logout` revokes that login's complete token family -before removing it from disk, including access tokens issued before earlier -rotations. Other machines that ran their own `sim login` remain signed in. To -cut off every independent login for the client, revoke the grant under -**Settings → General → Authorized apps**. +| Exit code | Meaning | +| --- | --- | +| `0` | Verification succeeded, or `--no-verify` skipped it | +| `1` | Missing credentials or a definitive refusal, including inaccessible or missing workspace | +| `2` | Verification could not finish, including no selected workspace or an unreachable endpoint | -A workspace profile that shares authentication cannot remove the shared login. -Remove only that local profile with `sim logout --all --profile `, or log -out of the authentication profile named by the error message. Removing an -authentication profile entirely is refused until its workspace profiles are -removed, so it cannot leave dangling references. - - -For a login created with `--method api-key`, `sim logout` removes the API key from -disk but does **not** revoke it. Revoke keys under **Settings → API keys**. - +For exit 1, inspect the endpoint and workspace before signing in again. A valid login cannot fix a wrong workspace or missing permission. Use `--no-verify` for offline inspection. ## Authenticating CI -Set an API key and workspace in the environment; no saved login is required, -and the environment key overrides any stored login: +Create a key under **Settings → Sim API keys**, then store it in your CI secret manager. Supply the key and workspace without running login: ```bash export SIM_API_KEY="sim_…" @@ -202,14 +154,12 @@ export SIM_WORKSPACE="2f6d0b1c-8a34-4d92-b7e5-31c8a0f45d67" sim workflows run 3a9e21d8-5f47-4c0b-b2ea-91d7c6034ef8 --input '{"source":"nightly"}' --output json ``` -Create the key in Sim under **Settings → Sim API keys**. Store it as a secret in your -CI provider — never commit it. - -`SIM_CONFIG_DIR` relocates both files if you need them somewhere other than -`~/.sim`, such as a runner with no writable home directory. +The environment key overrides stored authentication. Use a workspace key only for supported workspace-scoped operations; organization audit logs and fork administration require a personal credential. Never commit credentials. `SIM_CONFIG_DIR` relocates local state when a runner has no writable home directory. ### GitHub Actions +This job installs Node for the CLI and Bun to install the package. Add it to a workflow with your chosen trigger: + ```yaml title=".github/workflows/nightly.yml" jobs: digest: @@ -218,16 +168,19 @@ jobs: - uses: actions/setup-node@v4 with: node-version: '20' - - run: npm install -g sim + - uses: oven-sh/setup-bun@v2 + - run: bun add -g sim - run: sim workflows run 3a9e21d8-5f47-4c0b-b2ea-91d7c6034ef8 --output json env: SIM_API_KEY: ${{ secrets.SIM_API_KEY }} SIM_WORKSPACE: ${{ vars.SIM_WORKSPACE }} ``` +See [Scripting](/cli/scripting) for asynchronous runs and command-specific failure handling. + ## Several accounts and workspaces -Use separate logins for separate identities or deployments: +Use separate authentication profiles for different identities or deployments: ```bash sim login --profile dev --endpoint http://localhost:3000 @@ -237,7 +190,7 @@ sim workflows list --profile dev sim workflows list --profile prod ``` -Use workspace profiles when one login should target several workspaces: +Use shared workspace profiles when the same stored identity targets several workspaces: ```bash sim profile add marketing --workspace c3a70e58-9f21-4d6b-b842-05e7f19c6a3d @@ -247,33 +200,29 @@ sim workflows list --profile marketing sim workflows list --profile support ``` -See [Configuration](/cli/configuration) for how profiles are stored and resolved. +Shared profiles retain separate workspace/output settings but share an endpoint and stored login. References are direct, never chained. Log in against the authentication profile rather than a profile that shares it. ## Self-hosted and non-production deployments -Point the CLI at any deployment with `--endpoint`, then sign in against it: +Use HTTPS for remote sign-in. Both OAuth and pairing refuse non-loopback HTTP endpoints. Loopback development addresses can use HTTP: ```bash sim login --profile local --endpoint http://localhost:3000 ``` -Save it to avoid repeating the flag: +Login saves the endpoint. You can also configure it before signing in: ```bash sim configure --set-endpoint http://localhost:3000 --profile local ``` -OAuth sign-in is available by default when server authentication is enabled. -`DISABLE_AUTH=true` disables OAuth. Servers without OAuth use the pairing-code -handoff when they support platform API keys. See -[Sign in with Sim](/platform/self-hosting/authentication#sign-in-with-sim) for -server configuration and upgrade requirements. +An OAuth login belongs to its issuing deployment. Log out before changing or removing that endpoint. API keys must also belong to the selected deployment. + +OAuth is available by default when server authentication is enabled. `DISABLE_AUTH=true` disables OAuth. Servers without OAuth can use pairing if they support platform API keys. See [Sign in with Sim](/platform/self-hosting/authentication#sign-in-with-sim) for server setup and upgrade requirements. ## Where the login is stored -Logins live in `~/.sim/credentials`, written `0600`, separate from the non-secret -`~/.sim/config`. Commit `config` to a dotfiles repo if you like; never -`credentials`. +Stored authentication lives in `~/.sim/credentials`, written `0600`. Non-secret defaults live separately in `~/.sim/config`. Never copy credentials into a dotfiles repository: ```ini title="~/.sim/credentials" [default] @@ -288,20 +237,41 @@ oauth_scope = offline_access api:read api:write api_key = sim_… ``` -A profile holds one login. A stored API key can be replaced after confirmation -or with `--yes`; a live OAuth login must be revoked with `sim logout` before -signing in again. Several `sim` commands running at once share one renewal, so -a parallel shell loop cannot sign itself out. +Concurrent local commands coordinate OAuth renewal through the credentials lock. A process rereads credentials after taking the lock and adopts an already-renewed token instead of reusing the old refresh token. -Run `sim login` separately on each machine. Copying `~/.sim/credentials` copies -one single-use refresh-token family; simultaneous use from both copies is -treated as token replay and revokes that login. If a refresh response is lost -because the process or connection stops, the CLI does not retry the consumed -token: run `sim logout`, then `sim login` again. This fail-closed behavior keeps -a copied token from surviving an ambiguous refresh. +Run login separately on each machine. Copying the credentials file copies one single-use refresh-token family. Concurrent use of those copies can be treated as replay and revoke that login. + +If a refresh response is lost after the server consumes the token, the CLI does not retry that token. Recover with logout and a new login: + +```bash +sim logout --profile dev +sim login --profile dev +``` + +## Signing out + +```bash +sim logout +sim logout --all +``` + +The first command removes stored authentication; `--all` also removes the profile's settings. + +For OAuth, logout revokes that login's complete token family before clearing it locally, including access tokens from earlier rotations. Independent logins on other machines remain signed in. To revoke the client's grant across independent logins, use **Settings → General → Authorized apps**. + +A workspace profile cannot remove its shared login. Remove only that local profile with `sim logout --all --profile `, or log out of its authentication profile. Deleting an authentication profile entirely is refused while workspace profiles still reference it. + + +For API-key authentication, `sim logout` removes the local key but does not revoke it. Revoke the personal key under **Settings → Sim API keys**. + ## Organization audit logs -`sim audit-logs` requires a **personal** credential — an OAuth login, or the -personal API key `sim login --method api-key` issues. A workspace-scoped key cannot -read organization-level audit logs. +`sim audit-logs` requires a personal credential: an OAuth login or personal API key. Pairing creates a personal key. A workspace key cannot read organization audit logs. + +## Related docs + +- [Configuration](/cli/configuration) +- [Scripting](/cli/scripting) +- [Profiles commands](/cli/profiles) +- [Troubleshooting](/cli/troubleshooting) diff --git a/apps/docs/content/docs/cli/billing.mdx b/apps/docs/content/docs/cli/billing.mdx index 2058936e030..0e0f5cf781d 100644 --- a/apps/docs/content/docs/cli/billing.mdx +++ b/apps/docs/content/docs/cli/billing.mdx @@ -1,20 +1,22 @@ --- title: Billing -description: Manage billing — every subcommand, argument, and flag +description: Read billing status, credit usage, and storage usage. --- import { CommandTable } from '@/components/ui/command-table' -Every command below also accepts the [global options](/cli/commands#global-options). +Read billing status, credit usage, and storage usage. -## Show billing status, credits spent this period, and storage used +These commands accept the [global options](/cli/commands#global-options). + +## Show billing status, credits spent, and storage used + +Credits and storage require an OAuth login or personal API key. ```bash sim billing status [options] ``` -Show billing status, credits spent this period, and storage used (credits and storage require an OAuth login or personal API key) - **Options** @@ -25,22 +27,24 @@ Show billing status, credits spent this period, and storage used (credits and st +API request and response schemas: [getBillingStatus](/api-reference/billing/getBillingStatus). + ## List credit usage events +An OAuth login or personal API key reports only your events; a workspace API key reports every member's in aggregate, unattributed. + ```bash sim billing logs [options] ``` -List credit usage events (an OAuth login or personal API key reports only your events; a workspace API key reports every member's in aggregate, unattributed) - **Options** | Option | Required | Description | | --- | --- | --- | -| `--source ` | No | Filter by usage source; sim-chat combines Copilot and workspace chat. Accepted values: `workflow`, `wand`, `sim-chat`, `mcp_copilot`, `mothership_block`, `knowledge-base`, `voice-input`, `enrichment`, `voice-output`, `api-tool`. | -| `--period ` | No | Billing period. Accepted values: `1d`, `7d`, `30d`, `all`, `custom`. | +| `--source ` | No | Filter by usage source; sim-chat combines Sim agent and workspace Chat usage. Accepted values: `workflow`, `wand`, `sim-chat`, `mcp_copilot`, `mothership_block`, `knowledge-base`, `voice-input`, `enrichment`, `voice-output`, `api-tool`. | +| `--period ` | No | Billing period. Defaults to "30d". Accepted values: `1d`, `7d`, `30d`, `all`, `custom`. | | `--start-date ` | No | Custom period start (ISO 8601). | | `--end-date ` | No | Custom period end (ISO 8601). | | `--limit ` | No | Maximum items to return (0 for everything). Defaults to `100`. | @@ -48,3 +52,10 @@ List credit usage events (an OAuth login or personal API key reports only your e | `--all-workspaces` | No | Do not filter to the configured workspace (OAuth login or personal API key required for account-wide access). | + +API request and response schemas: [listBillingLogs](/api-reference/billing/listBillingLogs). + +## Related docs + +- [Costs](/platform/costs) +- [Authentication](/cli/authentication) diff --git a/apps/docs/content/docs/cli/blocks.mdx b/apps/docs/content/docs/cli/blocks.mdx index 93e6d3ce480..776cd4c7134 100644 --- a/apps/docs/content/docs/cli/blocks.mdx +++ b/apps/docs/content/docs/cli/blocks.mdx @@ -1,27 +1,15 @@ --- title: Blocks -description: Manage blocks — every subcommand, argument, and flag +description: Inspect workflow blocks, integration blocks, and triggers available to the workspace. --- import { CommandTable } from '@/components/ui/command-table' -Every command below also accepts the [global options](/cli/commands#global-options). +Inspect workflow blocks, integration blocks, and triggers available to the workspace. -## Get block - -```bash -sim blocks get -``` - -**Arguments** +The catalog reflects the workspace’s allowed integrations, revealed preview blocks, and deployed custom blocks. - - -| Argument | Required | Description | -| --- | --- | --- | -| `blockId` | Yes | Block type identifier. An unversioned base type resolves to the newest version, and the response echoes the resolved id. | - - +These commands accept the [global options](/cli/commands#global-options). ## List blocks @@ -41,8 +29,28 @@ sim blocks list [options] | `--source ` | No | Restrict to shipped blocks or to this workspace’s deployed custom blocks. Accepted values: `builtin`, `custom`. | | `--include-sunset` | No | Include `legacy` and `deprecated` blocks. Off by default: a sunset block keeps executing where it is already placed, but it is not offered for new authoring. Each returned entry carries `sunset.replacedBy`, the block to build with instead. | | `--no-include-sunset` | No | Send --include-sunset as false. | -| `--sort-by ` | No | Field used to sort the result. Sorting by `name` is case-sensitive and follows the storage collation, so do not rely on a case-insensitive order. Accepted values: `id`, `name`, `category`. | -| `--sort-order ` | No | Sort direction. Accepted values: `asc`, `desc`. | +| `--sort-by ` | No | Field used to sort the result. Do not rely on case-insensitive ordering when sorting by `name`. Defaults to "id". Accepted values: `id`, `name`, `category`. | +| `--sort-order ` | No | Sort direction. Defaults to "asc". Accepted values: `asc`, `desc`. | | `--limit ` | No | Maximum items to return (0 for everything). Defaults to `0`. | + +API request and response schemas: [listBlocks](/api-reference/catalog/listBlocks). + +## Get block + +```bash +sim blocks get +``` + +**Arguments** + + + +| Argument | Required | Description | +| --- | --- | --- | +| `blockId` | Yes | Block type identifier. An unversioned base type resolves to the newest visible version. The response echoes the resolved ID. | + + + +API request and response schemas: [getBlock](/api-reference/catalog/getBlock). diff --git a/apps/docs/content/docs/cli/chat-deployments.mdx b/apps/docs/content/docs/cli/chat-deployments.mdx index 59ab2d52d74..e6469503896 100644 --- a/apps/docs/content/docs/cli/chat-deployments.mdx +++ b/apps/docs/content/docs/cli/chat-deployments.mdx @@ -1,11 +1,13 @@ --- -title: Chat Deployments -description: Manage chat deployments — every subcommand, argument, and flag +title: Chat deployments +description: List workflow chat deployments in the workspace. --- import { CommandTable } from '@/components/ui/command-table' -Every command below also accepts the [global options](/cli/commands#global-options). +List workflow chat deployments in the workspace. + +These commands accept the [global options](/cli/commands#global-options). ## List chat deployments @@ -22,8 +24,14 @@ sim chat-deployments list [options] | `--workflow-id ` | No | Restrict to deployments of one workflow. | | `--is-active` | No | Restrict to active or inactive deployments. | | `--no-is-active` | No | Send --is-active as false. | -| `--sort-by ` | No | Field used to sort the result. Accepted values: `identifier`, `createdAt`, `updatedAt`. | -| `--sort-order ` | No | Sort direction. Accepted values: `asc`, `desc`. | +| `--sort-by ` | No | Field used to sort the result. Defaults to "createdAt". Accepted values: `identifier`, `createdAt`, `updatedAt`. | +| `--sort-order ` | No | Sort direction. Defaults to "desc". Accepted values: `asc`, `desc`. | | `--limit ` | No | Maximum items to return (0 for everything). Defaults to `0`. | + +API request and response schemas: [listChatDeployments](/api-reference/workflows/listChatDeployments). + +## Related docs + +- [Deploy or update a workflow chat](/cli/workflows#chat-deployments) diff --git a/apps/docs/content/docs/cli/cli.mdx b/apps/docs/content/docs/cli/cli.mdx index 2135fc78fb5..1c4a3a20ff5 100644 --- a/apps/docs/content/docs/cli/cli.mdx +++ b/apps/docs/content/docs/cli/cli.mdx @@ -1,13 +1,15 @@ --- -title: CLI -description: Discover commands in this CLI — every subcommand, argument, and flag +title: Command search +description: Find a command by describing the task you want to perform. --- import { CommandTable } from '@/components/ui/command-table' -Every command below also accepts the [global options](/cli/commands#global-options). +Find a command by describing the task you want to perform. -## Find the command for a task, described in plain words +These commands accept the [global options](/cli/commands#global-options). + +## Find commands for a task [#find-the-command-for-a-task-described-in-plain-words] ```bash sim cli search @@ -22,3 +24,12 @@ sim cli search | `query...` | Yes | What you want to do, e.g. "cancel a workflow run" | + +Ranks the commands this CLI ships, locally; your query is never sent anywhere. Returns the 5 best matches. Run ` --help` on one for its flags. + +**Examples** + +```bash +sim cli search "cancel a running workflow" +sim cli search list table rows +``` diff --git a/apps/docs/content/docs/cli/commands.mdx b/apps/docs/content/docs/cli/commands.mdx index 85c9eb0da58..e998b13dc7b 100644 --- a/apps/docs/content/docs/cli/commands.mdx +++ b/apps/docs/content/docs/cli/commands.mdx @@ -1,11 +1,11 @@ --- -title: CLI Commands -description: Global options, and every sim command group +title: CLI commands +description: Find command groups, global options, and login, configuration, and Chat commands. --- import { CommandTable } from '@/components/ui/command-table' -Every `sim` command follows the same shape: +Resource commands use this shape: ```bash sim [sub-resource] [arguments] [options] @@ -13,11 +13,15 @@ sim [sub-resource] [arguments] [options] Some resource groups also accept a singular alias: `sim workflow get` and `sim workflows get` are the same command. `knowledge` also answers to `kb`. -Each group’s reference lists its supported aliases. +Each group’s reference lists its supported aliases. Login, configuration, and +Chat commands appear below. To find a command for a task, use +`sim cli search "describe your task"`. ## Global options -These apply to every command, and may be written before or after it. +Place these options before or after the command. Each command uses the settings +relevant to its action. Telemetry commands always print text; workflow export +prints a portable JSON document, or YAML when selected. | Option | Description | | --- | --- | @@ -26,36 +30,42 @@ These apply to every command, and may be written before or after it. | `-w, --workspace ` | Workspace to target (env: SIM_WORKSPACE). | | `--output ` | Output format for this command. Accepted values: `table`, `json`, `yaml`, `text`. | +Use `--help` to inspect a command. Run `sim --version` to print the CLI version; +`--version` takes no value and exits without running a command. Deployment-version +commands use their documented arguments or `--to-version` instead. + +See [output formats](/cli/output) for the JSON default and display formats. + ## Command groups | Group | Description | | --- | --- | -| [`sim profiles`](/cli/profiles) | List profiles or add a workspace profile that shares a stored login | -| [`sim telemetry`](/cli/telemetry) | Control anonymous usage reporting | -| [`sim cli`](/cli/cli) | Discover commands in this CLI | -| [`sim audit-logs`](/cli/audit-logs) | Manage audit logs | -| [`sim billing`](/cli/billing) | Manage billing | -| [`sim blocks`](/cli/blocks) | Manage blocks | -| [`sim chat-deployments`](/cli/chat-deployments) | Manage chat deployments | -| [`sim connector-types`](/cli/connector-types) | Manage connector types | -| [`sim credentials`](/cli/credentials) | Manage credentials | -| [`sim custom-tools`](/cli/custom-tools) | Manage custom tools | -| [`sim files`](/cli/files) | Manage files | -| [`sim knowledge`](/cli/knowledge) | Manage knowledge | -| [`sim logs`](/cli/logs) | Manage logs | -| [`sim mcp-servers`](/cli/mcp-servers) | Manage mcp servers | -| [`sim meta`](/cli/meta) | Manage meta | -| [`sim organizations`](/cli/organizations) | Manage organizations | -| [`sim permission-groups`](/cli/permission-groups) | Manage permission groups | -| [`sim sandboxes`](/cli/sandboxes) | Manage sandboxes | -| [`sim secrets`](/cli/secrets) | Manage secrets | -| [`sim selectors`](/cli/selectors) | Manage selectors | -| [`sim skills`](/cli/skills) | Manage skills | -| [`sim tables`](/cli/tables) | Manage tables | -| [`sim tools`](/cli/tools) | Manage tools | -| [`sim workflow-mcp-servers`](/cli/workflow-mcp-servers) | Manage workflow mcp servers | -| [`sim workflows`](/cli/workflows) | Manage workflows | -| [`sim workspaces`](/cli/workspaces) | Manage workspaces | +| [`sim profiles`](/cli/profiles) | List profiles and add a workspace profile that shares a stored login. | +| [`sim telemetry`](/cli/telemetry) | Inspect and change this machine’s anonymous usage-reporting preference. | +| [`sim cli`](/cli/cli) | Find a command by describing the task you want to perform. | +| [`sim audit-logs`](/cli/audit-logs) | Read organization audit actions and filter by actor, resource, workspace, or time. | +| [`sim billing`](/cli/billing) | Read billing status, credit usage, and storage usage. | +| [`sim blocks`](/cli/blocks) | Inspect workflow blocks, integration blocks, and triggers available to the workspace. | +| [`sim chat-deployments`](/cli/chat-deployments) | List workflow chat deployments in the workspace. | +| [`sim connector-types`](/cli/connector-types) | Discover knowledge connectors and their authentication and source-configuration schemas. | +| [`sim credentials`](/cli/credentials) | Discover providers, connect accounts, and manage credential access. | +| [`sim custom-tools`](/cli/custom-tools) | Create and manage code-backed tools that agents can call. | +| [`sim files`](/cli/files) | Browse workspace files, read or write content, manage versions, and configure sharing. | +| [`sim knowledge`](/cli/knowledge) | Manage knowledge bases, indexed documents, search, tags, and connector syncs. | +| [`sim logs`](/cli/logs) | Read run diagnostics, follow new runs, and summarize failures and latency. | +| [`sim mcp-servers`](/cli/mcp-servers) | Connect external Model Context Protocol (MCP) servers so workflows can use their tools. | +| [`sim meta`](/cli/meta) | Inspect API availability and the calling credential’s type and expiry. | +| [`sim organizations`](/cli/organizations) | Manage organization membership, invitations, usage, access requests, and SSO. | +| [`sim permission-groups`](/cli/permission-groups) | Manage organization permission groups, their configuration, and member assignments. | +| [`sim sandboxes`](/cli/sandboxes) | Manage reusable dependency sets for Function blocks. | +| [`sim secrets`](/cli/secrets) | Set and manage workspace or personal secrets. | +| [`sim selectors`](/cli/selectors) | Discover destination options for registered fields, such as calendars, channels, and tables. | +| [`sim skills`](/cli/skills) | Create reusable agent instructions and manage their editors. | +| [`sim tables`](/cli/tables) | Manage tables, rows, schemas, views, enrichment runs, imports, and exports. | +| [`sim tools`](/cli/tools) | Find built-in tools, inspect their parameters, and run them. | +| [`sim workflow-mcp-servers`](/cli/workflow-mcp-servers) | Serve deployed workflows as tools for Model Context Protocol (MCP) clients. | +| [`sim workflows`](/cli/workflows) | Build, deploy, run, and inspect workflows from the terminal. | +| [`sim workspaces`](/cli/workspaces) | Read workspace access and manage reviewed fork, push, and pull operations. | ## Log in through the browser and store the login for the profile @@ -109,6 +119,8 @@ sim whoami [options] +API request and response schemas: [getMeta](/api-reference/meta/getApiMeta), [getWorkspace](/api-reference/workspaces/getWorkspace). + ## Switch a profile's default workspace, or set its endpoint or output format ```bash @@ -169,3 +181,19 @@ sim chat [options] | `-c, --conversation ` | No | Continue the conversation with this ID. | + +Each turn prints the reply on stdout and the conversation ID on stderr; pass that ID back with -c to continue the same conversation. With --output json or yaml the reply is not streamed — the finished result is printed as one document, conversation ID included. + +**Examples** + +```bash +sim chat "What workflows do I have?" +sim chat -c "$CONVERSATION_ID" "Which of those run on a schedule?" +sim --output json chat "Summarize yesterday's failed runs" | jq -r '.content' +``` + +## Related docs + +- [Complete command reference](/cli/reference) +- [Authentication](/cli/authentication) +- [Scripting](/cli/scripting) diff --git a/apps/docs/content/docs/cli/configuration.mdx b/apps/docs/content/docs/cli/configuration.mdx index 630e23f7090..b11e660fd2d 100644 --- a/apps/docs/content/docs/cli/configuration.mdx +++ b/apps/docs/content/docs/cli/configuration.mdx @@ -1,81 +1,63 @@ --- title: Configuration -description: Profiles, config files, environment variables, and how each setting is resolved +description: Select profiles and resolve endpoint, credential, workspace, and output settings. --- -These settings apply to the CLI you install locally. When Sim runs a `sim` -command for you inside Chat, it uses your session identity — there is no profile, -no `sim login`, and no config file. +The installed CLI resolves an endpoint, credential, workspace, and output format independently. A saved default can be overridden for one command. -The CLI resolves an **endpoint**, **credential**, **workspace**, and **output -format**. The credential can be a stored OAuth login or an API key. Each resolves independently, so a saved default can still be overridden -for a single command. +Commands Sim runs inside Chat receive their identity, endpoint, and workspace from Chat. Local `login`, `logout`, `whoami`, `profiles`, `configure`, `update`, and `telemetry` commands are unavailable there; local profiles and config files do not apply. ## Profiles -A profile selects one set of defaults, in the style of the AWS CLI. It normally -uses its same-named stored identity, but a workspace profile can share another -profile's identity through `auth_profile`. Select one with `-P`, `--profile`, or -`SIM_PROFILE`: +A profile stores defaults and normally uses its same-named stored login. A workspace profile can share another profile's authentication through `auth_profile`. + +Select a profile with `-P`, `--profile`, or `SIM_PROFILE`. A flag wins over the environment; omission selects `default`: ```bash sim workflows list --profile dev SIM_PROFILE=dev sim workflows list +sim profiles --output table ``` -The profile is named `default` when you do not pick one. - -```bash -sim profiles # list them; * marks the active one -``` - -Add a profile for another workspace without creating or copying an API key: - -```bash -sim profile add acme --workspace 7e2d9c14-6b83-4a55-8f01-c4d3e9a76b28 -``` +In table output, `*` marks the selected profile. JSON output includes an `active` boolean. An explicitly named profile must exist; `login` and `configure --set-*` can create one. ## Setting defaults +Use `configure` to save settings for the selected profile: + ```bash sim configure --set-endpoint http://localhost:3000 --profile dev sim configure --set-workspace 5c81f3a6-0e27-4b94-8d15-a7f60c39b2e8 --profile dev sim configure --set-output table ``` -| Option | What it sets | +| Option | Saved setting | | --- | --- | -| `--set-endpoint ` | The Sim deployment to talk to | +| `--set-endpoint ` | Sim deployment | | `--set-workspace ` | Default workspace for workspace-scoped commands | -| `--set-output ` | Default output format: `table`, `json`, `yaml`, or `text` | -| `--unset ` | Remove settings — `endpoint`, `workspace`, or `output` | +| `--set-output ` | `table`, `json`, `yaml`, or `text` | +| `--unset ` | Remove `endpoint`, `workspace`, or `output` settings | -Run `sim configure` with no flags to print the profile's stored settings. +Without setter flags, `sim configure` prints the profile's stored settings as text. Credentials are set through [login](/cli/authentication), or supplied with `SIM_API_KEY` for CI. -API keys are not settable here. Use [`sim login`](/cli/authentication), or -`SIM_API_KEY` for CI. +The global `--endpoint`, `--workspace`, and `--output` flags affect one invocation. `configure` rejects them; use the corresponding `--set-*` flag to persist a setting. ## Where settings come from -Each setting resolves independently, and the first match wins: +The first applicable source wins for each setting: | Rank | Source | | --- | --- | -| 1 | Command-line flag — `--endpoint`, `--workspace`, `--output` | -| 2 | Environment — `SIM_ENDPOINT`, `SIM_API_KEY`, `SIM_WORKSPACE`, `SIM_OUTPUT` | -| 3 | `~/.sim/config` for the selected profile and `~/.sim/credentials` for its `auth_profile`, when set | -| 4 | Built-in default — `https://www.sim.ai` and `json` | +| 1 | Command-line flag: `--endpoint`, `--workspace`, `--output` | +| 2 | Environment: `SIM_ENDPOINT`, `SIM_API_KEY`, `SIM_WORKSPACE`, `SIM_OUTPUT` | +| 3 | Selected profile in `~/.sim/config`; its stored login in `~/.sim/credentials`, or the login named by `auth_profile` | +| 4 | Defaults: endpoint `https://www.sim.ai`, output `json`; no default credential or workspace | -`sim whoami` prints the winning source for each setting: - -```bash -sim whoami -``` +`SIM_API_KEY` overrides a stored OAuth login or API key. There is no command-line API-key option. Use `sim whoami` to see each resolved value and its source; `--no-verify` skips API requests. ## The files -Non-secret settings live in `~/.sim/config`. It is safe to commit to a dotfiles -repo: +Non-secret settings live in `~/.sim/config` and can be kept in a dotfiles repository: ```ini title="~/.sim/config" [default] @@ -92,7 +74,7 @@ auth_profile = default workspace = 7e2d9c14-6b83-4a55-8f01-c4d3e9a76b28 ``` -Keys live in `~/.sim/credentials`, written `0600`: +API keys and OAuth tokens live in `~/.sim/credentials`, written with `0600` permissions. Never commit that file: ```ini title="~/.sim/credentials" [default] @@ -102,107 +84,103 @@ api_key = sim_… api_key = sim_… ``` -Section naming follows the AWS convention: `[profile dev]` in config, `[dev]` in -credentials. The `default` profile is `[default]` in both. +Named config sections use `[profile dev]`; credentials use `[dev]`. The default section is `[default]` in both files. See [Stored logins](/cli/authentication#where-the-login-is-stored) for OAuth fields and refresh behavior. + +### Shared authentication + +`auth_profile` names one direct authentication profile. It shares that profile's endpoint and stored OAuth login or API key; workspace and output stay local. References cannot be chained. A shared profile cannot set its own endpoint or stored login. + +Create a shared profile from a stored login: + +```bash +sim profile add acme --workspace 7e2d9c14-6b83-4a55-8f01-c4d3e9a76b28 +sim --profile acme tables list +``` + +`profile add` refuses environment-only credentials and endpoint overrides because those values would not persist in a new shell. Save the endpoint and sign in before creating the profile. + +An OAuth login is bound to its issuing deployment. Log out before changing or removing that authentication profile's endpoint. Change a shared endpoint on the authentication profile, not its workspace profiles. + +## Choosing a workspace + +Workspace-scoped commands need a target. Set it for one command, in the profile, or in the environment: + +```bash +sim tables list --workspace 9b4c7e02-1d58-4f36-a0c9-6e2b85df413a +sim configure --set-workspace 2f6d0b1c-8a34-4d92-b7e5-31c8a0f45d67 +export SIM_WORKSPACE=2f6d0b1c-8a34-4d92-b7e5-31c8a0f45d67 +``` + +To select an accessible workspace interactively, omit `--workspace` from `sim profile add `. The picker accepts at most 1,000 workspaces; above that, supply an ID. Non-interactive scripts must always supply it. -`auth_profile` references one direct profile and shares its endpoint and stored -login, whether OAuth or an API key. Workspace and output remain local. -References cannot be chained, and a shared profile cannot also set its own -endpoint or stored login. +`sim billing status`, `sim billing logs`, and `sim audit-logs list` accept `--all-workspaces` to omit the workspace filter. Do not combine it with an explicit `--workspace`. ## Environment variables | Variable | Effect | | --- | --- | -| `SIM_PROFILE` | Profile to use | -| `SIM_ENDPOINT` | Deployment to talk to | -| `SIM_API_KEY` | API key — skips `sim login` entirely | -| `SIM_WORKSPACE` | Workspace to target | -| `SIM_OUTPUT` | Output format | -| `SIM_CONFIG_DIR` | Relocate the config directory and update cache; file-specific overrides below still win | +| `SIM_PROFILE` | Select a profile | +| `SIM_ENDPOINT` | Select a deployment | +| `SIM_API_KEY` | Authenticate with an existing key; overrides stored authentication | +| `SIM_WORKSPACE` | Select a workspace | +| `SIM_OUTPUT` | Select an output format | +| `SIM_CONFIG_DIR` | Relocate config, credentials, usage state, and update cache; file-specific overrides still win | | `SIM_CONFIG_FILE` | Relocate only the config file | | `SIM_CREDENTIALS_FILE` | Relocate only the credentials file | -| `SIM_TIMEOUT_SECONDS` | Per-request timeout; `0` waits indefinitely. Defaults to `3600`, above every timeout the server itself applies | -| `SIM_DEBUG` | Trace each request's method, URL, status and duration to stderr | -| `SIM_NO_UPDATE_CHECK` | Turn off update checks and notices | -| `SIM_TELEMETRY_DISABLED` | Turn off anonymous usage reporting; see [usage data](/cli/usage-data) | +| `SIM_TIMEOUT_SECONDS` | Per-request timeout, default `3600` seconds; `0` removes the CLI timeout | +| `SIM_DEBUG` | Write request method, URL, status, and duration to stderr | +| `SIM_NO_UPDATE_CHECK` | Disable automatic update checks and notices | +| `SIM_TELEMETRY_DISABLED` | Disable anonymous usage reporting | +| `DO_NOT_TRACK` | Cross-tool usage-reporting opt-out; takes precedence over the CLI setting | -## Updates +For CI, supply `SIM_API_KEY` and `SIM_WORKSPACE`; a saved login or config file is not required. `SIM_CONFIG_DIR` can point at a writable runner directory. -The CLI checks for a newer stable release at most once per day on eligible -interactive invocations. It prints an optional notice to stderr and continues -your command. Installation only happens when you run `sim update`. - -Run `sim update` to update immediately, including in CI and when automatic checks -are disabled. It requires a global installation and verifies that the package -manager targets the running copy before installing. Supported managers are npm, -pnpm, Bun, and Yarn Classic. For custom installations, select the manager with -`sim update --package-manager bun`. Project-local and temporary package-runner -copies must be updated through their package manager. - -Manual updates preserve the stable, staging, or dev release channel. Installation -failures stop with an error; concurrent update attempts are refused. Installer -output goes to stderr and does not mix with JSON output on stdout. -The updater resolves the channel through the selected package manager before -installing. Older registry or mirror releases are refused; a newer release is -installed by its exact version so a moving tag cannot change the target. - -Checks are skipped in CI, when stderr is redirected, under `npm exec` or `npx`, -from a repository checkout, and for prerelease versions. Set -`SIM_NO_UPDATE_CHECK=1` to disable them. - -The check uses `registry.npmjs.org` unless `npm_config_registry` names another -HTTP(S) registry. It sends no Sim API key, workspace, or command. Query-string -credentials in a configured registry URL are preserved; URLs containing -username/password userinfo are rejected. Empty registry values use npm, while -malformed non-empty values disable the check. Redirects are not followed. - -The daily cache is `~/.sim/update-check.json`, or under `SIM_CONFIG_DIR`. -`SIM_CONFIG_FILE` and `SIM_CREDENTIALS_FILE` do not relocate it. If the cache -cannot be written, eligible invocations may check again. Concurrent commands -can also each check. Registry checks have a one-second deadline; package-manager -installation has a five-minute deadline. Registry-check failures suppress the -check, while installer failures are reported. - -Node's `fetch` uses `HTTP(S)_PROXY` when opted in with `NODE_USE_ENV_PROXY=1` -(Node 22.21+ or 24.0+) or `--use-env-proxy` (Node 22.21+ or 24.5+). - -For CI, set `SIM_API_KEY` and `SIM_WORKSPACE`; no saved login or config file is -required. +The request timeout does not change server execution limits. Run/operation waits have a separate `--wait-timeout`; see [Scripting](/cli/scripting#exit-codes). Debug URLs can include request selectors, so review them before sharing diagnostics. See [Usage data](/cli/usage-data) for the separate anonymous event fields. -## Choosing a workspace +## Updates -Workspace-scoped commands need a workspace: +Eligible interactive invocations check for a newer stable release using a daily cache. A notice goes to stderr and the command continues. Installation happens only when you run: ```bash -sim tables list --workspace 9b4c7e02-1d58-4f36-a0c9-6e2b85df413a -sim configure --set-workspace 2f6d0b1c-8a34-4d92-b7e5-31c8a0f45d67 -export SIM_WORKSPACE=2f6d0b1c-8a34-4d92-b7e5-31c8a0f45d67 +sim update ``` -For a reusable selection, create a workspace profile backed by the current -stored login: +Manual updates also work in CI and when automatic checks are disabled. They require a global installation and verify that the selected package manager owns the running copy. Supported managers are Bun, npm, pnpm, and Yarn Classic. Select one explicitly for a custom installation: ```bash -sim workspaces list -sim profile add acme --workspace 7e2d9c14-6b83-4a55-8f01-c4d3e9a76b28 -sim --profile acme tables list +sim update --package-manager bun ``` -When `--workspace` is omitted in a terminal, `profile add` presents an -interactive picker, capped at 1,000 entries. It refuses environment-only keys -and endpoint overrides because those values would disappear in another shell. +Update project-local dependencies and temporary package-runner copies through their package manager. A manual update preserves the stable, staging, or dev release channel. The updater refuses older registry/mirror releases and installs the resolved exact version. Concurrent updates are refused; installation errors stop the command. Installer output goes to stderr. + +### Automatic notices + +Checks are skipped in CI, when stderr is redirected, for prerelease versions, from a repository checkout, and for temporary/project-local installations including `npm exec` and `npx`. Set `SIM_NO_UPDATE_CHECK=1` to disable them. + +The cache lives at `~/.sim/update-check.json`, or under `SIM_CONFIG_DIR`. `SIM_CONFIG_FILE` and `SIM_CREDENTIALS_FILE` do not move it. A failed cache write or concurrent invocations can cause additional checks. -`sim billing status`, `sim billing logs`, and `sim audit-logs list` accept -`--all-workspaces` to drop the filter instead. It cannot be combined with -`--workspace`. +Registry checks have a one-second deadline and fail quietly. Package-manager installation has a five-minute deadline and reports failures. + +### Registry and proxy behavior + +Automatic checks use `registry.npmjs.org` unless `npm_config_registry` supplies another HTTP(S) registry. They send no Sim API key, workspace, or command. Configured query-string credentials are preserved; username/password URL userinfo is rejected. Empty registry values use the default, malformed non-empty values disable checking, and redirects are not followed. + +Node's `fetch` reads `HTTP(S)_PROXY` when opted in with `NODE_USE_ENV_PROXY=1` on Node 22.21+ or 24.0+. The `--use-env-proxy` flag requires Node 22.21+ or 24.5+. See [Node's proxy options](https://nodejs.org/api/cli.html#node_use_env_proxy1). ## Repairing a bad setting -An invalid `output` value fails with the list of accepted formats. A -higher-priority source still wins, so you can repair a profile without editing -the file: +An invalid output format stops profile resolution. Temporarily override it through the environment, then save a valid default: ```bash -sim --output table configure --set-output json +SIM_OUTPUT=json sim configure --set-output json +SIM_OUTPUT=json sim configure --profile dev --set-output json ``` + +If the invalid value comes from `SIM_OUTPUT`, correct or unset that variable too. A higher-priority environment value still overrides the repaired profile. + +## Related docs + +- [Authentication](/cli/authentication) +- [Output formats](/cli/output) +- [Profiles commands](/cli/profiles) +- [Troubleshooting](/cli/troubleshooting) diff --git a/apps/docs/content/docs/cli/connector-types.mdx b/apps/docs/content/docs/cli/connector-types.mdx index 88dd05a0cde..8b4da35396f 100644 --- a/apps/docs/content/docs/cli/connector-types.mdx +++ b/apps/docs/content/docs/cli/connector-types.mdx @@ -1,11 +1,15 @@ --- -title: Connector Types -description: Manage connector types — every subcommand, argument, and flag +title: Connector types +description: Discover knowledge connectors and their authentication and source-configuration schemas. --- import { CommandTable } from '@/components/ui/command-table' -Every command below also accepts the [global options](/cli/commands#global-options). +Discover knowledge connectors and their authentication and source-configuration schemas. + +Use `--detail full` to inspect a connector’s configuration before creating it. + +These commands accept the [global options](/cli/commands#global-options). ## List connector types @@ -25,3 +29,9 @@ sim connector-types list [options] | `--cursor ` | No | Continue from nextCursor returned by a previous result. | + +API request and response schemas: [listConnectorTypes](/api-reference/catalog/listConnectorTypes). + +## Related docs + +- [Create and sync knowledge connectors](/cli/knowledge#connectors) diff --git a/apps/docs/content/docs/cli/credentials.mdx b/apps/docs/content/docs/cli/credentials.mdx index 8e77cdac6af..4cd441379c5 100644 --- a/apps/docs/content/docs/cli/credentials.mdx +++ b/apps/docs/content/docs/cli/credentials.mdx @@ -1,31 +1,25 @@ --- title: Credentials -description: Manage credentials — every subcommand, argument, and flag +description: Discover providers, connect accounts, and manage credential access. --- import { CommandTable } from '@/components/ui/command-table' -`sim credentials` is also spelled `sim credential`. - -Every command below also accepts the [global options](/cli/commands#global-options). - -## Disconnect credential +Discover providers, connect accounts, and manage credential access. -```bash -sim credentials delete [options] -``` +Run `sim --output json credentials providers list` to inspect the provider’s fields and authentication requirements before creating a service-account credential. OAuth connection commands return a link that a person must open to authorize the connection. -Disconnect Credential (OAuth login or personal API key required) +`sim credentials` is also spelled `sim credential`. -**Arguments** +These commands accept the [global options](/cli/commands#global-options). - +## Provider discovery and connections -| Argument | Required | Description | -| --- | --- | --- | -| `credentialId` | Yes | Credential to disconnect. | +### List credential providers - +```bash +sim credentials providers list [options] +``` **Options** @@ -33,56 +27,50 @@ Disconnect Credential (OAuth login or personal API key required) | Option | Required | Description | | --- | --- | --- | -| `-y, --yes` | Yes | Confirm this operation. | +| `--search ` | No | Case-insensitive substring match against the credential provider name. | -## List credential members +API request and response schemas: [listCredentialProviders](/api-reference/credentials/listCredentialProviders). + +### List credentials ```bash -sim credentials members list [options] +sim credentials list [options] ``` -List Credential Members (OAuth login or personal API key required) - -**Arguments** - - - -| Argument | Required | Description | -| --- | --- | --- | -| `credentialId` | Yes | Credential whose sharing grants are managed. | - - - **Options** | Option | Required | Description | | --- | --- | --- | +| `--type ` | No | Restrict results to this credential type. Accepted values: `oauth`, `service_account`. | +| `--provider-id ` | No | Restrict results to credentials for this integration provider. | +| `--search ` | No | Case-insensitive substring match against the credential display name. | +| `--sort-by ` | No | Field used to sort the result. Defaults to "createdAt". Accepted values: `displayName`, `createdAt`, `updatedAt`. | +| `--sort-order ` | No | Sort direction. Defaults to "desc". Accepted values: `asc`, `desc`. | | `--limit ` | No | Maximum items to return (0 for everything). Defaults to `0`. | -| `--sort-by ` | No | Field used to sort the result. Sorting by `name` is case-sensitive and follows the storage collation, so do not rely on a case-insensitive order. Accepted values: `email`, `name`. | -| `--sort-order ` | No | Sort direction. Accepted values: `asc`, `desc`. | -## Remove credential member +API request and response schemas: [listCredentials](/api-reference/credentials/listCredentials). + +### Create a service-account credential using its discovered provider schema + +OAuth login or personal API key required. ```bash -sim credentials members remove [options] +sim credentials create [options] ``` -Remove Credential Member (OAuth login or personal API key required) - **Arguments** | Argument | Required | Description | | --- | --- | --- | -| `credentialId` | Yes | Credential whose sharing grants are managed. | -| `userId` | Yes | User whose explicit grant will be revoked. | +| `providerId` | Yes | Service-account provider to create a credential for | @@ -92,25 +80,30 @@ Remove Credential Member (OAuth login or personal API key required) | Option | Required | Description | | --- | --- | --- | -| `-y, --yes` | Yes | Confirm this operation. | +| `--name ` | Yes | Name shown for the credential in Sim. | +| `--credentials ` | Yes | Provider credentials as JSON (or @path / @- to read a file or stdin). | +| `--description ` | No | Optional credential description. | +| `--id ` | No | Client-generated credential ID when provider discovery requires it. | -## Upsert credential member +API request and response schemas: [createServiceAccountCredential](/api-reference/credentials/createServiceAccountCredential). + +### Create a short-lived link for connecting an OAuth provider + +OAuth login or personal API key required. ```bash -sim credentials members upsert [options] +sim credentials connect [options] ``` -Upsert Credential Member (OAuth login or personal API key required) - **Arguments** | Argument | Required | Description | | --- | --- | --- | -| `credentialId` | Yes | Credential whose sharing grants are managed. | +| `providerId` | Yes | OAuth provider to connect | @@ -120,56 +113,40 @@ Upsert Credential Member (OAuth login or personal API key required) | Option | Required | Description | | --- | --- | --- | -| `--user ` | Yes | Existing workspace member to grant or change access for. | -| `--role ` | Yes | Credential role to grant; workspace administrators cannot be demoted. Accepted values: `admin`, `member`. | +| `--name ` | Yes | Name shown for the new credential in Sim. | -## List credential providers +API request and response schemas: [createCredentialConnection](/api-reference/credentials/createCredentialConnection). -```bash -sim credentials providers list [options] -``` - -**Options** - - +### Create a short-lived link for reconnecting an OAuth credential -| Option | Required | Description | -| --- | --- | --- | -| `--search ` | No | Case-insensitive substring match against the credential provider name. | - - - -## List credentials +OAuth login or personal API key required. ```bash -sim credentials list [options] +sim credentials reconnect ``` -**Options** +**Arguments** -| Option | Required | Description | +| Argument | Required | Description | | --- | --- | --- | -| `--type ` | No | Restrict results to this credential type. Accepted values: `oauth`, `service_account`. | -| `--provider-id ` | No | Restrict results to credentials for this integration provider. | -| `--search ` | No | Case-insensitive substring match against the credential display name. | -| `--sort-by ` | No | Field used to sort the result. Accepted values: `displayName`, `createdAt`, `updatedAt`. | -| `--sort-order ` | No | Sort direction. Accepted values: `asc`, `desc`. | -| `--limit ` | No | Maximum items to return (0 for everything). Defaults to `0`. | +| `credentialId` | Yes | Existing OAuth credential to re-authorize | -## Update credential +API request and response schemas: [createCredentialConnection](/api-reference/credentials/createCredentialConnection). + +### Update credential + +OAuth login or personal API key required. ```bash sim credentials update [options] ``` -Update Credential (OAuth login or personal API key required) - **Arguments** @@ -212,21 +189,25 @@ Update Credential (OAuth login or personal API key required) -## Create a service-account credential using its discovered provider schema +API request and response schemas: [updateCredential](/api-reference/credentials/updateCredential). + +## Credential members + +### List credential members + +OAuth login or personal API key required. ```bash -sim credentials create [options] +sim credentials members list [options] ``` -Create a service-account credential using its discovered provider schema (OAuth login or personal API key required) - **Arguments** | Argument | Required | Description | | --- | --- | --- | -| `providerId` | Yes | Service-account provider to create a credential for | +| `credentialId` | Yes | Credential whose sharing grants are managed. | @@ -236,28 +217,29 @@ Create a service-account credential using its discovered provider schema (OAuth | Option | Required | Description | | --- | --- | --- | -| `--name ` | Yes | Name shown for the credential in Sim. | -| `--credentials ` | Yes | Provider credentials as JSON (or @path / @- to read a file or stdin). | -| `--description ` | No | Optional credential description. | -| `--id ` | No | Client-generated credential ID when provider discovery requires it. | +| `--limit ` | No | Maximum items to return (0 for everything). Defaults to `0`. | +| `--sort-by ` | No | Field used to sort the result. Do not rely on case-insensitive ordering when sorting by `name`. Defaults to "email". Accepted values: `email`, `name`. | +| `--sort-order ` | No | Sort direction. Defaults to "asc". Accepted values: `asc`, `desc`. | -## Create a short-lived link for connecting an OAuth provider +API request and response schemas: [listCredentialMembers](/api-reference/credentials/listCredentialMembers). + +### Upsert credential member + +OAuth login or personal API key required. ```bash -sim credentials connect [options] +sim credentials members upsert [options] ``` -Create a short-lived link for connecting an OAuth provider (OAuth login or personal API key required) - **Arguments** | Argument | Required | Description | | --- | --- | --- | -| `providerId` | Yes | OAuth provider to connect | +| `credentialId` | Yes | Credential whose sharing grants are managed. | @@ -267,17 +249,57 @@ Create a short-lived link for connecting an OAuth provider (OAuth login or perso | Option | Required | Description | | --- | --- | --- | -| `--name ` | Yes | Name shown for the new credential in Sim. | +| `--user ` | Yes | Existing workspace member to grant or change access for. | +| `--role ` | Yes | Credential role to grant; workspace administrators cannot be demoted. Accepted values: `admin`, `member`. | -## Create a short-lived link for reconnecting an OAuth credential +API request and response schemas: [upsertCredentialMember](/api-reference/credentials/upsertCredentialMember). + +### Remove credential member + +OAuth login or personal API key required. + +This revokes the selected user’s explicit credential grant. ```bash -sim credentials reconnect +sim credentials members remove [options] ``` -Create a short-lived link for reconnecting an OAuth credential (OAuth login or personal API key required) +**Arguments** + + + +| Argument | Required | Description | +| --- | --- | --- | +| `credentialId` | Yes | Credential whose sharing grants are managed. | +| `userId` | Yes | User whose explicit grant will be revoked. | + + + +**Options** + + + +| Option | Required | Description | +| --- | --- | --- | +| `-y, --yes` | Yes | Confirm this operation. | + + + +API request and response schemas: [removeCredentialMember](/api-reference/credentials/removeCredentialMember). + +## Disconnect credentials + +### Disconnect credential + +OAuth login or personal API key required. + +This disconnects the credential and removes its stored authentication. + +```bash +sim credentials delete [options] +``` **Arguments** @@ -285,6 +307,22 @@ Create a short-lived link for reconnecting an OAuth credential (OAuth login or p | Argument | Required | Description | | --- | --- | --- | -| `credentialId` | Yes | Existing OAuth credential to re-authorize | +| `credentialId` | Yes | Credential to disconnect. | + +**Options** + + + +| Option | Required | Description | +| --- | --- | --- | +| `-y, --yes` | Yes | Confirm this operation. | + + + +API request and response schemas: [deleteCredential](/api-reference/credentials/deleteCredential). + +## Related docs + +- [Credentials](/platform/credentials) diff --git a/apps/docs/content/docs/cli/custom-tools.mdx b/apps/docs/content/docs/cli/custom-tools.mdx index 5c83e67c805..a952d869ce1 100644 --- a/apps/docs/content/docs/cli/custom-tools.mdx +++ b/apps/docs/content/docs/cli/custom-tools.mdx @@ -1,18 +1,20 @@ --- -title: Custom Tools -description: Manage custom tools — every subcommand, argument, and flag +title: Custom tools +description: Create and manage code-backed tools that agents can call. --- import { CommandTable } from '@/components/ui/command-table' +Create and manage code-backed tools that agents can call. + `sim custom-tools` is also spelled `sim custom-tool`. -Every command below also accepts the [global options](/cli/commands#global-options). +These commands accept the [global options](/cli/commands#global-options). -## Create custom tool +## List custom tools ```bash -sim custom-tools create [options] +sim custom-tools list [options] ``` **Options** @@ -21,16 +23,19 @@ sim custom-tools create [options] | Option | Required | Description | | --- | --- | --- | -| `--title ` | Yes | Display title, unique within the workspace. | -| `--schema ` | Yes | OpenAI function schema: {"type":"function","function":{"name":"...","parameters":{"type":"object","properties":{}}}} (JSON, or @path / @- to read a file or stdin). | -| `--code ` | Yes | Tool implementation executed in the sandboxed function runtime. | +| `--search ` | No | Case-insensitive substring match against the tool title. | +| `--sort-by ` | No | Field used to sort the result. Defaults to "createdAt". Accepted values: `title`, `createdAt`, `updatedAt`. | +| `--sort-order ` | No | Sort direction. Defaults to "desc". Accepted values: `asc`, `desc`. | +| `--limit ` | No | Maximum items to return (0 for everything). Defaults to `0`. | -## Delete custom tool +API request and response schemas: [listCustomTools](/api-reference/custom-tools/listCustomTools). + +## Get custom tool ```bash -sim custom-tools delete [options] +sim custom-tools get ``` **Arguments** @@ -43,20 +48,32 @@ sim custom-tools delete [options] +API request and response schemas: [getCustomTool](/api-reference/custom-tools/getCustomTool). + +## Create custom tool + +```bash +sim custom-tools create [options] +``` + **Options** | Option | Required | Description | | --- | --- | --- | -| `-y, --yes` | Yes | Confirm this operation. | +| `--title ` | Yes | Display title, unique within the workspace. | +| `--schema ` | Yes | OpenAI function schema: {"type":"function","function":{"name":"...","parameters":{"type":"object","properties":{}}}} (JSON, or @path / @- to read a file or stdin). | +| `--code ` | Yes | Tool implementation executed in the sandboxed function runtime. | -## Get custom tool +API request and response schemas: [createCustomTool](/api-reference/custom-tools/createCustomTool). + +## Update custom tool ```bash -sim custom-tools get +sim custom-tools update [options] ``` **Arguments** @@ -69,29 +86,26 @@ sim custom-tools get -## List custom tools - -```bash -sim custom-tools list [options] -``` - **Options** | Option | Required | Description | | --- | --- | --- | -| `--search ` | No | Case-insensitive substring match against the tool title. | -| `--sort-by ` | No | Field used to sort the result. Accepted values: `title`, `createdAt`, `updatedAt`. | -| `--sort-order ` | No | Sort direction. Accepted values: `asc`, `desc`. | -| `--limit ` | No | Maximum items to return (0 for everything). Defaults to `0`. | +| `--title ` | No | New display title for the tool. | +| `--schema ` | No | OpenAI function schema: {"type":"function","function":{"name":"...","parameters":{"type":"object","properties":{}}}} (JSON, or @path / @- to read a file or stdin). | +| `--code ` | No | Replacement tool implementation. | -## Update custom tool +API request and response schemas: [updateCustomTool](/api-reference/custom-tools/updateCustomTool). + +## Delete custom tool + +This deletes the custom tool. ```bash -sim custom-tools update [options] +sim custom-tools delete [options] ``` **Arguments** @@ -110,8 +124,12 @@ sim custom-tools update [options] | Option | Required | Description | | --- | --- | --- | -| `--title ` | No | New display title for the tool. | -| `--schema ` | No | OpenAI function schema: {"type":"function","function":{"name":"...","parameters":{"type":"object","properties":{}}}} (JSON, or @path / @- to read a file or stdin). | -| `--code ` | No | Replacement tool implementation. | +| `-y, --yes` | Yes | Confirm this operation. | + +API request and response schemas: [deleteCustomTool](/api-reference/custom-tools/deleteCustomTool). + +## Related docs + +- [Custom tools](/agents/custom-tools) diff --git a/apps/docs/content/docs/cli/files.mdx b/apps/docs/content/docs/cli/files.mdx index 853e60ce484..315ec4600c8 100644 --- a/apps/docs/content/docs/cli/files.mdx +++ b/apps/docs/content/docs/cli/files.mdx @@ -1,35 +1,51 @@ --- title: Files -description: Manage files — every subcommand, argument, and flag +description: Browse workspace files, read or write content, manage versions, and configure sharing. --- import { CommandTable } from '@/components/ui/command-table' +Browse workspace files, read or write content, manage versions, and configure sharing. + `sim files` is also spelled `sim file`. -Every command below also accepts the [global options](/cli/commands#global-options). +These commands accept the [global options](/cli/commands#global-options). + +## Browse and inspect -## Delete several files at once +### List file resources and child folders together ```bash -sim files batch-delete [options] +sim files ls [path] [options] ``` +**Arguments** + + + +| Argument | Required | Description | +| --- | --- | --- | +| `path` | No | Folder path to list; defaults to the root folder | + + + **Options** | Option | Required | Description | | --- | --- | --- | -| `--file-ids ` | Yes | File identifiers to delete. (space-separated, or @path / @- with one value per line; @@value for a literal leading @). | -| `-y, --yes` | Yes | Confirm this operation. | +| `--search ` | No | Filter folders and resources by name. | +| `--limit ` | No | Maximum combined items to return (0 for everything). Defaults to `0`. | -## Create file +API request and response schemas: [listFiles](/api-reference/files/listFiles), [listFileFolders](/api-reference/files/listFilesFolders). + +### List files ```bash -sim files create [options] +sim files list [options] ``` **Options** @@ -38,34 +54,46 @@ sim files create [options] | Option | Required | Description | | --- | --- | --- | -| `--name ` | Yes | File name, including its extension. Path separators and dot segments are rejected. | -| `--content-type ` | No | MIME type. When omitted, it is inferred from the file extension. | | `--folder ` | No | Folder path as shown in the app; the leading / is optional. | -| `--content ` | No | Initial file content. Omit or send an empty string for a zero-byte file. The 70,000,000-character bound guards the JSON envelope; the decoded bytes must be at most 50 MiB, and a longer base64 payload is rejected with `413`. Use an upload session for anything larger. | -| `--encoding ` | No | Encoding of the content field. Accepted values: `utf-8`, `base64`. | +| `--recursive` | No | Include subfolders in the folder filter. Defaults to true when searching and false otherwise. Ignored without a folder filter. | +| `--no-recursive` | No | Send --recursive as false. | +| `--scope ` | No | Which lifecycle set to list: `active` (default) for live files, `archived` for files a delete soft-deleted. `folderPath` resolves against active folders only, so pairing it with `scope=archived` returns an empty page when the containing folder was archived too. Accepted values: `active`, `archived`. | +| `--search ` | No | Case-insensitive substring match against the file name. | +| `--sort-by ` | No | Field used to sort the result. Do not rely on case-insensitive ordering when sorting by `name`. Defaults to "uploadedAt". Accepted values: `name`, `size`, `uploadedAt`, `updatedAt`. | +| `--sort-order ` | No | Sort direction. Defaults to "asc". Accepted values: `asc`, `desc`. | +| `--limit ` | No | Maximum items to return (0 for everything). Defaults to `0`. | -## Create a file folder at a path +API request and response schemas: [listFiles](/api-reference/files/listFiles). + +### Search file content ```bash -sim files folders create +sim files search [options] ``` -**Arguments** +**Options** -| Argument | Required | Description | +| Option | Required | Description | | --- | --- | --- | -| `path` | Yes | Folder path as shown in the app; the leading / is optional | +| `--query ` | Yes | Regular expression, or exact text when `mode` is `exact`. | +| `--mode ` | No | How `query` is read. Defaults to "regex". Accepted values: `exact`, `regex`. | +| `--max-results ` | No | Maximum matching lines to return. Defaults to 50. | +| `--folder ` | No | Folders to search, by path as shown in the app; omit to search the whole workspace (space-separated, or @path / @- with one value per line; @@value for a literal leading @). | +| `--include-subfolders` | No | Whether each folder scope includes nested folders; on by default. | +| `--no-include-subfolders` | No | Send --include-subfolders as false. | -## Delete folder +API request and response schemas: [searchFileContent](/api-reference/files/searchFileContent). + +### Show file metadata and sharing status ```bash -sim files folders delete [options] +sim files describe [options] ``` **Arguments** @@ -74,7 +102,7 @@ sim files folders delete [options] | Argument | Required | Description | | --- | --- | --- | -| `path` | Yes | Folder path as shown in the app; the leading / is optional | +| `fileId` | Yes | File identifier. | @@ -84,18 +112,29 @@ sim files folders delete [options] | Option | Required | Description | | --- | --- | --- | -| `--recursive` | No | Delete the folder and its descendants. | -| `-y, --yes` | Yes | Confirm this operation. | +| `--scope ` | No | Which lifecycle set to read from: `active` (default) resolves live files only and returns `404` for a file a delete soft-deleted; `archived` also resolves soft-deleted files, so metadata stays readable before the file is restored. Authorization is identical for both. Accepted values: `active`, `archived`. | -## List folders +API request and response schemas: [getFile](/api-reference/files/getFile). + +## Upload, create, and read + +### Upload a file to the workspace ```bash -sim files folders list [options] +sim files upload [options] ``` -Also available as `sim files folders ls`. +**Arguments** + + + +| Argument | Required | Description | +| --- | --- | --- | +| `path` | Yes | Local file to upload | + + **Options** @@ -103,39 +142,39 @@ Also available as `sim files folders ls`. | Option | Required | Description | | --- | --- | --- | -| `--parent ` | No | Direct parent folder path. | -| `--search ` | No | Case-insensitive substring match against the folder name. | -| `--sort-by ` | No | Field used to sort the result. Sorting by `name` is case-sensitive and follows the storage collation, so do not rely on a case-insensitive order. Accepted values: `name`, `createdAt`, `updatedAt`. | -| `--sort-order ` | No | Sort direction. Accepted values: `asc`, `desc`. | -| `--scope ` | No | Which lifecycle set to list: `active` (default) returns live folders only; `archived` returns folders a recursive delete soft-deleted, which is how a caller finds a path to hand to the folder restore. Authorization is identical for both. Accepted values: `active`, `archived`. | -| `--recursive ` | No | Whether parentPath includes every descendant instead of direct children only. Accepted values: `true`, `1`, `yes`, `on`, `y`, `enabled`, `false`, `0`, `no`, `off`, `n`, `disabled`. | -| `--depth ` | No | Deepest level below parentPath to include when recursive is true. | +| `--folder ` | No | Folder path as shown in the app; defaults to the root folder. | +| `--name ` | No | Store it under a different name. | -## Rename or move a file folder +API request and response schemas: [createFileUpload](/api-reference/files/createFileUpload), [createFileUploadPartUrls](/api-reference/files/createFileUploadPartUrls), [completeFileUpload](/api-reference/files/completeFileUpload), [abortFileUpload](/api-reference/files/abortFileUpload). + +### Create file ```bash -sim files folders move +sim files create [options] ``` -Also available as `sim files folders mv`. - -**Arguments** +**Options** -| Argument | Required | Description | +| Option | Required | Description | | --- | --- | --- | -| `path` | Yes | Folder path as shown in the app; the leading / is optional | -| `destination` | Yes | Folder path as shown in the app; the leading / is optional | +| `--name ` | Yes | File name, including its extension. Path separators and dot segments are rejected. | +| `--content-type ` | No | MIME type. When omitted, it is inferred from the file extension. | +| `--folder ` | No | Folder path as shown in the app; the leading / is optional. | +| `--content ` | No | Initial file content. Omit or send an empty string for a zero-byte file. The complete JSON request is capped at 10 MiB, including encoding and the envelope; the separate decoded-file limit is 50 MiB. For larger payloads, use `sim files upload `. Defaults to "". | +| `--encoding ` | No | Encoding of the content field. Defaults to "utf-8". Accepted values: `utf-8`, `base64`. | -## Restore an archived file folder +API request and response schemas: [createFile](/api-reference/files/createFile). + +### Download a file’s content to stdout or a local file ```bash -sim files folders restore +sim files get [options] ``` **Arguments** @@ -144,14 +183,27 @@ sim files folders restore | Argument | Required | Description | | --- | --- | --- | -| `path` | Yes | Folder path as shown in the app; the leading / is optional | +| `fileId` | Yes | File whose content to read | -## Delete file +**Options** + + + +| Option | Required | Description | +| --- | --- | --- | +| `-o, --output-file ` | No | Write content to a file instead of stdout. | +| `--force` | No | Overwrite --output-file if it already exists. | + + + +API request and response schemas: [downloadFile](/api-reference/files/downloadFile). + +### Read a file’s text content as JSON or YAML ```bash -sim files delete [options] +sim files read [options] ``` **Arguments** @@ -160,7 +212,7 @@ sim files delete [options] | Argument | Required | Description | | --- | --- | --- | -| `fileId` | Yes | File identifier. | +| `fileId` | Yes | File identifier, or the file’s VFS path: `files//`, or `uploads/` for a Chat upload. | @@ -170,14 +222,20 @@ sim files delete [options] | Option | Required | Description | | --- | --- | --- | -| `-y, --yes` | Yes | Confirm this operation. | +| `--max-bytes ` | No | Optional ceiling on the source bytes fed to the parser, lowering but never raising the server limit. | +| `--offset ` | No | First line to return, 1-based; 0 also starts at the first line. Absent starts at the first line. | +| `--limit ` | No | How many lines to return from `offset`. Absent reads to the end. | -## Permanently delete a previous version of a file +API request and response schemas: [readFileText](/api-reference/files/readFileText). + +## Edit and organize + +### Apply one exact or anchor-based edit to a text file ```bash -sim files versions delete [options] +sim files edit [options] ``` **Arguments** @@ -187,7 +245,6 @@ sim files versions delete [options] | Argument | Required | Description | | --- | --- | --- | | `fileId` | Yes | File identifier. | -| `version` | Yes | Version number. | @@ -197,14 +254,17 @@ sim files versions delete [options] | Option | Required | Description | | --- | --- | --- | -| `-y, --yes` | Yes | Confirm this operation. | +| `--edit ` | Yes | One edit object: {"mode":"search_replace","search":"old","content":"new","replaceAll":false}, {"mode":"replace_between","beforeAnchor":"start line","afterAnchor":"end line","content":"new"}, {"mode":"insert_after","anchor":"line","content":"new"}, or {"mode":"delete_between","startAnchor":"first line deleted","endAnchor":"ending line kept"}. Anchored modes also accept occurrence starting at 1 (JSON, or @path / @- to read a file or stdin). | +| `--expected-revision ` | No | Revision from Get file metadata or an earlier write; the request is refused with `409` when the content moved on. | -## Show the metadata of one version of a file +API request and response schemas: [editFileContent](/api-reference/files/editFileContent). + +### Replace a file’s contents ```bash -sim files versions describe +sim files set-content [options] ``` **Arguments** @@ -214,14 +274,27 @@ sim files versions describe | Argument | Required | Description | | --- | --- | --- | | `fileId` | Yes | File identifier. | -| `version` | Yes | Version number. | -## List the recorded versions of a file +**Options** + + + +| Option | Required | Description | +| --- | --- | --- | +| `--content ` | Yes | Complete replacement content for the file. The complete JSON request is capped at 10 MiB, including UTF-8 encoding, escaping, base64, and the envelope. The separate decoded-file limit is 50 MiB. Small patches can edit a larger stored text file without sending its full content. | +| `--encoding ` | No | Content encoding. Defaults to "utf-8". Accepted values: `utf-8`, `base64`. | +| `--expected-revision ` | No | Revision from Get file metadata or an earlier write; the request is refused with `409` when the content moved on. | + + + +API request and response schemas: [updateFileContent](/api-reference/files/updateFileContent). + +### Rename a file ```bash -sim files versions list [options] +sim files rename [options] ``` **Arguments** @@ -240,29 +313,19 @@ sim files versions list [options] | Option | Required | Description | | --- | --- | --- | -| `--sort-by ` | No | Field used to sort the result. Accepted values: `version`. | -| `--sort-order ` | No | Sort direction. Accepted values: `asc`, `desc`. | -| `--limit ` | No | Maximum items to return (0 for everything). Defaults to `100`. | -| `--cursor ` | No | Continue from nextCursor returned by a previous result. | +| `--name ` | Yes | New file name, including its extension. | -## Read the text content of one version of a file as JSON or YAML +API request and response schemas: [renameFile](/api-reference/files/renameFile). + +### Move files into another folder ```bash -sim files versions read [options] +sim files move [options] ``` -**Arguments** - - - -| Argument | Required | Description | -| --- | --- | --- | -| `fileId` | Yes | File identifier. | -| `version` | Yes | Version number. | - - +Also available as `sim files mv`. **Options** @@ -270,16 +333,19 @@ sim files versions read [options] | Option | Required | Description | | --- | --- | --- | -| `--max-bytes ` | No | Optional ceiling on the source bytes fed to the parser, lowering but never raising the server limit. | -| `--offset ` | No | First line to return, 1-based; 0 also starts at the first line. Absent starts at the first line. | -| `--limit ` | No | How many lines to return from `offset`. Absent reads to the end. | +| `--file-ids ` | Yes | File identifiers to update. (space-separated, or @path / @- with one value per line; @@value for a literal leading @). | +| `--to ` | No | Destination folder path; omit for root. | -## Make a previous version of a file current again +API request and response schemas: [moveFileItems](/api-reference/files/moveFileItems). + +### Unzip an archive into a new folder beside it + +This writes every file in the archive into the workspace. ```bash -sim files versions revert [options] +sim files unzip [options] ``` **Arguments** @@ -289,7 +355,6 @@ sim files versions revert [options] | Argument | Required | Description | | --- | --- | --- | | `fileId` | Yes | File identifier. | -| `version` | Yes | Version number. | @@ -299,15 +364,18 @@ sim files versions revert [options] | Option | Required | Description | | --- | --- | --- | -| `--expected-current-version ` | No | Revert only while this is still the current version; otherwise the request fails with `409`. Omit to revert whatever is current. Collaborative edits and repeated workflow writes that fold into the current version keep its number, so prefer `expectedRevision` to guard content. | -| `--expected-revision ` | No | Revert only while the file still holds the content this revision names, as returned by Get File Metadata or an earlier write; otherwise the request fails with `409`. Unlike a version number, it also catches edits that folded into the current version. | +| `-y, --yes` | Yes | Confirm this operation. | -## Download the content of one version of a file +API request and response schemas: [unzipFile](/api-reference/files/unzipFile). + +## Sharing + +### Show a file’s share settings ```bash -sim files versions download [options] +sim files share get ``` **Arguments** @@ -317,25 +385,17 @@ sim files versions download [options] | Argument | Required | Description | | --- | --- | --- | | `fileId` | Yes | File identifier. | -| `version` | Yes | Version number. | -**Options** +API request and response schemas: [getFileShare](/api-reference/files/getFileShare). - +### Enable or disable sharing for a file -| Option | Required | Description | -| --- | --- | --- | -| `-o, --output-file ` | No | Write content to a file instead of stdout. | -| `--force` | No | Overwrite --output-file if it already exists. | - - - -## Apply one exact or anchor-based edit to a text file +OAuth login or personal API key required. ```bash -sim files edit [options] +sim files share set [options] ``` **Arguments** @@ -354,15 +414,21 @@ sim files edit [options] | Option | Required | Description | | --- | --- | --- | -| `--edit ` | Yes | One edit object: {"mode":"search_replace","search":"old","content":"new","replaceAll":false}, {"mode":"replace_between","beforeAnchor":"start line","afterAnchor":"end line","content":"new"}, {"mode":"insert_after","anchor":"line","content":"new"}, or {"mode":"delete_between","startAnchor":"first line deleted","endAnchor":"ending line kept"}. Anchored modes also accept occurrence starting at 1 (JSON, or @path / @- to read a file or stdin). | -| `--expected-revision ` | No | Revision from Get File Metadata or an earlier write; the request is refused with `409` when the content moved on. | +| `--is-active ` | Yes | Whether the share should resolve. Disabling preserves the token and the whole access configuration, so re-enabling restores the share as it was; enabling rewrites the credentials the resulting mode does not use. Accepted values: `true`, `false`. | +| `--auth-type ` | No | How access to the share is gated. The stored mode is kept when omitted. Enabling `public` clears the stored password and empties `allowedEmails`; `password` empties `allowedEmails`; `email` and `sso` clear the stored password. Accepted values: `public`, `password`, `email`, `sso`. | +| `--password ` | No | Password of 15 to 1024 characters for a password-gated share. Kept when omitted; enabling `password` with neither a supplied nor a stored password is a 400. Taken literally, except that a request from the Sim agent resolves a whole-value `{{ENV_VAR}}` reference to that variable before the rules apply. | +| `--allowed-emails ` | No | Allowed addresses or `@domain` patterns for email and SSO shares. Kept when omitted; enabling `email` or `sso` with an empty resulting list is a 400. (space-separated, or @path / @- with one value per line; @@value for a literal leading @). | -## Show file metadata and sharing status +API request and response schemas: [upsertFileShare](/api-reference/files/upsertFileShare). + +## Versions + +### List the recorded versions of a file ```bash -sim files describe [options] +sim files versions list [options] ``` **Arguments** @@ -381,14 +447,19 @@ sim files describe [options] | Option | Required | Description | | --- | --- | --- | -| `--scope ` | No | Which lifecycle set to read from: `active` (default) resolves live files only and returns `404` for a file a delete soft-deleted; `archived` also resolves soft-deleted files, so metadata stays readable before the file is restored. Authorization is identical for both. Accepted values: `active`, `archived`. | +| `--sort-by ` | No | Field used to sort the result. Defaults to "version". Accepted values: `version`. | +| `--sort-order ` | No | Sort direction. Defaults to "desc". Accepted values: `asc`, `desc`. | +| `--limit ` | No | Maximum items to return (0 for everything). Defaults to `100`. | +| `--cursor ` | No | Continue from nextCursor returned by a previous result. | -## Show a file’s share settings +API request and response schemas: [listFileVersions](/api-reference/files/listFileVersions). + +### Show the metadata of one version of a file ```bash -sim files share get +sim files versions describe ``` **Arguments** @@ -398,17 +469,18 @@ sim files share get | Argument | Required | Description | | --- | --- | --- | | `fileId` | Yes | File identifier. | +| `version` | Yes | Version number. | -## Enable or disable sharing for a file +API request and response schemas: [getFileVersion](/api-reference/files/getFileVersion). + +### Read the text content of one version of a file as JSON or YAML ```bash -sim files share set [options] +sim files versions read [options] ``` -Enable or disable sharing for a file (OAuth login or personal API key required) - **Arguments** @@ -416,6 +488,7 @@ Enable or disable sharing for a file (OAuth login or personal API key required) | Argument | Required | Description | | --- | --- | --- | | `fileId` | Yes | File identifier. | +| `version` | Yes | Version number. | @@ -425,59 +498,48 @@ Enable or disable sharing for a file (OAuth login or personal API key required) | Option | Required | Description | | --- | --- | --- | -| `--is-active ` | Yes | Whether the share should resolve. Disabling preserves the token and the whole access configuration, so re-enabling restores the share as it was; enabling rewrites the credentials the resulting mode does not use. Accepted values: `true`, `false`. | -| `--auth-type ` | No | How access to the share is gated. The stored mode is kept when omitted. Enabling `public` clears the stored password and empties `allowedEmails`; `password` empties `allowedEmails`; `email` and `sso` clear the stored password. Accepted values: `public`, `password`, `email`, `sso`. | -| `--password ` | No | Password of 15 to 1024 characters for a password-gated share. Kept when omitted; enabling `password` with neither a supplied nor a stored password is a 400. Taken literally, except that a request from the Sim agent resolves a whole-value `{{ENV_VAR}}` reference to that variable before the rules apply. | -| `--allowed-emails ` | No | Allowed addresses or `@domain` patterns for email and SSO shares. Kept when omitted; enabling `email` or `sso` with an empty resulting list is a 400. (space-separated, or @path / @- with one value per line; @@value for a literal leading @). | +| `--max-bytes ` | No | Optional ceiling on the source bytes fed to the parser, lowering but never raising the server limit. | +| `--offset ` | No | First line to return, 1-based; 0 also starts at the first line. Absent starts at the first line. | +| `--limit ` | No | How many lines to return from `offset`. Absent reads to the end. | -## List files +API request and response schemas: [readFileVersionText](/api-reference/files/readFileVersionText). + +### Download the content of one version of a file ```bash -sim files list [options] +sim files versions download [options] ``` -**Options** +**Arguments** -| Option | Required | Description | +| Argument | Required | Description | | --- | --- | --- | -| `--folder ` | No | Folder path as shown in the app; the leading / is optional. | -| `--recursive` | No | Include subfolders in the folder filter. Defaults to true when searching and false otherwise. Ignored without a folder filter. | -| `--no-recursive` | No | Send --recursive as false. | -| `--scope ` | No | Which lifecycle set to list: `active` (default) for live files, `archived` for files a delete soft-deleted. `folderPath` resolves against active folders only, so pairing it with `scope=archived` returns an empty page when the containing folder was archived too. Accepted values: `active`, `archived`. | -| `--search ` | No | Case-insensitive substring match against the file name. | -| `--sort-by ` | No | Field used to sort the result. Sorting by `name` is case-sensitive and follows the storage collation, so do not rely on a case-insensitive order. Accepted values: `name`, `size`, `uploadedAt`, `updatedAt`. | -| `--sort-order ` | No | Sort direction. Accepted values: `asc`, `desc`. | -| `--limit ` | No | Maximum items to return (0 for everything). Defaults to `0`. | +| `fileId` | Yes | File identifier. | +| `version` | Yes | Version number. | -## Move files into another folder - -```bash -sim files move [options] -``` - -Also available as `sim files mv`. - **Options** | Option | Required | Description | | --- | --- | --- | -| `--file-ids ` | Yes | File identifiers to update. (space-separated, or @path / @- with one value per line; @@value for a literal leading @). | -| `--to ` | No | Destination folder path; omit for root. | +| `-o, --output-file ` | No | Write content to a file instead of stdout. | +| `--force` | No | Overwrite --output-file if it already exists. | -## Read a file’s text content as JSON or YAML +API request and response schemas: [downloadFileVersion](/api-reference/files/downloadFileVersion). + +### Make a previous version of a file current again ```bash -sim files read [options] +sim files versions revert [options] ``` **Arguments** @@ -486,7 +548,8 @@ sim files read [options] | Argument | Required | Description | | --- | --- | --- | -| `fileId` | Yes | File identifier, or the file’s VFS path: `files/<folder>/<name>`, or `uploads/<name>` for a Chat upload. | +| `fileId` | Yes | File identifier. | +| `version` | Yes | Version number. | @@ -496,16 +559,19 @@ sim files read [options] | Option | Required | Description | | --- | --- | --- | -| `--max-bytes ` | No | Optional ceiling on the source bytes fed to the parser, lowering but never raising the server limit. | -| `--offset ` | No | First line to return, 1-based; 0 also starts at the first line. Absent starts at the first line. | -| `--limit ` | No | How many lines to return from `offset`. Absent reads to the end. | +| `--expected-current-version ` | No | Revert only while this is still the current version; otherwise the request fails with `409`. Omit to revert whatever is current. Collaborative edits and repeated workflow writes that fold into the current version keep its number, so prefer `expectedRevision` to guard content. | +| `--expected-revision ` | No | Revert only while the file still holds the content this revision names, as returned by Get file metadata or an earlier write; otherwise the request fails with `409`. Unlike a version number, it also catches edits that folded into the current version. | -## Rename a file +API request and response schemas: [revertFileVersion](/api-reference/files/revertFileVersion). + +### Permanently delete a previous version of a file + +This permanently removes the version from history and schedules deletion of its stored content; storage cleanup may retry in the background. ```bash -sim files rename [options] +sim files versions delete [options] ``` **Arguments** @@ -515,6 +581,7 @@ sim files rename [options] | Argument | Required | Description | | --- | --- | --- | | `fileId` | Yes | File identifier. | +| `version` | Yes | Version number. | @@ -524,14 +591,20 @@ sim files rename [options] | Option | Required | Description | | --- | --- | --- | -| `--name ` | Yes | New file name, including its extension. | +| `-y, --yes` | Yes | Confirm this operation. | -## Restore an archived file +API request and response schemas: [deleteFileVersion](/api-reference/files/deleteFileVersion). + +## Archive and restore + +### Delete file + +This archives the file. ```bash -sim files restore +sim files delete [options] ``` **Arguments** @@ -544,42 +617,25 @@ sim files restore -## Search file content - -```bash -sim files search [options] -``` - **Options** | Option | Required | Description | | --- | --- | --- | -| `--query ` | Yes | Regular expression, or exact text when `mode` is `exact`. | -| `--mode ` | No | How `query` is read. Accepted values: `exact`, `regex`. | -| `--max-results ` | No | Maximum matching lines to return. | -| `--folder ` | No | Folders to search, by path as shown in the app; omit to search the whole workspace (space-separated, or @path / @- with one value per line; @@value for a literal leading @). | -| `--include-subfolders` | No | Whether each folder scope includes nested folders; on by default. | -| `--no-include-subfolders` | No | Send --include-subfolders as false. | +| `-y, --yes` | Yes | Confirm this operation. | -## Unzip an archive into a new folder beside it +API request and response schemas: [deleteFile](/api-reference/files/deleteFile). -```bash -sim files unzip [options] -``` +### Delete several files at once -**Arguments** - - +This archives the listed files; restore them with `files restore`. -| Argument | Required | Description | -| --- | --- | --- | -| `fileId` | Yes | File identifier. | - - +```bash +sim files batch-delete [options] +``` **Options** @@ -587,14 +643,17 @@ sim files unzip [options] | Option | Required | Description | | --- | --- | --- | +| `--file-ids ` | Yes | File identifiers to delete. (space-separated, or @path / @- with one value per line; @@value for a literal leading @). | | `-y, --yes` | Yes | Confirm this operation. | -## Replace a file’s contents +API request and response schemas: [bulkDeleteFiles](/api-reference/files/bulkDeleteFiles). + +### Restore an archived file ```bash -sim files set-content [options] +sim files restore ``` **Arguments** @@ -607,22 +666,40 @@ sim files set-content [options] +API request and response schemas: [restoreFile](/api-reference/files/restoreFile). + +## Folders + +### List folders + +```bash +sim files folders list [options] +``` + +Also available as `sim files folders ls`. + **Options** | Option | Required | Description | | --- | --- | --- | -| `--content ` | Yes | Complete replacement content for the file. The 70,000,000-character bound guards the JSON envelope; the decoded bytes must be at most 50 MiB, and a longer base64 payload is rejected with `413`. | -| `--encoding ` | No | Content encoding. Accepted values: `utf-8`, `base64`. | -| `--expected-revision ` | No | Revision from Get File Metadata or an earlier write; the request is refused with `409` when the content moved on. | +| `--parent ` | No | Direct parent folder path. | +| `--search ` | No | Case-insensitive substring match against the folder name. | +| `--sort-by ` | No | Field used to sort the result. Do not rely on case-insensitive ordering when sorting by `name`. Defaults to "name". Accepted values: `name`, `createdAt`, `updatedAt`. | +| `--sort-order ` | No | Sort direction. Defaults to "asc". Accepted values: `asc`, `desc`. | +| `--scope ` | No | Which lifecycle set to list: `active` (default) returns live folders only; `archived` returns folders a recursive delete soft-deleted, which is how a caller finds a path to hand to the folder restore. Authorization is identical for both. Accepted values: `active`, `archived`. | +| `--recursive ` | No | Whether parentPath includes every descendant instead of direct children only. Accepted values: `true`, `1`, `yes`, `on`, `y`, `enabled`, `false`, `0`, `no`, `off`, `n`, `disabled`. | +| `--depth ` | No | Deepest level below parentPath to include when recursive is true. | -## Upload a file to the workspace +API request and response schemas: [listFileFolders](/api-reference/files/listFilesFolders). + +### Create a file folder at a path ```bash -sim files upload [options] +sim files folders create ``` **Arguments** @@ -631,25 +708,18 @@ sim files upload [options] | Argument | Required | Description | | --- | --- | --- | -| `path` | Yes | Local file to upload | +| `path` | Yes | Folder path as shown in the app; the leading / is optional | -**Options** +API request and response schemas: [createFileFolder](/api-reference/files/createFilesFolder). - +### Delete folder -| Option | Required | Description | -| --- | --- | --- | -| `--folder ` | No | Folder path as shown in the app; defaults to the root folder. | -| `--name ` | No | Store it under a different name. | - - - -## Download a file’s content to stdout or a local file +This archives the file folder and, when recursive, everything inside it. ```bash -sim files get [options] +sim files folders delete [options] ``` **Arguments** @@ -658,7 +728,7 @@ sim files get [options] | Argument | Required | Description | | --- | --- | --- | -| `fileId` | Yes | File whose content to read | +| `path` | Yes | Folder path as shown in the app; the leading / is optional | @@ -668,15 +738,17 @@ sim files get [options] | Option | Required | Description | | --- | --- | --- | -| `-o, --output-file ` | No | Write content to a file instead of stdout. | -| `--force` | No | Overwrite --output-file if it already exists. | +| `--recursive` | No | Archive the folder and its descendants. Defaults to "false". | +| `-y, --yes` | Yes | Confirm this operation. | -## List file resources and child folders together +API request and response schemas: [deleteFileFolder](/api-reference/files/deleteFilesFolder). + +### Restore an archived file folder ```bash -sim files ls [path] [options] +sim files folders restore ``` **Arguments** @@ -685,22 +757,34 @@ sim files ls [path] [options] | Argument | Required | Description | | --- | --- | --- | -| `path` | No | Folder path to list; defaults to the root folder | +| `path` | Yes | Folder path as shown in the app; the leading / is optional | -**Options** +API request and response schemas: [restoreFileFolder](/api-reference/files/restoreFilesFolder). + +### Rename or move a file folder + +```bash +sim files folders move +``` + +Also available as `sim files folders mv`. + +**Arguments** -| Option | Required | Description | +| Argument | Required | Description | | --- | --- | --- | -| `--search ` | No | Filter folders and resources by name. | -| `--limit ` | No | Maximum combined items to return (0 for everything). Defaults to `0`. | +| `path` | Yes | Folder path as shown in the app; the leading / is optional | +| `destination` | Yes | Folder path as shown in the app; the leading / is optional | -## Create a file directory at a path +API request and response schemas: [relocateFileFolder](/api-reference/files/relocateFilesFolder). + +### Create a file directory at a path ```bash sim files mkdir @@ -715,3 +799,10 @@ sim files mkdir | `path` | Yes | Folder path to create; the leading / is optional | + +API request and response schemas: [createFileFolder](/api-reference/files/createFilesFolder). + +## Related docs + +- [Files](/files) +- [Output formats](/cli/output) diff --git a/apps/docs/content/docs/cli/index.mdx b/apps/docs/content/docs/cli/index.mdx index f9996d4c3f9..ce66c969e07 100644 --- a/apps/docs/content/docs/cli/index.mdx +++ b/apps/docs/content/docs/cli/index.mdx @@ -1,115 +1,89 @@ --- title: Sim CLI -description: Drive workflows, tables, files, knowledge bases, and logs from your shell +description: Run workflows and manage Sim resources from your terminal. --- -import { Step, Steps } from 'fumadocs-ui/components/steps' -import { Tab, Tabs } from 'fumadocs-ui/components/tabs' - -`sim` is the command line for Sim. Sign in once, then run workflows, query tables, -move files, search knowledge bases, and read run logs from the terminal. Results -are JSON by default, so they pipe into `jq`, cron jobs, CI pipelines, and coding -agents; use `--output table` to read them as tables. Don't know a command? Run -`sim cli search ""`. See [Output formats](/cli/output) for commands that emit raw content -or local configuration. +Use `sim` to run workflows, query tables, move files, search knowledge bases, and read logs. Structured results default to JSON for scripts, CI jobs, and coding agents. Select `--output table` for a readable table. ## Install - - - ```bash - npm install -g sim - ``` - - - ```bash - pnpm add -g sim - ``` - - - ```bash - bun add -g sim - ``` - - - -Requires Node.js 20 or newer. Verify with `sim --version`. - -The CLI shows optional update notices on eligible interactive invocations. Run -`sim update` when you want to install the update. See -[Updates](/cli/configuration#updates) for installation requirements and how to -disable notices. - -To run it without installing, use `npx sim `. - -Using Sim as a library instead? See the [TypeScript](/api-reference/typescript) -and [Python](/api-reference/python) SDKs, or the -[HTTP API](/api-reference/getting-started). +The installed CLI requires Node.js 20 or newer. Install it globally with Bun, then check the version: -## Your first command +```bash +bun add -g sim +sim --version +``` + +To run a command without a global installation: + +```bash +bunx sim --help +``` - +The package also supports npm and pnpm installations. Keep using the package manager that owns your installation when upgrading; another manager may install a second copy on your `PATH`. - -### Sign in +Eligible interactive invocations can show an update notice. Run `sim update` to update the active global installation. See [Updates](/cli/configuration#updates) for supported managers, release channels, and notice controls. + +## Your first command + +### 1. Sign in ```bash sim login ``` -The CLI opens your browser for approval. Local sign-in prefers OAuth; remote -terminals use API-key pairing. After OAuth sign-in, choose a default workspace -with `sim configure --set-workspace `. For SSH and containers, use -`sim login --method api-key --no-browser` and approve the pairing code. +Local sign-in prefers OAuth and opens a browser for approval. SSH sessions and headless Linux terminals select API-key pairing. To choose pairing explicitly without opening a browser: + +```bash +sim login --method api-key --no-browser +``` + +Approve the code shown in your terminal. See [Authentication](/cli/authentication) for CI credentials, remote terminals, multiple accounts, and self-hosted deployments. -See [Authentication](/cli/authentication) for CI keys, multiple accounts, and -self-hosted deployments. - +### 2. Choose a workspace - -### Check what you are pointed at +After OAuth login, list your workspaces and set a default: ```bash -sim whoami +sim workspaces list +sim configure --set-workspace ``` -This prints the resolved endpoint, workspace, and output format — and **where -each one came from**. It is the fastest way to explain a surprising result. - +Pairing sets the default workspace you choose on its approval page. Override that target for one command with `--workspace `. - -### List your workflows +### 3. Check the resolved settings ```bash -sim workflows list +sim whoami ``` +This shows the endpoint, credential type, workspace, and output format, including the source of each setting. It also checks authentication and access to the selected workspace. Use `--no-verify` to inspect settings offline. + +### 4. List and run a workflow + +```bash +sim workflows list --output table ``` -ID NAME FOLDER DEPLOYED RUNS LAST RUN -3a9e21d8-5f47-4c0b-b2ea-91d7c6034ef8 Refund triage /Support yes 412 2026-08-15 14:02:11 -b8c0d247-9e13-4a86-97f5-2ad4e1638c09 Weekly digest /Reporting no 18 2026-08-11 09:00:04 -``` - - -### Run one +Example table output; timestamps are UTC: + +```text +ID NAME FOLDER DEPLOYED RUNS LAST RUN +3a9e21d8-5f47-4c0b-b2ea-91d7c6034ef8 Refund triage /Support yes 412 2026-08-15 14:02:11 +b8c0d247-9e13-4a86-97f5-2ad4e1638c09 Weekly digest /Reporting no 18 2026-08-11 09:00:04 +``` ```bash sim workflows run 3a9e21d8-5f47-4c0b-b2ea-91d7c6034ef8 --input '{"ticketId":"T-4821"}' ``` -This command runs the active deployment. Deploy from the editor or with -`sim workflows deploy `. To run the current saved workflow state instead, -use `sim workflows run --manual`. - - - +Ordinary execution runs the active deployment. Deploy from the workflow builder or with `sim workflows deploy `. To execute the current saved workflow state, use `sim workflows run --manual`. ## How commands are shaped -Every command reads the same way: +Resource commands use this shape: -```bash +```text sim [sub-resource] [arguments] [options] ``` @@ -119,11 +93,18 @@ sim tables rows query tbl_9f3c1a05d4b7426e8c2f0917ab35de64 --limit 50 sim knowledge documents upload 4c1b7f60-2d55-4a3e-9c18-70b6ea2f9d31 ./handbook.pdf ``` -Some resource groups also accept a singular alias: `sim workflow get` and -`sim workflows get` are the same command. `knowledge` also answers to `kb`. -Each group’s reference lists its supported aliases. +In the installed CLI, commands such as `login`, `whoami`, `configure`, `update`, and `chat` run directly under `sim`. Local setup and maintenance commands are unavailable when Sim runs commands inside Chat; see [Configuration](/cli/configuration). Some resource groups have singular aliases: `sim workflow get` and `sim workflows get` are equivalent. `knowledge` also accepts `kb`; each group reference lists its aliases. + +## Find a command + +Search by the task you want to complete, then inspect the result's arguments and options: + +```bash +sim cli search "cancel a workflow run" +sim workflows runs cancel --help +``` -Every command accepts `--help`, at any depth: +Help is available at every depth: ```bash sim --help @@ -133,38 +114,40 @@ sim tables rows query --help ## What you can do -| Group | What it covers | +| Group | Capabilities | | --- | --- | -| [`workflows`](/cli/workflows) | Run, deploy, roll back, import, export, and organize workflows | -| [`logs`](/cli/logs) | Read run diagnostics, including the full trace tree | -| [`tables`](/cli/tables) | Query, insert, update, and import rows; manage columns and views | -| [`files`](/cli/files) | Upload, download, share, and organize workspace files | -| [`knowledge`](/cli/knowledge) | Search knowledge bases and manage their documents and tags | -| [`skills`](/cli/skills) | Manage agent skills | -| [`sandboxes`](/cli/sandboxes) | Manage sandbox dependencies, managed CLIs, and system packages | -| [`mcp-servers`](/cli/mcp-servers) | Manage MCP server connections and their tools | +| [`workflows`](/cli/workflows) | Build, deploy, run, roll back, import, export, and organize workflows | +| [`logs`](/cli/logs) | Inspect runs and recursive traces | +| [`tables`](/cli/tables) | Query and change rows; manage columns, views, imports, and exports | +| [`files`](/cli/files) | Upload, download, share, version, and organize workspace files | +| [`knowledge`](/cli/knowledge) | Search knowledge bases and manage documents, connectors, and tags | +| [`skills`](/cli/skills) | Manage skills and their editors | +| [`sandboxes`](/cli/sandboxes) | Configure dependencies, managed CLIs, and system packages | +| [`mcp-servers`](/cli/mcp-servers) | Connect external Model Context Protocol (MCP) servers and discover tools | | [`custom-tools`](/cli/custom-tools) | Manage custom tool definitions | | [`credentials`](/cli/credentials) | Connect, reconnect, and disconnect integration credentials | -| [`secrets`](/cli/secrets) | Set and remove workspace secrets | -| [`billing`](/cli/billing) | Check plan status and credit usage | -| [`audit-logs`](/cli/audit-logs) | Read organization audit logs | -| [`workspaces`](/cli/workspaces) | Inspect the active workspace and its members | -| [`blocks`](/cli/blocks) | Browse the block catalog and read one block's configuration fields | -| [`tools`](/cli/tools) | Browse and execute built-in tools | -| [`connector-types`](/cli/connector-types) | Browse knowledge-base connector types and their config fields | -| [`chat-deployments`](/cli/chat-deployments) | List the hosted chats a workspace serves | -| [`workflow-mcp-servers`](/cli/workflow-mcp-servers) | Publish workflows as MCP tools for outside agents | -| [`meta`](/cli/meta) | Check what this API supports and which limits apply | - -The [command overview](/cli/commands) has the global options and the commands -that take no resource; the [complete reference](/cli/reference) documents every -subcommand, argument, and flag on one page. Both are generated from the CLI -itself. - -## Where to go next - -- [Authentication](/cli/authentication) — signing in, API keys for CI, and multiple accounts -- [Configuration](/cli/configuration) — profiles, config files, environment variables, and precedence -- [Output formats](/cli/output) — `table`, `json`, `yaml`, and `text`, and when to use each -- [Scripting](/cli/scripting) — piping, file inputs, exit codes, and automation recipes -- [Troubleshooting](/cli/troubleshooting) — what each error means, and how to resolve it +| [`secrets`](/cli/secrets) | Manage personal and workspace secrets | +| [`workspaces`](/cli/workspaces) | Manage members, invitations, forks, and workspace sync | +| [`organizations`](/cli/organizations) | Manage organization access, members, usage, domains, and SSO | +| [`permission-groups`](/cli/permission-groups) | Manage restrictions and group membership | +| [`billing`](/cli/billing) | Inspect plan status and credit usage | +| [`audit-logs`](/cli/audit-logs) | Read organization audit actions | +| [`blocks`](/cli/blocks) | Inspect the block catalog and configuration fields | +| [`tools`](/cli/tools) | Inspect and execute built-in tools | +| [`connector-types`](/cli/connector-types) | Inspect knowledge-base connector types and fields | +| [`selectors`](/cli/selectors) | Discover and verify configuration choices | +| [`chat-deployments`](/cli/chat-deployments) | List deployed workflow chats | +| [`workflow-mcp-servers`](/cli/workflow-mcp-servers) | Expose deployed workflows as MCP tools | +| [`meta`](/cli/meta) | Inspect API availability and credential status | + +The [command overview](/cli/commands) lists global options and root commands. The [complete reference](/cli/reference) contains every subcommand, argument, and option on one page. Both are generated from the CLI. + +## Related docs + +- [Authentication](/cli/authentication) +- [Configuration](/cli/configuration) +- [Output formats](/cli/output) +- [Scripting](/cli/scripting) +- [Workflow imports and workspace sync](/cli/workflow-sync) +- [Troubleshooting](/cli/troubleshooting) +- [TypeScript SDK](/api-reference/typescript), [Python SDK](/api-reference/python), and [HTTP API](/api-reference/getting-started) diff --git a/apps/docs/content/docs/cli/knowledge.mdx b/apps/docs/content/docs/cli/knowledge.mdx index e449824c7b9..29bad7ed758 100644 --- a/apps/docs/content/docs/cli/knowledge.mdx +++ b/apps/docs/content/docs/cli/knowledge.mdx @@ -1,21 +1,46 @@ --- title: Knowledge -description: Manage knowledge — every subcommand, argument, and flag +description: Manage knowledge bases, indexed documents, search, tags, and connector syncs. --- import { CommandTable } from '@/components/ui/command-table' +Manage knowledge bases, indexed documents, search, tags, and connector syncs. + `sim knowledge` is also spelled `sim kb`. -Every command below also accepts the [global options](/cli/commands#global-options). +These commands accept the [global options](/cli/commands#global-options). + +## Knowledge bases -## Index files the workspace already stores +### List knowledge bases ```bash -sim knowledge from-workspace-files create [options] +sim knowledge list [options] ``` -Index files the workspace already stores (OAuth login or personal API key required) +**Options** + + + +| Option | Required | Description | +| --- | --- | --- | +| `--scope ` | No | Lifecycle scope: active or archived knowledge bases. Use Restore knowledge base to recover archived entries. Folder paths resolve only active folders, so filtering by an archived folder returns no matches. Defaults to "active". Accepted values: `active`, `archived`. | +| `--folder ` | No | Folder path as shown in the app; the leading / is optional. | +| `--search ` | No | Case-insensitive substring match against the resource name. | +| `--sort-by ` | No | Field used to sort the result. Do not rely on case-insensitive ordering when sorting by `name`. Defaults to "createdAt". Accepted values: `name`, `createdAt`, `updatedAt`. | +| `--sort-order ` | No | Sort direction. Defaults to "asc". Accepted values: `asc`, `desc`. | +| `--limit ` | No | Maximum items to return (0 for everything). Defaults to `0`. | + + + +API request and response schemas: [listKnowledgeBases](/api-reference/knowledge-bases/listKnowledgeBases). + +### Get knowledge base + +```bash +sim knowledge get +``` **Arguments** @@ -27,24 +52,35 @@ Index files the workspace already stores (OAuth login or personal API key requir +API request and response schemas: [getKnowledgeBase](/api-reference/knowledge-bases/getKnowledgeBase). + +### Create knowledge base + +```bash +sim knowledge create [options] +``` + **Options** | Option | Required | Description | | --- | --- | --- | -| `--file ` | Yes | Workspace file ID or key (repeatable) (space-separated, or @path / @- with one value per line; @@value for a literal leading @). | +| `--name ` | Yes | Human-readable knowledge base name. | +| `--description ` | No | Optional knowledge base description. | +| `--chunking-config ` | No | Chunking configuration; defaults are applied when omitted. (JSON, or @path / @- to read a file or stdin). | +| `--folder ` | No | Folder path as shown in the app; the leading / is optional. | -## Declare the tag definitions a knowledge base needs +API request and response schemas: [createKnowledgeBase](/api-reference/knowledge-bases/createKnowledgeBase). + +### Update knowledge base ```bash -sim knowledge tags save [options] +sim knowledge update [options] ``` -Declare the tag definitions a knowledge base needs (OAuth login or personal API key required) - **Arguments** @@ -61,18 +97,21 @@ Declare the tag definitions a knowledge base needs (OAuth login or personal API | Option | Required | Description | | --- | --- | --- | -| `--definitions ` | Yes | Tag definitions: [{"tagSlot":"tag1","displayName":"category","fieldType":"text"}] (JSON, or @path / @- to read a file or stdin). | +| `--name ` | No | New knowledge base name. | +| `--description ` | No | New knowledge base description. | +| `--chunking-config ` | No | New document chunking configuration. (JSON, or @path / @- to read a file or stdin). | +| `--folder ` | No | Folder path as shown in the app; the leading / is optional. | -## Create tag +API request and response schemas: [updateKnowledgeBase](/api-reference/knowledge-bases/updateKnowledgeBase). + +### Move a knowledge base to a folder ```bash -sim knowledge tags create [options] +sim knowledge mv ``` -Create Tag (OAuth login or personal API key required) - **Arguments** @@ -80,29 +119,20 @@ Create Tag (OAuth login or personal API key required) | Argument | Required | Description | | --- | --- | --- | | `knowledgeBaseId` | Yes | Unique knowledge base identifier. | +| `folder` | Yes | Folder path as shown in the app; the leading / is optional | -**Options** - - - -| Option | Required | Description | -| --- | --- | --- | -| `--display-name ` | Yes | Name tag filters and document reads use for this tag. | -| `--field-type ` | No | Value type stored in the slot; it decides which slots are usable and which filter operators apply. Defaults to text, so a number, date, or boolean slot must name its type here. Slot capacity per type: text 7, number 5, date 2, boolean 3. Accepted values: `text`, `number`, `date`, `boolean`. | -| `--tag-slot ` | No | Slot to store the tag in. Omit to take the next free slot for the field type; a slot that does not belong to the field type, or one already in use, is rejected. Accepted values: `tag1`, `tag2`, `tag3`, `tag4`, `tag5`, `tag6`, `tag7`, `number1`, `number2`, `number3`, `number4`, `number5`, `date1`, `date2`, `boolean1`, `boolean2`, `boolean3`. | +API request and response schemas: [updateKnowledgeBase](/api-reference/knowledge-bases/updateKnowledgeBase). - +### Delete knowledge base -## Delete tag +This archives the knowledge base and every document in it; restore with `knowledge restore`. ```bash -sim knowledge tags delete [options] +sim knowledge delete [options] ``` -Delete Tag (OAuth login or personal API key required) - **Arguments** @@ -110,7 +140,6 @@ Delete Tag (OAuth login or personal API key required) | Argument | Required | Description | | --- | --- | --- | | `knowledgeBaseId` | Yes | Unique knowledge base identifier. | -| `tagId` | Yes | Unique tag definition identifier. | @@ -124,14 +153,14 @@ Delete Tag (OAuth login or personal API key required) -## Remove tag definitions no document still uses +API request and response schemas: [deleteKnowledgeBase](/api-reference/knowledge-bases/deleteKnowledgeBase). + +### Restore an archived knowledge base ```bash -sim knowledge tags cleanup [options] +sim knowledge restore ``` -Remove tag definitions no document still uses (OAuth login or personal API key required) - **Arguments** @@ -142,33 +171,49 @@ Remove tag definitions no document still uses (OAuth login or personal API key r +API request and response schemas: [restoreKnowledgeBase](/api-reference/knowledge-bases/restoreKnowledgeBase). + +## Search and export + +### Search knowledge + +```bash +sim knowledge search [options] +``` + **Options** | Option | Required | Description | | --- | --- | --- | -| `--unused` | No | Whether to remove only the tag definitions no document in the knowledge base still carries a value for. Defaults to true. Pass --no-unused to delete every definition on the knowledge base, which also clears its slot on every document and chunk and is not recoverable. | -| `--no-unused` | No | Send --unused as false. | -| `-y, --yes` | Yes | Confirm this operation. | +| `--kb ` | Yes | Knowledge base ID (repeatable) (space-separated, or @path / @- with one value per line; @@value for a literal leading @). | +| `--query ` | No | Text to search for. | +| `--top-k ` | No | Maximum number of search results to return. Must be a whole number between 1 and 100. Defaults to 10. | +| `--tag-filters ` | No | Tag filters as [{"tagName":"...","operator":"...","value":"..."}] (JSON, or @path / @- to read a file or stdin). | +| `--search-mode ` | No | Search algorithm. Accepted values: `vector`, `hybrid`. | +| `--reranker-enabled` | No | Reorder retrieved chunks with a reranking model before truncating to `topK`. Ignored for tag-only searches. A completed reranking call adds a search unit. If reranking is unavailable, results keep their retrieval order; check `rerankerStatus`. | +| `--no-reranker-enabled` | No | Send --reranker-enabled as false. | +| `--reranker-model ` | No | Reranking model to use when `rerankerEnabled` is true. Defaults to `rerank-v4.0-fast`. Accepted values: `rerank-v4.0-pro`, `rerank-v4.0-fast`, `rerank-v3.5`. | +| `--reranker-input-count ` | No | How many candidate chunks to retrieve before reranking. Defaults to four times `topK`, capped at 100. A larger pool costs more retrieval work but gives the reranker more to choose from. | -## Show which tag slot a create would take for a field type +API request and response schemas: [searchKnowledge](/api-reference/knowledge-bases/searchKnowledge). + +### Export a knowledge base as a .simkb.zip bundle ```bash -sim knowledge tags next-slot [options] +sim knowledge export [options] ``` -Show which tag slot a create would take for a field type (OAuth login or personal API key required) - **Arguments** | Argument | Required | Description | | --- | --- | --- | -| `knowledgeBaseId` | Yes | Unique knowledge base identifier. | +| `knowledgeBaseId` | Yes | Knowledge base to export | @@ -178,14 +223,20 @@ Show which tag slot a create would take for a field type (OAuth login or persona | Option | Required | Description | | --- | --- | --- | -| `--field-type ` | Yes | Value type stored in the slot; it decides which slots are usable and which filter operators apply. Slot capacity per type: text 7, number 5, date 2, boolean 3. Accepted values: `text`, `number`, `date`, `boolean`. | +| `-o, --output-file ` | No | Write the bundle to this path instead of the name the server suggests; pass - to stream it to stdout. | +| `--force` | No | Overwrite --output-file if it already exists. | +| `--no-vectors` | No | Leave chunk vectors out of the bundle, so an import re-embeds every chunk. | -## List tags +API request and response schemas: [exportKnowledgeBase](/api-reference/knowledge-bases/exportKnowledgeBase). + +## Documents + +### List documents ```bash -sim knowledge tags list +sim knowledge documents list [options] ``` **Arguments** @@ -198,14 +249,30 @@ sim knowledge tags list -## Show how many documents and chunks carry each tag +**Options** + + + +| Option | Required | Description | +| --- | --- | --- | +| `--limit ` | No | Maximum items to return (0 for everything). Defaults to `100`. | +| `--search ` | No | Case-insensitive substring match against the document filename. | +| `--enabled-filter ` | No | Filter by whether documents are enabled for search. Defaults to "all". Accepted values: `all`, `enabled`, `disabled`. | +| `--sort-by ` | No | Field used to sort the result. Do not rely on case-insensitive ordering when sorting by `filename`. Defaults to "uploadedAt". Accepted values: `filename`, `fileSize`, `tokenCount`, `chunkCount`, `uploadedAt`, `processingStatus`, `enabled`. | +| `--sort-order ` | No | Sort direction. Defaults to "desc". Accepted values: `asc`, `desc`. | +| `--cursor ` | No | Continue from nextCursor returned by a previous result. | +| `--tag-filters ` | No | A JSON-encoded array of at most 10 tag filters, using the same display-name shape as knowledge search: `[{"tagName":"category","operator":"eq","value":"billing"}]`. Every filter must hold, including two that name the same tag. A name that is not defined in this knowledge base is rejected, never ignored. | + + + +API request and response schemas: [listKnowledgeDocuments](/api-reference/knowledge-bases/listKnowledgeDocuments). + +### Get document ```bash -sim knowledge tags usage +sim knowledge documents get ``` -Show how many documents and chunks carry each tag (OAuth login or personal API key required) - **Arguments** @@ -213,25 +280,26 @@ Show how many documents and chunks carry each tag (OAuth login or personal API k | Argument | Required | Description | | --- | --- | --- | | `knowledgeBaseId` | Yes | Unique knowledge base identifier. | +| `documentId` | Yes | Unique knowledge document identifier. | -## Update tag +API request and response schemas: [getKnowledgeDocument](/api-reference/knowledge-bases/getKnowledgeDocument). + +### Upload a document to a knowledge base ```bash -sim knowledge tags update [options] +sim knowledge documents upload [options] ``` -Update Tag (OAuth login or personal API key required) - **Arguments** | Argument | Required | Description | | --- | --- | --- | -| `knowledgeBaseId` | Yes | Unique knowledge base identifier. | -| `tagId` | Yes | Unique tag definition identifier. | +| `knowledgeBaseId` | Yes | Knowledge base to upload into | +| `path` | Yes | Local file to upload | @@ -241,19 +309,23 @@ Update Tag (OAuth login or personal API key required) | Option | Required | Description | | --- | --- | --- | -| `--display-name ` | No | New tag display name. | -| `--field-type ` | No | New value type for the tag. Accepted values: `text`, `number`, `date`, `boolean`. | +| `--name ` | No | Store it under a different name. | +| `--tag ` | No | Document tags, in tag1 through tag7 order. | +| `--recipe ` | No | Document processing recipe. Accepted values: `default`, `plain`, `markdown`, `code`. | +| `--lang ` | No | Document language tag: hyphen-separated letter and digit subtags, for example en or en-US. | -## Enable, disable, or delete many chunks at once +API request and response schemas: [createKnowledgeDocumentUpload](/api-reference/knowledge-bases/createKnowledgeDocumentUpload), [createKnowledgeDocumentUploadPartUrls](/api-reference/knowledge-bases/createKnowledgeDocumentUploadPartUrls), [completeKnowledgeDocumentUpload](/api-reference/knowledge-bases/completeKnowledgeDocumentUpload), [abortKnowledgeDocumentUpload](/api-reference/knowledge-bases/abortKnowledgeDocumentUpload). + +### Update document + +OAuth login or personal API key required. ```bash -sim knowledge chunks batch-update [options] +sim knowledge documents update [options] ``` -Enable, disable, or delete many chunks at once (OAuth login or personal API key required) - **Arguments** @@ -271,20 +343,43 @@ Enable, disable, or delete many chunks at once (OAuth login or personal API key | Option | Required | Description | | --- | --- | --- | -| `--operation ` | Yes | What to do with the selected chunks. Accepted values: `enable`, `disable`, `delete`. | -| `--chunk ` | Yes | Chunks to operate on, by identifier. An id naming no chunk in the document is reported in errors and does not fail the request. (space-separated, or @path / @- with one value per line; @@value for a literal leading @). | -| `-y, --yes` | Yes | Confirm this operation. | +| `--filename ` | No | New filename for the document. | +| `--enabled` | No | Whether the document participates in search. Disabling keeps it indexed. | +| `--no-enabled` | No | Send --enabled as false. | +| `--tag1 ` | No | New value for tag slot 1. | +| `--tag2 ` | No | New value for tag slot 2. | +| `--tag3 ` | No | New value for tag slot 3. | +| `--tag4 ` | No | New value for tag slot 4. | +| `--tag5 ` | No | New value for tag slot 5. | +| `--tag6 ` | No | New value for tag slot 6. | +| `--tag7 ` | No | New value for tag slot 7. | +| `--number1 ` | No | New value for number tag slot 1. | +| `--number2 ` | No | New value for number tag slot 2. | +| `--number3 ` | No | New value for number tag slot 3. | +| `--number4 ` | No | New value for number tag slot 4. | +| `--number5 ` | No | New value for number tag slot 5. | +| `--date1 ` | No | New value for date tag slot 1, formatted YYYY-MM-DD. | +| `--date2 ` | No | New value for date tag slot 2, formatted YYYY-MM-DD. | +| `--boolean1` | No | New value for boolean tag slot 1. | +| `--no-boolean1` | No | Send --boolean1 as false. | +| `--boolean2` | No | New value for boolean tag slot 2. | +| `--no-boolean2` | No | Send --boolean2 as false. | +| `--boolean3` | No | New value for boolean tag slot 3. | +| `--no-boolean3` | No | Send --boolean3 as false. | +| `--retry-processing` | No | Requeue a failed or stuck document for processing. Send it alone — no other field may accompany it — and it answers with a queue acknowledgement rather than the document. | -## Create chunk +API request and response schemas: [updateKnowledgeDocument](/api-reference/knowledge-bases/updateKnowledgeDocument). + +### Enable or disable every matching document + +OAuth login or personal API key required. ```bash -sim knowledge chunks create [options] +sim knowledge documents batch-update [options] ``` -Create Chunk (OAuth login or personal API key required) - **Arguments** @@ -292,7 +387,6 @@ Create Chunk (OAuth login or personal API key required) | Argument | Required | Description | | --- | --- | --- | | `knowledgeBaseId` | Yes | Unique knowledge base identifier. | -| `documentId` | Yes | Unique knowledge document identifier. | @@ -302,20 +396,23 @@ Create Chunk (OAuth login or personal API key required) | Option | Required | Description | | --- | --- | --- | -| `--content ` | Yes | Text to embed. It is embedded on write, so the chunk is searchable immediately. | -| `--enabled` | No | Whether the new chunk participates in search. | -| `--no-enabled` | No | Send --enabled as false. | +| `--operation ` | Yes | Whether the selected documents become enabled or disabled for search. Accepted values: `enable`, `disable`. | +| `--document ` | No | Documents to update, by identifier. (space-separated, or @path / @- with one value per line; @@value for a literal leading @). | +| `--select-all` | No | Apply to every document in the knowledge base. | +| `--enabled-filter ` | No | With `selectAll`, restrict the update to documents in this state. Accepted values: `all`, `enabled`, `disabled`. | -## Delete chunk +API request and response schemas: [bulkUpdateKnowledgeDocuments](/api-reference/knowledge-bases/bulkUpdateKnowledgeDocuments). + +### Delete a document from a knowledge base + +This deletes the document and its embeddings. ```bash -sim knowledge chunks delete [options] +sim knowledge documents delete [options] ``` -Delete Chunk (OAuth login or personal API key required) - **Arguments** @@ -324,7 +421,6 @@ Delete Chunk (OAuth login or personal API key required) | --- | --- | --- | | `knowledgeBaseId` | Yes | Unique knowledge base identifier. | | `documentId` | Yes | Unique knowledge document identifier. | -| `chunkId` | Yes | Unique chunk identifier. | @@ -338,14 +434,16 @@ Delete Chunk (OAuth login or personal API key required) -## Get chunk +API request and response schemas: [deleteKnowledgeDocument](/api-reference/knowledge-bases/deleteKnowledgeDocument). + +### Index files the workspace already stores + +OAuth login or personal API key required. ```bash -sim knowledge chunks get +sim knowledge from-workspace-files create [options] ``` -Get Chunk (OAuth login or personal API key required) - **Arguments** @@ -353,19 +451,31 @@ Get Chunk (OAuth login or personal API key required) | Argument | Required | Description | | --- | --- | --- | | `knowledgeBaseId` | Yes | Unique knowledge base identifier. | -| `documentId` | Yes | Unique knowledge document identifier. | -| `chunkId` | Yes | Unique chunk identifier. | -## List chunks +**Options** + + + +| Option | Required | Description | +| --- | --- | --- | +| `--file ` | Yes | Workspace file ID or canonical files/<folder>/<name> path (repeatable) (space-separated, or @path / @- with one value per line; @@value for a literal leading @). | + + + +API request and response schemas: [addWorkspaceFilesToKnowledgeBase](/api-reference/knowledge-bases/addWorkspaceFilesToKnowledgeBase). + +## Chunks + +### List chunks + +OAuth login or personal API key required. ```bash sim knowledge chunks list [options] ``` -List Chunks (OAuth login or personal API key required) - **Arguments** @@ -384,22 +494,24 @@ List Chunks (OAuth login or personal API key required) | Option | Required | Description | | --- | --- | --- | | `--search ` | No | Case-insensitive substring match against chunk content. | -| `--enabled ` | No | Restrict to enabled or disabled chunks. `all` returns both. Accepted values: `true`, `false`, `all`. | -| `--sort-by ` | No | Field used to sort the result. Accepted values: `chunkIndex`, `tokenCount`, `enabled`. | -| `--sort-order ` | No | Sort direction. Accepted values: `asc`, `desc`. | +| `--enabled ` | No | Restrict to enabled or disabled chunks. `all` returns both. Defaults to "all". Accepted values: `true`, `false`, `all`. | +| `--sort-by ` | No | Field used to sort the result. Defaults to "chunkIndex". Accepted values: `chunkIndex`, `tokenCount`, `enabled`. | +| `--sort-order ` | No | Sort direction. Defaults to "asc". Accepted values: `asc`, `desc`. | | `--limit ` | No | Maximum items to return (0 for everything). Defaults to `100`. | | `--cursor ` | No | Continue from nextCursor returned by a previous result. | -## Update chunk +API request and response schemas: [listKnowledgeChunks](/api-reference/knowledge-bases/listKnowledgeChunks). + +### Get chunk + +OAuth login or personal API key required. ```bash -sim knowledge chunks update [options] +sim knowledge chunks get ``` -Update Chunk (OAuth login or personal API key required) - **Arguments** @@ -412,26 +524,16 @@ Update Chunk (OAuth login or personal API key required) -**Options** - - - -| Option | Required | Description | -| --- | --- | --- | -| `--content ` | No | Replacement text. Changing it re-embeds the chunk and re-derives its token and character counts. | -| `--enabled` | No | Whether the chunk participates in search. Disabling keeps it indexed. | -| `--no-enabled` | No | Send --enabled as false. | +API request and response schemas: [getKnowledgeChunk](/api-reference/knowledge-bases/getKnowledgeChunk). - +### Create chunk -## Enable or disable every matching document +OAuth login or personal API key required. ```bash -sim knowledge documents batch-update [options] +sim knowledge chunks create [options] ``` -Enable or disable every matching document (OAuth login or personal API key required) - **Arguments** @@ -439,6 +541,7 @@ Enable or disable every matching document (OAuth login or personal API key requi | Argument | Required | Description | | --- | --- | --- | | `knowledgeBaseId` | Yes | Unique knowledge base identifier. | +| `documentId` | Yes | Unique knowledge document identifier. | @@ -448,17 +551,20 @@ Enable or disable every matching document (OAuth login or personal API key requi | Option | Required | Description | | --- | --- | --- | -| `--operation ` | Yes | Whether the selected documents become enabled or disabled for search. Accepted values: `enable`, `disable`. | -| `--document ` | No | Documents to update, by identifier. (space-separated, or @path / @- with one value per line; @@value for a literal leading @). | -| `--select-all` | No | Apply to every document in the knowledge base. | -| `--enabled-filter ` | No | With `selectAll`, restrict the update to documents in this state. Accepted values: `all`, `enabled`, `disabled`. | +| `--content ` | Yes | Text embedded before the response. Search includes it when the chunk and document are enabled and the document has completed processing. | +| `--enabled` | No | Whether the new chunk participates in search. Defaults to true. | +| `--no-enabled` | No | Send --enabled as false. | -## Delete a document from a knowledge base +API request and response schemas: [createKnowledgeChunk](/api-reference/knowledge-bases/createKnowledgeChunk). + +### Update chunk + +OAuth login or personal API key required. ```bash -sim knowledge documents delete [options] +sim knowledge chunks update [options] ``` **Arguments** @@ -469,6 +575,7 @@ sim knowledge documents delete [options] | --- | --- | --- | | `knowledgeBaseId` | Yes | Unique knowledge base identifier. | | `documentId` | Yes | Unique knowledge document identifier. | +| `chunkId` | Yes | Unique chunk identifier. | @@ -478,31 +585,22 @@ sim knowledge documents delete [options] | Option | Required | Description | | --- | --- | --- | -| `-y, --yes` | Yes | Confirm this operation. | +| `--content ` | No | Replacement text. Changing it re-embeds the chunk and re-derives its token and character counts. | +| `--enabled` | No | Whether the chunk participates in search. Disabling keeps it indexed. | +| `--no-enabled` | No | Send --enabled as false. | -## Get document - -```bash -sim knowledge documents get -``` - -**Arguments** - - +API request and response schemas: [updateKnowledgeChunk](/api-reference/knowledge-bases/updateKnowledgeChunk). -| Argument | Required | Description | -| --- | --- | --- | -| `knowledgeBaseId` | Yes | Unique knowledge base identifier. | -| `documentId` | Yes | Unique knowledge document identifier. | +### Enable, disable, or delete many chunks at once - +OAuth login or personal API key required. -## List documents +This applies --operation to every named chunk; with --operation delete it deletes them and their embeddings, which cannot be undone. ```bash -sim knowledge documents list [options] +sim knowledge chunks batch-update [options] ``` **Arguments** @@ -512,6 +610,7 @@ sim knowledge documents list [options] | Argument | Required | Description | | --- | --- | --- | | `knowledgeBaseId` | Yes | Unique knowledge base identifier. | +| `documentId` | Yes | Unique knowledge document identifier. | @@ -521,24 +620,24 @@ sim knowledge documents list [options] | Option | Required | Description | | --- | --- | --- | -| `--limit ` | No | Maximum items to return (0 for everything). Defaults to `100`. | -| `--search ` | No | Case-insensitive substring match against the document filename. | -| `--enabled-filter ` | No | Filter by whether documents are enabled for search. Accepted values: `all`, `enabled`, `disabled`. | -| `--sort-by ` | No | Field used to sort the result. Sorting by `filename` is case-sensitive and follows the storage collation, so do not rely on a case-insensitive order. Accepted values: `filename`, `fileSize`, `tokenCount`, `chunkCount`, `uploadedAt`, `processingStatus`, `enabled`. | -| `--sort-order ` | No | Sort direction. Accepted values: `asc`, `desc`. | -| `--cursor ` | No | Continue from nextCursor returned by a previous result. | -| `--tag-filters ` | No | A JSON-encoded array of at most 10 tag filters, using the same display-name shape as knowledge search: `[{"tagName":"category","operator":"eq","value":"billing"}]`. Every filter must hold, including two that name the same tag. A name that is not defined in this knowledge base is rejected, never ignored. | +| `--operation ` | Yes | What to do with the selected chunks. Accepted values: `enable`, `disable`, `delete`. | +| `--chunk ` | Yes | Chunks to operate on, by identifier. An id naming no chunk in the document is reported in errors and does not fail the request. (space-separated, or @path / @- with one value per line; @@value for a literal leading @). | +| `-y, --yes` | Yes | Confirm this operation. | -## Update document +API request and response schemas: [bulkUpdateKnowledgeChunks](/api-reference/knowledge-bases/bulkUpdateKnowledgeChunks). + +### Delete chunk + +OAuth login or personal API key required. + +This deletes the chunk and its embedding. ```bash -sim knowledge documents update [options] +sim knowledge chunks delete [options] ``` -Update Document (OAuth login or personal API key required) - **Arguments** @@ -547,6 +646,7 @@ Update Document (OAuth login or personal API key required) | --- | --- | --- | | `knowledgeBaseId` | Yes | Unique knowledge base identifier. | | `documentId` | Yes | Unique knowledge document identifier. | +| `chunkId` | Yes | Unique chunk identifier. | @@ -556,37 +656,18 @@ Update Document (OAuth login or personal API key required) | Option | Required | Description | | --- | --- | --- | -| `--filename ` | No | New filename for the document. | -| `--enabled` | No | Whether the document participates in search. Disabling keeps it indexed. | -| `--no-enabled` | No | Send --enabled as false. | -| `--tag1 ` | No | New value for tag slot 1. | -| `--tag2 ` | No | New value for tag slot 2. | -| `--tag3 ` | No | New value for tag slot 3. | -| `--tag4 ` | No | New value for tag slot 4. | -| `--tag5 ` | No | New value for tag slot 5. | -| `--tag6 ` | No | New value for tag slot 6. | -| `--tag7 ` | No | New value for tag slot 7. | -| `--number1 ` | No | New value for number tag slot 1. | -| `--number2 ` | No | New value for number tag slot 2. | -| `--number3 ` | No | New value for number tag slot 3. | -| `--number4 ` | No | New value for number tag slot 4. | -| `--number5 ` | No | New value for number tag slot 5. | -| `--date1 ` | No | New value for date tag slot 1, formatted YYYY-MM-DD. | -| `--date2 ` | No | New value for date tag slot 2, formatted YYYY-MM-DD. | -| `--boolean1` | No | New value for boolean tag slot 1. | -| `--no-boolean1` | No | Send --boolean1 as false. | -| `--boolean2` | No | New value for boolean tag slot 2. | -| `--no-boolean2` | No | Send --boolean2 as false. | -| `--boolean3` | No | New value for boolean tag slot 3. | -| `--no-boolean3` | No | Send --boolean3 as false. | -| `--retry-processing` | No | Requeue a failed or stuck document for processing. Send it alone — no other field may accompany it — and it answers with a queue acknowledgement rather than the document. | +| `-y, --yes` | Yes | Confirm this operation. | -## Upload a document to a knowledge base +API request and response schemas: [deleteKnowledgeChunk](/api-reference/knowledge-bases/deleteKnowledgeChunk). + +## Tags + +### List tags ```bash -sim knowledge documents upload [options] +sim knowledge tags list ``` **Arguments** @@ -595,51 +676,52 @@ sim knowledge documents upload [options] | Argument | Required | Description | | --- | --- | --- | -| `knowledgeBaseId` | Yes | Knowledge base to upload into | -| `path` | Yes | Local file to upload | +| `knowledgeBaseId` | Yes | Unique knowledge base identifier. | -**Options** +API request and response schemas: [listKnowledgeTags](/api-reference/knowledge-bases/listKnowledgeTags). + +### Create tag + +OAuth login or personal API key required. + +```bash +sim knowledge tags create [options] +``` + +**Arguments** -| Option | Required | Description | +| Argument | Required | Description | | --- | --- | --- | -| `--name ` | No | Store it under a different name. | -| `--tag ` | No | Document tags, in tag1 through tag7 order. | -| `--recipe ` | No | Document processing recipe. Accepted values: `default`, `plain`, `markdown`, `code`. | -| `--lang ` | No | Document language tag: hyphen-separated letter and digit subtags, for example en or en-US. | +| `knowledgeBaseId` | Yes | Unique knowledge base identifier. | -## Create knowledge base - -```bash -sim knowledge create [options] -``` - **Options** | Option | Required | Description | | --- | --- | --- | -| `--name ` | Yes | Human-readable knowledge base name. | -| `--description ` | No | Optional knowledge base description. | -| `--chunking-config ` | No | Chunking configuration; defaults are applied when omitted. (JSON, or @path / @- to read a file or stdin). | -| `--folder ` | No | Folder path as shown in the app; the leading / is optional. | +| `--display-name ` | Yes | Name tag filters and document reads use for this tag. | +| `--field-type ` | No | Value type stored in the slot; it decides which slots are usable and which filter operators apply. Defaults to text, so a number, date, or boolean slot must name its type here. Slot capacity per type: text 7, number 5, date 2, boolean 3. Accepted values: `text`, `number`, `date`, `boolean`. | +| `--tag-slot ` | No | Slot to store the tag in. Omit to take the next free slot for the field type; a slot that does not belong to the field type, or one already in use, is rejected. Accepted values: `tag1`, `tag2`, `tag3`, `tag4`, `tag5`, `tag6`, `tag7`, `number1`, `number2`, `number3`, `number4`, `number5`, `date1`, `date2`, `boolean1`, `boolean2`, `boolean3`. | -## Create knowledge connector +API request and response schemas: [createKnowledgeTag](/api-reference/knowledge-bases/createKnowledgeTag). + +### Declare the tag definitions a knowledge base needs + +OAuth login or personal API key required. ```bash -sim knowledge connectors create [options] +sim knowledge tags save [options] ``` -Create Knowledge Connector (OAuth login or personal API key required) - **Arguments** @@ -656,30 +738,28 @@ Create Knowledge Connector (OAuth login or personal API key required) | Option | Required | Description | | --- | --- | --- | -| `--connector-type ` | Yes | Registered connector type. | -| `--credential-id ` | No | OAuth credential identifier for connector types whose `auth.mode` is `oauth` (see connector types); omit it for `apiKey` connectors. | -| `--api-key ` | No | Write-only API key for connector types whose `auth.mode` is `apiKey` (see connector types), or a personal access token for an OAuth connector that also accepts one, such as GitHub. Send it instead of `credentialId`. Pass a raw key, or a secret reference written as the whole value `{{SECRET_NAME}}`, which the server resolves; `$SECRET_NAME` is not a reference. | -| `--source-config ` | Yes | Connector-specific source selection and filtering configuration. (JSON, or @path / @- to read a file or stdin). | -| `--sync-interval-minutes ` | No | Scheduled synchronization interval in minutes; zero disables scheduling. | +| `--definitions ` | Yes | Tag definitions: [{"tagSlot":"tag1","displayName":"category","fieldType":"text"}] (JSON, or @path / @- to read a file or stdin). | -## Delete knowledge connector +API request and response schemas: [bulkSaveKnowledgeTagDefinitions](/api-reference/knowledge-bases/bulkSaveKnowledgeTagDefinitions). + +### Update tag + +OAuth login or personal API key required. ```bash -sim knowledge connectors delete [options] +sim knowledge tags update [options] ``` -Delete Knowledge Connector (OAuth login or personal API key required) - **Arguments** | Argument | Required | Description | | --- | --- | --- | -| `knowledgeBaseId` | Yes | Knowledge base that owns the connector. | -| `connectorId` | Yes | Connector selected for the operation. | +| `knowledgeBaseId` | Yes | Unique knowledge base identifier. | +| `tagId` | Yes | Unique tag definition identifier. | @@ -689,47 +769,48 @@ Delete Knowledge Connector (OAuth login or personal API key required) | Option | Required | Description | | --- | --- | --- | -| `--delete-documents` | No | Also permanently delete documents produced by this connector. | -| `--no-delete-documents` | No | Send --delete-documents as false. | -| `-y, --yes` | Yes | Confirm this operation. | +| `--display-name ` | No | New tag display name. | +| `--field-type ` | No | New value type for the tag. Accepted values: `text`, `number`, `date`, `boolean`. | -## Get knowledge connector +API request and response schemas: [updateKnowledgeTag](/api-reference/knowledge-bases/updateKnowledgeTag). + +### Show how many documents and chunks carry each tag + +OAuth login or personal API key required. ```bash -sim knowledge connectors get +sim knowledge tags usage ``` -Get Knowledge Connector (OAuth login or personal API key required) - **Arguments** | Argument | Required | Description | | --- | --- | --- | -| `knowledgeBaseId` | Yes | Knowledge base that owns the connector. | -| `connectorId` | Yes | Connector selected for the operation. | +| `knowledgeBaseId` | Yes | Unique knowledge base identifier. | -## List knowledge connector documents +API request and response schemas: [listKnowledgeTagUsage](/api-reference/knowledge-bases/listKnowledgeTagUsage). + +### Show which tag slot a create would take for a field type + +OAuth login or personal API key required. ```bash -sim knowledge connectors documents list [options] +sim knowledge tags next-slot [options] ``` -List Knowledge Connector Documents (OAuth login or personal API key required) - **Arguments** | Argument | Required | Description | | --- | --- | --- | -| `knowledgeBaseId` | Yes | Knowledge base that owns the connector. | -| `connectorId` | Yes | Connector selected for the operation. | +| `knowledgeBaseId` | Yes | Unique knowledge base identifier. | @@ -739,29 +820,30 @@ List Knowledge Connector Documents (OAuth login or personal API key required) | Option | Required | Description | | --- | --- | --- | -| `--include-excluded` | No | Include documents explicitly excluded by a user. | -| `--no-include-excluded` | No | Send --include-excluded as false. | -| `--limit ` | No | Maximum items to return (0 for everything). Defaults to `100`. | -| `--cursor ` | No | Continue from nextCursor returned by a previous result. | +| `--field-type ` | Yes | Value type stored in the slot; it decides which slots are usable and which filter operators apply. Slot capacity per type: text 7, number 5, date 2, boolean 3. Accepted values: `text`, `number`, `date`, `boolean`. | -## Update knowledge connector documents +API request and response schemas: [getNextKnowledgeTagSlot](/api-reference/knowledge-bases/getNextKnowledgeTagSlot). + +### Delete tag + +OAuth login or personal API key required. + +This deletes the tag and clears its values on every document and chunk. ```bash -sim knowledge connectors documents update [options] +sim knowledge tags delete [options] ``` -Update Knowledge Connector Documents (OAuth login or personal API key required) - **Arguments** | Argument | Required | Description | | --- | --- | --- | -| `knowledgeBaseId` | Yes | Knowledge base that owns the connector. | -| `connectorId` | Yes | Connector selected for the operation. | +| `knowledgeBaseId` | Yes | Unique knowledge base identifier. | +| `tagId` | Yes | Unique tag definition identifier. | @@ -771,19 +853,22 @@ Update Knowledge Connector Documents (OAuth login or personal API key required) | Option | Required | Description | | --- | --- | --- | -| `--operation ` | Yes | Whether to restore or exclude the selected documents. Accepted values: `restore`, `exclude`. | -| `--document ` | Yes | Connector document identifiers to update. (space-separated, or @path / @- with one value per line; @@value for a literal leading @). | +| `-y, --yes` | Yes | Confirm this operation. | -## List knowledge connectors +API request and response schemas: [deleteKnowledgeTag](/api-reference/knowledge-bases/deleteKnowledgeTag). + +### Remove tag definitions no document still uses + +OAuth login or personal API key required. + +This deletes every tag definition no document still uses. Their slots become free for a different field. ```bash -sim knowledge connectors list [options] +sim knowledge tags cleanup [options] ``` -List Knowledge Connectors (OAuth login or personal API key required) - **Arguments** @@ -800,28 +885,31 @@ List Knowledge Connectors (OAuth login or personal API key required) | Option | Required | Description | | --- | --- | --- | -| `--sort-by ` | No | Field used to sort the result. Accepted values: `connectorType`, `createdAt`, `updatedAt`. | -| `--sort-order ` | No | Sort direction. Accepted values: `asc`, `desc`. | -| `--limit ` | No | Maximum items to return (0 for everything). Defaults to `0`. | +| `--unused` | No | Whether to remove only the tag definitions no document in the knowledge base still carries a value for. Defaults to true. Pass --no-unused to delete every definition on the knowledge base, which also clears its slot on every document and chunk and is not recoverable. | +| `--no-unused` | No | Send --unused as false. | +| `-y, --yes` | Yes | Confirm this operation. | -## Queue a knowledge connector synchronization +API request and response schemas: [deleteKnowledgeTagDefinitions](/api-reference/knowledge-bases/deleteKnowledgeTagDefinitions). + +## Connectors + +### List knowledge connectors + +OAuth login or personal API key required. ```bash -sim knowledge connectors sync [options] +sim knowledge connectors list [options] ``` -Queue a knowledge connector synchronization (OAuth login or personal API key required) - **Arguments** | Argument | Required | Description | | --- | --- | --- | -| `knowledgeBaseId` | Yes | Knowledge base that owns the connector. | -| `connectorId` | Yes | Connector selected for the operation. | +| `knowledgeBaseId` | Yes | Unique knowledge base identifier. | @@ -831,19 +919,22 @@ Queue a knowledge connector synchronization (OAuth login or personal API key req | Option | Required | Description | | --- | --- | --- | -| `--rehydrate` | No | Re-fetch and re-index every existing connector document. | -| `--no-rehydrate` | No | Send --rehydrate as false. | +| `--sort-by ` | No | Field used to sort the result. Defaults to "createdAt". Accepted values: `connectorType`, `createdAt`, `updatedAt`. | +| `--sort-order ` | No | Sort direction. Defaults to "desc". Accepted values: `asc`, `desc`. | +| `--limit ` | No | Maximum items to return (0 for everything). Defaults to `0`. | -## Update knowledge connector +API request and response schemas: [listKnowledgeConnectors](/api-reference/knowledge-bases/listKnowledgeConnectors). + +### Get knowledge connector + +OAuth login or personal API key required. ```bash -sim knowledge connectors update [options] +sim knowledge connectors get ``` -Update Knowledge Connector (OAuth login or personal API key required) - **Arguments** @@ -855,22 +946,14 @@ Update Knowledge Connector (OAuth login or personal API key required) -**Options** - - - -| Option | Required | Description | -| --- | --- | --- | -| `--source-config ` | No | Replacement source selection and filtering configuration. Updating a runnable connector queues synchronization; paused connectors remain paused. (JSON, or @path / @- to read a file or stdin). | -| `--sync-interval-minutes ` | No | New scheduled synchronization interval in minutes. | -| `--status ` | No | New connector state. Accepted values: `active`, `paused`. | +API request and response schemas: [getKnowledgeConnector](/api-reference/knowledge-bases/getKnowledgeConnector). - +### Create knowledge connector -## Create a knowledge folder at a path +OAuth login or personal API key required. ```bash -sim knowledge folders create +sim knowledge connectors create [options] ``` **Arguments** @@ -879,14 +962,32 @@ sim knowledge folders create | Argument | Required | Description | | --- | --- | --- | -| `path` | Yes | Folder path as shown in the app; the leading / is optional | +| `knowledgeBaseId` | Yes | Unique knowledge base identifier. | + + + +**Options** + + + +| Option | Required | Description | +| --- | --- | --- | +| `--connector-type ` | Yes | Registered connector type. | +| `--credential-id ` | No | OAuth credential identifier for connector types whose `auth.mode` is `oauth` (see connector types); omit it for `apiKey` connectors. | +| `--api-key ` | No | Write-only API key for connector types whose `auth.mode` is `apiKey` (see connector types), or a personal access token for an OAuth connector that also accepts one, such as GitHub. Send it instead of `credentialId`. Pass a raw key, or a secret reference written as the whole value `{{SECRET_NAME}}`, which the server resolves; `$SECRET_NAME` is not a reference. | +| `--source-config ` | Yes | Connector-specific source selection and filtering configuration. (JSON, or @path / @- to read a file or stdin). | +| `--sync-interval-minutes ` | No | Scheduled synchronization interval in minutes; zero disables scheduling. Defaults to 1440. | -## Delete folder +API request and response schemas: [createKnowledgeConnector](/api-reference/knowledge-bases/createKnowledgeConnector). + +### Update knowledge connector + +OAuth login or personal API key required. ```bash -sim knowledge folders delete [options] +sim knowledge connectors update [options] ``` **Arguments** @@ -895,7 +996,8 @@ sim knowledge folders delete [options] | Argument | Required | Description | | --- | --- | --- | -| `path` | Yes | Folder path as shown in the app; the leading / is optional | +| `knowledgeBaseId` | Yes | Knowledge base that owns the connector. | +| `connectorId` | Yes | Connector selected for the operation. | @@ -905,18 +1007,32 @@ sim knowledge folders delete [options] | Option | Required | Description | | --- | --- | --- | -| `--recursive` | No | Delete the folder and its descendants. | -| `-y, --yes` | Yes | Confirm this operation. | +| `--source-config ` | No | Replacement source selection and filtering configuration. Updating a runnable connector queues synchronization; paused connectors remain paused. (JSON, or @path / @- to read a file or stdin). | +| `--sync-interval-minutes ` | No | New scheduled synchronization interval in minutes. | +| `--status ` | No | New connector state. Accepted values: `active`, `paused`. | -## List knowledge folders +API request and response schemas: [updateKnowledgeConnector](/api-reference/knowledge-bases/updateKnowledgeConnector). + +### Queue a knowledge connector synchronization + +OAuth login or personal API key required. ```bash -sim knowledge folders list [options] +sim knowledge connectors sync [options] ``` -Also available as `sim knowledge folders ls`. +**Arguments** + + + +| Argument | Required | Description | +| --- | --- | --- | +| `knowledgeBaseId` | Yes | Knowledge base that owns the connector. | +| `connectorId` | Yes | Connector selected for the operation. | + + **Options** @@ -924,36 +1040,53 @@ Also available as `sim knowledge folders ls`. | Option | Required | Description | | --- | --- | --- | -| `--parent ` | No | Direct parent folder path. | -| `--search ` | No | Case-insensitive substring match against the folder name. | -| `--sort-by ` | No | Field used to sort the result. Sorting by `name` is case-sensitive and follows the storage collation, so do not rely on a case-insensitive order. Accepted values: `name`, `createdAt`, `updatedAt`. | -| `--sort-order ` | No | Sort direction. Accepted values: `asc`, `desc`. | +| `--rehydrate` | No | Re-fetch and re-index every existing connector document. Defaults to false. | +| `--no-rehydrate` | No | Send --rehydrate as false. | -## Rename or move a knowledge folder +API request and response schemas: [syncKnowledgeConnector](/api-reference/knowledge-bases/syncKnowledgeConnector). + +### List knowledge connector documents + +OAuth login or personal API key required. ```bash -sim knowledge folders move +sim knowledge connectors documents list [options] ``` -Also available as `sim knowledge folders mv`. - **Arguments** | Argument | Required | Description | | --- | --- | --- | -| `path` | Yes | Folder path as shown in the app; the leading / is optional | -| `destination` | Yes | Folder path as shown in the app; the leading / is optional | +| `knowledgeBaseId` | Yes | Knowledge base that owns the connector. | +| `connectorId` | Yes | Connector selected for the operation. | -## Delete knowledge base +**Options** + + + +| Option | Required | Description | +| --- | --- | --- | +| `--include-excluded` | No | Include documents explicitly excluded by a user. | +| `--no-include-excluded` | No | Send --include-excluded as false. | +| `--limit ` | No | Maximum items to return (0 for everything). Defaults to `100`. | +| `--cursor ` | No | Continue from nextCursor returned by a previous result. | + + + +API request and response schemas: [listKnowledgeConnectorDocuments](/api-reference/knowledge-bases/listKnowledgeConnectorDocuments). + +### Update knowledge connector documents + +OAuth login or personal API key required. ```bash -sim knowledge delete [options] +sim knowledge connectors documents update [options] ``` **Arguments** @@ -962,7 +1095,8 @@ sim knowledge delete [options] | Argument | Required | Description | | --- | --- | --- | -| `knowledgeBaseId` | Yes | Unique knowledge base identifier. | +| `knowledgeBaseId` | Yes | Knowledge base that owns the connector. | +| `connectorId` | Yes | Connector selected for the operation. | @@ -972,14 +1106,21 @@ sim knowledge delete [options] | Option | Required | Description | | --- | --- | --- | -| `-y, --yes` | Yes | Confirm this operation. | +| `--operation ` | Yes | Whether to restore or exclude the selected documents. Accepted values: `restore`, `exclude`. | +| `--document ` | Yes | Connector document identifiers to update. (space-separated, or @path / @- with one value per line; @@value for a literal leading @). | -## Get knowledge base +API request and response schemas: [updateKnowledgeConnectorDocuments](/api-reference/knowledge-bases/updateKnowledgeConnectorDocuments). + +### Delete knowledge connector + +OAuth login or personal API key required. + +This deletes the connector; --delete-documents also deletes its synchronized documents. ```bash -sim knowledge get +sim knowledge connectors delete [options] ``` **Arguments** @@ -988,35 +1129,31 @@ sim knowledge get | Argument | Required | Description | | --- | --- | --- | -| `knowledgeBaseId` | Yes | Unique knowledge base identifier. | +| `knowledgeBaseId` | Yes | Knowledge base that owns the connector. | +| `connectorId` | Yes | Connector selected for the operation. | -## List knowledge bases - -```bash -sim knowledge list [options] -``` - **Options** | Option | Required | Description | | --- | --- | --- | -| `--scope ` | No | Lifecycle scope: active or archived knowledge bases. Use Restore Knowledge Base to recover archived entries. Folder paths resolve only active folders, so filtering by an archived folder returns no matches. Accepted values: `active`, `archived`. | -| `--folder ` | No | Folder path as shown in the app; the leading / is optional. | -| `--search ` | No | Case-insensitive substring match against the resource name. | -| `--sort-by ` | No | Field used to sort the result. Sorting by `name` is case-sensitive and follows the storage collation, so do not rely on a case-insensitive order. Accepted values: `name`, `createdAt`, `updatedAt`. | -| `--sort-order ` | No | Sort direction. Accepted values: `asc`, `desc`. | -| `--limit ` | No | Maximum items to return (0 for everything). Defaults to `0`. | +| `--delete-documents` | No | Also permanently delete documents produced by this connector. | +| `--no-delete-documents` | No | Send --delete-documents as false. | +| `-y, --yes` | Yes | Confirm this operation. | -## Restore an archived knowledge base +API request and response schemas: [deleteKnowledgeConnector](/api-reference/knowledge-bases/deleteKnowledgeConnector). + +## Folders + +### List knowledge resources and child folders together ```bash -sim knowledge restore +sim knowledge ls [path] [options] ``` **Arguments** @@ -1025,49 +1162,30 @@ sim knowledge restore | Argument | Required | Description | | --- | --- | --- | -| `knowledgeBaseId` | Yes | Unique knowledge base identifier. | +| `path` | No | Folder path to list; defaults to the root folder | -## Search knowledge - -```bash -sim knowledge search [options] -``` - **Options** | Option | Required | Description | | --- | --- | --- | -| `--kb ` | Yes | Knowledge base ID (repeatable) (space-separated, or @path / @- with one value per line; @@value for a literal leading @). | -| `--query ` | No | Text to search for. | -| `--top-k ` | No | Maximum number of search results to return. Must be a whole number between 1 and 100. | -| `--tag-filters ` | No | Tag filters as [{"tagName":"...","operator":"...","value":"..."}] (JSON, or @path / @- to read a file or stdin). | -| `--search-mode ` | No | Search algorithm. Accepted values: `vector`, `hybrid`. | -| `--reranker-enabled` | No | Re-order retrieved chunks with a reranking model before truncating to `topK`. Ignored for a tag-only search, and billed as an additional search unit. Reranking is best-effort — a provider failure falls back to vector ordering, so check `rerankerStatus` on the response. | -| `--no-reranker-enabled` | No | Send --reranker-enabled as false. | -| `--reranker-model ` | No | Reranking model to use when `rerankerEnabled` is true. Defaults to `rerank-v4.0-fast`. Accepted values: `rerank-v4.0-pro`, `rerank-v4.0-fast`, `rerank-v3.5`. | -| `--reranker-input-count ` | No | How many candidate chunks to retrieve before reranking. Defaults to four times `topK`, capped at 100. A larger pool costs more retrieval work but gives the reranker more to choose from. | +| `--search ` | No | Filter folders and resources by name. | +| `--limit ` | No | Maximum combined items to return (0 for everything). Defaults to `0`. | -## Update knowledge base +API request and response schemas: [listKnowledgeBases](/api-reference/knowledge-bases/listKnowledgeBases), [listKnowledgeFolders](/api-reference/knowledge-bases/listKnowledgeFolders). + +### List knowledge folders ```bash -sim knowledge update [options] +sim knowledge folders list [options] ``` -**Arguments** - - - -| Argument | Required | Description | -| --- | --- | --- | -| `knowledgeBaseId` | Yes | Unique knowledge base identifier. | - - +Also available as `sim knowledge folders ls`. **Options** @@ -1075,17 +1193,19 @@ sim knowledge update [options] | Option | Required | Description | | --- | --- | --- | -| `--name ` | No | New knowledge base name. | -| `--description ` | No | New knowledge base description. | -| `--chunking-config ` | No | New document chunking configuration. (JSON, or @path / @- to read a file or stdin). | -| `--folder ` | No | Folder path as shown in the app; the leading / is optional. | +| `--parent ` | No | Direct parent folder path. | +| `--search ` | No | Case-insensitive substring match against the folder name. | +| `--sort-by ` | No | Field used to sort the result. Do not rely on case-insensitive ordering when sorting by `name`. Defaults to "name". Accepted values: `name`, `createdAt`, `updatedAt`. | +| `--sort-order ` | No | Sort direction. Defaults to "asc". Accepted values: `asc`, `desc`. | -## Move a knowledge base to a folder +API request and response schemas: [listKnowledgeFolders](/api-reference/knowledge-bases/listKnowledgeFolders). + +### Create a knowledge folder at a path ```bash -sim knowledge mv +sim knowledge folders create ``` **Arguments** @@ -1094,15 +1214,18 @@ sim knowledge mv | Argument | Required | Description | | --- | --- | --- | -| `knowledgeBaseId` | Yes | Unique knowledge base identifier. | -| `folder` | Yes | Folder path as shown in the app; the leading / is optional | +| `path` | Yes | Folder path as shown in the app; the leading / is optional | -## Export a knowledge base as a .simkb.zip bundle +API request and response schemas: [createKnowledgeFolder](/api-reference/knowledge-bases/createKnowledgeFolder). + +### Delete folder + +This archives the knowledge folder and, when recursive, everything inside it. ```bash -sim knowledge export [options] +sim knowledge folders delete [options] ``` **Arguments** @@ -1111,7 +1234,7 @@ sim knowledge export [options] | Argument | Required | Description | | --- | --- | --- | -| `knowledgeBaseId` | Yes | Knowledge base to export | +| `path` | Yes | Folder path as shown in the app; the leading / is optional | @@ -1121,40 +1244,35 @@ sim knowledge export [options] | Option | Required | Description | | --- | --- | --- | -| `-o, --output-file ` | No | Write the bundle to this path instead of the name the server suggests; pass - to stream it to stdout. | -| `--force` | No | Overwrite --output-file if it already exists. | -| `--no-vectors` | No | Leave chunk vectors out of the bundle, so an import re-embeds every chunk. | +| `--recursive` | No | Archive the folder and its descendants. Defaults to "false". | +| `-y, --yes` | Yes | Confirm this operation. | -## List knowledge resources and child folders together +API request and response schemas: [deleteKnowledgeFolder](/api-reference/knowledge-bases/deleteKnowledgeFolder). + +### Rename or move a knowledge folder ```bash -sim knowledge ls [path] [options] +sim knowledge folders move ``` +Also available as `sim knowledge folders mv`. + **Arguments** | Argument | Required | Description | | --- | --- | --- | -| `path` | No | Folder path to list; defaults to the root folder | +| `path` | Yes | Folder path as shown in the app; the leading / is optional | +| `destination` | Yes | Folder path as shown in the app; the leading / is optional | -**Options** - - - -| Option | Required | Description | -| --- | --- | --- | -| `--search ` | No | Filter folders and resources by name. | -| `--limit ` | No | Maximum combined items to return (0 for everything). Defaults to `0`. | - - +API request and response schemas: [relocateKnowledgeFolder](/api-reference/knowledge-bases/relocateKnowledgeFolder). -## Create a knowledge directory at a path +### Create a knowledge directory at a path ```bash sim knowledge mkdir @@ -1169,3 +1287,11 @@ sim knowledge mkdir | `path` | Yes | Folder path to create; the leading / is optional | + +API request and response schemas: [createKnowledgeFolder](/api-reference/knowledge-bases/createKnowledgeFolder). + +## Related docs + +- [Knowledge Base](/knowledgebase) +- [Tags and filters](/knowledgebase/tags) +- [Export and import](/knowledgebase/export-import) diff --git a/apps/docs/content/docs/cli/logs.mdx b/apps/docs/content/docs/cli/logs.mdx index 159e4a4909c..5ae8626c80d 100644 --- a/apps/docs/content/docs/cli/logs.mdx +++ b/apps/docs/content/docs/cli/logs.mdx @@ -1,13 +1,57 @@ --- title: Logs -description: Manage logs — every subcommand, argument, and flag +description: Read run diagnostics, follow new runs, and summarize failures and latency. --- import { CommandTable } from '@/components/ui/command-table' +Read run diagnostics, follow new runs, and summarize failures and latency. + `sim logs` is also spelled `sim log`. -Every command below also accepts the [global options](/cli/commands#global-options). +These commands accept the [global options](/cli/commands#global-options). + +## List run logs, such as failed or errored runs, by workflow, trigger or time + +```bash +sim logs list [options] +``` + +**Options** + + + +| Option | Required | Description | +| --- | --- | --- | +| `--workflow ` | No | Comma-separated workflow identifiers to include. An empty entry is rejected. At most 200 entries. (space-separated, or @path / @- with one value per line; @@value for a literal leading @). | +| `--trigger ` | No | Comma-separated, lowercase trigger types or webhook provider IDs. Matching is exact and case-sensitive; unknown values select no runs. An empty entry is rejected. The sentinel `all` disables this filter, even when listed with other values. At most 100 entries. (space-separated, or @path / @- with one value per line; @@value for a literal leading @). | +| `--level ` | No | Severity level to include. Accepted values: `info`, `error`. | +| `--start-date ` | No | Only include runs started at or after this UTC ISO 8601 timestamp, e.g. `2026-08-06T00:00:00Z`. A date without a time, or a timestamp carrying a UTC offset instead of `Z`, is rejected, as is year `0000`, which names no storable instant. | +| `--end-date ` | No | Only include runs started at or before this UTC ISO 8601 timestamp, e.g. `2026-08-06T00:00:00Z`. A date without a time, or a timestamp carrying a UTC offset instead of `Z`, is rejected, as is year `0000`, which names no storable instant. | +| `--min-duration-ms ` | No | Minimum total execution duration in milliseconds. Whole milliseconds from 0 to 2147483647; the stored duration is a 32-bit integer, so a fractional or out-of-range bound is rejected. | +| `--max-duration-ms ` | No | Maximum total execution duration in milliseconds. Whole milliseconds from 0 to 2147483647; the stored duration is a 32-bit integer, so a fractional or out-of-range bound is rejected. | +| `--min-cost ` | No | Minimum execution cost in USD, from 0 to 1000000. A run is never charged a negative amount, so a negative bound is rejected rather than treated as a filter that matches every run. | +| `--max-cost ` | No | Maximum execution cost in USD, from 0 to 1000000. A run is never charged a negative amount, so a negative bound is rejected rather than treated as a filter that matches every run. | +| `--model ` | No | AI model used during execution. | +| `--details ` | No | Response detail level; full is requested by default to name each run’s workflow. Accepted values: `basic`, `full`. | +| `--include-trace-spans` | No | Include trace spans in JSON or YAML output (implies full detail). | +| `--include-final-output` | No | Include final output in JSON or YAML output (implies full detail). | +| `--limit ` | No | Maximum items to return (0 for everything). Defaults to `100`. | +| `--cursor ` | No | Continue from nextCursor returned by a previous result. | +| `--include-handled-errors` | No | Whether `level=error` also selects runs that finished at `info` after a block error was recovered by an error path. Off by default: such a run succeeded, so it is an error only to a caller auditing error handling. Every row reports `hasHandledErrors` whether or not this is set. Job runs carry no block trace, so the flag never widens that branch. | +| `--no-include-handled-errors` | No | Send --include-handled-errors as false. | +| `--status ` | No | Comma-separated execution statuses to include, from `pending` \| `running` \| `paused` \| `redacting` \| `completed` \| `failed` \| `cancelled`. An empty entry is rejected. ANDed with `level`, which reports severity rather than lifecycle. | +| `--workflow-name ` | No | Case-insensitive substring match against the run's workflow name. Runs whose workflow has been deleted match nothing, because the name is no longer joinable. | +| `--include-job-runs` | No | Include Chat and Sim-agent jobs alongside workflow runs. Jobs use `kind: "job"` and have no workflow or cost ledger. Workflow, folder, model, or status filters exclude jobs. This option is valid only when sorting by `startedAt`. | +| `--no-include-job-runs` | No | Send --include-job-runs as false. | +| `--run-id ` | No | Exact run identifier to match. | +| `--sort-by ` | No | Field used to sort the result. `durationMs` and `cost` are null until a run settles; those runs sort before recorded values in ascending order and after them in descending order. Only `startedAt` can order Chat and Sim-agent job runs, so any other value is rejected when job runs are included. Defaults to "startedAt". Accepted values: `startedAt`, `durationMs`, `cost`, `status`. | +| `--sort-order ` | No | Sort direction. Defaults to "desc". Accepted values: `asc`, `desc`. | +| `--folder ` | No | Folder path as shown in the app; the leading / is optional (space-separated, or @path / @- with one value per line; @@value for a literal leading @). | + + + +API request and response schemas: [listLogs](/api-reference/logs/listLogs). ## Show run diagnostics @@ -37,6 +81,8 @@ sim logs get [options] +API request and response schemas: [getLog](/api-reference/logs/getLog). + ## Summarize run counts, failures and latency over a window ```bash @@ -57,50 +103,12 @@ sim logs stats [options] | `--no-include-handled-errors` | No | Send --include-handled-errors as false. | | `--start-date ` | No | Only include runs started at or after this UTC ISO 8601 timestamp, e.g. `2026-08-06T00:00:00Z`. A date without a time, or a timestamp carrying a UTC offset instead of `Z`, is rejected, as is year `0000`, which names no storable instant. | | `--end-date ` | No | Only include runs started at or before this UTC ISO 8601 timestamp, e.g. `2026-08-06T00:00:00Z`. A date without a time, or a timestamp carrying a UTC offset instead of `Z`, is rejected, as is year `0000`, which names no storable instant. | -| `--segment-count ` | No | Number of equal time buckets to divide the window into, from 1 to 500. It is the ceiling on how many buckets a series carries: with `includeEmpty=true` exactly this many are returned, otherwise only the buckets holding at least one run. Buckets are never narrower than one minute, so on a short window the series extends past the end of the window rather than being compressed, and the trailing buckets are empty. | +| `--segment-count ` | No | Number of equal time buckets to divide the window into, from 1 to 500. It is the ceiling on how many buckets a series carries: with `includeEmpty=true` exactly this many are returned, otherwise only the buckets holding at least one run. Buckets are never narrower than one minute, so on a short window the series extends past the end of the window rather than being compressed, and the trailing buckets are empty. Defaults to 72. | | `--include-empty ` | No | Whether buckets with no runs are included in every series. Off by default, so each series carries only the buckets that hold at least one run; set it to publish exactly `segmentCount` buckets per series, empty ones included. The listed spellings are the whole accepted vocabulary and are case-sensitive; any other value is rejected. Accepted values: `true`, `1`, `yes`, `on`, `y`, `enabled`, `false`, `0`, `no`, `off`, `n`, `disabled`. | -## List run logs, such as failed or errored runs, by workflow, trigger or time - -```bash -sim logs list [options] -``` - -**Options** - - - -| Option | Required | Description | -| --- | --- | --- | -| `--workflow ` | No | Comma-separated workflow identifiers to include. An empty entry is rejected. At most 200 entries. (space-separated, or @path / @- with one value per line; @@value for a literal leading @). | -| `--trigger ` | No | Comma-separated, lowercase trigger types or webhook provider IDs. Matching is exact and case-sensitive; unknown values select no runs. An empty entry is rejected. The sentinel `all` disables this filter, even when listed with other values. At most 100 entries. (space-separated, or @path / @- with one value per line; @@value for a literal leading @). | -| `--level ` | No | Severity level to include. Accepted values: `info`, `error`. | -| `--start-date ` | No | Only include runs started at or after this UTC ISO 8601 timestamp, e.g. `2026-08-06T00:00:00Z`. A date without a time, or a timestamp carrying a UTC offset instead of `Z`, is rejected, as is year `0000`, which names no storable instant. | -| `--end-date ` | No | Only include runs started at or before this UTC ISO 8601 timestamp, e.g. `2026-08-06T00:00:00Z`. A date without a time, or a timestamp carrying a UTC offset instead of `Z`, is rejected, as is year `0000`, which names no storable instant. | -| `--min-duration-ms ` | No | Minimum total execution duration in milliseconds. Whole milliseconds from 0 to 2147483647; the stored duration is a 32-bit integer, so a fractional or out-of-range bound is rejected. | -| `--max-duration-ms ` | No | Maximum total execution duration in milliseconds. Whole milliseconds from 0 to 2147483647; the stored duration is a 32-bit integer, so a fractional or out-of-range bound is rejected. | -| `--min-cost ` | No | Minimum execution cost in USD, from 0 to 1000000. A run is never charged a negative amount, so a negative bound is rejected rather than treated as a filter that matches every run. | -| `--max-cost ` | No | Maximum execution cost in USD, from 0 to 1000000. A run is never charged a negative amount, so a negative bound is rejected rather than treated as a filter that matches every run. | -| `--model ` | No | AI model used during execution. | -| `--details ` | No | Response detail level; full is requested by default to name each run’s workflow. Accepted values: `basic`, `full`. | -| `--include-trace-spans` | No | Include trace spans in JSON or YAML output (implies full detail). | -| `--include-final-output` | No | Include final output in JSON or YAML output (implies full detail). | -| `--limit ` | No | Maximum items to return (0 for everything). Defaults to `100`. | -| `--cursor ` | No | Continue from nextCursor returned by a previous result. | -| `--include-handled-errors` | No | Whether `level=error` also selects runs that finished at `info` after a block error was recovered by an error path. Off by default: such a run succeeded, so it is an error only to a caller auditing error handling. Every row reports `hasHandledErrors` whether or not this is set. Job runs carry no block trace, so the flag never widens that branch. | -| `--no-include-handled-errors` | No | Send --include-handled-errors as false. | -| `--status ` | No | Comma-separated execution statuses to include, from `pending` \| `running` \| `paused` \| `redacting` \| `completed` \| `failed` \| `cancelled`. An empty entry is rejected. ANDed with `level`, which reports severity rather than lifecycle. | -| `--workflow-name ` | No | Case-insensitive substring match against the run's workflow name. Runs whose workflow has been deleted match nothing, because the name is no longer joinable. | -| `--include-job-runs` | No | Include Chat and Sim-agent jobs alongside workflow runs. Jobs use `kind: "job"` and have no workflow or cost ledger. Workflow, folder, model, or status filters exclude jobs. This option is valid only when sorting by `startedAt`. | -| `--no-include-job-runs` | No | Send --include-job-runs as false. | -| `--run-id ` | No | Exact run identifier to match. | -| `--sort-by ` | No | Field used to sort the result. `durationMs` and `cost` are null until a run settles; those runs sort before recorded values in ascending order and after them in descending order. Only `startedAt` can order Chat and Sim-agent job runs, so any other value is rejected when job runs are included. Accepted values: `startedAt`, `durationMs`, `cost`, `status`. | -| `--sort-order ` | No | Sort direction. Accepted values: `asc`, `desc`. | -| `--folder ` | No | Folder path as shown in the app; the leading / is optional (space-separated, or @path / @- with one value per line; @@value for a literal leading @). | - - +API request and response schemas: [getLogStats](/api-reference/logs/getLogStats). ## Watch runs live as they arrive, printing each new run once @@ -123,3 +131,20 @@ sim logs follow [options] | `--interval ` | No | Seconds between polls. Defaults to `3`. | + +Each run prints once, when it is first seen, so its status is the status it had at that moment. With --output json every run is a JSON object on its own line (JSONL) rather than a member of an array, because a follow never ends and so can never close one; --output yaml emits a --- separated document stream. Progress and retries go to stderr, leaving stdout a clean stream of rows. Ctrl-C stops the follow. + +**Examples** + +```bash +sim logs follow --level error +sim logs follow --workflow 00000000-0000-4000-8000-000000000000 -n 0 +sim --output json logs follow | jq -r '.runId' +``` + +API request and response schemas: [listLogs](/api-reference/logs/listLogs). + +## Related docs + +- [Logs and debugging](/logs-debugging) +- [Output formats](/cli/output) diff --git a/apps/docs/content/docs/cli/mcp-servers.mdx b/apps/docs/content/docs/cli/mcp-servers.mdx index bb9559b297b..60b6c97c803 100644 --- a/apps/docs/content/docs/cli/mcp-servers.mdx +++ b/apps/docs/content/docs/cli/mcp-servers.mdx @@ -1,18 +1,24 @@ --- -title: MCP Servers -description: Manage mcp servers — every subcommand, argument, and flag +title: MCP servers +description: Connect external Model Context Protocol (MCP) servers so workflows can use their tools. --- import { CommandTable } from '@/components/ui/command-table' +Connect external Model Context Protocol (MCP) servers so workflows can use their tools. + +To serve Sim workflows to MCP clients instead, use [workflow MCP servers](/cli/workflow-mcp-servers). + `sim mcp-servers` is also spelled `sim mcp-server`. -Every command below also accepts the [global options](/cli/commands#global-options). +These commands accept the [global options](/cli/commands#global-options). + +## Server connections -## Create MCP server +### List MCP servers ```bash -sim mcp-servers create [options] +sim mcp-servers list [options] ``` **Options** @@ -21,25 +27,19 @@ sim mcp-servers create [options] | Option | Required | Description | | --- | --- | --- | -| `--name ` | Yes | Server display name. | -| `--description ` | No | Optional server description. | -| `--transport ` | No | Transport protocol. Defaults to `streamable-http` on creation. Accepted values: `streamable-http`. | -| `--url ` | Yes | Absolute HTTP or HTTPS endpoint URL without `{{ENV_VAR}}` references. It determines server identity and is immutable: delete and recreate the server to change endpoints. | -| `--auth-type ` | No | Authentication method. When omitted, and no `headers` are sent, registration probes the endpoint once to classify it, falling back to `headers` when the probe fails or the server does not advertise OAuth. A server publishing RFC 9728 metadata is therefore stored as `oauth`, and headers configured afterwards will not authenticate — send this field explicitly to pin the method. Accepted values: `none`, `headers`, `oauth`. | -| `--headers ` | No | Write-only request headers sent to the server. Replaced wholesale rather than merged on update: sending this field drops every stored header it does not repeat. (JSON, or @path / @- to read a file or stdin). | -| `--timeout ` | No | Per-request timeout in milliseconds. Defaults to 30000 on creation. | -| `--retries ` | No | Number of retries per request. Defaults to 3 on creation. | -| `--enabled` | No | Whether workflows can use the server's tools. Defaults to true on creation. | -| `--no-enabled` | No | Send --enabled as false. | -| `--oauth-client-id ` | No | Pre-registered OAuth client identifier. Changing it on update revokes the stored OAuth grant and forces reauthorization. | -| `--oauth-client-secret ` | No | Write-only pre-registered OAuth client secret. Sending it on update as null or a new value revokes the stored OAuth grant and forces reauthorization, as does switching away from OAuth authentication. (--oauth-client-secret null sends the word, not JSON null). | +| `--search ` | No | Case-insensitive substring match against the server name. | +| `--sort-by ` | No | Field used to sort the result. Do not rely on case-insensitive ordering when sorting by `name`. Defaults to "createdAt". Accepted values: `name`, `createdAt`, `updatedAt`. | +| `--sort-order ` | No | Sort direction. Defaults to "desc". Accepted values: `asc`, `desc`. | +| `--limit ` | No | Maximum items to return (0 for everything). Defaults to `0`. | -## Delete MCP server +API request and response schemas: [listMcpServers](/api-reference/mcp-servers/listMcpServers). + +### Get MCP server ```bash -sim mcp-servers delete [options] +sim mcp-servers get ``` **Arguments** @@ -52,20 +52,41 @@ sim mcp-servers delete [options] +API request and response schemas: [getMcpServer](/api-reference/mcp-servers/getMcpServer). + +### Create MCP server + +```bash +sim mcp-servers create [options] +``` + **Options** | Option | Required | Description | | --- | --- | --- | -| `-y, --yes` | Yes | Confirm this operation. | +| `--name ` | Yes | Server display name. | +| `--description ` | No | Optional server description. | +| `--transport ` | No | Transport protocol. Defaults to `streamable-http` on creation. Accepted values: `streamable-http`. | +| `--url ` | Yes | Absolute HTTP or HTTPS endpoint URL without `{{ENV_VAR}}` references. It determines server identity and is immutable: delete and recreate the server to change endpoints. | +| `--auth-type ` | No | Authentication method. On creation, omission without `headers` probes once: an OAuth challenge selects `oauth`, an unauthenticated success selects `none`, and other outcomes fall back to `headers`. An OAuth client ID selects `oauth` when the method is omitted. Set explicitly to use headers with a server advertising OAuth; adding headers later does not change the saved method. Accepted values: `none`, `headers`, `oauth`. | +| `--headers ` | No | Write-only request headers sent to the server. Replaced wholesale rather than merged on update: sending this field drops every stored header it does not repeat. (JSON, or @path / @- to read a file or stdin). | +| `--timeout ` | No | Per-request timeout in milliseconds. Defaults to 30000 on creation. | +| `--retries ` | No | Number of retries per request. Defaults to 3 on creation. | +| `--enabled` | No | Whether workflows can use the server's tools. Defaults to true on creation. | +| `--no-enabled` | No | Send --enabled as false. | +| `--oauth-client-id ` | No | Pre-registered OAuth client identifier. Changing it on update revokes the stored OAuth grant and forces reauthorization. | +| `--oauth-client-secret ` | No | Write-only pre-registered OAuth client secret. Sending it on update as null or a new value revokes the stored OAuth grant and forces reauthorization, as does switching away from OAuth authentication. (--oauth-client-secret null sends the word, not JSON null). | -## Get MCP server +API request and response schemas: [createMcpServer](/api-reference/mcp-servers/createMcpServer). + +### Update MCP server ```bash -sim mcp-servers get +sim mcp-servers update [options] ``` **Arguments** @@ -78,33 +99,39 @@ sim mcp-servers get -## List MCP servers - -```bash -sim mcp-servers list [options] -``` - **Options** | Option | Required | Description | | --- | --- | --- | -| `--search ` | No | Case-insensitive substring match against the server name. | -| `--sort-by ` | No | Field used to sort the result. Sorting by `name` is case-sensitive and follows the storage collation, so do not rely on a case-insensitive order. Accepted values: `name`, `createdAt`, `updatedAt`. | -| `--sort-order ` | No | Sort direction. Accepted values: `asc`, `desc`. | -| `--limit ` | No | Maximum items to return (0 for everything). Defaults to `0`. | +| `--name ` | No | Server display name. | +| `--description ` | No | Optional server description. | +| `--transport ` | No | Transport protocol. Defaults to `streamable-http` on creation. Accepted values: `streamable-http`. | +| `--url ` | No | Immutable server URL. When provided, it must equal the current URL; use delete and create to change endpoints. | +| `--auth-type ` | No | Authentication method. On creation, omission without `headers` probes once: an OAuth challenge selects `oauth`, an unauthenticated success selects `none`, and other outcomes fall back to `headers`. An OAuth client ID selects `oauth` when the method is omitted. Set explicitly to use headers with a server advertising OAuth; adding headers later does not change the saved method. Accepted values: `none`, `headers`, `oauth`. | +| `--headers ` | No | Write-only request headers sent to the server. Replaced wholesale rather than merged on update: sending this field drops every stored header it does not repeat. (JSON, or @path / @- to read a file or stdin). | +| `--timeout ` | No | Per-request timeout in milliseconds. Defaults to 30000 on creation. | +| `--retries ` | No | Number of retries per request. Defaults to 3 on creation. | +| `--enabled` | No | Whether workflows can use the server's tools. Defaults to true on creation. | +| `--no-enabled` | No | Send --enabled as false. | +| `--oauth-client-id ` | No | Pre-registered OAuth client identifier. Changing it on update revokes the stored OAuth grant and forces reauthorization. | +| `--oauth-client-secret ` | No | Write-only pre-registered OAuth client secret. Sending it on update as null or a new value revokes the stored OAuth grant and forces reauthorization, as does switching away from OAuth authentication. (--oauth-client-secret null sends the word, not JSON null). | -## List MCP server tools +API request and response schemas: [updateMcpServer](/api-reference/mcp-servers/updateMcpServer). + +## Tool discovery + +### List MCP server tools + +OAuth login or personal API key required. ```bash sim mcp-servers tools list [options] ``` -List MCP Server Tools (OAuth login or personal API key required) - **Arguments** @@ -126,10 +153,16 @@ List MCP Server Tools (OAuth login or personal API key required) -## Update MCP server +API request and response schemas: [listMcpServerTools](/api-reference/mcp-servers/listMcpServerTools). + +## Remove servers + +### Delete MCP server + +This removes the MCP server and the tools it provides. ```bash -sim mcp-servers update [options] +sim mcp-servers delete [options] ``` **Arguments** @@ -148,17 +181,12 @@ sim mcp-servers update [options] | Option | Required | Description | | --- | --- | --- | -| `--name ` | No | Server display name. | -| `--description ` | No | Optional server description. | -| `--transport ` | No | Transport protocol. Defaults to `streamable-http` on creation. Accepted values: `streamable-http`. | -| `--url ` | No | Immutable server URL. When provided, it must equal the current URL; use delete and create to change endpoints. | -| `--auth-type ` | No | Authentication method. When omitted, and no `headers` are sent, registration probes the endpoint once to classify it, falling back to `headers` when the probe fails or the server does not advertise OAuth. A server publishing RFC 9728 metadata is therefore stored as `oauth`, and headers configured afterwards will not authenticate — send this field explicitly to pin the method. Accepted values: `none`, `headers`, `oauth`. | -| `--headers ` | No | Write-only request headers sent to the server. Replaced wholesale rather than merged on update: sending this field drops every stored header it does not repeat. (JSON, or @path / @- to read a file or stdin). | -| `--timeout ` | No | Per-request timeout in milliseconds. Defaults to 30000 on creation. | -| `--retries ` | No | Number of retries per request. Defaults to 3 on creation. | -| `--enabled` | No | Whether workflows can use the server's tools. Defaults to true on creation. | -| `--no-enabled` | No | Send --enabled as false. | -| `--oauth-client-id ` | No | Pre-registered OAuth client identifier. Changing it on update revokes the stored OAuth grant and forces reauthorization. | -| `--oauth-client-secret ` | No | Write-only pre-registered OAuth client secret. Sending it on update as null or a new value revokes the stored OAuth grant and forces reauthorization, as does switching away from OAuth authentication. (--oauth-client-secret null sends the word, not JSON null). | +| `-y, --yes` | Yes | Confirm this operation. | + +API request and response schemas: [deleteMcpServer](/api-reference/mcp-servers/deleteMcpServer). + +## Related docs + +- [MCP connections](/agents/mcp) diff --git a/apps/docs/content/docs/cli/meta.mdx b/apps/docs/content/docs/cli/meta.mdx index 66f7a488b23..ff6113c27e4 100644 --- a/apps/docs/content/docs/cli/meta.mdx +++ b/apps/docs/content/docs/cli/meta.mdx @@ -1,14 +1,21 @@ --- -title: Meta -description: Manage meta — every subcommand, argument, and flag +title: API status +description: Inspect API availability and the calling credential’s type and expiry. --- -import { CommandTable } from '@/components/ui/command-table' -Every command below also accepts the [global options](/cli/commands#global-options). +Inspect API availability and the calling credential’s type and expiry. -## Show what this API supports and which limits apply +These commands accept the [global options](/cli/commands#global-options). + +## Show API availability and the calling credential’s type and expiry ```bash sim meta status ``` + +API request and response schemas: [getMeta](/api-reference/meta/getApiMeta). + +## Related docs + +- [Authentication](/cli/authentication) diff --git a/apps/docs/content/docs/cli/organizations.mdx b/apps/docs/content/docs/cli/organizations.mdx index 05c47a2d394..d339914d780 100644 --- a/apps/docs/content/docs/cli/organizations.mdx +++ b/apps/docs/content/docs/cli/organizations.mdx @@ -1,38 +1,66 @@ --- title: Organizations -description: Manage organizations — every subcommand, argument, and flag +description: Manage organization membership, invitations, usage, access requests, and SSO. --- import { CommandTable } from '@/components/ui/command-table' -Every command below also accepts the [global options](/cli/commands#global-options). +Manage organization membership, invitations, usage, access requests, and SSO. -## Add organization domain +These commands accept the [global options](/cli/commands#global-options). + +## Organizations and workspaces + +### List organizations + +OAuth login or personal API key required. ```bash -sim organizations domains add [options] +sim organizations list [options] ``` -Add Organization Domain (OAuth login or personal API key required) - **Options** | Option | Required | Description | | --- | --- | --- | -| `--organization ` | Yes | Organization identifier. | -| `--domain ` | Yes | Domain to claim and verify through a DNS TXT record. | +| `--search ` | No | Case-insensitive substring match against the organization name. | +| `--sort-by ` | No | Field used to sort the result. Do not rely on case-insensitive ordering when sorting by `name`. Defaults to "name". Accepted values: `name`, `createdAt`. | +| `--sort-order ` | No | Sort direction. Defaults to "asc". Accepted values: `asc`, `desc`. | +| `--limit ` | No | Maximum items to return (0 for everything). Defaults to `0`. | -## List organization domains +API request and response schemas: [listOrganizations](/api-reference/organizations/listOrganizations). + +### Get organization + +OAuth login or personal API key required. ```bash -sim organizations domains list [options] +sim organizations get ``` -List Organization Domains (OAuth login or personal API key required) +**Arguments** + + + +| Argument | Required | Description | +| --- | --- | --- | +| `organizationId` | Yes | Organization identifier. | + + + +API request and response schemas: [getOrganization](/api-reference/organizations/getOrganization). + +### List organization workspaces + +OAuth login or personal API key required. + +```bash +sim organizations workspaces [options] +``` **Options** @@ -41,19 +69,48 @@ List Organization Domains (OAuth login or personal API key required) | Option | Required | Description | | --- | --- | --- | | `--organization ` | Yes | Organization identifier. | +| `--search ` | No | Case-insensitive substring match against the workspace name. | +| `--sort-by ` | No | Field used to sort the result. Do not rely on case-insensitive ordering when sorting by `name`. Defaults to "name". Accepted values: `name`, `id`. | +| `--sort-order ` | No | Sort direction. Defaults to "asc". Accepted values: `asc`, `desc`. | | `--limit ` | No | Maximum items to return (0 for everything). Defaults to `0`. | -| `--sort-by ` | No | Field used to sort the result. Accepted values: `domain`. | -| `--sort-order ` | No | Sort direction. Accepted values: `asc`, `desc`. | -## Remove organization domain +API request and response schemas: [listOrganizationWorkspaces](/api-reference/organizations/listOrganizationWorkspaces). + +## Members and credit limits + +### List organization members + +OAuth login or personal API key required. ```bash -sim organizations domains remove [options] +sim organizations members list [options] ``` -Remove Organization Domain (OAuth login or personal API key required) +**Options** + + + +| Option | Required | Description | +| --- | --- | --- | +| `--organization ` | Yes | Organization identifier. | +| `--search ` | No | Case-insensitive substring match against member name or email. | +| `--sort-by ` | No | Field used to sort the result. Do not rely on case-insensitive ordering when sorting by `name`. Defaults to "name". Accepted values: `name`, `email`, `joinedAt`. | +| `--sort-order ` | No | Sort direction. Defaults to "asc". Accepted values: `asc`, `desc`. | +| `--limit ` | No | Maximum items to return (0 for everything). Defaults to `0`. | + + + +API request and response schemas: [listOrganizationMembers](/api-reference/organizations/listOrganizationMembers). + +### Get organization member credit limit + +OAuth login or personal API key required. + +```bash +sim organizations members usage-limit get [options] +``` **Arguments** @@ -61,7 +118,7 @@ Remove Organization Domain (OAuth login or personal API key required) | Argument | Required | Description | | --- | --- | --- | -| `domainId` | Yes | Domain claim owned by this organization. | +| `userId` | Yes | User ID of an organization member or external collaborator with workspace access in this organization. Use List Organization Members or List Workspace Members to find it. | @@ -72,25 +129,26 @@ Remove Organization Domain (OAuth login or personal API key required) | Option | Required | Description | | --- | --- | --- | | `--organization ` | Yes | Organization identifier. | -| `-y, --yes` | Yes | Confirm this operation. | -## Verify organization domain +API request and response schemas: [getOrganizationMemberUsageLimit](/api-reference/organizations/getOrganizationMemberUsageLimit). + +### Update organization member + +OAuth login or personal API key required. ```bash -sim organizations domains verify [options] +sim organizations members update [options] ``` -Verify Organization Domain (OAuth login or personal API key required) - **Arguments** | Argument | Required | Description | | --- | --- | --- | -| `domainId` | Yes | Domain claim owned by this organization. | +| `userId` | Yes | User identifier of the organization member. | @@ -101,24 +159,27 @@ Verify Organization Domain (OAuth login or personal API key required) | Option | Required | Description | | --- | --- | --- | | `--organization ` | Yes | Organization identifier. | +| `--role ` | Yes | New organization role. Ownership transfers use a separate operation. Accepted values: `member`, `admin`. | -## Cancel organization access request +API request and response schemas: [updateOrganizationMember](/api-reference/organizations/updateOrganizationMember). + +### Update organization member credit limit + +OAuth login or personal API key required. ```bash -sim organizations access-requests cancel [options] +sim organizations members usage-limit update [options] ``` -Cancel Organization Access Request (OAuth login or personal API key required) - **Arguments** | Argument | Required | Description | | --- | --- | --- | -| `requestId` | Yes | Access request identifier. | +| `userId` | Yes | User ID of an organization member or external collaborator with workspace access in this organization. Use List Organization Members or List Workspace Members to find it. | @@ -129,16 +190,31 @@ Cancel Organization Access Request (OAuth login or personal API key required) | Option | Required | Description | | --- | --- | --- | | `--organization ` | Yes | Organization identifier. | +| `--credit-limit ` | Yes | Credit cap for this person. Send null to clear the cap or 0 to prevent further credit-consuming usage. Organization limits still apply. | -## Create organization access request +API request and response schemas: [updateOrganizationMemberUsageLimit](/api-reference/organizations/updateOrganizationMemberUsageLimit). + +### Remove organization member + +OAuth login or personal API key required. + +This removes the member, revokes their organization workspace access, and ends their sessions. ```bash -sim organizations access-requests create [options] +sim organizations members remove [options] ``` -Create Organization Access Request (OAuth login or personal API key required) +**Arguments** + + + +| Argument | Required | Description | +| --- | --- | --- | +| `userId` | Yes | User identifier of the organization member. | + + **Options** @@ -147,19 +223,22 @@ Create Organization Access Request (OAuth login or personal API key required) | Option | Required | Description | | --- | --- | --- | | `--organization ` | Yes | Organization identifier. | -| `--target ` | Yes | Target returned by Discover Workspace Access Requests or Discover Organization Access Requests. The target must currently be requestable. (JSON, or @path / @- to read a file or stdin). | -| `--reason ` | No | Why the acting user needs this access. | +| `-y, --yes` | Yes | Confirm this operation. | -## Discover organization access requests +API request and response schemas: [removeOrganizationMember](/api-reference/organizations/removeOrganizationMember). + +## Invitations + +### List organization invitations + +OAuth login or personal API key required. ```bash -sim organizations access-requests discover [options] +sim organizations invitations list [options] ``` -Discover Organization Access Requests (OAuth login or personal API key required) - **Options** @@ -167,42 +246,35 @@ Discover Organization Access Requests (OAuth login or personal API key required) | Option | Required | Description | | --- | --- | --- | | `--organization ` | Yes | Organization identifier. | -| `--search ` | No | Case-insensitive substring match against the access item label. | -| `--target-kind ` | No | Category of access to discover. Accepted values: `feature`, `integration`, `provider`, `model`, `tool`, `knowledge_connector`, `file_share_auth`, `chat_deploy_auth`, `usage_limit`. | -| `--state ` | No | Filter by the acting user’s current access. Requestable items can be submitted for review. Accepted values: `allowed`, `requestable`, `unavailable`. | -| `--sort-by ` | No | Field used to sort the result. Accepted values: `label`. | -| `--sort-order ` | No | Sort direction. Accepted values: `asc`, `desc`. | +| `--search ` | No | Case-insensitive substring match against the invitee email. | +| `--status ` | No | Filter by current invitation status. Omit to include all statuses. Accepted values: `pending`, `accepted`, `rejected`, `cancelled`, `expired`. | +| `--sort-by ` | No | Field used to sort the result. Defaults to "createdAt". Accepted values: `email`, `createdAt`. | +| `--sort-order ` | No | Sort direction. Defaults to "desc". Accepted values: `asc`, `desc`. | | `--limit ` | No | Maximum items to return (0 for everything). Defaults to `100`. | | `--cursor ` | No | Continue from nextCursor returned by a previous result. | -## Get organization access request settings +API request and response schemas: [listOrganizationInvitations](/api-reference/organizations/listOrganizationInvitations). + +### Get organization invitation + +OAuth login or personal API key required. ```bash -sim organizations access-requests settings get [options] +sim organizations invitations get [options] ``` -Get Organization Access Request Settings (OAuth login or personal API key required) - -**Options** +**Arguments** -| Option | Required | Description | +| Argument | Required | Description | | --- | --- | --- | -| `--organization ` | Yes | Organization identifier. | +| `invitationId` | Yes | Invitation identifier. | -## Update organization access request settings - -```bash -sim organizations access-requests settings update [options] -``` - -Update Organization Access Request Settings (OAuth login or personal API key required) - **Options** @@ -210,18 +282,19 @@ Update Organization Access Request Settings (OAuth login or personal API key req | Option | Required | Description | | --- | --- | --- | | `--organization ` | Yes | Organization identifier. | -| `--allow-requests ` | Yes | Allow new requests and approvals. Disabling requests preserves history and still allows cancellation and decline. Accepted values: `true`, `false`. | -## List my organization access requests +API request and response schemas: [getOrganizationInvitation](/api-reference/organizations/getOrganizationInvitation). + +### Create organization invitation + +OAuth login or personal API key required. ```bash -sim organizations access-requests mine [options] +sim organizations invitations create [options] ``` -List My Organization Access Requests (OAuth login or personal API key required) - **Options** @@ -229,21 +302,30 @@ List My Organization Access Requests (OAuth login or personal API key required) | Option | Required | Description | | --- | --- | --- | | `--organization ` | Yes | Organization identifier. | -| `--status ` | No | Filter by request status; omit to include all statuses. Accepted values: `pending`, `fulfilled`, `declined`, `cancelled`, `closed`. | -| `--sort-by ` | No | Field used to sort the result. Accepted values: `createdAt`, `targetLabel`. | -| `--sort-order ` | No | Sort direction. Accepted values: `asc`, `desc`. | -| `--limit ` | No | Maximum items to return (0 for everything). Defaults to `100`. | -| `--cursor ` | No | Continue from nextCursor returned by a previous result. | +| `--email ` | Yes | Email address of the person to invite. | +| `--role ` | No | Organization role to offer. Defaults to member; grants no workspace-specific permissions. Accepted values: `member`, `admin`. | -## List organization access requests +API request and response schemas: [createOrganizationInvitation](/api-reference/organizations/createOrganizationInvitation). + +### Resend organization invitation + +OAuth login or personal API key required. ```bash -sim organizations access-requests list [options] +sim organizations invitations resend [options] ``` -List Organization Access Requests (OAuth login or personal API key required) +**Arguments** + + + +| Argument | Required | Description | +| --- | --- | --- | +| `invitationId` | Yes | Invitation identifier. | + + **Options** @@ -252,30 +334,28 @@ List Organization Access Requests (OAuth login or personal API key required) | Option | Required | Description | | --- | --- | --- | | `--organization ` | Yes | Organization identifier. | -| `--status ` | No | Filter by request status; omit to include all statuses. Accepted values: `pending`, `fulfilled`, `declined`, `cancelled`, `closed`. | -| `--sort-by ` | No | Field used to sort the result. Accepted values: `createdAt`, `targetLabel`. | -| `--sort-order ` | No | Sort direction. Accepted values: `asc`, `desc`. | -| `--limit ` | No | Maximum items to return (0 for everything). Defaults to `100`. | -| `--cursor ` | No | Continue from nextCursor returned by a previous result. | -| `--search ` | No | Case-insensitive substring match against the target label or requester name or email. | -## Preview organization access request +API request and response schemas: [resendOrganizationInvitation](/api-reference/organizations/resendOrganizationInvitation). + +### Revoke organization invitation + +OAuth login or personal API key required. + +This cancels the invitation and all its workspace grants, preventing acceptance. ```bash -sim organizations access-requests preview [options] +sim organizations invitations revoke [options] ``` -Preview Organization Access Request (OAuth login or personal API key required) - **Arguments** | Argument | Required | Description | | --- | --- | --- | -| `requestId` | Yes | Access request identifier. | +| `invitationId` | Yes | Invitation identifier. | @@ -286,24 +366,27 @@ Preview Organization Access Request (OAuth login or personal API key required) | Option | Required | Description | | --- | --- | --- | | `--organization ` | Yes | Organization identifier. | +| `-y, --yes` | Yes | Confirm this operation. | -## Resolve organization access request +API request and response schemas: [revokeOrganizationInvitation](/api-reference/organizations/revokeOrganizationInvitation). + +### List organization invitation workspaces + +OAuth login or personal API key required. ```bash -sim organizations access-requests resolve [options] +sim organizations invitations workspaces [options] ``` -Resolve Organization Access Request (OAuth login or personal API key required) - **Arguments** | Argument | Required | Description | | --- | --- | --- | -| `requestId` | Yes | Access request identifier. | +| `invitationId` | Yes | Invitation identifier. | @@ -314,21 +397,26 @@ Resolve Organization Access Request (OAuth login or personal API key required) | Option | Required | Description | | --- | --- | --- | | `--organization ` | Yes | Organization identifier. | -| `--action ` | Yes | apply: Apply the reviewed change to the governing group or member credit cap. decline: Decline the request without changing permissions or credit limits. Accepted values: `apply`, `decline`. | -| `--expected-fingerprint ` | No | Fingerprint from Preview Organization Access Request. Review its changes and impact before applying; a stale preview returns a conflict. Available when action is apply. Required when action is apply. | -| `--new-limit-credits ` | No | Required only for a usage-limit request: a whole-number credit cap greater than the current cap. Omit for permission requests. Available when action is apply. | -| `--reason ` | No | Required explanation for declining this request. Available when action is decline. Required when action is decline. | +| `--search ` | No | Case-insensitive substring match against the workspace name. | +| `--sort-by ` | No | Field used to sort the result. Do not rely on case-insensitive ordering when sorting by `name`. Defaults to "name". Accepted values: `name`, `id`. | +| `--sort-order ` | No | Sort direction. Defaults to "asc". Accepted values: `asc`, `desc`. | +| `--limit ` | No | Maximum items to return (0 for everything). Defaults to `100`. | +| `--cursor ` | No | Continue from nextCursor returned by a previous result. | -## Create organization invitation +API request and response schemas: [listOrganizationInvitationWorkspaces](/api-reference/organizations/listOrganizationInvitationWorkspaces). + +## Usage + +### Get organization usage summary + +OAuth login or personal API key required. ```bash -sim organizations invitations create [options] +sim organizations usage summary [options] ``` -Create Organization Invitation (OAuth login or personal API key required) - **Options** @@ -336,29 +424,49 @@ Create Organization Invitation (OAuth login or personal API key required) | Option | Required | Description | | --- | --- | --- | | `--organization ` | Yes | Organization identifier. | -| `--email ` | Yes | Email address of the person to invite. | -| `--role ` | No | Organization role to offer. Defaults to member; grants no workspace-specific permissions. Accepted values: `member`, `admin`. | +| `--preset ` | No | Reporting window. Custom requires startDate and endDate and is capped at 92 days; other presets reject those bounds. Resolved billing windows are capped at 366 days. Defaults to "30d". Accepted values: `current-period`, `previous-period`, `7d`, `30d`, `custom`. | +| `--start-date ` | No | First calendar date included, in the selected timezone. Requires preset=custom. | +| `--end-date ` | No | Last calendar date included, in the selected timezone. Requires preset=custom. | +| `--timezone ` | No | IANA timezone for calendar boundaries; defaults to UTC. | -## Get organization invitation +API request and response schemas: [getOrganizationUsageSummary](/api-reference/organizations/getOrganizationUsageSummary). + +### Get organization usage breakdown + +OAuth login or personal API key required. ```bash -sim organizations invitations get [options] +sim organizations usage breakdown [options] ``` -Get Organization Invitation (OAuth login or personal API key required) - -**Arguments** +**Options** -| Argument | Required | Description | +| Option | Required | Description | | --- | --- | --- | -| `invitationId` | Yes | Invitation identifier. | +| `--organization ` | Yes | Organization identifier. | +| `--preset ` | No | Reporting window. Custom requires startDate and endDate and is capped at 92 days; other presets reject those bounds. Resolved billing windows are capped at 366 days. Defaults to "30d". Accepted values: `current-period`, `previous-period`, `7d`, `30d`, `custom`. | +| `--start-date ` | No | First calendar date included, in the selected timezone. Requires preset=custom. | +| `--end-date ` | No | Last calendar date included, in the selected timezone. Requires preset=custom. | +| `--timezone ` | No | IANA timezone for calendar boundaries; defaults to UTC. | +| `--dimension ` | Yes | Usage grouping dimension. Accepted values: `member`, `workspace`, `workflow`, `model`, `byok`, `source`. | +| `--limit ` | No | Maximum ranked groups to return. Remaining usage is summarized in other. Must be a whole number from 1 to 100. Defaults to 50. | +API request and response schemas: [getOrganizationUsageBreakdown](/api-reference/organizations/getOrganizationUsageBreakdown). + +### List organization usage events + +OAuth login or personal API key required. + +```bash +sim organizations usage events [options] +``` + **Options** @@ -366,17 +474,30 @@ Get Organization Invitation (OAuth login or personal API key required) | Option | Required | Description | | --- | --- | --- | | `--organization ` | Yes | Organization identifier. | +| `--preset ` | No | Reporting window. Custom requires startDate and endDate and is capped at 92 days; other presets reject those bounds. Resolved billing windows are capped at 366 days. Defaults to "30d". Accepted values: `current-period`, `previous-period`, `7d`, `30d`, `custom`. | +| `--start-date ` | No | First calendar date included, in the selected timezone. Requires preset=custom. | +| `--end-date ` | No | Last calendar date included, in the selected timezone. Requires preset=custom. | +| `--timezone ` | No | IANA timezone for calendar boundaries; defaults to UTC. | +| `--source ` | No | Restrict events to one product surface. Accepted values: `workflow`, `wand`, `sim-chat`, `mcp_copilot`, `mothership_block`, `knowledge-base`, `voice-input`, `enrichment`, `voice-output`, `api-tool`. | +| `--limit ` | No | Maximum items to return (0 for everything). Defaults to `100`. | +| `--cursor ` | No | Continue from nextCursor returned by a previous result. | +| `--sort-by ` | No | Field used to sort the result. Defaults to "createdAt". Accepted values: `createdAt`. | +| `--sort-order ` | No | Sort direction. Defaults to "desc". Accepted values: `asc`, `desc`. | -## List organization invitations +API request and response schemas: [listOrganizationUsageEvents](/api-reference/organizations/listOrganizationUsageEvents). + +## Access requests + +### Discover organization access requests + +OAuth login or personal API key required. ```bash -sim organizations invitations list [options] +sim organizations access-requests discover [options] ``` -List Organization Invitations (OAuth login or personal API key required) - **Options** @@ -384,33 +505,48 @@ List Organization Invitations (OAuth login or personal API key required) | Option | Required | Description | | --- | --- | --- | | `--organization ` | Yes | Organization identifier. | -| `--search ` | No | Case-insensitive substring match against the invitee email. | -| `--status ` | No | Filter by current invitation status. Omit to include all statuses. Accepted values: `pending`, `accepted`, `rejected`, `cancelled`, `expired`. | -| `--sort-by ` | No | Field used to sort the result. Accepted values: `email`, `createdAt`. | -| `--sort-order ` | No | Sort direction. Accepted values: `asc`, `desc`. | +| `--search ` | No | Case-insensitive substring match against the access item label. | +| `--target-kind ` | No | Category of access to discover. Accepted values: `feature`, `integration`, `provider`, `model`, `tool`, `knowledge_connector`, `file_share_auth`, `chat_deploy_auth`, `usage_limit`. | +| `--state ` | No | Filter by the acting user’s current access. Requestable items can be submitted for review. Accepted values: `allowed`, `requestable`, `unavailable`. | +| `--sort-by ` | No | Field used to sort the result. Defaults to "label". Accepted values: `label`. | +| `--sort-order ` | No | Sort direction. Defaults to "asc". Accepted values: `asc`, `desc`. | | `--limit ` | No | Maximum items to return (0 for everything). Defaults to `100`. | | `--cursor ` | No | Continue from nextCursor returned by a previous result. | -## List organization invitation workspaces +API request and response schemas: [discoverOrganizationAccessRequests](/api-reference/access-requests/discoverOrganizationAccessRequests). + +### Create organization access request + +OAuth login or personal API key required. ```bash -sim organizations invitations workspaces [options] +sim organizations access-requests create [options] ``` -List Organization Invitation Workspaces (OAuth login or personal API key required) - -**Arguments** +**Options** -| Argument | Required | Description | +| Option | Required | Description | | --- | --- | --- | -| `invitationId` | Yes | Invitation identifier. | +| `--organization ` | Yes | Organization identifier. | +| `--target ` | Yes | Target returned by Discover Workspace Access Requests or Discover Organization Access Requests. The target must currently be requestable. (JSON, or @path / @- to read a file or stdin). | +| `--reason ` | No | Why the acting user needs this access. Defaults to "". | +API request and response schemas: [createOrganizationAccessRequest](/api-reference/access-requests/createOrganizationAccessRequest). + +### List my organization access requests + +OAuth login or personal API key required. + +```bash +sim organizations access-requests mine [options] +``` + **Options** @@ -418,29 +554,31 @@ List Organization Invitation Workspaces (OAuth login or personal API key require | Option | Required | Description | | --- | --- | --- | | `--organization ` | Yes | Organization identifier. | -| `--search ` | No | Case-insensitive substring match against the workspace name. | -| `--sort-by ` | No | Field used to sort the result. Sorting by `name` is case-sensitive and follows the storage collation, so do not rely on a case-insensitive order. Accepted values: `name`, `id`. | -| `--sort-order ` | No | Sort direction. Accepted values: `asc`, `desc`. | +| `--status ` | No | Filter by request status; omit to include all statuses. Accepted values: `pending`, `fulfilled`, `declined`, `cancelled`, `closed`. | +| `--sort-by ` | No | Field used to sort the result. Defaults to "createdAt". Accepted values: `createdAt`, `targetLabel`. | +| `--sort-order ` | No | Sort direction. Defaults to "desc". Accepted values: `asc`, `desc`. | | `--limit ` | No | Maximum items to return (0 for everything). Defaults to `100`. | | `--cursor ` | No | Continue from nextCursor returned by a previous result. | -## Resend organization invitation +API request and response schemas: [listMyOrganizationAccessRequests](/api-reference/access-requests/listMyOrganizationAccessRequests). + +### Cancel organization access request + +OAuth login or personal API key required. ```bash -sim organizations invitations resend [options] +sim organizations access-requests cancel [options] ``` -Resend Organization Invitation (OAuth login or personal API key required) - **Arguments** | Argument | Required | Description | | --- | --- | --- | -| `invitationId` | Yes | Invitation identifier. | +| `requestId` | Yes | Access request identifier. | @@ -454,23 +592,15 @@ Resend Organization Invitation (OAuth login or personal API key required) -## Revoke organization invitation +API request and response schemas: [cancelOrganizationAccessRequest](/api-reference/access-requests/cancelOrganizationAccessRequest). -```bash -sim organizations invitations revoke [options] -``` - -Revoke Organization Invitation (OAuth login or personal API key required) - -**Arguments** - - +### List organization access requests -| Argument | Required | Description | -| --- | --- | --- | -| `invitationId` | Yes | Invitation identifier. | +OAuth login or personal API key required. - +```bash +sim organizations access-requests list [options] +``` **Options** @@ -479,25 +609,32 @@ Revoke Organization Invitation (OAuth login or personal API key required) | Option | Required | Description | | --- | --- | --- | | `--organization ` | Yes | Organization identifier. | -| `-y, --yes` | Yes | Confirm this operation. | +| `--status ` | No | Filter by request status; omit to include all statuses. Accepted values: `pending`, `fulfilled`, `declined`, `cancelled`, `closed`. | +| `--sort-by ` | No | Field used to sort the result. Defaults to "createdAt". Accepted values: `createdAt`, `targetLabel`. | +| `--sort-order ` | No | Sort direction. Defaults to "desc". Accepted values: `asc`, `desc`. | +| `--limit ` | No | Maximum items to return (0 for everything). Defaults to `100`. | +| `--cursor ` | No | Continue from nextCursor returned by a previous result. | +| `--search ` | No | Case-insensitive substring match against the target label or requester name or email. | -## Delete SSO provider +API request and response schemas: [listOrganizationAccessRequests](/api-reference/access-requests/listOrganizationAccessRequests). + +### Preview organization access request + +OAuth login or personal API key required. ```bash -sim organizations sso providers delete [options] +sim organizations access-requests preview [options] ``` -Delete SSO Provider (OAuth login or personal API key required) - **Arguments** | Argument | Required | Description | | --- | --- | --- | -| `providerId` | Yes | Identity provider identifier. | +| `requestId` | Yes | Access request identifier. | @@ -508,25 +645,26 @@ Delete SSO Provider (OAuth login or personal API key required) | Option | Required | Description | | --- | --- | --- | | `--organization ` | Yes | Organization identifier. | -| `-y, --yes` | Yes | Confirm this operation. | -## Get SSO provider +API request and response schemas: [previewOrganizationAccessRequest](/api-reference/access-requests/previewOrganizationAccessRequest). + +### Resolve organization access request + +OAuth login or personal API key required. ```bash -sim organizations sso providers get [options] +sim organizations access-requests resolve [options] ``` -Get SSO Provider (OAuth login or personal API key required) - **Arguments** | Argument | Required | Description | | --- | --- | --- | -| `providerId` | Yes | Identity provider identifier. | +| `requestId` | Yes | Access request identifier. | @@ -537,17 +675,23 @@ Get SSO Provider (OAuth login or personal API key required) | Option | Required | Description | | --- | --- | --- | | `--organization ` | Yes | Organization identifier. | +| `--action ` | Yes | apply: Apply the reviewed change to the governing group or member credit cap. decline: Decline the request without changing permissions or credit limits. Accepted values: `apply`, `decline`. | +| `--expected-fingerprint ` | Conditional | Fingerprint from Preview Organization Access Request. Review its changes and impact before applying; a stale preview returns a conflict. Available when action is apply. Required when action is apply. | +| `--new-limit-credits ` | Conditional | Required only for a usage-limit request: a whole-number credit cap greater than the current cap. Omit for permission requests. Available when action is apply. | +| `--reason ` | Conditional | Required explanation for declining this request. Available when action is decline. Required when action is decline. | -## List SSO providers +API request and response schemas: [resolveOrganizationAccessRequest](/api-reference/access-requests/resolveOrganizationAccessRequest). + +### Get organization access request settings + +OAuth login or personal API key required. ```bash -sim organizations sso providers list [options] +sim organizations access-requests settings get [options] ``` -List SSO Providers (OAuth login or personal API key required) - **Options** @@ -555,20 +699,19 @@ List SSO Providers (OAuth login or personal API key required) | Option | Required | Description | | --- | --- | --- | | `--organization ` | Yes | Organization identifier. | -| `--limit ` | No | Maximum items to return (0 for everything). Defaults to `0`. | -| `--sort-by ` | No | Field used to sort the result. Accepted values: `providerId`, `domain`. | -| `--sort-order ` | No | Sort direction. Accepted values: `asc`, `desc`. | -## Save SSO provider +API request and response schemas: [getOrganizationAccessRequestSettings](/api-reference/access-requests/getOrganizationAccessRequestSettings). + +### Update organization access request settings + +OAuth login or personal API key required. ```bash -sim organizations sso providers save [options] +sim organizations access-requests settings update [options] ``` -Save SSO Provider (OAuth login or personal API key required) - **Options** @@ -576,73 +719,22 @@ Save SSO Provider (OAuth login or personal API key required) | Option | Required | Description | | --- | --- | --- | | `--organization ` | Yes | Organization identifier. | -| `--provider-type ` | Yes | oidc: Configure an OpenID Connect identity provider. saml: Configure a SAML identity provider. Accepted values: `oidc`, `saml`. | -| `--provider-id ` | Yes | Globally unique provider ID; saving an existing provider replaces its supplied configuration. | -| `--issuer ` | Yes | Identity provider issuer URL. | -| `--domain ` | Yes | Email domain already verified by this organization. | -| `--jit-provisioning-enabled` | No | Allow SSO sign-in to provision organization membership, subject to eligibility and available seats. | -| `--no-jit-provisioning-enabled` | No | Send --jit-provisioning-enabled as false. | -| `--mapping ` | No | Identity-provider claims mapped to user fields. (JSON, or @path / @- to read a file or stdin). | -| `--client-id ` | No | Identity provider client identifier. Available when providerType is oidc. Required when providerType is oidc. | -| `--client-secret ` | No | Write-only OIDC client secret; the redacted marker from providers get preserves an existing secret. Passing it inline exposes it to shell history and process listings. Required when --provider-type is oidc (@path / @- reads a file or stdin verbatim, including trailing newlines; @@value for a literal leading @). | -| `--scopes ` | No | OIDC scopes; offline_access is omitted. Available when providerType is oidc. (JSON, or @path / @- to read a file or stdin). | -| `--pkce` | No | Use PKCE for the authorization flow. Available when providerType is oidc. | -| `--no-pkce` | No | Send --pkce as false. | -| `--authorization-endpoint ` | No | Optional authorization endpoint; otherwise resolved through issuer discovery. Available when providerType is oidc. | -| `--token-endpoint ` | No | Optional token endpoint; otherwise resolved through issuer discovery. Available when providerType is oidc. | -| `--user-info-endpoint ` | No | Optional UserInfo endpoint. Available when providerType is oidc. | -| `--skip-user-info-endpoint` | No | Read identity claims from the ID token instead of calling UserInfo. Available when providerType is oidc. | -| `--no-skip-user-info-endpoint` | No | Send --skip-user-info-endpoint as false. | -| `--jwks-endpoint ` | No | Optional signing-key endpoint; otherwise resolved through issuer discovery. Available when providerType is oidc. | -| `--entry-point ` | No | Identity provider SAML sign-in endpoint. Available when providerType is saml. Required when providerType is saml. | -| `--cert ` | No | Identity provider signing certificate. Available when providerType is saml. Required when providerType is saml. | -| `--callback-url ` | No | SAML callback URL; defaults to this provider’s Sim callback. Available when providerType is saml. | -| `--audience ` | No | SAML audience; omission preserves the saved value. Available when providerType is saml. | -| `--want-assertions-signed` | No | Require signed assertions; omission preserves the saved value. Available when providerType is saml. | -| `--no-want-assertions-signed` | No | Send --want-assertions-signed as false. | -| `--signature-algorithm ` | No | Signature algorithm accepted by the SAML configuration validator; omission preserves the saved value. Available when providerType is saml. | -| `--digest-algorithm ` | No | Digest algorithm accepted by the SAML configuration validator; omission preserves the saved value. Available when providerType is saml. | -| `--identifier-format ` | No | SAML NameID format; omission clears the saved value. Available when providerType is saml. | -| `--idp-metadata ` | No | Identity provider metadata XML; omission clears the saved document. Available when providerType is saml. | - - - -## Set primary SSO provider - -```bash -sim organizations sso providers primary [options] -``` - -Set Primary SSO Provider (OAuth login or personal API key required) - -**Arguments** - - - -| Argument | Required | Description | -| --- | --- | --- | -| `providerId` | Yes | Identity provider identifier. | +| `--allow-requests ` | Yes | Allow new requests and approvals. Disabling requests preserves history and still allows cancellation and decline. Accepted values: `true`, `false`. | -**Options** +API request and response schemas: [updateOrganizationAccessRequestSettings](/api-reference/access-requests/updateOrganizationAccessRequestSettings). - +## Verified domains -| Option | Required | Description | -| --- | --- | --- | -| `--organization ` | Yes | Organization identifier. | +### List organization domains - - -## Get SSO policy +OAuth login or personal API key required. ```bash -sim organizations sso policy get [options] +sim organizations domains list [options] ``` -Get SSO Policy (OAuth login or personal API key required) - **Options** @@ -650,17 +742,22 @@ Get SSO Policy (OAuth login or personal API key required) | Option | Required | Description | | --- | --- | --- | | `--organization ` | Yes | Organization identifier. | +| `--limit ` | No | Maximum items to return (0 for everything). Defaults to `0`. | +| `--sort-by ` | No | Field used to sort the result. Defaults to "domain". Accepted values: `domain`. | +| `--sort-order ` | No | Sort direction. Defaults to "asc". Accepted values: `asc`, `desc`. | -## Update SSO policy +API request and response schemas: [listOrganizationDomains](/api-reference/organizations/listOrganizationDomains). + +### Add organization domain + +OAuth login or personal API key required. ```bash -sim organizations sso policy update [options] +sim organizations domains add [options] ``` -Update SSO Policy (OAuth login or personal API key required) - **Options** @@ -668,43 +765,27 @@ Update SSO Policy (OAuth login or personal API key required) | Option | Required | Description | | --- | --- | --- | | `--organization ` | Yes | Organization identifier. | -| `--require-sso ` | Yes | Require organization SSO on future sign-ins; existing sessions remain active. Accepted values: `true`, `false`. | +| `--domain ` | Yes | Domain to claim and verify through a DNS TXT record. | -## Get organization - -```bash -sim organizations get -``` - -Get Organization (OAuth login or personal API key required) - -**Arguments** - - - -| Argument | Required | Description | -| --- | --- | --- | -| `organizationId` | Yes | Organization identifier. | +API request and response schemas: [addOrganizationDomain](/api-reference/organizations/addOrganizationDomain). - +### Verify organization domain -## Get organization member credit limit +OAuth login or personal API key required. ```bash -sim organizations members usage-limit get [options] +sim organizations domains verify [options] ``` -Get Organization Member Credit Limit (OAuth login or personal API key required) - **Arguments** | Argument | Required | Description | | --- | --- | --- | -| `userId` | Yes | User ID of an organization member or external collaborator with workspace access in this organization. Use List Organization Members or List Workspace Members to find it. | +| `domainId` | Yes | Domain claim owned by this organization. | @@ -718,21 +799,25 @@ Get Organization Member Credit Limit (OAuth login or personal API key required) -## Update organization member credit limit +API request and response schemas: [verifyOrganizationDomain](/api-reference/organizations/verifyOrganizationDomain). + +### Remove organization domain + +OAuth login or personal API key required. + +This removes the domain claim and revokes verified SSO authority for its providers. ```bash -sim organizations members usage-limit update [options] +sim organizations domains remove [options] ``` -Update Organization Member Credit Limit (OAuth login or personal API key required) - **Arguments** | Argument | Required | Description | | --- | --- | --- | -| `userId` | Yes | User ID of an organization member or external collaborator with workspace access in this organization. Use List Organization Members or List Workspace Members to find it. | +| `domainId` | Yes | Domain claim owned by this organization. | @@ -743,18 +828,22 @@ Update Organization Member Credit Limit (OAuth login or personal API key require | Option | Required | Description | | --- | --- | --- | | `--organization ` | Yes | Organization identifier. | -| `--credit-limit ` | Yes | Credit cap for this person. Send null to clear the cap or 0 to prevent further credit-consuming usage. Organization limits still apply. | +| `-y, --yes` | Yes | Confirm this operation. | -## List organization members +API request and response schemas: [removeOrganizationDomain](/api-reference/organizations/removeOrganizationDomain). + +## SSO providers and policy + +### List SSO providers + +OAuth login or personal API key required. ```bash -sim organizations members list [options] +sim organizations sso providers list [options] ``` -List Organization Members (OAuth login or personal API key required) - **Options** @@ -762,28 +851,29 @@ List Organization Members (OAuth login or personal API key required) | Option | Required | Description | | --- | --- | --- | | `--organization ` | Yes | Organization identifier. | -| `--search ` | No | Case-insensitive substring match against member name or email. | -| `--sort-by ` | No | Field used to sort the result. Sorting by `name` is case-sensitive and follows the storage collation, so do not rely on a case-insensitive order. Accepted values: `name`, `email`, `joinedAt`. | -| `--sort-order ` | No | Sort direction. Accepted values: `asc`, `desc`. | | `--limit ` | No | Maximum items to return (0 for everything). Defaults to `0`. | +| `--sort-by ` | No | Field used to sort the result. Defaults to "providerId". Accepted values: `providerId`, `domain`. | +| `--sort-order ` | No | Sort direction. Defaults to "asc". Accepted values: `asc`, `desc`. | -## Remove organization member +API request and response schemas: [listSsoProviders](/api-reference/organizations/listSsoProviders). + +### Get SSO provider + +OAuth login or personal API key required. ```bash -sim organizations members remove [options] +sim organizations sso providers get [options] ``` -Remove Organization Member (OAuth login or personal API key required) - **Arguments** | Argument | Required | Description | | --- | --- | --- | -| `userId` | Yes | User identifier of the organization member. | +| `providerId` | Yes | Identity provider identifier. | @@ -794,27 +884,20 @@ Remove Organization Member (OAuth login or personal API key required) | Option | Required | Description | | --- | --- | --- | | `--organization ` | Yes | Organization identifier. | -| `-y, --yes` | Yes | Confirm this operation. | -## Update organization member +API request and response schemas: [getSsoProvider](/api-reference/organizations/getSsoProvider). -```bash -sim organizations members update [options] -``` +### Save SSO provider -Update Organization Member (OAuth login or personal API key required) +OAuth login or personal API key required. -**Arguments** +Choose `--provider-type oidc` or `saml`. OIDC requires `--client-id` and `--client-secret`; SAML requires `--entry-point` and `--cert`. Both require an organization-verified domain. The option descriptions state which omitted fields are preserved or cleared. - - -| Argument | Required | Description | -| --- | --- | --- | -| `userId` | Yes | User identifier of the organization member. | - - +```bash +sim organizations sso providers save [options] +``` **Options** @@ -823,42 +906,57 @@ Update Organization Member (OAuth login or personal API key required) | Option | Required | Description | | --- | --- | --- | | `--organization ` | Yes | Organization identifier. | -| `--role ` | Yes | New organization role. Ownership transfers use a separate operation. Accepted values: `member`, `admin`. | +| `--provider-type ` | Yes | oidc: Configure an OpenID Connect identity provider. saml: Configure a SAML identity provider. Accepted values: `oidc`, `saml`. | +| `--provider-id ` | Yes | Globally unique provider ID; saving an existing provider replaces its supplied configuration. | +| `--issuer ` | Yes | Identity provider issuer URL. | +| `--domain ` | Yes | Email domain already verified by this organization. | +| `--jit-provisioning-enabled` | No | Allow SSO sign-in to provision organization membership, subject to eligibility and available seats. Defaults to true. | +| `--no-jit-provisioning-enabled` | No | Send --jit-provisioning-enabled as false. | +| `--mapping ` | No | Identity-provider claims mapped to user fields. Defaults to {"id":"sub","email":"email","name":"name","image":"picture"}. (JSON, or @path / @- to read a file or stdin). | +| `--client-id ` | Conditional | Identity provider client identifier. Available when providerType is oidc. Required when providerType is oidc. | +| `--client-secret ` | Conditional | Write-only OIDC client secret; the redacted marker from providers get preserves an existing secret. Passing it inline exposes it to shell history and process listings. Required when --provider-type is oidc (@path / @- reads a file or stdin verbatim, including trailing newlines; @@value for a literal leading @). | +| `--scopes ` | No | OIDC scopes; offline_access is omitted. Available when providerType is oidc. Defaults to ["openid","profile","email"]. (JSON, or @path / @- to read a file or stdin). | +| `--pkce` | No | Use PKCE for the authorization flow. Available when providerType is oidc. Defaults to true. | +| `--no-pkce` | No | Send --pkce as false. | +| `--authorization-endpoint ` | No | Optional authorization endpoint; otherwise resolved through issuer discovery. Available when providerType is oidc. | +| `--token-endpoint ` | No | Optional token endpoint; otherwise resolved through issuer discovery. Available when providerType is oidc. | +| `--user-info-endpoint ` | No | Optional UserInfo endpoint. Available when providerType is oidc. | +| `--skip-user-info-endpoint` | No | Read identity claims from the ID token instead of calling UserInfo. Available when providerType is oidc. Defaults to false. | +| `--no-skip-user-info-endpoint` | No | Send --skip-user-info-endpoint as false. | +| `--jwks-endpoint ` | No | Optional signing-key endpoint; otherwise resolved through issuer discovery. Available when providerType is oidc. | +| `--entry-point ` | Conditional | Identity provider SAML sign-in endpoint. Available when providerType is saml. Required when providerType is saml. | +| `--cert ` | Conditional | Identity provider signing certificate. Available when providerType is saml. Required when providerType is saml. | +| `--callback-url ` | No | SAML callback URL; defaults to this provider’s Sim callback. Available when providerType is saml. | +| `--audience ` | No | SAML audience; omission preserves the saved value. Available when providerType is saml. | +| `--want-assertions-signed` | No | Require signed assertions; omission preserves the saved value. Available when providerType is saml. | +| `--no-want-assertions-signed` | No | Send --want-assertions-signed as false. | +| `--signature-algorithm ` | No | Signature algorithm accepted by the SAML configuration validator; omission preserves the saved value. Available when providerType is saml. | +| `--digest-algorithm ` | No | Digest algorithm accepted by the SAML configuration validator; omission preserves the saved value. Available when providerType is saml. | +| `--identifier-format ` | No | SAML NameID format; omission clears the saved value. Available when providerType is saml. | +| `--idp-metadata ` | No | Identity provider metadata XML; omission clears the saved document. Available when providerType is saml. | -## Get organization usage breakdown +API request and response schemas: [saveSsoProvider](/api-reference/organizations/saveSsoProvider). + +### Set primary SSO provider + +OAuth login or personal API key required. ```bash -sim organizations usage breakdown [options] +sim organizations sso providers primary [options] ``` -Get Organization Usage Breakdown (OAuth login or personal API key required) - -**Options** +**Arguments** -| Option | Required | Description | +| Argument | Required | Description | | --- | --- | --- | -| `--organization ` | Yes | Organization identifier. | -| `--preset ` | No | Reporting window. Custom requires startDate and endDate and is capped at 92 days; other presets reject those bounds. Resolved billing windows are capped at 366 days. Accepted values: `current-period`, `previous-period`, `7d`, `30d`, `custom`. | -| `--start-date ` | No | First calendar date included, in the selected timezone. Requires preset=custom. | -| `--end-date ` | No | Last calendar date included, in the selected timezone. Requires preset=custom. | -| `--timezone ` | No | IANA timezone for calendar boundaries; defaults to UTC. | -| `--dimension ` | Yes | Usage grouping dimension. Accepted values: `member`, `workspace`, `workflow`, `model`, `byok`, `source`. | -| `--limit ` | No | Maximum ranked groups to return. Remaining usage is summarized in other. Must be a whole number from 1 to 100. Defaults to 50. | +| `providerId` | Yes | Identity provider identifier. | -## Get organization usage summary - -```bash -sim organizations usage summary [options] -``` - -Get Organization Usage Summary (OAuth login or personal API key required) - **Options** @@ -866,20 +964,30 @@ Get Organization Usage Summary (OAuth login or personal API key required) | Option | Required | Description | | --- | --- | --- | | `--organization ` | Yes | Organization identifier. | -| `--preset ` | No | Reporting window. Custom requires startDate and endDate and is capped at 92 days; other presets reject those bounds. Resolved billing windows are capped at 366 days. Accepted values: `current-period`, `previous-period`, `7d`, `30d`, `custom`. | -| `--start-date ` | No | First calendar date included, in the selected timezone. Requires preset=custom. | -| `--end-date ` | No | Last calendar date included, in the selected timezone. Requires preset=custom. | -| `--timezone ` | No | IANA timezone for calendar boundaries; defaults to UTC. | -## List organization usage events +API request and response schemas: [setPrimarySsoProvider](/api-reference/organizations/setPrimarySsoProvider). + +### Delete SSO provider + +OAuth login or personal API key required. + +This removes the identity provider used for SSO sign-in; linked accounts remain. ```bash -sim organizations usage events [options] +sim organizations sso providers delete [options] ``` -List Organization Usage Events (OAuth login or personal API key required) +**Arguments** + + + +| Argument | Required | Description | +| --- | --- | --- | +| `providerId` | Yes | Identity provider identifier. | + + **Options** @@ -888,47 +996,40 @@ List Organization Usage Events (OAuth login or personal API key required) | Option | Required | Description | | --- | --- | --- | | `--organization ` | Yes | Organization identifier. | -| `--preset ` | No | Reporting window. Custom requires startDate and endDate and is capped at 92 days; other presets reject those bounds. Resolved billing windows are capped at 366 days. Accepted values: `current-period`, `previous-period`, `7d`, `30d`, `custom`. | -| `--start-date ` | No | First calendar date included, in the selected timezone. Requires preset=custom. | -| `--end-date ` | No | Last calendar date included, in the selected timezone. Requires preset=custom. | -| `--timezone ` | No | IANA timezone for calendar boundaries; defaults to UTC. | -| `--source ` | No | Restrict events to one product surface. Accepted values: `workflow`, `wand`, `sim-chat`, `mcp_copilot`, `mothership_block`, `knowledge-base`, `voice-input`, `enrichment`, `voice-output`, `api-tool`. | -| `--limit ` | No | Maximum items to return (0 for everything). Defaults to `100`. | -| `--cursor ` | No | Continue from nextCursor returned by a previous result. | -| `--sort-by ` | No | Field used to sort the result. Accepted values: `createdAt`. | -| `--sort-order ` | No | Sort direction. Accepted values: `asc`, `desc`. | +| `-y, --yes` | Yes | Confirm this operation. | -## List organizations +API request and response schemas: [deleteSsoProvider](/api-reference/organizations/deleteSsoProvider). + +### Get SSO policy + +OAuth login or personal API key required. ```bash -sim organizations list [options] +sim organizations sso policy get [options] ``` -List Organizations (OAuth login or personal API key required) - **Options** | Option | Required | Description | | --- | --- | --- | -| `--search ` | No | Case-insensitive substring match against the organization name. | -| `--sort-by ` | No | Field used to sort the result. Sorting by `name` is case-sensitive and follows the storage collation, so do not rely on a case-insensitive order. Accepted values: `name`, `createdAt`. | -| `--sort-order ` | No | Sort direction. Accepted values: `asc`, `desc`. | -| `--limit ` | No | Maximum items to return (0 for everything). Defaults to `0`. | +| `--organization ` | Yes | Organization identifier. | -## List organization workspaces +API request and response schemas: [getSsoPolicy](/api-reference/organizations/getSsoPolicy). + +### Update SSO policy + +OAuth login or personal API key required. ```bash -sim organizations workspaces [options] +sim organizations sso policy update [options] ``` -List Organization Workspaces (OAuth login or personal API key required) - **Options** @@ -936,9 +1037,13 @@ List Organization Workspaces (OAuth login or personal API key required) | Option | Required | Description | | --- | --- | --- | | `--organization ` | Yes | Organization identifier. | -| `--search ` | No | Case-insensitive substring match against the workspace name. | -| `--sort-by ` | No | Field used to sort the result. Sorting by `name` is case-sensitive and follows the storage collation, so do not rely on a case-insensitive order. Accepted values: `name`, `id`. | -| `--sort-order ` | No | Sort direction. Accepted values: `asc`, `desc`. | -| `--limit ` | No | Maximum items to return (0 for everything). Defaults to `0`. | +| `--require-sso ` | Yes | Require organization SSO on future sign-ins; existing sessions remain active. Accepted values: `true`, `false`. | + +API request and response schemas: [updateSsoPolicy](/api-reference/organizations/updateSsoPolicy). + +## Related docs + +- [Organizations](/platform/organization) +- [Permissions](/platform/permissions) diff --git a/apps/docs/content/docs/cli/output.mdx b/apps/docs/content/docs/cli/output.mdx index 67df6820722..ead4f4f601f 100644 --- a/apps/docs/content/docs/cli/output.mdx +++ b/apps/docs/content/docs/cli/output.mdx @@ -1,18 +1,18 @@ --- title: Output formats -description: table, json, yaml, and text — what each is for, and how to select one +description: Select a format, parse results, and separate output from diagnostics. --- -Commands that return structured API data support four output formats. +Commands that return structured API data support four formats. JSON is the default. -| Format | For | +| Format | Output | | --- | --- | -| `json` | agents, scripts, and piping into `jq` (default) | -| `table` | reading | -| `yaml` | piping into anything that reads YAML | -| `text` | shell loops — tab-separated, no header, no colour | +| `json` | Raw field names and values for scripts, agents, and `jq` | +| `table` | Formatted values for reading in a terminal | +| `yaml` | Raw values for YAML consumers | +| `text` | Formatted, tab-separated values without color or a list header | -Select one per command, save it to the profile, or set it in the environment: +Select a format for one command, save a default, or use an environment variable: ```bash sim tables get tbl_9f3c1a05d4b7426e8c2f0917ab35de64 --output table @@ -20,47 +20,53 @@ sim configure --set-output table SIM_OUTPUT=yaml sim logs list > logs.yaml ``` -`--output` works before or after the command. +`--output` can appear before or after the command. Commands use it when their action supports formatted output; the exceptions are listed below. ## What each format emits -`json` and `yaml` emit the API's raw values, not the table's formatting — a -duration stays `1500`, not `"1.5s"`. +### JSON and YAML -Paginated lists include the rows under `data` and the continuation cursor under -`nextCursor`. A `null` cursor means no pages remain: +Machine formats preserve API values: a duration remains `1500`, rather than the display string `"1.5s"`. Single-resource API responses are unwrapped from their outer `data` envelope. Cursor-paginated results retain rows under `data` and the continuation under `nextCursor`: ```json { "data": [{ "runId": "9c4f0b7e-2d81-4a35-b6e9-70f1c8a2d543" }], "nextCursor": null } ``` -Read list rows with `jq '.data[]'` and check for more pages with `jq '.nextCursor'`. +Read rows with `jq '.data[]'` and check `.nextCursor` for continuation. A null cursor means pagination is finished; inspect any command-specific truncation flags or notices too. See [Pagination](/cli/scripting#pagination) for limits and memory behavior. -`table` formats for reading: timestamps without milliseconds, sizes as `4.2 MB`, -booleans as `yes`/`no`, costs as `$0.0142`. Long cells are clipped to keep rows -on one line; switch to `json` for the full value. +### Tables and text -`text` uses the rendered cells, tab-separated, with no header or colour: +Tables show UTC timestamps without milliseconds, formatted sizes, `yes`/`no` booleans, and formatted monetary amounts. Each command's reference specifies its units. Long table cells are clipped to one line; use JSON or YAML to inspect the returned value in full. + +Text uses the same formatted cells, flattened to one line and separated by tabs. Lists have no header or color; single records use a label and value on each line. Text values are not clipped to the table's column width: ```bash -SIM_OUTPUT=text sim files list | while IFS=$'\t' read -r id name folder size type uploader uploaded; do - echo "$id $name" +sim files list --output text | while IFS=$'\t' read -r id name folder size type uploader uploaded; do + printf '%s %s\n' "$id" "$name" done ``` -An absent value is an em-dash in `table` and an empty field in `text`. +An absent value displays as an em dash in a table and an empty field in text. Use JSON when field types or empty-field positions matter. + +## Separate results and diagnostics + +Results go to stdout. Errors, progress, update notices, and operational notes go to stderr, so this pipe receives only the result: + +```bash +sim logs list --output json | jq '.data[]' +``` + +In JSON/YAML mode, API errors use an `error` object on stderr with `code`, `message`, and optional `details`. Configuration errors, argument-parser errors, and some command outcome messages remain text. See [Exit codes](/cli/scripting#exit-codes) before branching on a command's outcome. ## Reading a run in detail -`sim logs get` prints a concise summary. Add `--trace` for the recursive trace -with span inputs, outputs, errors, timing, and cost: +In table mode, `sim logs get` prints a summary. Add `--trace` to print recursive spans with inputs, outputs, errors, timing, and cost: ```bash -sim logs get 9c4f0b7e-2d81-4a35-b6e9-70f1c8a2d543 --trace +sim logs get 9c4f0b7e-2d81-4a35-b6e9-70f1c8a2d543 --trace --output table ``` -`json` and `yaml` always carry the complete response, so `--trace` is a no-op -there: +JSON and YAML include the returned trace without `--trace`; the flag does not change those formats: ```bash sim logs get 9c4f0b7e-2d81-4a35-b6e9-70f1c8a2d543 --output json | jq '.traceSpans' @@ -68,16 +74,27 @@ sim logs get 9c4f0b7e-2d81-4a35-b6e9-70f1c8a2d543 --output json | jq '.traceSpan ## Exceptions -`sim configure` prints local configuration for humans. `sim profiles` honors `--output`. -`sim files get` writes the file’s raw content to stdout or `--output-file`. +| Command | Output behavior | +| --- | --- | +| `sim configure` | Prints local settings as text | +| `sim profiles` | Honors `--output`; JSON includes an `active` boolean | +| `sim telemetry status`, `enable`, `disable` | Always print text | +| `sim files get` | Streams file content to stdout; `--output-file` saves content and prints a save receipt | +| `sim chat` | Streams reply text in table/text modes and prints the conversation ID to stderr; JSON/YAML wait for the finished result including that ID | +| `sim workflows export` | Emits YAML when selected; otherwise emits JSON, including in table/text mode | -`sim chat` streams reply text in `table` and `text` modes. In `json` or `yaml` -mode it waits for the finished result and includes the conversation ID. +File downloads refuse binary content on an interactive terminal. Pipe stdout or use `--output-file`; overwriting an existing output file requires `--force`. -`sim workflows export` always emits raw JSON, or YAML when the profile says so, -so that it round-trips through `import`: +Workflow import accepts JSON. Pin that format when exporting a file you plan to import, even if your profile prefers YAML: ```bash -sim workflows export 3a9e21d8-5f47-4c0b-b2ea-91d7c6034ef8 > wf.json +sim workflows export 3a9e21d8-5f47-4c0b-b2ea-91d7c6034ef8 --output json > wf.json sim workflows import --workflow @wf.json ``` + +## Related docs + +- [Configuration](/cli/configuration) +- [Scripting](/cli/scripting) +- [Logs commands](/cli/logs) +- [File commands](/cli/files) diff --git a/apps/docs/content/docs/cli/permission-groups.mdx b/apps/docs/content/docs/cli/permission-groups.mdx index eebbfa89431..dd6bafa29b9 100644 --- a/apps/docs/content/docs/cli/permission-groups.mdx +++ b/apps/docs/content/docs/cli/permission-groups.mdx @@ -1,22 +1,28 @@ --- -title: Permission Groups -description: Manage permission groups — every subcommand, argument, and flag +title: Permission groups +description: Manage organization permission groups, their configuration, and member assignments. --- import { CommandTable } from '@/components/ui/command-table' +Manage organization permission groups, their configuration, and member assignments. + +Use the linked API request schema for the supported `--config` keys. Supplied arrays replace their entire lists; omitted settings remain unchanged on update. + `sim permission-groups` is also spelled `sim permission-group`. -Every command below also accepts the [global options](/cli/commands#global-options). +These commands accept the [global options](/cli/commands#global-options). + +## Group configuration + +### List permission groups -## Add permission group member +OAuth login or personal API key required. ```bash -sim permission-groups members add [options] +sim permission-groups list [options] ``` -Add Permission Group Member (OAuth login or personal API key required) - **Options** @@ -24,18 +30,32 @@ Add Permission Group Member (OAuth login or personal API key required) | Option | Required | Description | | --- | --- | --- | | `--organization ` | Yes | Organization identifier. | -| `--group ` | Yes | Permission group identifier. | -| `--user ` | Yes | Existing organization member to add. | +| `--search ` | No | Case-insensitive substring match against the group name. | +| `--sort-by ` | No | Field used to sort the result. Do not rely on case-insensitive ordering when sorting by `name`. Defaults to "createdAt". Accepted values: `name`, `createdAt`, `updatedAt`. | +| `--sort-order ` | No | Sort direction. Defaults to "desc". Accepted values: `asc`, `desc`. | +| `--limit ` | No | Maximum items to return (0 for everything). Defaults to `0`. | -## Bulk add permission group members +API request and response schemas: [listPermissionGroups](/api-reference/permission-groups/listPermissionGroups). + +### Get permission group + +OAuth login or personal API key required. ```bash -sim permission-groups members batch-add [options] +sim permission-groups get [options] ``` -Bulk Add Permission Group Members (OAuth login or personal API key required) +**Arguments** + + + +| Argument | Required | Description | +| --- | --- | --- | +| `groupId` | Yes | Permission group identifier. | + + **Options** @@ -44,20 +64,19 @@ Bulk Add Permission Group Members (OAuth login or personal API key required) | Option | Required | Description | | --- | --- | --- | | `--organization ` | Yes | Organization identifier. | -| `--group ` | Yes | Permission group identifier. | -| `--user ` | No | User IDs to add; cannot be combined with --all-members (space-separated, or @path / @- with one value per line; @@value for a literal leading @). | -| `--all-members` | No | Add every current organization member; cannot be combined with --user. | -## List permission group members +API request and response schemas: [getPermissionGroup](/api-reference/permission-groups/getPermissionGroup). + +### Create permission group + +OAuth login or personal API key required. ```bash -sim permission-groups members list [options] +sim permission-groups create [options] ``` -List Permission Group Members (OAuth login or personal API key required) - **Options** @@ -65,28 +84,32 @@ List Permission Group Members (OAuth login or personal API key required) | Option | Required | Description | | --- | --- | --- | | `--organization ` | Yes | Organization identifier. | -| `--group ` | Yes | Permission group identifier. | -| `--sort-by ` | No | Field used to sort the result. Accepted values: `assignedAt`, `userId`. | -| `--sort-order ` | No | Sort direction. Accepted values: `asc`, `desc`. | -| `--limit ` | No | Maximum items to return (0 for everything). Defaults to `0`. | +| `--name ` | Yes | Group name, unique within the organization. | +| `--description ` | No | Optional group description. | +| `--config ` | No | Group settings to set. Omitted keys use the default permission configuration. (JSON, or @path / @- to read a file or stdin). | +| `--default` | No | Whether the group is the organization default. Only one group can be the default. | +| `--no-default` | No | Send --default as false. | +| `--workspace-ids ` | Conditional | Workspace IDs targeted by a non-default group. Required when creating a non-default group; omit for a default group. (JSON, or @path / @- to read a file or stdin). | -## Remove permission group member +API request and response schemas: [createPermissionGroup](/api-reference/permission-groups/createPermissionGroup). + +### Update permission group + +OAuth login or personal API key required. ```bash -sim permission-groups members remove [options] +sim permission-groups update [options] ``` -Remove Permission Group Member (OAuth login or personal API key required) - **Arguments** | Argument | Required | Description | | --- | --- | --- | -| `userId` | Yes | User identifier of the member to remove. | +| `groupId` | Yes | Permission group identifier. | @@ -97,19 +120,27 @@ Remove Permission Group Member (OAuth login or personal API key required) | Option | Required | Description | | --- | --- | --- | | `--organization ` | Yes | Organization identifier. | -| `--group ` | Yes | Permission group identifier. | -| `-y, --yes` | Yes | Confirm this operation. | +| `--name ` | No | Group name, unique within the organization. | +| `--description ` | No | Group description. Null or an empty string clears it; omission leaves it unchanged. (--description null sends the word, not JSON null). | +| `--config ` | No | Patch of group settings. Omitted keys remain unchanged; each supplied array replaces that entire list. (JSON, or @path / @- to read a file or stdin). | +| `--default` | No | Whether the group is the organization default. Only one group can be the default. | +| `--no-default` | No | Send --default as false. | +| `--workspace-ids ` | No | Workspace identifiers for a non-default group. Required on creation; an empty update makes the group inactive. (JSON, or @path / @- to read a file or stdin). | -## Create permission group +API request and response schemas: [updatePermissionGroup](/api-reference/permission-groups/updatePermissionGroup). + +## Member assignments + +### List permission group members + +OAuth login or personal API key required. ```bash -sim permission-groups create [options] +sim permission-groups members list [options] ``` -Create Permission Group (OAuth login or personal API key required) - **Options** @@ -117,32 +148,22 @@ Create Permission Group (OAuth login or personal API key required) | Option | Required | Description | | --- | --- | --- | | `--organization ` | Yes | Organization identifier. | -| `--name ` | Yes | Group name, unique within the organization. | -| `--description ` | No | Optional group description. | -| `--config ` | No | Group settings to set. Omitted keys use the default permission configuration. (JSON, or @path / @- to read a file or stdin). | -| `--default` | No | Whether the group is the organization default. Only one group can be the default. | -| `--no-default` | No | Send --default as false. | -| `--workspace-ids ` | No | Workspace IDs targeted by a non-default group. Required when creating a non-default group; omit for a default group. (JSON, or @path / @- to read a file or stdin). | +| `--group ` | Yes | Permission group identifier. | +| `--sort-by ` | No | Field used to sort the result. Defaults to "assignedAt". Accepted values: `assignedAt`, `userId`. | +| `--sort-order ` | No | Sort direction. Defaults to "asc". Accepted values: `asc`, `desc`. | +| `--limit ` | No | Maximum items to return (0 for everything). Defaults to `0`. | -## Delete permission group - -```bash -sim permission-groups delete [options] -``` - -Delete Permission Group (OAuth login or personal API key required) +API request and response schemas: [listPermissionGroupMembers](/api-reference/permission-groups/listPermissionGroupMembers). -**Arguments** +### Add permission group member - +OAuth login or personal API key required. -| Argument | Required | Description | -| --- | --- | --- | -| `groupId` | Yes | Permission group identifier. | - - +```bash +sim permission-groups members add [options] +``` **Options** @@ -151,25 +172,30 @@ Delete Permission Group (OAuth login or personal API key required) | Option | Required | Description | | --- | --- | --- | | `--organization ` | Yes | Organization identifier. | -| `-y, --yes` | Yes | Confirm this operation. | +| `--group ` | Yes | Permission group identifier. | +| `--user ` | Yes | Existing organization member to add. | -## Get permission group +API request and response schemas: [addPermissionGroupMember](/api-reference/permission-groups/addPermissionGroupMember). + +### Remove permission group member + +OAuth login or personal API key required. + +This removes the member assignment and changes which permission groups apply to the user. ```bash -sim permission-groups get [options] +sim permission-groups members remove [options] ``` -Get Permission Group (OAuth login or personal API key required) - **Arguments** | Argument | Required | Description | | --- | --- | --- | -| `groupId` | Yes | Permission group identifier. | +| `userId` | Yes | User identifier of the member to remove. | @@ -180,17 +206,21 @@ Get Permission Group (OAuth login or personal API key required) | Option | Required | Description | | --- | --- | --- | | `--organization ` | Yes | Organization identifier. | +| `--group ` | Yes | Permission group identifier. | +| `-y, --yes` | Yes | Confirm this operation. | -## List permission groups +API request and response schemas: [removePermissionGroupMember](/api-reference/permission-groups/removePermissionGroupMember). + +### Bulk add permission group members + +OAuth login or personal API key required. ```bash -sim permission-groups list [options] +sim permission-groups members batch-add [options] ``` -List Permission Groups (OAuth login or personal API key required) - **Options** @@ -198,21 +228,26 @@ List Permission Groups (OAuth login or personal API key required) | Option | Required | Description | | --- | --- | --- | | `--organization ` | Yes | Organization identifier. | -| `--search ` | No | Case-insensitive substring match against the group name. | -| `--sort-by ` | No | Field used to sort the result. Sorting by `name` is case-sensitive and follows the storage collation, so do not rely on a case-insensitive order. Accepted values: `name`, `createdAt`, `updatedAt`. | -| `--sort-order ` | No | Sort direction. Accepted values: `asc`, `desc`. | -| `--limit ` | No | Maximum items to return (0 for everything). Defaults to `0`. | +| `--group ` | Yes | Permission group identifier. | +| `--user ` | No | User IDs to add; cannot be combined with --all-members (space-separated, or @path / @- with one value per line; @@value for a literal leading @). | +| `--all-members` | No | Add every current organization member; cannot be combined with --user. | -## Update permission group +API request and response schemas: [bulkAddPermissionGroupMembers](/api-reference/permission-groups/bulkAddPermissionGroupMembers). + +## Delete groups + +### Delete permission group + +OAuth login or personal API key required. + +This permanently deletes the permission group and its member assignments. ```bash -sim permission-groups update [options] +sim permission-groups delete [options] ``` -Update Permission Group (OAuth login or personal API key required) - **Arguments** @@ -230,11 +265,12 @@ Update Permission Group (OAuth login or personal API key required) | Option | Required | Description | | --- | --- | --- | | `--organization ` | Yes | Organization identifier. | -| `--name ` | No | Group name, unique within the organization. | -| `--description ` | No | Group description. Null or an empty string clears it; omission leaves it unchanged. (--description null sends the word, not JSON null). | -| `--config ` | No | Patch of group settings. Omitted keys remain unchanged; each supplied array replaces that entire list. (JSON, or @path / @- to read a file or stdin). | -| `--default` | No | Whether the group is the organization default. Only one group can be the default. | -| `--no-default` | No | Send --default as false. | -| `--workspace-ids ` | No | Workspace identifiers for a non-default group. Required on creation; an empty update makes the group inactive. (JSON, or @path / @- to read a file or stdin). | +| `-y, --yes` | Yes | Confirm this operation. | + +API request and response schemas: [deletePermissionGroup](/api-reference/permission-groups/deletePermissionGroup). + +## Related docs + +- [Permission groups](/platform/permissions) diff --git a/apps/docs/content/docs/cli/profiles.mdx b/apps/docs/content/docs/cli/profiles.mdx index 5cdb26f604b..be05de4dc08 100644 --- a/apps/docs/content/docs/cli/profiles.mdx +++ b/apps/docs/content/docs/cli/profiles.mdx @@ -1,13 +1,17 @@ --- title: Profiles -description: List profiles or add a workspace profile that shares a stored login — every subcommand, argument, and flag +description: List profiles and add a workspace profile that shares a stored login. --- import { CommandTable } from '@/components/ui/command-table' +List profiles and add a workspace profile that shares a stored login. + +Adding a profile reuses the active stored login and selects a default workspace. Supply `--workspace` when running without an interactive terminal. + `sim profiles` is also spelled `sim profile`. -Every command below also accepts the [global options](/cli/commands#global-options). +These commands accept the [global options](/cli/commands#global-options). ## List configured profiles @@ -40,3 +44,10 @@ sim profiles add [options] | `-w, --workspace ` | No | Existing workspace to use; omit for an interactive picker. | + +API request and response schemas: [getWorkspace](/api-reference/workspaces/getWorkspace), [listWorkspaces](/api-reference/workspaces/listWorkspaces). + +## Related docs + +- [Configuration](/cli/configuration) +- [Authentication](/cli/authentication) diff --git a/apps/docs/content/docs/cli/reference.mdx b/apps/docs/content/docs/cli/reference.mdx index f46c03bb001..27318d9e39e 100644 --- a/apps/docs/content/docs/cli/reference.mdx +++ b/apps/docs/content/docs/cli/reference.mdx @@ -8,14 +8,16 @@ import { CommandTable } from '@/components/ui/command-table' Every command on one page, generated from the CLI itself. Start at the [overview](/cli/commands) to browse; this page is for searching and for tools. -Append `.mdx` to any page for its raw Markdown — +Append `.mdx` to an authored guide or CLI reference page for its raw Markdown — [`/cli/reference.mdx`](/cli/reference.mdx) is this page as plain text. The docs are also published as [`/llms.txt`](/llms.txt) and [`/llms-full.txt`](/llms-full.txt). ## Global options -These apply to every command, and may be written before or after it. +Place these options before or after the command. Each command uses the settings +relevant to its action. Telemetry commands always print text; workflow export +prints a portable JSON document, or YAML when selected. | Option | Description | | --- | --- | @@ -24,6 +26,13 @@ These apply to every command, and may be written before or after it. | `-w, --workspace ` | Workspace to target (env: SIM_WORKSPACE). | | `--output ` | Output format for this command. Accepted values: `table`, `json`, `yaml`, `text`. | +Use `--help` to inspect a command. `sim --version` prints the CLI version, +takes no value, and exits without running a command. Deployment-version commands +use their documented arguments or `--to-version`. + +API schema links describe HTTP payloads. See [CLI output formats](/cli/output) +for resource unwrapping, pagination envelopes, and display formats. + ## sim login Log in through the browser and store the login for the profile @@ -82,6 +91,8 @@ sim whoami [options] +API request and response schemas: [getMeta](/api-reference/meta/getApiMeta), [getWorkspace](/api-reference/workspaces/getWorkspace). + ## sim configure Switch a profile's default workspace, or set its endpoint or output format @@ -149,8 +160,22 @@ sim chat [options] +Each turn prints the reply on stdout and the conversation ID on stderr; pass that ID back with -c to continue the same conversation. With --output json or yaml the reply is not streamed — the finished result is printed as one document, conversation ID included. + +**Examples** + +```bash +sim chat "What workflows do I have?" +sim chat -c "$CONVERSATION_ID" "Which of those run on a schedule?" +sim --output json chat "Summarize yesterday's failed runs" | jq -r '.content' +``` + ## sim profiles +List profiles and add a workspace profile that shares a stored login. + +Adding a profile reuses the active stored login and selects a default workspace. Supply `--workspace` when running without an interactive terminal. + Also spelled `sim profile`. ### sim profiles list @@ -189,19 +214,25 @@ sim profiles add [options] +API request and response schemas: [getWorkspace](/api-reference/workspaces/getWorkspace), [listWorkspaces](/api-reference/workspaces/listWorkspaces). + ## sim telemetry +Inspect and change this machine’s anonymous usage-reporting preference. + ### sim telemetry status -Show whether usage reporting is on, and why not if it is off +Show usage-reporting status ```bash sim telemetry status ``` +Telemetry commands always print text. DO_NOT_TRACK and SIM_TELEMETRY_DISABLED override the saved preference; a build without a reporting destination remains off. See the usage-data guide for the data collected. + ### sim telemetry enable -Turn usage reporting on for this machine +Enable the usage-reporting preference for this machine ```bash sim telemetry enable @@ -217,9 +248,11 @@ sim telemetry disable ## sim cli +Find a command by describing the task you want to perform. + ### sim cli search -Find the command for a task, described in plain words +Find commands for a task ```bash sim cli search @@ -235,13 +268,26 @@ sim cli search +Ranks the commands this CLI ships, locally; your query is never sent anywhere. Returns the 5 best matches. Run ` --help` on one for its flags. + +**Examples** + +```bash +sim cli search "cancel a running workflow" +sim cli search list table rows +``` + ## sim audit-logs +Read organization audit actions and filter by actor, resource, workspace, or time. + +Requires an organization Admin or owner, an OAuth login or personal API key, and enabled enterprise audit access for the deployment. + Also spelled `sim audit-log`. ### sim audit-logs get -Get Audit Log (OAuth login or personal API key required) +Get audit log (OAuth login or personal API key required) ```bash sim audit-logs get [options] @@ -263,13 +309,15 @@ sim audit-logs get [options] | Option | Required | Description | | --- | --- | --- | -| `--organization ` | No | Organization ID; defaults to your only organization, and is required when your account belongs to more than one (OAuth login or personal API key required). | +| `--organization ` | No | Organization whose audit trail to read; defaults to the caller’s organization. A caller that belongs to no organization, or names one it does not belong to, is refused with 403. | +API request and response schemas: [getAuditLog](/api-reference/audit-logs/getAuditLog). + ### sim audit-logs list -List Audit Logs (OAuth login or personal API key required) +List audit logs (OAuth login or personal API key required) ```bash sim audit-logs list [options] @@ -284,23 +332,27 @@ sim audit-logs list [options] | `--action ` | No | Filter by exact action name. | | `--resource-type ` | No | Filter by resource type. Accepts a comma-separated set; members are trimmed and deduplicated, and member order affects neither the result nor the cursor. | | `--resource-id ` | No | Filter by exact resource identifier. | -| `--start-date ` | No | Only include runs started at or after this UTC ISO 8601 timestamp, e.g. `2026-08-06T00:00:00Z`. A date without a time, or a timestamp carrying a UTC offset instead of `Z`, is rejected, as is year `0000`, which names no storable instant. | -| `--end-date ` | No | Only include runs started at or before this UTC ISO 8601 timestamp, e.g. `2026-08-06T00:00:00Z`. A date without a time, or a timestamp carrying a UTC offset instead of `Z`, is rejected, as is year `0000`, which names no storable instant. | +| `--start-date ` | No | Include audit entries created at or after this UTC ISO 8601 timestamp, such as `2026-08-06T00:00:00Z`. Dates without a time, timestamps with an offset instead of `Z`, and year `0000` are rejected. | +| `--end-date ` | No | Include audit entries created at or before this UTC ISO 8601 timestamp, such as `2026-08-06T00:00:00Z`. Dates without a time, timestamps with an offset instead of `Z`, and year `0000` are rejected. | | `--include-departed` | No | Include actions by users who have left the organization. | | `--no-include-departed` | No | Send --include-departed as false. | | `--limit ` | No | Maximum items to return (0 for everything). Defaults to `100`. | | `--cursor ` | No | Continue from nextCursor returned by a previous result. | -| `--organization ` | No | Organization ID; defaults to your only organization, and is required when your account belongs to more than one (OAuth login or personal API key required). | +| `--organization ` | No | Organization whose audit trail to read; defaults to the caller’s organization. A caller that belongs to no organization, or names one it does not belong to, is refused with 403. | | `--actor-email ` | No | Filter by actor email address. | | `--all-workspaces` | No | Do not filter to the configured workspace (OAuth login or personal API key required for account-wide access). | +API request and response schemas: [listAuditLogs](/api-reference/audit-logs/listAuditLogs). + ## sim billing +Read billing status, credit usage, and storage usage. + ### sim billing status -Show billing status, credits spent this period, and storage used (credits and storage require an OAuth login or personal API key) +Show billing status, credits spent, and storage used (credits and storage require an OAuth login or personal API key) ```bash sim billing status [options] @@ -316,6 +368,8 @@ sim billing status [options] +API request and response schemas: [getBillingStatus](/api-reference/billing/getBillingStatus). + ### sim billing logs List credit usage events (an OAuth login or personal API key reports only your events; a workspace API key reports every member's in aggregate, unattributed) @@ -330,8 +384,8 @@ sim billing logs [options] | Option | Required | Description | | --- | --- | --- | -| `--source ` | No | Filter by usage source; sim-chat combines Copilot and workspace chat. Accepted values: `workflow`, `wand`, `sim-chat`, `mcp_copilot`, `mothership_block`, `knowledge-base`, `voice-input`, `enrichment`, `voice-output`, `api-tool`. | -| `--period ` | No | Billing period. Accepted values: `1d`, `7d`, `30d`, `all`, `custom`. | +| `--source ` | No | Filter by usage source; sim-chat combines Sim agent and workspace Chat usage. Accepted values: `workflow`, `wand`, `sim-chat`, `mcp_copilot`, `mothership_block`, `knowledge-base`, `voice-input`, `enrichment`, `voice-output`, `api-tool`. | +| `--period ` | No | Billing period. Defaults to "30d". Accepted values: `1d`, `7d`, `30d`, `all`, `custom`. | | `--start-date ` | No | Custom period start (ISO 8601). | | `--end-date ` | No | Custom period end (ISO 8601). | | `--limit ` | No | Maximum items to return (0 for everything). Defaults to `100`. | @@ -340,11 +394,17 @@ sim billing logs [options] +API request and response schemas: [listBillingLogs](/api-reference/billing/listBillingLogs). + ## sim blocks +Inspect workflow blocks, integration blocks, and triggers available to the workspace. + +The catalog reflects the workspace’s allowed integrations, revealed preview blocks, and deployed custom blocks. + ### sim blocks get -Get Block +Get block ```bash sim blocks get @@ -356,13 +416,15 @@ sim blocks get | Argument | Required | Description | | --- | --- | --- | -| `blockId` | Yes | Block type identifier. An unversioned base type resolves to the newest version, and the response echoes the resolved id. | +| `blockId` | Yes | Block type identifier. An unversioned base type resolves to the newest visible version. The response echoes the resolved ID. | +API request and response schemas: [getBlock](/api-reference/catalog/getBlock). + ### sim blocks list -List Blocks +List blocks ```bash sim blocks list [options] @@ -380,17 +442,21 @@ sim blocks list [options] | `--source ` | No | Restrict to shipped blocks or to this workspace’s deployed custom blocks. Accepted values: `builtin`, `custom`. | | `--include-sunset` | No | Include `legacy` and `deprecated` blocks. Off by default: a sunset block keeps executing where it is already placed, but it is not offered for new authoring. Each returned entry carries `sunset.replacedBy`, the block to build with instead. | | `--no-include-sunset` | No | Send --include-sunset as false. | -| `--sort-by ` | No | Field used to sort the result. Sorting by `name` is case-sensitive and follows the storage collation, so do not rely on a case-insensitive order. Accepted values: `id`, `name`, `category`. | -| `--sort-order ` | No | Sort direction. Accepted values: `asc`, `desc`. | +| `--sort-by ` | No | Field used to sort the result. Do not rely on case-insensitive ordering when sorting by `name`. Defaults to "id". Accepted values: `id`, `name`, `category`. | +| `--sort-order ` | No | Sort direction. Defaults to "asc". Accepted values: `asc`, `desc`. | | `--limit ` | No | Maximum items to return (0 for everything). Defaults to `0`. | +API request and response schemas: [listBlocks](/api-reference/catalog/listBlocks). + ## sim chat-deployments +List workflow chat deployments in the workspace. + ### sim chat-deployments list -List Chat Deployments +List chat deployments ```bash sim chat-deployments list [options] @@ -405,17 +471,23 @@ sim chat-deployments list [options] | `--workflow-id ` | No | Restrict to deployments of one workflow. | | `--is-active` | No | Restrict to active or inactive deployments. | | `--no-is-active` | No | Send --is-active as false. | -| `--sort-by ` | No | Field used to sort the result. Accepted values: `identifier`, `createdAt`, `updatedAt`. | -| `--sort-order ` | No | Sort direction. Accepted values: `asc`, `desc`. | +| `--sort-by ` | No | Field used to sort the result. Defaults to "createdAt". Accepted values: `identifier`, `createdAt`, `updatedAt`. | +| `--sort-order ` | No | Sort direction. Defaults to "desc". Accepted values: `asc`, `desc`. | | `--limit ` | No | Maximum items to return (0 for everything). Defaults to `0`. | +API request and response schemas: [listChatDeployments](/api-reference/workflows/listChatDeployments). + ## sim connector-types +Discover knowledge connectors and their authentication and source-configuration schemas. + +Use `--detail full` to inspect a connector’s configuration before creating it. + ### sim connector-types list -List Connector Types +List connector types ```bash sim connector-types list [options] @@ -434,13 +506,21 @@ sim connector-types list [options] +API request and response schemas: [listConnectorTypes](/api-reference/catalog/listConnectorTypes). + ## sim credentials +Discover providers, connect accounts, and manage credential access. + +Run `sim --output json credentials providers list` to inspect the provider’s fields and authentication requirements before creating a service-account credential. OAuth connection commands return a link that a person must open to authorize the connection. + Also spelled `sim credential`. ### sim credentials delete -Disconnect Credential (OAuth login or personal API key required) +Disconnect credential (OAuth login or personal API key required) + +This disconnects the credential and removes its stored authentication. ```bash sim credentials delete [options] @@ -466,9 +546,11 @@ sim credentials delete [options] +API request and response schemas: [deleteCredential](/api-reference/credentials/deleteCredential). + ### sim credentials members list -List Credential Members (OAuth login or personal API key required) +List credential members (OAuth login or personal API key required) ```bash sim credentials members list [options] @@ -491,14 +573,18 @@ sim credentials members list [options] | Option | Required | Description | | --- | --- | --- | | `--limit ` | No | Maximum items to return (0 for everything). Defaults to `0`. | -| `--sort-by ` | No | Field used to sort the result. Sorting by `name` is case-sensitive and follows the storage collation, so do not rely on a case-insensitive order. Accepted values: `email`, `name`. | -| `--sort-order ` | No | Sort direction. Accepted values: `asc`, `desc`. | +| `--sort-by ` | No | Field used to sort the result. Do not rely on case-insensitive ordering when sorting by `name`. Defaults to "email". Accepted values: `email`, `name`. | +| `--sort-order ` | No | Sort direction. Defaults to "asc". Accepted values: `asc`, `desc`. | +API request and response schemas: [listCredentialMembers](/api-reference/credentials/listCredentialMembers). + ### sim credentials members remove -Remove Credential Member (OAuth login or personal API key required) +Remove credential member (OAuth login or personal API key required) + +This revokes the selected user’s explicit credential grant. ```bash sim credentials members remove [options] @@ -525,9 +611,11 @@ sim credentials members remove [options] +API request and response schemas: [removeCredentialMember](/api-reference/credentials/removeCredentialMember). + ### sim credentials members upsert -Upsert Credential Member (OAuth login or personal API key required) +Upsert credential member (OAuth login or personal API key required) ```bash sim credentials members upsert [options] @@ -554,9 +642,11 @@ sim credentials members upsert [options] +API request and response schemas: [upsertCredentialMember](/api-reference/credentials/upsertCredentialMember). + ### sim credentials providers list -List Credential Providers +List credential providers ```bash sim credentials providers list [options] @@ -572,9 +662,11 @@ sim credentials providers list [options] +API request and response schemas: [listCredentialProviders](/api-reference/credentials/listCredentialProviders). + ### sim credentials list -List Credentials +List credentials ```bash sim credentials list [options] @@ -589,15 +681,17 @@ sim credentials list [options] | `--type ` | No | Restrict results to this credential type. Accepted values: `oauth`, `service_account`. | | `--provider-id ` | No | Restrict results to credentials for this integration provider. | | `--search ` | No | Case-insensitive substring match against the credential display name. | -| `--sort-by ` | No | Field used to sort the result. Accepted values: `displayName`, `createdAt`, `updatedAt`. | -| `--sort-order ` | No | Sort direction. Accepted values: `asc`, `desc`. | +| `--sort-by ` | No | Field used to sort the result. Defaults to "createdAt". Accepted values: `displayName`, `createdAt`, `updatedAt`. | +| `--sort-order ` | No | Sort direction. Defaults to "desc". Accepted values: `asc`, `desc`. | | `--limit ` | No | Maximum items to return (0 for everything). Defaults to `0`. | +API request and response schemas: [listCredentials](/api-reference/credentials/listCredentials). + ### sim credentials update -Update Credential (OAuth login or personal API key required) +Update credential (OAuth login or personal API key required) ```bash sim credentials update [options] @@ -645,6 +739,8 @@ sim credentials update [options] +API request and response schemas: [updateCredential](/api-reference/credentials/updateCredential). + ### sim credentials create Create a service-account credential using its discovered provider schema (OAuth login or personal API key required) @@ -676,6 +772,8 @@ sim credentials create [options] +API request and response schemas: [createServiceAccountCredential](/api-reference/credentials/createServiceAccountCredential). + ### sim credentials connect Create a short-lived link for connecting an OAuth provider (OAuth login or personal API key required) @@ -704,6 +802,8 @@ sim credentials connect [options] +API request and response schemas: [createCredentialConnection](/api-reference/credentials/createCredentialConnection). + ### sim credentials reconnect Create a short-lived link for reconnecting an OAuth credential (OAuth login or personal API key required) @@ -722,13 +822,17 @@ sim credentials reconnect +API request and response schemas: [createCredentialConnection](/api-reference/credentials/createCredentialConnection). + ## sim custom-tools +Create and manage code-backed tools that agents can call. + Also spelled `sim custom-tool`. ### sim custom-tools create -Create Custom Tool +Create custom tool ```bash sim custom-tools create [options] @@ -746,9 +850,13 @@ sim custom-tools create [options] +API request and response schemas: [createCustomTool](/api-reference/custom-tools/createCustomTool). + ### sim custom-tools delete -Delete Custom Tool +Delete custom tool + +This deletes the custom tool. ```bash sim custom-tools delete [options] @@ -774,9 +882,11 @@ sim custom-tools delete [options] +API request and response schemas: [deleteCustomTool](/api-reference/custom-tools/deleteCustomTool). + ### sim custom-tools get -Get Custom Tool +Get custom tool ```bash sim custom-tools get @@ -792,9 +902,11 @@ sim custom-tools get +API request and response schemas: [getCustomTool](/api-reference/custom-tools/getCustomTool). + ### sim custom-tools list -List Custom Tools +List custom tools ```bash sim custom-tools list [options] @@ -807,15 +919,17 @@ sim custom-tools list [options] | Option | Required | Description | | --- | --- | --- | | `--search ` | No | Case-insensitive substring match against the tool title. | -| `--sort-by ` | No | Field used to sort the result. Accepted values: `title`, `createdAt`, `updatedAt`. | -| `--sort-order ` | No | Sort direction. Accepted values: `asc`, `desc`. | +| `--sort-by ` | No | Field used to sort the result. Defaults to "createdAt". Accepted values: `title`, `createdAt`, `updatedAt`. | +| `--sort-order ` | No | Sort direction. Defaults to "desc". Accepted values: `asc`, `desc`. | | `--limit ` | No | Maximum items to return (0 for everything). Defaults to `0`. | +API request and response schemas: [listCustomTools](/api-reference/custom-tools/listCustomTools). + ### sim custom-tools update -Update Custom Tool +Update custom tool ```bash sim custom-tools update [options] @@ -843,14 +957,20 @@ sim custom-tools update [options] +API request and response schemas: [updateCustomTool](/api-reference/custom-tools/updateCustomTool). + ## sim files +Browse workspace files, read or write content, manage versions, and configure sharing. + Also spelled `sim file`. ### sim files batch-delete Delete several files at once +This archives the listed files; restore them with `files restore`. + ```bash sim files batch-delete [options] ``` @@ -866,9 +986,11 @@ sim files batch-delete [options] +API request and response schemas: [bulkDeleteFiles](/api-reference/files/bulkDeleteFiles). + ### sim files create -Create File +Create file ```bash sim files create [options] @@ -883,11 +1005,13 @@ sim files create [options] | `--name ` | Yes | File name, including its extension. Path separators and dot segments are rejected. | | `--content-type ` | No | MIME type. When omitted, it is inferred from the file extension. | | `--folder ` | No | Folder path as shown in the app; the leading / is optional. | -| `--content ` | No | Initial file content. Omit or send an empty string for a zero-byte file. The 70,000,000-character bound guards the JSON envelope; the decoded bytes must be at most 50 MiB, and a longer base64 payload is rejected with `413`. Use an upload session for anything larger. | -| `--encoding ` | No | Encoding of the content field. Accepted values: `utf-8`, `base64`. | +| `--content ` | No | Initial file content. Omit or send an empty string for a zero-byte file. The complete JSON request is capped at 10 MiB, including encoding and the envelope; the separate decoded-file limit is 50 MiB. For larger payloads, use `sim files upload `. Defaults to "". | +| `--encoding ` | No | Encoding of the content field. Defaults to "utf-8". Accepted values: `utf-8`, `base64`. | +API request and response schemas: [createFile](/api-reference/files/createFile). + ### sim files folders create Create a file folder at a path @@ -906,9 +1030,13 @@ sim files folders create +API request and response schemas: [createFileFolder](/api-reference/files/createFilesFolder). + ### sim files folders delete -Delete Folder +Delete folder + +This archives the file folder and, when recursive, everything inside it. ```bash sim files folders delete [options] @@ -930,11 +1058,13 @@ sim files folders delete [options] | Option | Required | Description | | --- | --- | --- | -| `--recursive` | No | Delete the folder and its descendants. | +| `--recursive` | No | Archive the folder and its descendants. Defaults to "false". | | `-y, --yes` | Yes | Confirm this operation. | +API request and response schemas: [deleteFileFolder](/api-reference/files/deleteFilesFolder). + ### sim files folders list List folders @@ -953,14 +1083,16 @@ Also available as `sim files folders ls`. | --- | --- | --- | | `--parent ` | No | Direct parent folder path. | | `--search ` | No | Case-insensitive substring match against the folder name. | -| `--sort-by ` | No | Field used to sort the result. Sorting by `name` is case-sensitive and follows the storage collation, so do not rely on a case-insensitive order. Accepted values: `name`, `createdAt`, `updatedAt`. | -| `--sort-order ` | No | Sort direction. Accepted values: `asc`, `desc`. | +| `--sort-by ` | No | Field used to sort the result. Do not rely on case-insensitive ordering when sorting by `name`. Defaults to "name". Accepted values: `name`, `createdAt`, `updatedAt`. | +| `--sort-order ` | No | Sort direction. Defaults to "asc". Accepted values: `asc`, `desc`. | | `--scope ` | No | Which lifecycle set to list: `active` (default) returns live folders only; `archived` returns folders a recursive delete soft-deleted, which is how a caller finds a path to hand to the folder restore. Authorization is identical for both. Accepted values: `active`, `archived`. | | `--recursive ` | No | Whether parentPath includes every descendant instead of direct children only. Accepted values: `true`, `1`, `yes`, `on`, `y`, `enabled`, `false`, `0`, `no`, `off`, `n`, `disabled`. | | `--depth ` | No | Deepest level below parentPath to include when recursive is true. | +API request and response schemas: [listFileFolders](/api-reference/files/listFilesFolders). + ### sim files folders move Rename or move a file folder @@ -982,6 +1114,8 @@ Also available as `sim files folders mv`. +API request and response schemas: [relocateFileFolder](/api-reference/files/relocateFilesFolder). + ### sim files folders restore Restore an archived file folder @@ -1000,9 +1134,13 @@ sim files folders restore +API request and response schemas: [restoreFileFolder](/api-reference/files/restoreFilesFolder). + ### sim files delete -Delete File +Delete file + +This archives the file. ```bash sim files delete [options] @@ -1028,10 +1166,14 @@ sim files delete [options] +API request and response schemas: [deleteFile](/api-reference/files/deleteFile). + ### sim files versions delete Permanently delete a previous version of a file +This permanently removes the version from history and schedules deletion of its stored content; storage cleanup may retry in the background. + ```bash sim files versions delete [options] ``` @@ -1057,6 +1199,8 @@ sim files versions delete [options] +API request and response schemas: [deleteFileVersion](/api-reference/files/deleteFileVersion). + ### sim files versions describe Show the metadata of one version of a file @@ -1076,6 +1220,8 @@ sim files versions describe +API request and response schemas: [getFileVersion](/api-reference/files/getFileVersion). + ### sim files versions list List the recorded versions of a file @@ -1100,13 +1246,15 @@ sim files versions list [options] | Option | Required | Description | | --- | --- | --- | -| `--sort-by ` | No | Field used to sort the result. Accepted values: `version`. | -| `--sort-order ` | No | Sort direction. Accepted values: `asc`, `desc`. | +| `--sort-by ` | No | Field used to sort the result. Defaults to "version". Accepted values: `version`. | +| `--sort-order ` | No | Sort direction. Defaults to "desc". Accepted values: `asc`, `desc`. | | `--limit ` | No | Maximum items to return (0 for everything). Defaults to `100`. | | `--cursor ` | No | Continue from nextCursor returned by a previous result. | +API request and response schemas: [listFileVersions](/api-reference/files/listFileVersions). + ### sim files versions read Read the text content of one version of a file as JSON or YAML @@ -1138,6 +1286,8 @@ sim files versions read [options] +API request and response schemas: [readFileVersionText](/api-reference/files/readFileVersionText). + ### sim files versions revert Make a previous version of a file current again @@ -1164,10 +1314,12 @@ sim files versions revert [options] | Option | Required | Description | | --- | --- | --- | | `--expected-current-version ` | No | Revert only while this is still the current version; otherwise the request fails with `409`. Omit to revert whatever is current. Collaborative edits and repeated workflow writes that fold into the current version keep its number, so prefer `expectedRevision` to guard content. | -| `--expected-revision ` | No | Revert only while the file still holds the content this revision names, as returned by Get File Metadata or an earlier write; otherwise the request fails with `409`. Unlike a version number, it also catches edits that folded into the current version. | +| `--expected-revision ` | No | Revert only while the file still holds the content this revision names, as returned by Get file metadata or an earlier write; otherwise the request fails with `409`. Unlike a version number, it also catches edits that folded into the current version. | +API request and response schemas: [revertFileVersion](/api-reference/files/revertFileVersion). + ### sim files versions download Download the content of one version of a file @@ -1198,6 +1350,8 @@ sim files versions download [options] +API request and response schemas: [downloadFileVersion](/api-reference/files/downloadFileVersion). + ### sim files edit Apply one exact or anchor-based edit to a text file @@ -1223,10 +1377,12 @@ sim files edit [options] | Option | Required | Description | | --- | --- | --- | | `--edit ` | Yes | One edit object: {"mode":"search_replace","search":"old","content":"new","replaceAll":false}, {"mode":"replace_between","beforeAnchor":"start line","afterAnchor":"end line","content":"new"}, {"mode":"insert_after","anchor":"line","content":"new"}, or {"mode":"delete_between","startAnchor":"first line deleted","endAnchor":"ending line kept"}. Anchored modes also accept occurrence starting at 1 (JSON, or @path / @- to read a file or stdin). | -| `--expected-revision ` | No | Revision from Get File Metadata or an earlier write; the request is refused with `409` when the content moved on. | +| `--expected-revision ` | No | Revision from Get file metadata or an earlier write; the request is refused with `409` when the content moved on. | +API request and response schemas: [editFileContent](/api-reference/files/editFileContent). + ### sim files describe Show file metadata and sharing status @@ -1255,6 +1411,8 @@ sim files describe [options] +API request and response schemas: [getFile](/api-reference/files/getFile). + ### sim files share get Show a file’s share settings @@ -1273,6 +1431,8 @@ sim files share get +API request and response schemas: [getFileShare](/api-reference/files/getFileShare). + ### sim files share set Enable or disable sharing for a file (OAuth login or personal API key required) @@ -1299,14 +1459,16 @@ sim files share set [options] | --- | --- | --- | | `--is-active ` | Yes | Whether the share should resolve. Disabling preserves the token and the whole access configuration, so re-enabling restores the share as it was; enabling rewrites the credentials the resulting mode does not use. Accepted values: `true`, `false`. | | `--auth-type ` | No | How access to the share is gated. The stored mode is kept when omitted. Enabling `public` clears the stored password and empties `allowedEmails`; `password` empties `allowedEmails`; `email` and `sso` clear the stored password. Accepted values: `public`, `password`, `email`, `sso`. | -| `--password ` | No | Password of 15 to 1024 characters for a password-gated share. Kept when omitted; enabling `password` with neither a supplied nor a stored password is a 400. Taken literally, except that a request from the Sim agent resolves a whole-value `{{ENV_VAR}}` reference to that variable before the rules apply. | +| `--password ` | No | Password of 15 to 1024 characters for a password-gated share. Kept when omitted; enabling `password` with neither a supplied nor a stored password is a 400. Taken literally, except that a request from the Sim agent resolves a whole-value `{{ENV_VAR}}` reference to that variable before the rules apply. | | `--allowed-emails ` | No | Allowed addresses or `@domain` patterns for email and SSO shares. Kept when omitted; enabling `email` or `sso` with an empty resulting list is a 400. (space-separated, or @path / @- with one value per line; @@value for a literal leading @). | +API request and response schemas: [upsertFileShare](/api-reference/files/upsertFileShare). + ### sim files list -List Files +List files ```bash sim files list [options] @@ -1323,12 +1485,14 @@ sim files list [options] | `--no-recursive` | No | Send --recursive as false. | | `--scope ` | No | Which lifecycle set to list: `active` (default) for live files, `archived` for files a delete soft-deleted. `folderPath` resolves against active folders only, so pairing it with `scope=archived` returns an empty page when the containing folder was archived too. Accepted values: `active`, `archived`. | | `--search ` | No | Case-insensitive substring match against the file name. | -| `--sort-by ` | No | Field used to sort the result. Sorting by `name` is case-sensitive and follows the storage collation, so do not rely on a case-insensitive order. Accepted values: `name`, `size`, `uploadedAt`, `updatedAt`. | -| `--sort-order ` | No | Sort direction. Accepted values: `asc`, `desc`. | +| `--sort-by ` | No | Field used to sort the result. Do not rely on case-insensitive ordering when sorting by `name`. Defaults to "uploadedAt". Accepted values: `name`, `size`, `uploadedAt`, `updatedAt`. | +| `--sort-order ` | No | Sort direction. Defaults to "asc". Accepted values: `asc`, `desc`. | | `--limit ` | No | Maximum items to return (0 for everything). Defaults to `0`. | +API request and response schemas: [listFiles](/api-reference/files/listFiles). + ### sim files move Move files into another folder @@ -1350,6 +1514,8 @@ Also available as `sim files mv`. +API request and response schemas: [moveFileItems](/api-reference/files/moveFileItems). + ### sim files read Read a file’s text content as JSON or YAML @@ -1364,7 +1530,7 @@ sim files read [options] | Argument | Required | Description | | --- | --- | --- | -| `fileId` | Yes | File identifier, or the file’s VFS path: `files/<folder>/<name>`, or `uploads/<name>` for a Chat upload. | +| `fileId` | Yes | File identifier, or the file’s VFS path: `files//`, or `uploads/` for a Chat upload. | @@ -1380,6 +1546,8 @@ sim files read [options] +API request and response schemas: [readFileText](/api-reference/files/readFileText). + ### sim files rename Rename a file @@ -1408,6 +1576,8 @@ sim files rename [options] +API request and response schemas: [renameFile](/api-reference/files/renameFile). + ### sim files restore Restore an archived file @@ -1426,9 +1596,11 @@ sim files restore +API request and response schemas: [restoreFile](/api-reference/files/restoreFile). + ### sim files search -Search File Content +Search file content ```bash sim files search [options] @@ -1441,18 +1613,22 @@ sim files search [options] | Option | Required | Description | | --- | --- | --- | | `--query ` | Yes | Regular expression, or exact text when `mode` is `exact`. | -| `--mode ` | No | How `query` is read. Accepted values: `exact`, `regex`. | -| `--max-results ` | No | Maximum matching lines to return. | +| `--mode ` | No | How `query` is read. Defaults to "regex". Accepted values: `exact`, `regex`. | +| `--max-results ` | No | Maximum matching lines to return. Defaults to 50. | | `--folder ` | No | Folders to search, by path as shown in the app; omit to search the whole workspace (space-separated, or @path / @- with one value per line; @@value for a literal leading @). | | `--include-subfolders` | No | Whether each folder scope includes nested folders; on by default. | | `--no-include-subfolders` | No | Send --include-subfolders as false. | +API request and response schemas: [searchFileContent](/api-reference/files/searchFileContent). + ### sim files unzip Unzip an archive into a new folder beside it +This writes every file in the archive into the workspace. + ```bash sim files unzip [options] ``` @@ -1477,6 +1653,8 @@ sim files unzip [options] +API request and response schemas: [unzipFile](/api-reference/files/unzipFile). + ### sim files set-content Replace a file’s contents @@ -1501,12 +1679,14 @@ sim files set-content [options] | Option | Required | Description | | --- | --- | --- | -| `--content ` | Yes | Complete replacement content for the file. The 70,000,000-character bound guards the JSON envelope; the decoded bytes must be at most 50 MiB, and a longer base64 payload is rejected with `413`. | -| `--encoding ` | No | Content encoding. Accepted values: `utf-8`, `base64`. | -| `--expected-revision ` | No | Revision from Get File Metadata or an earlier write; the request is refused with `409` when the content moved on. | +| `--content ` | Yes | Complete replacement content for the file. The complete JSON request is capped at 10 MiB, including UTF-8 encoding, escaping, base64, and the envelope. The separate decoded-file limit is 50 MiB. Small patches can edit a larger stored text file without sending its full content. | +| `--encoding ` | No | Content encoding. Defaults to "utf-8". Accepted values: `utf-8`, `base64`. | +| `--expected-revision ` | No | Revision from Get file metadata or an earlier write; the request is refused with `409` when the content moved on. | +API request and response schemas: [updateFileContent](/api-reference/files/updateFileContent). + ### sim files upload Upload a file to the workspace @@ -1536,6 +1716,8 @@ sim files upload [options] +API request and response schemas: [createFileUpload](/api-reference/files/createFileUpload), [createFileUploadPartUrls](/api-reference/files/createFileUploadPartUrls), [completeFileUpload](/api-reference/files/completeFileUpload), [abortFileUpload](/api-reference/files/abortFileUpload). + ### sim files get Download a file’s content to stdout or a local file @@ -1565,6 +1747,8 @@ sim files get [options] +API request and response schemas: [downloadFile](/api-reference/files/downloadFile). + ### sim files ls List file resources and child folders together @@ -1594,6 +1778,8 @@ sim files ls [path] [options] +API request and response schemas: [listFiles](/api-reference/files/listFiles), [listFileFolders](/api-reference/files/listFilesFolders). + ### sim files mkdir Create a file directory at a path @@ -1612,8 +1798,12 @@ sim files mkdir +API request and response schemas: [createFileFolder](/api-reference/files/createFilesFolder). + ## sim knowledge +Manage knowledge bases, indexed documents, search, tags, and connector syncs. + Also spelled `sim kb`. ### sim knowledge from-workspace-files create @@ -1640,10 +1830,12 @@ sim knowledge from-workspace-files create [options] | Option | Required | Description | | --- | --- | --- | -| `--file ` | Yes | Workspace file ID or key (repeatable) (space-separated, or @path / @- with one value per line; @@value for a literal leading @). | +| `--file ` | Yes | Workspace file ID or canonical files/<folder>/<name> path (repeatable) (space-separated, or @path / @- with one value per line; @@value for a literal leading @). | +API request and response schemas: [addWorkspaceFilesToKnowledgeBase](/api-reference/knowledge-bases/addWorkspaceFilesToKnowledgeBase). + ### sim knowledge tags save Declare the tag definitions a knowledge base needs (OAuth login or personal API key required) @@ -1672,9 +1864,11 @@ sim knowledge tags save [options] +API request and response schemas: [bulkSaveKnowledgeTagDefinitions](/api-reference/knowledge-bases/bulkSaveKnowledgeTagDefinitions). + ### sim knowledge tags create -Create Tag (OAuth login or personal API key required) +Create tag (OAuth login or personal API key required) ```bash sim knowledge tags create [options] @@ -1702,9 +1896,13 @@ sim knowledge tags create [options] +API request and response schemas: [createKnowledgeTag](/api-reference/knowledge-bases/createKnowledgeTag). + ### sim knowledge tags delete -Delete Tag (OAuth login or personal API key required) +Delete tag (OAuth login or personal API key required) + +This deletes the tag and clears its values on every document and chunk. ```bash sim knowledge tags delete [options] @@ -1731,10 +1929,14 @@ sim knowledge tags delete [options] +API request and response schemas: [deleteKnowledgeTag](/api-reference/knowledge-bases/deleteKnowledgeTag). + ### sim knowledge tags cleanup Remove tag definitions no document still uses (OAuth login or personal API key required) +This deletes every tag definition no document still uses. Their slots become free for a different field. + ```bash sim knowledge tags cleanup [options] ``` @@ -1761,6 +1963,8 @@ sim knowledge tags cleanup [options] +API request and response schemas: [deleteKnowledgeTagDefinitions](/api-reference/knowledge-bases/deleteKnowledgeTagDefinitions). + ### sim knowledge tags next-slot Show which tag slot a create would take for a field type (OAuth login or personal API key required) @@ -1789,9 +1993,11 @@ sim knowledge tags next-slot [options] +API request and response schemas: [getNextKnowledgeTagSlot](/api-reference/knowledge-bases/getNextKnowledgeTagSlot). + ### sim knowledge tags list -List Tags +List tags ```bash sim knowledge tags list @@ -1807,6 +2013,8 @@ sim knowledge tags list +API request and response schemas: [listKnowledgeTags](/api-reference/knowledge-bases/listKnowledgeTags). + ### sim knowledge tags usage Show how many documents and chunks carry each tag (OAuth login or personal API key required) @@ -1825,9 +2033,11 @@ sim knowledge tags usage +API request and response schemas: [listKnowledgeTagUsage](/api-reference/knowledge-bases/listKnowledgeTagUsage). + ### sim knowledge tags update -Update Tag (OAuth login or personal API key required) +Update tag (OAuth login or personal API key required) ```bash sim knowledge tags update [options] @@ -1855,10 +2065,14 @@ sim knowledge tags update [options] +API request and response schemas: [updateKnowledgeTag](/api-reference/knowledge-bases/updateKnowledgeTag). + ### sim knowledge chunks batch-update Enable, disable, or delete many chunks at once (OAuth login or personal API key required) +This applies --operation to every named chunk; with --operation delete it deletes them and their embeddings, which cannot be undone. + ```bash sim knowledge chunks batch-update [options] ``` @@ -1886,9 +2100,11 @@ sim knowledge chunks batch-update [options] +API request and response schemas: [bulkUpdateKnowledgeChunks](/api-reference/knowledge-bases/bulkUpdateKnowledgeChunks). + ### sim knowledge chunks create -Create Chunk (OAuth login or personal API key required) +Create chunk (OAuth login or personal API key required) ```bash sim knowledge chunks create [options] @@ -1911,15 +2127,19 @@ sim knowledge chunks create [options] | Option | Required | Description | | --- | --- | --- | -| `--content ` | Yes | Text to embed. It is embedded on write, so the chunk is searchable immediately. | -| `--enabled` | No | Whether the new chunk participates in search. | +| `--content ` | Yes | Text embedded before the response. Search includes it when the chunk and document are enabled and the document has completed processing. | +| `--enabled` | No | Whether the new chunk participates in search. Defaults to true. | | `--no-enabled` | No | Send --enabled as false. | +API request and response schemas: [createKnowledgeChunk](/api-reference/knowledge-bases/createKnowledgeChunk). + ### sim knowledge chunks delete -Delete Chunk (OAuth login or personal API key required) +Delete chunk (OAuth login or personal API key required) + +This deletes the chunk and its embedding. ```bash sim knowledge chunks delete [options] @@ -1947,9 +2167,11 @@ sim knowledge chunks delete [options] +API request and response schemas: [deleteKnowledgeChunk](/api-reference/knowledge-bases/deleteKnowledgeChunk). + ### sim knowledge chunks get -Get Chunk (OAuth login or personal API key required) +Get chunk (OAuth login or personal API key required) ```bash sim knowledge chunks get @@ -1967,9 +2189,11 @@ sim knowledge chunks get +API request and response schemas: [getKnowledgeChunk](/api-reference/knowledge-bases/getKnowledgeChunk). + ### sim knowledge chunks list -List Chunks (OAuth login or personal API key required) +List chunks (OAuth login or personal API key required) ```bash sim knowledge chunks list [options] @@ -1993,17 +2217,19 @@ sim knowledge chunks list [options] | Option | Required | Description | | --- | --- | --- | | `--search ` | No | Case-insensitive substring match against chunk content. | -| `--enabled ` | No | Restrict to enabled or disabled chunks. `all` returns both. Accepted values: `true`, `false`, `all`. | -| `--sort-by ` | No | Field used to sort the result. Accepted values: `chunkIndex`, `tokenCount`, `enabled`. | -| `--sort-order ` | No | Sort direction. Accepted values: `asc`, `desc`. | +| `--enabled ` | No | Restrict to enabled or disabled chunks. `all` returns both. Defaults to "all". Accepted values: `true`, `false`, `all`. | +| `--sort-by ` | No | Field used to sort the result. Defaults to "chunkIndex". Accepted values: `chunkIndex`, `tokenCount`, `enabled`. | +| `--sort-order ` | No | Sort direction. Defaults to "asc". Accepted values: `asc`, `desc`. | | `--limit ` | No | Maximum items to return (0 for everything). Defaults to `100`. | | `--cursor ` | No | Continue from nextCursor returned by a previous result. | +API request and response schemas: [listKnowledgeChunks](/api-reference/knowledge-bases/listKnowledgeChunks). + ### sim knowledge chunks update -Update Chunk (OAuth login or personal API key required) +Update chunk (OAuth login or personal API key required) ```bash sim knowledge chunks update [options] @@ -2033,6 +2259,8 @@ sim knowledge chunks update [options] +API request and response schemas: [updateKnowledgeChunk](/api-reference/knowledge-bases/updateKnowledgeChunk). + ### sim knowledge documents batch-update Enable or disable every matching document (OAuth login or personal API key required) @@ -2064,10 +2292,14 @@ sim knowledge documents batch-update [options] +API request and response schemas: [bulkUpdateKnowledgeDocuments](/api-reference/knowledge-bases/bulkUpdateKnowledgeDocuments). + ### sim knowledge documents delete Delete a document from a knowledge base +This deletes the document and its embeddings. + ```bash sim knowledge documents delete [options] ``` @@ -2093,9 +2325,11 @@ sim knowledge documents delete [options] +API request and response schemas: [deleteKnowledgeDocument](/api-reference/knowledge-bases/deleteKnowledgeDocument). + ### sim knowledge documents get -Get Document +Get document ```bash sim knowledge documents get @@ -2112,9 +2346,11 @@ sim knowledge documents get +API request and response schemas: [getKnowledgeDocument](/api-reference/knowledge-bases/getKnowledgeDocument). + ### sim knowledge documents list -List Documents +List documents ```bash sim knowledge documents list [options] @@ -2138,17 +2374,19 @@ sim knowledge documents list [options] | --- | --- | --- | | `--limit ` | No | Maximum items to return (0 for everything). Defaults to `100`. | | `--search ` | No | Case-insensitive substring match against the document filename. | -| `--enabled-filter ` | No | Filter by whether documents are enabled for search. Accepted values: `all`, `enabled`, `disabled`. | -| `--sort-by ` | No | Field used to sort the result. Sorting by `filename` is case-sensitive and follows the storage collation, so do not rely on a case-insensitive order. Accepted values: `filename`, `fileSize`, `tokenCount`, `chunkCount`, `uploadedAt`, `processingStatus`, `enabled`. | -| `--sort-order ` | No | Sort direction. Accepted values: `asc`, `desc`. | +| `--enabled-filter ` | No | Filter by whether documents are enabled for search. Defaults to "all". Accepted values: `all`, `enabled`, `disabled`. | +| `--sort-by ` | No | Field used to sort the result. Do not rely on case-insensitive ordering when sorting by `filename`. Defaults to "uploadedAt". Accepted values: `filename`, `fileSize`, `tokenCount`, `chunkCount`, `uploadedAt`, `processingStatus`, `enabled`. | +| `--sort-order ` | No | Sort direction. Defaults to "desc". Accepted values: `asc`, `desc`. | | `--cursor ` | No | Continue from nextCursor returned by a previous result. | -| `--tag-filters ` | No | A JSON-encoded array of at most 10 tag filters, using the same display-name shape as knowledge search: `[{"tagName":"category","operator":"eq","value":"billing"}]`. Every filter must hold, including two that name the same tag. A name that is not defined in this knowledge base is rejected, never ignored. | +| `--tag-filters ` | No | A JSON-encoded array of at most 10 tag filters, using the same display-name shape as knowledge search: `[{"tagName":"category","operator":"eq","value":"billing"}]`. Every filter must hold, including two that name the same tag. A name that is not defined in this knowledge base is rejected, never ignored. | +API request and response schemas: [listKnowledgeDocuments](/api-reference/knowledge-bases/listKnowledgeDocuments). + ### sim knowledge documents update -Update Document (OAuth login or personal API key required) +Update document (OAuth login or personal API key required) ```bash sim knowledge documents update [options] @@ -2198,6 +2436,8 @@ sim knowledge documents update [options] +API request and response schemas: [updateKnowledgeDocument](/api-reference/knowledge-bases/updateKnowledgeDocument). + ### sim knowledge documents upload Upload a document to a knowledge base @@ -2230,9 +2470,11 @@ sim knowledge documents upload [options] +API request and response schemas: [createKnowledgeDocumentUpload](/api-reference/knowledge-bases/createKnowledgeDocumentUpload), [createKnowledgeDocumentUploadPartUrls](/api-reference/knowledge-bases/createKnowledgeDocumentUploadPartUrls), [completeKnowledgeDocumentUpload](/api-reference/knowledge-bases/completeKnowledgeDocumentUpload), [abortKnowledgeDocumentUpload](/api-reference/knowledge-bases/abortKnowledgeDocumentUpload). + ### sim knowledge create -Create Knowledge Base +Create knowledge base ```bash sim knowledge create [options] @@ -2251,9 +2493,11 @@ sim knowledge create [options] +API request and response schemas: [createKnowledgeBase](/api-reference/knowledge-bases/createKnowledgeBase). + ### sim knowledge connectors create -Create Knowledge Connector (OAuth login or personal API key required) +Create knowledge connector (OAuth login or personal API key required) ```bash sim knowledge connectors create [options] @@ -2277,15 +2521,19 @@ sim knowledge connectors create [options] | --- | --- | --- | | `--connector-type ` | Yes | Registered connector type. | | `--credential-id ` | No | OAuth credential identifier for connector types whose `auth.mode` is `oauth` (see connector types); omit it for `apiKey` connectors. | -| `--api-key ` | No | Write-only API key for connector types whose `auth.mode` is `apiKey` (see connector types), or a personal access token for an OAuth connector that also accepts one, such as GitHub. Send it instead of `credentialId`. Pass a raw key, or a secret reference written as the whole value `{{SECRET_NAME}}`, which the server resolves; `$SECRET_NAME` is not a reference. | +| `--api-key ` | No | Write-only API key for connector types whose `auth.mode` is `apiKey` (see connector types), or a personal access token for an OAuth connector that also accepts one, such as GitHub. Send it instead of `credentialId`. Pass a raw key, or a secret reference written as the whole value `{{SECRET_NAME}}`, which the server resolves; `$SECRET_NAME` is not a reference. | | `--source-config ` | Yes | Connector-specific source selection and filtering configuration. (JSON, or @path / @- to read a file or stdin). | -| `--sync-interval-minutes ` | No | Scheduled synchronization interval in minutes; zero disables scheduling. | +| `--sync-interval-minutes ` | No | Scheduled synchronization interval in minutes; zero disables scheduling. Defaults to 1440. | +API request and response schemas: [createKnowledgeConnector](/api-reference/knowledge-bases/createKnowledgeConnector). + ### sim knowledge connectors delete -Delete Knowledge Connector (OAuth login or personal API key required) +Delete knowledge connector (OAuth login or personal API key required) + +This deletes the connector; --delete-documents also deletes its synchronized documents. ```bash sim knowledge connectors delete [options] @@ -2314,9 +2562,11 @@ sim knowledge connectors delete [options] +API request and response schemas: [deleteKnowledgeConnector](/api-reference/knowledge-bases/deleteKnowledgeConnector). + ### sim knowledge connectors get -Get Knowledge Connector (OAuth login or personal API key required) +Get knowledge connector (OAuth login or personal API key required) ```bash sim knowledge connectors get @@ -2333,9 +2583,11 @@ sim knowledge connectors get +API request and response schemas: [getKnowledgeConnector](/api-reference/knowledge-bases/getKnowledgeConnector). + ### sim knowledge connectors documents list -List Knowledge Connector Documents (OAuth login or personal API key required) +List knowledge connector documents (OAuth login or personal API key required) ```bash sim knowledge connectors documents list [options] @@ -2365,9 +2617,11 @@ sim knowledge connectors documents list [options +API request and response schemas: [listKnowledgeConnectorDocuments](/api-reference/knowledge-bases/listKnowledgeConnectorDocuments). + ### sim knowledge connectors documents update -Update Knowledge Connector Documents (OAuth login or personal API key required) +Update knowledge connector documents (OAuth login or personal API key required) ```bash sim knowledge connectors documents update [options] @@ -2395,9 +2649,11 @@ sim knowledge connectors documents update [optio +API request and response schemas: [updateKnowledgeConnectorDocuments](/api-reference/knowledge-bases/updateKnowledgeConnectorDocuments). + ### sim knowledge connectors list -List Knowledge Connectors (OAuth login or personal API key required) +List knowledge connectors (OAuth login or personal API key required) ```bash sim knowledge connectors list [options] @@ -2419,12 +2675,14 @@ sim knowledge connectors list [options] | Option | Required | Description | | --- | --- | --- | -| `--sort-by ` | No | Field used to sort the result. Accepted values: `connectorType`, `createdAt`, `updatedAt`. | -| `--sort-order ` | No | Sort direction. Accepted values: `asc`, `desc`. | +| `--sort-by ` | No | Field used to sort the result. Defaults to "createdAt". Accepted values: `connectorType`, `createdAt`, `updatedAt`. | +| `--sort-order ` | No | Sort direction. Defaults to "desc". Accepted values: `asc`, `desc`. | | `--limit ` | No | Maximum items to return (0 for everything). Defaults to `0`. | +API request and response schemas: [listKnowledgeConnectors](/api-reference/knowledge-bases/listKnowledgeConnectors). + ### sim knowledge connectors sync Queue a knowledge connector synchronization (OAuth login or personal API key required) @@ -2450,14 +2708,16 @@ sim knowledge connectors sync [options] | Option | Required | Description | | --- | --- | --- | -| `--rehydrate` | No | Re-fetch and re-index every existing connector document. | +| `--rehydrate` | No | Re-fetch and re-index every existing connector document. Defaults to false. | | `--no-rehydrate` | No | Send --rehydrate as false. | +API request and response schemas: [syncKnowledgeConnector](/api-reference/knowledge-bases/syncKnowledgeConnector). + ### sim knowledge connectors update -Update Knowledge Connector (OAuth login or personal API key required) +Update knowledge connector (OAuth login or personal API key required) ```bash sim knowledge connectors update [options] @@ -2486,6 +2746,8 @@ sim knowledge connectors update [options] +API request and response schemas: [updateKnowledgeConnector](/api-reference/knowledge-bases/updateKnowledgeConnector). + ### sim knowledge folders create Create a knowledge folder at a path @@ -2504,9 +2766,13 @@ sim knowledge folders create +API request and response schemas: [createKnowledgeFolder](/api-reference/knowledge-bases/createKnowledgeFolder). + ### sim knowledge folders delete -Delete Folder +Delete folder + +This archives the knowledge folder and, when recursive, everything inside it. ```bash sim knowledge folders delete [options] @@ -2528,11 +2794,13 @@ sim knowledge folders delete [options] | Option | Required | Description | | --- | --- | --- | -| `--recursive` | No | Delete the folder and its descendants. | +| `--recursive` | No | Archive the folder and its descendants. Defaults to "false". | | `-y, --yes` | Yes | Confirm this operation. | +API request and response schemas: [deleteKnowledgeFolder](/api-reference/knowledge-bases/deleteKnowledgeFolder). + ### sim knowledge folders list List knowledge folders @@ -2551,11 +2819,13 @@ Also available as `sim knowledge folders ls`. | --- | --- | --- | | `--parent ` | No | Direct parent folder path. | | `--search ` | No | Case-insensitive substring match against the folder name. | -| `--sort-by ` | No | Field used to sort the result. Sorting by `name` is case-sensitive and follows the storage collation, so do not rely on a case-insensitive order. Accepted values: `name`, `createdAt`, `updatedAt`. | -| `--sort-order ` | No | Sort direction. Accepted values: `asc`, `desc`. | +| `--sort-by ` | No | Field used to sort the result. Do not rely on case-insensitive ordering when sorting by `name`. Defaults to "name". Accepted values: `name`, `createdAt`, `updatedAt`. | +| `--sort-order ` | No | Sort direction. Defaults to "asc". Accepted values: `asc`, `desc`. | +API request and response schemas: [listKnowledgeFolders](/api-reference/knowledge-bases/listKnowledgeFolders). + ### sim knowledge folders move Rename or move a knowledge folder @@ -2577,9 +2847,13 @@ Also available as `sim knowledge folders mv`. +API request and response schemas: [relocateKnowledgeFolder](/api-reference/knowledge-bases/relocateKnowledgeFolder). + ### sim knowledge delete -Delete Knowledge Base +Delete knowledge base + +This archives the knowledge base and every document in it; restore with `knowledge restore`. ```bash sim knowledge delete [options] @@ -2605,9 +2879,11 @@ sim knowledge delete [options] +API request and response schemas: [deleteKnowledgeBase](/api-reference/knowledge-bases/deleteKnowledgeBase). + ### sim knowledge get -Get Knowledge Base +Get knowledge base ```bash sim knowledge get @@ -2623,9 +2899,11 @@ sim knowledge get +API request and response schemas: [getKnowledgeBase](/api-reference/knowledge-bases/getKnowledgeBase). + ### sim knowledge list -List Knowledge Bases +List knowledge bases ```bash sim knowledge list [options] @@ -2637,15 +2915,17 @@ sim knowledge list [options] | Option | Required | Description | | --- | --- | --- | -| `--scope ` | No | Lifecycle scope: active or archived knowledge bases. Use Restore Knowledge Base to recover archived entries. Folder paths resolve only active folders, so filtering by an archived folder returns no matches. Accepted values: `active`, `archived`. | +| `--scope ` | No | Lifecycle scope: active or archived knowledge bases. Use Restore knowledge base to recover archived entries. Folder paths resolve only active folders, so filtering by an archived folder returns no matches. Defaults to "active". Accepted values: `active`, `archived`. | | `--folder ` | No | Folder path as shown in the app; the leading / is optional. | | `--search ` | No | Case-insensitive substring match against the resource name. | -| `--sort-by ` | No | Field used to sort the result. Sorting by `name` is case-sensitive and follows the storage collation, so do not rely on a case-insensitive order. Accepted values: `name`, `createdAt`, `updatedAt`. | -| `--sort-order ` | No | Sort direction. Accepted values: `asc`, `desc`. | +| `--sort-by ` | No | Field used to sort the result. Do not rely on case-insensitive ordering when sorting by `name`. Defaults to "createdAt". Accepted values: `name`, `createdAt`, `updatedAt`. | +| `--sort-order ` | No | Sort direction. Defaults to "asc". Accepted values: `asc`, `desc`. | | `--limit ` | No | Maximum items to return (0 for everything). Defaults to `0`. | +API request and response schemas: [listKnowledgeBases](/api-reference/knowledge-bases/listKnowledgeBases). + ### sim knowledge restore Restore an archived knowledge base @@ -2664,9 +2944,11 @@ sim knowledge restore +API request and response schemas: [restoreKnowledgeBase](/api-reference/knowledge-bases/restoreKnowledgeBase). + ### sim knowledge search -Search Knowledge +Search knowledge ```bash sim knowledge search [options] @@ -2680,19 +2962,21 @@ sim knowledge search [options] | --- | --- | --- | | `--kb ` | Yes | Knowledge base ID (repeatable) (space-separated, or @path / @- with one value per line; @@value for a literal leading @). | | `--query ` | No | Text to search for. | -| `--top-k ` | No | Maximum number of search results to return. Must be a whole number between 1 and 100. | +| `--top-k ` | No | Maximum number of search results to return. Must be a whole number between 1 and 100. Defaults to 10. | | `--tag-filters ` | No | Tag filters as [{"tagName":"...","operator":"...","value":"..."}] (JSON, or @path / @- to read a file or stdin). | | `--search-mode ` | No | Search algorithm. Accepted values: `vector`, `hybrid`. | -| `--reranker-enabled` | No | Re-order retrieved chunks with a reranking model before truncating to `topK`. Ignored for a tag-only search, and billed as an additional search unit. Reranking is best-effort — a provider failure falls back to vector ordering, so check `rerankerStatus` on the response. | +| `--reranker-enabled` | No | Reorder retrieved chunks with a reranking model before truncating to `topK`. Ignored for tag-only searches. A completed reranking call adds a search unit. If reranking is unavailable, results keep their retrieval order; check `rerankerStatus`. | | `--no-reranker-enabled` | No | Send --reranker-enabled as false. | | `--reranker-model ` | No | Reranking model to use when `rerankerEnabled` is true. Defaults to `rerank-v4.0-fast`. Accepted values: `rerank-v4.0-pro`, `rerank-v4.0-fast`, `rerank-v3.5`. | | `--reranker-input-count ` | No | How many candidate chunks to retrieve before reranking. Defaults to four times `topK`, capped at 100. A larger pool costs more retrieval work but gives the reranker more to choose from. | +API request and response schemas: [searchKnowledge](/api-reference/knowledge-bases/searchKnowledge). + ### sim knowledge update -Update Knowledge Base +Update knowledge base ```bash sim knowledge update [options] @@ -2721,6 +3005,8 @@ sim knowledge update [options] +API request and response schemas: [updateKnowledgeBase](/api-reference/knowledge-bases/updateKnowledgeBase). + ### sim knowledge mv Move a knowledge base to a folder @@ -2740,6 +3026,8 @@ sim knowledge mv +API request and response schemas: [updateKnowledgeBase](/api-reference/knowledge-bases/updateKnowledgeBase). + ### sim knowledge export Export a knowledge base as a .simkb.zip bundle @@ -2770,6 +3058,8 @@ sim knowledge export [options] +API request and response schemas: [exportKnowledgeBase](/api-reference/knowledge-bases/exportKnowledgeBase). + ### sim knowledge ls List knowledge resources and child folders together @@ -2799,6 +3089,8 @@ sim knowledge ls [path] [options] +API request and response schemas: [listKnowledgeBases](/api-reference/knowledge-bases/listKnowledgeBases), [listKnowledgeFolders](/api-reference/knowledge-bases/listKnowledgeFolders). + ### sim knowledge mkdir Create a knowledge directory at a path @@ -2817,8 +3109,12 @@ sim knowledge mkdir +API request and response schemas: [createKnowledgeFolder](/api-reference/knowledge-bases/createKnowledgeFolder). + ## sim logs +Read run diagnostics, follow new runs, and summarize failures and latency. + Also spelled `sim log`. ### sim logs get @@ -2851,6 +3147,8 @@ sim logs get [options] +API request and response schemas: [getLog](/api-reference/logs/getLog). + ### sim logs stats Summarize run counts, failures and latency over a window @@ -2873,11 +3171,13 @@ sim logs stats [options] | `--no-include-handled-errors` | No | Send --include-handled-errors as false. | | `--start-date ` | No | Only include runs started at or after this UTC ISO 8601 timestamp, e.g. `2026-08-06T00:00:00Z`. A date without a time, or a timestamp carrying a UTC offset instead of `Z`, is rejected, as is year `0000`, which names no storable instant. | | `--end-date ` | No | Only include runs started at or before this UTC ISO 8601 timestamp, e.g. `2026-08-06T00:00:00Z`. A date without a time, or a timestamp carrying a UTC offset instead of `Z`, is rejected, as is year `0000`, which names no storable instant. | -| `--segment-count ` | No | Number of equal time buckets to divide the window into, from 1 to 500. It is the ceiling on how many buckets a series carries: with `includeEmpty=true` exactly this many are returned, otherwise only the buckets holding at least one run. Buckets are never narrower than one minute, so on a short window the series extends past the end of the window rather than being compressed, and the trailing buckets are empty. | +| `--segment-count ` | No | Number of equal time buckets to divide the window into, from 1 to 500. It is the ceiling on how many buckets a series carries: with `includeEmpty=true` exactly this many are returned, otherwise only the buckets holding at least one run. Buckets are never narrower than one minute, so on a short window the series extends past the end of the window rather than being compressed, and the trailing buckets are empty. Defaults to 72. | | `--include-empty ` | No | Whether buckets with no runs are included in every series. Off by default, so each series carries only the buckets that hold at least one run; set it to publish exactly `segmentCount` buckets per series, empty ones included. The listed spellings are the whole accepted vocabulary and are case-sensitive; any other value is rejected. Accepted values: `true`, `1`, `yes`, `on`, `y`, `enabled`, `false`, `0`, `no`, `off`, `n`, `disabled`. | +API request and response schemas: [getLogStats](/api-reference/logs/getLogStats). + ### sim logs list List run logs, such as failed or errored runs, by workflow, trigger or time @@ -2914,12 +3214,14 @@ sim logs list [options] | `--include-job-runs` | No | Include Chat and Sim-agent jobs alongside workflow runs. Jobs use `kind: "job"` and have no workflow or cost ledger. Workflow, folder, model, or status filters exclude jobs. This option is valid only when sorting by `startedAt`. | | `--no-include-job-runs` | No | Send --include-job-runs as false. | | `--run-id ` | No | Exact run identifier to match. | -| `--sort-by ` | No | Field used to sort the result. `durationMs` and `cost` are null until a run settles; those runs sort before recorded values in ascending order and after them in descending order. Only `startedAt` can order Chat and Sim-agent job runs, so any other value is rejected when job runs are included. Accepted values: `startedAt`, `durationMs`, `cost`, `status`. | -| `--sort-order ` | No | Sort direction. Accepted values: `asc`, `desc`. | +| `--sort-by ` | No | Field used to sort the result. `durationMs` and `cost` are null until a run settles; those runs sort before recorded values in ascending order and after them in descending order. Only `startedAt` can order Chat and Sim-agent job runs, so any other value is rejected when job runs are included. Defaults to "startedAt". Accepted values: `startedAt`, `durationMs`, `cost`, `status`. | +| `--sort-order ` | No | Sort direction. Defaults to "desc". Accepted values: `asc`, `desc`. | | `--folder ` | No | Folder path as shown in the app; the leading / is optional (space-separated, or @path / @- with one value per line; @@value for a literal leading @). | +API request and response schemas: [listLogs](/api-reference/logs/listLogs). + ### sim logs follow Watch runs live as they arrive, printing each new run once @@ -2944,13 +3246,29 @@ sim logs follow [options] +Each run prints once, when it is first seen, so its status is the status it had at that moment. With --output json every run is a JSON object on its own line (JSONL) rather than a member of an array, because a follow never ends and so can never close one; --output yaml emits a --- separated document stream. Progress and retries go to stderr, leaving stdout a clean stream of rows. Ctrl-C stops the follow. + +**Examples** + +```bash +sim logs follow --level error +sim logs follow --workflow 00000000-0000-4000-8000-000000000000 -n 0 +sim --output json logs follow | jq -r '.runId' +``` + +API request and response schemas: [listLogs](/api-reference/logs/listLogs). + ## sim mcp-servers +Connect external Model Context Protocol (MCP) servers so workflows can use their tools. + +To serve Sim workflows to MCP clients instead, use [workflow MCP servers](/cli/workflow-mcp-servers). + Also spelled `sim mcp-server`. ### sim mcp-servers create -Create MCP Server +Create MCP server ```bash sim mcp-servers create [options] @@ -2965,8 +3283,8 @@ sim mcp-servers create [options] | `--name ` | Yes | Server display name. | | `--description ` | No | Optional server description. | | `--transport ` | No | Transport protocol. Defaults to `streamable-http` on creation. Accepted values: `streamable-http`. | -| `--url ` | Yes | Absolute HTTP or HTTPS endpoint URL without `{{ENV_VAR}}` references. It determines server identity and is immutable: delete and recreate the server to change endpoints. | -| `--auth-type ` | No | Authentication method. When omitted, and no `headers` are sent, registration probes the endpoint once to classify it, falling back to `headers` when the probe fails or the server does not advertise OAuth. A server publishing RFC 9728 metadata is therefore stored as `oauth`, and headers configured afterwards will not authenticate — send this field explicitly to pin the method. Accepted values: `none`, `headers`, `oauth`. | +| `--url ` | Yes | Absolute HTTP or HTTPS endpoint URL without `{{ENV_VAR}}` references. It determines server identity and is immutable: delete and recreate the server to change endpoints. | +| `--auth-type ` | No | Authentication method. On creation, omission without `headers` probes once: an OAuth challenge selects `oauth`, an unauthenticated success selects `none`, and other outcomes fall back to `headers`. An OAuth client ID selects `oauth` when the method is omitted. Set explicitly to use headers with a server advertising OAuth; adding headers later does not change the saved method. Accepted values: `none`, `headers`, `oauth`. | | `--headers ` | No | Write-only request headers sent to the server. Replaced wholesale rather than merged on update: sending this field drops every stored header it does not repeat. (JSON, or @path / @- to read a file or stdin). | | `--timeout ` | No | Per-request timeout in milliseconds. Defaults to 30000 on creation. | | `--retries ` | No | Number of retries per request. Defaults to 3 on creation. | @@ -2977,9 +3295,13 @@ sim mcp-servers create [options] +API request and response schemas: [createMcpServer](/api-reference/mcp-servers/createMcpServer). + ### sim mcp-servers delete -Delete MCP Server +Delete MCP server + +This removes the MCP server and the tools it provides. ```bash sim mcp-servers delete [options] @@ -3005,9 +3327,11 @@ sim mcp-servers delete [options] +API request and response schemas: [deleteMcpServer](/api-reference/mcp-servers/deleteMcpServer). + ### sim mcp-servers get -Get MCP Server +Get MCP server ```bash sim mcp-servers get @@ -3023,9 +3347,11 @@ sim mcp-servers get +API request and response schemas: [getMcpServer](/api-reference/mcp-servers/getMcpServer). + ### sim mcp-servers list -List MCP Servers +List MCP servers ```bash sim mcp-servers list [options] @@ -3038,15 +3364,17 @@ sim mcp-servers list [options] | Option | Required | Description | | --- | --- | --- | | `--search ` | No | Case-insensitive substring match against the server name. | -| `--sort-by ` | No | Field used to sort the result. Sorting by `name` is case-sensitive and follows the storage collation, so do not rely on a case-insensitive order. Accepted values: `name`, `createdAt`, `updatedAt`. | -| `--sort-order ` | No | Sort direction. Accepted values: `asc`, `desc`. | +| `--sort-by ` | No | Field used to sort the result. Do not rely on case-insensitive ordering when sorting by `name`. Defaults to "createdAt". Accepted values: `name`, `createdAt`, `updatedAt`. | +| `--sort-order ` | No | Sort direction. Defaults to "desc". Accepted values: `asc`, `desc`. | | `--limit ` | No | Maximum items to return (0 for everything). Defaults to `0`. | +API request and response schemas: [listMcpServers](/api-reference/mcp-servers/listMcpServers). + ### sim mcp-servers tools list -List MCP Server Tools (OAuth login or personal API key required) +List MCP server tools (OAuth login or personal API key required) ```bash sim mcp-servers tools list [options] @@ -3073,9 +3401,11 @@ sim mcp-servers tools list [options] +API request and response schemas: [listMcpServerTools](/api-reference/mcp-servers/listMcpServerTools). + ### sim mcp-servers update -Update MCP Server +Update MCP server ```bash sim mcp-servers update [options] @@ -3101,7 +3431,7 @@ sim mcp-servers update [options] | `--description ` | No | Optional server description. | | `--transport ` | No | Transport protocol. Defaults to `streamable-http` on creation. Accepted values: `streamable-http`. | | `--url ` | No | Immutable server URL. When provided, it must equal the current URL; use delete and create to change endpoints. | -| `--auth-type ` | No | Authentication method. When omitted, and no `headers` are sent, registration probes the endpoint once to classify it, falling back to `headers` when the probe fails or the server does not advertise OAuth. A server publishing RFC 9728 metadata is therefore stored as `oauth`, and headers configured afterwards will not authenticate — send this field explicitly to pin the method. Accepted values: `none`, `headers`, `oauth`. | +| `--auth-type ` | No | Authentication method. On creation, omission without `headers` probes once: an OAuth challenge selects `oauth`, an unauthenticated success selects `none`, and other outcomes fall back to `headers`. An OAuth client ID selects `oauth` when the method is omitted. Set explicitly to use headers with a server advertising OAuth; adding headers later does not change the saved method. Accepted values: `none`, `headers`, `oauth`. | | `--headers ` | No | Write-only request headers sent to the server. Replaced wholesale rather than merged on update: sending this field drops every stored header it does not repeat. (JSON, or @path / @- to read a file or stdin). | | `--timeout ` | No | Per-request timeout in milliseconds. Defaults to 30000 on creation. | | `--retries ` | No | Number of retries per request. Defaults to 3 on creation. | @@ -3112,21 +3442,29 @@ sim mcp-servers update [options] +API request and response schemas: [updateMcpServer](/api-reference/mcp-servers/updateMcpServer). + ## sim meta +Inspect API availability and the calling credential’s type and expiry. + ### sim meta status -Show what this API supports and which limits apply +Show API availability and the calling credential’s type and expiry ```bash sim meta status ``` +API request and response schemas: [getMeta](/api-reference/meta/getApiMeta). + ## sim organizations +Manage organization membership, invitations, usage, access requests, and SSO. + ### sim organizations domains add -Add Organization Domain (OAuth login or personal API key required) +Add organization domain (OAuth login or personal API key required) ```bash sim organizations domains add [options] @@ -3143,9 +3481,11 @@ sim organizations domains add [options] +API request and response schemas: [addOrganizationDomain](/api-reference/organizations/addOrganizationDomain). + ### sim organizations domains list -List Organization Domains (OAuth login or personal API key required) +List organization domains (OAuth login or personal API key required) ```bash sim organizations domains list [options] @@ -3159,14 +3499,18 @@ sim organizations domains list [options] | --- | --- | --- | | `--organization ` | Yes | Organization identifier. | | `--limit ` | No | Maximum items to return (0 for everything). Defaults to `0`. | -| `--sort-by ` | No | Field used to sort the result. Accepted values: `domain`. | -| `--sort-order ` | No | Sort direction. Accepted values: `asc`, `desc`. | +| `--sort-by ` | No | Field used to sort the result. Defaults to "domain". Accepted values: `domain`. | +| `--sort-order ` | No | Sort direction. Defaults to "asc". Accepted values: `asc`, `desc`. | +API request and response schemas: [listOrganizationDomains](/api-reference/organizations/listOrganizationDomains). + ### sim organizations domains remove -Remove Organization Domain (OAuth login or personal API key required) +Remove organization domain (OAuth login or personal API key required) + +This removes the domain claim and revokes verified SSO authority for its providers. ```bash sim organizations domains remove [options] @@ -3193,9 +3537,11 @@ sim organizations domains remove [options] +API request and response schemas: [removeOrganizationDomain](/api-reference/organizations/removeOrganizationDomain). + ### sim organizations domains verify -Verify Organization Domain (OAuth login or personal API key required) +Verify organization domain (OAuth login or personal API key required) ```bash sim organizations domains verify [options] @@ -3221,9 +3567,11 @@ sim organizations domains verify [options] +API request and response schemas: [verifyOrganizationDomain](/api-reference/organizations/verifyOrganizationDomain). + ### sim organizations access-requests cancel -Cancel Organization Access Request (OAuth login or personal API key required) +Cancel organization access request (OAuth login or personal API key required) ```bash sim organizations access-requests cancel [options] @@ -3249,9 +3597,11 @@ sim organizations access-requests cancel [options] +API request and response schemas: [cancelOrganizationAccessRequest](/api-reference/access-requests/cancelOrganizationAccessRequest). + ### sim organizations access-requests create -Create Organization Access Request (OAuth login or personal API key required) +Create organization access request (OAuth login or personal API key required) ```bash sim organizations access-requests create [options] @@ -3265,13 +3615,15 @@ sim organizations access-requests create [options] | --- | --- | --- | | `--organization ` | Yes | Organization identifier. | | `--target ` | Yes | Target returned by Discover Workspace Access Requests or Discover Organization Access Requests. The target must currently be requestable. (JSON, or @path / @- to read a file or stdin). | -| `--reason ` | No | Why the acting user needs this access. | +| `--reason ` | No | Why the acting user needs this access. Defaults to "". | +API request and response schemas: [createOrganizationAccessRequest](/api-reference/access-requests/createOrganizationAccessRequest). + ### sim organizations access-requests discover -Discover Organization Access Requests (OAuth login or personal API key required) +Discover organization access requests (OAuth login or personal API key required) ```bash sim organizations access-requests discover [options] @@ -3287,16 +3639,18 @@ sim organizations access-requests discover [options] | `--search ` | No | Case-insensitive substring match against the access item label. | | `--target-kind ` | No | Category of access to discover. Accepted values: `feature`, `integration`, `provider`, `model`, `tool`, `knowledge_connector`, `file_share_auth`, `chat_deploy_auth`, `usage_limit`. | | `--state ` | No | Filter by the acting user’s current access. Requestable items can be submitted for review. Accepted values: `allowed`, `requestable`, `unavailable`. | -| `--sort-by ` | No | Field used to sort the result. Accepted values: `label`. | -| `--sort-order ` | No | Sort direction. Accepted values: `asc`, `desc`. | +| `--sort-by ` | No | Field used to sort the result. Defaults to "label". Accepted values: `label`. | +| `--sort-order ` | No | Sort direction. Defaults to "asc". Accepted values: `asc`, `desc`. | | `--limit ` | No | Maximum items to return (0 for everything). Defaults to `100`. | | `--cursor ` | No | Continue from nextCursor returned by a previous result. | +API request and response schemas: [discoverOrganizationAccessRequests](/api-reference/access-requests/discoverOrganizationAccessRequests). + ### sim organizations access-requests settings get -Get Organization Access Request Settings (OAuth login or personal API key required) +Get organization access request settings (OAuth login or personal API key required) ```bash sim organizations access-requests settings get [options] @@ -3312,9 +3666,11 @@ sim organizations access-requests settings get [options] +API request and response schemas: [getOrganizationAccessRequestSettings](/api-reference/access-requests/getOrganizationAccessRequestSettings). + ### sim organizations access-requests settings update -Update Organization Access Request Settings (OAuth login or personal API key required) +Update organization access request settings (OAuth login or personal API key required) ```bash sim organizations access-requests settings update [options] @@ -3331,9 +3687,11 @@ sim organizations access-requests settings update [options] +API request and response schemas: [updateOrganizationAccessRequestSettings](/api-reference/access-requests/updateOrganizationAccessRequestSettings). + ### sim organizations access-requests mine -List My Organization Access Requests (OAuth login or personal API key required) +List my organization access requests (OAuth login or personal API key required) ```bash sim organizations access-requests mine [options] @@ -3347,16 +3705,18 @@ sim organizations access-requests mine [options] | --- | --- | --- | | `--organization ` | Yes | Organization identifier. | | `--status ` | No | Filter by request status; omit to include all statuses. Accepted values: `pending`, `fulfilled`, `declined`, `cancelled`, `closed`. | -| `--sort-by ` | No | Field used to sort the result. Accepted values: `createdAt`, `targetLabel`. | -| `--sort-order ` | No | Sort direction. Accepted values: `asc`, `desc`. | +| `--sort-by ` | No | Field used to sort the result. Defaults to "createdAt". Accepted values: `createdAt`, `targetLabel`. | +| `--sort-order ` | No | Sort direction. Defaults to "desc". Accepted values: `asc`, `desc`. | | `--limit ` | No | Maximum items to return (0 for everything). Defaults to `100`. | | `--cursor ` | No | Continue from nextCursor returned by a previous result. | +API request and response schemas: [listMyOrganizationAccessRequests](/api-reference/access-requests/listMyOrganizationAccessRequests). + ### sim organizations access-requests list -List Organization Access Requests (OAuth login or personal API key required) +List organization access requests (OAuth login or personal API key required) ```bash sim organizations access-requests list [options] @@ -3370,17 +3730,19 @@ sim organizations access-requests list [options] | --- | --- | --- | | `--organization ` | Yes | Organization identifier. | | `--status ` | No | Filter by request status; omit to include all statuses. Accepted values: `pending`, `fulfilled`, `declined`, `cancelled`, `closed`. | -| `--sort-by ` | No | Field used to sort the result. Accepted values: `createdAt`, `targetLabel`. | -| `--sort-order ` | No | Sort direction. Accepted values: `asc`, `desc`. | +| `--sort-by ` | No | Field used to sort the result. Defaults to "createdAt". Accepted values: `createdAt`, `targetLabel`. | +| `--sort-order ` | No | Sort direction. Defaults to "desc". Accepted values: `asc`, `desc`. | | `--limit ` | No | Maximum items to return (0 for everything). Defaults to `100`. | | `--cursor ` | No | Continue from nextCursor returned by a previous result. | | `--search ` | No | Case-insensitive substring match against the target label or requester name or email. | +API request and response schemas: [listOrganizationAccessRequests](/api-reference/access-requests/listOrganizationAccessRequests). + ### sim organizations access-requests preview -Preview Organization Access Request (OAuth login or personal API key required) +Preview organization access request (OAuth login or personal API key required) ```bash sim organizations access-requests preview [options] @@ -3406,9 +3768,11 @@ sim organizations access-requests preview [options] +API request and response schemas: [previewOrganizationAccessRequest](/api-reference/access-requests/previewOrganizationAccessRequest). + ### sim organizations access-requests resolve -Resolve Organization Access Request (OAuth login or personal API key required) +Resolve organization access request (OAuth login or personal API key required) ```bash sim organizations access-requests resolve [options] @@ -3432,15 +3796,17 @@ sim organizations access-requests resolve [options] | --- | --- | --- | | `--organization ` | Yes | Organization identifier. | | `--action ` | Yes | apply: Apply the reviewed change to the governing group or member credit cap. decline: Decline the request without changing permissions or credit limits. Accepted values: `apply`, `decline`. | -| `--expected-fingerprint ` | No | Fingerprint from Preview Organization Access Request. Review its changes and impact before applying; a stale preview returns a conflict. Available when action is apply. Required when action is apply. | -| `--new-limit-credits ` | No | Required only for a usage-limit request: a whole-number credit cap greater than the current cap. Omit for permission requests. Available when action is apply. | -| `--reason ` | No | Required explanation for declining this request. Available when action is decline. Required when action is decline. | +| `--expected-fingerprint ` | Conditional | Fingerprint from Preview Organization Access Request. Review its changes and impact before applying; a stale preview returns a conflict. Available when action is apply. Required when action is apply. | +| `--new-limit-credits ` | Conditional | Required only for a usage-limit request: a whole-number credit cap greater than the current cap. Omit for permission requests. Available when action is apply. | +| `--reason ` | Conditional | Required explanation for declining this request. Available when action is decline. Required when action is decline. | +API request and response schemas: [resolveOrganizationAccessRequest](/api-reference/access-requests/resolveOrganizationAccessRequest). + ### sim organizations invitations create -Create Organization Invitation (OAuth login or personal API key required) +Create organization invitation (OAuth login or personal API key required) ```bash sim organizations invitations create [options] @@ -3458,9 +3824,11 @@ sim organizations invitations create [options] +API request and response schemas: [createOrganizationInvitation](/api-reference/organizations/createOrganizationInvitation). + ### sim organizations invitations get -Get Organization Invitation (OAuth login or personal API key required) +Get organization invitation (OAuth login or personal API key required) ```bash sim organizations invitations get [options] @@ -3486,9 +3854,11 @@ sim organizations invitations get [options] +API request and response schemas: [getOrganizationInvitation](/api-reference/organizations/getOrganizationInvitation). + ### sim organizations invitations list -List Organization Invitations (OAuth login or personal API key required) +List organization invitations (OAuth login or personal API key required) ```bash sim organizations invitations list [options] @@ -3503,16 +3873,18 @@ sim organizations invitations list [options] | `--organization ` | Yes | Organization identifier. | | `--search ` | No | Case-insensitive substring match against the invitee email. | | `--status ` | No | Filter by current invitation status. Omit to include all statuses. Accepted values: `pending`, `accepted`, `rejected`, `cancelled`, `expired`. | -| `--sort-by ` | No | Field used to sort the result. Accepted values: `email`, `createdAt`. | -| `--sort-order ` | No | Sort direction. Accepted values: `asc`, `desc`. | +| `--sort-by ` | No | Field used to sort the result. Defaults to "createdAt". Accepted values: `email`, `createdAt`. | +| `--sort-order ` | No | Sort direction. Defaults to "desc". Accepted values: `asc`, `desc`. | | `--limit ` | No | Maximum items to return (0 for everything). Defaults to `100`. | | `--cursor ` | No | Continue from nextCursor returned by a previous result. | +API request and response schemas: [listOrganizationInvitations](/api-reference/organizations/listOrganizationInvitations). + ### sim organizations invitations workspaces -List Organization Invitation Workspaces (OAuth login or personal API key required) +List organization invitation workspaces (OAuth login or personal API key required) ```bash sim organizations invitations workspaces [options] @@ -3536,16 +3908,18 @@ sim organizations invitations workspaces [options] | --- | --- | --- | | `--organization ` | Yes | Organization identifier. | | `--search ` | No | Case-insensitive substring match against the workspace name. | -| `--sort-by ` | No | Field used to sort the result. Sorting by `name` is case-sensitive and follows the storage collation, so do not rely on a case-insensitive order. Accepted values: `name`, `id`. | -| `--sort-order ` | No | Sort direction. Accepted values: `asc`, `desc`. | +| `--sort-by ` | No | Field used to sort the result. Do not rely on case-insensitive ordering when sorting by `name`. Defaults to "name". Accepted values: `name`, `id`. | +| `--sort-order ` | No | Sort direction. Defaults to "asc". Accepted values: `asc`, `desc`. | | `--limit ` | No | Maximum items to return (0 for everything). Defaults to `100`. | | `--cursor ` | No | Continue from nextCursor returned by a previous result. | +API request and response schemas: [listOrganizationInvitationWorkspaces](/api-reference/organizations/listOrganizationInvitationWorkspaces). + ### sim organizations invitations resend -Resend Organization Invitation (OAuth login or personal API key required) +Resend organization invitation (OAuth login or personal API key required) ```bash sim organizations invitations resend [options] @@ -3571,9 +3945,13 @@ sim organizations invitations resend [options] +API request and response schemas: [resendOrganizationInvitation](/api-reference/organizations/resendOrganizationInvitation). + ### sim organizations invitations revoke -Revoke Organization Invitation (OAuth login or personal API key required) +Revoke organization invitation (OAuth login or personal API key required) + +This cancels the invitation and all its workspace grants, preventing acceptance. ```bash sim organizations invitations revoke [options] @@ -3600,9 +3978,13 @@ sim organizations invitations revoke [options] +API request and response schemas: [revokeOrganizationInvitation](/api-reference/organizations/revokeOrganizationInvitation). + ### sim organizations sso providers delete -Delete SSO Provider (OAuth login or personal API key required) +Delete SSO provider (OAuth login or personal API key required) + +This removes the identity provider used for SSO sign-in; linked accounts remain. ```bash sim organizations sso providers delete [options] @@ -3629,9 +4011,11 @@ sim organizations sso providers delete [options] +API request and response schemas: [deleteSsoProvider](/api-reference/organizations/deleteSsoProvider). + ### sim organizations sso providers get -Get SSO Provider (OAuth login or personal API key required) +Get SSO provider (OAuth login or personal API key required) ```bash sim organizations sso providers get [options] @@ -3657,9 +4041,11 @@ sim organizations sso providers get [options] +API request and response schemas: [getSsoProvider](/api-reference/organizations/getSsoProvider). + ### sim organizations sso providers list -List SSO Providers (OAuth login or personal API key required) +List SSO providers (OAuth login or personal API key required) ```bash sim organizations sso providers list [options] @@ -3673,14 +4059,18 @@ sim organizations sso providers list [options] | --- | --- | --- | | `--organization ` | Yes | Organization identifier. | | `--limit ` | No | Maximum items to return (0 for everything). Defaults to `0`. | -| `--sort-by ` | No | Field used to sort the result. Accepted values: `providerId`, `domain`. | -| `--sort-order ` | No | Sort direction. Accepted values: `asc`, `desc`. | +| `--sort-by ` | No | Field used to sort the result. Defaults to "providerId". Accepted values: `providerId`, `domain`. | +| `--sort-order ` | No | Sort direction. Defaults to "asc". Accepted values: `asc`, `desc`. | +API request and response schemas: [listSsoProviders](/api-reference/organizations/listSsoProviders). + ### sim organizations sso providers save -Save SSO Provider (OAuth login or personal API key required) +Save SSO provider (OAuth login or personal API key required) + +Choose `--provider-type oidc` or `saml`. OIDC requires `--client-id` and `--client-secret`; SAML requires `--entry-point` and `--cert`. Both require an organization-verified domain. The option descriptions state which omitted fields are preserved or cleared. ```bash sim organizations sso providers save [options] @@ -3697,22 +4087,22 @@ sim organizations sso providers save [options] | `--provider-id ` | Yes | Globally unique provider ID; saving an existing provider replaces its supplied configuration. | | `--issuer ` | Yes | Identity provider issuer URL. | | `--domain ` | Yes | Email domain already verified by this organization. | -| `--jit-provisioning-enabled` | No | Allow SSO sign-in to provision organization membership, subject to eligibility and available seats. | +| `--jit-provisioning-enabled` | No | Allow SSO sign-in to provision organization membership, subject to eligibility and available seats. Defaults to true. | | `--no-jit-provisioning-enabled` | No | Send --jit-provisioning-enabled as false. | -| `--mapping ` | No | Identity-provider claims mapped to user fields. (JSON, or @path / @- to read a file or stdin). | -| `--client-id ` | No | Identity provider client identifier. Available when providerType is oidc. Required when providerType is oidc. | -| `--client-secret ` | No | Write-only OIDC client secret; the redacted marker from providers get preserves an existing secret. Passing it inline exposes it to shell history and process listings. Required when --provider-type is oidc (@path / @- reads a file or stdin verbatim, including trailing newlines; @@value for a literal leading @). | -| `--scopes ` | No | OIDC scopes; offline_access is omitted. Available when providerType is oidc. (JSON, or @path / @- to read a file or stdin). | -| `--pkce` | No | Use PKCE for the authorization flow. Available when providerType is oidc. | +| `--mapping ` | No | Identity-provider claims mapped to user fields. Defaults to {"id":"sub","email":"email","name":"name","image":"picture"}. (JSON, or @path / @- to read a file or stdin). | +| `--client-id ` | Conditional | Identity provider client identifier. Available when providerType is oidc. Required when providerType is oidc. | +| `--client-secret ` | Conditional | Write-only OIDC client secret; the redacted marker from providers get preserves an existing secret. Passing it inline exposes it to shell history and process listings. Required when --provider-type is oidc (@path / @- reads a file or stdin verbatim, including trailing newlines; @@value for a literal leading @). | +| `--scopes ` | No | OIDC scopes; offline_access is omitted. Available when providerType is oidc. Defaults to ["openid","profile","email"]. (JSON, or @path / @- to read a file or stdin). | +| `--pkce` | No | Use PKCE for the authorization flow. Available when providerType is oidc. Defaults to true. | | `--no-pkce` | No | Send --pkce as false. | | `--authorization-endpoint ` | No | Optional authorization endpoint; otherwise resolved through issuer discovery. Available when providerType is oidc. | | `--token-endpoint ` | No | Optional token endpoint; otherwise resolved through issuer discovery. Available when providerType is oidc. | | `--user-info-endpoint ` | No | Optional UserInfo endpoint. Available when providerType is oidc. | -| `--skip-user-info-endpoint` | No | Read identity claims from the ID token instead of calling UserInfo. Available when providerType is oidc. | +| `--skip-user-info-endpoint` | No | Read identity claims from the ID token instead of calling UserInfo. Available when providerType is oidc. Defaults to false. | | `--no-skip-user-info-endpoint` | No | Send --skip-user-info-endpoint as false. | | `--jwks-endpoint ` | No | Optional signing-key endpoint; otherwise resolved through issuer discovery. Available when providerType is oidc. | -| `--entry-point ` | No | Identity provider SAML sign-in endpoint. Available when providerType is saml. Required when providerType is saml. | -| `--cert ` | No | Identity provider signing certificate. Available when providerType is saml. Required when providerType is saml. | +| `--entry-point ` | Conditional | Identity provider SAML sign-in endpoint. Available when providerType is saml. Required when providerType is saml. | +| `--cert ` | Conditional | Identity provider signing certificate. Available when providerType is saml. Required when providerType is saml. | | `--callback-url ` | No | SAML callback URL; defaults to this provider’s Sim callback. Available when providerType is saml. | | `--audience ` | No | SAML audience; omission preserves the saved value. Available when providerType is saml. | | `--want-assertions-signed` | No | Require signed assertions; omission preserves the saved value. Available when providerType is saml. | @@ -3724,9 +4114,11 @@ sim organizations sso providers save [options] +API request and response schemas: [saveSsoProvider](/api-reference/organizations/saveSsoProvider). + ### sim organizations sso providers primary -Set Primary SSO Provider (OAuth login or personal API key required) +Set primary SSO provider (OAuth login or personal API key required) ```bash sim organizations sso providers primary [options] @@ -3752,9 +4144,11 @@ sim organizations sso providers primary [options] +API request and response schemas: [setPrimarySsoProvider](/api-reference/organizations/setPrimarySsoProvider). + ### sim organizations sso policy get -Get SSO Policy (OAuth login or personal API key required) +Get SSO policy (OAuth login or personal API key required) ```bash sim organizations sso policy get [options] @@ -3770,9 +4164,11 @@ sim organizations sso policy get [options] +API request and response schemas: [getSsoPolicy](/api-reference/organizations/getSsoPolicy). + ### sim organizations sso policy update -Update SSO Policy (OAuth login or personal API key required) +Update SSO policy (OAuth login or personal API key required) ```bash sim organizations sso policy update [options] @@ -3789,9 +4185,11 @@ sim organizations sso policy update [options] +API request and response schemas: [updateSsoPolicy](/api-reference/organizations/updateSsoPolicy). + ### sim organizations get -Get Organization (OAuth login or personal API key required) +Get organization (OAuth login or personal API key required) ```bash sim organizations get @@ -3807,9 +4205,11 @@ sim organizations get +API request and response schemas: [getOrganization](/api-reference/organizations/getOrganization). + ### sim organizations members usage-limit get -Get Organization Member Credit Limit (OAuth login or personal API key required) +Get organization member credit limit (OAuth login or personal API key required) ```bash sim organizations members usage-limit get [options] @@ -3835,9 +4235,11 @@ sim organizations members usage-limit get [options] +API request and response schemas: [getOrganizationMemberUsageLimit](/api-reference/organizations/getOrganizationMemberUsageLimit). + ### sim organizations members usage-limit update -Update Organization Member Credit Limit (OAuth login or personal API key required) +Update organization member credit limit (OAuth login or personal API key required) ```bash sim organizations members usage-limit update [options] @@ -3864,9 +4266,11 @@ sim organizations members usage-limit update [options] +API request and response schemas: [updateOrganizationMemberUsageLimit](/api-reference/organizations/updateOrganizationMemberUsageLimit). + ### sim organizations members list -List Organization Members (OAuth login or personal API key required) +List organization members (OAuth login or personal API key required) ```bash sim organizations members list [options] @@ -3880,15 +4284,19 @@ sim organizations members list [options] | --- | --- | --- | | `--organization ` | Yes | Organization identifier. | | `--search ` | No | Case-insensitive substring match against member name or email. | -| `--sort-by ` | No | Field used to sort the result. Sorting by `name` is case-sensitive and follows the storage collation, so do not rely on a case-insensitive order. Accepted values: `name`, `email`, `joinedAt`. | -| `--sort-order ` | No | Sort direction. Accepted values: `asc`, `desc`. | +| `--sort-by ` | No | Field used to sort the result. Do not rely on case-insensitive ordering when sorting by `name`. Defaults to "name". Accepted values: `name`, `email`, `joinedAt`. | +| `--sort-order ` | No | Sort direction. Defaults to "asc". Accepted values: `asc`, `desc`. | | `--limit ` | No | Maximum items to return (0 for everything). Defaults to `0`. | +API request and response schemas: [listOrganizationMembers](/api-reference/organizations/listOrganizationMembers). + ### sim organizations members remove -Remove Organization Member (OAuth login or personal API key required) +Remove organization member (OAuth login or personal API key required) + +This removes the member, revokes their organization workspace access, and ends their sessions. ```bash sim organizations members remove [options] @@ -3915,9 +4323,11 @@ sim organizations members remove [options] +API request and response schemas: [removeOrganizationMember](/api-reference/organizations/removeOrganizationMember). + ### sim organizations members update -Update Organization Member (OAuth login or personal API key required) +Update organization member (OAuth login or personal API key required) ```bash sim organizations members update [options] @@ -3944,9 +4354,11 @@ sim organizations members update [options] +API request and response schemas: [updateOrganizationMember](/api-reference/organizations/updateOrganizationMember). + ### sim organizations usage breakdown -Get Organization Usage Breakdown (OAuth login or personal API key required) +Get organization usage breakdown (OAuth login or personal API key required) ```bash sim organizations usage breakdown [options] @@ -3959,7 +4371,7 @@ sim organizations usage breakdown [options] | Option | Required | Description | | --- | --- | --- | | `--organization ` | Yes | Organization identifier. | -| `--preset ` | No | Reporting window. Custom requires startDate and endDate and is capped at 92 days; other presets reject those bounds. Resolved billing windows are capped at 366 days. Accepted values: `current-period`, `previous-period`, `7d`, `30d`, `custom`. | +| `--preset ` | No | Reporting window. Custom requires startDate and endDate and is capped at 92 days; other presets reject those bounds. Resolved billing windows are capped at 366 days. Defaults to "30d". Accepted values: `current-period`, `previous-period`, `7d`, `30d`, `custom`. | | `--start-date ` | No | First calendar date included, in the selected timezone. Requires preset=custom. | | `--end-date ` | No | Last calendar date included, in the selected timezone. Requires preset=custom. | | `--timezone ` | No | IANA timezone for calendar boundaries; defaults to UTC. | @@ -3968,9 +4380,11 @@ sim organizations usage breakdown [options] +API request and response schemas: [getOrganizationUsageBreakdown](/api-reference/organizations/getOrganizationUsageBreakdown). + ### sim organizations usage summary -Get Organization Usage Summary (OAuth login or personal API key required) +Get organization usage summary (OAuth login or personal API key required) ```bash sim organizations usage summary [options] @@ -3983,16 +4397,18 @@ sim organizations usage summary [options] | Option | Required | Description | | --- | --- | --- | | `--organization ` | Yes | Organization identifier. | -| `--preset ` | No | Reporting window. Custom requires startDate and endDate and is capped at 92 days; other presets reject those bounds. Resolved billing windows are capped at 366 days. Accepted values: `current-period`, `previous-period`, `7d`, `30d`, `custom`. | +| `--preset ` | No | Reporting window. Custom requires startDate and endDate and is capped at 92 days; other presets reject those bounds. Resolved billing windows are capped at 366 days. Defaults to "30d". Accepted values: `current-period`, `previous-period`, `7d`, `30d`, `custom`. | | `--start-date ` | No | First calendar date included, in the selected timezone. Requires preset=custom. | | `--end-date ` | No | Last calendar date included, in the selected timezone. Requires preset=custom. | | `--timezone ` | No | IANA timezone for calendar boundaries; defaults to UTC. | +API request and response schemas: [getOrganizationUsageSummary](/api-reference/organizations/getOrganizationUsageSummary). + ### sim organizations usage events -List Organization Usage Events (OAuth login or personal API key required) +List organization usage events (OAuth login or personal API key required) ```bash sim organizations usage events [options] @@ -4005,21 +4421,23 @@ sim organizations usage events [options] | Option | Required | Description | | --- | --- | --- | | `--organization ` | Yes | Organization identifier. | -| `--preset ` | No | Reporting window. Custom requires startDate and endDate and is capped at 92 days; other presets reject those bounds. Resolved billing windows are capped at 366 days. Accepted values: `current-period`, `previous-period`, `7d`, `30d`, `custom`. | +| `--preset ` | No | Reporting window. Custom requires startDate and endDate and is capped at 92 days; other presets reject those bounds. Resolved billing windows are capped at 366 days. Defaults to "30d". Accepted values: `current-period`, `previous-period`, `7d`, `30d`, `custom`. | | `--start-date ` | No | First calendar date included, in the selected timezone. Requires preset=custom. | | `--end-date ` | No | Last calendar date included, in the selected timezone. Requires preset=custom. | | `--timezone ` | No | IANA timezone for calendar boundaries; defaults to UTC. | | `--source ` | No | Restrict events to one product surface. Accepted values: `workflow`, `wand`, `sim-chat`, `mcp_copilot`, `mothership_block`, `knowledge-base`, `voice-input`, `enrichment`, `voice-output`, `api-tool`. | | `--limit ` | No | Maximum items to return (0 for everything). Defaults to `100`. | | `--cursor ` | No | Continue from nextCursor returned by a previous result. | -| `--sort-by ` | No | Field used to sort the result. Accepted values: `createdAt`. | -| `--sort-order ` | No | Sort direction. Accepted values: `asc`, `desc`. | +| `--sort-by ` | No | Field used to sort the result. Defaults to "createdAt". Accepted values: `createdAt`. | +| `--sort-order ` | No | Sort direction. Defaults to "desc". Accepted values: `asc`, `desc`. | +API request and response schemas: [listOrganizationUsageEvents](/api-reference/organizations/listOrganizationUsageEvents). + ### sim organizations list -List Organizations (OAuth login or personal API key required) +List organizations (OAuth login or personal API key required) ```bash sim organizations list [options] @@ -4032,15 +4450,17 @@ sim organizations list [options] | Option | Required | Description | | --- | --- | --- | | `--search ` | No | Case-insensitive substring match against the organization name. | -| `--sort-by ` | No | Field used to sort the result. Sorting by `name` is case-sensitive and follows the storage collation, so do not rely on a case-insensitive order. Accepted values: `name`, `createdAt`. | -| `--sort-order ` | No | Sort direction. Accepted values: `asc`, `desc`. | +| `--sort-by ` | No | Field used to sort the result. Do not rely on case-insensitive ordering when sorting by `name`. Defaults to "name". Accepted values: `name`, `createdAt`. | +| `--sort-order ` | No | Sort direction. Defaults to "asc". Accepted values: `asc`, `desc`. | | `--limit ` | No | Maximum items to return (0 for everything). Defaults to `0`. | +API request and response schemas: [listOrganizations](/api-reference/organizations/listOrganizations). + ### sim organizations workspaces -List Organization Workspaces (OAuth login or personal API key required) +List organization workspaces (OAuth login or personal API key required) ```bash sim organizations workspaces [options] @@ -4054,19 +4474,25 @@ sim organizations workspaces [options] | --- | --- | --- | | `--organization ` | Yes | Organization identifier. | | `--search ` | No | Case-insensitive substring match against the workspace name. | -| `--sort-by ` | No | Field used to sort the result. Sorting by `name` is case-sensitive and follows the storage collation, so do not rely on a case-insensitive order. Accepted values: `name`, `id`. | -| `--sort-order ` | No | Sort direction. Accepted values: `asc`, `desc`. | +| `--sort-by ` | No | Field used to sort the result. Do not rely on case-insensitive ordering when sorting by `name`. Defaults to "name". Accepted values: `name`, `id`. | +| `--sort-order ` | No | Sort direction. Defaults to "asc". Accepted values: `asc`, `desc`. | | `--limit ` | No | Maximum items to return (0 for everything). Defaults to `0`. | +API request and response schemas: [listOrganizationWorkspaces](/api-reference/organizations/listOrganizationWorkspaces). + ## sim permission-groups +Manage organization permission groups, their configuration, and member assignments. + +Use the linked API request schema for the supported `--config` keys. Supplied arrays replace their entire lists; omitted settings remain unchanged on update. + Also spelled `sim permission-group`. ### sim permission-groups members add -Add Permission Group Member (OAuth login or personal API key required) +Add permission group member (OAuth login or personal API key required) ```bash sim permission-groups members add [options] @@ -4084,9 +4510,11 @@ sim permission-groups members add [options] +API request and response schemas: [addPermissionGroupMember](/api-reference/permission-groups/addPermissionGroupMember). + ### sim permission-groups members batch-add -Bulk Add Permission Group Members (OAuth login or personal API key required) +Bulk add permission group members (OAuth login or personal API key required) ```bash sim permission-groups members batch-add [options] @@ -4105,9 +4533,11 @@ sim permission-groups members batch-add [options] +API request and response schemas: [bulkAddPermissionGroupMembers](/api-reference/permission-groups/bulkAddPermissionGroupMembers). + ### sim permission-groups members list -List Permission Group Members (OAuth login or personal API key required) +List permission group members (OAuth login or personal API key required) ```bash sim permission-groups members list [options] @@ -4121,15 +4551,19 @@ sim permission-groups members list [options] | --- | --- | --- | | `--organization ` | Yes | Organization identifier. | | `--group ` | Yes | Permission group identifier. | -| `--sort-by ` | No | Field used to sort the result. Accepted values: `assignedAt`, `userId`. | -| `--sort-order ` | No | Sort direction. Accepted values: `asc`, `desc`. | +| `--sort-by ` | No | Field used to sort the result. Defaults to "assignedAt". Accepted values: `assignedAt`, `userId`. | +| `--sort-order ` | No | Sort direction. Defaults to "asc". Accepted values: `asc`, `desc`. | | `--limit ` | No | Maximum items to return (0 for everything). Defaults to `0`. | +API request and response schemas: [listPermissionGroupMembers](/api-reference/permission-groups/listPermissionGroupMembers). + ### sim permission-groups members remove -Remove Permission Group Member (OAuth login or personal API key required) +Remove permission group member (OAuth login or personal API key required) + +This removes the member assignment and changes which permission groups apply to the user. ```bash sim permission-groups members remove [options] @@ -4157,9 +4591,11 @@ sim permission-groups members remove [options] +API request and response schemas: [removePermissionGroupMember](/api-reference/permission-groups/removePermissionGroupMember). + ### sim permission-groups create -Create Permission Group (OAuth login or personal API key required) +Create permission group (OAuth login or personal API key required) ```bash sim permission-groups create [options] @@ -4177,13 +4613,17 @@ sim permission-groups create [options] | `--config ` | No | Group settings to set. Omitted keys use the default permission configuration. (JSON, or @path / @- to read a file or stdin). | | `--default` | No | Whether the group is the organization default. Only one group can be the default. | | `--no-default` | No | Send --default as false. | -| `--workspace-ids ` | No | Workspace IDs targeted by a non-default group. Required when creating a non-default group; omit for a default group. (JSON, or @path / @- to read a file or stdin). | +| `--workspace-ids ` | Conditional | Workspace IDs targeted by a non-default group. Required when creating a non-default group; omit for a default group. (JSON, or @path / @- to read a file or stdin). | +API request and response schemas: [createPermissionGroup](/api-reference/permission-groups/createPermissionGroup). + ### sim permission-groups delete -Delete Permission Group (OAuth login or personal API key required) +Delete permission group (OAuth login or personal API key required) + +This permanently deletes the permission group and its member assignments. ```bash sim permission-groups delete [options] @@ -4210,9 +4650,11 @@ sim permission-groups delete [options] +API request and response schemas: [deletePermissionGroup](/api-reference/permission-groups/deletePermissionGroup). + ### sim permission-groups get -Get Permission Group (OAuth login or personal API key required) +Get permission group (OAuth login or personal API key required) ```bash sim permission-groups get [options] @@ -4238,9 +4680,11 @@ sim permission-groups get [options] +API request and response schemas: [getPermissionGroup](/api-reference/permission-groups/getPermissionGroup). + ### sim permission-groups list -List Permission Groups (OAuth login or personal API key required) +List permission groups (OAuth login or personal API key required) ```bash sim permission-groups list [options] @@ -4254,15 +4698,17 @@ sim permission-groups list [options] | --- | --- | --- | | `--organization ` | Yes | Organization identifier. | | `--search ` | No | Case-insensitive substring match against the group name. | -| `--sort-by ` | No | Field used to sort the result. Sorting by `name` is case-sensitive and follows the storage collation, so do not rely on a case-insensitive order. Accepted values: `name`, `createdAt`, `updatedAt`. | -| `--sort-order ` | No | Sort direction. Accepted values: `asc`, `desc`. | +| `--sort-by ` | No | Field used to sort the result. Do not rely on case-insensitive ordering when sorting by `name`. Defaults to "createdAt". Accepted values: `name`, `createdAt`, `updatedAt`. | +| `--sort-order ` | No | Sort direction. Defaults to "desc". Accepted values: `asc`, `desc`. | | `--limit ` | No | Maximum items to return (0 for everything). Defaults to `0`. | +API request and response schemas: [listPermissionGroups](/api-reference/permission-groups/listPermissionGroups). + ### sim permission-groups update -Update Permission Group (OAuth login or personal API key required) +Update permission group (OAuth login or personal API key required) ```bash sim permission-groups update [options] @@ -4294,13 +4740,17 @@ sim permission-groups update [options] +API request and response schemas: [updatePermissionGroup](/api-reference/permission-groups/updatePermissionGroup). + ## sim sandboxes +Manage reusable dependency sets for Function blocks. + Also spelled `sim sandbox`. ### sim sandboxes create -Create Sandbox (OAuth login or personal API key required) +Create sandbox (OAuth login or personal API key required) ```bash sim sandboxes create [options] @@ -4314,15 +4764,19 @@ sim sandboxes create [options] | --- | --- | --- | | `--name ` | Yes | Display name, unique within the workspace; 1 to 64 characters. | | `--language ` | Yes | Dependency ecosystem: `javascript` installs from npm, `python` from PyPI. Accepted values: `javascript`, `python`. | -| `--dependencies ` | No | Package specifiers installed into the sandbox, one per entry. (space-separated, or @path / @- with one value per line; in a file, blank lines and # comments are ignored, while inline values are sent as typed and may not be empty; @@value for a literal leading @). | -| `--cli-tools ` | No | Pinned managed CLI ids installed into the sandbox, at most 10, no duplicates. (space-separated, or @path / @- with one value per line; @@value for a literal leading @). | -| `--system-packages ` | No | Debian packages installed into the sandbox, one per entry. (space-separated, or @path / @- with one value per line; in a file, blank lines and # comments are ignored, while inline values are sent as typed and may not be empty; @@value for a literal leading @). | +| `--dependencies ` | No | Package specifiers installed into the sandbox, one per entry. Defaults to []. (space-separated, or @path / @- with one value per line; in a file, blank lines and # comments are ignored, while inline values are sent as typed and may not be empty; @@value for a literal leading @). | +| `--cli-tools ` | No | Pinned managed CLI ids installed into the sandbox, at most 10, no duplicates. Defaults to []. (space-separated, or @path / @- with one value per line; @@value for a literal leading @). | +| `--system-packages ` | No | Debian packages installed into the sandbox, one per entry. Defaults to []. (space-separated, or @path / @- with one value per line; in a file, blank lines and # comments are ignored, while inline values are sent as typed and may not be empty; @@value for a literal leading @). | +API request and response schemas: [createSandbox](/api-reference/sandboxes/createSandbox). + ### sim sandboxes delete -Delete Sandbox (OAuth login or personal API key required) +Delete sandbox (OAuth login or personal API key required) + +This deletes the sandbox; Function blocks that select it fail until re-pointed. ```bash sim sandboxes delete [options] @@ -4348,9 +4802,11 @@ sim sandboxes delete [options] +API request and response schemas: [deleteSandbox](/api-reference/sandboxes/deleteSandbox). + ### sim sandboxes get -Get Sandbox +Get sandbox ```bash sim sandboxes get @@ -4366,9 +4822,11 @@ sim sandboxes get +API request and response schemas: [getSandbox](/api-reference/sandboxes/getSandbox). + ### sim sandboxes list -List Sandboxes +List sandboxes ```bash sim sandboxes list [options] @@ -4381,15 +4839,17 @@ sim sandboxes list [options] | Option | Required | Description | | --- | --- | --- | | `--search ` | No | Case-insensitive substring match against the sandbox name. | -| `--sort-by ` | No | Field used to sort the result. Sorting by `name` is case-sensitive and follows the storage collation, so do not rely on a case-insensitive order. Accepted values: `name`, `createdAt`, `updatedAt`. | -| `--sort-order ` | No | Sort direction. Accepted values: `asc`, `desc`. | +| `--sort-by ` | No | Field used to sort the result. Do not rely on case-insensitive ordering when sorting by `name`. Defaults to "name". Accepted values: `name`, `createdAt`, `updatedAt`. | +| `--sort-order ` | No | Sort direction. Defaults to "asc". Accepted values: `asc`, `desc`. | | `--limit ` | No | Maximum items to return (0 for everything). Defaults to `0`. | +API request and response schemas: [listSandboxes](/api-reference/sandboxes/listSandboxes). + ### sim sandboxes update -Update Sandbox (OAuth login or personal API key required) +Update sandbox (OAuth login or personal API key required) ```bash sim sandboxes update [options] @@ -4419,13 +4879,21 @@ sim sandboxes update [options] +API request and response schemas: [updateSandbox](/api-reference/sandboxes/updateSandbox). + ## sim secrets +Set and manage workspace or personal secrets. + +Personal secrets belong to the caller across workspaces. Workspace secrets are shared resources. Listings include stored values only for workspace secrets marked visible (unredacted); all other entries contain metadata. + Also spelled `sim secret`. ### sim secrets delete -Delete Secret (OAuth login or personal API key required) +Delete secret (OAuth login or personal API key required) + +This deletes the secret; anything using it may stop working. ```bash sim secrets delete [options] @@ -4452,9 +4920,11 @@ sim secrets delete [options] +API request and response schemas: [deleteSecret](/api-reference/secrets/deleteSecret). + ### sim secrets list -List Secrets (OAuth login or personal API key required) +List secrets (OAuth login or personal API key required) ```bash sim secrets list [options] @@ -4468,12 +4938,14 @@ sim secrets list [options] | --- | --- | --- | | `--scope ` | No | Restrict results to one ownership scope. Accepted values: `workspace`, `personal`. | | `--search ` | No | Case-insensitive substring match against the secret name. | -| `--sort-by ` | No | Field used to sort the result. Sorting by `name` is case-sensitive and follows the storage collation, so do not rely on a case-insensitive order. Accepted values: `name`, `createdAt`, `updatedAt`. | -| `--sort-order ` | No | Sort direction. Accepted values: `asc`, `desc`. | +| `--sort-by ` | No | Field used to sort the result. Do not rely on case-insensitive ordering when sorting by `name`. Defaults to "name". Accepted values: `name`, `createdAt`, `updatedAt`. | +| `--sort-order ` | No | Sort direction. Defaults to "asc". Accepted values: `asc`, `desc`. | | `--limit ` | No | Maximum items to return (0 for everything). Defaults to `0`. | +API request and response schemas: [listSecrets](/api-reference/secrets/listSecrets). + ### sim secrets set Create or replace a named secret, such as an API key or environment variable (OAuth login or personal API key required) @@ -4506,11 +4978,19 @@ sim secrets set [options] +Omit --value to enter it privately in a terminal. For an existing workspace secret, passing only --description or a redaction flag keeps the stored value and does not prompt. Personal secrets always require a value; they accept no writable metadata. In scripts, pass --value @path or --value @-. + +API request and response schemas: [setSecret](/api-reference/secrets/setSecret). + ## sim selectors +Discover destination options for registered fields, such as calendars, channels, and tables. + +A selector key identifies the field’s option source. Its context accepts only declared dependencies; missing OAuth access requires a person to authorize the connection. + ### sim selectors get -Get Selector Option (OAuth login or personal API key required) +Get selector option (OAuth login or personal API key required) ```bash sim selectors get [options] @@ -4522,15 +5002,17 @@ sim selectors get [options] | Option | Required | Description | | --- | --- | --- | -| `--selector-key ` | Yes | Registered selector key for discovering this field’s destination options. Accepted values: `airtable.bases`, `airtable.tables`, `asana.workspaces`, `attio.lists`, `attio.objects`, `bigquery.datasets`, `bigquery.tables`, `bitbucket.workspaces`, `bitbucket.repositories`, `calcom.eventTypes`, `calcom.schedules`, `clickup.workspaces`, `clickup.spaces`, `clickup.folders`, `clickup.lists`, `coda.docs`, `coda.pages`, `coda.tables`, `coda.columns`, `coda.rows`, `coda.formulas`, `coda.controls`, `coda.folders`, `coda.permissions`, `confluence.spaces`, `confluence.spacesById`, `confluence.pages`, `google.tasks.lists`, `fivetran.groups`, `fivetran.connections`, `gmail.labels`, `google.calendar`, `google.drive`, `google.sheets`, `harmonic.savedSearches`, `hubspot.lists`, `hubspot.owners`, `hubspot.pipelines`, `hubspot.pipelineStages`, `hubspot.properties`, `jsm.requestTypes`, `jsm.serviceDesks`, `microsoft.planner.plans`, `notion.databases`, `notion.pages`, `netsuite.recordTypes`, `netsuite.asyncTasks`, `pipedrive.pipelines`, `sharepoint.lists`, `trello.boards`, `zoho_desk.organizations`, `zoho_desk.departments`, `zoho_desk.agents`, `zoom.meetings`, `slack.channels`, `snowflake.databases`, `snowflake.schemas`, `snowflake.tables`, `snowflake.warehouses`, `snowflake.roles`, `snowflake.fileFormats`, `snowflake.procedures`, `slack.users`, `outlook.folders`, `outlook.calendars`, `microsoft.teams`, `microsoft.chats`, `microsoft.channels`, `microsoft.planner`, `onedrive.files`, `onedrive.folders`, `sharepoint.sites`, `microsoft.excel`, `microsoft.excel.drives`, `microsoft.excel.sheets`, `microsoft.word`, `wealthbox.contacts`, `jira.issues`, `jira.projects`, `jira.projectKeys`, `linear.projects`, `linear.teams`, `monday.boards`, `monday.groups`, `webflow.sites`, `webflow.collections`, `webflow.items`, `planetscale.databases`, `powerbi.workspaces`, `powerbi.datasets`, `powerbi.reports`, `planetscale.branches`, `planetscale.backups`, `planetscale.deployRequests`, `cloudwatch.logGroups`, `cloudwatch.logStreams`, `imap.mailboxes`, `mcp.tools`, `managedAgent.agents`, `managedAgent.environments`, `managedAgent.vaults`, `managedAgent.memoryStores`, `knowledge.documents`, `sim.workflows`, `table.columns`, `table.outputColumns`, `workspace.secretNames`, `workspace.sandboxes`, `providers.ollamaEmbeddingModels`, `providers.openrouterEmbeddingModels`. | -| `--context ` | No | Only the dependencies declared by the selector, such as oauthCredential and channelId. Missing OAuth connections require human authorization. (JSON, or @path / @- to read a file or stdin). | -| `--id ` | Yes | Resource identifier. | +| `--selector-key ` | Yes | Registered selector key from an import or sync preview, such as `gmail.labels`. Accepted values: `airtable.bases`, `airtable.tables`, `asana.workspaces`, `attio.lists`, `attio.objects`, `bigquery.datasets`, `bigquery.tables`, `bitbucket.workspaces`, `bitbucket.repositories`, `calcom.eventTypes`, `calcom.schedules`, `clickup.workspaces`, `clickup.spaces`, `clickup.folders`, `clickup.lists`, `coda.docs`, `coda.pages`, `coda.tables`, `coda.columns`, `coda.rows`, `coda.formulas`, `coda.controls`, `coda.folders`, `coda.permissions`, `confluence.spaces`, `confluence.spacesById`, `confluence.pages`, `google.tasks.lists`, `fivetran.groups`, `fivetran.connections`, `gmail.labels`, `google.calendar`, `google.drive`, `google.sheets`, `harmonic.savedSearches`, `hubspot.lists`, `hubspot.owners`, `hubspot.pipelines`, `hubspot.pipelineStages`, `hubspot.properties`, `jsm.requestTypes`, `jsm.serviceDesks`, `microsoft.planner.plans`, `notion.databases`, `notion.pages`, `netsuite.recordTypes`, `netsuite.asyncTasks`, `pipedrive.pipelines`, `sharepoint.lists`, `trello.boards`, `zoho_desk.organizations`, `zoho_desk.departments`, `zoho_desk.agents`, `zoom.meetings`, `slack.channels`, `snowflake.databases`, `snowflake.schemas`, `snowflake.tables`, `snowflake.warehouses`, `snowflake.roles`, `snowflake.fileFormats`, `snowflake.procedures`, `slack.users`, `outlook.folders`, `outlook.calendars`, `microsoft.teams`, `microsoft.chats`, `microsoft.channels`, `microsoft.planner`, `onedrive.files`, `onedrive.folders`, `sharepoint.sites`, `microsoft.excel`, `microsoft.excel.drives`, `microsoft.excel.sheets`, `microsoft.word`, `wealthbox.contacts`, `jira.issues`, `jira.projects`, `jira.projectKeys`, `linear.projects`, `linear.teams`, `monday.boards`, `monday.groups`, `webflow.sites`, `webflow.collections`, `webflow.items`, `planetscale.databases`, `powerbi.workspaces`, `powerbi.datasets`, `powerbi.reports`, `planetscale.branches`, `planetscale.backups`, `planetscale.deployRequests`, `cloudwatch.logGroups`, `cloudwatch.logStreams`, `imap.mailboxes`, `mcp.tools`, `managedAgent.agents`, `managedAgent.environments`, `managedAgent.vaults`, `managedAgent.memoryStores`, `knowledge.documents`, `sim.workflows`, `table.columns`, `table.outputColumns`, `workspace.secretNames`, `workspace.sandboxes`, `providers.ollamaEmbeddingModels`, `providers.openrouterEmbeddingModels`. | +| `--context ` | No | Only the dependencies declared by the selector, such as oauthCredential and channelId. Missing OAuth connections require human authorization. Defaults to {}. (JSON, or @path / @- to read a file or stdin). | +| `--id ` | Yes | Provider option ID to resolve with the same selector and declared context. | +API request and response schemas: [getSelector](/api-reference/workspace-sync/getSelector). + ### sim selectors list -List Selector Options (OAuth login or personal API key required) +List selector options (OAuth login or personal API key required) ```bash sim selectors list [options] @@ -4542,21 +5024,25 @@ sim selectors list [options] | Option | Required | Description | | --- | --- | --- | -| `--selector-key ` | Yes | Registered selector key for discovering this field’s destination options. Accepted values: `airtable.bases`, `airtable.tables`, `asana.workspaces`, `attio.lists`, `attio.objects`, `bigquery.datasets`, `bigquery.tables`, `bitbucket.workspaces`, `bitbucket.repositories`, `calcom.eventTypes`, `calcom.schedules`, `clickup.workspaces`, `clickup.spaces`, `clickup.folders`, `clickup.lists`, `coda.docs`, `coda.pages`, `coda.tables`, `coda.columns`, `coda.rows`, `coda.formulas`, `coda.controls`, `coda.folders`, `coda.permissions`, `confluence.spaces`, `confluence.spacesById`, `confluence.pages`, `google.tasks.lists`, `fivetran.groups`, `fivetran.connections`, `gmail.labels`, `google.calendar`, `google.drive`, `google.sheets`, `harmonic.savedSearches`, `hubspot.lists`, `hubspot.owners`, `hubspot.pipelines`, `hubspot.pipelineStages`, `hubspot.properties`, `jsm.requestTypes`, `jsm.serviceDesks`, `microsoft.planner.plans`, `notion.databases`, `notion.pages`, `netsuite.recordTypes`, `netsuite.asyncTasks`, `pipedrive.pipelines`, `sharepoint.lists`, `trello.boards`, `zoho_desk.organizations`, `zoho_desk.departments`, `zoho_desk.agents`, `zoom.meetings`, `slack.channels`, `snowflake.databases`, `snowflake.schemas`, `snowflake.tables`, `snowflake.warehouses`, `snowflake.roles`, `snowflake.fileFormats`, `snowflake.procedures`, `slack.users`, `outlook.folders`, `outlook.calendars`, `microsoft.teams`, `microsoft.chats`, `microsoft.channels`, `microsoft.planner`, `onedrive.files`, `onedrive.folders`, `sharepoint.sites`, `microsoft.excel`, `microsoft.excel.drives`, `microsoft.excel.sheets`, `microsoft.word`, `wealthbox.contacts`, `jira.issues`, `jira.projects`, `jira.projectKeys`, `linear.projects`, `linear.teams`, `monday.boards`, `monday.groups`, `webflow.sites`, `webflow.collections`, `webflow.items`, `planetscale.databases`, `powerbi.workspaces`, `powerbi.datasets`, `powerbi.reports`, `planetscale.branches`, `planetscale.backups`, `planetscale.deployRequests`, `cloudwatch.logGroups`, `cloudwatch.logStreams`, `imap.mailboxes`, `mcp.tools`, `managedAgent.agents`, `managedAgent.environments`, `managedAgent.vaults`, `managedAgent.memoryStores`, `knowledge.documents`, `sim.workflows`, `table.columns`, `table.outputColumns`, `workspace.secretNames`, `workspace.sandboxes`, `providers.ollamaEmbeddingModels`, `providers.openrouterEmbeddingModels`. | -| `--context ` | No | Only the dependencies declared by the selector, such as oauthCredential and channelId. Missing OAuth connections require human authorization. (JSON, or @path / @- to read a file or stdin). | +| `--selector-key ` | Yes | Registered selector key from an import or sync preview, such as `gmail.labels`. Accepted values: `airtable.bases`, `airtable.tables`, `asana.workspaces`, `attio.lists`, `attio.objects`, `bigquery.datasets`, `bigquery.tables`, `bitbucket.workspaces`, `bitbucket.repositories`, `calcom.eventTypes`, `calcom.schedules`, `clickup.workspaces`, `clickup.spaces`, `clickup.folders`, `clickup.lists`, `coda.docs`, `coda.pages`, `coda.tables`, `coda.columns`, `coda.rows`, `coda.formulas`, `coda.controls`, `coda.folders`, `coda.permissions`, `confluence.spaces`, `confluence.spacesById`, `confluence.pages`, `google.tasks.lists`, `fivetran.groups`, `fivetran.connections`, `gmail.labels`, `google.calendar`, `google.drive`, `google.sheets`, `harmonic.savedSearches`, `hubspot.lists`, `hubspot.owners`, `hubspot.pipelines`, `hubspot.pipelineStages`, `hubspot.properties`, `jsm.requestTypes`, `jsm.serviceDesks`, `microsoft.planner.plans`, `notion.databases`, `notion.pages`, `netsuite.recordTypes`, `netsuite.asyncTasks`, `pipedrive.pipelines`, `sharepoint.lists`, `trello.boards`, `zoho_desk.organizations`, `zoho_desk.departments`, `zoho_desk.agents`, `zoom.meetings`, `slack.channels`, `snowflake.databases`, `snowflake.schemas`, `snowflake.tables`, `snowflake.warehouses`, `snowflake.roles`, `snowflake.fileFormats`, `snowflake.procedures`, `slack.users`, `outlook.folders`, `outlook.calendars`, `microsoft.teams`, `microsoft.chats`, `microsoft.channels`, `microsoft.planner`, `onedrive.files`, `onedrive.folders`, `sharepoint.sites`, `microsoft.excel`, `microsoft.excel.drives`, `microsoft.excel.sheets`, `microsoft.word`, `wealthbox.contacts`, `jira.issues`, `jira.projects`, `jira.projectKeys`, `linear.projects`, `linear.teams`, `monday.boards`, `monday.groups`, `webflow.sites`, `webflow.collections`, `webflow.items`, `planetscale.databases`, `powerbi.workspaces`, `powerbi.datasets`, `powerbi.reports`, `planetscale.branches`, `planetscale.backups`, `planetscale.deployRequests`, `cloudwatch.logGroups`, `cloudwatch.logStreams`, `imap.mailboxes`, `mcp.tools`, `managedAgent.agents`, `managedAgent.environments`, `managedAgent.vaults`, `managedAgent.memoryStores`, `knowledge.documents`, `sim.workflows`, `table.columns`, `table.outputColumns`, `workspace.secretNames`, `workspace.sandboxes`, `providers.ollamaEmbeddingModels`, `providers.openrouterEmbeddingModels`. | +| `--context ` | No | Only the dependencies declared by the selector, such as oauthCredential and channelId. Missing OAuth connections require human authorization. Defaults to {}. (JSON, or @path / @- to read a file or stdin). | | `--search ` | No | Provider option search text. | | `--cursor ` | No | Continue from nextCursor returned by a previous result. | | `--limit ` | No | Maximum items to return (0 for everything). Defaults to `100`. | +API request and response schemas: [listSelector](/api-reference/workspace-sync/listSelector). + ## sim skills +Create reusable agent instructions and manage their editors. + Also spelled `sim skill`. ### sim skills create -Create Skill (OAuth login or personal API key required) +Create skill (OAuth login or personal API key required) ```bash sim skills create [options] @@ -4574,9 +5060,13 @@ sim skills create [options] +API request and response schemas: [createSkill](/api-reference/skills/createSkill). + ### sim skills delete -Delete Skill (OAuth login or personal API key required) +Delete skill (OAuth login or personal API key required) + +This deletes the skill. ```bash sim skills delete [options] @@ -4602,9 +5092,11 @@ sim skills delete [options] +API request and response schemas: [deleteSkill](/api-reference/skills/deleteSkill). + ### sim skills get -Get Skill +Get skill ```bash sim skills get @@ -4620,9 +5112,11 @@ sim skills get +API request and response schemas: [getSkill](/api-reference/skills/getSkill). + ### sim skills editors create -Grant Skill Editor (OAuth login or personal API key required) +Grant skill editor (OAuth login or personal API key required) ```bash sim skills editors create [options] @@ -4648,9 +5142,11 @@ sim skills editors create [options] +API request and response schemas: [grantSkillEditor](/api-reference/skills/grantSkillEditor). + ### sim skills editors list -List Skill Editors +List skill editors ```bash sim skills editors list [options] @@ -4672,15 +5168,19 @@ sim skills editors list [options] | Option | Required | Description | | --- | --- | --- | -| `--sort-by ` | No | Field used to sort the result. Sorting by `name` is case-sensitive and follows the storage collation, so do not rely on a case-insensitive order. Accepted values: `email`, `name`. | -| `--sort-order ` | No | Sort direction. Accepted values: `asc`, `desc`. | +| `--sort-by ` | No | Field used to sort the result. Do not rely on case-insensitive ordering when sorting by `name`. Defaults to "email". Accepted values: `email`, `name`. | +| `--sort-order ` | No | Sort direction. Defaults to "asc". Accepted values: `asc`, `desc`. | | `--limit ` | No | Maximum items to return (0 for everything). Defaults to `0`. | +API request and response schemas: [listSkillEditors](/api-reference/skills/listSkillEditors). + ### sim skills editors delete -Revoke Skill Editor (OAuth login or personal API key required) +Revoke skill editor (OAuth login or personal API key required) + +This revokes the explicit skill editor grant for the selected email. ```bash sim skills editors delete [options] @@ -4707,9 +5207,11 @@ sim skills editors delete [options] +API request and response schemas: [revokeSkillEditor](/api-reference/skills/revokeSkillEditor). + ### sim skills list -List Skills +List skills ```bash sim skills list [options] @@ -4722,15 +5224,17 @@ sim skills list [options] | Option | Required | Description | | --- | --- | --- | | `--search ` | No | Case-insensitive substring match against the skill name. | -| `--sort-by ` | No | Field used to sort the result. Sorting by `name` is case-sensitive and follows the storage collation, so do not rely on a case-insensitive order. Accepted values: `name`, `createdAt`, `updatedAt`. | -| `--sort-order ` | No | Sort direction. Accepted values: `asc`, `desc`. | +| `--sort-by ` | No | Field used to sort the result. Do not rely on case-insensitive ordering when sorting by `name`. Defaults to "createdAt". Accepted values: `name`, `createdAt`, `updatedAt`. | +| `--sort-order ` | No | Sort direction. Defaults to "desc". Accepted values: `asc`, `desc`. | | `--limit ` | No | Maximum items to return (0 for everything). Defaults to `0`. | +API request and response schemas: [listSkills](/api-reference/skills/listSkills). + ### sim skills update -Update Skill (OAuth login or personal API key required) +Update skill (OAuth login or personal API key required) ```bash sim skills update [options] @@ -4758,13 +5262,17 @@ sim skills update [options] +API request and response schemas: [updateSkill](/api-reference/skills/updateSkill). + ## sim tables +Manage tables, rows, schemas, views, enrichment runs, imports, and exports. + Also spelled `sim table`. ### sim tables columns create -Add Column +Add column ```bash sim tables columns create [options] @@ -4790,9 +5298,13 @@ sim tables columns create [options] +API request and response schemas: [addTableColumn](/api-reference/tables/addTableColumn). + ### sim tables columns delete -Delete Column +Delete column + +This deletes the column and its values in every row. ```bash sim tables columns delete [options] @@ -4819,9 +5331,11 @@ sim tables columns delete [options] +API request and response schemas: [deleteTableColumn](/api-reference/tables/deleteTableColumn). + ### sim tables columns update -Update Column +Update column ```bash sim tables columns update [options] @@ -4848,9 +5362,11 @@ sim tables columns update [options] +API request and response schemas: [updateTableColumn](/api-reference/tables/updateTableColumn). + ### sim tables groups create -Add Workflow Group +Add workflow group ```bash sim tables groups create [options] @@ -4873,15 +5389,19 @@ sim tables groups create [options] | Option | Required | Description | | --- | --- | --- | | `--group ` | Yes | Workflow or enrichment producer definition. (JSON, or @path / @- to read a file or stdin). | -| `--output-columns ` | No | Columns to create for producer outputs. An entry naming a column the table already has attaches that column to the group instead of creating it (its `type` must match), and an output whose column already exists may omit its entry entirely — so `[]` attaches existing columns only. (JSON, or @path / @- to read a file or stdin). | -| `--auto-run` | No | Whether to schedule existing rows after group creation. | +| `--output-columns ` | No | Columns to create for producer outputs. An entry naming a column the table already has attaches that column to the group instead of creating it (its `type` must match), and an output whose column already exists may omit its entry entirely — so `[]` attaches existing columns only. Defaults to []. (JSON, or @path / @- to read a file or stdin). | +| `--auto-run` | No | Whether to schedule existing rows after group creation. Defaults to false. | | `--no-auto-run` | No | Send --auto-run as false. | +API request and response schemas: [addWorkflowGroup](/api-reference/tables/addTableWorkflowGroup). + ### sim tables groups delete -Delete Workflow Group +Delete workflow group + +This deletes the group AND its output columns with all of their row data; the workflow it pointed at is untouched. ```bash sim tables groups delete [options] @@ -4908,9 +5428,11 @@ sim tables groups delete [options] +API request and response schemas: [deleteWorkflowGroup](/api-reference/tables/deleteTableWorkflowGroup). + ### sim tables groups list -List Workflow Groups +List workflow groups ```bash sim tables groups list @@ -4926,9 +5448,11 @@ sim tables groups list +API request and response schemas: [listWorkflowGroups](/api-reference/tables/listTableWorkflowGroups). + ### sim tables groups update -Update Workflow Group +Update workflow group ```bash sim tables groups update [options] @@ -4965,9 +5489,13 @@ sim tables groups update [options] +API request and response schemas: [updateWorkflowGroup](/api-reference/tables/updateTableWorkflowGroup). + ### sim tables batch-delete -Bulk Delete Tables and Folders +Bulk delete tables and folders + +This archives the selected tables and folders, including their rows. Restore eligible tables with `tables restore`. ```bash sim tables batch-delete [options] @@ -4979,12 +5507,14 @@ sim tables batch-delete [options] | Option | Required | Description | | --- | --- | --- | -| `--table-ids ` | No | Tables to archive, by identifier. (JSON, or @path / @- to read a file or stdin). | +| `--table-ids ` | No | Tables to archive, by identifier. Defaults to []. (JSON, or @path / @- to read a file or stdin). | | `--folder ` | No | Folder path as shown in the app; the leading / is optional (space-separated, or @path / @- with one value per line; @@value for a literal leading @). | | `-y, --yes` | Yes | Confirm this operation. | +API request and response schemas: [bulkDeleteTables](/api-reference/tables/bulkDeleteTables). + ### sim tables rows update-each Apply a distinct patch to each listed row @@ -5013,9 +5543,11 @@ sim tables rows update-each [options] +API request and response schemas: [bulkUpdateTableRows](/api-reference/tables/bulkUpdateTableRows). + ### sim tables rows create -Create Rows +Create rows ```bash sim tables rows create [options] @@ -5042,9 +5574,13 @@ sim tables rows create [options] +API request and response schemas: [createTableRows](/api-reference/tables/createTableRows). + ### sim tables rows delete -Delete Row +Delete row + +This deletes the row. ```bash sim tables rows delete [options] @@ -5071,10 +5607,14 @@ sim tables rows delete [options] +API request and response schemas: [deleteTableRow](/api-reference/tables/deleteTableRow). + ### sim tables rows batch-delete Delete rows matching a filter, or an explicit list of ids +This deletes every matching row and cannot be undone. + ```bash sim tables rows batch-delete [options] ``` @@ -5102,9 +5642,11 @@ sim tables rows batch-delete [options] +API request and response schemas: [deleteTableRows](/api-reference/tables/deleteTableRows). + ### sim tables rows get -Get Row +Get row ```bash sim tables rows get [options] @@ -5127,14 +5669,16 @@ sim tables rows get [options] | Option | Required | Description | | --- | --- | --- | -| `--include-run-state` | No | Include per-workflow-group run state on the returned row. Off by default. | +| `--include-run-state` | No | Include per-workflow-group run outcomes on the row. Off by default. Run state above 2 MiB returns `413`; omit this option to read the row without run state. | | `--no-include-run-state` | No | Send --include-run-state as false. | +API request and response schemas: [getTableRow](/api-reference/tables/getTableRow). + ### sim tables rows list -List Rows +List rows ```bash sim tables rows list [options] @@ -5158,11 +5702,13 @@ sim tables rows list [options] | --- | --- | --- | | `--limit ` | No | Maximum items to return (0 for everything). Defaults to `100`. | | `--cursor ` | No | Continue from nextCursor returned by a previous result. | -| `--include-run-state` | No | Include per-workflow-group run state on every returned row. Off by default: run state is a separate sidecar read and its `blockErrors` are unbounded, so a full page carries it only when asked. Caps `limit` at 200. | +| `--include-run-state` | No | Include per-workflow-group run outcomes on every row. Off by default. Caps `limit` at 200. Run state above 2 MiB returns `413`; request fewer rows or omit run state. | | `--no-include-run-state` | No | Send --include-run-state as false. | +API request and response schemas: [listTableRows](/api-reference/tables/listTableRows). + ### sim tables rows query Query rows with a filter and sort @@ -5191,11 +5737,13 @@ sim tables rows query [options] | `--sort ` | No | Ordered sort keys: [{"field":"createdAt","direction":"desc"}] (direction: asc or desc) (JSON, or @path / @- to read a file or stdin). | | `--limit ` | No | Maximum items to return (0 for everything). Defaults to `100`. | | `--cursor ` | No | Continue from nextCursor returned by a previous result. | -| `--include-run-state` | No | Include per-workflow-group run state on every returned row. Off by default: run state is a separate sidecar read and its `blockErrors` are unbounded, so a full page carries it only when asked. Incompatible with `limit: 0`, and caps `limit` at 200. | +| `--include-run-state` | No | Include per-workflow-group run outcomes on every row. Off by default. Each request above 2 MiB of run state returns 413; request fewer rows or omit run state. CLI --limit 0 still fetches bounded pages. | | `--no-include-run-state` | No | Send --include-run-state as false. | +API request and response schemas: [queryRows](/api-reference/tables/queryTableRows). + ### sim tables rows count Count rows matching a filter @@ -5224,6 +5772,8 @@ sim tables rows count [options] +API request and response schemas: [queryRowsCount](/api-reference/tables/countTableRows). + ### sim tables rows enrich Run one row’s enrichment group @@ -5244,6 +5794,8 @@ sim tables rows enrich +API request and response schemas: [runRowEnrichment](/api-reference/tables/runRowEnrichment). + ### sim tables rows search Search cells for a value and return their coordinates @@ -5274,10 +5826,14 @@ sim tables rows search [options] +API request and response schemas: [searchTableRows](/api-reference/tables/searchTableRows). + ### sim tables rows batch-update Update every row matching a filter +This updates every matching row and cannot be undone. + ```bash sim tables rows batch-update [options] ``` @@ -5305,9 +5861,11 @@ sim tables rows batch-update [options] +API request and response schemas: [updateRowsByFilter](/api-reference/tables/updateTableRows). + ### sim tables rows update -Update Row +Update row ```bash sim tables rows update [options] @@ -5334,10 +5892,14 @@ sim tables rows update [options] +API request and response schemas: [updateTableRow](/api-reference/tables/updateTableRow). + ### sim tables dispatches cancel Cancel a running dispatch +This stops the dispatch. Cells already handed to the queue keep running — use `tables cancel-runs` to stop those. + ```bash sim tables dispatches cancel [options] ``` @@ -5363,6 +5925,8 @@ sim tables dispatches cancel [options] +API request and response schemas: [cancelTableDispatch](/api-reference/tables/cancelTableDispatch). + ### sim tables dispatches create Start a column or enrichment run @@ -5388,7 +5952,7 @@ sim tables dispatches create [options] | Option | Required | Description | | --- | --- | --- | | `--group-ids ` | Yes | Workflow or enrichment groups to run. (space-separated, or @path / @- with one value per line; @@value for a literal leading @). | -| `--run-mode ` | No | Whether to run all or only incomplete cells. Accepted values: `all`, `incomplete`. | +| `--run-mode ` | No | Whether to run all or only incomplete cells. Defaults to "all". Accepted values: `all`, `incomplete`. | | `--row-ids ` | No | Explicit row subset to run. (space-separated, or @path / @- with one value per line; @@value for a literal leading @). | | `--filter ` | No | Predicate: {"all":[{"field":"status","op":"eq","value":"active"}]}; groups use all/any. Operators: eq, ne, gt, gte, lt, lte, in, nin, contains, ncontains, startsWith, endsWith, like, ilike, nlike, nilike, isEmpty, isNotEmpty, isNull, isNotNull (JSON, or @path / @- to read a file or stdin). | | `--exclude-row-ids ` | No | Rows excluded from a select-all run scope. (space-separated, or @path / @- with one value per line; @@value for a literal leading @). | @@ -5396,9 +5960,11 @@ sim tables dispatches create [options] +API request and response schemas: [createTableDispatch](/api-reference/tables/createTableDispatch). + ### sim tables dispatches get -Get Run Dispatch +Get run dispatch ```bash sim tables dispatches get @@ -5415,9 +5981,11 @@ sim tables dispatches get +API request and response schemas: [getTableDispatch](/api-reference/tables/getTableDispatch). + ### sim tables dispatches list -List Run Dispatches +List run dispatches ```bash sim tables dispatches list @@ -5433,6 +6001,8 @@ sim tables dispatches list +API request and response schemas: [listTableDispatches](/api-reference/tables/listTableDispatches). + ### sim tables exports cancel Stop a running export @@ -5452,9 +6022,11 @@ sim tables exports cancel +API request and response schemas: [cancelTableExport](/api-reference/tables/cancelTableExport). + ### sim tables exports create -Create Table Export +Create table export ```bash sim tables exports create [options] @@ -5476,13 +6048,15 @@ sim tables exports create [options] | Option | Required | Description | | --- | --- | --- | -| `--format ` | No | Export file format. Accepted values: `csv`, `json`. | +| `--format ` | No | Export file format. Defaults to "csv". Accepted values: `csv`, `json`. | +API request and response schemas: [createTableExport](/api-reference/tables/createTableExport). + ### sim tables exports get -Get Table Export +Get table export ```bash sim tables exports get @@ -5499,6 +6073,8 @@ sim tables exports get +API request and response schemas: [getTableExport](/api-reference/tables/getTableExport). + ### sim tables exports download Get the download URL for a finished export @@ -5518,10 +6094,14 @@ sim tables exports download +API request and response schemas: [tableExportDownload](/api-reference/tables/downloadTableExport). + ### sim tables imports cancel Stop a running import +This stops the import between row batches, so whatever it already wrote stays and nothing resumes it. A replace import empties the table before its first batch, so cancelling one leaves only part of the new file; an append adds its rows again if you import the file a second time. + ```bash sim tables imports cancel [options] ``` @@ -5546,9 +6126,11 @@ sim tables imports cancel [options] +API request and response schemas: [cancelTableImport](/api-reference/tables/cancelTableImport). + ### sim tables imports get -Get Table Import +Get table import ```bash sim tables imports get @@ -5564,10 +6146,14 @@ sim tables imports get +API request and response schemas: [getTableImport](/api-reference/tables/getTableImport). + ### sim tables cancel-runs Stop every running column job +This cancels running column jobs — the whole table with --scope all, one row with --scope row. + ```bash sim tables cancel-runs [options] ``` @@ -5596,9 +6182,11 @@ sim tables cancel-runs [options] +API request and response schemas: [cancelTableRuns](/api-reference/tables/cancelTableRuns). + ### sim tables create -Create Table +Create table ```bash sim tables create [options] @@ -5617,6 +6205,8 @@ sim tables create [options] +API request and response schemas: [createTable](/api-reference/tables/createTable). + ### sim tables folders create Create a table folder at a path @@ -5635,9 +6225,13 @@ sim tables folders create +API request and response schemas: [createTableFolder](/api-reference/tables/createTablesFolder). + ### sim tables folders delete -Delete Folder +Delete folder + +This archives the table folder and, when recursive, everything inside it. ```bash sim tables folders delete [options] @@ -5659,11 +6253,13 @@ sim tables folders delete [options] | Option | Required | Description | | --- | --- | --- | -| `--recursive` | No | Delete the folder and its descendants. | +| `--recursive` | No | Archive the folder and its descendants. Defaults to "false". | | `-y, --yes` | Yes | Confirm this operation. | +API request and response schemas: [deleteTableFolder](/api-reference/tables/deleteTablesFolder). + ### sim tables folders list List table folders @@ -5682,11 +6278,13 @@ Also available as `sim tables folders ls`. | --- | --- | --- | | `--parent ` | No | Direct parent folder path. | | `--search ` | No | Case-insensitive substring match against the folder name. | -| `--sort-by ` | No | Field used to sort the result. Sorting by `name` is case-sensitive and follows the storage collation, so do not rely on a case-insensitive order. Accepted values: `name`, `createdAt`, `updatedAt`. | -| `--sort-order ` | No | Sort direction. Accepted values: `asc`, `desc`. | +| `--sort-by ` | No | Field used to sort the result. Do not rely on case-insensitive ordering when sorting by `name`. Defaults to "name". Accepted values: `name`, `createdAt`, `updatedAt`. | +| `--sort-order ` | No | Sort direction. Defaults to "asc". Accepted values: `asc`, `desc`. | +API request and response schemas: [listTableFolders](/api-reference/tables/listTablesFolders). + ### sim tables folders move Rename or move a table folder @@ -5708,6 +6306,8 @@ Also available as `sim tables folders mv`. +API request and response schemas: [relocateTableFolder](/api-reference/tables/relocateTablesFolder). + ### sim tables folders restore Restore an archived table folder @@ -5726,9 +6326,11 @@ sim tables folders restore +API request and response schemas: [restoreTableFolder](/api-reference/tables/restoreTablesFolder). + ### sim tables views create -Create View +Create view ```bash sim tables views create [options] @@ -5755,9 +6357,13 @@ sim tables views create [options] +API request and response schemas: [createTableView](/api-reference/tables/createTableView). + ### sim tables views delete -Delete View +Delete view + +This deletes the saved view and its filters. ```bash sim tables views delete [options] @@ -5784,9 +6390,11 @@ sim tables views delete [options] +API request and response schemas: [deleteTableView](/api-reference/tables/deleteTableView). + ### sim tables views get -Get View +Get view ```bash sim tables views get @@ -5803,9 +6411,11 @@ sim tables views get +API request and response schemas: [getTableView](/api-reference/tables/getTableView). + ### sim tables views list -List Views +List views ```bash sim tables views list @@ -5821,9 +6431,11 @@ sim tables views list +API request and response schemas: [listTableViews](/api-reference/tables/listTableViews). + ### sim tables views update -Update View +Update view ```bash sim tables views update [options] @@ -5854,9 +6466,13 @@ sim tables views update [options] +API request and response schemas: [updateTableView](/api-reference/tables/updateTableView). + ### sim tables delete -Delete Table +Delete table + +This archives the table and all of its rows; restore with `tables restore`. ```bash sim tables delete [options] @@ -5882,9 +6498,11 @@ sim tables delete [options] +API request and response schemas: [deleteTable](/api-reference/tables/deleteTable). + ### sim tables enrichment get -Get Row Group Run +Get row group run ```bash sim tables enrichment get @@ -5902,9 +6520,11 @@ sim tables enrichment get +API request and response schemas: [getRowEnrichment](/api-reference/tables/getRowEnrichment). + ### sim tables get -Get Table +Get table ```bash sim tables get @@ -5920,9 +6540,11 @@ sim tables get +API request and response schemas: [getTable](/api-reference/tables/getTable). + ### sim tables list -List Tables +List tables ```bash sim tables list [options] @@ -5937,15 +6559,17 @@ sim tables list [options] | `--scope ` | No | Which lifecycle set to list: `active` (default) for live tables, `archived` for tables a delete archived and a table restore can bring back. `folderPath` resolves against active folders only, so pairing it with `scope=archived` returns an empty page when the containing folder was archived too. Accepted values: `active`, `archived`. | | `--folder ` | No | Folder path as shown in the app; the leading / is optional. | | `--search ` | No | Case-insensitive substring match against the resource name. | -| `--sort-by ` | No | Field used to sort the result. Sorting by `name` is case-sensitive and follows the storage collation, so do not rely on a case-insensitive order. Accepted values: `name`, `createdAt`, `updatedAt`. | -| `--sort-order ` | No | Sort direction. Accepted values: `asc`, `desc`. | +| `--sort-by ` | No | Field used to sort the result. Do not rely on case-insensitive ordering when sorting by `name`. Defaults to "createdAt". Accepted values: `name`, `createdAt`, `updatedAt`. | +| `--sort-order ` | No | Sort direction. Defaults to "asc". Accepted values: `asc`, `desc`. | | `--limit ` | No | Maximum items to return (0 for everything). Defaults to `0`. | +API request and response schemas: [listTables](/api-reference/tables/listTables). + ### sim tables move -Move Tables and Folders +Move tables and folders ```bash sim tables move [options] @@ -5957,12 +6581,14 @@ sim tables move [options] | Option | Required | Description | | --- | --- | --- | -| `--table-ids ` | No | Tables to move, by identifier. (JSON, or @path / @- to read a file or stdin). | +| `--table-ids ` | No | Tables to move, by identifier. Defaults to []. (JSON, or @path / @- to read a file or stdin). | | `--folder ` | No | Table folders to move, by path as shown in the app; the leading / is optional (space-separated, or @path / @- with one value per line; @@value for a literal leading @). | | `--to ` | No | Destination folder path; omit for root. | +API request and response schemas: [moveTables](/api-reference/tables/moveTables). + ### sim tables restore Restore an archived table @@ -5981,9 +6607,11 @@ sim tables restore +API request and response schemas: [restoreTable](/api-reference/tables/restoreTable). + ### sim tables update -Update Table +Update table ```bash sim tables update [options] @@ -6011,6 +6639,8 @@ sim tables update [options] +API request and response schemas: [updateTable](/api-reference/tables/updateTable). + ### sim tables mv Move a table to a folder @@ -6030,9 +6660,11 @@ sim tables mv +API request and response schemas: [updateTable](/api-reference/tables/updateTable). + ### sim tables upsert -Insert a row, or update the one that conflicts on a unique column +Insert a row, or replace the one matching a unique column ```bash sim tables upsert [options] @@ -6059,10 +6691,18 @@ sim tables upsert [options] +API request and response schemas: [upsertTableRow](/api-reference/tables/upsertTableRow). + ### sim tables import Import a CSV, into a new table by default +Choose exactly one source: a local CSV path or `--file-id`. For a new table imported with `--file-id`, supply `--name`. With `--table-id`, omit the new-table `--name` and `--folder` flags; `--mode`, `--mapping`, and `--create-columns` apply only to an existing table. + +**Replace mode deletes all existing rows before loading the CSV and cannot be undone.** It requires `--yes`; cancellation leaves only the rows already imported. + +The command watches the import by default. `--no-wait` returns a queued receipt. A completed import can still report `rowsRejected`, `cellsRejected`, and `rejectedSamples`; inspect them before accepting the result. + ```bash sim tables import [path] [options] ``` @@ -6073,7 +6713,7 @@ sim tables import [path] [options] | Argument | Required | Description | | --- | --- | --- | -| `path` | No | Local CSV file to import; omit when using --file-id | +| `path` | No | Local CSV file to import; choose exactly one source: this path or --file-id | @@ -6083,7 +6723,7 @@ sim tables import [path] [options] | Option | Required | Description | | --- | --- | --- | -| `--name ` | No | Identifier for the new table: letters, numbers, and underscores; defaults to the sanitized file name. | +| `--name ` | Conditional | Name for a new table: letters, numbers, and underscores. A local CSV defaults to its sanitized filename; required with --file-id unless --table-id names an existing table. | | `--table-id ` | No | Import into this existing table instead of creating one. | | `--mode ` | No | How to write into --table-id (default: append). Accepted values: `append`, `replace`. | | `--folder ` | No | Folder path for the new table, as shown in the app. | @@ -6091,11 +6731,13 @@ sim tables import [path] [options] | `--mapping ` | No | Column mapping (--table-id only). | | `--create-columns ` | No | Columns to create (--table-id only). | | `--timezone ` | No | Timezone for date parsing, e.g. America/New_York. | -| `-y, --yes` | No | Confirm this destructive operation (required with --mode replace). | +| `-y, --yes` | Conditional | Confirm this destructive operation (required with --mode replace). | | `--no-wait` | No | Return once the import is queued instead of watching it. | +API request and response schemas: [createTableImport](/api-reference/tables/createTableImport), [createTableImportPartUrls](/api-reference/tables/createTableImportPartUrls), [completeTableImport](/api-reference/tables/completeTableImportUpload), [cancelTableImport](/api-reference/tables/cancelTableImport), [getTableImport](/api-reference/tables/getTableImport). + ### sim tables ls List table resources and child folders together @@ -6125,6 +6767,8 @@ sim tables ls [path] [options] +API request and response schemas: [listTables](/api-reference/tables/listTables), [listTableFolders](/api-reference/tables/listTablesFolders). + ### sim tables mkdir Create a table directory at a path @@ -6143,8 +6787,14 @@ sim tables mkdir +API request and response schemas: [createTableFolder](/api-reference/tables/createTablesFolder). + ## sim tools +Find built-in tools, inspect their parameters, and run them. + +Inspect a tool with `sim tools get ` before passing its parameters to `sim tools execute`. + ### sim tools execute Run one built-in tool and print what it produced (OAuth login or personal API key required) @@ -6159,7 +6809,7 @@ sim tools execute [options] | Argument | Required | Description | | --- | --- | --- | -| `toolId` | Yes | Tool identifier. An unversioned name resolves to the newest version, and the response echoes the resolved id. | +| `toolId` | Yes | Tool identifier. An exact visible ID is retained; an unversioned name resolves to the newest visible family version. The response echoes the resolved ID. | @@ -6169,15 +6819,17 @@ sim tools execute [options] | Option | Required | Description | | --- | --- | --- | -| `--input ` | No | Tool arguments as JSON, keyed by the parameter ids `sim tools get <toolId>` lists (JSON, or @path / @- to read a file or stdin). | +| `--input ` | No | Tool arguments as JSON, keyed by the parameter ids `sim tools get ` lists. Defaults to {}. (JSON, or @path / @- to read a file or stdin). | | `--credential-id ` | No | Credential to authenticate with, required for OAuth tools. | | `--timeout ` | No | Seconds to wait before abandoning the call. | +API request and response schemas: [executeTool](/api-reference/catalog/executeTool). + ### sim tools get -Get Tool +Get tool ```bash sim tools get @@ -6189,13 +6841,15 @@ sim tools get | Argument | Required | Description | | --- | --- | --- | -| `toolId` | Yes | Tool identifier. An unversioned name resolves to the newest version, and the response echoes the resolved id. | +| `toolId` | Yes | Tool identifier. An exact visible ID is retained; an unversioned name resolves to the newest visible family version. The response echoes the resolved ID. | +API request and response schemas: [getTool](/api-reference/catalog/getTool). + ### sim tools list -List Tools +List tools ```bash sim tools list [options] @@ -6210,17 +6864,23 @@ sim tools list [options] | `--search ` | No | Case-insensitive substring match against the tool id, name, and description. | | `--hosted-api-key ` | No | Restrict to tools by how their API key is supplied. Accepted values: `always`, `conditional`, `none`. | | `--oauth-provider ` | No | Restrict to tools that authenticate against this OAuth service. | -| `--sort-by ` | No | Field used to sort the result. Sorting by `name` is case-sensitive and follows the storage collation, so do not rely on a case-insensitive order. Accepted values: `id`, `name`. | -| `--sort-order ` | No | Sort direction. Accepted values: `asc`, `desc`. | +| `--sort-by ` | No | Field used to sort the result. Do not rely on case-insensitive ordering when sorting by `name`. Defaults to "id". Accepted values: `id`, `name`. | +| `--sort-order ` | No | Sort direction. Defaults to "asc". Accepted values: `asc`, `desc`. | | `--limit ` | No | Maximum items to return (0 for everything). Defaults to `0`. | +API request and response schemas: [listTools](/api-reference/catalog/listTools). + ## sim workflow-mcp-servers +Serve deployed workflows as tools for Model Context Protocol (MCP) clients. + +These servers expose Sim workflows. To connect a server that provides external tools, use [MCP servers](/cli/mcp-servers). + ### sim workflow-mcp-servers create -Create Workflow MCP Server (OAuth login or personal API key required) +Create workflow MCP server (OAuth login or personal API key required) ```bash sim workflow-mcp-servers create [options] @@ -6234,15 +6894,19 @@ sim workflow-mcp-servers create [options] | --- | --- | --- | | `--name ` | Yes | Server display name, shown to connecting MCP clients. | | `--description ` | No | Optional server description. | -| `--is-public` | No | Whether the server answers MCP clients without a Sim API key. Defaults to false — a public server executes the workflows it publishes for anyone holding its URL. | +| `--is-public` | No | Whether the server accepts MCP clients without a Sim API key. Defaults to false; a public server lets anyone holding its URL execute the workflows it exposes. | | `--no-is-public` | No | Send --is-public as false. | -| `--workflow ` | No | Deployed workflows to publish as tools on the new server. (space-separated, or @path / @- with one value per line; @@value for a literal leading @). | +| `--workflow ` | No | Deployed workflows to expose as MCP tools on the new server. (space-separated, or @path / @- with one value per line; @@value for a literal leading @). | +API request and response schemas: [createWorkflowMcpServer](/api-reference/mcp-servers/createWorkflowMcpServer). + ### sim workflow-mcp-servers delete -Delete Workflow MCP Server (OAuth login or personal API key required) +Delete workflow MCP server (OAuth login or personal API key required) + +This deletes the MCP server, and any agent calling its tools loses access. ```bash sim workflow-mcp-servers delete [options] @@ -6268,9 +6932,11 @@ sim workflow-mcp-servers delete [options] +API request and response schemas: [deleteWorkflowMcpServer](/api-reference/mcp-servers/deleteWorkflowMcpServer). + ### sim workflow-mcp-servers tools create -Publish Workflow As MCP Tool (OAuth login or personal API key required) +Deploy workflow as MCP tool (OAuth login or personal API key required) ```bash sim workflow-mcp-servers tools create [options] @@ -6292,16 +6958,18 @@ sim workflow-mcp-servers tools create [options] | Option | Required | Description | | --- | --- | --- | -| `--workflow-id ` | Yes | Deployed workflow to publish. The workflow must already be deployed. | +| `--workflow-id ` | Yes | Workflow to expose as an MCP tool. It must already be deployed. | | `--tool-name ` | No | Name MCP clients call. Normalized to the MCP tool-name grammar, and derived from the workflow name when omitted. | | `--tool-description ` | No | Description shown to MCP clients. Derived from the workflow name when omitted. | | `--parameter-descriptions ` | No | Per-field description overrides applied to the schema generated from the deployed workflow inputs, as [{"name":"email","description":"Customer email address"}]. A name matching no input field is ignored (JSON, or @path / @- to read a file or stdin). | +API request and response schemas: [deployWorkflowMcpTool](/api-reference/mcp-servers/deployWorkflowMcpTool). + ### sim workflow-mcp-servers tools list -List Workflow MCP Tools (OAuth login or personal API key required) +List workflow MCP tools (OAuth login or personal API key required) ```bash sim workflow-mcp-servers tools list @@ -6317,9 +6985,13 @@ sim workflow-mcp-servers tools list +API request and response schemas: [listWorkflowMcpTools](/api-reference/mcp-servers/listWorkflowMcpTools). + ### sim workflow-mcp-servers tools delete -Unpublish Workflow MCP Tool (OAuth login or personal API key required) +Undeploy workflow MCP tool (OAuth login or personal API key required) + +This withdraws the tool, and any agent calling it loses access. ```bash sim workflow-mcp-servers tools delete [options] @@ -6332,7 +7004,7 @@ sim workflow-mcp-servers tools delete [options] | Argument | Required | Description | | --- | --- | --- | | `serverId` | Yes | Unique workflow-MCP server identifier. | -| `workflowId` | Yes | Workflow published as a tool on this server. | +| `workflowId` | Yes | Workflow registered as an MCP tool on this server. | @@ -6346,9 +7018,11 @@ sim workflow-mcp-servers tools delete [options] +API request and response schemas: [undeployWorkflowMcpTool](/api-reference/mcp-servers/undeployWorkflowMcpTool). + ### sim workflow-mcp-servers get -Get Workflow MCP Server (OAuth login or personal API key required) +Get workflow MCP server (OAuth login or personal API key required) ```bash sim workflow-mcp-servers get @@ -6364,9 +7038,11 @@ sim workflow-mcp-servers get +API request and response schemas: [getWorkflowMcpServer](/api-reference/mcp-servers/getWorkflowMcpServer). + ### sim workflow-mcp-servers list -List Workflow MCP Servers (OAuth login or personal API key required) +List workflow MCP servers (OAuth login or personal API key required) ```bash sim workflow-mcp-servers list [options] @@ -6378,15 +7054,17 @@ sim workflow-mcp-servers list [options] | Option | Required | Description | | --- | --- | --- | -| `--sort-by ` | No | Field used to sort the result. Sorting by `name` is case-sensitive and follows the storage collation, so do not rely on a case-insensitive order. Accepted values: `name`, `createdAt`, `updatedAt`. | -| `--sort-order ` | No | Sort direction. Accepted values: `asc`, `desc`. | +| `--sort-by ` | No | Field used to sort the result. Do not rely on case-insensitive ordering when sorting by `name`. Defaults to "createdAt". Accepted values: `name`, `createdAt`, `updatedAt`. | +| `--sort-order ` | No | Sort direction. Defaults to "desc". Accepted values: `asc`, `desc`. | | `--limit ` | No | Maximum items to return (0 for everything). Defaults to `0`. | +API request and response schemas: [listWorkflowMcpServers](/api-reference/mcp-servers/listWorkflowMcpServers). + ### sim workflow-mcp-servers update -Update Workflow MCP Server (OAuth login or personal API key required) +Update workflow MCP server (OAuth login or personal API key required) ```bash sim workflow-mcp-servers update [options] @@ -6415,13 +7093,19 @@ sim workflow-mcp-servers update [options] +API request and response schemas: [updateWorkflowMcpServer](/api-reference/mcp-servers/updateWorkflowMcpServer). + ## sim workflows +Build, deploy, run, and inspect workflows from the terminal. + Also spelled `sim workflow`. ### sim workflows activate create -Activate Workflow Version (OAuth login or personal API key required) +Activate workflow version (OAuth login or personal API key required) + +This changes which deployed version runs in production for every API and chat consumer. ```bash sim workflows activate create [options] @@ -6448,10 +7132,14 @@ sim workflows activate create [options] +API request and response schemas: [activateWorkflowVersion](/api-reference/workflows/activateWorkflowVersion). + ### sim workflows operations apply Edit a workflow’s blocks, connections and settings with a batch of operations (OAuth login or personal API key required) +This edits the draft graph: the batch adds, edits, or deletes blocks and their edges as written. + ```bash sim workflows operations apply [options] ``` @@ -6479,13 +7167,17 @@ sim workflows operations apply [options] | `--no-atomic` | No | Send --atomic as false. | | `--layout ` | No | Whether to reposition blocks the batch touched. `targeted` (default) nudges only the affected subgraph; `none` leaves every position exactly as supplied. Accepted values: `targeted`, `none`. | | `--set-block-enabled ` | No | Blocks to enable or disable, applied after --operations: [{"block_id":"<uuid>","enabled":false}]. Disabling a loop or parallel cascades to its unlocked descendants; enabling a block whose container is disabled is declined (JSON, or @path / @- to read a file or stdin). | -| `-y, --yes` | No | Confirm this operation (required unless --dry-run). | +| `-y, --yes` | Conditional | Confirm this operation (required unless --dry-run). | +API request and response schemas: [applyWorkflowOperations](/api-reference/workflows/applyWorkflowOperations). + ### sim workflows variables update -Update Workflow Variables +Update workflow variables + +This applies the listed variable changes; variables omitted from the operations remain unchanged. ```bash sim workflows variables update [options] @@ -6512,10 +7204,14 @@ sim workflows variables update [options] +API request and response schemas: [applyWorkflowVariables](/api-reference/workflows/applyWorkflowVariables). + ### sim workflows runs cancel Cancel a running workflow run +Canceling a paused run prevents resuming that run. Starting a new run can repeat side effects already performed. + ```bash sim workflows runs cancel [options] ``` @@ -6540,6 +7236,8 @@ sim workflows runs cancel [options] +API request and response schemas: [cancelWorkflowRun](/api-reference/workflow-runs/cancelRunV2). + ### sim workflows runs get Show run status (requested outputs are included in JSON or YAML output) @@ -6573,6 +7271,8 @@ sim workflows runs get [options] +API request and response schemas: [getWorkflowRun](/api-reference/workflow-runs/getWorkflowRunV2). + ### sim workflows runs list List runs for a workflow @@ -6594,10 +7294,12 @@ sim workflows runs list [options] | `--end-date ` | No | Only include runs started at or before this UTC ISO 8601 timestamp, e.g. `2026-08-06T00:00:00Z`. A date without a time, or a timestamp carrying a UTC offset instead of `Z`, is rejected, as is year `0000`, which names no storable instant. | | `--limit ` | No | Maximum items to return (0 for everything). Defaults to `100`. | | `--cursor ` | No | Continue from nextCursor returned by a previous result. | -| `--order ` | No | Sort direction by run start time. This list is sortable only by run start time, so it takes `order` in place of `sortBy`/`sortOrder`, which it rejects. Accepted values: `asc`, `desc`. | +| `--order ` | No | Sort direction by run start time. This list is sortable only by run start time, so it takes `order` in place of `sortBy`/`sortOrder`, which it rejects. Defaults to "desc". Accepted values: `asc`, `desc`. | +API request and response schemas: [listWorkflowRuns](/api-reference/workflow-runs/listWorkflowRunsV2). + ### sim workflows runs resume Resume a paused run (output is included in JSON or YAML output) @@ -6628,9 +7330,11 @@ sim workflows runs resume [options] +API request and response schemas: [resumeWorkflow](/api-reference/workflow-runs/resumeWorkflowRunV2). + ### sim workflows runs wait -Wait for a run to reach a terminal state, then show it +Wait until a run finishes or needs input ```bash sim workflows runs wait [options] @@ -6657,9 +7361,13 @@ sim workflows runs wait [options] +Exit codes: 0 completed, 1 failed, 2 cancelled, 3 needs input, 4 timed out. Time-based pauses continue waiting; a human pause or an unspecified pause kind ends the wait with code 3. Use `sim workflows runs resume` with the pause context to continue. + +API request and response schemas: [getWorkflowRun](/api-reference/workflow-runs/getWorkflowRunV2). + ### sim workflows versions compare -Compare Workflow Versions +Compare workflow versions ```bash sim workflows versions compare [options] @@ -6686,9 +7394,11 @@ sim workflows versions compare [options] +API request and response schemas: [compareWorkflowVersions](/api-reference/workflows/compareWorkflowVersionsV2). + ### sim workflows versions get -Get Workflow Version +Get workflow version ```bash sim workflows versions get @@ -6705,9 +7415,11 @@ sim workflows versions get +API request and response schemas: [getWorkflowVersion](/api-reference/workflows/getWorkflowVersionV2). + ### sim workflows versions list -List Workflow Versions +List workflow versions ```bash sim workflows versions list [options] @@ -6734,9 +7446,11 @@ sim workflows versions list [options] +API request and response schemas: [listWorkflowVersions](/api-reference/workflows/listWorkflowVersionsV2). + ### sim workflows versions update -Update Workflow Version +Update workflow version ```bash sim workflows versions update [options] @@ -6764,9 +7478,11 @@ sim workflows versions update [options] +API request and response schemas: [updateWorkflowVersion](/api-reference/workflows/updateWorkflowVersionV2). + ### sim workflows create -Create Workflow +Create workflow ```bash sim workflows create [options] @@ -6784,6 +7500,8 @@ sim workflows create [options] +API request and response schemas: [createWorkflow](/api-reference/workflows/createWorkflowV2). + ### sim workflows folders create Create a workflow folder at a path @@ -6802,9 +7520,13 @@ sim workflows folders create +API request and response schemas: [createWorkflowFolder](/api-reference/workflows/createWorkflowsFolder). + ### sim workflows folders delete -Delete Workflow Folder +Delete workflow folder + +This archives the workflow folder and, when recursive, everything inside it. ```bash sim workflows folders delete [options] @@ -6826,11 +7548,13 @@ sim workflows folders delete [options] | Option | Required | Description | | --- | --- | --- | -| `--recursive` | No | Delete the folder and its descendants. | +| `--recursive` | No | Archive the folder and its descendants. Defaults to "false". | | `-y, --yes` | Yes | Confirm this operation. | +API request and response schemas: [deleteWorkflowFolder](/api-reference/workflows/deleteWorkflowsFolder). + ### sim workflows folders list List workflow folders @@ -6849,11 +7573,13 @@ Also available as `sim workflows folders ls`. | --- | --- | --- | | `--parent ` | No | Direct parent folder path. | | `--search ` | No | Case-insensitive substring match against the folder name. | -| `--sort-by ` | No | Field used to sort the result. Sorting by `name` is case-sensitive and follows the storage collation, so do not rely on a case-insensitive order. Accepted values: `name`, `createdAt`, `updatedAt`. | -| `--sort-order ` | No | Sort direction. Accepted values: `asc`, `desc`. | +| `--sort-by ` | No | Field used to sort the result. Do not rely on case-insensitive ordering when sorting by `name`. Defaults to "name". Accepted values: `name`, `createdAt`, `updatedAt`. | +| `--sort-order ` | No | Sort direction. Defaults to "asc". Accepted values: `asc`, `desc`. | +API request and response schemas: [listWorkflowFolders](/api-reference/workflows/listWorkflowsFolders). + ### sim workflows folders move Rename or move a workflow folder @@ -6875,9 +7601,13 @@ Also available as `sim workflows folders mv`. +API request and response schemas: [relocateWorkflowFolder](/api-reference/workflows/relocateWorkflowsFolder). + ### sim workflows delete -Delete Workflow +Delete workflow + +This archives the workflow and its run history; restore with `workflows restore`. ```bash sim workflows delete [options] @@ -6903,10 +7633,14 @@ sim workflows delete [options] +API request and response schemas: [deleteWorkflow](/api-reference/workflows/deleteWorkflowV2). + ### sim workflows chat unpublish Take a workflow’s chat deployment offline (OAuth login or personal API key required) +This takes the chat offline and frees its identifier. The workflow itself stays deployed and executable. + ```bash sim workflows chat unpublish [options] ``` @@ -6931,6 +7665,8 @@ sim workflows chat unpublish [options] +API request and response schemas: [deleteWorkflowChatDeployment](/api-reference/workflows/deleteWorkflowChatDeployment). + ### sim workflows chat status Show a workflow’s chat deployment (OAuth login or personal API key required) @@ -6949,9 +7685,15 @@ sim workflows chat status +API request and response schemas: [getWorkflowChatDeployment](/api-reference/workflows/getWorkflowChatDeployment). + ### sim workflows chat publish -Publish or replace a workflow’s chat deployment (OAuth login or personal API key required) +Deploy or replace a workflow chat (OAuth login or personal API key required) + +This replaces visitor access settings for the chat deployment. Omitted authentication fields reset to defaults, including the password and allowed-email list; avatar and welcome-message behavior follows their option descriptions. + +Omitting `--auth-type` selects public access: anyone holding the URL can chat. Supply the complete password or allow-list settings again when replacing a restricted deployment. ```bash sim workflows chat publish [options] @@ -6976,22 +7718,24 @@ sim workflows chat publish [options] | `--identifier ` | Yes | URL slug the deployed chat answers on. Must be free across live deployments. | | `--title ` | Yes | Title shown to visitors. | | `--description ` | No | Description shown to visitors. Omitted clears it. | -| `--customizations ` | No | Presentation overrides. Omitted fields take platform defaults. (JSON, or @path / @- to read a file or stdin). | -| `--auth-type ` | No | How visitors are gated. `public` leaves the chat open to anyone holding the URL. Accepted values: `public`, `password`, `email`, `sso`. | -| `--password ` | No | Write-only password of 15 to 1024 characters, not only whitespace. Required whenever `authType` is `password`, and rejected otherwise. Never readable back. Taken literally, except that a request from the Sim agent resolves a whole-value `{{ENV_VAR}}` reference to that variable before the rules apply. | +| `--customizations ` | No | Presentation overrides. Omitted `primaryColor` and `welcomeMessage` use platform defaults; an omitted or empty `imageUrl` keeps the existing avatar. An empty `welcomeMessage` keeps the existing message. (JSON, or @path / @- to read a file or stdin). | +| `--auth-type ` | No | How visitors are gated. `public` leaves the chat open to anyone holding the URL. Defaults to "public". Accepted values: `public`, `password`, `email`, `sso`. | +| `--password ` | Conditional | Write-only password of 15 to 1024 characters, not only whitespace. Required whenever `authType` is `password`, and rejected otherwise. Never readable back. Taken literally, except that a request from the Sim agent resolves a whole-value `{{ENV_VAR}}` reference to that variable before the rules apply. | | `--allowed-emails ` | No | Email addresses or domains admitted under `email` and `sso` gating. At least one is required for those modes. (JSON, or @path / @- to read a file or stdin). | | `--output-configs ` | No | Block outputs to surface to visitors. Omitted surfaces none. (JSON, or @path / @- to read a file or stdin). | -| `--include-thinking` | No | Allow visitors to receive provider thinking events. | +| `--include-thinking` | No | Allow visitors to receive provider thinking events. Defaults to false. | | `--no-include-thinking` | No | Send --include-thinking as false. | -| `--include-tool-calls` | No | Allow visitors to receive tool lifecycle events. | +| `--include-tool-calls` | No | Allow visitors to receive tool lifecycle events. Defaults to false. | | `--no-include-tool-calls` | No | Send --include-tool-calls as false. | | `-y, --yes` | Yes | Confirm this operation. | +API request and response schemas: [replaceWorkflowChatDeployment](/api-reference/workflows/replaceWorkflowChatDeployment). + ### sim workflows deploy -Deploy Workflow (OAuth login or personal API key required) +Deploy workflow (OAuth login or personal API key required) ```bash sim workflows deploy [options] @@ -7018,9 +7762,11 @@ sim workflows deploy [options] +API request and response schemas: [deployWorkflow](/api-reference/workflows/deployWorkflow). + ### sim workflows duplicate create -Duplicate Workflow +Duplicate workflow ```bash sim workflows duplicate create [options] @@ -7047,6 +7793,8 @@ sim workflows duplicate create [options] +API request and response schemas: [duplicateWorkflow](/api-reference/workflows/duplicateWorkflow). + ### sim workflows run Run a deployed workflow or execute saved state manually @@ -7072,10 +7820,10 @@ sim workflows run [options] | Option | Required | Description | | --- | --- | --- | | `--input ` | No | Trigger input as JSON (JSON, or @path / @- to read a file or stdin). | -| `--async` | No | Queue the run and return immediately. | +| `--async` | No | Queue the run and return immediately. Defaults to false. | | `--execution-timeout-seconds ` | No | Maximum duration of an asynchronous run, in seconds, capped by the plan's execution timeout. Requires `async: true`; otherwise returns `400`. | | `--select-output ` | No | Return blockName.path values (e.g. agent_1.content), or childWorkflowId.blockName.path for a child workflow (applies to every invocation) — in blockOutputs on a sync run, or from the streamed result with --follow; missing paths are omitted. Not available with --async (space-separated, or @path / @- with one value per line; @@value for a literal leading @). | -| `--include-file-base64` | No | Inline eligible output files as base64 content (default: true; Sim’s in-app agent gets file references only unless this flag is passed). Rejected when `async` is true. | +| `--include-file-base64` | No | Inline eligible output files as base64 content. Defaults to true for the installed CLI; Chat defaults to file references and admits requested bytes only for synchronous runs. Rejected when async is true. | | `--no-include-file-base64` | No | Send --include-file-base64 as false. | | `--base64-max-bytes ` | No | Maximum total bytes of file content to inline as base64, lowering but never raising the server limit of 16 MiB. Rejected when `async` is true. | | `--run-id ` | No | One-shot identifier for this run; NOT an idempotency key — reusing a claimed value fails with RUN_ID_CONFLICT instead of replaying the first result, and a fresh value starts another run. | @@ -7091,10 +7839,14 @@ sim workflows run [options] +API request and response schemas: [executeWorkflow](/api-reference/workflows/executeWorkflowV2). + ### sim workflows export Print a workflow as a portable JSON document +The export clears credentials, passwords, and table sub-block values, but it is not a general secret scanner. Inspect literal variables and inline configuration before sharing the document. + ```bash sim workflows export [options] ``` @@ -7116,14 +7868,16 @@ sim workflows export [options] | Option | Required | Description | | --- | --- | --- | | `--include-references` | No | Include non-secret resource identities for mapped import. | -| `--include-workspace-bindings` | No | Whether to keep workspace-scoped bindings — table, knowledge base, document, folder, channel, and other resource selectors — in the exported state. Defaults to false, the sharing-safe export in which those ids are cleared because they resolve nowhere else. Send true for a same-workspace round trip so the re-imported workflow can run without re-selecting them. Credentials, passwords, and table sub-block values are cleared either way. | +| `--include-workspace-bindings` | No | Keep non-secret table, knowledge base, document, folder, channel, and other workspace bindings for a same-workspace import. Defaults to false, which clears these IDs. Registered credential fields and opaque table/tool values are cleared either way; environment references and ordinary workflow variables remain included. | | `--no-include-workspace-bindings` | No | Send --include-workspace-bindings as false. | +API request and response schemas: [exportWorkflow](/api-reference/workflows/exportWorkflow). + ### sim workflows get -Get Workflow +Get workflow ```bash sim workflows get @@ -7139,6 +7893,8 @@ sim workflows get +API request and response schemas: [getWorkflow](/api-reference/workflows/getWorkflow). + ### sim workflows deployment status Show a workflow’s current deployment @@ -7157,9 +7913,11 @@ sim workflows deployment status +API request and response schemas: [getWorkflowDeployment](/api-reference/workflows/getWorkflowDeployment). + ### sim workflows deployment update -Update Workflow Public API Access (OAuth login or personal API key required) +Update workflow public API access (OAuth login or personal API key required) ```bash sim workflows deployment update [options] @@ -7185,9 +7943,11 @@ sim workflows deployment update [options] +API request and response schemas: [updateWorkflowPublicApi](/api-reference/workflows/updateWorkflowPublicApi). + ### sim workflows state get -Get Workflow State +Get workflow state ```bash sim workflows state get @@ -7203,9 +7963,13 @@ sim workflows state get +API request and response schemas: [getWorkflowState](/api-reference/workflows/getWorkflowState). + ### sim workflows state replace -Replace Workflow State (OAuth login or personal API key required) +Replace workflow state (OAuth login or personal API key required) + +This replaces the entire draft graph and cannot be undone. ```bash sim workflows state replace [options] @@ -7234,13 +7998,15 @@ sim workflows state replace [options] | `--loops ` | No | Ignored on write: loop containers are recomputed from `blocks`. (JSON, or @path / @- to read a file or stdin). | | `--parallels ` | No | Ignored on write: parallel containers are recomputed from `blocks`. (JSON, or @path / @- to read a file or stdin). | | `--variables ` | No | Replacement variable set. Omit to leave the stored variables untouched. (JSON, or @path / @- to read a file or stdin). | -| `-y, --yes` | No | Confirm this operation (required unless --dry-run). | +| `-y, --yes` | Conditional | Confirm this operation (required unless --dry-run). | +API request and response schemas: [replaceWorkflowState](/api-reference/workflows/replaceWorkflowState). + ### sim workflows import -Import Workflow +Import workflow ```bash sim workflows import [options] @@ -7256,19 +8022,21 @@ sim workflows import [options] | `--folder ` | No | Folder path as shown in the app; the leading / is optional. | | `--name ` | No | Override for the imported workflow name. | | `--description ` | No | Override for the imported workflow description. | -| `--mappings ` | No | Mappings keyed by resource type and source identifier. (JSON, or @path / @- to read a file or stdin). | +| `--mappings ` | No | Mapping entries addressed by resource kind and source identifier. (JSON, or @path / @- to read a file or stdin). | | `--bindings ` | No | Resolved and unresolved source occurrences with their destination selections. (JSON, or @path / @- to read a file or stdin). | -| `--dependent-values ` | No | Destination-dependent choices keyed by source workflow, block, and field identities. (JSON, or @path / @- to read a file or stdin). | -| `--request-id ` | No | Stable client request ID for reconciliation and identical retries. | -| `--preview-fingerprint ` | No | Fingerprint of the reviewed preview and its choices. | +| `--dependent-values ` | No | Destination-specific values addressed by the source block ID and field key, before imported IDs are regenerated. (JSON, or @path / @- to read a file or stdin). | +| `--request-id ` | No | Stable client request ID for mapped import. Reuse it with identical inputs after an uncertain response; changed inputs return 409. A new ID can create another workflow. | +| `--preview-fingerprint ` | No | Fingerprint returned by an import preview with the same choices. A changed plan returns 409; preview again. Do not invent this value. | | `--wait` | No | Wait for the committed operation to finish; missing configuration and failure exit nonzero. | | `--wait-timeout ` | No | Maximum operation wait in seconds (default 3600; 0 waits indefinitely). | +API request and response schemas: [importWorkflow](/api-reference/workflows/importWorkflow). + ### sim workflows list -List Workflows +List workflows ```bash sim workflows list [options] @@ -7286,14 +8054,16 @@ sim workflows list [options] | `--no-deployed-only` | No | Send --deployed-only as false. | | `--limit ` | No | Maximum items to return (0 for everything). Defaults to `0`. | | `--search ` | No | Case-insensitive substring match against the resource name. | -| `--sort-by ` | No | Field used to sort the result. Sorting by `name` is case-sensitive and follows the storage collation, so do not rely on a case-insensitive order. Accepted values: `position`, `name`, `createdAt`, `updatedAt`, `runCount`. | -| `--sort-order ` | No | Sort direction. Accepted values: `asc`, `desc`. | +| `--sort-by ` | No | Field used to sort the result. Do not rely on case-insensitive ordering when sorting by `name`. Defaults to "position". Accepted values: `position`, `name`, `createdAt`, `updatedAt`, `runCount`. | +| `--sort-order ` | No | Sort direction. Defaults to "asc". Accepted values: `asc`, `desc`. | +API request and response schemas: [listWorkflows](/api-reference/workflows/listWorkflows). + ### sim workflows move -Move Workflows +Move workflows ```bash sim workflows move [options] @@ -7310,9 +8080,11 @@ sim workflows move [options] +API request and response schemas: [moveWorkflows](/api-reference/workflows/moveWorkflows). + ### sim workflows import-preview -Preview Workflow Import +Preview workflow import ```bash sim workflows import-preview [options] @@ -7328,12 +8100,14 @@ sim workflows import-preview [options] | `--folder ` | No | Folder path as shown in the app; the leading / is optional. | | `--name ` | No | Override for the imported workflow name. | | `--description ` | No | Override for the imported workflow description. | -| `--mappings ` | No | Mappings keyed by resource type and source identifier. (JSON, or @path / @- to read a file or stdin). | +| `--mappings ` | No | Mapping entries addressed by resource kind and source identifier. (JSON, or @path / @- to read a file or stdin). | | `--bindings ` | No | Resolved and unresolved source occurrences with their destination selections. (JSON, or @path / @- to read a file or stdin). | -| `--dependent-values ` | No | Destination-dependent choices keyed by source workflow, block, and field identities. (JSON, or @path / @- to read a file or stdin). | +| `--dependent-values ` | No | Destination-specific values addressed by the source block ID and field key, before imported IDs are regenerated. (JSON, or @path / @- to read a file or stdin). | +API request and response schemas: [previewWorkflowImport](/api-reference/workspace-sync/previewWorkflowImport). + ### sim workflows restore Restore an archived workflow @@ -7352,9 +8126,13 @@ sim workflows restore +API request and response schemas: [restoreWorkflow](/api-reference/workflows/restoreWorkflow). + ### sim workflows revert create -Revert Workflow To Version (OAuth login or personal API key required) +Revert workflow to version (OAuth login or personal API key required) + +This overwrites the draft graph with the selected version and cannot be undone. ```bash sim workflows revert create [options] @@ -7381,9 +8159,13 @@ sim workflows revert create [options] +API request and response schemas: [revertWorkflowVersion](/api-reference/workflows/revertWorkflowVersion). + ### sim workflows rollback -Rollback Workflow (OAuth login or personal API key required) +Rollback workflow (OAuth login or personal API key required) + +This changes which deployed version runs in production for every API and chat consumer. ```bash sim workflows rollback [options] @@ -7410,10 +8192,14 @@ sim workflows rollback [options] +API request and response schemas: [rollbackWorkflow](/api-reference/workflows/rollbackWorkflow). + ### sim workflows undeploy Take a workflow out of deployment (OAuth login or personal API key required) +This takes the workflow offline for every API and chat consumer, and agents calling its MCP tools lose access until it is deployed again. + ```bash sim workflows undeploy [options] ``` @@ -7438,9 +8224,11 @@ sim workflows undeploy [options] +API request and response schemas: [undeployWorkflow](/api-reference/workflows/undeployWorkflow). + ### sim workflows update -Update Workflow +Update workflow ```bash sim workflows update [options] @@ -7468,6 +8256,8 @@ sim workflows update [options] +API request and response schemas: [updateWorkflow](/api-reference/workflows/updateWorkflowV2). + ### sim workflows mv Move a workflow to a folder @@ -7487,6 +8277,8 @@ sim workflows mv +API request and response schemas: [updateWorkflow](/api-reference/workflows/updateWorkflowV2). + ### sim workflows ls List workflow resources and child folders together @@ -7516,6 +8308,8 @@ sim workflows ls [path] [options] +API request and response schemas: [listWorkflows](/api-reference/workflows/listWorkflows), [listWorkflowFolders](/api-reference/workflows/listWorkflowsFolders). + ### sim workflows mkdir Create a workflow directory at a path @@ -7534,13 +8328,17 @@ sim workflows mkdir +API request and response schemas: [createWorkflowFolder](/api-reference/workflows/createWorkflowsFolder). + ## sim workspaces +Read workspace access and manage reviewed fork, push, and pull operations. + Also spelled `sim workspace`. ### sim workspaces access-requests cancel -Cancel Workspace Access Request (OAuth login or personal API key required) +Cancel workspace access request (OAuth login or personal API key required) ```bash sim workspaces access-requests cancel @@ -7556,9 +8354,11 @@ sim workspaces access-requests cancel +API request and response schemas: [cancelWorkspaceAccessRequest](/api-reference/access-requests/cancelWorkspaceAccessRequest). + ### sim workspaces access-requests create -Create Workspace Access Request (OAuth login or personal API key required) +Create workspace access request (OAuth login or personal API key required) ```bash sim workspaces access-requests create [options] @@ -7571,13 +8371,15 @@ sim workspaces access-requests create [options] | Option | Required | Description | | --- | --- | --- | | `--target ` | Yes | Target returned by Discover Workspace Access Requests or Discover Organization Access Requests. The target must currently be requestable. (JSON, or @path / @- to read a file or stdin). | -| `--reason ` | No | Why the acting user needs this access. | +| `--reason ` | No | Why the acting user needs this access. Defaults to "". | +API request and response schemas: [createWorkspaceAccessRequest](/api-reference/access-requests/createWorkspaceAccessRequest). + ### sim workspaces access-requests discover -Discover Workspace Access Requests (OAuth login or personal API key required) +Discover workspace access requests (OAuth login or personal API key required) ```bash sim workspaces access-requests discover [options] @@ -7592,16 +8394,18 @@ sim workspaces access-requests discover [options] | `--search ` | No | Case-insensitive substring match against the access item label. | | `--target-kind ` | No | Category of access to discover. Accepted values: `feature`, `integration`, `provider`, `model`, `tool`, `knowledge_connector`, `file_share_auth`, `chat_deploy_auth`, `usage_limit`. | | `--state ` | No | Filter by the acting user’s current access. Requestable items can be submitted for review. Accepted values: `allowed`, `requestable`, `unavailable`. | -| `--sort-by ` | No | Field used to sort the result. Accepted values: `label`. | -| `--sort-order ` | No | Sort direction. Accepted values: `asc`, `desc`. | +| `--sort-by ` | No | Field used to sort the result. Defaults to "label". Accepted values: `label`. | +| `--sort-order ` | No | Sort direction. Defaults to "asc". Accepted values: `asc`, `desc`. | | `--limit ` | No | Maximum items to return (0 for everything). Defaults to `100`. | | `--cursor ` | No | Continue from nextCursor returned by a previous result. | +API request and response schemas: [discoverWorkspaceAccessRequests](/api-reference/access-requests/discoverWorkspaceAccessRequests). + ### sim workspaces access-requests mine -List My Workspace Access Requests (OAuth login or personal API key required) +List my workspace access requests (OAuth login or personal API key required) ```bash sim workspaces access-requests mine [options] @@ -7614,16 +8418,18 @@ sim workspaces access-requests mine [options] | Option | Required | Description | | --- | --- | --- | | `--status ` | No | Filter by request status; omit to include all statuses. Accepted values: `pending`, `fulfilled`, `declined`, `cancelled`, `closed`. | -| `--sort-by ` | No | Field used to sort the result. Accepted values: `createdAt`, `targetLabel`. | -| `--sort-order ` | No | Sort direction. Accepted values: `asc`, `desc`. | +| `--sort-by ` | No | Field used to sort the result. Defaults to "createdAt". Accepted values: `createdAt`, `targetLabel`. | +| `--sort-order ` | No | Sort direction. Defaults to "desc". Accepted values: `asc`, `desc`. | | `--limit ` | No | Maximum items to return (0 for everything). Defaults to `100`. | | `--cursor ` | No | Continue from nextCursor returned by a previous result. | +API request and response schemas: [listMyWorkspaceAccessRequests](/api-reference/access-requests/listMyWorkspaceAccessRequests). + ### sim workspaces invitations create -Create Workspace Invitations (OAuth login or personal API key required) +Create workspace invitations (OAuth login or personal API key required) ```bash sim workspaces invitations create [options] @@ -7636,14 +8442,16 @@ sim workspaces invitations create [options] | Option | Required | Description | | --- | --- | --- | | `--emails ` | Yes | Email addresses to invite. Each address is processed separately; inspect failed for unsuccessful recipients. (space-separated, or @path / @- with one value per line; @@value for a literal leading @). | -| `--permission ` | No | Workspace permission to grant. Existing workspace access is preserved. Accepted values: `admin`, `write`, `read`. | -| `--membership ` | No | Organization membership: member or admin uses a seat when billing is enabled. External grants workspace access only and requires an eligible paid account when billing is enabled. Existing members of another organization remain external. Accepted values: `member`, `admin`, `external`. | +| `--permission ` | No | Workspace permission to grant. Existing workspace access is preserved. Defaults to "read". Accepted values: `admin`, `write`, `read`. | +| `--membership ` | No | Organization membership: member or admin uses a seat when billing is enabled. External grants workspace access only and requires an eligible paid account when billing is enabled. Existing members of another organization remain external. Defaults to "member". Accepted values: `member`, `admin`, `external`. | +API request and response schemas: [createWorkspaceInvitations](/api-reference/workspaces/createWorkspaceInvitations). + ### sim workspaces fork -Fork Workspace (OAuth login or personal API key required) +Fork workspace (OAuth login or personal API key required) ```bash sim workspaces fork [options] @@ -7657,40 +8465,48 @@ sim workspaces fork [options] | --- | --- | --- | | `--name ` | No | Display name of the workflow or workspace. | | `--copy ` | No | Explicit resource selections to copy into the new fork; omitted resource kinds are not copied. (JSON, or @path / @- to read a file or stdin). | -| `--request-id ` | Yes | Stable client request ID for reconciliation and identical retries. | -| `--preview-fingerprint ` | Yes | Fingerprint of the reviewed preview and its choices. | +| `--request-id ` | Yes | Stable client request ID. Reuse it with identical inputs after an uncertain response; changed inputs return 409. A new ID can apply another operation. | +| `--preview-fingerprint ` | Yes | Fingerprint returned by a preview with the same choices. A changed plan returns 409; preview again. The example hash is illustrative; use the actual preview value. | | `--wait` | No | Wait for the committed operation to finish; missing configuration and failure exit nonzero. | | `--wait-timeout ` | No | Maximum operation wait in seconds (default 3600; 0 waits indefinitely). | +API request and response schemas: [forkWorkspace](/api-reference/workspace-sync/forkWorkspace). + ### sim workspaces get -Get Workspace +Get workspace ```bash sim workspaces get ``` +API request and response schemas: [getWorkspace](/api-reference/workspaces/getWorkspace). + ### sim workspaces fork-availability -Get Workspace Fork Availability (OAuth login or personal API key required) +Get workspace fork availability (OAuth login or personal API key required) ```bash sim workspaces fork-availability ``` +API request and response schemas: [getWorkspaceForkAvailability](/api-reference/workspace-sync/getWorkspaceForkAvailability). + ### sim workspaces lineage -Get Workspace Fork Lineage (OAuth login or personal API key required) +Get workspace fork lineage (OAuth login or personal API key required) ```bash sim workspaces lineage ``` +API request and response schemas: [getWorkspaceForkLineage](/api-reference/workspace-sync/getWorkspaceForkLineage). + ### sim workspaces mappings get -Get Workspace Fork Mappings (OAuth login or personal API key required) +Get workspace fork mappings (OAuth login or personal API key required) ```bash sim workspaces mappings get [options] @@ -7706,14 +8522,16 @@ sim workspaces mappings get [options] | `--direction ` | Yes | Push means current to other; pull means other to current, independent of parent/child orientation. Accepted values: `push`, `pull`. | | `--limit ` | No | Maximum items to return (0 for everything). Defaults to `100`. | | `--cursor ` | No | Continue from nextCursor returned by a previous result. | -| `--sort-by ` | No | Supported stable sort key for this collection. Accepted values: `id`. | -| `--sort-order ` | No | Sort direction. Accepted values: `asc`. | +| `--sort-by ` | No | Supported stable sort key for this collection. Defaults to "id". Accepted values: `id`. | +| `--sort-order ` | No | Sort direction. Defaults to "asc". Accepted values: `asc`. | +API request and response schemas: [getWorkspaceForkMappings](/api-reference/workspace-sync/getWorkspaceForkMappings). + ### sim workspaces mappings update -Update Workspace Fork Mappings (OAuth login or personal API key required) +Update workspace fork mappings (OAuth login or personal API key required) ```bash sim workspaces mappings update [options] @@ -7727,13 +8545,15 @@ sim workspaces mappings update [options] | --- | --- | --- | | `--other-workspace-id ` | Yes | Workspace on the other side of the direct fork edge. | | `--direction ` | Yes | Push means current to other; pull means other to current, independent of parent/child orientation. Accepted values: `push`, `pull`. | -| `--mappings ` | Yes | Mappings keyed by resource type and source identifier. (JSON, or @path / @- to read a file or stdin). | +| `--mappings ` | Yes | Mapping entries addressed by resource type and `sourceId`. `targetId: null` clears a mapping. (JSON, or @path / @- to read a file or stdin). | +API request and response schemas: [updateWorkspaceForkMappings](/api-reference/workspace-sync/updateWorkspaceForkMappings). + ### sim workspaces operations get -Get Workspace Operation +Get workspace operation ```bash sim workspaces operations get @@ -7749,9 +8569,11 @@ sim workspaces operations get +API request and response schemas: [getWorkspaceOperation](/api-reference/workspace-sync/getWorkspaceOperation). + ### sim workspaces operations list -List Workspace Operations +List workspace operations ```bash sim workspaces operations list [options] @@ -7765,13 +8587,15 @@ sim workspaces operations list [options] | --- | --- | --- | | `--limit ` | No | Maximum items to return (0 for everything). Defaults to `100`. | | `--cursor ` | No | Continue from nextCursor returned by a previous result. | -| `--request-id ` | No | Stable client request ID for reconciliation and identical retries. | +| `--request-id ` | No | Find an uncertain mutation by the original client request ID; keep the same filter while paging. | +API request and response schemas: [listWorkspaceOperations](/api-reference/workspace-sync/listWorkspaceOperations). + ### sim workspaces operations wait -Wait for copy and deployment readiness; exit 3 for configuration, 1 for failure, or 4 for timeout +Wait for workspace copy and deployment readiness ```bash sim workspaces operations wait [options] @@ -7797,17 +8621,23 @@ sim workspaces operations wait [options] +Exit codes: 0 completed (including completion with warnings), 1 follow-up work failed, 3 destination configuration is required, 4 timed out. The mutation may already be committed; reconcile using the same operation or request ID rather than repeating it with a new ID. + +API request and response schemas: [getWorkspaceOperation](/api-reference/workspace-sync/getWorkspaceOperation). + ### sim workspaces permission-config -Get Workspace Permission Config (OAuth login or personal API key required) +Get workspace permission config (OAuth login or personal API key required) ```bash sim workspaces permission-config ``` +API request and response schemas: [getWorkspacePermissionConfig](/api-reference/workspaces/getWorkspacePermissionConfig). + ### sim workspaces children -List Workspace Fork Children (OAuth login or personal API key required) +List workspace fork children (OAuth login or personal API key required) ```bash sim workspaces children [options] @@ -7821,14 +8651,16 @@ sim workspaces children [options] | --- | --- | --- | | `--limit ` | No | Maximum items to return (0 for everything). Defaults to `100`. | | `--cursor ` | No | Continue from nextCursor returned by a previous result. | -| `--sort-by ` | No | Supported stable sort key for this collection. Accepted values: `createdAt`. | -| `--sort-order ` | No | Sort direction. Accepted values: `desc`. | +| `--sort-by ` | No | Supported stable sort key for this collection. Defaults to "createdAt". Accepted values: `createdAt`. | +| `--sort-order ` | No | Sort direction. Defaults to "desc". Accepted values: `desc`. | +API request and response schemas: [listWorkspaceForkChildren](/api-reference/workspace-sync/listWorkspaceForkChildren). + ### sim workspaces fork-resources -List Workspace Fork Resources (OAuth login or personal API key required) +List workspace fork resources (OAuth login or personal API key required) ```bash sim workspaces fork-resources [options] @@ -7842,12 +8674,14 @@ sim workspaces fork-resources [options] | --- | --- | --- | | `--limit ` | No | Maximum items to return (0 for everything). Defaults to `100`. | | `--cursor ` | No | Continue from nextCursor returned by a previous result. | -| `--kind ` | Yes | Resource or operation kind. Accepted values: `files`, `tables`, `knowledgeBases`, `customTools`, `skills`, `mcpServers`, `workflowMcpServers`. | -| `--sort-by ` | No | Supported stable sort key for this collection. Accepted values: `id`. | -| `--sort-order ` | No | Sort direction. Accepted values: `asc`. | +| `--kind ` | Yes | Kind of source resource to list for copy selection. Accepted values: `files`, `tables`, `knowledgeBases`, `customTools`, `skills`, `mcpServers`, `workflowMcpServers`. | +| `--sort-by ` | No | Supported stable sort key for this collection. Defaults to "id". Accepted values: `id`. | +| `--sort-order ` | No | Sort direction. Defaults to "asc". Accepted values: `asc`. | +API request and response schemas: [listWorkspaceForkResources](/api-reference/workspace-sync/listWorkspaceForkResources). + ### sim workspaces members List workspace members @@ -7866,9 +8700,11 @@ sim workspaces members [options] +API request and response schemas: [listWorkspaceMembers](/api-reference/workspaces/listWorkspaceMembers). + ### sim workspaces list -List Workspaces +List workspaces ```bash sim workspaces list [options] @@ -7880,15 +8716,17 @@ sim workspaces list [options] | Option | Required | Description | | --- | --- | --- | -| `--sort-by ` | No | Field used to sort the result. Sorting by `name` is case-sensitive and follows the storage collation, so do not rely on a case-insensitive order. Accepted values: `name`, `createdAt`, `updatedAt`. | -| `--sort-order ` | No | Sort direction. Accepted values: `asc`, `desc`. | +| `--sort-by ` | No | Field used to sort the result. Do not rely on case-insensitive ordering when sorting by `name`. Defaults to "createdAt". Accepted values: `name`, `createdAt`, `updatedAt`. | +| `--sort-order ` | No | Sort direction. Defaults to "desc". Accepted values: `asc`, `desc`. | | `--limit ` | No | Maximum items to return (0 for everything). Defaults to `0`. | +API request and response schemas: [listWorkspaces](/api-reference/workspaces/listWorkspaces). + ### sim workspaces fork-preview -Preview Workspace Fork (OAuth login or personal API key required) +Preview workspace fork (OAuth login or personal API key required) ```bash sim workspaces fork-preview [options] @@ -7905,9 +8743,11 @@ sim workspaces fork-preview [options] +API request and response schemas: [previewWorkspaceFork](/api-reference/workspace-sync/previewWorkspaceFork). + ### sim workspaces pull-preview -Preview Workspace Pull (OAuth login or personal API key required) +Preview workspace pull (OAuth login or personal API key required) ```bash sim workspaces pull-preview [options] @@ -7920,17 +8760,19 @@ sim workspaces pull-preview [options] | Option | Required | Description | | --- | --- | --- | | `--other-workspace-id ` | Yes | Workspace on the other side of the direct fork edge. | -| `--mappings ` | No | Mappings keyed by resource type and source identifier. (JSON, or @path / @- to read a file or stdin). | -| `--dependent-values ` | No | Destination-dependent choices keyed by source workflow, block, and field identities. (JSON, or @path / @- to read a file or stdin). | +| `--mappings ` | No | Proposed mapping entries addressed by resource type and `sourceId`. Preview does not save them; apply commits them with the sync. (JSON, or @path / @- to read a file or stdin). | +| `--dependent-values ` | No | Destination-specific choices addressed by source workflow ID, source block ID, and field key. Omission keeps saved overrides; an explicit empty array clears them. (JSON, or @path / @- to read a file or stdin). | | `--copy-resources ` | No | Explicit source resources to copy before syncing the workflows. (JSON, or @path / @- to read a file or stdin). | | `--drop-references ` | No | Source-deleted references explicitly acknowledged for removal; live source references cannot be dropped. (JSON, or @path / @- to read a file or stdin). | | `--trigger-mappings ` | No | Public trigger path choices from preview.triggerSlots, addressed by source workflow and block IDs. Duplicate or unavailable choices are rejected. (JSON, or @path / @- to read a file or stdin). | +API request and response schemas: [previewWorkspacePull](/api-reference/workspace-sync/previewWorkspacePull). + ### sim workspaces push-preview -Preview Workspace Push (OAuth login or personal API key required) +Preview workspace push (OAuth login or personal API key required) ```bash sim workspaces push-preview [options] @@ -7943,17 +8785,21 @@ sim workspaces push-preview [options] | Option | Required | Description | | --- | --- | --- | | `--other-workspace-id ` | Yes | Workspace on the other side of the direct fork edge. | -| `--mappings ` | No | Mappings keyed by resource type and source identifier. (JSON, or @path / @- to read a file or stdin). | -| `--dependent-values ` | No | Destination-dependent choices keyed by source workflow, block, and field identities. (JSON, or @path / @- to read a file or stdin). | +| `--mappings ` | No | Proposed mapping entries addressed by resource type and `sourceId`. Preview does not save them; apply commits them with the sync. (JSON, or @path / @- to read a file or stdin). | +| `--dependent-values ` | No | Destination-specific choices addressed by source workflow ID, source block ID, and field key. Omission keeps saved overrides; an explicit empty array clears them. (JSON, or @path / @- to read a file or stdin). | | `--copy-resources ` | No | Explicit source resources to copy before syncing the workflows. (JSON, or @path / @- to read a file or stdin). | | `--drop-references ` | No | Source-deleted references explicitly acknowledged for removal; live source references cannot be dropped. (JSON, or @path / @- to read a file or stdin). | | `--trigger-mappings ` | No | Public trigger path choices from preview.triggerSlots, addressed by source workflow and block IDs. Duplicate or unavailable choices are rejected. (JSON, or @path / @- to read a file or stdin). | +API request and response schemas: [previewWorkspacePush](/api-reference/workspace-sync/previewWorkspacePush). + ### sim workspaces pull -Pull Workspace (OAuth login or personal API key required) +Pull workspace (OAuth login or personal API key required) + +This replaces target workflows and may archive targets whose sources were deleted. ```bash sim workspaces pull [options] @@ -7966,22 +8812,26 @@ sim workspaces pull [options] | Option | Required | Description | | --- | --- | --- | | `--other-workspace-id ` | Yes | Workspace on the other side of the direct fork edge. | -| `--mappings ` | No | Mappings keyed by resource type and source identifier. (JSON, or @path / @- to read a file or stdin). | -| `--dependent-values ` | No | Destination-dependent choices keyed by source workflow, block, and field identities. (JSON, or @path / @- to read a file or stdin). | +| `--mappings ` | No | Proposed mapping entries addressed by resource type and `sourceId`. Preview does not save them; apply commits them with the sync. (JSON, or @path / @- to read a file or stdin). | +| `--dependent-values ` | No | Destination-specific choices addressed by source workflow ID, source block ID, and field key. Omission keeps saved overrides; an explicit empty array clears them. (JSON, or @path / @- to read a file or stdin). | | `--copy-resources ` | No | Explicit source resources to copy before syncing the workflows. (JSON, or @path / @- to read a file or stdin). | | `--drop-references ` | No | Source-deleted references explicitly acknowledged for removal; live source references cannot be dropped. (JSON, or @path / @- to read a file or stdin). | | `--trigger-mappings ` | No | Public trigger path choices from preview.triggerSlots, addressed by source workflow and block IDs. Duplicate or unavailable choices are rejected. (JSON, or @path / @- to read a file or stdin). | -| `--request-id ` | Yes | Stable client request ID for reconciliation and identical retries. | -| `--preview-fingerprint ` | Yes | Fingerprint of the reviewed preview and its choices. | +| `--request-id ` | Yes | Stable client request ID. Reuse it with identical inputs after an uncertain response; changed inputs return 409. A new ID can apply another operation. | +| `--preview-fingerprint ` | Yes | Fingerprint returned by a preview with the same choices. A changed plan returns 409; preview again. The example hash is illustrative; use the actual preview value. | | `--wait` | No | Wait for the committed operation to finish; missing configuration and failure exit nonzero. | | `--wait-timeout ` | No | Maximum operation wait in seconds (default 3600; 0 waits indefinitely). | | `-y, --yes` | Yes | Confirm this operation. | +API request and response schemas: [pullWorkspace](/api-reference/workspace-sync/pullWorkspace). + ### sim workspaces push -Push Workspace (OAuth login or personal API key required) +Push workspace (OAuth login or personal API key required) + +This replaces target workflows and may archive targets whose sources were deleted. ```bash sim workspaces push [options] @@ -7994,22 +8844,26 @@ sim workspaces push [options] | Option | Required | Description | | --- | --- | --- | | `--other-workspace-id ` | Yes | Workspace on the other side of the direct fork edge. | -| `--mappings ` | No | Mappings keyed by resource type and source identifier. (JSON, or @path / @- to read a file or stdin). | -| `--dependent-values ` | No | Destination-dependent choices keyed by source workflow, block, and field identities. (JSON, or @path / @- to read a file or stdin). | +| `--mappings ` | No | Proposed mapping entries addressed by resource type and `sourceId`. Preview does not save them; apply commits them with the sync. (JSON, or @path / @- to read a file or stdin). | +| `--dependent-values ` | No | Destination-specific choices addressed by source workflow ID, source block ID, and field key. Omission keeps saved overrides; an explicit empty array clears them. (JSON, or @path / @- to read a file or stdin). | | `--copy-resources ` | No | Explicit source resources to copy before syncing the workflows. (JSON, or @path / @- to read a file or stdin). | | `--drop-references ` | No | Source-deleted references explicitly acknowledged for removal; live source references cannot be dropped. (JSON, or @path / @- to read a file or stdin). | | `--trigger-mappings ` | No | Public trigger path choices from preview.triggerSlots, addressed by source workflow and block IDs. Duplicate or unavailable choices are rejected. (JSON, or @path / @- to read a file or stdin). | -| `--request-id ` | Yes | Stable client request ID for reconciliation and identical retries. | -| `--preview-fingerprint ` | Yes | Fingerprint of the reviewed preview and its choices. | +| `--request-id ` | Yes | Stable client request ID. Reuse it with identical inputs after an uncertain response; changed inputs return 409. A new ID can apply another operation. | +| `--preview-fingerprint ` | Yes | Fingerprint returned by a preview with the same choices. A changed plan returns 409; preview again. The example hash is illustrative; use the actual preview value. | | `--wait` | No | Wait for the committed operation to finish; missing configuration and failure exit nonzero. | | `--wait-timeout ` | No | Maximum operation wait in seconds (default 3600; 0 waits indefinitely). | | `-y, --yes` | Yes | Confirm this operation. | +API request and response schemas: [pushWorkspace](/api-reference/workspace-sync/pushWorkspace). + ### sim workspaces fork-rollback -Rollback Workspace Fork (OAuth login or personal API key required) +Rollback workspace fork (OAuth login or personal API key required) + +This restores the latest sync using its prior deployed versions. ```bash sim workspaces fork-rollback [options] @@ -8026,9 +8880,13 @@ sim workspaces fork-rollback [options] +API request and response schemas: [rollbackWorkspaceFork](/api-reference/workspace-sync/rollbackWorkspaceFork). + ### sim workspaces unlink -Unlink Workspace Fork (OAuth login or personal API key required) +Unlink workspace fork (OAuth login or personal API key required) + +This removes the fork relationship and its persisted mappings. ```bash sim workspaces unlink [options] @@ -8045,9 +8903,11 @@ sim workspaces unlink [options] +API request and response schemas: [unlinkWorkspaceFork](/api-reference/workspace-sync/unlinkWorkspaceFork). + ### sim workspaces sync-exclusions -Update Workspace Fork Exclusions (OAuth login or personal API key required) +Update workspace fork exclusions (OAuth login or personal API key required) ```bash sim workspaces sync-exclusions [options] @@ -8063,3 +8923,5 @@ sim workspaces sync-exclusions [options] | `--fork-sync-excluded ` | Yes | Whether the named workflows should be skipped as sync sources and targets. Accepted values: `true`, `false`. | + +API request and response schemas: [updateWorkspaceForkExclusions](/api-reference/workspace-sync/updateWorkspaceForkExclusions). diff --git a/apps/docs/content/docs/cli/sandboxes.mdx b/apps/docs/content/docs/cli/sandboxes.mdx index 4ebd42422e1..4382b6ec5c1 100644 --- a/apps/docs/content/docs/cli/sandboxes.mdx +++ b/apps/docs/content/docs/cli/sandboxes.mdx @@ -1,44 +1,43 @@ --- title: Sandboxes -description: Manage sandboxes — every subcommand, argument, and flag +description: Manage reusable dependency sets for Function blocks. --- import { CommandTable } from '@/components/ui/command-table' +Manage reusable dependency sets for Function blocks. + `sim sandboxes` is also spelled `sim sandbox`. -Every command below also accepts the [global options](/cli/commands#global-options). +These commands accept the [global options](/cli/commands#global-options). -## Create sandbox +## List sandboxes ```bash -sim sandboxes create [options] +sim sandboxes list [options] ``` -Create Sandbox (OAuth login or personal API key required) - **Options** | Option | Required | Description | | --- | --- | --- | -| `--name ` | Yes | Display name, unique within the workspace; 1 to 64 characters. | -| `--language ` | Yes | Dependency ecosystem: `javascript` installs from npm, `python` from PyPI. Accepted values: `javascript`, `python`. | -| `--dependencies ` | No | Package specifiers installed into the sandbox, one per entry. (space-separated, or @path / @- with one value per line; in a file, blank lines and # comments are ignored, while inline values are sent as typed and may not be empty; @@value for a literal leading @). | -| `--cli-tools ` | No | Pinned managed CLI ids installed into the sandbox, at most 10, no duplicates. (space-separated, or @path / @- with one value per line; @@value for a literal leading @). | -| `--system-packages ` | No | Debian packages installed into the sandbox, one per entry. (space-separated, or @path / @- with one value per line; in a file, blank lines and # comments are ignored, while inline values are sent as typed and may not be empty; @@value for a literal leading @). | +| `--search ` | No | Case-insensitive substring match against the sandbox name. | +| `--sort-by ` | No | Field used to sort the result. Do not rely on case-insensitive ordering when sorting by `name`. Defaults to "name". Accepted values: `name`, `createdAt`, `updatedAt`. | +| `--sort-order ` | No | Sort direction. Defaults to "asc". Accepted values: `asc`, `desc`. | +| `--limit ` | No | Maximum items to return (0 for everything). Defaults to `0`. | -## Delete sandbox +API request and response schemas: [listSandboxes](/api-reference/sandboxes/listSandboxes). + +## Get sandbox ```bash -sim sandboxes delete [options] +sim sandboxes get ``` -Delete Sandbox (OAuth login or personal API key required) - **Arguments** @@ -49,20 +48,38 @@ Delete Sandbox (OAuth login or personal API key required) +API request and response schemas: [getSandbox](/api-reference/sandboxes/getSandbox). + +## Create sandbox + +OAuth login or personal API key required. + +```bash +sim sandboxes create [options] +``` + **Options** | Option | Required | Description | | --- | --- | --- | -| `-y, --yes` | Yes | Confirm this operation. | +| `--name ` | Yes | Display name, unique within the workspace; 1 to 64 characters. | +| `--language ` | Yes | Dependency ecosystem: `javascript` installs from npm, `python` from PyPI. Accepted values: `javascript`, `python`. | +| `--dependencies ` | No | Package specifiers installed into the sandbox, one per entry. Defaults to []. (space-separated, or @path / @- with one value per line; in a file, blank lines and # comments are ignored, while inline values are sent as typed and may not be empty; @@value for a literal leading @). | +| `--cli-tools ` | No | Pinned managed CLI ids installed into the sandbox, at most 10, no duplicates. Defaults to []. (space-separated, or @path / @- with one value per line; @@value for a literal leading @). | +| `--system-packages ` | No | Debian packages installed into the sandbox, one per entry. Defaults to []. (space-separated, or @path / @- with one value per line; in a file, blank lines and # comments are ignored, while inline values are sent as typed and may not be empty; @@value for a literal leading @). | -## Get sandbox +API request and response schemas: [createSandbox](/api-reference/sandboxes/createSandbox). + +## Update sandbox + +OAuth login or personal API key required. ```bash -sim sandboxes get +sim sandboxes update [options] ``` **Arguments** @@ -75,33 +92,32 @@ sim sandboxes get -## List sandboxes - -```bash -sim sandboxes list [options] -``` - **Options** | Option | Required | Description | | --- | --- | --- | -| `--search ` | No | Case-insensitive substring match against the sandbox name. | -| `--sort-by ` | No | Field used to sort the result. Sorting by `name` is case-sensitive and follows the storage collation, so do not rely on a case-insensitive order. Accepted values: `name`, `createdAt`, `updatedAt`. | -| `--sort-order ` | No | Sort direction. Accepted values: `asc`, `desc`. | -| `--limit ` | No | Maximum items to return (0 for everything). Defaults to `0`. | +| `--name ` | No | New display name, unique within the workspace; 1 to 64 characters. | +| `--language ` | No | Replacement dependency ecosystem. The whole spec is revalidated against it, so a Python dependency list does not survive a switch to JavaScript. Accepted values: `javascript`, `python`. | +| `--dependencies ` | No | Replacement package list; replaces the whole list. (space-separated, or @path / @- with one value per line; in a file, blank lines and # comments are ignored, while inline values are sent as typed and may not be empty; @@value for a literal leading @). | +| `--cli-tools ` | No | Replacement managed CLI list; replaces the whole list. (space-separated, or @path / @- with one value per line; @@value for a literal leading @). | +| `--system-packages ` | No | Replacement Debian package list; replaces the whole list. (space-separated, or @path / @- with one value per line; in a file, blank lines and # comments are ignored, while inline values are sent as typed and may not be empty; @@value for a literal leading @). | -## Update sandbox +API request and response schemas: [updateSandbox](/api-reference/sandboxes/updateSandbox). + +## Delete sandbox + +OAuth login or personal API key required. + +This deletes the sandbox; Function blocks that select it fail until re-pointed. ```bash -sim sandboxes update [options] +sim sandboxes delete [options] ``` -Update Sandbox (OAuth login or personal API key required) - **Arguments** @@ -118,10 +134,12 @@ Update Sandbox (OAuth login or personal API key required) | Option | Required | Description | | --- | --- | --- | -| `--name ` | No | New display name, unique within the workspace; 1 to 64 characters. | -| `--language ` | No | Replacement dependency ecosystem. The whole spec is revalidated against it, so a Python dependency list does not survive a switch to JavaScript. Accepted values: `javascript`, `python`. | -| `--dependencies ` | No | Replacement package list; replaces the whole list. (space-separated, or @path / @- with one value per line; in a file, blank lines and # comments are ignored, while inline values are sent as typed and may not be empty; @@value for a literal leading @). | -| `--cli-tools ` | No | Replacement managed CLI list; replaces the whole list. (space-separated, or @path / @- with one value per line; @@value for a literal leading @). | -| `--system-packages ` | No | Replacement Debian package list; replaces the whole list. (space-separated, or @path / @- with one value per line; in a file, blank lines and # comments are ignored, while inline values are sent as typed and may not be empty; @@value for a literal leading @). | +| `-y, --yes` | Yes | Confirm this operation. | + +API request and response schemas: [deleteSandbox](/api-reference/sandboxes/deleteSandbox). + +## Related docs + +- [Function sandboxes](/workflows/blocks/function#sandboxes) diff --git a/apps/docs/content/docs/cli/scripting.mdx b/apps/docs/content/docs/cli/scripting.mdx index 7c494033d0f..cfa3efff57d 100644 --- a/apps/docs/content/docs/cli/scripting.mdx +++ b/apps/docs/content/docs/cli/scripting.mdx @@ -1,19 +1,24 @@ --- title: Scripting -description: File and stdin inputs, list flags, pagination, exit codes, and automation recipes +description: Pass inputs, paginate results, and handle run and mutation outcomes in scripts. --- import { Callout } from 'fumadocs-ui/components/callout' -Use these patterns to pass inputs, page through results, and handle command outcomes. +Use JSON output and explicit authentication/workspace settings for unattended commands. Enable pipeline failure handling in shell scripts so a failed command is not hidden by a successful parser: -## Reading input from files and stdin +```bash +set -euo pipefail +export SIM_API_KEY="${SIM_API_KEY:?missing}" +export SIM_WORKSPACE="${SIM_WORKSPACE:?missing}" +export SIM_OUTPUT=json +``` + +See [Authentication](/cli/authentication#authenticating-ci) for CI setup. Examples below assume Bash and `jq`. -Any flag that takes JSON or a list also accepts `@path` to read a file, or `@-` -to read stdin. +## Reading input from files and stdin -When Sim runs a command for you, `@path` reads from the chat's sandbox, not from -workspace Files. Use `sim files read` for a workspace path. +JSON flags and primitive-list flags accept `@path` to read a file or `@-` to read stdin: ```bash sim workflows import --workflow @wf.json @@ -21,10 +26,13 @@ sim tables rows query tbl_9f3c1a05d4b7426e8c2f0917ab35de64 --filter @filter.json cat wf.json | sim workflows import --workflow @- ``` +JSON input and the assembled JSON request body have a 10 MiB limit. JSON flags require JSON, including workflow imports; YAML exports must be converted before import. File-aware text flags, such as secret `--value`, are identified in the command reference; ordinary string flags do not all support file input. + +When Sim runs a command inside Chat, `@path` reads the Chat sandbox rather than workspace Files. Use `sim files read` for workspace file content. That embedded invocation has no stdin, so use `@path` or inline input instead of `@-`. + ## List flags -Primitive lists take space-separated values. With `@`, the file supplies one -value per line: +Primitive lists use space-separated values. An input file supplies one value per line: ```bash sim files mv --file-ids wf_3Qm8ZtLpR2yVnKd7BsXwC wf_5Hn1JvTqW9xUcMb4RzPgL --to Archive @@ -32,26 +40,22 @@ sim files mv --file-ids @file-ids.txt --to Archive printf 'wf_3Qm8ZtLpR2yVnKd7BsXwC\nwf_5Hn1JvTqW9xUcMb4RzPgL\n' | sim files mv --file-ids @- --to Archive ``` -Arrays of objects stay JSON. +Empty list entries are rejected. Arrays of objects remain JSON. Dependency-manifest flags can ignore blank lines and `#` comments; this exception does not apply to every list file. ## Passing a literal leading `@` -Because `@` introduces a file reference, a value that genuinely starts with one -is written `@@`. Only the leading `@` is dropped, and every `@`-aware flag -accepts the escape: +File-aware flags interpret a leading `@` as a file reference. Write `@@` to pass a literal leading `@`; only the first character is removed: ```bash sim files share set wf_3Qm8ZtLpR2yVnKd7BsXwC --is-active true --auth-type email --allowed-emails @@example.org sim secrets set API_HOST --scope workspace --value @@internal ``` -Without it, `--allowed-emails @example.org` can only be read as a request to -open a file named `example.org`. +Without escaping, `--allowed-emails @example.org` tries to open a file named `example.org`. ## Filtering table rows -`--filter` takes the same predicate tree the API uses: `all` (AND) or `any` (OR) -groups of `{field, op, value}` conditions, nestable. +`--filter` accepts a predicate tree. Use `all` for AND, `any` for OR, and `{field, op, value}` for a condition. Groups can be nested: ```bash sim tables rows query tbl_9f3c1a05d4b7426e8c2f0917ab35de64 \ @@ -60,11 +64,9 @@ sim tables rows query tbl_9f3c1a05d4b7426e8c2f0917ab35de64 \ --limit 50 ``` -Operators: `eq`, `ne`, `gt`, `gte`, `lt`, `lte`, `in`, `nin`, `contains`, -`ncontains`, `startsWith`, `endsWith`, `like`, `ilike`, `nlike`, `nilike`, -`isEmpty`, `isNotEmpty`, `isNull`, `isNotNull`. +Operators are `eq`, `ne`, `gt`, `gte`, `lt`, `lte`, `in`, `nin`, `contains`, `ncontains`, `startsWith`, `endsWith`, `like`, `ilike`, `nlike`, `nilike`, `isEmpty`, `isNotEmpty`, `isNull`, and `isNotNull`. Supported operators depend on the column type. Omit `value` for the empty/null checks. -`--sort` is also JSON, an ordered list of keys: +`--sort` is an ordered JSON list: ```bash sim tables rows query tbl_9f3c1a05d4b7426e8c2f0917ab35de64 --sort '[{"field":"createdAt","direction":"desc"}]' @@ -72,210 +74,199 @@ sim tables rows query tbl_9f3c1a05d4b7426e8c2f0917ab35de64 --sort '[{"field":"cr ## Pagination -Resource lists and directory `ls` follow every page by default. Pass `--limit N` -to cap the returned items: +Inventory commands such as `workflows list` and `files list`, and resource directory `ls`, fetch all pages by default. Use a limit for a smaller result: ```bash sim workflows list --output json sim files ls /Reports --limit 50 ``` -Table rows (including queries), logs, audit/billing events, workflow runs and -versions, and knowledge documents/chunks retain a default limit of `100`. -Connector document lists also use this cap. Use `--limit 0` to fetch every page -of a large dataset: +Data/history lists default to 100 items, including table rows and queries, logs, audit/billing events, workflow runs/versions, and knowledge documents/chunks. Connector document lists and other bounded collections also use this default. The command reference states each invocation's limit; these CLI limits differ from API per-page defaults. + +`--limit 0` fetches every remaining page: ```bash sim logs list --limit 0 --output json > all-logs.json ``` -Pages are fetched sequentially, accumulated in memory, and printed as one -result. A large table can consume substantial memory; use filters or an explicit -limit when you only need a subset. Each API request fetches at most 100 items. +Pages are fetched sequentially, accumulated in memory, and printed as one result. Each paginated API request fetches at most 100 items. For large datasets, use filters or an explicit limit. -Paginated JSON and YAML results have the shape `{ data: [...], nextCursor }`. -`nextCursor` is the cursor after the last returned row, or `null` when all pages -have been fetched. Scripts that read list rows should use `.data[]`: +Paginated JSON/YAML output has `{ data: [...], nextCursor }`. The cursor follows the last returned row; null ends pagination: ```bash sim logs list --output json | jq -r '.data[].runId' ``` -The capped dataset commands accept `--cursor` to resume from the previous -result's `nextCursor`. Keep the same resource, filters, and sort order, and stop -when the cursor is `null`: +Commands with `--cursor` can continue from the previous result. Keep the same scope, resource, filters, and sort order: ```bash -sim tables rows list tbl_9f3c1a05d4b7426e8c2f0917ab35de64 --limit 100 --output json -sim tables rows list tbl_9f3c1a05d4b7426e8c2f0917ab35de64 --limit 100 --cursor "$nextCursor" --output json +sim tables rows list tbl_9f3c1a05d4b7426e8c2f0917ab35de64 --limit 100 --output json > page.json +if next_cursor=$(jq -er '.nextCursor' page.json); then + sim tables rows list tbl_9f3c1a05d4b7426e8c2f0917ab35de64 --limit 100 --cursor "$next_cursor" --output json +fi ``` -`--limit` applies to each invocation starting at its cursor. `--limit 0` with -`--cursor` fetches every remaining page. Table-row queries, logs (including -billing and audit logs), workflow run/version histories, and knowledge -document/chunk lists all support this continuation. +Run the next command only when the cursor is non-null. `--limit` applies to each invocation starting at its cursor; `--limit 0 --cursor ...` fetches all remaining pages. Table-row queries, logs, billing/audit logs, workflow run/version histories, and knowledge document/chunk lists support continuation. -## Organization access and invitations +## Exit codes + +Results go to stdout; diagnostics go to stderr. JSON/YAML modes serialize API errors as `{error:{code,message,details?}}`. Display formats use `Error:` plus any supplied code/details. Configuration and argument-parser errors, run-wait outcome messages, and unexpected stack traces can remain text. Do not assume every stderr stream is a single JSON document. + +Most successful actions exit 0; API, configuration, or argument failures exit 1. Interactive secret entry cancelled with Ctrl-C exits 130. Other outcomes are command-specific: + +| Code | `sim whoami` | +| --- | --- | +| `0` | Verified, or verification skipped with `--no-verify` | +| `1` | Missing credential or definitive refusal, including workspace access | +| `2` | No verification verdict: unset workspace or unreachable endpoint | + +| Code | `sim workflows runs wait` | +| --- | --- | +| `0` | Completed | +| `1` | Failed run or command/request failure | +| `2` | Cancelled run | +| `3` | Human pause or unspecified pause kind; input is needed | +| `4` | Wait timed out | + +| Code | Workspace operation wait, or import/fork/push/pull with `--wait` | +| --- | --- | +| `0` | Completed, including completion with warnings | +| `1` | Failed completion or command/request failure | +| `3` | Committed operation requires configuration | +| `4` | Wait timed out | + +Both waits default to 3600 seconds; `--wait-timeout 0` waits indefinitely. `SIM_TIMEOUT_SECONDS` independently bounds one API request. A timeout does not cancel the underlying run or operation. -Organization commands use `--organization`; workspace commands use `--workspace` -or the active profile. Use `userId` from `organizations members list` or -`workspaces members list` for member credit limits, including external collaborators. +A synchronous or followed workflow run prints its result before exiting 1 for failure/cancellation. A paused run is not failed and can return 0; use `runs wait` or inspect status if your script requires completion. Fetching a failed run or listing runs only reports their state. -`access-requests mine` shows your requests in the selected scope. Organization -`access-requests list` is the administrator inbox across all organization workspaces. -Use discovery to find the exact target to submit: +Capture a failure without losing its output: ```bash -sim workspaces access-requests discover --workspace "$workspace_id" --state requestable --output json -sim workspaces access-requests create --workspace "$workspace_id" \ - --target '{"kind":"feature","configKey":"hideTablesTab"}' --reason 'Maintain team data' -sim workspaces access-requests mine --workspace "$workspace_id" +if sim workflows run 3a9e21d8-5f47-4c0b-b2ea-91d7c6034ef8 --output json > result.json; then + printf 'command succeeded\n' +else + status=$? + printf 'command exited %s; inspect result.json and stderr\n' "$status" >&2 + exit "$status" +fi ``` -Administrators preview a request before approving it. Inspect `canApply`, `changes`, -and `impact`: permission approvals change the governing group for all affected -members. Pass the reviewed fingerprint explicitly; a conflict means you need a -new preview. +For verification failures, inspect the endpoint, credential, and workspace before logging in again: ```bash -sim organizations access-requests preview "$request_id" --organization "$organization_id" --output json > preview.json -sim organizations access-requests resolve "$request_id" --organization "$organization_id" \ - --action apply --expected-fingerprint "$(jq -r '.fingerprint' preview.json)" +if sim whoami --output json > identity.json; then + : +else + status=$? + case "$status" in + 1) printf 'profile refused; inspect identity.json\n' >&2 ;; + 2) printf 'verification incomplete; check workspace and endpoint\n' >&2 ;; + esac + exit "$status" +fi ``` -For a credit-cap request, applying also requires `--new-limit-credits` greater than -the current cap. To decline instead, use `--action decline --reason 'Explanation'`. +See [Troubleshooting](/cli/troubleshooting) for recovery and reporting unexpected failures. + +## Polling a long run -Administrators can also set a cap directly. `0` prevents further credit-consuming -usage; `null` removes only the per-person cap, so organization limits still apply: +Start asynchronously, retain the run ID, then wait: ```bash -sim organizations members usage-limit update "$user_id" --organization "$organization_id" --credit-limit 5000 -sim organizations members usage-limit update "$user_id" --organization "$organization_id" --credit-limit null +run_id=$(sim workflows run 3a9e21d8-5f47-4c0b-b2ea-91d7c6034ef8 --async --output json | jq -er '.runId') +sim workflows runs wait "$run_id" --workflow 3a9e21d8-5f47-4c0b-b2ea-91d7c6034ef8 --wait-timeout 3600 --output json ``` -Workspace invitations accept a list of up to 50 emails. Recipients are processed -independently. If any fail, the CLI prints the full result and exits `1`; successful -invitations and grants remain committed. Inspect `failed` and current invitations -before retrying, especially when delivery could not be confirmed. +Time-based pauses continue waiting. Human or unspecified pauses return exit 3 and include the pause context needed by `sim workflows runs resume`. Inspect the saved result before resuming; use `sim logs get "$run_id" --trace --output table` for diagnostics. + +Starting another run is not an idempotent retry of the first. After a lost response or wait timeout, inspect the existing run rather than starting another execution blindly. + +## Selecting workflow output + +`--select-output` returns named values in `blockOutputs` on a synchronous run or its streamed result with `--follow`. It cannot be combined with `--async`. Use `blockName.field` selectors; outputs not produced by the run are omitted: ```bash -sim workspaces invitations create --workspace "$workspace_id" \ - --emails alex@example.com sam@example.com --permission write --membership member --output json +sim workflows run 3a9e21d8-5f47-4c0b-b2ea-91d7c6034ef8 --follow --select-output agent_1.content --output json +``` + +For a finished run, `runs get` accepts `blockName.path` or `blockId.path`. Names resolve against the workflow's current blocks: + +```bash +sim workflows runs get "$run_id" --workflow 3a9e21d8-5f47-4c0b-b2ea-91d7c6034ef8 \ + --select-output 1d4c8f02-7b63-4a19-8e52-63f0a7c5d9b1.content --output json ``` ## Destructive commands -Deletions require an explicit selector **and** `--yes`. There is no "delete -everything" default: +Deletion requires an explicit target and `--yes`; omission does not select everything: ```bash sim tables rows batch-delete tbl_9f3c1a05d4b7426e8c2f0917ab35de64 --row row_2f81c0a94db54e6f8a13c7e0526bd94a row_6b3e59d0af1c42d7b80e94f3a271c568 --yes sim files delete wf_8Kd2NpVrY6zTfQa3XwBmS --yes ``` -Without `--yes` the command explains what it would have destroyed and stops. +Without confirmation, the command explains the consequence and stops. Commands that support a non-writing `--dry-run` do not require `--yes` for that preview. -On `batch-delete` and `batch-update`, `--limit` has no default and is not a page -size — it is a ceiling on how many matching rows the one call may touch. Leave it -off and the command acts on **every** row the filter matches, however many that -is. `--limit 0` is not the unbounded form here and is rejected; pass a whole -number of 1 or more to cap the blast radius, or omit the flag deliberately. +For row `batch-delete` and `batch-update`, `--limit` caps how many matching rows one call may change. It has no default: omission affects every matching row. `--limit 0` is rejected; use a whole number of at least 1. On `batch-delete`, an explicit `--row` list cannot be combined with this filter cap. -## Exit codes +Other commands require confirmation for replacement or cancellation too. Read the [command reference](/cli/reference) for consequences, including chat-setting resets and partial table imports. Cancelling an import does not undo rows already written; replace mode clears the table before loading. -| Code | Meaning | -| --- | --- | -| `0` | Success | -| `1` | API/configuration/argument failure, or a failed workflow when using `workflows runs wait` | -| `2` | `whoami`: no verification verdict; `workflows runs wait`: the run was cancelled | -| `3` | `workflows runs wait`: the run is paused for human input | -| `4` | `workflows runs wait`: the wait timed out | -| `130` | Interactive secret entry was cancelled with Ctrl-C | +## Working with folders -Errors print one line to stderr, prefixed `Error:`, plus the API's error code and -validation details when it supplies them. Failures are safe to branch on: +Workflow, table, file, and knowledge-base directories share path commands: ```bash -if ! sim workflows run 3a9e21d8-5f47-4c0b-b2ea-91d7c6034ef8 --output json > result.json; then - echo "run failed" >&2 - exit 1 -fi +sim tables ls Reports +sim tables mkdir Reports/Quarterly +sim tables folders mv Reports/Quarterly Archive/Quarterly +sim tables folders delete Archive --recursive --yes ``` -An unexpected error prints a stack trace — that is a bug in the CLI, so please -[open an issue](https://github.com/simstudioai/sim/issues). - -`sim whoami` splits its failure in two because the fixes differ: `1` means the -credentials are wrong and a fresh `sim login` is the answer, while `2` means the -CLI never got a verdict — no workspace to check against, or an endpoint that did -not answer — and logging in again would not help. +`ls` lists resources at a path and that folder's direct children. It does not descend further. Pass the displayed `ref` to the next command. Use `list` for resources only or `folders ls` for folders only. A leading `/` is optional. -```bash -sim whoami > /dev/null -case $? in - 0) ;; # ready - 1) echo "run: sim login" >&2; exit 1 ;; - 2) echo "endpoint unreachable, retrying later" >&2; exit 75 ;; -esac -``` +## Organization access and invitations -## Selecting workflow output +Organization commands use `--organization`; workspace commands use `--workspace` or the active profile. Get `userId` from `organizations members list` or `workspaces members list` when setting member credit caps, including external collaborators. -`--select-output` returns the named values in `blockOutputs` on a sync run, or -from the streamed result with `--follow`. It cannot be combined with `--async`. -It takes `blockName.field` selectors; fields that a run did not produce are -simply omitted: +`access-requests mine` shows your requests in the selected scope. Organization `access-requests list` is the Admin inbox across organization workspaces. Discover the target before submitting: ```bash -sim workflows run 3a9e21d8-5f47-4c0b-b2ea-91d7c6034ef8 --follow --select-output agent_1.content --output json +sim workspaces access-requests discover --workspace "$workspace_id" --state requestable --output json +sim workspaces access-requests create --workspace "$workspace_id" \ + --target '{"kind":"feature","configKey":"hideTablesTab"}' --reason 'Maintain team data' +sim workspaces access-requests mine --workspace "$workspace_id" ``` -To narrow a run that has already finished, read it back with -`workflows runs get`, which takes the same `blockName.path` or `blockId.path` -selectors; names resolve against the workflow's current blocks: +An Admin previews a request before applying it. Inspect `canApply`, `changes`, and `impact`: a permission approval changes the governing group for all affected members. Apply the reviewed fingerprint; a conflict requires a new preview: ```bash -sim workflows runs get "$run_id" --workflow 3a9e21d8-5f47-4c0b-b2ea-91d7c6034ef8 \ - --select-output 1d4c8f02-7b63-4a19-8e52-63f0a7c5d9b1.content --output json +sim organizations access-requests preview "$request_id" --organization "$organization_id" --output json > preview.json +sim organizations access-requests resolve "$request_id" --organization "$organization_id" \ + --action apply --expected-fingerprint "$(jq -er '.fingerprint' preview.json)" ``` -## Polling a long run +Applying a credit-cap request also requires `--new-limit-credits` greater than the current cap. To decline, use `--action decline --reason 'Explanation'`. -Start the run asynchronously, then use the CLI’s wait command: +An Admin can set a cap directly. Zero prevents further credit-consuming usage; `null` removes only the per-person cap, leaving organization limits in effect: ```bash -run_id=$(sim workflows run 3a9e21d8-5f47-4c0b-b2ea-91d7c6034ef8 --async --output json | jq -r '.runId') -sim workflows runs wait "$run_id" --workflow 3a9e21d8-5f47-4c0b-b2ea-91d7c6034ef8 --wait-timeout 3600 --output json +sim organizations members usage-limit update "$user_id" --organization "$organization_id" --credit-limit 5000 +sim organizations members usage-limit update "$user_id" --organization "$organization_id" --credit-limit null ``` -The command polls until the run completes, fails, is cancelled, or pauses for -human input. Time-based pauses continue waiting. Its exit code identifies the -outcome; `--wait-timeout 0` waits indefinitely. - -Use `sim logs get "$run_id" --trace` for full diagnostics. A run paused for human -input includes the context ID needed by `sim workflows runs resume`. - -## Working with folders - -Every folder-backed resource — `workflows`, `tables`, `files`, `knowledge` — -shares the same path commands: +Workspace invitations accept up to 50 emails. Recipients are processed independently. Any failure makes the CLI print the full result and exit 1; successful invitations and grants remain committed. Inspect `failed` and current invitations before retrying, especially when delivery was uncertain: ```bash -sim tables ls Reports -sim tables mkdir Reports/Quarterly -sim tables folders mv Reports/Quarterly Archive/Quarterly -sim tables folders delete Archive --recursive --yes +sim workspaces invitations create --workspace "$workspace_id" \ + --emails alex@example.com sam@example.com --permission write --membership member --output json ``` -`ls` lists the resources at a path plus that folder's direct children, never -deeper. Its `ref` column is the value to pass to the next command. Use `list` for -resources only, or `folders ls` for folders only. A leading `/` is optional. - ## A nightly job, end to end +This script starts one run, waits for its outcome, and preserves the run ID for recovery. The wait is inside an `if` so `set -e` does not exit before outcome handling: + ```bash title="nightly-digest.sh" #!/usr/bin/env bash set -euo pipefail @@ -284,10 +275,28 @@ export SIM_API_KEY="${SIM_API_KEY:?missing}" export SIM_WORKSPACE="${SIM_WORKSPACE:?missing}" export SIM_OUTPUT=json -run_id=$(sim workflows run 3a9e21d8-5f47-4c0b-b2ea-91d7c6034ef8 --input '{"source":"nightly"}' | jq -r '.runId') +workflow_id=3a9e21d8-5f47-4c0b-b2ea-91d7c6034ef8 +sim workflows run "$workflow_id" --async --input '{"source":"nightly"}' > started.json +run_id=$(jq -er '.runId' started.json) -if [ "$(sim workflows runs get "$run_id" --workflow 3a9e21d8-5f47-4c0b-b2ea-91d7c6034ef8 | jq -r '.status')" != "completed" ]; then - sim logs get "$run_id" >&2 - exit 1 +if sim workflows runs wait "$run_id" --workflow "$workflow_id" --wait-timeout 3600 > result.json; then + exit 0 +else + status=$? fi + +case "$status" in + 1|2) sim logs get "$run_id" --trace --output table >&2 || true ;; + 3) printf 'run %s needs input; inspect result.json before resuming\n' "$run_id" >&2 ;; + 4) printf 'wait expired; inspect existing run %s before retrying\n' "$run_id" >&2 ;; +esac +exit "$status" ``` + +## Related docs + +- [Output formats](/cli/output) +- [Workflow commands](/cli/workflows) +- [Workflow imports and workspace sync](/cli/workflow-sync) +- [Organization commands](/cli/organizations) +- [Troubleshooting](/cli/troubleshooting) diff --git a/apps/docs/content/docs/cli/secrets.mdx b/apps/docs/content/docs/cli/secrets.mdx index 2b6d70dc1f5..1027c17bea1 100644 --- a/apps/docs/content/docs/cli/secrets.mdx +++ b/apps/docs/content/docs/cli/secrets.mdx @@ -1,51 +1,26 @@ --- title: Secrets -description: Manage secrets — every subcommand, argument, and flag +description: Set and manage workspace or personal secrets. --- import { CommandTable } from '@/components/ui/command-table' -`sim secrets` is also spelled `sim secret`. - -Every command below also accepts the [global options](/cli/commands#global-options). - -## Delete secret - -```bash -sim secrets delete [options] -``` - -Delete Secret (OAuth login or personal API key required) - -**Arguments** - - - -| Argument | Required | Description | -| --- | --- | --- | -| `name` | Yes | Secret to delete. | +Set and manage workspace or personal secrets. - - -**Options** - - +Personal secrets belong to the caller across workspaces. Workspace secrets are shared resources. Listings include stored values only for workspace secrets marked visible (unredacted); all other entries contain metadata. -| Option | Required | Description | -| --- | --- | --- | -| `--scope ` | Yes | Whether the secret belongs to the workspace or to the caller. A personal secret belongs to the caller across every workspace, not to one workspace. Accepted values: `workspace`, `personal`. | -| `-y, --yes` | Yes | Confirm this operation. | +`sim secrets` is also spelled `sim secret`. - +These commands accept the [global options](/cli/commands#global-options). ## List secrets +OAuth login or personal API key required. + ```bash sim secrets list [options] ``` -List Secrets (OAuth login or personal API key required) - **Options** @@ -54,20 +29,22 @@ List Secrets (OAuth login or personal API key required) | --- | --- | --- | | `--scope ` | No | Restrict results to one ownership scope. Accepted values: `workspace`, `personal`. | | `--search ` | No | Case-insensitive substring match against the secret name. | -| `--sort-by ` | No | Field used to sort the result. Sorting by `name` is case-sensitive and follows the storage collation, so do not rely on a case-insensitive order. Accepted values: `name`, `createdAt`, `updatedAt`. | -| `--sort-order ` | No | Sort direction. Accepted values: `asc`, `desc`. | +| `--sort-by ` | No | Field used to sort the result. Do not rely on case-insensitive ordering when sorting by `name`. Defaults to "name". Accepted values: `name`, `createdAt`, `updatedAt`. | +| `--sort-order ` | No | Sort direction. Defaults to "asc". Accepted values: `asc`, `desc`. | | `--limit ` | No | Maximum items to return (0 for everything). Defaults to `0`. | +API request and response schemas: [listSecrets](/api-reference/secrets/listSecrets). + ## Create or replace a named secret, such as an API key or environment variable +OAuth login or personal API key required. + ```bash sim secrets set [options] ``` -Create or replace a named secret, such as an API key or environment variable (OAuth login or personal API key required) - **Arguments** @@ -91,3 +68,44 @@ Create or replace a named secret, such as an API key or environment variable (OA | `--no-unredacted` | No | Send --unredacted as false. | + +Omit --value to enter it privately in a terminal. For an existing workspace secret, passing only --description or a redaction flag keeps the stored value and does not prompt. Personal secrets always require a value; they accept no writable metadata. In scripts, pass --value @path or --value @-. + +API request and response schemas: [setSecret](/api-reference/secrets/setSecret). + +## Delete secret + +OAuth login or personal API key required. + +This deletes the secret; anything using it may stop working. + +```bash +sim secrets delete [options] +``` + +**Arguments** + + + +| Argument | Required | Description | +| --- | --- | --- | +| `name` | Yes | Secret to delete. | + + + +**Options** + + + +| Option | Required | Description | +| --- | --- | --- | +| `--scope ` | Yes | Whether the secret belongs to the workspace or to the caller. A personal secret belongs to the caller across every workspace, not to one workspace. Accepted values: `workspace`, `personal`. | +| `-y, --yes` | Yes | Confirm this operation. | + + + +API request and response schemas: [deleteSecret](/api-reference/secrets/deleteSecret). + +## Related docs + +- [Credentials and secrets](/platform/credentials) diff --git a/apps/docs/content/docs/cli/selectors.mdx b/apps/docs/content/docs/cli/selectors.mdx index 6ec54c24305..7a13af40734 100644 --- a/apps/docs/content/docs/cli/selectors.mdx +++ b/apps/docs/content/docs/cli/selectors.mdx @@ -1,50 +1,58 @@ --- title: Selectors -description: Manage selectors — every subcommand, argument, and flag +description: Discover destination options for registered fields, such as calendars, channels, and tables. --- import { CommandTable } from '@/components/ui/command-table' -Every command below also accepts the [global options](/cli/commands#global-options). +Discover destination options for registered fields, such as calendars, channels, and tables. -## Get selector option +A selector key identifies the field’s option source. Its context accepts only declared dependencies; missing OAuth access requires a person to authorize the connection. + +These commands accept the [global options](/cli/commands#global-options). + +## List selector options + +OAuth login or personal API key required. ```bash -sim selectors get [options] +sim selectors list [options] ``` -Get Selector Option (OAuth login or personal API key required) - **Options** | Option | Required | Description | | --- | --- | --- | -| `--selector-key ` | Yes | Registered selector key for discovering this field’s destination options. Accepted values: `airtable.bases`, `airtable.tables`, `asana.workspaces`, `attio.lists`, `attio.objects`, `bigquery.datasets`, `bigquery.tables`, `bitbucket.workspaces`, `bitbucket.repositories`, `calcom.eventTypes`, `calcom.schedules`, `clickup.workspaces`, `clickup.spaces`, `clickup.folders`, `clickup.lists`, `coda.docs`, `coda.pages`, `coda.tables`, `coda.columns`, `coda.rows`, `coda.formulas`, `coda.controls`, `coda.folders`, `coda.permissions`, `confluence.spaces`, `confluence.spacesById`, `confluence.pages`, `google.tasks.lists`, `fivetran.groups`, `fivetran.connections`, `gmail.labels`, `google.calendar`, `google.drive`, `google.sheets`, `harmonic.savedSearches`, `hubspot.lists`, `hubspot.owners`, `hubspot.pipelines`, `hubspot.pipelineStages`, `hubspot.properties`, `jsm.requestTypes`, `jsm.serviceDesks`, `microsoft.planner.plans`, `notion.databases`, `notion.pages`, `netsuite.recordTypes`, `netsuite.asyncTasks`, `pipedrive.pipelines`, `sharepoint.lists`, `trello.boards`, `zoho_desk.organizations`, `zoho_desk.departments`, `zoho_desk.agents`, `zoom.meetings`, `slack.channels`, `snowflake.databases`, `snowflake.schemas`, `snowflake.tables`, `snowflake.warehouses`, `snowflake.roles`, `snowflake.fileFormats`, `snowflake.procedures`, `slack.users`, `outlook.folders`, `outlook.calendars`, `microsoft.teams`, `microsoft.chats`, `microsoft.channels`, `microsoft.planner`, `onedrive.files`, `onedrive.folders`, `sharepoint.sites`, `microsoft.excel`, `microsoft.excel.drives`, `microsoft.excel.sheets`, `microsoft.word`, `wealthbox.contacts`, `jira.issues`, `jira.projects`, `jira.projectKeys`, `linear.projects`, `linear.teams`, `monday.boards`, `monday.groups`, `webflow.sites`, `webflow.collections`, `webflow.items`, `planetscale.databases`, `powerbi.workspaces`, `powerbi.datasets`, `powerbi.reports`, `planetscale.branches`, `planetscale.backups`, `planetscale.deployRequests`, `cloudwatch.logGroups`, `cloudwatch.logStreams`, `imap.mailboxes`, `mcp.tools`, `managedAgent.agents`, `managedAgent.environments`, `managedAgent.vaults`, `managedAgent.memoryStores`, `knowledge.documents`, `sim.workflows`, `table.columns`, `table.outputColumns`, `workspace.secretNames`, `workspace.sandboxes`, `providers.ollamaEmbeddingModels`, `providers.openrouterEmbeddingModels`. | -| `--context ` | No | Only the dependencies declared by the selector, such as oauthCredential and channelId. Missing OAuth connections require human authorization. (JSON, or @path / @- to read a file or stdin). | -| `--id ` | Yes | Resource identifier. | +| `--selector-key ` | Yes | Registered selector key from an import or sync preview, such as `gmail.labels`. Accepted values: `airtable.bases`, `airtable.tables`, `asana.workspaces`, `attio.lists`, `attio.objects`, `bigquery.datasets`, `bigquery.tables`, `bitbucket.workspaces`, `bitbucket.repositories`, `calcom.eventTypes`, `calcom.schedules`, `clickup.workspaces`, `clickup.spaces`, `clickup.folders`, `clickup.lists`, `coda.docs`, `coda.pages`, `coda.tables`, `coda.columns`, `coda.rows`, `coda.formulas`, `coda.controls`, `coda.folders`, `coda.permissions`, `confluence.spaces`, `confluence.spacesById`, `confluence.pages`, `google.tasks.lists`, `fivetran.groups`, `fivetran.connections`, `gmail.labels`, `google.calendar`, `google.drive`, `google.sheets`, `harmonic.savedSearches`, `hubspot.lists`, `hubspot.owners`, `hubspot.pipelines`, `hubspot.pipelineStages`, `hubspot.properties`, `jsm.requestTypes`, `jsm.serviceDesks`, `microsoft.planner.plans`, `notion.databases`, `notion.pages`, `netsuite.recordTypes`, `netsuite.asyncTasks`, `pipedrive.pipelines`, `sharepoint.lists`, `trello.boards`, `zoho_desk.organizations`, `zoho_desk.departments`, `zoho_desk.agents`, `zoom.meetings`, `slack.channels`, `snowflake.databases`, `snowflake.schemas`, `snowflake.tables`, `snowflake.warehouses`, `snowflake.roles`, `snowflake.fileFormats`, `snowflake.procedures`, `slack.users`, `outlook.folders`, `outlook.calendars`, `microsoft.teams`, `microsoft.chats`, `microsoft.channels`, `microsoft.planner`, `onedrive.files`, `onedrive.folders`, `sharepoint.sites`, `microsoft.excel`, `microsoft.excel.drives`, `microsoft.excel.sheets`, `microsoft.word`, `wealthbox.contacts`, `jira.issues`, `jira.projects`, `jira.projectKeys`, `linear.projects`, `linear.teams`, `monday.boards`, `monday.groups`, `webflow.sites`, `webflow.collections`, `webflow.items`, `planetscale.databases`, `powerbi.workspaces`, `powerbi.datasets`, `powerbi.reports`, `planetscale.branches`, `planetscale.backups`, `planetscale.deployRequests`, `cloudwatch.logGroups`, `cloudwatch.logStreams`, `imap.mailboxes`, `mcp.tools`, `managedAgent.agents`, `managedAgent.environments`, `managedAgent.vaults`, `managedAgent.memoryStores`, `knowledge.documents`, `sim.workflows`, `table.columns`, `table.outputColumns`, `workspace.secretNames`, `workspace.sandboxes`, `providers.ollamaEmbeddingModels`, `providers.openrouterEmbeddingModels`. | +| `--context ` | No | Only the dependencies declared by the selector, such as oauthCredential and channelId. Missing OAuth connections require human authorization. Defaults to {}. (JSON, or @path / @- to read a file or stdin). | +| `--search ` | No | Provider option search text. | +| `--cursor ` | No | Continue from nextCursor returned by a previous result. | +| `--limit ` | No | Maximum items to return (0 for everything). Defaults to `100`. | -## List selector options +API request and response schemas: [listSelector](/api-reference/workspace-sync/listSelector). + +## Get selector option + +OAuth login or personal API key required. ```bash -sim selectors list [options] +sim selectors get [options] ``` -List Selector Options (OAuth login or personal API key required) - **Options** | Option | Required | Description | | --- | --- | --- | -| `--selector-key ` | Yes | Registered selector key for discovering this field’s destination options. Accepted values: `airtable.bases`, `airtable.tables`, `asana.workspaces`, `attio.lists`, `attio.objects`, `bigquery.datasets`, `bigquery.tables`, `bitbucket.workspaces`, `bitbucket.repositories`, `calcom.eventTypes`, `calcom.schedules`, `clickup.workspaces`, `clickup.spaces`, `clickup.folders`, `clickup.lists`, `coda.docs`, `coda.pages`, `coda.tables`, `coda.columns`, `coda.rows`, `coda.formulas`, `coda.controls`, `coda.folders`, `coda.permissions`, `confluence.spaces`, `confluence.spacesById`, `confluence.pages`, `google.tasks.lists`, `fivetran.groups`, `fivetran.connections`, `gmail.labels`, `google.calendar`, `google.drive`, `google.sheets`, `harmonic.savedSearches`, `hubspot.lists`, `hubspot.owners`, `hubspot.pipelines`, `hubspot.pipelineStages`, `hubspot.properties`, `jsm.requestTypes`, `jsm.serviceDesks`, `microsoft.planner.plans`, `notion.databases`, `notion.pages`, `netsuite.recordTypes`, `netsuite.asyncTasks`, `pipedrive.pipelines`, `sharepoint.lists`, `trello.boards`, `zoho_desk.organizations`, `zoho_desk.departments`, `zoho_desk.agents`, `zoom.meetings`, `slack.channels`, `snowflake.databases`, `snowflake.schemas`, `snowflake.tables`, `snowflake.warehouses`, `snowflake.roles`, `snowflake.fileFormats`, `snowflake.procedures`, `slack.users`, `outlook.folders`, `outlook.calendars`, `microsoft.teams`, `microsoft.chats`, `microsoft.channels`, `microsoft.planner`, `onedrive.files`, `onedrive.folders`, `sharepoint.sites`, `microsoft.excel`, `microsoft.excel.drives`, `microsoft.excel.sheets`, `microsoft.word`, `wealthbox.contacts`, `jira.issues`, `jira.projects`, `jira.projectKeys`, `linear.projects`, `linear.teams`, `monday.boards`, `monday.groups`, `webflow.sites`, `webflow.collections`, `webflow.items`, `planetscale.databases`, `powerbi.workspaces`, `powerbi.datasets`, `powerbi.reports`, `planetscale.branches`, `planetscale.backups`, `planetscale.deployRequests`, `cloudwatch.logGroups`, `cloudwatch.logStreams`, `imap.mailboxes`, `mcp.tools`, `managedAgent.agents`, `managedAgent.environments`, `managedAgent.vaults`, `managedAgent.memoryStores`, `knowledge.documents`, `sim.workflows`, `table.columns`, `table.outputColumns`, `workspace.secretNames`, `workspace.sandboxes`, `providers.ollamaEmbeddingModels`, `providers.openrouterEmbeddingModels`. | -| `--context ` | No | Only the dependencies declared by the selector, such as oauthCredential and channelId. Missing OAuth connections require human authorization. (JSON, or @path / @- to read a file or stdin). | -| `--search ` | No | Provider option search text. | -| `--cursor ` | No | Continue from nextCursor returned by a previous result. | -| `--limit ` | No | Maximum items to return (0 for everything). Defaults to `100`. | +| `--selector-key ` | Yes | Registered selector key from an import or sync preview, such as `gmail.labels`. Accepted values: `airtable.bases`, `airtable.tables`, `asana.workspaces`, `attio.lists`, `attio.objects`, `bigquery.datasets`, `bigquery.tables`, `bitbucket.workspaces`, `bitbucket.repositories`, `calcom.eventTypes`, `calcom.schedules`, `clickup.workspaces`, `clickup.spaces`, `clickup.folders`, `clickup.lists`, `coda.docs`, `coda.pages`, `coda.tables`, `coda.columns`, `coda.rows`, `coda.formulas`, `coda.controls`, `coda.folders`, `coda.permissions`, `confluence.spaces`, `confluence.spacesById`, `confluence.pages`, `google.tasks.lists`, `fivetran.groups`, `fivetran.connections`, `gmail.labels`, `google.calendar`, `google.drive`, `google.sheets`, `harmonic.savedSearches`, `hubspot.lists`, `hubspot.owners`, `hubspot.pipelines`, `hubspot.pipelineStages`, `hubspot.properties`, `jsm.requestTypes`, `jsm.serviceDesks`, `microsoft.planner.plans`, `notion.databases`, `notion.pages`, `netsuite.recordTypes`, `netsuite.asyncTasks`, `pipedrive.pipelines`, `sharepoint.lists`, `trello.boards`, `zoho_desk.organizations`, `zoho_desk.departments`, `zoho_desk.agents`, `zoom.meetings`, `slack.channels`, `snowflake.databases`, `snowflake.schemas`, `snowflake.tables`, `snowflake.warehouses`, `snowflake.roles`, `snowflake.fileFormats`, `snowflake.procedures`, `slack.users`, `outlook.folders`, `outlook.calendars`, `microsoft.teams`, `microsoft.chats`, `microsoft.channels`, `microsoft.planner`, `onedrive.files`, `onedrive.folders`, `sharepoint.sites`, `microsoft.excel`, `microsoft.excel.drives`, `microsoft.excel.sheets`, `microsoft.word`, `wealthbox.contacts`, `jira.issues`, `jira.projects`, `jira.projectKeys`, `linear.projects`, `linear.teams`, `monday.boards`, `monday.groups`, `webflow.sites`, `webflow.collections`, `webflow.items`, `planetscale.databases`, `powerbi.workspaces`, `powerbi.datasets`, `powerbi.reports`, `planetscale.branches`, `planetscale.backups`, `planetscale.deployRequests`, `cloudwatch.logGroups`, `cloudwatch.logStreams`, `imap.mailboxes`, `mcp.tools`, `managedAgent.agents`, `managedAgent.environments`, `managedAgent.vaults`, `managedAgent.memoryStores`, `knowledge.documents`, `sim.workflows`, `table.columns`, `table.outputColumns`, `workspace.secretNames`, `workspace.sandboxes`, `providers.ollamaEmbeddingModels`, `providers.openrouterEmbeddingModels`. | +| `--context ` | No | Only the dependencies declared by the selector, such as oauthCredential and channelId. Missing OAuth connections require human authorization. Defaults to {}. (JSON, or @path / @- to read a file or stdin). | +| `--id ` | Yes | Provider option ID to resolve with the same selector and declared context. | + +API request and response schemas: [getSelector](/api-reference/workspace-sync/getSelector). diff --git a/apps/docs/content/docs/cli/skills.mdx b/apps/docs/content/docs/cli/skills.mdx index 76bdf2da396..e2bb3753445 100644 --- a/apps/docs/content/docs/cli/skills.mdx +++ b/apps/docs/content/docs/cli/skills.mdx @@ -1,42 +1,45 @@ --- title: Skills -description: Manage skills — every subcommand, argument, and flag +description: Create reusable agent instructions and manage their editors. --- import { CommandTable } from '@/components/ui/command-table' +Create reusable agent instructions and manage their editors. + `sim skills` is also spelled `sim skill`. -Every command below also accepts the [global options](/cli/commands#global-options). +These commands accept the [global options](/cli/commands#global-options). + +## Skill instructions -## Create skill +### List skills ```bash -sim skills create [options] +sim skills list [options] ``` -Create Skill (OAuth login or personal API key required) - **Options** | Option | Required | Description | | --- | --- | --- | -| `--name ` | Yes | Kebab-case name, unique within the workspace and not reserved by a built-in skill. | -| `--description ` | Yes | One-line summary of when the skill applies. | -| `--content ` | Yes | Skill body containing the instructions given to the agent. | +| `--search ` | No | Case-insensitive substring match against the skill name. | +| `--sort-by ` | No | Field used to sort the result. Do not rely on case-insensitive ordering when sorting by `name`. Defaults to "createdAt". Accepted values: `name`, `createdAt`, `updatedAt`. | +| `--sort-order ` | No | Sort direction. Defaults to "desc". Accepted values: `asc`, `desc`. | +| `--limit ` | No | Maximum items to return (0 for everything). Defaults to `0`. | -## Delete skill +API request and response schemas: [listSkills](/api-reference/skills/listSkills). + +### Get skill ```bash -sim skills delete [options] +sim skills get ``` -Delete Skill (OAuth login or personal API key required) - **Arguments** @@ -47,20 +50,36 @@ Delete Skill (OAuth login or personal API key required) +API request and response schemas: [getSkill](/api-reference/skills/getSkill). + +### Create skill + +OAuth login or personal API key required. + +```bash +sim skills create [options] +``` + **Options** | Option | Required | Description | | --- | --- | --- | -| `-y, --yes` | Yes | Confirm this operation. | +| `--name ` | Yes | Kebab-case name, unique within the workspace and not reserved by a built-in skill. | +| `--description ` | Yes | One-line summary of when the skill applies. | +| `--content ` | Yes | Skill body containing the instructions given to the agent. | -## Get skill +API request and response schemas: [createSkill](/api-reference/skills/createSkill). + +### Update skill + +OAuth login or personal API key required. ```bash -sim skills get +sim skills update [options] ``` **Arguments** @@ -73,14 +92,28 @@ sim skills get -## Grant skill editor +**Options** + + + +| Option | Required | Description | +| --- | --- | --- | +| `--name ` | No | New kebab-case skill name. | +| `--description ` | No | New one-line summary of when the skill applies. | +| `--content ` | No | Replacement skill body. | + + + +API request and response schemas: [updateSkill](/api-reference/skills/updateSkill). + +## Editors + +### List skill editors ```bash -sim skills editors create [options] +sim skills editors list [options] ``` -Grant Skill Editor (OAuth login or personal API key required) - **Arguments** @@ -97,14 +130,20 @@ Grant Skill Editor (OAuth login or personal API key required) | Option | Required | Description | | --- | --- | --- | -| `--email ` | Yes | Email address of a current workspace member. | +| `--sort-by ` | No | Field used to sort the result. Do not rely on case-insensitive ordering when sorting by `name`. Defaults to "email". Accepted values: `email`, `name`. | +| `--sort-order ` | No | Sort direction. Defaults to "asc". Accepted values: `asc`, `desc`. | +| `--limit ` | No | Maximum items to return (0 for everything). Defaults to `0`. | -## List skill editors +API request and response schemas: [listSkillEditors](/api-reference/skills/listSkillEditors). + +### Grant skill editor + +OAuth login or personal API key required. ```bash -sim skills editors list [options] +sim skills editors create [options] ``` **Arguments** @@ -123,20 +162,22 @@ sim skills editors list [options] | Option | Required | Description | | --- | --- | --- | -| `--sort-by ` | No | Field used to sort the result. Sorting by `name` is case-sensitive and follows the storage collation, so do not rely on a case-insensitive order. Accepted values: `email`, `name`. | -| `--sort-order ` | No | Sort direction. Accepted values: `asc`, `desc`. | -| `--limit ` | No | Maximum items to return (0 for everything). Defaults to `0`. | +| `--email ` | Yes | Email address of a current workspace member. | -## Revoke skill editor +API request and response schemas: [grantSkillEditor](/api-reference/skills/grantSkillEditor). + +### Revoke skill editor + +OAuth login or personal API key required. + +This revokes the explicit skill editor grant for the selected email. ```bash sim skills editors delete [options] ``` -Revoke Skill Editor (OAuth login or personal API key required) - **Arguments** @@ -158,33 +199,20 @@ Revoke Skill Editor (OAuth login or personal API key required) -## List skills - -```bash -sim skills list [options] -``` - -**Options** +API request and response schemas: [revokeSkillEditor](/api-reference/skills/revokeSkillEditor). - +## Delete skills -| Option | Required | Description | -| --- | --- | --- | -| `--search ` | No | Case-insensitive substring match against the skill name. | -| `--sort-by ` | No | Field used to sort the result. Sorting by `name` is case-sensitive and follows the storage collation, so do not rely on a case-insensitive order. Accepted values: `name`, `createdAt`, `updatedAt`. | -| `--sort-order ` | No | Sort direction. Accepted values: `asc`, `desc`. | -| `--limit ` | No | Maximum items to return (0 for everything). Defaults to `0`. | +### Delete skill - +OAuth login or personal API key required. -## Update skill +This deletes the skill. ```bash -sim skills update [options] +sim skills delete [options] ``` -Update Skill (OAuth login or personal API key required) - **Arguments** @@ -201,8 +229,12 @@ Update Skill (OAuth login or personal API key required) | Option | Required | Description | | --- | --- | --- | -| `--name ` | No | New kebab-case skill name. | -| `--description ` | No | New one-line summary of when the skill applies. | -| `--content ` | No | Replacement skill body. | +| `-y, --yes` | Yes | Confirm this operation. | + +API request and response schemas: [deleteSkill](/api-reference/skills/deleteSkill). + +## Related docs + +- [Skills](/agents/skills) diff --git a/apps/docs/content/docs/cli/tables.mdx b/apps/docs/content/docs/cli/tables.mdx index 79f0a440134..ce1f3e06bec 100644 --- a/apps/docs/content/docs/cli/tables.mdx +++ b/apps/docs/content/docs/cli/tables.mdx @@ -1,44 +1,45 @@ --- title: Tables -description: Manage tables — every subcommand, argument, and flag +description: Manage tables, rows, schemas, views, enrichment runs, imports, and exports. --- import { CommandTable } from '@/components/ui/command-table' +Manage tables, rows, schemas, views, enrichment runs, imports, and exports. + `sim tables` is also spelled `sim table`. -Every command below also accepts the [global options](/cli/commands#global-options). +These commands accept the [global options](/cli/commands#global-options). + +## Tables -## Add column +### List tables ```bash -sim tables columns create [options] +sim tables list [options] ``` -**Arguments** - - - -| Argument | Required | Description | -| --- | --- | --- | -| `tableId` | Yes | Unique table identifier. | - - - **Options** | Option | Required | Description | | --- | --- | --- | -| `--column ` | Yes | Column definition to add. (JSON, or @path / @- to read a file or stdin). | +| `--scope ` | No | Which lifecycle set to list: `active` (default) for live tables, `archived` for tables a delete archived and a table restore can bring back. `folderPath` resolves against active folders only, so pairing it with `scope=archived` returns an empty page when the containing folder was archived too. Accepted values: `active`, `archived`. | +| `--folder ` | No | Folder path as shown in the app; the leading / is optional. | +| `--search ` | No | Case-insensitive substring match against the resource name. | +| `--sort-by ` | No | Field used to sort the result. Do not rely on case-insensitive ordering when sorting by `name`. Defaults to "createdAt". Accepted values: `name`, `createdAt`, `updatedAt`. | +| `--sort-order ` | No | Sort direction. Defaults to "asc". Accepted values: `asc`, `desc`. | +| `--limit ` | No | Maximum items to return (0 for everything). Defaults to `0`. | -## Delete column +API request and response schemas: [listTables](/api-reference/tables/listTables). + +### Get table ```bash -sim tables columns delete [options] +sim tables get ``` **Arguments** @@ -51,21 +52,33 @@ sim tables columns delete [options] +API request and response schemas: [getTable](/api-reference/tables/getTable). + +### Create table + +```bash +sim tables create [options] +``` + **Options** | Option | Required | Description | | --- | --- | --- | -| `--column-name ` | Yes | Name of the column to delete. | -| `-y, --yes` | Yes | Confirm this operation. | +| `--name ` | Yes | Identifier: letters, numbers, and underscores; cannot start with a number. | +| `--description ` | No | Optional table description. | +| `--schema ` | Yes | Table schema: {"columns":[{"name":"email","type":"string"}]} (JSON, or @path / @- to read a file or stdin). | +| `--folder ` | No | Folder path as shown in the app; the leading / is optional. | -## Update column +API request and response schemas: [createTable](/api-reference/tables/createTable). + +### Update table ```bash -sim tables columns update [options] +sim tables update [options] ``` **Arguments** @@ -84,44 +97,59 @@ sim tables columns update [options] | Option | Required | Description | | --- | --- | --- | -| `--column-name ` | Yes | Current name of the column to update. | -| `--updates ` | Yes | Mutable column fields. (JSON, or @path / @- to read a file or stdin). | +| `--name ` | No | Identifier: letters, numbers, and underscores; cannot start with a number. | +| `--description ` | No | Replacement table description, or null to clear it. (--description null sends the word, not JSON null). | +| `--folder ` | No | Folder path as shown in the app; the leading / is optional. | -## Add workflow group +API request and response schemas: [updateTable](/api-reference/tables/updateTable). + +### Move tables and folders ```bash -sim tables groups create [options] +sim tables move [options] ``` -**Arguments** +**Options** -| Argument | Required | Description | +| Option | Required | Description | | --- | --- | --- | -| `tableId` | Yes | Unique table identifier. | +| `--table-ids ` | No | Tables to move, by identifier. Defaults to []. (JSON, or @path / @- to read a file or stdin). | +| `--folder ` | No | Table folders to move, by path as shown in the app; the leading / is optional (space-separated, or @path / @- with one value per line; @@value for a literal leading @). | +| `--to ` | No | Destination folder path; omit for root. | -**Options** +API request and response schemas: [moveTables](/api-reference/tables/moveTables). + +### Move a table to a folder + +```bash +sim tables mv +``` + +**Arguments** -| Option | Required | Description | +| Argument | Required | Description | | --- | --- | --- | -| `--group ` | Yes | Workflow or enrichment producer definition. (JSON, or @path / @- to read a file or stdin). | -| `--output-columns ` | No | Columns to create for producer outputs. An entry naming a column the table already has attaches that column to the group instead of creating it (its `type` must match), and an output whose column already exists may omit its entry entirely — so `[]` attaches existing columns only. (JSON, or @path / @- to read a file or stdin). | -| `--auto-run` | No | Whether to schedule existing rows after group creation. | -| `--no-auto-run` | No | Send --auto-run as false. | +| `tableId` | Yes | Unique table identifier. | +| `folder` | Yes | Folder path as shown in the app; the leading / is optional | -## Delete workflow group +API request and response schemas: [updateTable](/api-reference/tables/updateTable). + +### Delete table + +This archives the table and all of its rows; restore with `tables restore`. ```bash -sim tables groups delete [options] +sim tables delete [options] ``` **Arguments** @@ -140,31 +168,38 @@ sim tables groups delete [options] | Option | Required | Description | | --- | --- | --- | -| `--group-id ` | Yes | Workflow group to delete. | | `-y, --yes` | Yes | Confirm this operation. | -## List workflow groups +API request and response schemas: [deleteTable](/api-reference/tables/deleteTable). + +### Bulk delete tables and folders + +This archives the selected tables and folders, including their rows. Restore eligible tables with `tables restore`. ```bash -sim tables groups list +sim tables batch-delete [options] ``` -**Arguments** +**Options** -| Argument | Required | Description | +| Option | Required | Description | | --- | --- | --- | -| `tableId` | Yes | Unique table identifier. | +| `--table-ids ` | No | Tables to archive, by identifier. Defaults to []. (JSON, or @path / @- to read a file or stdin). | +| `--folder ` | No | Folder path as shown in the app; the leading / is optional (space-separated, or @path / @- with one value per line; @@value for a literal leading @). | +| `-y, --yes` | Yes | Confirm this operation. | -## Update workflow group +API request and response schemas: [bulkDeleteTables](/api-reference/tables/bulkDeleteTables). + +### Restore an archived table ```bash -sim tables groups update [options] +sim tables restore ``` **Arguments** @@ -177,49 +212,45 @@ sim tables groups update [options] -**Options** +API request and response schemas: [restoreTable](/api-reference/tables/restoreTable). + +## Rows and queries + +### List rows + +```bash +sim tables rows list [options] +``` + +**Arguments** -| Option | Required | Description | +| Argument | Required | Description | | --- | --- | --- | -| `--group-id ` | Yes | Workflow group to update. | -| `--workflow-id ` | No | Replacement backing workflow identifier. | -| `--name ` | No | Replacement workflow-group display name. | -| `--dependencies ` | No | Replacement input dependencies. (JSON, or @path / @- to read a file or stdin). | -| `--outputs ` | No | Replacement producer outputs. (JSON, or @path / @- to read a file or stdin). | -| `--new-output-columns ` | No | Columns to add for new outputs. (JSON, or @path / @- to read a file or stdin). | -| `--mapping-updates ` | No | Existing output-column mapping changes. (JSON, or @path / @- to read a file or stdin). | -| `--input-mappings ` | No | Replacement workflow input mappings. (JSON, or @path / @- to read a file or stdin). | -| `--deployment-mode ` | No | Replacement workflow execution mode. Accepted values: `live`, `deployed`. | -| `--type ` | No | Workflow-group producer type. Must match the group's stored type — a group's producer cannot be changed after creation. Accepted values: `manual`, `enrichment`. | -| `--auto-run` | No | Replacement automatic-run setting. | -| `--no-auto-run` | No | Send --auto-run as false. | +| `tableId` | Yes | Unique table identifier. | -## Bulk delete tables and folders - -```bash -sim tables batch-delete [options] -``` - **Options** | Option | Required | Description | | --- | --- | --- | -| `--table-ids ` | No | Tables to archive, by identifier. (JSON, or @path / @- to read a file or stdin). | -| `--folder ` | No | Folder path as shown in the app; the leading / is optional (space-separated, or @path / @- with one value per line; @@value for a literal leading @). | -| `-y, --yes` | Yes | Confirm this operation. | +| `--limit ` | No | Maximum items to return (0 for everything). Defaults to `100`. | +| `--cursor ` | No | Continue from nextCursor returned by a previous result. | +| `--include-run-state` | No | Include per-workflow-group run outcomes on every row. Off by default. Caps `limit` at 200. Run state above 2 MiB returns `413`; request fewer rows or omit run state. | +| `--no-include-run-state` | No | Send --include-run-state as false. | -## Apply a distinct patch to each listed row +API request and response schemas: [listTableRows](/api-reference/tables/listTableRows). + +### Get row ```bash -sim tables rows update-each [options] +sim tables rows get [options] ``` **Arguments** @@ -229,6 +260,7 @@ sim tables rows update-each [options] | Argument | Required | Description | | --- | --- | --- | | `tableId` | Yes | Unique table identifier. | +| `rowId` | Yes | Unique table row identifier. | @@ -238,14 +270,17 @@ sim tables rows update-each [options] | Option | Required | Description | | --- | --- | --- | -| `--updates ` | Yes | One merge patch per row. Each row identifier may appear at most once. (JSON, or @path / @- to read a file or stdin). | +| `--include-run-state` | No | Include per-workflow-group run outcomes on the row. Off by default. Run state above 2 MiB returns `413`; omit this option to read the row without run state. | +| `--no-include-run-state` | No | Send --include-run-state as false. | -## Create rows +API request and response schemas: [getTableRow](/api-reference/tables/getTableRow). + +### Query rows with a filter and sort ```bash -sim tables rows create [options] +sim tables rows query [options] ``` **Arguments** @@ -264,15 +299,21 @@ sim tables rows create [options] | Option | Required | Description | | --- | --- | --- | -| `--data ` | No | One row keyed by column name (JSON, or @path / @-; choose exactly one body flag). | -| `--rows ` | No | Several rows keyed by column name (JSON, or @path / @-; choose exactly one body flag). | +| `--filter ` | No | Condition: {"field":"status","op":"eq","value":"active"}. Groups: {"all":[{"field":"status","op":"eq","value":"active"}]} or {"any":[{"field":"status","op":"eq","value":"active"}]}; group entries may also be nested groups. Operators: eq, ne, gt, gte, lt, lte, in, nin, contains, ncontains, startsWith, endsWith, like, ilike, nlike, nilike, isEmpty, isNotEmpty, isNull, isNotNull (JSON, or @path / @- to read a file or stdin). | +| `--sort ` | No | Ordered sort keys: [{"field":"createdAt","direction":"desc"}] (direction: asc or desc) (JSON, or @path / @- to read a file or stdin). | +| `--limit ` | No | Maximum items to return (0 for everything). Defaults to `100`. | +| `--cursor ` | No | Continue from nextCursor returned by a previous result. | +| `--include-run-state` | No | Include per-workflow-group run outcomes on every row. Off by default. Each request above 2 MiB of run state returns 413; request fewer rows or omit run state. CLI --limit 0 still fetches bounded pages. | +| `--no-include-run-state` | No | Send --include-run-state as false. | -## Delete row +API request and response schemas: [queryRows](/api-reference/tables/queryTableRows). + +### Count rows matching a filter ```bash -sim tables rows delete [options] +sim tables rows count [options] ``` **Arguments** @@ -282,7 +323,6 @@ sim tables rows delete [options] | Argument | Required | Description | | --- | --- | --- | | `tableId` | Yes | Unique table identifier. | -| `rowId` | Yes | Unique table row identifier. | @@ -292,14 +332,16 @@ sim tables rows delete [options] | Option | Required | Description | | --- | --- | --- | -| `-y, --yes` | Yes | Confirm this operation. | +| `--filter ` | No | Condition: {"field":"status","op":"eq","value":"active"}. Groups: {"all":[{"field":"status","op":"eq","value":"active"}]} or {"any":[{"field":"status","op":"eq","value":"active"}]}; group entries may also be nested groups. Operators: eq, ne, gt, gte, lt, lte, in, nin, contains, ncontains, startsWith, endsWith, like, ilike, nlike, nilike, isEmpty, isNotEmpty, isNull, isNotNull (JSON, or @path / @- to read a file or stdin). | -## Delete rows matching a filter, or an explicit list of ids +API request and response schemas: [queryRowsCount](/api-reference/tables/countTableRows). + +### Search cells for a value and return their coordinates ```bash -sim tables rows batch-delete [options] +sim tables rows search [options] ``` **Arguments** @@ -318,17 +360,18 @@ sim tables rows batch-delete [options] | Option | Required | Description | | --- | --- | --- | +| `--query ` | Yes | Value to search for. | | `--filter ` | No | Predicate: {"all":[{"field":"status","op":"eq","value":"active"}]}; groups use all/any. Operators: eq, ne, gt, gte, lt, lte, in, nin, contains, ncontains, startsWith, endsWith, like, ilike, nlike, nilike, isEmpty, isNotEmpty, isNull, isNotNull (JSON, or @path / @- to read a file or stdin). | -| `--limit ` | No | Maximum matching rows to delete. (caps a --filter match only; omit it to act on every match, and note 0 is not accepted). | -| `--row ` | No | Explicit row identifiers to delete. (space-separated, or @path / @- with one value per line; @@value for a literal leading @). | -| `-y, --yes` | Yes | Confirm this operation. | +| `--sort ` | No | Ordered sort keys: [{"field":"createdAt","direction":"desc"}] (direction: asc or desc) (JSON, or @path / @- to read a file or stdin). | -## Get row +API request and response schemas: [searchTableRows](/api-reference/tables/searchTableRows). + +### Create rows ```bash -sim tables rows get [options] +sim tables rows create [options] ``` **Arguments** @@ -338,7 +381,6 @@ sim tables rows get [options] | Argument | Required | Description | | --- | --- | --- | | `tableId` | Yes | Unique table identifier. | -| `rowId` | Yes | Unique table row identifier. | @@ -348,15 +390,17 @@ sim tables rows get [options] | Option | Required | Description | | --- | --- | --- | -| `--include-run-state` | No | Include per-workflow-group run state on the returned row. Off by default. | -| `--no-include-run-state` | No | Send --include-run-state as false. | +| `--data ` | No | One row keyed by column name (JSON, or @path / @-; choose exactly one body flag). | +| `--rows ` | No | Several rows keyed by column name (JSON, or @path / @-; choose exactly one body flag). | -## List rows +API request and response schemas: [createTableRows](/api-reference/tables/createTableRows). + +### Update row ```bash -sim tables rows list [options] +sim tables rows update [options] ``` **Arguments** @@ -366,6 +410,7 @@ sim tables rows list [options] | Argument | Required | Description | | --- | --- | --- | | `tableId` | Yes | Unique table identifier. | +| `rowId` | Yes | Unique table row identifier. | @@ -375,17 +420,16 @@ sim tables rows list [options] | Option | Required | Description | | --- | --- | --- | -| `--limit ` | No | Maximum items to return (0 for everything). Defaults to `100`. | -| `--cursor ` | No | Continue from nextCursor returned by a previous result. | -| `--include-run-state` | No | Include per-workflow-group run state on every returned row. Off by default: run state is a separate sidecar read and its `blockErrors` are unbounded, so a full page carries it only when asked. Caps `limit` at 200. | -| `--no-include-run-state` | No | Send --include-run-state as false. | +| `--data ` | Yes | Partial row-data patch keyed by column name. (JSON, or @path / @- to read a file or stdin). | -## Query rows with a filter and sort +API request and response schemas: [updateTableRow](/api-reference/tables/updateTableRow). + +### Apply a distinct patch to each listed row ```bash -sim tables rows query [options] +sim tables rows update-each [options] ``` **Arguments** @@ -404,19 +448,18 @@ sim tables rows query [options] | Option | Required | Description | | --- | --- | --- | -| `--filter ` | No | Condition: {"field":"status","op":"eq","value":"active"}. Groups: {"all":[{"field":"status","op":"eq","value":"active"}]} or {"any":[{"field":"status","op":"eq","value":"active"}]}; group entries may also be nested groups. Operators: eq, ne, gt, gte, lt, lte, in, nin, contains, ncontains, startsWith, endsWith, like, ilike, nlike, nilike, isEmpty, isNotEmpty, isNull, isNotNull (JSON, or @path / @- to read a file or stdin). | -| `--sort ` | No | Ordered sort keys: [{"field":"createdAt","direction":"desc"}] (direction: asc or desc) (JSON, or @path / @- to read a file or stdin). | -| `--limit ` | No | Maximum items to return (0 for everything). Defaults to `100`. | -| `--cursor ` | No | Continue from nextCursor returned by a previous result. | -| `--include-run-state` | No | Include per-workflow-group run state on every returned row. Off by default: run state is a separate sidecar read and its `blockErrors` are unbounded, so a full page carries it only when asked. Incompatible with `limit: 0`, and caps `limit` at 200. | -| `--no-include-run-state` | No | Send --include-run-state as false. | +| `--updates ` | Yes | One merge patch per row. Each row identifier may appear at most once. (JSON, or @path / @- to read a file or stdin). | -## Count rows matching a filter +API request and response schemas: [bulkUpdateTableRows](/api-reference/tables/bulkUpdateTableRows). + +### Update every row matching a filter + +This updates every matching row and cannot be undone. ```bash -sim tables rows count [options] +sim tables rows batch-update [options] ``` **Arguments** @@ -435,11 +478,16 @@ sim tables rows count [options] | Option | Required | Description | | --- | --- | --- | -| `--filter ` | No | Condition: {"field":"status","op":"eq","value":"active"}. Groups: {"all":[{"field":"status","op":"eq","value":"active"}]} or {"any":[{"field":"status","op":"eq","value":"active"}]}; group entries may also be nested groups. Operators: eq, ne, gt, gte, lt, lte, in, nin, contains, ncontains, startsWith, endsWith, like, ilike, nlike, nilike, isEmpty, isNotEmpty, isNull, isNotNull (JSON, or @path / @- to read a file or stdin). | +| `--filter ` | Yes | Predicate: {"all":[{"field":"status","op":"eq","value":"active"}]}; groups use all/any. Operators: eq, ne, gt, gte, lt, lte, in, nin, contains, ncontains, startsWith, endsWith, like, ilike, nlike, nilike, isEmpty, isNotEmpty, isNull, isNotNull (JSON, or @path / @- to read a file or stdin). | +| `--data ` | Yes | Row-data patch applied to every matching row. (JSON, or @path / @- to read a file or stdin). | +| `--limit ` | No | Maximum matching rows to update. (caps a --filter match only; omit it to act on every match, and note 0 is not accepted). | +| `-y, --yes` | Yes | Confirm this operation. | -## Run one row’s enrichment group +API request and response schemas: [updateRowsByFilter](/api-reference/tables/updateTableRows). + +### Run one row’s enrichment group ```bash sim tables rows enrich @@ -457,10 +505,14 @@ sim tables rows enrich -## Search cells for a value and return their coordinates +API request and response schemas: [runRowEnrichment](/api-reference/tables/runRowEnrichment). + +### Delete row + +This deletes the row. ```bash -sim tables rows search [options] +sim tables rows delete [options] ``` **Arguments** @@ -470,6 +522,7 @@ sim tables rows search [options] | Argument | Required | Description | | --- | --- | --- | | `tableId` | Yes | Unique table identifier. | +| `rowId` | Yes | Unique table row identifier. | @@ -479,16 +532,18 @@ sim tables rows search [options] | Option | Required | Description | | --- | --- | --- | -| `--query ` | Yes | Value to search for. | -| `--filter ` | No | Predicate: {"all":[{"field":"status","op":"eq","value":"active"}]}; groups use all/any. Operators: eq, ne, gt, gte, lt, lte, in, nin, contains, ncontains, startsWith, endsWith, like, ilike, nlike, nilike, isEmpty, isNotEmpty, isNull, isNotNull (JSON, or @path / @- to read a file or stdin). | -| `--sort ` | No | Ordered sort keys: [{"field":"createdAt","direction":"desc"}] (direction: asc or desc) (JSON, or @path / @- to read a file or stdin). | +| `-y, --yes` | Yes | Confirm this operation. | -## Update every row matching a filter +API request and response schemas: [deleteTableRow](/api-reference/tables/deleteTableRow). + +### Delete rows matching a filter, or an explicit list of ids + +This deletes every matching row and cannot be undone. ```bash -sim tables rows batch-update [options] +sim tables rows batch-delete [options] ``` **Arguments** @@ -507,17 +562,19 @@ sim tables rows batch-update [options] | Option | Required | Description | | --- | --- | --- | -| `--filter ` | Yes | Predicate: {"all":[{"field":"status","op":"eq","value":"active"}]}; groups use all/any. Operators: eq, ne, gt, gte, lt, lte, in, nin, contains, ncontains, startsWith, endsWith, like, ilike, nlike, nilike, isEmpty, isNotEmpty, isNull, isNotNull (JSON, or @path / @- to read a file or stdin). | -| `--data ` | Yes | Row-data patch applied to every matching row. (JSON, or @path / @- to read a file or stdin). | -| `--limit ` | No | Maximum matching rows to update. (caps a --filter match only; omit it to act on every match, and note 0 is not accepted). | +| `--filter ` | No | Predicate: {"all":[{"field":"status","op":"eq","value":"active"}]}; groups use all/any. Operators: eq, ne, gt, gte, lt, lte, in, nin, contains, ncontains, startsWith, endsWith, like, ilike, nlike, nilike, isEmpty, isNotEmpty, isNull, isNotNull (JSON, or @path / @- to read a file or stdin). | +| `--limit ` | No | Maximum matching rows to delete. (caps a --filter match only; omit it to act on every match, and note 0 is not accepted). | +| `--row ` | No | Explicit row identifiers to delete. (space-separated, or @path / @- with one value per line; @@value for a literal leading @). | | `-y, --yes` | Yes | Confirm this operation. | -## Update row +API request and response schemas: [deleteTableRows](/api-reference/tables/deleteTableRows). + +### Insert a row, or replace the one matching a unique column ```bash -sim tables rows update [options] +sim tables upsert [options] ``` **Arguments** @@ -527,7 +584,6 @@ sim tables rows update [options] | Argument | Required | Description | | --- | --- | --- | | `tableId` | Yes | Unique table identifier. | -| `rowId` | Yes | Unique table row identifier. | @@ -537,14 +593,19 @@ sim tables rows update [options] | Option | Required | Description | | --- | --- | --- | -| `--data ` | Yes | Partial row-data patch keyed by column name. (JSON, or @path / @- to read a file or stdin). | +| `--data ` | Yes | Complete set of row cells keyed by column name. On the update branch this REPLACES the matched row: any column not present here is cleared, unlike a single-row update, which merges. (JSON, or @path / @- to read a file or stdin). | +| `--on ` | No | Unique column to resolve the conflict against. | -## Cancel a running dispatch +API request and response schemas: [upsertTableRow](/api-reference/tables/upsertTableRow). + +## Columns + +### Add column ```bash -sim tables dispatches cancel [options] +sim tables columns create [options] ``` **Arguments** @@ -554,7 +615,6 @@ sim tables dispatches cancel [options] | Argument | Required | Description | | --- | --- | --- | | `tableId` | Yes | Unique table identifier. | -| `dispatchId` | Yes | Unique table run-dispatch identifier. | @@ -564,14 +624,16 @@ sim tables dispatches cancel [options] | Option | Required | Description | | --- | --- | --- | -| `-y, --yes` | Yes | Confirm this operation. | +| `--column ` | Yes | Column definition to add. (JSON, or @path / @- to read a file or stdin). | -## Start a column or enrichment run +API request and response schemas: [addTableColumn](/api-reference/tables/addTableColumn). + +### Update column ```bash -sim tables dispatches create [options] +sim tables columns update [options] ``` **Arguments** @@ -590,19 +652,19 @@ sim tables dispatches create [options] | Option | Required | Description | | --- | --- | --- | -| `--group-ids ` | Yes | Workflow or enrichment groups to run. (space-separated, or @path / @- with one value per line; @@value for a literal leading @). | -| `--run-mode ` | No | Whether to run all or only incomplete cells. Accepted values: `all`, `incomplete`. | -| `--row-ids ` | No | Explicit row subset to run. (space-separated, or @path / @- with one value per line; @@value for a literal leading @). | -| `--filter ` | No | Predicate: {"all":[{"field":"status","op":"eq","value":"active"}]}; groups use all/any. Operators: eq, ne, gt, gte, lt, lte, in, nin, contains, ncontains, startsWith, endsWith, like, ilike, nlike, nilike, isEmpty, isNotEmpty, isNull, isNotNull (JSON, or @path / @- to read a file or stdin). | -| `--exclude-row-ids ` | No | Rows excluded from a select-all run scope. (space-separated, or @path / @- with one value per line; @@value for a literal leading @). | -| `--max-rows ` | No | Stop after this many eligible rows have run (1-1,000,000). Omit for an unbounded run. | +| `--column-name ` | Yes | Current name of the column to update. | +| `--updates ` | Yes | Mutable column fields. (JSON, or @path / @- to read a file or stdin). | -## Get run dispatch +API request and response schemas: [updateTableColumn](/api-reference/tables/updateTableColumn). + +### Delete column + +This deletes the column and its values in every row. ```bash -sim tables dispatches get +sim tables columns delete [options] ``` **Arguments** @@ -612,14 +674,28 @@ sim tables dispatches get | Argument | Required | Description | | --- | --- | --- | | `tableId` | Yes | Unique table identifier. | -| `dispatchId` | Yes | Unique table run-dispatch identifier. | -## List run dispatches +**Options** + + + +| Option | Required | Description | +| --- | --- | --- | +| `--column-name ` | Yes | Name of the column to delete. | +| `-y, --yes` | Yes | Confirm this operation. | + + + +API request and response schemas: [deleteTableColumn](/api-reference/tables/deleteTableColumn). + +## Saved views + +### List views ```bash -sim tables dispatches list +sim tables views list ``` **Arguments** @@ -632,10 +708,12 @@ sim tables dispatches list -## Stop a running export +API request and response schemas: [listTableViews](/api-reference/tables/listTableViews). + +### Get view ```bash -sim tables exports cancel +sim tables views get ``` **Arguments** @@ -645,14 +723,16 @@ sim tables exports cancel | Argument | Required | Description | | --- | --- | --- | | `tableId` | Yes | Unique table identifier. | -| `exportId` | Yes | Unique table-export identifier. | +| `viewId` | Yes | Unique saved-view identifier. | -## Create table export +API request and response schemas: [getTableView](/api-reference/tables/getTableView). + +### Create view ```bash -sim tables exports create [options] +sim tables views create [options] ``` **Arguments** @@ -671,14 +751,17 @@ sim tables exports create [options] | Option | Required | Description | | --- | --- | --- | -| `--format ` | No | Export file format. Accepted values: `csv`, `json`. | +| `--name ` | Yes | Saved-view display name. | +| `--config ` | Yes | Saved filter, sort, and column-layout configuration. (JSON, or @path / @- to read a file or stdin). | -## Get table export +API request and response schemas: [createTableView](/api-reference/tables/createTableView). + +### Update view ```bash -sim tables exports get +sim tables views update [options] ``` **Arguments** @@ -688,31 +771,32 @@ sim tables exports get | Argument | Required | Description | | --- | --- | --- | | `tableId` | Yes | Unique table identifier. | -| `exportId` | Yes | Unique table-export identifier. | +| `viewId` | Yes | Unique saved-view identifier. | -## Get the download URL for a finished export - -```bash -sim tables exports download -``` - -**Arguments** +**Options** -| Argument | Required | Description | +| Option | Required | Description | | --- | --- | --- | -| `tableId` | Yes | Unique table identifier. | -| `exportId` | Yes | Unique table-export identifier. | +| `--name ` | No | Replacement saved-view display name. | +| `--config ` | No | Complete replacement saved-view configuration. (JSON, or @path / @- to read a file or stdin). | +| `--config-patch ` | No | Saved-view configuration fields to shallow-merge. (JSON, or @path / @- to read a file or stdin). | +| `--default` | No | Whether to promote this view to the table default. | +| `--no-default` | No | Send --default as false. | -## Stop a running import +API request and response schemas: [updateTableView](/api-reference/tables/updateTableView). + +### Delete view + +This deletes the saved view and its filters. ```bash -sim tables imports cancel [options] +sim tables views delete [options] ``` **Arguments** @@ -721,7 +805,8 @@ sim tables imports cancel [options] | Argument | Required | Description | | --- | --- | --- | -| `importId` | Yes | Unique table-import identifier. | +| `tableId` | Yes | Unique table identifier. | +| `viewId` | Yes | Unique saved-view identifier. | @@ -735,10 +820,14 @@ sim tables imports cancel [options] -## Get table import +API request and response schemas: [deleteTableView](/api-reference/tables/deleteTableView). + +## Producer groups and runs + +### List workflow groups ```bash -sim tables imports get +sim tables groups list ``` **Arguments** @@ -747,14 +836,16 @@ sim tables imports get | Argument | Required | Description | | --- | --- | --- | -| `importId` | Yes | Unique table-import identifier. | +| `tableId` | Yes | Unique table identifier. | -## Stop every running column job +API request and response schemas: [listWorkflowGroups](/api-reference/tables/listTableWorkflowGroups). + +### Add workflow group ```bash -sim tables cancel-runs [options] +sim tables groups create [options] ``` **Arguments** @@ -773,53 +864,60 @@ sim tables cancel-runs [options] | Option | Required | Description | | --- | --- | --- | -| `--scope ` | Yes | Whether to cancel across the table or one row. Accepted values: `all`, `row`. | -| `--row-id ` | No | Row whose runs should be canceled for row scope. | -| `--filter ` | No | Predicate: {"all":[{"field":"status","op":"eq","value":"active"}]}; groups use all/any. Operators: eq, ne, gt, gte, lt, lte, in, nin, contains, ncontains, startsWith, endsWith, like, ilike, nlike, nilike, isEmpty, isNotEmpty, isNull, isNotNull (JSON, or @path / @- to read a file or stdin). | -| `--exclude-row-ids ` | No | Rows excluded from an all-scope cancellation. (space-separated, or @path / @- with one value per line; @@value for a literal leading @). | -| `-y, --yes` | Yes | Confirm this operation. | +| `--group ` | Yes | Workflow or enrichment producer definition. (JSON, or @path / @- to read a file or stdin). | +| `--output-columns ` | No | Columns to create for producer outputs. An entry naming a column the table already has attaches that column to the group instead of creating it (its `type` must match), and an output whose column already exists may omit its entry entirely — so `[]` attaches existing columns only. Defaults to []. (JSON, or @path / @- to read a file or stdin). | +| `--auto-run` | No | Whether to schedule existing rows after group creation. Defaults to false. | +| `--no-auto-run` | No | Send --auto-run as false. | -## Create table +API request and response schemas: [addWorkflowGroup](/api-reference/tables/addTableWorkflowGroup). + +### Update workflow group ```bash -sim tables create [options] +sim tables groups update [options] ``` -**Options** +**Arguments** -| Option | Required | Description | +| Argument | Required | Description | | --- | --- | --- | -| `--name ` | Yes | Identifier: letters, numbers, and underscores; cannot start with a number. | -| `--description ` | No | Optional table description. | -| `--schema ` | Yes | Table schema: {"columns":[{"name":"email","type":"string"}]} (JSON, or @path / @- to read a file or stdin). | -| `--folder ` | No | Folder path as shown in the app; the leading / is optional. | +| `tableId` | Yes | Unique table identifier. | -## Create a table folder at a path - -```bash -sim tables folders create -``` - -**Arguments** +**Options** -| Argument | Required | Description | +| Option | Required | Description | | --- | --- | --- | -| `path` | Yes | Folder path as shown in the app; the leading / is optional | +| `--group-id ` | Yes | Workflow group to update. | +| `--workflow-id ` | No | Replacement backing workflow identifier. | +| `--name ` | No | Replacement workflow-group display name. | +| `--dependencies ` | No | Replacement input dependencies. (JSON, or @path / @- to read a file or stdin). | +| `--outputs ` | No | Replacement producer outputs. (JSON, or @path / @- to read a file or stdin). | +| `--new-output-columns ` | No | Columns to add for new outputs. (JSON, or @path / @- to read a file or stdin). | +| `--mapping-updates ` | No | Existing output-column mapping changes. (JSON, or @path / @- to read a file or stdin). | +| `--input-mappings ` | No | Replacement workflow input mappings. (JSON, or @path / @- to read a file or stdin). | +| `--deployment-mode ` | No | Replacement workflow execution mode. Accepted values: `live`, `deployed`. | +| `--type ` | No | Workflow-group producer type. Must match the group's stored type — a group's producer cannot be changed after creation. Accepted values: `manual`, `enrichment`. | +| `--auto-run` | No | Replacement automatic-run setting. | +| `--no-auto-run` | No | Send --auto-run as false. | -## Delete folder +API request and response schemas: [updateWorkflowGroup](/api-reference/tables/updateTableWorkflowGroup). + +### Delete workflow group + +This deletes the group AND its output columns with all of their row data; the workflow it pointed at is untouched. ```bash -sim tables folders delete [options] +sim tables groups delete [options] ``` **Arguments** @@ -828,7 +926,7 @@ sim tables folders delete [options] | Argument | Required | Description | | --- | --- | --- | -| `path` | Yes | Folder path as shown in the app; the leading / is optional | +| `tableId` | Yes | Unique table identifier. | @@ -838,55 +936,55 @@ sim tables folders delete [options] | Option | Required | Description | | --- | --- | --- | -| `--recursive` | No | Delete the folder and its descendants. | +| `--group-id ` | Yes | Workflow group to delete. | | `-y, --yes` | Yes | Confirm this operation. | -## List table folders +API request and response schemas: [deleteWorkflowGroup](/api-reference/tables/deleteTableWorkflowGroup). + +### Get row group run ```bash -sim tables folders list [options] +sim tables enrichment get ``` -Also available as `sim tables folders ls`. - -**Options** +**Arguments** -| Option | Required | Description | +| Argument | Required | Description | | --- | --- | --- | -| `--parent ` | No | Direct parent folder path. | -| `--search ` | No | Case-insensitive substring match against the folder name. | -| `--sort-by ` | No | Field used to sort the result. Sorting by `name` is case-sensitive and follows the storage collation, so do not rely on a case-insensitive order. Accepted values: `name`, `createdAt`, `updatedAt`. | -| `--sort-order ` | No | Sort direction. Accepted values: `asc`, `desc`. | +| `tableId` | Yes | Unique table identifier. | +| `rowId` | Yes | Unique table row identifier. | +| `groupId` | Yes | Workflow or enrichment group to run. | -## Rename or move a table folder +API request and response schemas: [getRowEnrichment](/api-reference/tables/getRowEnrichment). + +### List run dispatches ```bash -sim tables folders move +sim tables dispatches list ``` -Also available as `sim tables folders mv`. - **Arguments** | Argument | Required | Description | | --- | --- | --- | -| `path` | Yes | Folder path as shown in the app; the leading / is optional | -| `destination` | Yes | Folder path as shown in the app; the leading / is optional | +| `tableId` | Yes | Unique table identifier. | -## Restore an archived table folder +API request and response schemas: [listTableDispatches](/api-reference/tables/listTableDispatches). + +### Get run dispatch ```bash -sim tables folders restore +sim tables dispatches get ``` **Arguments** @@ -895,14 +993,17 @@ sim tables folders restore | Argument | Required | Description | | --- | --- | --- | -| `path` | Yes | Folder path as shown in the app; the leading / is optional | +| `tableId` | Yes | Unique table identifier. | +| `dispatchId` | Yes | Unique table run-dispatch identifier. | -## Create view +API request and response schemas: [getTableDispatch](/api-reference/tables/getTableDispatch). + +### Start a column or enrichment run ```bash -sim tables views create [options] +sim tables dispatches create [options] ``` **Arguments** @@ -921,15 +1022,23 @@ sim tables views create [options] | Option | Required | Description | | --- | --- | --- | -| `--name ` | Yes | Saved-view display name. | -| `--config ` | Yes | Saved filter, sort, and column-layout configuration. (JSON, or @path / @- to read a file or stdin). | +| `--group-ids ` | Yes | Workflow or enrichment groups to run. (space-separated, or @path / @- with one value per line; @@value for a literal leading @). | +| `--run-mode ` | No | Whether to run all or only incomplete cells. Defaults to "all". Accepted values: `all`, `incomplete`. | +| `--row-ids ` | No | Explicit row subset to run. (space-separated, or @path / @- with one value per line; @@value for a literal leading @). | +| `--filter ` | No | Predicate: {"all":[{"field":"status","op":"eq","value":"active"}]}; groups use all/any. Operators: eq, ne, gt, gte, lt, lte, in, nin, contains, ncontains, startsWith, endsWith, like, ilike, nlike, nilike, isEmpty, isNotEmpty, isNull, isNotNull (JSON, or @path / @- to read a file or stdin). | +| `--exclude-row-ids ` | No | Rows excluded from a select-all run scope. (space-separated, or @path / @- with one value per line; @@value for a literal leading @). | +| `--max-rows ` | No | Stop after this many eligible rows have run (1-1,000,000). Omit for an unbounded run. | -## Delete view +API request and response schemas: [createTableDispatch](/api-reference/tables/createTableDispatch). + +### Cancel a running dispatch + +This stops the dispatch. Cells already handed to the queue keep running — use `tables cancel-runs` to stop those. ```bash -sim tables views delete [options] +sim tables dispatches cancel [options] ``` **Arguments** @@ -939,7 +1048,7 @@ sim tables views delete [options] | Argument | Required | Description | | --- | --- | --- | | `tableId` | Yes | Unique table identifier. | -| `viewId` | Yes | Unique saved-view identifier. | +| `dispatchId` | Yes | Unique table run-dispatch identifier. | @@ -953,10 +1062,14 @@ sim tables views delete [options] -## Get view +API request and response schemas: [cancelTableDispatch](/api-reference/tables/cancelTableDispatch). + +### Stop every running column job + +This cancels running column jobs — the whole table with --scope all, one row with --scope row. ```bash -sim tables views get +sim tables cancel-runs [options] ``` **Arguments** @@ -966,30 +1079,37 @@ sim tables views get | Argument | Required | Description | | --- | --- | --- | | `tableId` | Yes | Unique table identifier. | -| `viewId` | Yes | Unique saved-view identifier. | -## List views - -```bash -sim tables views list -``` - -**Arguments** +**Options** -| Argument | Required | Description | +| Option | Required | Description | | --- | --- | --- | -| `tableId` | Yes | Unique table identifier. | +| `--scope ` | Yes | Whether to cancel across the table or one row. Accepted values: `all`, `row`. | +| `--row-id ` | No | Row whose runs should be canceled for row scope. | +| `--filter ` | No | Predicate: {"all":[{"field":"status","op":"eq","value":"active"}]}; groups use all/any. Operators: eq, ne, gt, gte, lt, lte, in, nin, contains, ncontains, startsWith, endsWith, like, ilike, nlike, nilike, isEmpty, isNotEmpty, isNull, isNotNull (JSON, or @path / @- to read a file or stdin). | +| `--exclude-row-ids ` | No | Rows excluded from an all-scope cancellation. (space-separated, or @path / @- with one value per line; @@value for a literal leading @). | +| `-y, --yes` | Yes | Confirm this operation. | -## Update view +API request and response schemas: [cancelTableRuns](/api-reference/tables/cancelTableRuns). + +## Imports + +### Import a CSV, into a new table by default + +Choose exactly one source: a local CSV path or `--file-id`. For a new table imported with `--file-id`, supply `--name`. With `--table-id`, omit the new-table `--name` and `--folder` flags; `--mode`, `--mapping`, and `--create-columns` apply only to an existing table. + +**Replace mode deletes all existing rows before loading the CSV and cannot be undone.** It requires `--yes`; cancellation leaves only the rows already imported. + +The command watches the import by default. `--no-wait` returns a queued receipt. A completed import can still report `rowsRejected`, `cellsRejected`, and `rejectedSamples`; inspect them before accepting the result. ```bash -sim tables views update [options] +sim tables import [path] [options] ``` **Arguments** @@ -998,8 +1118,7 @@ sim tables views update [options] | Argument | Required | Description | | --- | --- | --- | -| `tableId` | Yes | Unique table identifier. | -| `viewId` | Yes | Unique saved-view identifier. | +| `path` | No | Local CSV file to import; choose exactly one source: this path or --file-id | @@ -1009,18 +1128,25 @@ sim tables views update [options] | Option | Required | Description | | --- | --- | --- | -| `--name ` | No | Replacement saved-view display name. | -| `--config ` | No | Complete replacement saved-view configuration. (JSON, or @path / @- to read a file or stdin). | -| `--config-patch ` | No | Saved-view configuration fields to shallow-merge. (JSON, or @path / @- to read a file or stdin). | -| `--default` | No | Whether to promote this view to the table default. | -| `--no-default` | No | Send --default as false. | +| `--name ` | Conditional | Name for a new table: letters, numbers, and underscores. A local CSV defaults to its sanitized filename; required with --file-id unless --table-id names an existing table. | +| `--table-id ` | No | Import into this existing table instead of creating one. | +| `--mode ` | No | How to write into --table-id (default: append). Accepted values: `append`, `replace`. | +| `--folder ` | No | Folder path for the new table, as shown in the app. | +| `--file-id ` | No | Import a file already in the workspace instead of a local path. | +| `--mapping ` | No | Column mapping (--table-id only). | +| `--create-columns ` | No | Columns to create (--table-id only). | +| `--timezone ` | No | Timezone for date parsing, e.g. America/New_York. | +| `-y, --yes` | Conditional | Confirm this destructive operation (required with --mode replace). | +| `--no-wait` | No | Return once the import is queued instead of watching it. | -## Delete table +API request and response schemas: [createTableImport](/api-reference/tables/createTableImport), [createTableImportPartUrls](/api-reference/tables/createTableImportPartUrls), [completeTableImport](/api-reference/tables/completeTableImportUpload), [cancelTableImport](/api-reference/tables/cancelTableImport), [getTableImport](/api-reference/tables/getTableImport). + +### Get table import ```bash -sim tables delete [options] +sim tables imports get ``` **Arguments** @@ -1029,7 +1155,27 @@ sim tables delete [options] | Argument | Required | Description | | --- | --- | --- | -| `tableId` | Yes | Unique table identifier. | +| `importId` | Yes | Unique table-import identifier. | + + + +API request and response schemas: [getTableImport](/api-reference/tables/getTableImport). + +### Stop a running import + +This stops the import between row batches, so whatever it already wrote stays and nothing resumes it. A replace import empties the table before its first batch, so cancelling one leaves only part of the new file; an append adds its rows again if you import the file a second time. + +```bash +sim tables imports cancel [options] +``` + +**Arguments** + + + +| Argument | Required | Description | +| --- | --- | --- | +| `importId` | Yes | Unique table-import identifier. | @@ -1043,10 +1189,14 @@ sim tables delete [options] -## Get row group run +API request and response schemas: [cancelTableImport](/api-reference/tables/cancelTableImport). + +## Exports + +### Create table export ```bash -sim tables enrichment get +sim tables exports create [options] ``` **Arguments** @@ -1056,70 +1206,63 @@ sim tables enrichment get | Argument | Required | Description | | --- | --- | --- | | `tableId` | Yes | Unique table identifier. | -| `rowId` | Yes | Unique table row identifier. | -| `groupId` | Yes | Workflow or enrichment group to run. | -## Get table - -```bash -sim tables get -``` - -**Arguments** +**Options** -| Argument | Required | Description | +| Option | Required | Description | | --- | --- | --- | -| `tableId` | Yes | Unique table identifier. | +| `--format ` | No | Export file format. Defaults to "csv". Accepted values: `csv`, `json`. | -## List tables +API request and response schemas: [createTableExport](/api-reference/tables/createTableExport). + +### Get table export ```bash -sim tables list [options] +sim tables exports get ``` -**Options** +**Arguments** -| Option | Required | Description | +| Argument | Required | Description | | --- | --- | --- | -| `--scope ` | No | Which lifecycle set to list: `active` (default) for live tables, `archived` for tables a delete archived and a table restore can bring back. `folderPath` resolves against active folders only, so pairing it with `scope=archived` returns an empty page when the containing folder was archived too. Accepted values: `active`, `archived`. | -| `--folder ` | No | Folder path as shown in the app; the leading / is optional. | -| `--search ` | No | Case-insensitive substring match against the resource name. | -| `--sort-by ` | No | Field used to sort the result. Sorting by `name` is case-sensitive and follows the storage collation, so do not rely on a case-insensitive order. Accepted values: `name`, `createdAt`, `updatedAt`. | -| `--sort-order ` | No | Sort direction. Accepted values: `asc`, `desc`. | -| `--limit ` | No | Maximum items to return (0 for everything). Defaults to `0`. | +| `tableId` | Yes | Unique table identifier. | +| `exportId` | Yes | Unique table-export identifier. | -## Move tables and folders +API request and response schemas: [getTableExport](/api-reference/tables/getTableExport). + +### Get the download URL for a finished export ```bash -sim tables move [options] +sim tables exports download ``` -**Options** +**Arguments** -| Option | Required | Description | +| Argument | Required | Description | | --- | --- | --- | -| `--table-ids ` | No | Tables to move, by identifier. (JSON, or @path / @- to read a file or stdin). | -| `--folder ` | No | Table folders to move, by path as shown in the app; the leading / is optional (space-separated, or @path / @- with one value per line; @@value for a literal leading @). | -| `--to ` | No | Destination folder path; omit for root. | +| `tableId` | Yes | Unique table identifier. | +| `exportId` | Yes | Unique table-export identifier. | -## Restore an archived table +API request and response schemas: [tableExportDownload](/api-reference/tables/downloadTableExport). + +### Stop a running export ```bash -sim tables restore +sim tables exports cancel ``` **Arguments** @@ -1129,13 +1272,18 @@ sim tables restore | Argument | Required | Description | | --- | --- | --- | | `tableId` | Yes | Unique table identifier. | +| `exportId` | Yes | Unique table-export identifier. | -## Update table +API request and response schemas: [cancelTableExport](/api-reference/tables/cancelTableExport). + +## Folders + +### List table resources and child folders together ```bash -sim tables update [options] +sim tables ls [path] [options] ``` **Arguments** @@ -1144,7 +1292,7 @@ sim tables update [options] | Argument | Required | Description | | --- | --- | --- | -| `tableId` | Yes | Unique table identifier. | +| `path` | No | Folder path to list; defaults to the root folder | @@ -1154,33 +1302,40 @@ sim tables update [options] | Option | Required | Description | | --- | --- | --- | -| `--name ` | No | Identifier: letters, numbers, and underscores; cannot start with a number. | -| `--description ` | No | Replacement table description, or null to clear it. (--description null sends the word, not JSON null). | -| `--folder ` | No | Folder path as shown in the app; the leading / is optional. | +| `--search ` | No | Filter folders and resources by name. | +| `--limit ` | No | Maximum combined items to return (0 for everything). Defaults to `0`. | -## Move a table to a folder +API request and response schemas: [listTables](/api-reference/tables/listTables), [listTableFolders](/api-reference/tables/listTablesFolders). + +### List table folders ```bash -sim tables mv +sim tables folders list [options] ``` -**Arguments** +Also available as `sim tables folders ls`. + +**Options** -| Argument | Required | Description | +| Option | Required | Description | | --- | --- | --- | -| `tableId` | Yes | Unique table identifier. | -| `folder` | Yes | Folder path as shown in the app; the leading / is optional | +| `--parent ` | No | Direct parent folder path. | +| `--search ` | No | Case-insensitive substring match against the folder name. | +| `--sort-by ` | No | Field used to sort the result. Do not rely on case-insensitive ordering when sorting by `name`. Defaults to "name". Accepted values: `name`, `createdAt`, `updatedAt`. | +| `--sort-order ` | No | Sort direction. Defaults to "asc". Accepted values: `asc`, `desc`. | -## Insert a row, or update the one that conflicts on a unique column +API request and response schemas: [listTableFolders](/api-reference/tables/listTablesFolders). + +### Create a table folder at a path ```bash -sim tables upsert [options] +sim tables folders create ``` **Arguments** @@ -1189,25 +1344,18 @@ sim tables upsert [options] | Argument | Required | Description | | --- | --- | --- | -| `tableId` | Yes | Unique table identifier. | +| `path` | Yes | Folder path as shown in the app; the leading / is optional | -**Options** - - - -| Option | Required | Description | -| --- | --- | --- | -| `--data ` | Yes | Complete set of row cells keyed by column name. On the update branch this REPLACES the matched row: any column not present here is cleared, unlike a single-row update, which merges. (JSON, or @path / @- to read a file or stdin). | -| `--on ` | No | Unique column to resolve the conflict against. | +API request and response schemas: [createTableFolder](/api-reference/tables/createTablesFolder). - +### Delete folder -## Import a CSV, into a new table by default +This archives the table folder and, when recursive, everything inside it. ```bash -sim tables import [path] [options] +sim tables folders delete [options] ``` **Arguments** @@ -1216,7 +1364,7 @@ sim tables import [path] [options] | Argument | Required | Description | | --- | --- | --- | -| `path` | No | Local CSV file to import; omit when using --file-id | +| `path` | Yes | Folder path as shown in the app; the leading / is optional | @@ -1226,23 +1374,17 @@ sim tables import [path] [options] | Option | Required | Description | | --- | --- | --- | -| `--name ` | No | Identifier for the new table: letters, numbers, and underscores; defaults to the sanitized file name. | -| `--table-id ` | No | Import into this existing table instead of creating one. | -| `--mode ` | No | How to write into --table-id (default: append). Accepted values: `append`, `replace`. | -| `--folder ` | No | Folder path for the new table, as shown in the app. | -| `--file-id ` | No | Import a file already in the workspace instead of a local path. | -| `--mapping ` | No | Column mapping (--table-id only). | -| `--create-columns ` | No | Columns to create (--table-id only). | -| `--timezone ` | No | Timezone for date parsing, e.g. America/New_York. | -| `-y, --yes` | No | Confirm this destructive operation (required with --mode replace). | -| `--no-wait` | No | Return once the import is queued instead of watching it. | +| `--recursive` | No | Archive the folder and its descendants. Defaults to "false". | +| `-y, --yes` | Yes | Confirm this operation. | -## List table resources and child folders together +API request and response schemas: [deleteTableFolder](/api-reference/tables/deleteTablesFolder). + +### Restore an archived table folder ```bash -sim tables ls [path] [options] +sim tables folders restore ``` **Arguments** @@ -1251,22 +1393,34 @@ sim tables ls [path] [options] | Argument | Required | Description | | --- | --- | --- | -| `path` | No | Folder path to list; defaults to the root folder | +| `path` | Yes | Folder path as shown in the app; the leading / is optional | -**Options** +API request and response schemas: [restoreTableFolder](/api-reference/tables/restoreTablesFolder). + +### Rename or move a table folder + +```bash +sim tables folders move +``` + +Also available as `sim tables folders mv`. + +**Arguments** -| Option | Required | Description | +| Argument | Required | Description | | --- | --- | --- | -| `--search ` | No | Filter folders and resources by name. | -| `--limit ` | No | Maximum combined items to return (0 for everything). Defaults to `0`. | +| `path` | Yes | Folder path as shown in the app; the leading / is optional | +| `destination` | Yes | Folder path as shown in the app; the leading / is optional | -## Create a table directory at a path +API request and response schemas: [relocateTableFolder](/api-reference/tables/relocateTablesFolder). + +### Create a table directory at a path ```bash sim tables mkdir @@ -1281,3 +1435,10 @@ sim tables mkdir | `path` | Yes | Folder path to create; the leading / is optional | + +API request and response schemas: [createTableFolder](/api-reference/tables/createTablesFolder). + +## Related docs + +- [Tables](/tables) +- [Workflow columns](/tables/workflow-columns) diff --git a/apps/docs/content/docs/cli/telemetry.mdx b/apps/docs/content/docs/cli/telemetry.mdx index 9bea4c847d4..8853ac89b6f 100644 --- a/apps/docs/content/docs/cli/telemetry.mdx +++ b/apps/docs/content/docs/cli/telemetry.mdx @@ -1,26 +1,33 @@ --- title: Telemetry -description: Control anonymous usage reporting — every subcommand, argument, and flag +description: Inspect and change this machine’s anonymous usage-reporting preference. --- -import { CommandTable } from '@/components/ui/command-table' -Every command below also accepts the [global options](/cli/commands#global-options). +Inspect and change this machine’s anonymous usage-reporting preference. -## Show whether usage reporting is on, and why not if it is off +These commands accept the [global options](/cli/commands#global-options). + +## Show usage-reporting status [#show-whether-usage-reporting-is-on-and-why-not-if-it-is-off] ```bash sim telemetry status ``` -## Turn usage reporting on for this machine +Telemetry commands always print text. DO_NOT_TRACK and SIM_TELEMETRY_DISABLED override the saved preference; a build without a reporting destination remains off. See the usage-data guide for the data collected. + +## Turn usage reporting off for this machine ```bash -sim telemetry enable +sim telemetry disable ``` -## Turn usage reporting off for this machine +## Enable the usage-reporting preference for this machine [#turn-usage-reporting-on-for-this-machine] ```bash -sim telemetry disable +sim telemetry enable ``` + +## Related docs + +- [Usage data](/cli/usage-data) diff --git a/apps/docs/content/docs/cli/tools.mdx b/apps/docs/content/docs/cli/tools.mdx index 93f264a8186..ed3972a2d47 100644 --- a/apps/docs/content/docs/cli/tools.mdx +++ b/apps/docs/content/docs/cli/tools.mdx @@ -1,29 +1,21 @@ --- title: Tools -description: Manage tools — every subcommand, argument, and flag +description: Find built-in tools, inspect their parameters, and run them. --- import { CommandTable } from '@/components/ui/command-table' -Every command below also accepts the [global options](/cli/commands#global-options). +Find built-in tools, inspect their parameters, and run them. -## Run one built-in tool and print what it produced - -```bash -sim tools execute [options] -``` - -Run one built-in tool and print what it produced (OAuth login or personal API key required) +Inspect a tool with `sim tools get ` before passing its parameters to `sim tools execute`. -**Arguments** - - +These commands accept the [global options](/cli/commands#global-options). -| Argument | Required | Description | -| --- | --- | --- | -| `toolId` | Yes | Tool identifier. An unversioned name resolves to the newest version, and the response echoes the resolved id. | +## List tools - +```bash +sim tools list [options] +``` **Options** @@ -31,12 +23,17 @@ Run one built-in tool and print what it produced (OAuth login or personal API ke | Option | Required | Description | | --- | --- | --- | -| `--input ` | No | Tool arguments as JSON, keyed by the parameter ids `sim tools get <toolId>` lists (JSON, or @path / @- to read a file or stdin). | -| `--credential-id ` | No | Credential to authenticate with, required for OAuth tools. | -| `--timeout ` | No | Seconds to wait before abandoning the call. | +| `--search ` | No | Case-insensitive substring match against the tool id, name, and description. | +| `--hosted-api-key ` | No | Restrict to tools by how their API key is supplied. Accepted values: `always`, `conditional`, `none`. | +| `--oauth-provider ` | No | Restrict to tools that authenticate against this OAuth service. | +| `--sort-by ` | No | Field used to sort the result. Do not rely on case-insensitive ordering when sorting by `name`. Defaults to "id". Accepted values: `id`, `name`. | +| `--sort-order ` | No | Sort direction. Defaults to "asc". Accepted values: `asc`, `desc`. | +| `--limit ` | No | Maximum items to return (0 for everything). Defaults to `0`. | +API request and response schemas: [listTools](/api-reference/catalog/listTools). + ## Get tool ```bash @@ -49,27 +46,40 @@ sim tools get | Argument | Required | Description | | --- | --- | --- | -| `toolId` | Yes | Tool identifier. An unversioned name resolves to the newest version, and the response echoes the resolved id. | +| `toolId` | Yes | Tool identifier. An exact visible ID is retained; an unversioned name resolves to the newest visible family version. The response echoes the resolved ID. | -## List tools +API request and response schemas: [getTool](/api-reference/catalog/getTool). + +## Run one built-in tool and print what it produced + +OAuth login or personal API key required. ```bash -sim tools list [options] +sim tools execute [options] ``` +**Arguments** + + + +| Argument | Required | Description | +| --- | --- | --- | +| `toolId` | Yes | Tool identifier. An exact visible ID is retained; an unversioned name resolves to the newest visible family version. The response echoes the resolved ID. | + + + **Options** | Option | Required | Description | | --- | --- | --- | -| `--search ` | No | Case-insensitive substring match against the tool id, name, and description. | -| `--hosted-api-key ` | No | Restrict to tools by how their API key is supplied. Accepted values: `always`, `conditional`, `none`. | -| `--oauth-provider ` | No | Restrict to tools that authenticate against this OAuth service. | -| `--sort-by ` | No | Field used to sort the result. Sorting by `name` is case-sensitive and follows the storage collation, so do not rely on a case-insensitive order. Accepted values: `id`, `name`. | -| `--sort-order ` | No | Sort direction. Accepted values: `asc`, `desc`. | -| `--limit ` | No | Maximum items to return (0 for everything). Defaults to `0`. | +| `--input ` | No | Tool arguments as JSON, keyed by the parameter ids `sim tools get ` lists. Defaults to {}. (JSON, or @path / @- to read a file or stdin). | +| `--credential-id ` | No | Credential to authenticate with, required for OAuth tools. | +| `--timeout ` | No | Seconds to wait before abandoning the call. | + +API request and response schemas: [executeTool](/api-reference/catalog/executeTool). diff --git a/apps/docs/content/docs/cli/troubleshooting.mdx b/apps/docs/content/docs/cli/troubleshooting.mdx index 4ad1a9b2f22..81a766a60ab 100644 --- a/apps/docs/content/docs/cli/troubleshooting.mdx +++ b/apps/docs/content/docs/cli/troubleshooting.mdx @@ -1,147 +1,160 @@ --- title: Troubleshooting -description: The failures whose cause is not obvious from the error message +description: Diagnose profile, connection, input, output, and update failures. --- -import { Tab, Tabs } from 'fumadocs-ui/components/tabs' +Start by checking the version and resolved settings: -Most command errors print to stderr and exit `1`. `sim whoami` and -`sim workflows runs wait` use additional codes to distinguish outcomes; see -[Exit codes](/cli/scripting#exit-codes). The cases below explain failures whose -cause may not be obvious from the message. +```bash +sim --version +sim whoami --no-verify +sim whoami +``` + +`--no-verify` stays offline. Normal `whoami` checks authentication and access to the selected workspace. Inspect its `verification` result before changing credentials. -Start with `sim whoami`. It prints the resolved endpoint, workspace, and output -format, **and where each came from** — which explains most surprises on its own — -then checks the resolved key against the API. Add `--no-verify` to skip the check -and stay offline. +Most command failures exit 1. Verification, run waiting, and workspace-operation waiting have additional outcomes; see [Exit codes](/cli/scripting#exit-codes). ## A command targets the wrong workspace or deployment -Each setting resolves independently, and a flag beats the environment, which -beats the profile. A stale `SIM_WORKSPACE` in your shell silently outranks the -workspace you configured. +Flags override the environment, which overrides profile defaults. A stale `SIM_WORKSPACE` can outrank the workspace saved in your profile. `whoami` shows each winning value and source: ```bash -sim whoami +sim whoami --no-verify --profile ``` -API-key pairing sets the default workspace selected on its approval page. -After OAuth login, set one with `sim configure --set-workspace `. -The default target does not restrict your credential: use `--workspace` to reach -another workspace that credential can access. +After OAuth login, set a default with `sim configure --set-workspace `. Pairing sets the default chosen on its approval page. A default target does not restrict credential scope; `--workspace` can select another accessible workspace. + +See [Configuration](/cli/configuration#where-settings-come-from) for the full precedence rules. ## An error ends in `— run: sim login --profile ` -The API rejected the key with a `401`. Either it was revoked, or it belongs to a -different deployment than the endpoint you are pointed at — a key minted against -a local stack will not authenticate against production. Check the endpoint before -re-authenticating: +A 401 means the API rejected authentication. The credential may be revoked, expired, or issued by another deployment. Check the endpoint before signing in again: + +```bash +sim whoami --no-verify --profile +``` + +For a stored OAuth login, logout is required before a new login: ```bash -sim whoami --profile +sim logout --profile +sim login --profile ``` +`whoami` exit 1 can also mean a valid credential cannot access the selected workspace, or the workspace does not exist. A 403/404 workspace refusal needs an access or target correction rather than repeated login. + +### OAuth refresh or endpoint mismatch + +An OAuth login cannot move to another deployment. Restore its original endpoint, or log out before configuring a new one. Workspace profiles share their authentication profile's endpoint. + +Sign in separately on each machine. Copied credential files can reuse one single-use refresh family and cause revocation. If a refresh response was lost, the CLI will not retry the consumed token; log out and sign in again. See [Stored logins](/cli/authentication#where-the-login-is-stored). + ## `Could not reach https://www.sim.ai: ` -The request never got a response: DNS, TLS, a proxy, or a self-hosted stack that -is not running. Confirm the endpoint the CLI actually used with `sim whoami`, and -that it has the right scheme and port: +DNS, TLS, a proxy, or an unavailable self-hosted service can prevent a response. Check the resolved endpoint's scheme and port: ```bash +sim whoami --no-verify sim configure --set-endpoint http://localhost:3000 --profile local ``` +Loopback development endpoints can use HTTP. Remote browser sign-in requires HTTPS for OAuth and pairing. + +### Endpoint redirects + +The CLI does not follow API redirects: they can change a write's method/body or forward a credential to another origin. Configure the actual API endpoint shown by the error. The hosted default is `https://www.sim.ai`. + +### Proxy settings + +Node must opt in before `fetch` uses `HTTP(S)_PROXY`. Set `NODE_USE_ENV_PROXY=1` before launching the CLI, using Node 22.21+ or 24.0+. The equivalent `--use-env-proxy` Node flag requires 22.21+ or 24.5+. Older runtimes need an upgrade. See [Registry and proxy behavior](/cli/configuration#registry-and-proxy-behavior). + ## A JSON flag rejects a value that looks like valid JSON -Your shell consumed the quotes. Wrap the whole value in single quotes, or read it -from a file: +A shell may consume unquoted JSON quotes. Quote the whole value or read JSON from a file: ```bash sim tables rows query tbl_9f3c1a05d4b7426e8c2f0917ab35de64 --filter '{"all":[{"field":"status","op":"eq","value":"open"}]}' sim tables rows query tbl_9f3c1a05d4b7426e8c2f0917ab35de64 --filter @filter.json ``` +Workflow imports require JSON, even if an export was saved as YAML. File-aware flags interpret `@value` as a path; write `@@value` for a literal leading `@`. See [Scripting](/cli/scripting). + ## A value looks truncated -`table` clips long cells to keep rows on one line. The data is not truncated — -switch to a machine format to see it in full: +Table display clips long cells. Select JSON/YAML to inspect the returned values: ```bash sim logs get 9c4f0b7e-2d81-4a35-b6e9-70f1c8a2d543 --output json ``` +Changing format does not remove server-side caps. Check any reported truncation flag/notice, filters, and pagination before assuming the response contains everything. + ## In an interactive terminal, `sim files get` refuses to print to the terminal -Writing arbitrary binary to an interactive terminal can corrupt it, so non-text -content has to go to a file or a pipe: +Binary content must go to a file or a pipe: ```bash sim files get wf_8Kd2NpVrY6zTfQa3XwBmS -o ./image.png sim files get wf_8Kd2NpVrY6zTfQa3XwBmS | shasum ``` +An existing output file requires `--force`. With `--output-file`, file content is saved and stdout contains a save receipt. See [File commands](/cli/files). + ## A stored output format is invalid -A higher-priority source still wins, so you can repair the profile without -editing the file by hand: +Use an environment override to repair the saved default: ```bash -sim --output table configure --set-output json +SIM_OUTPUT=json sim configure --set-output json +SIM_OUTPUT=json sim configure --profile --set-output json ``` +`configure` rejects global `--output`, `--endpoint`, and `--workspace`; persistence uses `--set-*`. If an invalid environment variable caused the error, correct or unset it as well. + ## A command is missing that the documentation describes -The docs track the current release, so a command that exists here and not in -`sim --help` usually means the installed CLI is older than the feature. Compare -`sim --version` against the published version and upgrade: +Compare the installed version and command help. These docs describe the current source; an older installed CLI or self-hosted server can lack an operation: ```bash sim --version +sim --help +sim update ``` -Run `sim update` to update the active global installation. If this older release -does not yet have the `update` command, upgrade with the package manager you installed it with — using a different -one installs a second copy instead of replacing the executable on your `PATH`: - - - - ```bash - npm install -g sim@latest - ``` - - - ```bash - pnpm add -g sim@latest - ``` - - - ```bash - bun add -g sim@latest - ``` - - - ```bash - yarn global add sim@latest - ``` - - - -The CLI also shows an optional update notice through a cached daily check on -eligible interactive invocations. Your command continues, and you choose when to -run `sim update`. Checks stay quiet when stderr is redirected, in CI, and under -`npm exec` or `npx`. +`sim update` verifies the active global installation and preserves its stable/staging/dev channel. If an older Bun installation has no update command, update the package through Bun: + +```bash +bun add -g sim@latest +``` + +Use the corresponding staging/dev tag for an intentional prerelease installation. Installations made with npm, pnpm, or Yarn Classic should be upgraded through their original manager; a different manager can create another executable on `PATH`. Project-local and temporary package-runner copies must be updated through their package manager too. + +See [Updates](/cli/configuration#updates) for supported managers and copy-detection behavior. ## An update notice appears in output I am parsing -It should not: the notice is written to stderr, never stdout, so `--output json` -piped to `jq` is unaffected. If something merges the two streams, silence it: +Notices go to stderr, so a JSON stdout pipe is unaffected. If your runner combines streams, separate stdout/stderr or suppress automatic checks: ```bash export SIM_NO_UPDATE_CHECK=1 ``` +Checks are already quiet in CI and when stderr is redirected. Manual `sim update` remains available when notices are disabled. + +## A sync apply or wait did not return a clear outcome + +Retain the original request/operation IDs and exact input. An operation may have committed even when its response was lost or its follow-up copying/deployment failed. Query it in the receipt workspace or retry only identical input with the original request ID. See [Reconcile completion and retries](/cli/workflow-sync#reconcile-completion-and-retries). + +A workflow wait timeout also leaves its run active. Inspect that run ID; do not assume another execution is a retry of the same work. + ## Anything else -An unexpected error prints a stack trace. That is a bug in the CLI — please -[open an issue](https://github.com/simstudioai/sim/issues) with the command you -ran, the trace, and the output of `sim --version`. +For an unexpected stack trace, [open an issue](https://github.com/simstudioai/sim/issues) with the CLI version, command, sanitized trace, and relevant resolved settings. Remove credentials, sensitive inputs, and private file contents before posting. Debug output can contain request selectors. + +## Related docs + +- [Authentication](/cli/authentication) +- [Configuration](/cli/configuration) +- [Output formats](/cli/output) +- [Scripting](/cli/scripting) diff --git a/apps/docs/content/docs/cli/usage-data.mdx b/apps/docs/content/docs/cli/usage-data.mdx index 9c21bd5f092..37a814cc9d9 100644 --- a/apps/docs/content/docs/cli/usage-data.mdx +++ b/apps/docs/content/docs/cli/usage-data.mdx @@ -1,82 +1,85 @@ --- title: Usage data -description: What the CLI reports about how it is used, what it never sends, and how to turn reporting off +description: Inspect CLI usage fields, reporting controls, and local state. --- -The `sim` CLI reports anonymous usage data so the team can see which commands -are used, which fail, and how long they take. Reporting is on by default and -takes one command to turn off. +The installed CLI sends anonymous usage events by default when its build includes a reporting destination. The events record which commands execute, their outcomes, and duration. Disable reporting for this installation with: -## What is sent +```bash +sim telemetry disable +sim telemetry status +``` + +Telemetry commands always print text, regardless of `--output`. + +## Turning it off -One event per command, after the command finishes: +Reporting follows this precedence. `sim telemetry status` names the first reason that disables it: -| Field | Example | Notes | +| Priority | Control | Scope | | --- | --- | --- | -| Command | `workflows list` | The command's name, never its arguments | -| Flags | `--output`, `--workspace` | Flag names only, never their values | -| Argument count | `1` | How many positional arguments, never what they were | -| Outcome | exit code `0`, `SimApiError`, HTTP `404`, API code `NOT_FOUND` | Never an error message | -| Duration | `1432` ms | From process start to completion | -| CLI, Node, OS, CPU | `2.1.2`, `22.14.0`, `darwin`, `arm64` | | -| Terminal and CI | `is_tty`, `is_ci` | Whether stdout is a terminal, whether a CI variable is set | -| Coding agent | `claude-code`, or `none` | The AI coding agent whose shell the CLI runs in, if any | -| Deployment kind | `hosted` or `self_hosted` | Never the address | -| Device and session ids | random UUIDs | See below | +| 1 | `DO_NOT_TRACK=1` | Cross-tool environment opt-out | +| 2 | `SIM_TELEMETRY_DISABLED=1` | CLI environment opt-out | +| 3 | `sim telemetry disable` | Saved preference in this installation's usage state | +| 4 | No destination configured in the build | No event can be sent | -## What is never sent +```bash +export DO_NOT_TRACK=1 +export SIM_TELEMETRY_DISABLED=1 +sim telemetry disable +``` -Nothing you type. No argument values, flag values, file paths, workflow or -workspace ids, error messages, environment variable values, credentials, or the -address of the deployment you talk to. The report leaves your machine from a -separate short-lived process that is not given your API key. +Use whichever control matches your environment. `sim telemetry enable` changes the saved preference but cannot override an environment opt-out or add a missing build destination. -## Location +Disabling reporting also withholds the coding-agent name from Sim API requests. Requests still identify the CLI and its version/runtime through client headers; that request attribution is separate from the anonymous usage event. -The report carries no location of its own. The analytics service derives an -approximate location (country and city) from the address the report arrived -from, the way any HTTP request exposes one, and Sim uses that only to see -which regions use the CLI. +## What is sent -## Identity +When enabled, reporting sends one event after an executed command finishes. Telemetry commands, help/version output, parse failures before execution, and the run that displays the first notice are excluded. -The first run mints a random device id and stores it in `telemetry.json` under -`~/.sim` (or `SIM_CONFIG_DIR`). It is not derived from your hardware, account, -or network. Commands run within thirty minutes of each other share a session id -and are numbered, so a sequence of commands can be read back. No profile is -created for the device, and the data is not joined to your Sim account. +| Field | Example | Contents | +| --- | --- | --- | +| Command | `workflows list` | Registered command name, without argument values | +| Flags | `--output`, `--workspace` | Names of supplied flags, without values | +| Argument count | `1` | Count of positional arguments | +| Outcome | exit `0`, `SimApiError`, HTTP `404`, `NOT_FOUND` | Exit code, error class, HTTP status, and API error code when available; no message | +| Duration | `1432` ms | Time from process start to completion | +| CLI, Node, OS, CPU | `2.1.2`, `22.14.0`, `darwin`, `arm64` | Runtime/version information | +| Terminal and CI | `is_tty`, `is_ci` | Whether stdout is a terminal and whether a CI environment was detected | +| Coding agent | `claude-code` or `none` | Detected coding agent driving the shell | +| Deployment kind | `hosted` or `self_hosted` | Deployment classification, without its address | +| Device/session IDs | Random UUIDs | Installation identifier and a time-based command session | + +These are illustrative values, not a required CLI or Node version. -Deleting `telemetry.json` forgets the device id and shows the first-run notice -again. +## What is never sent -## Turning it off +The usage payload excludes argument values, flag values, file paths, workflow/workspace IDs, error messages, environment-variable values, credentials, and the deployment address. It includes no Sim account identity and requests no analytics person profile. -Any of these turns reporting off. The first one that applies is the one -`sim telemetry status` names. +A separate short-lived process sends the event. It is not given your Sim API key, and the CLI does not wait for delivery before returning your prompt. -```bash -export DO_NOT_TRACK=1 # the cross-tool convention, honoured before anything else -export SIM_TELEMETRY_DISABLED=1 # this CLI only, for one shell or CI job -sim telemetry disable # this machine, saved in telemetry.json -``` +## Identity -`sim telemetry enable` reverses the saved setting. `sim telemetry status` shows -the current state. +Usage state is stored in `~/.sim/telemetry.json`, or under `SIM_CONFIG_DIR`. The random device ID is not derived from hardware, account, or network information. Reported commands less than 30 minutes apart share a session ID and sequence number. -Turning reporting off also stops the CLI from telling the API which coding -agent, if any, is driving it. The CLI still identifies itself as the CLI on -every request, the way every official client does; that is how a request is -attributed, not usage data. +Deleting `telemetry.json` resets the device ID, notice state, and saved enabled/disabled preference. Reporting can return to its default. Environment opt-outs still apply. + +## Location + +The event contains no location field. The receiving analytics service sees the request's IP address and can derive an approximate country/city from it. This network-derived information is separate from the client payload's device and session IDs. ## The first-run notice -The first time the CLI would report from an interactive terminal it prints a -short notice on stderr and does not report that run. The notice is not shown in -CI or when stderr is redirected, and it is shown once per device. +The first eligible interactive run prints a notice on stderr and does not report that run. The notice is shown once per saved device state. It is not shown in CI or when stderr is redirected; those conditions alone do not disable reporting. ## Self-hosted deployments -Reporting is tied to the CLI build, not to the deployment it talks to. The -published `sim` package reports to Sim. A build made from the repository without -`SIM_CLI_TELEMETRY_KEY` set has no destination and reports nothing; setting it -to your own PostHog project token at build time reports to your own project. +Reporting follows the CLI build, not the Sim deployment it calls. A configured build can report while targeting a self-hosted endpoint. + +Building from the repository without `SIM_CLI_TELEMETRY_KEY` supplies no reporting destination. Set that build-time variable to your own PostHog project token to configure a destination; `SIM_CLI_TELEMETRY_HOST` can select its host. Run `sim telemetry status` to inspect the effective state of your installed build. + +## Related docs + +- [Telemetry commands](/cli/telemetry) +- [Configuration](/cli/configuration) +- [Output formats](/cli/output) diff --git a/apps/docs/content/docs/cli/workflow-mcp-servers.mdx b/apps/docs/content/docs/cli/workflow-mcp-servers.mdx index 8237adc8c0a..2a630a233d4 100644 --- a/apps/docs/content/docs/cli/workflow-mcp-servers.mdx +++ b/apps/docs/content/docs/cli/workflow-mcp-servers.mdx @@ -1,42 +1,48 @@ --- -title: Workflow MCP Servers -description: Manage workflow mcp servers — every subcommand, argument, and flag +title: Workflow MCP servers +description: Serve deployed workflows as tools for Model Context Protocol (MCP) clients. --- import { CommandTable } from '@/components/ui/command-table' -Every command below also accepts the [global options](/cli/commands#global-options). +Serve deployed workflows as tools for Model Context Protocol (MCP) clients. -## Create workflow MCP server +These servers expose Sim workflows. To connect a server that provides external tools, use [MCP servers](/cli/mcp-servers). + +These commands accept the [global options](/cli/commands#global-options). + +## Servers + +### List workflow MCP servers + +OAuth login or personal API key required. ```bash -sim workflow-mcp-servers create [options] +sim workflow-mcp-servers list [options] ``` -Create Workflow MCP Server (OAuth login or personal API key required) - **Options** | Option | Required | Description | | --- | --- | --- | -| `--name ` | Yes | Server display name, shown to connecting MCP clients. | -| `--description ` | No | Optional server description. | -| `--is-public` | No | Whether the server answers MCP clients without a Sim API key. Defaults to false — a public server executes the workflows it publishes for anyone holding its URL. | -| `--no-is-public` | No | Send --is-public as false. | -| `--workflow ` | No | Deployed workflows to publish as tools on the new server. (space-separated, or @path / @- with one value per line; @@value for a literal leading @). | +| `--sort-by ` | No | Field used to sort the result. Do not rely on case-insensitive ordering when sorting by `name`. Defaults to "createdAt". Accepted values: `name`, `createdAt`, `updatedAt`. | +| `--sort-order ` | No | Sort direction. Defaults to "desc". Accepted values: `asc`, `desc`. | +| `--limit ` | No | Maximum items to return (0 for everything). Defaults to `0`. | -## Delete workflow MCP server +API request and response schemas: [listWorkflowMcpServers](/api-reference/mcp-servers/listWorkflowMcpServers). + +### Get workflow MCP server + +OAuth login or personal API key required. ```bash -sim workflow-mcp-servers delete [options] +sim workflow-mcp-servers get ``` -Delete Workflow MCP Server (OAuth login or personal API key required) - **Arguments** @@ -47,24 +53,40 @@ Delete Workflow MCP Server (OAuth login or personal API key required) +API request and response schemas: [getWorkflowMcpServer](/api-reference/mcp-servers/getWorkflowMcpServer). + +### Create workflow MCP server + +OAuth login or personal API key required. + +```bash +sim workflow-mcp-servers create [options] +``` + **Options** | Option | Required | Description | | --- | --- | --- | -| `-y, --yes` | Yes | Confirm this operation. | +| `--name ` | Yes | Server display name, shown to connecting MCP clients. | +| `--description ` | No | Optional server description. | +| `--is-public` | No | Whether the server accepts MCP clients without a Sim API key. Defaults to false; a public server lets anyone holding its URL execute the workflows it exposes. | +| `--no-is-public` | No | Send --is-public as false. | +| `--workflow ` | No | Deployed workflows to expose as MCP tools on the new server. (space-separated, or @path / @- with one value per line; @@value for a literal leading @). | -## Publish workflow as MCP tool +API request and response schemas: [createWorkflowMcpServer](/api-reference/mcp-servers/createWorkflowMcpServer). + +### Update workflow MCP server + +OAuth login or personal API key required. ```bash -sim workflow-mcp-servers tools create [options] +sim workflow-mcp-servers update [options] ``` -Publish Workflow As MCP Tool (OAuth login or personal API key required) - **Arguments** @@ -81,21 +103,25 @@ Publish Workflow As MCP Tool (OAuth login or personal API key required) | Option | Required | Description | | --- | --- | --- | -| `--workflow-id ` | Yes | Deployed workflow to publish. The workflow must already be deployed. | -| `--tool-name ` | No | Name MCP clients call. Normalized to the MCP tool-name grammar, and derived from the workflow name when omitted. | -| `--tool-description ` | No | Description shown to MCP clients. Derived from the workflow name when omitted. | -| `--parameter-descriptions ` | No | Per-field description overrides applied to the schema generated from the deployed workflow inputs, as [{"name":"email","description":"Customer email address"}]. A name matching no input field is ignored (JSON, or @path / @- to read a file or stdin). | +| `--name ` | No | Server display name, shown to connecting MCP clients. | +| `--description ` | No | New server description, or null to clear it. (--description null sends the word, not JSON null). | +| `--is-public` | No | Whether the server answers MCP clients without a Sim API key. | +| `--no-is-public` | No | Send --is-public as false. | -## List workflow MCP tools +API request and response schemas: [updateWorkflowMcpServer](/api-reference/mcp-servers/updateWorkflowMcpServer). + +## Workflow tools + +### List workflow MCP tools + +OAuth login or personal API key required. ```bash sim workflow-mcp-servers tools list ``` -List Workflow MCP Tools (OAuth login or personal API key required) - **Arguments** @@ -106,14 +132,16 @@ List Workflow MCP Tools (OAuth login or personal API key required) -## Unpublish workflow MCP tool +API request and response schemas: [listWorkflowMcpTools](/api-reference/mcp-servers/listWorkflowMcpTools). + +### Deploy workflow as MCP tool [#publish-workflow-as-mcp-tool] + +OAuth login or personal API key required. ```bash -sim workflow-mcp-servers tools delete [options] +sim workflow-mcp-servers tools create [options] ``` -Unpublish Workflow MCP Tool (OAuth login or personal API key required) - **Arguments** @@ -121,7 +149,6 @@ Unpublish Workflow MCP Tool (OAuth login or personal API key required) | Argument | Required | Description | | --- | --- | --- | | `serverId` | Yes | Unique workflow-MCP server identifier. | -| `workflowId` | Yes | Workflow published as a tool on this server. | @@ -131,18 +158,25 @@ Unpublish Workflow MCP Tool (OAuth login or personal API key required) | Option | Required | Description | | --- | --- | --- | -| `-y, --yes` | Yes | Confirm this operation. | +| `--workflow-id ` | Yes | Workflow to expose as an MCP tool. It must already be deployed. | +| `--tool-name ` | No | Name MCP clients call. Normalized to the MCP tool-name grammar, and derived from the workflow name when omitted. | +| `--tool-description ` | No | Description shown to MCP clients. Derived from the workflow name when omitted. | +| `--parameter-descriptions ` | No | Per-field description overrides applied to the schema generated from the deployed workflow inputs, as [{"name":"email","description":"Customer email address"}]. A name matching no input field is ignored (JSON, or @path / @- to read a file or stdin). | -## Get workflow MCP server +API request and response schemas: [deployWorkflowMcpTool](/api-reference/mcp-servers/deployWorkflowMcpTool). + +### Undeploy workflow MCP tool [#unpublish-workflow-mcp-tool] + +OAuth login or personal API key required. + +This withdraws the tool, and any agent calling it loses access. ```bash -sim workflow-mcp-servers get +sim workflow-mcp-servers tools delete [options] ``` -Get Workflow MCP Server (OAuth login or personal API key required) - **Arguments** @@ -150,37 +184,34 @@ Get Workflow MCP Server (OAuth login or personal API key required) | Argument | Required | Description | | --- | --- | --- | | `serverId` | Yes | Unique workflow-MCP server identifier. | +| `workflowId` | Yes | Workflow registered as an MCP tool on this server. | -## List workflow MCP servers - -```bash -sim workflow-mcp-servers list [options] -``` - -List Workflow MCP Servers (OAuth login or personal API key required) - **Options** | Option | Required | Description | | --- | --- | --- | -| `--sort-by ` | No | Field used to sort the result. Sorting by `name` is case-sensitive and follows the storage collation, so do not rely on a case-insensitive order. Accepted values: `name`, `createdAt`, `updatedAt`. | -| `--sort-order ` | No | Sort direction. Accepted values: `asc`, `desc`. | -| `--limit ` | No | Maximum items to return (0 for everything). Defaults to `0`. | +| `-y, --yes` | Yes | Confirm this operation. | -## Update workflow MCP server +API request and response schemas: [undeployWorkflowMcpTool](/api-reference/mcp-servers/undeployWorkflowMcpTool). + +## Delete servers + +### Delete workflow MCP server + +OAuth login or personal API key required. + +This deletes the MCP server, and any agent calling its tools loses access. ```bash -sim workflow-mcp-servers update [options] +sim workflow-mcp-servers delete [options] ``` -Update Workflow MCP Server (OAuth login or personal API key required) - **Arguments** @@ -197,9 +228,12 @@ Update Workflow MCP Server (OAuth login or personal API key required) | Option | Required | Description | | --- | --- | --- | -| `--name ` | No | Server display name, shown to connecting MCP clients. | -| `--description ` | No | New server description, or null to clear it. (--description null sends the word, not JSON null). | -| `--is-public` | No | Whether the server answers MCP clients without a Sim API key. | -| `--no-is-public` | No | Send --is-public as false. | +| `-y, --yes` | Yes | Confirm this operation. | + +API request and response schemas: [deleteWorkflowMcpServer](/api-reference/mcp-servers/deleteWorkflowMcpServer). + +## Related docs + +- [MCP connections](/agents/mcp) diff --git a/apps/docs/content/docs/cli/workflow-sync.mdx b/apps/docs/content/docs/cli/workflow-sync.mdx index 076494631f3..7431f696b9b 100644 --- a/apps/docs/content/docs/cli/workflow-sync.mdx +++ b/apps/docs/content/docs/cli/workflow-sync.mdx @@ -1,15 +1,36 @@ --- title: Workflow imports and workspace sync -description: Preview resource bindings, apply reviewed changes, and verify readiness from an LLM or CI client +description: Preview destination choices, apply reviewed changes, and reconcile operation completion. --- -Use an explicit profile and workspace for every environment. Fork administration requires a personal API key or OAuth login; workspace API keys cannot administer fork edges. Fork creation requires source admin access. Sync and mapping changes require admin access on both workspaces. +Import an exported workflow as a draft, or fork and sync related workspaces. Preview the destination bindings, apply the same choices, and inspect the operation receipt before using the destination. -These commands use the same v2 operations as a direct API client. See the [API workflow guide](/api-reference/workflow-sync) for HTTP requests, response envelopes, and the command-to-endpoint mapping. CLI JSON output unwraps single-resource responses, so read `.previewFingerprint`; raw HTTP clients read `.data.previewFingerprint`. +These commands use the v2 protocol described in the [API workflow guide](/api-reference/workflow-sync). CLI single-resource results omit the outer HTTP `data` envelope: read `.previewFingerprint` in CLI output and `.data.previewFingerprint` in raw HTTP output. Paginated CLI lists retain `{data, nextCursor}`. + +## Prerequisites + +Use an explicit profile and workspace for each environment. Replace example resource IDs with IDs from your export and destination. Save a stable request ID and the exact input for each intended mutation before applying it. + +| Operation | Required access | +| --- | --- | +| Export | Workflow read access | +| Import preview/apply | Destination write access; credential binding requires an acting personal/OAuth identity with credential access | +| Fork discovery, preview, creation | Personal API key or OAuth login and source workspace Admin; creation policy must allow a new workspace | +| Sync and mapping changes | Personal API key or OAuth login and Admin access to both workspaces on a direct parent/child fork edge | +| Selectors | Read access in the discovery workspace and access to the chosen credential; workspace keys are unsupported | +| Operation reads | Read access in the receipt workspace | + +Workspace keys cannot administer fork relationships or stand in for a user when binding credentials. OAuth import/fork/sync previews require `api:write`; export, discovery, mapping reads, selectors, and operation reads use `api:read`. + +Forking and sync require Enterprise on billing-enabled deployments. Billing-disabled deployments must enable forking through deployment configuration. Check `workspaces fork-availability` before starting. Import and operation reports do not inherit this fork-specific gate. ## Import a workflow with destination bindings -Portable export is opt-in. It adds a versioned reference manifest to the sanitized graph; credentials and secret values stay in their original workspace. +### 1. Export and inspect the workflow + +`--include-references` adds a versioned manifest of resource identities and their occurrences. Default export clears registered credential fields and workspace bindings. It does not remove every ordinary variable value or literal configuration; inspect the payload before sharing it. Credentials and secret values are not transferred as destination resources. + +Pin JSON because import does not accept YAML: ```sh sim --profile source --workspace "$SOURCE_WORKSPACE" --output json \ @@ -19,7 +40,11 @@ sim --profile destination --workspace "$DESTINATION_WORKSPACE" --output json \ workflows import-preview --workflow @workflow.json > preview.json ``` -Read `unresolvedBindings` and `unresolvedConfiguration`. Resource mappings select a destination by resource kind and source ID. For example, `mappings.json` can contain: +`--include-workspace-bindings` can preserve non-secret bindings for a same-workspace round trip. Otherwise, configure required bindings reported by import. + +### 2. Map destination resources + +Read `unresolvedBindings` and `unresolvedConfiguration`. Resource mappings select a destination by `kind` and source ID. Save an array such as this in `mappings.json`: ```json [ @@ -28,7 +53,9 @@ Read `unresolvedBindings` and `unresolvedConfiguration`. Resource mappings selec ] ``` -Use the existing credentials, tables, files, sandboxes, and other resource commands to discover or create destination resources. An older export without reference metadata can use `--bindings @bindings.json` to address individual source fields. For example, a nested Agent tool's credential binding is: +Use the credential, table, file, sandbox, and other resource commands to discover or create destination resources. A mapping applies to registered occurrences of that source resource. `targetId:null` requests clearing and cannot satisfy a required binding. Source IDs are labels, not permission to read a source workspace. + +Older exports without a reference manifest can use `--bindings @bindings.json` for individual registered source fields. A nested Agent tool credential can be addressed as: ```json [ @@ -43,9 +70,11 @@ Use the existing credentials, tables, files, sandboxes, and other resource comma ] ``` -Use the field path and encoding registered for the actual export. A top-level field uses its own `subBlockKey` and `valuePath: []`. Field bindings have no `sourceId`; they address an occurrence directly. Conflicting resource mappings and field bindings are rejected. Include `--bindings` on both preview and apply when using them. +Use the path and encoding registered for the actual export. A top-level field uses its own `subBlockKey` and `valuePath:[]`. Field bindings have no `sourceId`; they address an occurrence directly. Conflicting mappings/bindings are rejected. Include `--bindings` in both preview and apply when using them. + +### 3. Resolve dependent choices -Dependent choices use the selector key and destination context returned by preview. For example: +Use the selector key and destination context returned by preview to discover valid values. For example: ```sh sim --profile destination --workspace "$DESTINATION_WORKSPACE" --output json \ @@ -53,15 +82,19 @@ sim --profile destination --workspace "$DESTINATION_WORKSPACE" --output json \ --context '{"oauthCredential":"destination-connection"}' ``` -MCP tool discovery uses `mcp.tools` with `mcpServerId`. OAuth connections may require a human to authorize the provider before discovery can succeed. +MCP tool discovery uses `mcp.tools` with `mcpServerId`. OAuth connections can require human provider authorization before discovery succeeds. Check selector pagination and truncation rather than assuming one result contains every provider option. -Import dependent values use source block IDs and field keys: +Import-dependent values use source block IDs and the returned field key. Save values in `values.json`: ```json [{ "blockId": "source-agent", "subBlockKey": "tools[0].folder", "value": "destination-label" }] ``` -Preview again with the exact choices, then apply with that fingerprint and a request ID saved by your client: +Keep the field key unchanged, including nested tool indices. A field with `multiSelect:true` accepts selected IDs as one comma-separated string. + +### 4. Preview and apply the same choices + +Preview again with the exact mappings and values. When the preview is ready, apply its fingerprint using the request ID saved for this mutation: ```sh sim --profile destination --workspace "$DESTINATION_WORKSPACE" --output json \ @@ -71,15 +104,19 @@ sim --profile destination --workspace "$DESTINATION_WORKSPACE" --output json \ sim --profile destination --workspace "$DESTINATION_WORKSPACE" --output json \ workflows import --workflow @workflow.json \ --mappings @mappings.json --dependent-values @values.json \ - --preview-fingerprint "$(jq -r .previewFingerprint preview.json)" \ - --request-id "$REQUEST_ID" --wait + --preview-fingerprint "$(jq -er '.previewFingerprint' preview.json)" \ + --request-id "$IMPORT_REQUEST_ID" --wait ``` -Mapped import creates a draft atomically after required bindings and configuration are resolved. The receipt includes the imported IDs and `idMap`. Imports without mapping options retain the existing behavior; they do not return a durable operation receipt. Supplying mapping options, even an empty `--mappings '[]'`, requires both `--request-id` and `--preview-fingerprint`. JSON flags accept `@file` and `@-` for stdin. +Mapped import creates the draft atomically after required bindings/configuration resolve. The receipt includes imported IDs and `idMap`; remapping occurs before graph ID regeneration. The workflow remains a draft and must be deployed for ordinary execution. + +Plain imports without mapping options retain their earlier behavior and return no durable operation receipt. Supplying mapping options, including `--mappings '[]'`, requires both `--request-id` and `--preview-fingerprint`. JSON flags accept `@file` or `@-` for local stdin. ## Fork, push, and pull -Inspect `workspaces fork-availability`, `lineage`, and `fork-resources`, then use `fork-preview` and `fork` with identical name and copy selections. A fork creates child drafts; resource copying must be explicitly selected. +### Create a fork + +Inspect `workspaces fork-availability`, `lineage`, and `fork-resources`. Resource copies are opt-in. Preview and apply the identical name and copy selections: ```sh sim --profile source --workspace "$SOURCE_WORKSPACE" --output json \ @@ -92,11 +129,17 @@ sim --profile source --workspace "$SOURCE_WORKSPACE" --output json \ sim --profile source --workspace "$SOURCE_WORKSPACE" --output json \ workspaces fork --name "Review environment" \ --copy '{"tables":["source-table"]}' \ - --preview-fingerprint "$(jq -r .previewFingerprint fork-preview.json)" \ + --preview-fingerprint "$(jq -er '.previewFingerprint' fork-preview.json)" \ --request-id "$FORK_REQUEST_ID" --wait ``` -Push means the current workspace sends its deployed workflows to `--other-workspace-id`. Pull means the other workspace sends them to the current workspace. These meanings are the same on either side of the edge. +Eligible deployed source workflows become child drafts. Neither fork nor sync copies credentials or secret values. Review destination configuration before deploying forked workflows. + +### Select the sync direction and mappings + +Push sends the current workspace's deployed workflows to `--other-workspace-id`. Pull brings the other workspace's deployed workflows into the current workspace. Direction is relative to the selected workspace, regardless of which side is the parent. The pair must form a direct fork relationship. + +Sync can replace target workflows and archive mapped targets whose source was deleted or archived. Review those actions before confirming: ```sh sim --profile destination --workspace "$DESTINATION_WORKSPACE" --output json \ @@ -104,59 +147,98 @@ sim --profile destination --workspace "$DESTINATION_WORKSPACE" --output json \ sim --profile destination --workspace "$DESTINATION_WORKSPACE" --output json \ workspaces pull --other-workspace-id "$SOURCE_WORKSPACE" \ - --preview-fingerprint "$(jq -r .previewFingerprint sync-preview.json)" \ + --preview-fingerprint "$(jq -er '.previewFingerprint' sync-preview.json)" \ --request-id "$SYNC_REQUEST_ID" --yes --wait ``` -Include the same inline mappings and dependent values on preview and apply. Sync values identify `sourceWorkflowId`, `sourceBlockId`, and `subBlockKey`; preview target IDs are not stable public override identities. Sync mapping entries use `resourceType`, `sourceId`, and `targetId` as returned by mapping inspection; import entries use `kind`. Inline sync mappings persist on the fork edge in the same transaction as the sync. - -`workspaces mappings get` also returns a storage `id` on each row. Strip it before reusing a result as input: `jq '[.data[] | {resourceType, sourceId, targetId}]'`. Use `oauth_credential` or `service_account_credential` for sync credential mappings, according to the credential type. +Include identical inline mappings, dependent values, and trigger choices on preview/apply when using them. Sync mapping entries use `resourceType`, `sourceId`, and `targetId`; import entries use `kind`. Inline sync mappings persist in the same transaction as the sync. -For example, `--mappings` and `--dependent-values` take these respective arrays: +For example, `--mappings` takes: ```json [{ "resourceType": "oauth_credential", "sourceId": "source-connection", "targetId": "destination-connection" }] ``` +Use `oauth_credential` or `service_account_credential` according to credential type. `workspaces mappings get` requires the other workspace and direction, and returns storage `id` fields. Strip them before reuse: + +```sh +sim --profile destination --workspace "$DESTINATION_WORKSPACE" --output json \ + workspaces mappings get --other-workspace-id "$SOURCE_WORKSPACE" --direction pull --limit 0 \ + | jq '[.data[] | {resourceType, sourceId, targetId}]' > sync-mappings.json +``` + +### Configure copies and dependent values + +Fork creation uses `--copy`; sync uses `--copy-resources`, for example `'{"tables":["source-table"]}'`. Fork `copy.files` contains workspace file IDs. Sync `copyResources.files` contains storage keys. + +Sync-dependent values identify source workflows, blocks, and field keys, rather than provisional preview target IDs: + ```json [{ "sourceWorkflowId": "source-workflow", "sourceBlockId": "source-agent", "subBlockKey": "tools[0].folder", "value": "destination-label" }] ``` -Use `--copy-resources` for sync copies, such as `'{"tables":["source-table"]}'`; fork creation uses `--copy`. Fork `copy.files` takes workspace file IDs; sync `copyResources.files` takes storage keys. Neither copies credentials or secret values. +Discover each field in its returned `discoveryWorkspaceId` using the returned selector context. This is the source when its parent resource is being copied and the destination when the parent is mapped. Keep nested field keys unchanged; multi-select values are one comma-separated string. + +Omitting `--dependent-values` reuses saved choices. Supplying the flag replaces choices for affected workflows, and `[]` clears them. A value in a target draft alone is not saved sync configuration. `dropReferences` acknowledges references deleted in the source; it cannot discard live source resources. + +### Review trigger URLs and target changes -For each sync configuration field, run selector discovery in its `discoveryWorkspaceId` with the returned context. This is the source workspace when the parent resource is being copied, and the destination workspace for an existing mapping. Use the returned field key unchanged, including nested tool indices. When `multiSelect` is true, send selected IDs as one comma-separated string. +Preview's `ready` means the change can commit; it is not deployment readiness. Sync replaces eligible targets and deploys admitted snapshots while preserving exclusions. Merely undeploying a source does not archive its mapped target. -Saved sync choices apply when `--dependent-values` is omitted. Supplying the flag replaces saved choices for the affected workflows; an explicit `[]` clears them. Values that exist only in a target draft are not saved sync choices. +Inspect `triggerSlots` before replacing webhook triggers: -Sync preview's `ready` describes whether the change can commit; it does not report deployment readiness. Sync replaces eligible target workflows and deploys the admitted snapshots. It preserves exclusions. Deleting a source can archive its mapped target; merely undeploying it does not. Rollback restores the latest target sync using prior deployed versions, and does not restore arbitrary drafts or undo every resource copy. +- Slots with `ownPath` preserve that URL and accept no override. +- Other slots can adopt a path from `adoptablePaths`, or select `adoptPath:null` for a new URL. +- `--trigger-mappings` entries use `sourceWorkflowId`, `sourceBlockId`, and `adoptPath`. Unknown, duplicate, or unavailable choices are rejected. -Inspect preview's `triggerSlots` before replacing webhook triggers. Slots with `ownPath` keep it. For other slots, `--trigger-mappings` accepts entries with `sourceWorkflowId`, `sourceBlockId`, and `adoptPath` selected from `adoptablePaths`, or `null` for a new URL. Pass the identical choices to preview and apply; unknown, duplicate, and unavailable choices are rejected. +Pass identical trigger choices to preview and apply. Candidates belong to the same target workflow and provider. Review reported trigger URL changes before using the destination. + +Rollback restores the latest inbound sync using prior deployed versions. It can archive sync-created workflows and restore archived targets, but does not restore arbitrary drafts or undo every resource copy. Inspect pending activation work. Unlink removes the relationship/mappings while retaining content; exclusions keep selected workflows out of later syncs. See [Workspace commands](/cli/workspaces). ## Reconcile completion and retries -A successful apply returns `operationId`, `requestId`, `applied`, `status`, resource IDs, and structured issues. `applied: true` means the transaction committed, even if later copying or deployment fails. +An apply receipt includes `operationId`, `requestId`, `workspaceId`, `applied`, `status`, resource IDs, and issues. `applied:true` means the transaction committed, even if later copying or deployment fails. -Poll in the receipt's `workspaceId`, which may differ from the workspace receiving workflows: +Poll in the receipt's workspace, which can differ from the workspace receiving workflows: | Operation | Receipt workspace | | --- | --- | -| Import | Destination workspace | +| Import | Destination | | Fork creation | Source workspace on which `fork` ran | -| Push or pull | Current `--workspace` on which the command ran | +| Push/pull | Current `--workspace` on which the command ran | ```sh sim --profile automation --workspace "$OPERATION_WORKSPACE_ID" --output json \ workspaces operations wait "$OPERATION_ID" --wait-timeout 300 ``` -If the response was lost, use `workspaces operations list --request-id "$REQUEST_ID"` in that same workspace, or retry the identical mutation. List results retain `{ "data": [...], "nextCursor": ... }`; single operation and preview results are unwrapped. Operation lists contain stored snapshots; use `operations get` or `operations wait` to refresh completion status. +The default wait is 3600 seconds; zero waits indefinitely. The request timeout is separate. Wait outcomes are: -Verify deployment readiness before treating a synced environment as ready. Inspect trigger URL changes and configuration issues in the report. Completion with warnings exits successfully; required configuration exits 3, failed completion exits 1, and wait timeout exits 4. Timeout and uncertain-mutation diagnostics retain reconciliation IDs. +| Exit code | Outcome | +| --- | --- | +| `0` | Completed, including completion with warnings | +| `1` | Failed completion or command/request failure | +| `3` | Operation committed but requires configuration | +| `4` | Wait timed out; the operation can still continue | -After a lost response, retry the exact mutation with the original request ID. Identical retries return the same operation. Changing inputs under that ID returns 409. If a preview is stale and nothing committed, request a new preview and use a new request ID for the revised request. The CLI never invents a fresh ID to retry an uncertain mutation. +Inspect `issues`, copied-resource progress, the exact admitted deployments' readiness, and trigger URL changes. Completed imports and forks remain drafts. For sync, verify deployment readiness before using the environment. + +### Recover a lost response + +Use `workspaces operations list --request-id "$REQUEST_ID"` in the same receipt workspace, or retry the identical mutation with its original ID. Lists retain `{data, nextCursor}` and contain stored snapshots; `operations get` or `operations wait` refreshes completion status. Timeout and uncertain-mutation diagnostics retain reconciliation IDs. + +Identical authorized retries return the original operation. Changed inputs under that request ID return 409. If a preview is stale and nothing committed, obtain a new preview and use a new ID for the revised request. The CLI does not invent a new ID to retry an uncertain mutation. ## Validation boundary -The repository's `bun run test:workflow-sync` harness starts a disposable PostgreSQL database and exercises real authorization, v2 HTTP adapters, CLI subprocesses, transactions, receipts, and deployment workers. External provider responses and the separate realtime process use controlled fixtures. This covers platform behavior and failure recovery; a provider connection still needs validation in the destination environment. +Validate provider connections in the destination environment as well as the platform operation report. Repository integration fixtures do not establish a live provider connection. + +## Related docs -Completed imports and forks are drafts. For sync, check the report's deployment readiness and copied-resource progress before using the environment. +- [API workflow guide](/api-reference/workflow-sync) +- [Workspace forking](/platform/enterprise/forks) +- [Workflow commands](/cli/workflows) +- [Workspace commands](/cli/workspaces) +- [Selectors](/cli/selectors) +- [Exit codes](/cli/scripting#exit-codes) +- [Workflow-sync contributor harness](/api-reference/workflow-sync#related-docs) diff --git a/apps/docs/content/docs/cli/workflows.mdx b/apps/docs/content/docs/cli/workflows.mdx index 019d9691255..0e670a1d73f 100644 --- a/apps/docs/content/docs/cli/workflows.mdx +++ b/apps/docs/content/docs/cli/workflows.mdx @@ -1,51 +1,49 @@ --- title: Workflows -description: Manage workflows — every subcommand, argument, and flag +description: Build, deploy, run, and inspect workflows from the terminal. --- import { CommandTable } from '@/components/ui/command-table' +Build, deploy, run, and inspect workflows from the terminal. + `sim workflows` is also spelled `sim workflow`. -Every command below also accepts the [global options](/cli/commands#global-options). +These commands accept the [global options](/cli/commands#global-options). + +## Workflows -## Activate workflow version +### List workflows ```bash -sim workflows activate create [options] +sim workflows list [options] ``` -Activate Workflow Version (OAuth login or personal API key required) - -**Arguments** - - - -| Argument | Required | Description | -| --- | --- | --- | -| `workflowId` | Yes | Unique workflow identifier. | -| `version` | Yes | Numeric deployment version. | - - - **Options** | Option | Required | Description | | --- | --- | --- | -| `-y, --yes` | Yes | Confirm this operation. | +| `--scope ` | No | Which lifecycle set to list: `active` (default) for live workflows, `archived` for workflows a `DELETE` archived. The folder filter resolves against active folders only, so pairing it with `archived` returns an empty page when the containing folder was archived too. Accepted values: `active`, `archived`. | +| `--folder ` | No | Folder path as shown in the app; the leading / is optional. | +| `--deployed-only` | No | Return only workflows with an active deployment when true. | +| `--no-deployed-only` | No | Send --deployed-only as false. | +| `--limit ` | No | Maximum items to return (0 for everything). Defaults to `0`. | +| `--search ` | No | Case-insensitive substring match against the resource name. | +| `--sort-by ` | No | Field used to sort the result. Do not rely on case-insensitive ordering when sorting by `name`. Defaults to "position". Accepted values: `position`, `name`, `createdAt`, `updatedAt`, `runCount`. | +| `--sort-order ` | No | Sort direction. Defaults to "asc". Accepted values: `asc`, `desc`. | -## Edit a workflow’s blocks, connections and settings with a batch of operations +API request and response schemas: [listWorkflows](/api-reference/workflows/listWorkflows). + +### Get workflow ```bash -sim workflows operations apply [options] +sim workflows get ``` -Edit a workflow’s blocks, connections and settings with a batch of operations (OAuth login or personal API key required) - **Arguments** @@ -56,27 +54,32 @@ Edit a workflow’s blocks, connections and settings with a batch of operations +API request and response schemas: [getWorkflow](/api-reference/workflows/getWorkflow). + +### Create workflow + +```bash +sim workflows create [options] +``` + **Options** | Option | Required | Description | | --- | --- | --- | -| `--dry-run` | No | Validate and lint without writing, auditing, or notifying collaborators. Returns the same validation, preparation warnings, lint findings, and ID-ownership conflicts (`409`) as a committed write. `needsRedeployment` describes the pre-write state. For semantic operations, `mintedBlockIds` is empty; `previewBlockIds` contains provisional IDs with a warning, since committing mints new IDs. | -| `--no-dry-run` | No | Send --dry-run as false. | -| `--operations ` | Yes | Edits to apply, in a single batch, keyed by operation_type: [{"operation_type":"add","block_id":"my-fn","params":{"type":"function","name":"My Fn","inputs":{"code":"return {ok:true}"}}},{"operation_type":"edit","block_id":"<uuid>","params":{"name":"Renamed","connections":{"success":"my-fn"}}},{"operation_type":"delete","block_id":"<uuid>"}]. Also extract_from_subflow, whose params carry {"subflowId":"<loop-id>"}, and insert_into_subflow, which creates a block and so takes an add’s params plus that subflowId (JSON, or @path / @- to read a file or stdin). | -| `--atomic` | No | Fail the whole batch when any operation is declined or any block input would be dropped. The default applies what it can and reports the rest in `skipped` and `inputValidationErrors`; `true` writes nothing and answers `409` instead. | -| `--no-atomic` | No | Send --atomic as false. | -| `--layout ` | No | Whether to reposition blocks the batch touched. `targeted` (default) nudges only the affected subgraph; `none` leaves every position exactly as supplied. Accepted values: `targeted`, `none`. | -| `--set-block-enabled ` | No | Blocks to enable or disable, applied after --operations: [{"block_id":"<uuid>","enabled":false}]. Disabling a loop or parallel cascades to its unlocked descendants; enabling a block whose container is disabled is declined (JSON, or @path / @- to read a file or stdin). | -| `-y, --yes` | No | Confirm this operation (required unless --dry-run). | +| `--name ` | Yes | Workflow name. | +| `--description ` | No | Optional workflow description. | +| `--folder ` | No | Existing folder path (leading / optional); create it first with sim workflows mkdir <path>. | -## Update workflow variables +API request and response schemas: [createWorkflow](/api-reference/workflows/createWorkflowV2). + +### Update workflow ```bash -sim workflows variables update [options] +sim workflows update [options] ``` **Arguments** @@ -95,15 +98,18 @@ sim workflows variables update [options] | Option | Required | Description | | --- | --- | --- | -| `--operations ` | Yes | Variable changes to apply in order, keyed by operation: [{"operation":"add","name":"my_var","type":"string","value":"hello"},{"operation":"edit","name":"my_var","value":"updated"},{"operation":"delete","name":"my_var"}] (JSON, or @path / @- to read a file or stdin). | -| `-y, --yes` | Yes | Confirm this operation. | +| `--name ` | No | Replacement workflow name. | +| `--description ` | No | Replacement workflow description; null clears it. (--description null sends the word, not JSON null). | +| `--folder ` | No | Folder path as shown in the app; the leading / is optional. | -## Cancel a running workflow run +API request and response schemas: [updateWorkflow](/api-reference/workflows/updateWorkflowV2). + +### Duplicate workflow ```bash -sim workflows runs cancel [options] +sim workflows duplicate create [options] ``` **Arguments** @@ -112,7 +118,7 @@ sim workflows runs cancel [options] | Argument | Required | Description | | --- | --- | --- | -| `runId` | Yes | Unique workflow run identifier. | +| `workflowId` | Yes | Unique workflow identifier. | @@ -122,81 +128,66 @@ sim workflows runs cancel [options] | Option | Required | Description | | --- | --- | --- | -| `--workflow ` | Yes | Workflow ID. | +| `--name ` | No | Name for the copy. Defaults to the source name, deduplicated within the folder. | +| `--folder ` | No | Folder path as shown in the app; the leading / is optional. | -## Show run status +API request and response schemas: [duplicateWorkflow](/api-reference/workflows/duplicateWorkflow). + +### Move workflows ```bash -sim workflows runs get [options] +sim workflows move [options] ``` -Show run status (requested outputs are included in JSON or YAML output) - -**Arguments** - - - -| Argument | Required | Description | -| --- | --- | --- | -| `runId` | Yes | Unique workflow run identifier. | - - - **Options** | Option | Required | Description | | --- | --- | --- | -| `--workflow ` | Yes | Workflow ID. | -| `--include-output` | No | Include the final output in JSON or YAML output. | -| `--select-output ` | No | Include blockName.path or blockId.path values (e.g. agent_1.content) in JSON or YAML output; names resolve against the workflow’s current blocks, and missing paths are omitted (space-separated, or @path / @- with one value per line; @@value for a literal leading @). | -| `--include-file-base64` | No | Inline each produced file's bytes as base64. Requires `includeOutput`. A file above the inline ceiling answers `413` naming its download path; fetch large files from `downloadPath` instead. | -| `--no-include-file-base64` | No | Send --include-file-base64 as false. | -| `--base64-max-bytes ` | No | Per-file inline ceiling, lowering but never raising the server limit of 16 MiB. | +| `--workflow ` | Yes | Workflows to move. Duplicates are collapsed. (space-separated, or @path / @- with one value per line; @@value for a literal leading @). | +| `--to ` | Yes | Destination folder path; / moves the workflows to the workspace root. | -## List runs for a workflow +API request and response schemas: [moveWorkflows](/api-reference/workflows/moveWorkflows). + +### Move a workflow to a folder ```bash -sim workflows runs list [options] +sim workflows mv ``` -**Options** +**Arguments** -| Option | Required | Description | +| Argument | Required | Description | | --- | --- | --- | -| `--workflow ` | Yes | Workflow ID. | -| `--status ` | No | Filter by run status. Accepted values: `pending`, `running`, `completed`, `failed`, `cancelled`, `paused`. | -| `--trigger ` | No | Filter by trigger type. | -| `--start-date ` | No | Only include runs started at or after this UTC ISO 8601 timestamp, e.g. `2026-08-06T00:00:00Z`. A date without a time, or a timestamp carrying a UTC offset instead of `Z`, is rejected, as is year `0000`, which names no storable instant. | -| `--end-date ` | No | Only include runs started at or before this UTC ISO 8601 timestamp, e.g. `2026-08-06T00:00:00Z`. A date without a time, or a timestamp carrying a UTC offset instead of `Z`, is rejected, as is year `0000`, which names no storable instant. | -| `--limit ` | No | Maximum items to return (0 for everything). Defaults to `100`. | -| `--cursor ` | No | Continue from nextCursor returned by a previous result. | -| `--order ` | No | Sort direction by run start time. This list is sortable only by run start time, so it takes `order` in place of `sortBy`/`sortOrder`, which it rejects. Accepted values: `asc`, `desc`. | +| `workflowId` | Yes | Unique workflow identifier. | +| `folder` | Yes | Folder path as shown in the app; the leading / is optional | -## Resume a paused run +API request and response schemas: [updateWorkflow](/api-reference/workflows/updateWorkflowV2). + +### Delete workflow + +This archives the workflow and its run history; restore with `workflows restore`. ```bash -sim workflows runs resume [options] +sim workflows delete [options] ``` -Resume a paused run (output is included in JSON or YAML output) - **Arguments** | Argument | Required | Description | | --- | --- | --- | -| `runId` | Yes | Unique workflow run identifier. | +| `workflowId` | Yes | Unique workflow identifier. | @@ -206,16 +197,16 @@ Resume a paused run (output is included in JSON or YAML output) | Option | Required | Description | | --- | --- | --- | -| `--workflow ` | Yes | Workflow ID. | -| `--context ` | Yes | Pause context ID returned by run status. | -| `--input ` | No | Resume input as JSON (JSON, or @path / @- to read a file or stdin). | +| `-y, --yes` | Yes | Confirm this operation. | -## Wait for a run to reach a terminal state, then show it +API request and response schemas: [deleteWorkflow](/api-reference/workflows/deleteWorkflowV2). + +### Restore an archived workflow ```bash -sim workflows runs wait [options] +sim workflows restore ``` **Arguments** @@ -224,25 +215,18 @@ sim workflows runs wait [options] | Argument | Required | Description | | --- | --- | --- | -| `runId` | Yes | Unique workflow run identifier. | +| `workflowId` | Yes | Unique workflow identifier. | -**Options** - - - -| Option | Required | Description | -| --- | --- | --- | -| `--workflow ` | Yes | Workflow ID. | -| `--wait-timeout ` | No | Give up after this many seconds, or 0 to wait indefinitely (default: 3600). Bounds the whole wait; SIM_TIMEOUT_SECONDS bounds one request. | +API request and response schemas: [restoreWorkflow](/api-reference/workflows/restoreWorkflow). - +## Draft state and edits -## Compare workflow versions +### Get workflow state ```bash -sim workflows versions compare [options] +sim workflows state get ``` **Arguments** @@ -255,21 +239,16 @@ sim workflows versions compare [options] -**Options** - - +API request and response schemas: [getWorkflowState](/api-reference/workflows/getWorkflowState). -| Option | Required | Description | -| --- | --- | --- | -| `--base ` | Yes | Deployment version to compare from. | -| `--target ` | Yes | Deployment version to compare to, in the same workflow. | +### Replace workflow state - +OAuth login or personal API key required. -## Get workflow version +This replaces the entire draft graph and cannot be undone. ```bash -sim workflows versions get +sim workflows state replace [options] ``` **Arguments** @@ -279,14 +258,36 @@ sim workflows versions get | Argument | Required | Description | | --- | --- | --- | | `workflowId` | Yes | Unique workflow identifier. | -| `version` | Yes | Numeric deployment version. | -## List workflow versions +**Options** + + + +| Option | Required | Description | +| --- | --- | --- | +| `--dry-run` | No | Validate and lint without writing, auditing, or notifying collaborators. Returns the same validation, preparation warnings, lint findings, and ID-ownership conflicts (`409`) as a committed write. `needsRedeployment` describes the pre-write state. For semantic operations, `mintedBlockIds` is empty; `previewBlockIds` contains provisional IDs with a warning, since committing mints new IDs. | +| `--no-dry-run` | No | Send --dry-run as false. | +| `--blocks ` | Yes | Blocks keyed by block id. (JSON, or @path / @- to read a file or stdin). | +| `--edges ` | Yes | Directed connections between blocks. (JSON, or @path / @- to read a file or stdin). | +| `--loops ` | No | Ignored on write: loop containers are recomputed from `blocks`. (JSON, or @path / @- to read a file or stdin). | +| `--parallels ` | No | Ignored on write: parallel containers are recomputed from `blocks`. (JSON, or @path / @- to read a file or stdin). | +| `--variables ` | No | Replacement variable set. Omit to leave the stored variables untouched. (JSON, or @path / @- to read a file or stdin). | +| `-y, --yes` | Conditional | Confirm this operation (required unless --dry-run). | + + + +API request and response schemas: [replaceWorkflowState](/api-reference/workflows/replaceWorkflowState). + +### Edit a workflow’s blocks, connections and settings with a batch of operations + +OAuth login or personal API key required. + +This edits the draft graph: the batch adds, edits, or deletes blocks and their edges as written. ```bash -sim workflows versions list [options] +sim workflows operations apply [options] ``` **Arguments** @@ -305,15 +306,25 @@ sim workflows versions list [options] | Option | Required | Description | | --- | --- | --- | -| `--limit ` | No | Maximum items to return (0 for everything). Defaults to `100`. | -| `--cursor ` | No | Continue from nextCursor returned by a previous result. | +| `--dry-run` | No | Validate and lint without writing, auditing, or notifying collaborators. Returns the same validation, preparation warnings, lint findings, and ID-ownership conflicts (`409`) as a committed write. `needsRedeployment` describes the pre-write state. For semantic operations, `mintedBlockIds` is empty; `previewBlockIds` contains provisional IDs with a warning, since committing mints new IDs. | +| `--no-dry-run` | No | Send --dry-run as false. | +| `--operations ` | Yes | Edits to apply, in a single batch, keyed by operation_type: [{"operation_type":"add","block_id":"my-fn","params":{"type":"function","name":"My Fn","inputs":{"code":"return {ok:true}"}}},{"operation_type":"edit","block_id":"<uuid>","params":{"name":"Renamed","connections":{"success":"my-fn"}}},{"operation_type":"delete","block_id":"<uuid>"}]. Also extract_from_subflow, whose params carry {"subflowId":"<loop-id>"}, and insert_into_subflow, which creates a block and so takes an add’s params plus that subflowId (JSON, or @path / @- to read a file or stdin). | +| `--atomic` | No | Fail the whole batch when any operation is declined or any block input would be dropped. The default applies what it can and reports the rest in `skipped` and `inputValidationErrors`; `true` writes nothing and answers `409` instead. | +| `--no-atomic` | No | Send --atomic as false. | +| `--layout ` | No | Whether to reposition blocks the batch touched. `targeted` (default) nudges only the affected subgraph; `none` leaves every position exactly as supplied. Accepted values: `targeted`, `none`. | +| `--set-block-enabled ` | No | Blocks to enable or disable, applied after --operations: [{"block_id":"<uuid>","enabled":false}]. Disabling a loop or parallel cascades to its unlocked descendants; enabling a block whose container is disabled is declined (JSON, or @path / @- to read a file or stdin). | +| `-y, --yes` | Conditional | Confirm this operation (required unless --dry-run). | -## Update workflow version +API request and response schemas: [applyWorkflowOperations](/api-reference/workflows/applyWorkflowOperations). + +### Update workflow variables + +This applies the listed variable changes; variables omitted from the operations remain unchanged. ```bash -sim workflows versions update [options] +sim workflows variables update [options] ``` **Arguments** @@ -323,7 +334,6 @@ sim workflows versions update [options] | Argument | Required | Description | | --- | --- | --- | | `workflowId` | Yes | Unique workflow identifier. | -| `version` | Yes | Numeric deployment version. | @@ -333,33 +343,50 @@ sim workflows versions update [options] | Option | Required | Description | | --- | --- | --- | -| `--name ` | No | New label for the deployment version. | -| `--description ` | No | New release note for the deployment version, or null to clear it. (--description null sends the word, not JSON null). | +| `--operations ` | Yes | Variable changes to apply in order, keyed by operation: [{"operation":"add","name":"my_var","type":"string","value":"hello"},{"operation":"edit","name":"my_var","value":"updated"},{"operation":"delete","name":"my_var"}] (JSON, or @path / @- to read a file or stdin). | +| `-y, --yes` | Yes | Confirm this operation. | -## Create workflow +API request and response schemas: [applyWorkflowVariables](/api-reference/workflows/applyWorkflowVariables). + +## Deployments and versions + +### Deploy workflow + +OAuth login or personal API key required. ```bash -sim workflows create [options] +sim workflows deploy [options] ``` +**Arguments** + + + +| Argument | Required | Description | +| --- | --- | --- | +| `workflowId` | Yes | Unique workflow identifier. | + + + **Options** | Option | Required | Description | | --- | --- | --- | -| `--name ` | Yes | Workflow name. | -| `--description ` | No | Optional workflow description. | -| `--folder ` | No | Existing folder path (leading / optional); create it first with sim workflows mkdir <path>. | +| `--name ` | No | Optional label for the deployment version. | +| `--description ` | No | Optional release note for the deployment version. | -## Create a workflow folder at a path +API request and response schemas: [deployWorkflow](/api-reference/workflows/deployWorkflow). + +### Show a workflow’s current deployment ```bash -sim workflows folders create +sim workflows deployment status ``` **Arguments** @@ -368,14 +395,18 @@ sim workflows folders create | Argument | Required | Description | | --- | --- | --- | -| `path` | Yes | Folder path as shown in the app; the leading / is optional | +| `workflowId` | Yes | Unique workflow identifier. | -## Delete workflow folder +API request and response schemas: [getWorkflowDeployment](/api-reference/workflows/getWorkflowDeployment). + +### Update workflow public API access + +OAuth login or personal API key required. ```bash -sim workflows folders delete [options] +sim workflows deployment update [options] ``` **Arguments** @@ -384,7 +415,7 @@ sim workflows folders delete [options] | Argument | Required | Description | | --- | --- | --- | -| `path` | Yes | Folder path as shown in the app; the leading / is optional | +| `workflowId` | Yes | Unique workflow identifier. | @@ -394,18 +425,27 @@ sim workflows folders delete [options] | Option | Required | Description | | --- | --- | --- | -| `--recursive` | No | Delete the folder and its descendants. | -| `-y, --yes` | Yes | Confirm this operation. | +| `--is-public-api ` | Yes | Whether the deployed workflow should accept unauthenticated public API execution. Accepted values: `true`, `false`. | -## List workflow folders +API request and response schemas: [updateWorkflowPublicApi](/api-reference/workflows/updateWorkflowPublicApi). + +### List workflow versions ```bash -sim workflows folders list [options] +sim workflows versions list [options] ``` -Also available as `sim workflows folders ls`. +**Arguments** + + + +| Argument | Required | Description | +| --- | --- | --- | +| `workflowId` | Yes | Unique workflow identifier. | + + **Options** @@ -413,36 +453,36 @@ Also available as `sim workflows folders ls`. | Option | Required | Description | | --- | --- | --- | -| `--parent ` | No | Direct parent folder path. | -| `--search ` | No | Case-insensitive substring match against the folder name. | -| `--sort-by ` | No | Field used to sort the result. Sorting by `name` is case-sensitive and follows the storage collation, so do not rely on a case-insensitive order. Accepted values: `name`, `createdAt`, `updatedAt`. | -| `--sort-order ` | No | Sort direction. Accepted values: `asc`, `desc`. | +| `--limit ` | No | Maximum items to return (0 for everything). Defaults to `100`. | +| `--cursor ` | No | Continue from nextCursor returned by a previous result. | -## Rename or move a workflow folder +API request and response schemas: [listWorkflowVersions](/api-reference/workflows/listWorkflowVersionsV2). + +### Get workflow version ```bash -sim workflows folders move +sim workflows versions get ``` -Also available as `sim workflows folders mv`. - **Arguments** | Argument | Required | Description | | --- | --- | --- | -| `path` | Yes | Folder path as shown in the app; the leading / is optional | -| `destination` | Yes | Folder path as shown in the app; the leading / is optional | +| `workflowId` | Yes | Unique workflow identifier. | +| `version` | Yes | Numeric deployment version. | -## Delete workflow +API request and response schemas: [getWorkflowVersion](/api-reference/workflows/getWorkflowVersionV2). + +### Update workflow version ```bash -sim workflows delete [options] +sim workflows versions update [options] ``` **Arguments** @@ -452,6 +492,7 @@ sim workflows delete [options] | Argument | Required | Description | | --- | --- | --- | | `workflowId` | Yes | Unique workflow identifier. | +| `version` | Yes | Numeric deployment version. | @@ -461,18 +502,19 @@ sim workflows delete [options] | Option | Required | Description | | --- | --- | --- | -| `-y, --yes` | Yes | Confirm this operation. | +| `--name ` | No | New label for the deployment version. | +| `--description ` | No | New release note for the deployment version, or null to clear it. (--description null sends the word, not JSON null). | -## Take a workflow’s chat deployment offline +API request and response schemas: [updateWorkflowVersion](/api-reference/workflows/updateWorkflowVersionV2). + +### Compare workflow versions ```bash -sim workflows chat unpublish [options] +sim workflows versions compare [options] ``` -Take a workflow’s chat deployment offline (OAuth login or personal API key required) - **Arguments** @@ -489,18 +531,23 @@ Take a workflow’s chat deployment offline (OAuth login or personal API key req | Option | Required | Description | | --- | --- | --- | -| `-y, --yes` | Yes | Confirm this operation. | +| `--base ` | Yes | Deployment version to compare from. | +| `--target ` | Yes | Deployment version to compare to, in the same workflow. | -## Show a workflow’s chat deployment +API request and response schemas: [compareWorkflowVersions](/api-reference/workflows/compareWorkflowVersionsV2). + +### Activate workflow version + +OAuth login or personal API key required. + +This changes which deployed version runs in production for every API and chat consumer. ```bash -sim workflows chat status +sim workflows activate create [options] ``` -Show a workflow’s chat deployment (OAuth login or personal API key required) - **Arguments** @@ -508,16 +555,31 @@ Show a workflow’s chat deployment (OAuth login or personal API key required) | Argument | Required | Description | | --- | --- | --- | | `workflowId` | Yes | Unique workflow identifier. | +| `version` | Yes | Numeric deployment version. | -## Publish or replace a workflow’s chat deployment +**Options** -```bash -sim workflows chat publish [options] -``` + + +| Option | Required | Description | +| --- | --- | --- | +| `-y, --yes` | Yes | Confirm this operation. | + + + +API request and response schemas: [activateWorkflowVersion](/api-reference/workflows/activateWorkflowVersion). -Publish or replace a workflow’s chat deployment (OAuth login or personal API key required) +### Revert workflow to version + +OAuth login or personal API key required. + +This overwrites the draft graph with the selected version and cannot be undone. + +```bash +sim workflows revert create [options] +``` **Arguments** @@ -526,6 +588,7 @@ Publish or replace a workflow’s chat deployment (OAuth login or personal API k | Argument | Required | Description | | --- | --- | --- | | `workflowId` | Yes | Unique workflow identifier. | +| `version` | Yes | Numeric deployment version, or `active` for the currently live version. | @@ -535,30 +598,22 @@ Publish or replace a workflow’s chat deployment (OAuth login or personal API k | Option | Required | Description | | --- | --- | --- | -| `--identifier ` | Yes | URL slug the deployed chat answers on. Must be free across live deployments. | -| `--title ` | Yes | Title shown to visitors. | -| `--description ` | No | Description shown to visitors. Omitted clears it. | -| `--customizations ` | No | Presentation overrides. Omitted fields take platform defaults. (JSON, or @path / @- to read a file or stdin). | -| `--auth-type ` | No | How visitors are gated. `public` leaves the chat open to anyone holding the URL. Accepted values: `public`, `password`, `email`, `sso`. | -| `--password ` | No | Write-only password of 15 to 1024 characters, not only whitespace. Required whenever `authType` is `password`, and rejected otherwise. Never readable back. Taken literally, except that a request from the Sim agent resolves a whole-value `{{ENV_VAR}}` reference to that variable before the rules apply. | -| `--allowed-emails ` | No | Email addresses or domains admitted under `email` and `sso` gating. At least one is required for those modes. (JSON, or @path / @- to read a file or stdin). | -| `--output-configs ` | No | Block outputs to surface to visitors. Omitted surfaces none. (JSON, or @path / @- to read a file or stdin). | -| `--include-thinking` | No | Allow visitors to receive provider thinking events. | -| `--no-include-thinking` | No | Send --include-thinking as false. | -| `--include-tool-calls` | No | Allow visitors to receive tool lifecycle events. | -| `--no-include-tool-calls` | No | Send --include-tool-calls as false. | | `-y, --yes` | Yes | Confirm this operation. | -## Deploy workflow +API request and response schemas: [revertWorkflowVersion](/api-reference/workflows/revertWorkflowVersion). + +### Rollback workflow + +OAuth login or personal API key required. + +This changes which deployed version runs in production for every API and chat consumer. ```bash -sim workflows deploy [options] +sim workflows rollback [options] ``` -Deploy Workflow (OAuth login or personal API key required) - **Arguments** @@ -575,15 +630,21 @@ Deploy Workflow (OAuth login or personal API key required) | Option | Required | Description | | --- | --- | --- | -| `--name ` | No | Optional label for the deployment version. | -| `--description ` | No | Optional release note for the deployment version. | +| `--to-version ` | No | Deployment version to reactivate. Omit to select the previous active version. | +| `-y, --yes` | Yes | Confirm this operation. | -## Duplicate workflow +API request and response schemas: [rollbackWorkflow](/api-reference/workflows/rollbackWorkflow). + +### Take a workflow out of deployment + +OAuth login or personal API key required. + +This takes the workflow offline for every API and chat consumer, and agents calling its MCP tools lose access until it is deployed again. ```bash -sim workflows duplicate create [options] +sim workflows undeploy [options] ``` **Arguments** @@ -602,12 +663,15 @@ sim workflows duplicate create [options] | Option | Required | Description | | --- | --- | --- | -| `--name ` | No | Name for the copy. Defaults to the source name, deduplicated within the folder. | -| `--folder ` | No | Folder path as shown in the app; the leading / is optional. | +| `-y, --yes` | Yes | Confirm this operation. | -## Run a deployed workflow or execute saved state manually +API request and response schemas: [undeployWorkflow](/api-reference/workflows/undeployWorkflow). + +## Run and inspect + +### Run a deployed workflow or execute saved state manually ```bash sim workflows run [options] @@ -630,10 +694,10 @@ sim workflows run [options] | Option | Required | Description | | --- | --- | --- | | `--input ` | No | Trigger input as JSON (JSON, or @path / @- to read a file or stdin). | -| `--async` | No | Queue the run and return immediately. | +| `--async` | No | Queue the run and return immediately. Defaults to false. | | `--execution-timeout-seconds ` | No | Maximum duration of an asynchronous run, in seconds, capped by the plan's execution timeout. Requires `async: true`; otherwise returns `400`. | | `--select-output ` | No | Return blockName.path values (e.g. agent_1.content), or childWorkflowId.blockName.path for a child workflow (applies to every invocation) — in blockOutputs on a sync run, or from the streamed result with --follow; missing paths are omitted. Not available with --async (space-separated, or @path / @- with one value per line; @@value for a literal leading @). | -| `--include-file-base64` | No | Inline eligible output files as base64 content (default: true; Sim’s in-app agent gets file references only unless this flag is passed). Rejected when `async` is true. | +| `--include-file-base64` | No | Inline eligible output files as base64 content. Defaults to true for the installed CLI; Chat defaults to file references and admits requested bytes only for synchronous runs. Rejected when async is true. | | `--no-include-file-base64` | No | Send --include-file-base64 as false. | | `--base64-max-bytes ` | No | Maximum total bytes of file content to inline as base64, lowering but never raising the server limit of 16 MiB. Rejected when `async` is true. | | `--run-id ` | No | One-shot identifier for this run; NOT an idempotency key — reusing a claimed value fails with RUN_ID_CONFLICT instead of replaying the first result, and a fresh value starts another run. | @@ -649,10 +713,39 @@ sim workflows run [options] -## Print a workflow as a portable JSON document +API request and response schemas: [executeWorkflow](/api-reference/workflows/executeWorkflowV2). + +### List runs for a workflow ```bash -sim workflows export [options] +sim workflows runs list [options] +``` + +**Options** + + + +| Option | Required | Description | +| --- | --- | --- | +| `--workflow ` | Yes | Workflow ID. | +| `--status ` | No | Filter by run status. Accepted values: `pending`, `running`, `completed`, `failed`, `cancelled`, `paused`. | +| `--trigger ` | No | Filter by trigger type. | +| `--start-date ` | No | Only include runs started at or after this UTC ISO 8601 timestamp, e.g. `2026-08-06T00:00:00Z`. A date without a time, or a timestamp carrying a UTC offset instead of `Z`, is rejected, as is year `0000`, which names no storable instant. | +| `--end-date ` | No | Only include runs started at or before this UTC ISO 8601 timestamp, e.g. `2026-08-06T00:00:00Z`. A date without a time, or a timestamp carrying a UTC offset instead of `Z`, is rejected, as is year `0000`, which names no storable instant. | +| `--limit ` | No | Maximum items to return (0 for everything). Defaults to `100`. | +| `--cursor ` | No | Continue from nextCursor returned by a previous result. | +| `--order ` | No | Sort direction by run start time. This list is sortable only by run start time, so it takes `order` in place of `sortBy`/`sortOrder`, which it rejects. Defaults to "desc". Accepted values: `asc`, `desc`. | + + + +API request and response schemas: [listWorkflowRuns](/api-reference/workflow-runs/listWorkflowRunsV2). + +### Show run status + +Requested outputs are included in JSON or YAML output. + +```bash +sim workflows runs get [options] ``` **Arguments** @@ -661,7 +754,7 @@ sim workflows export [options] | Argument | Required | Description | | --- | --- | --- | -| `workflowId` | Yes | Unique workflow identifier. | +| `runId` | Yes | Unique workflow run identifier. | @@ -671,16 +764,21 @@ sim workflows export [options] | Option | Required | Description | | --- | --- | --- | -| `--include-references` | No | Include non-secret resource identities for mapped import. | -| `--include-workspace-bindings` | No | Whether to keep workspace-scoped bindings — table, knowledge base, document, folder, channel, and other resource selectors — in the exported state. Defaults to false, the sharing-safe export in which those ids are cleared because they resolve nowhere else. Send true for a same-workspace round trip so the re-imported workflow can run without re-selecting them. Credentials, passwords, and table sub-block values are cleared either way. | -| `--no-include-workspace-bindings` | No | Send --include-workspace-bindings as false. | +| `--workflow ` | Yes | Workflow ID. | +| `--include-output` | No | Include the final output in JSON or YAML output. | +| `--select-output ` | No | Include blockName.path or blockId.path values (e.g. agent_1.content) in JSON or YAML output; names resolve against the workflow’s current blocks, and missing paths are omitted (space-separated, or @path / @- with one value per line; @@value for a literal leading @). | +| `--include-file-base64` | No | Inline each produced file's bytes as base64. Requires `includeOutput`. A file above the inline ceiling answers `413` naming its download path; fetch large files from `downloadPath` instead. | +| `--no-include-file-base64` | No | Send --include-file-base64 as false. | +| `--base64-max-bytes ` | No | Per-file inline ceiling, lowering but never raising the server limit of 16 MiB. | -## Get workflow +API request and response schemas: [getWorkflowRun](/api-reference/workflow-runs/getWorkflowRunV2). + +### Wait until a run finishes or needs input [#wait-for-a-run-to-reach-a-terminal-state-then-show-it] ```bash -sim workflows get +sim workflows runs wait [options] ``` **Arguments** @@ -689,14 +787,31 @@ sim workflows get | Argument | Required | Description | | --- | --- | --- | -| `workflowId` | Yes | Unique workflow identifier. | +| `runId` | Yes | Unique workflow run identifier. | + + + +**Options** + + + +| Option | Required | Description | +| --- | --- | --- | +| `--workflow ` | Yes | Workflow ID. | +| `--wait-timeout ` | No | Give up after this many seconds, or 0 to wait indefinitely (default: 3600). Bounds the whole wait; SIM_TIMEOUT_SECONDS bounds one request. | -## Show a workflow’s current deployment +Exit codes: 0 completed, 1 failed, 2 cancelled, 3 needs input, 4 timed out. Time-based pauses continue waiting; a human pause or an unspecified pause kind ends the wait with code 3. Use `sim workflows runs resume` with the pause context to continue. + +API request and response schemas: [getWorkflowRun](/api-reference/workflow-runs/getWorkflowRunV2). + +### Resume a paused run + +Output is included in JSON or YAML output. ```bash -sim workflows deployment status +sim workflows runs resume [options] ``` **Arguments** @@ -705,25 +820,39 @@ sim workflows deployment status | Argument | Required | Description | | --- | --- | --- | -| `workflowId` | Yes | Unique workflow identifier. | +| `runId` | Yes | Unique workflow run identifier. | -## Update workflow public API access +**Options** + + + +| Option | Required | Description | +| --- | --- | --- | +| `--workflow ` | Yes | Workflow ID. | +| `--context ` | Yes | Pause context ID returned by run status. | +| `--input ` | No | Resume input as JSON (JSON, or @path / @- to read a file or stdin). | + + + +API request and response schemas: [resumeWorkflow](/api-reference/workflow-runs/resumeWorkflowRunV2). + +### Cancel a running workflow run + +Canceling a paused run prevents resuming that run. Starting a new run can repeat side effects already performed. ```bash -sim workflows deployment update [options] +sim workflows runs cancel [options] ``` -Update Workflow Public API Access (OAuth login or personal API key required) - **Arguments** | Argument | Required | Description | | --- | --- | --- | -| `workflowId` | Yes | Unique workflow identifier. | +| `runId` | Yes | Unique workflow run identifier. | @@ -733,14 +862,20 @@ Update Workflow Public API Access (OAuth login or personal API key required) | Option | Required | Description | | --- | --- | --- | -| `--is-public-api ` | Yes | Whether the deployed workflow should accept unauthenticated public API execution. Accepted values: `true`, `false`. | +| `--workflow ` | Yes | Workflow ID. | -## Get workflow state +API request and response schemas: [cancelWorkflowRun](/api-reference/workflow-runs/cancelRunV2). + +## Chat deployments + +### Show a workflow’s chat deployment + +OAuth login or personal API key required. ```bash -sim workflows state get +sim workflows chat status ``` **Arguments** @@ -753,14 +888,20 @@ sim workflows state get -## Replace workflow state +API request and response schemas: [getWorkflowChatDeployment](/api-reference/workflows/getWorkflowChatDeployment). + +### Deploy or replace a workflow chat [#publish-or-replace-a-workflows-chat-deployment] + +OAuth login or personal API key required. + +This replaces visitor access settings for the chat deployment. Omitted authentication fields reset to defaults, including the password and allowed-email list; avatar and welcome-message behavior follows their option descriptions. + +Omitting `--auth-type` selects public access: anyone holding the URL can chat. Supply the complete password or allow-list settings again when replacing a restricted deployment. ```bash -sim workflows state replace [options] +sim workflows chat publish [options] ``` -Replace Workflow State (OAuth login or personal API key required) - **Arguments** @@ -777,84 +918,91 @@ Replace Workflow State (OAuth login or personal API key required) | Option | Required | Description | | --- | --- | --- | -| `--dry-run` | No | Validate and lint without writing, auditing, or notifying collaborators. Returns the same validation, preparation warnings, lint findings, and ID-ownership conflicts (`409`) as a committed write. `needsRedeployment` describes the pre-write state. For semantic operations, `mintedBlockIds` is empty; `previewBlockIds` contains provisional IDs with a warning, since committing mints new IDs. | -| `--no-dry-run` | No | Send --dry-run as false. | -| `--blocks ` | Yes | Blocks keyed by block id. (JSON, or @path / @- to read a file or stdin). | -| `--edges ` | Yes | Directed connections between blocks. (JSON, or @path / @- to read a file or stdin). | -| `--loops ` | No | Ignored on write: loop containers are recomputed from `blocks`. (JSON, or @path / @- to read a file or stdin). | -| `--parallels ` | No | Ignored on write: parallel containers are recomputed from `blocks`. (JSON, or @path / @- to read a file or stdin). | -| `--variables ` | No | Replacement variable set. Omit to leave the stored variables untouched. (JSON, or @path / @- to read a file or stdin). | -| `-y, --yes` | No | Confirm this operation (required unless --dry-run). | +| `--identifier ` | Yes | URL slug the deployed chat answers on. Must be free across live deployments. | +| `--title ` | Yes | Title shown to visitors. | +| `--description ` | No | Description shown to visitors. Omitted clears it. | +| `--customizations ` | No | Presentation overrides. Omitted `primaryColor` and `welcomeMessage` use platform defaults; an omitted or empty `imageUrl` keeps the existing avatar. An empty `welcomeMessage` keeps the existing message. (JSON, or @path / @- to read a file or stdin). | +| `--auth-type ` | No | How visitors are gated. `public` leaves the chat open to anyone holding the URL. Defaults to "public". Accepted values: `public`, `password`, `email`, `sso`. | +| `--password ` | Conditional | Write-only password of 15 to 1024 characters, not only whitespace. Required whenever `authType` is `password`, and rejected otherwise. Never readable back. Taken literally, except that a request from the Sim agent resolves a whole-value `{{ENV_VAR}}` reference to that variable before the rules apply. | +| `--allowed-emails ` | No | Email addresses or domains admitted under `email` and `sso` gating. At least one is required for those modes. (JSON, or @path / @- to read a file or stdin). | +| `--output-configs ` | No | Block outputs to surface to visitors. Omitted surfaces none. (JSON, or @path / @- to read a file or stdin). | +| `--include-thinking` | No | Allow visitors to receive provider thinking events. Defaults to false. | +| `--no-include-thinking` | No | Send --include-thinking as false. | +| `--include-tool-calls` | No | Allow visitors to receive tool lifecycle events. Defaults to false. | +| `--no-include-tool-calls` | No | Send --include-tool-calls as false. | +| `-y, --yes` | Yes | Confirm this operation. | -## Import workflow +API request and response schemas: [replaceWorkflowChatDeployment](/api-reference/workflows/replaceWorkflowChatDeployment). + +### Take a workflow’s chat deployment offline + +OAuth login or personal API key required. + +This takes the chat offline and frees its identifier. The workflow itself stays deployed and executable. ```bash -sim workflows import [options] +sim workflows chat unpublish [options] ``` -**Options** +**Arguments** -| Option | Required | Description | +| Argument | Required | Description | | --- | --- | --- | -| `--workflow ` | Yes | Workflow export object, bare workflow state, or JSON string containing either form. (JSON, or @path / @- to read a file or stdin). | -| `--folder ` | No | Folder path as shown in the app; the leading / is optional. | -| `--name ` | No | Override for the imported workflow name. | -| `--description ` | No | Override for the imported workflow description. | -| `--mappings ` | No | Mappings keyed by resource type and source identifier. (JSON, or @path / @- to read a file or stdin). | -| `--bindings ` | No | Resolved and unresolved source occurrences with their destination selections. (JSON, or @path / @- to read a file or stdin). | -| `--dependent-values ` | No | Destination-dependent choices keyed by source workflow, block, and field identities. (JSON, or @path / @- to read a file or stdin). | -| `--request-id ` | No | Stable client request ID for reconciliation and identical retries. | -| `--preview-fingerprint ` | No | Fingerprint of the reviewed preview and its choices. | -| `--wait` | No | Wait for the committed operation to finish; missing configuration and failure exit nonzero. | -| `--wait-timeout ` | No | Maximum operation wait in seconds (default 3600; 0 waits indefinitely). | +| `workflowId` | Yes | Unique workflow identifier. | -## List workflows - -```bash -sim workflows list [options] -``` - **Options** | Option | Required | Description | | --- | --- | --- | -| `--scope ` | No | Which lifecycle set to list: `active` (default) for live workflows, `archived` for workflows a `DELETE` archived. The folder filter resolves against active folders only, so pairing it with `archived` returns an empty page when the containing folder was archived too. Accepted values: `active`, `archived`. | -| `--folder ` | No | Folder path as shown in the app; the leading / is optional. | -| `--deployed-only` | No | Return only workflows with an active deployment when true. | -| `--no-deployed-only` | No | Send --deployed-only as false. | -| `--limit ` | No | Maximum items to return (0 for everything). Defaults to `0`. | -| `--search ` | No | Case-insensitive substring match against the resource name. | -| `--sort-by ` | No | Field used to sort the result. Sorting by `name` is case-sensitive and follows the storage collation, so do not rely on a case-insensitive order. Accepted values: `position`, `name`, `createdAt`, `updatedAt`, `runCount`. | -| `--sort-order ` | No | Sort direction. Accepted values: `asc`, `desc`. | +| `-y, --yes` | Yes | Confirm this operation. | -## Move workflows +API request and response schemas: [deleteWorkflowChatDeployment](/api-reference/workflows/deleteWorkflowChatDeployment). + +## Export and import + +### Print a workflow as a portable JSON document + +The export clears credentials, passwords, and table sub-block values, but it is not a general secret scanner. Inspect literal variables and inline configuration before sharing the document. ```bash -sim workflows move [options] +sim workflows export [options] ``` +**Arguments** + + + +| Argument | Required | Description | +| --- | --- | --- | +| `workflowId` | Yes | Unique workflow identifier. | + + + **Options** | Option | Required | Description | | --- | --- | --- | -| `--workflow ` | Yes | Workflows to move. Duplicates are collapsed. (space-separated, or @path / @- with one value per line; @@value for a literal leading @). | -| `--to ` | Yes | Destination folder path; / moves the workflows to the workspace root. | +| `--include-references` | No | Include non-secret resource identities for mapped import. | +| `--include-workspace-bindings` | No | Keep non-secret table, knowledge base, document, folder, channel, and other workspace bindings for a same-workspace import. Defaults to false, which clears these IDs. Registered credential fields and opaque table/tool values are cleared either way; environment references and ordinary workflow variables remain included. | +| `--no-include-workspace-bindings` | No | Send --include-workspace-bindings as false. | -## Preview workflow import +API request and response schemas: [exportWorkflow](/api-reference/workflows/exportWorkflow). + +### Preview workflow import ```bash sim workflows import-preview [options] @@ -870,44 +1018,57 @@ sim workflows import-preview [options] | `--folder ` | No | Folder path as shown in the app; the leading / is optional. | | `--name ` | No | Override for the imported workflow name. | | `--description ` | No | Override for the imported workflow description. | -| `--mappings ` | No | Mappings keyed by resource type and source identifier. (JSON, or @path / @- to read a file or stdin). | +| `--mappings ` | No | Mapping entries addressed by resource kind and source identifier. (JSON, or @path / @- to read a file or stdin). | | `--bindings ` | No | Resolved and unresolved source occurrences with their destination selections. (JSON, or @path / @- to read a file or stdin). | -| `--dependent-values ` | No | Destination-dependent choices keyed by source workflow, block, and field identities. (JSON, or @path / @- to read a file or stdin). | +| `--dependent-values ` | No | Destination-specific values addressed by the source block ID and field key, before imported IDs are regenerated. (JSON, or @path / @- to read a file or stdin). | -## Restore an archived workflow +API request and response schemas: [previewWorkflowImport](/api-reference/workspace-sync/previewWorkflowImport). + +### Import workflow ```bash -sim workflows restore +sim workflows import [options] ``` -**Arguments** +**Options** -| Argument | Required | Description | +| Option | Required | Description | | --- | --- | --- | -| `workflowId` | Yes | Unique workflow identifier. | +| `--workflow ` | Yes | Workflow export object, bare workflow state, or JSON string containing either form. (JSON, or @path / @- to read a file or stdin). | +| `--folder ` | No | Folder path as shown in the app; the leading / is optional. | +| `--name ` | No | Override for the imported workflow name. | +| `--description ` | No | Override for the imported workflow description. | +| `--mappings ` | No | Mapping entries addressed by resource kind and source identifier. (JSON, or @path / @- to read a file or stdin). | +| `--bindings ` | No | Resolved and unresolved source occurrences with their destination selections. (JSON, or @path / @- to read a file or stdin). | +| `--dependent-values ` | No | Destination-specific values addressed by the source block ID and field key, before imported IDs are regenerated. (JSON, or @path / @- to read a file or stdin). | +| `--request-id ` | No | Stable client request ID for mapped import. Reuse it with identical inputs after an uncertain response; changed inputs return 409. A new ID can create another workflow. | +| `--preview-fingerprint ` | No | Fingerprint returned by an import preview with the same choices. A changed plan returns 409; preview again. Do not invent this value. | +| `--wait` | No | Wait for the committed operation to finish; missing configuration and failure exit nonzero. | +| `--wait-timeout ` | No | Maximum operation wait in seconds (default 3600; 0 waits indefinitely). | -## Revert workflow to version +API request and response schemas: [importWorkflow](/api-reference/workflows/importWorkflow). + +## Folders + +### List workflow resources and child folders together ```bash -sim workflows revert create [options] +sim workflows ls [path] [options] ``` -Revert Workflow To Version (OAuth login or personal API key required) - **Arguments** | Argument | Required | Description | | --- | --- | --- | -| `workflowId` | Yes | Unique workflow identifier. | -| `version` | Yes | Numeric deployment version, or `active` for the currently live version. | +| `path` | No | Folder path to list; defaults to the root folder | @@ -917,27 +1078,20 @@ Revert Workflow To Version (OAuth login or personal API key required) | Option | Required | Description | | --- | --- | --- | -| `-y, --yes` | Yes | Confirm this operation. | +| `--search ` | No | Filter folders and resources by name. | +| `--limit ` | No | Maximum combined items to return (0 for everything). Defaults to `0`. | -## Rollback workflow +API request and response schemas: [listWorkflows](/api-reference/workflows/listWorkflows), [listWorkflowFolders](/api-reference/workflows/listWorkflowsFolders). + +### List workflow folders ```bash -sim workflows rollback [options] +sim workflows folders list [options] ``` -Rollback Workflow (OAuth login or personal API key required) - -**Arguments** - - - -| Argument | Required | Description | -| --- | --- | --- | -| `workflowId` | Yes | Unique workflow identifier. | - - +Also available as `sim workflows folders ls`. **Options** @@ -945,43 +1099,39 @@ Rollback Workflow (OAuth login or personal API key required) | Option | Required | Description | | --- | --- | --- | -| `--to-version ` | No | Deployment version to reactivate. Omit to select the previous active version. | -| `-y, --yes` | Yes | Confirm this operation. | +| `--parent ` | No | Direct parent folder path. | +| `--search ` | No | Case-insensitive substring match against the folder name. | +| `--sort-by ` | No | Field used to sort the result. Do not rely on case-insensitive ordering when sorting by `name`. Defaults to "name". Accepted values: `name`, `createdAt`, `updatedAt`. | +| `--sort-order ` | No | Sort direction. Defaults to "asc". Accepted values: `asc`, `desc`. | -## Take a workflow out of deployment +API request and response schemas: [listWorkflowFolders](/api-reference/workflows/listWorkflowsFolders). + +### Create a workflow folder at a path ```bash -sim workflows undeploy [options] +sim workflows folders create ``` -Take a workflow out of deployment (OAuth login or personal API key required) - **Arguments** | Argument | Required | Description | | --- | --- | --- | -| `workflowId` | Yes | Unique workflow identifier. | +| `path` | Yes | Folder path as shown in the app; the leading / is optional | -**Options** +API request and response schemas: [createWorkflowFolder](/api-reference/workflows/createWorkflowsFolder). - +### Delete workflow folder -| Option | Required | Description | -| --- | --- | --- | -| `-y, --yes` | Yes | Confirm this operation. | - - - -## Update workflow +This archives the workflow folder and, when recursive, everything inside it. ```bash -sim workflows update [options] +sim workflows folders delete [options] ``` **Arguments** @@ -990,7 +1140,7 @@ sim workflows update [options] | Argument | Required | Description | | --- | --- | --- | -| `workflowId` | Yes | Unique workflow identifier. | +| `path` | Yes | Folder path as shown in the app; the leading / is optional | @@ -1000,57 +1150,35 @@ sim workflows update [options] | Option | Required | Description | | --- | --- | --- | -| `--name ` | No | Replacement workflow name. | -| `--description ` | No | Replacement workflow description; null clears it. (--description null sends the word, not JSON null). | -| `--folder ` | No | Folder path as shown in the app; the leading / is optional. | +| `--recursive` | No | Archive the folder and its descendants. Defaults to "false". | +| `-y, --yes` | Yes | Confirm this operation. | -## Move a workflow to a folder - -```bash -sim workflows mv -``` - -**Arguments** +API request and response schemas: [deleteWorkflowFolder](/api-reference/workflows/deleteWorkflowsFolder). - - -| Argument | Required | Description | -| --- | --- | --- | -| `workflowId` | Yes | Unique workflow identifier. | -| `folder` | Yes | Folder path as shown in the app; the leading / is optional | - - - -## List workflow resources and child folders together +### Rename or move a workflow folder ```bash -sim workflows ls [path] [options] +sim workflows folders move ``` +Also available as `sim workflows folders mv`. + **Arguments** | Argument | Required | Description | | --- | --- | --- | -| `path` | No | Folder path to list; defaults to the root folder | +| `path` | Yes | Folder path as shown in the app; the leading / is optional | +| `destination` | Yes | Folder path as shown in the app; the leading / is optional | -**Options** - - - -| Option | Required | Description | -| --- | --- | --- | -| `--search ` | No | Filter folders and resources by name. | -| `--limit ` | No | Maximum combined items to return (0 for everything). Defaults to `0`. | +API request and response schemas: [relocateWorkflowFolder](/api-reference/workflows/relocateWorkflowsFolder). - - -## Create a workflow directory at a path +### Create a workflow directory at a path ```bash sim workflows mkdir @@ -1065,3 +1193,11 @@ sim workflows mkdir | `path` | Yes | Folder path to create; the leading / is optional | + +API request and response schemas: [createWorkflowFolder](/api-reference/workflows/createWorkflowsFolder). + +## Related docs + +- [Workflow builder](/workflows) +- [Import and workspace sync](/cli/workflow-sync) +- [Scripting and exit codes](/cli/scripting#exit-codes) diff --git a/apps/docs/content/docs/cli/workspaces.mdx b/apps/docs/content/docs/cli/workspaces.mdx index 3125fe12195..826b0d42133 100644 --- a/apps/docs/content/docs/cli/workspaces.mdx +++ b/apps/docs/content/docs/cli/workspaces.mdx @@ -1,39 +1,51 @@ --- title: Workspaces -description: Manage workspaces — every subcommand, argument, and flag +description: Read workspace access and manage reviewed fork, push, and pull operations. --- import { CommandTable } from '@/components/ui/command-table' +Read workspace access and manage reviewed fork, push, and pull operations. + `sim workspaces` is also spelled `sim workspace`. -Every command below also accepts the [global options](/cli/commands#global-options). +These commands accept the [global options](/cli/commands#global-options). + +## Workspace access -## Cancel workspace access request +### List workspaces ```bash -sim workspaces access-requests cancel +sim workspaces list [options] ``` -Cancel Workspace Access Request (OAuth login or personal API key required) - -**Arguments** +**Options** -| Argument | Required | Description | +| Option | Required | Description | | --- | --- | --- | -| `requestId` | Yes | Access request identifier. | +| `--sort-by ` | No | Field used to sort the result. Do not rely on case-insensitive ordering when sorting by `name`. Defaults to "createdAt". Accepted values: `name`, `createdAt`, `updatedAt`. | +| `--sort-order ` | No | Sort direction. Defaults to "desc". Accepted values: `asc`, `desc`. | +| `--limit ` | No | Maximum items to return (0 for everything). Defaults to `0`. | -## Create workspace access request +API request and response schemas: [listWorkspaces](/api-reference/workspaces/listWorkspaces). + +### Get workspace ```bash -sim workspaces access-requests create [options] +sim workspaces get ``` -Create Workspace Access Request (OAuth login or personal API key required) +API request and response schemas: [getWorkspace](/api-reference/workspaces/getWorkspace). + +### List workspace members + +```bash +sim workspaces members [options] +``` **Options** @@ -41,185 +53,155 @@ Create Workspace Access Request (OAuth login or personal API key required) | Option | Required | Description | | --- | --- | --- | -| `--target ` | Yes | Target returned by Discover Workspace Access Requests or Discover Organization Access Requests. The target must currently be requestable. (JSON, or @path / @- to read a file or stdin). | -| `--reason ` | No | Why the acting user needs this access. | +| `--limit ` | No | Maximum items to return (0 for everything). Defaults to `0`. | -## Discover workspace access requests +API request and response schemas: [listWorkspaceMembers](/api-reference/workspaces/listWorkspaceMembers). + +### Create workspace invitations + +OAuth login or personal API key required. ```bash -sim workspaces access-requests discover [options] +sim workspaces invitations create [options] ``` -Discover Workspace Access Requests (OAuth login or personal API key required) - **Options** | Option | Required | Description | | --- | --- | --- | -| `--search ` | No | Case-insensitive substring match against the access item label. | -| `--target-kind ` | No | Category of access to discover. Accepted values: `feature`, `integration`, `provider`, `model`, `tool`, `knowledge_connector`, `file_share_auth`, `chat_deploy_auth`, `usage_limit`. | -| `--state ` | No | Filter by the acting user’s current access. Requestable items can be submitted for review. Accepted values: `allowed`, `requestable`, `unavailable`. | -| `--sort-by ` | No | Field used to sort the result. Accepted values: `label`. | -| `--sort-order ` | No | Sort direction. Accepted values: `asc`, `desc`. | -| `--limit ` | No | Maximum items to return (0 for everything). Defaults to `100`. | -| `--cursor ` | No | Continue from nextCursor returned by a previous result. | +| `--emails ` | Yes | Email addresses to invite. Each address is processed separately; inspect failed for unsuccessful recipients. (space-separated, or @path / @- with one value per line; @@value for a literal leading @). | +| `--permission ` | No | Workspace permission to grant. Existing workspace access is preserved. Defaults to "read". Accepted values: `admin`, `write`, `read`. | +| `--membership ` | No | Organization membership: member or admin uses a seat when billing is enabled. External grants workspace access only and requires an eligible paid account when billing is enabled. Existing members of another organization remain external. Defaults to "member". Accepted values: `member`, `admin`, `external`. | -## List my workspace access requests +API request and response schemas: [createWorkspaceInvitations](/api-reference/workspaces/createWorkspaceInvitations). -```bash -sim workspaces access-requests mine [options] -``` +### Get workspace permission config -List My Workspace Access Requests (OAuth login or personal API key required) +OAuth login or personal API key required. -**Options** +```bash +sim workspaces permission-config +``` - +API request and response schemas: [getWorkspacePermissionConfig](/api-reference/workspaces/getWorkspacePermissionConfig). -| Option | Required | Description | -| --- | --- | --- | -| `--status ` | No | Filter by request status; omit to include all statuses. Accepted values: `pending`, `fulfilled`, `declined`, `cancelled`, `closed`. | -| `--sort-by ` | No | Field used to sort the result. Accepted values: `createdAt`, `targetLabel`. | -| `--sort-order ` | No | Sort direction. Accepted values: `asc`, `desc`. | -| `--limit ` | No | Maximum items to return (0 for everything). Defaults to `100`. | -| `--cursor ` | No | Continue from nextCursor returned by a previous result. | +## Access requests - +### Discover workspace access requests -## Create workspace invitations +OAuth login or personal API key required. ```bash -sim workspaces invitations create [options] +sim workspaces access-requests discover [options] ``` -Create Workspace Invitations (OAuth login or personal API key required) - **Options** | Option | Required | Description | | --- | --- | --- | -| `--emails ` | Yes | Email addresses to invite. Each address is processed separately; inspect failed for unsuccessful recipients. (space-separated, or @path / @- with one value per line; @@value for a literal leading @). | -| `--permission ` | No | Workspace permission to grant. Existing workspace access is preserved. Accepted values: `admin`, `write`, `read`. | -| `--membership ` | No | Organization membership: member or admin uses a seat when billing is enabled. External grants workspace access only and requires an eligible paid account when billing is enabled. Existing members of another organization remain external. Accepted values: `member`, `admin`, `external`. | +| `--search ` | No | Case-insensitive substring match against the access item label. | +| `--target-kind ` | No | Category of access to discover. Accepted values: `feature`, `integration`, `provider`, `model`, `tool`, `knowledge_connector`, `file_share_auth`, `chat_deploy_auth`, `usage_limit`. | +| `--state ` | No | Filter by the acting user’s current access. Requestable items can be submitted for review. Accepted values: `allowed`, `requestable`, `unavailable`. | +| `--sort-by ` | No | Field used to sort the result. Defaults to "label". Accepted values: `label`. | +| `--sort-order ` | No | Sort direction. Defaults to "asc". Accepted values: `asc`, `desc`. | +| `--limit ` | No | Maximum items to return (0 for everything). Defaults to `100`. | +| `--cursor ` | No | Continue from nextCursor returned by a previous result. | -## Fork workspace +API request and response schemas: [discoverWorkspaceAccessRequests](/api-reference/access-requests/discoverWorkspaceAccessRequests). + +### Create workspace access request + +OAuth login or personal API key required. ```bash -sim workspaces fork [options] +sim workspaces access-requests create [options] ``` -Fork Workspace (OAuth login or personal API key required) - **Options** | Option | Required | Description | | --- | --- | --- | -| `--name ` | No | Display name of the workflow or workspace. | -| `--copy ` | No | Explicit resource selections to copy into the new fork; omitted resource kinds are not copied. (JSON, or @path / @- to read a file or stdin). | -| `--request-id ` | Yes | Stable client request ID for reconciliation and identical retries. | -| `--preview-fingerprint ` | Yes | Fingerprint of the reviewed preview and its choices. | -| `--wait` | No | Wait for the committed operation to finish; missing configuration and failure exit nonzero. | -| `--wait-timeout ` | No | Maximum operation wait in seconds (default 3600; 0 waits indefinitely). | +| `--target ` | Yes | Target returned by Discover Workspace Access Requests or Discover Organization Access Requests. The target must currently be requestable. (JSON, or @path / @- to read a file or stdin). | +| `--reason ` | No | Why the acting user needs this access. Defaults to "". | -## Get workspace +API request and response schemas: [createWorkspaceAccessRequest](/api-reference/access-requests/createWorkspaceAccessRequest). -```bash -sim workspaces get -``` +### List my workspace access requests -## Get workspace fork availability +OAuth login or personal API key required. ```bash -sim workspaces fork-availability -``` - -Get Workspace Fork Availability (OAuth login or personal API key required) - -## Get workspace fork lineage - -```bash -sim workspaces lineage -``` - -Get Workspace Fork Lineage (OAuth login or personal API key required) - -## Get workspace fork mappings - -```bash -sim workspaces mappings get [options] +sim workspaces access-requests mine [options] ``` -Get Workspace Fork Mappings (OAuth login or personal API key required) - **Options** | Option | Required | Description | | --- | --- | --- | -| `--other-workspace-id ` | Yes | Workspace on the other side of the direct fork edge. | -| `--direction ` | Yes | Push means current to other; pull means other to current, independent of parent/child orientation. Accepted values: `push`, `pull`. | +| `--status ` | No | Filter by request status; omit to include all statuses. Accepted values: `pending`, `fulfilled`, `declined`, `cancelled`, `closed`. | +| `--sort-by ` | No | Field used to sort the result. Defaults to "createdAt". Accepted values: `createdAt`, `targetLabel`. | +| `--sort-order ` | No | Sort direction. Defaults to "desc". Accepted values: `asc`, `desc`. | | `--limit ` | No | Maximum items to return (0 for everything). Defaults to `100`. | | `--cursor ` | No | Continue from nextCursor returned by a previous result. | -| `--sort-by ` | No | Supported stable sort key for this collection. Accepted values: `id`. | -| `--sort-order ` | No | Sort direction. Accepted values: `asc`. | -## Update workspace fork mappings +API request and response schemas: [listMyWorkspaceAccessRequests](/api-reference/access-requests/listMyWorkspaceAccessRequests). + +### Cancel workspace access request + +OAuth login or personal API key required. ```bash -sim workspaces mappings update [options] +sim workspaces access-requests cancel ``` -Update Workspace Fork Mappings (OAuth login or personal API key required) - -**Options** +**Arguments** -| Option | Required | Description | +| Argument | Required | Description | | --- | --- | --- | -| `--other-workspace-id ` | Yes | Workspace on the other side of the direct fork edge. | -| `--direction ` | Yes | Push means current to other; pull means other to current, independent of parent/child orientation. Accepted values: `push`, `pull`. | -| `--mappings ` | Yes | Mappings keyed by resource type and source identifier. (JSON, or @path / @- to read a file or stdin). | +| `requestId` | Yes | Access request identifier. | -## Get workspace operation +API request and response schemas: [cancelWorkspaceAccessRequest](/api-reference/access-requests/cancelWorkspaceAccessRequest). -```bash -sim workspaces operations get -``` +## Forks and lineage -**Arguments** +### Get workspace fork availability - +OAuth login or personal API key required. -| Argument | Required | Description | -| --- | --- | --- | -| `operationId` | Yes | Durable operation identifier to use for polling. | +```bash +sim workspaces fork-availability +``` - +API request and response schemas: [getWorkspaceForkAvailability](/api-reference/workspace-sync/getWorkspaceForkAvailability). -## List workspace operations +### List workspace fork resources + +OAuth login or personal API key required. ```bash -sim workspaces operations list [options] +sim workspaces fork-resources [options] ``` **Options** @@ -230,52 +212,78 @@ sim workspaces operations list [options] | --- | --- | --- | | `--limit ` | No | Maximum items to return (0 for everything). Defaults to `100`. | | `--cursor ` | No | Continue from nextCursor returned by a previous result. | -| `--request-id ` | No | Stable client request ID for reconciliation and identical retries. | +| `--kind ` | Yes | Kind of source resource to list for copy selection. Accepted values: `files`, `tables`, `knowledgeBases`, `customTools`, `skills`, `mcpServers`, `workflowMcpServers`. | +| `--sort-by ` | No | Supported stable sort key for this collection. Defaults to "id". Accepted values: `id`. | +| `--sort-order ` | No | Sort direction. Defaults to "asc". Accepted values: `asc`. | -## Wait for copy and deployment readiness; exit 3 for configuration, 1 for failure, or 4 for timeout +API request and response schemas: [listWorkspaceForkResources](/api-reference/workspace-sync/listWorkspaceForkResources). + +### Preview workspace fork + +OAuth login or personal API key required. ```bash -sim workspaces operations wait [options] +sim workspaces fork-preview [options] ``` -**Arguments** +**Options** -| Argument | Required | Description | +| Option | Required | Description | | --- | --- | --- | -| `operationId` | Yes | Operation ID returned by import, fork, push, or pull | +| `--name ` | No | Display name of the workflow or workspace. | +| `--copy ` | No | Explicit resource selections to copy into the new fork; omitted resource kinds are not copied. (JSON, or @path / @- to read a file or stdin). | +API request and response schemas: [previewWorkspaceFork](/api-reference/workspace-sync/previewWorkspaceFork). + +### Fork workspace + +OAuth login or personal API key required. + +```bash +sim workspaces fork [options] +``` + **Options** | Option | Required | Description | | --- | --- | --- | -| `--wait-timeout ` | No | Maximum total wait (default 3600; 0 waits indefinitely). | +| `--name ` | No | Display name of the workflow or workspace. | +| `--copy ` | No | Explicit resource selections to copy into the new fork; omitted resource kinds are not copied. (JSON, or @path / @- to read a file or stdin). | +| `--request-id ` | Yes | Stable client request ID. Reuse it with identical inputs after an uncertain response; changed inputs return 409. A new ID can apply another operation. | +| `--preview-fingerprint ` | Yes | Fingerprint returned by a preview with the same choices. A changed plan returns 409; preview again. The example hash is illustrative; use the actual preview value. | +| `--wait` | No | Wait for the committed operation to finish; missing configuration and failure exit nonzero. | +| `--wait-timeout ` | No | Maximum operation wait in seconds (default 3600; 0 waits indefinitely). | -## Get workspace permission config +API request and response schemas: [forkWorkspace](/api-reference/workspace-sync/forkWorkspace). + +### Get workspace fork lineage + +OAuth login or personal API key required. ```bash -sim workspaces permission-config +sim workspaces lineage ``` -Get Workspace Permission Config (OAuth login or personal API key required) +API request and response schemas: [getWorkspaceForkLineage](/api-reference/workspace-sync/getWorkspaceForkLineage). -## List workspace fork children +### List workspace fork children + +OAuth login or personal API key required. ```bash sim workspaces children [options] ``` -List Workspace Fork Children (OAuth login or personal API key required) - **Options** @@ -284,37 +292,46 @@ List Workspace Fork Children (OAuth login or personal API key required) | --- | --- | --- | | `--limit ` | No | Maximum items to return (0 for everything). Defaults to `100`. | | `--cursor ` | No | Continue from nextCursor returned by a previous result. | -| `--sort-by ` | No | Supported stable sort key for this collection. Accepted values: `createdAt`. | -| `--sort-order ` | No | Sort direction. Accepted values: `desc`. | +| `--sort-by ` | No | Supported stable sort key for this collection. Defaults to "createdAt". Accepted values: `createdAt`. | +| `--sort-order ` | No | Sort direction. Defaults to "desc". Accepted values: `desc`. | -## List workspace fork resources +API request and response schemas: [listWorkspaceForkChildren](/api-reference/workspace-sync/listWorkspaceForkChildren). + +## Mappings + +### Get workspace fork mappings + +OAuth login or personal API key required. ```bash -sim workspaces fork-resources [options] +sim workspaces mappings get [options] ``` -List Workspace Fork Resources (OAuth login or personal API key required) - **Options** | Option | Required | Description | | --- | --- | --- | +| `--other-workspace-id ` | Yes | Workspace on the other side of the direct fork edge. | +| `--direction ` | Yes | Push means current to other; pull means other to current, independent of parent/child orientation. Accepted values: `push`, `pull`. | | `--limit ` | No | Maximum items to return (0 for everything). Defaults to `100`. | | `--cursor ` | No | Continue from nextCursor returned by a previous result. | -| `--kind ` | Yes | Resource or operation kind. Accepted values: `files`, `tables`, `knowledgeBases`, `customTools`, `skills`, `mcpServers`, `workflowMcpServers`. | -| `--sort-by ` | No | Supported stable sort key for this collection. Accepted values: `id`. | -| `--sort-order ` | No | Sort direction. Accepted values: `asc`. | +| `--sort-by ` | No | Supported stable sort key for this collection. Defaults to "id". Accepted values: `id`. | +| `--sort-order ` | No | Sort direction. Defaults to "asc". Accepted values: `asc`. | -## List workspace members +API request and response schemas: [getWorkspaceForkMappings](/api-reference/workspace-sync/getWorkspaceForkMappings). + +### Update workspace fork mappings + +OAuth login or personal API key required. ```bash -sim workspaces members [options] +sim workspaces mappings update [options] ``` **Options** @@ -323,14 +340,22 @@ sim workspaces members [options] | Option | Required | Description | | --- | --- | --- | -| `--limit ` | No | Maximum items to return (0 for everything). Defaults to `0`. | +| `--other-workspace-id ` | Yes | Workspace on the other side of the direct fork edge. | +| `--direction ` | Yes | Push means current to other; pull means other to current, independent of parent/child orientation. Accepted values: `push`, `pull`. | +| `--mappings ` | Yes | Mapping entries addressed by resource type and `sourceId`. `targetId: null` clears a mapping. (JSON, or @path / @- to read a file or stdin). | -## List workspaces +API request and response schemas: [updateWorkspaceForkMappings](/api-reference/workspace-sync/updateWorkspaceForkMappings). + +## Push and pull + +### Preview workspace push + +OAuth login or personal API key required. ```bash -sim workspaces list [options] +sim workspaces push-preview [options] ``` **Options** @@ -339,39 +364,57 @@ sim workspaces list [options] | Option | Required | Description | | --- | --- | --- | -| `--sort-by ` | No | Field used to sort the result. Sorting by `name` is case-sensitive and follows the storage collation, so do not rely on a case-insensitive order. Accepted values: `name`, `createdAt`, `updatedAt`. | -| `--sort-order ` | No | Sort direction. Accepted values: `asc`, `desc`. | -| `--limit ` | No | Maximum items to return (0 for everything). Defaults to `0`. | +| `--other-workspace-id ` | Yes | Workspace on the other side of the direct fork edge. | +| `--mappings ` | No | Proposed mapping entries addressed by resource type and `sourceId`. Preview does not save them; apply commits them with the sync. (JSON, or @path / @- to read a file or stdin). | +| `--dependent-values ` | No | Destination-specific choices addressed by source workflow ID, source block ID, and field key. Omission keeps saved overrides; an explicit empty array clears them. (JSON, or @path / @- to read a file or stdin). | +| `--copy-resources ` | No | Explicit source resources to copy before syncing the workflows. (JSON, or @path / @- to read a file or stdin). | +| `--drop-references ` | No | Source-deleted references explicitly acknowledged for removal; live source references cannot be dropped. (JSON, or @path / @- to read a file or stdin). | +| `--trigger-mappings ` | No | Public trigger path choices from preview.triggerSlots, addressed by source workflow and block IDs. Duplicate or unavailable choices are rejected. (JSON, or @path / @- to read a file or stdin). | -## Preview workspace fork +API request and response schemas: [previewWorkspacePush](/api-reference/workspace-sync/previewWorkspacePush). + +### Push workspace + +OAuth login or personal API key required. + +This replaces target workflows and may archive targets whose sources were deleted. ```bash -sim workspaces fork-preview [options] +sim workspaces push [options] ``` -Preview Workspace Fork (OAuth login or personal API key required) - **Options** | Option | Required | Description | | --- | --- | --- | -| `--name ` | No | Display name of the workflow or workspace. | -| `--copy ` | No | Explicit resource selections to copy into the new fork; omitted resource kinds are not copied. (JSON, or @path / @- to read a file or stdin). | +| `--other-workspace-id ` | Yes | Workspace on the other side of the direct fork edge. | +| `--mappings ` | No | Proposed mapping entries addressed by resource type and `sourceId`. Preview does not save them; apply commits them with the sync. (JSON, or @path / @- to read a file or stdin). | +| `--dependent-values ` | No | Destination-specific choices addressed by source workflow ID, source block ID, and field key. Omission keeps saved overrides; an explicit empty array clears them. (JSON, or @path / @- to read a file or stdin). | +| `--copy-resources ` | No | Explicit source resources to copy before syncing the workflows. (JSON, or @path / @- to read a file or stdin). | +| `--drop-references ` | No | Source-deleted references explicitly acknowledged for removal; live source references cannot be dropped. (JSON, or @path / @- to read a file or stdin). | +| `--trigger-mappings ` | No | Public trigger path choices from preview.triggerSlots, addressed by source workflow and block IDs. Duplicate or unavailable choices are rejected. (JSON, or @path / @- to read a file or stdin). | +| `--request-id ` | Yes | Stable client request ID. Reuse it with identical inputs after an uncertain response; changed inputs return 409. A new ID can apply another operation. | +| `--preview-fingerprint ` | Yes | Fingerprint returned by a preview with the same choices. A changed plan returns 409; preview again. The example hash is illustrative; use the actual preview value. | +| `--wait` | No | Wait for the committed operation to finish; missing configuration and failure exit nonzero. | +| `--wait-timeout ` | No | Maximum operation wait in seconds (default 3600; 0 waits indefinitely). | +| `-y, --yes` | Yes | Confirm this operation. | -## Preview workspace pull +API request and response schemas: [pushWorkspace](/api-reference/workspace-sync/pushWorkspace). + +### Preview workspace pull + +OAuth login or personal API key required. ```bash sim workspaces pull-preview [options] ``` -Preview Workspace Pull (OAuth login or personal API key required) - **Options** @@ -379,22 +422,26 @@ Preview Workspace Pull (OAuth login or personal API key required) | Option | Required | Description | | --- | --- | --- | | `--other-workspace-id ` | Yes | Workspace on the other side of the direct fork edge. | -| `--mappings ` | No | Mappings keyed by resource type and source identifier. (JSON, or @path / @- to read a file or stdin). | -| `--dependent-values ` | No | Destination-dependent choices keyed by source workflow, block, and field identities. (JSON, or @path / @- to read a file or stdin). | +| `--mappings ` | No | Proposed mapping entries addressed by resource type and `sourceId`. Preview does not save them; apply commits them with the sync. (JSON, or @path / @- to read a file or stdin). | +| `--dependent-values ` | No | Destination-specific choices addressed by source workflow ID, source block ID, and field key. Omission keeps saved overrides; an explicit empty array clears them. (JSON, or @path / @- to read a file or stdin). | | `--copy-resources ` | No | Explicit source resources to copy before syncing the workflows. (JSON, or @path / @- to read a file or stdin). | | `--drop-references ` | No | Source-deleted references explicitly acknowledged for removal; live source references cannot be dropped. (JSON, or @path / @- to read a file or stdin). | | `--trigger-mappings ` | No | Public trigger path choices from preview.triggerSlots, addressed by source workflow and block IDs. Duplicate or unavailable choices are rejected. (JSON, or @path / @- to read a file or stdin). | -## Preview workspace push +API request and response schemas: [previewWorkspacePull](/api-reference/workspace-sync/previewWorkspacePull). + +### Pull workspace + +OAuth login or personal API key required. + +This replaces target workflows and may archive targets whose sources were deleted. ```bash -sim workspaces push-preview [options] +sim workspaces pull [options] ``` -Preview Workspace Push (OAuth login or personal API key required) - **Options** @@ -402,49 +449,76 @@ Preview Workspace Push (OAuth login or personal API key required) | Option | Required | Description | | --- | --- | --- | | `--other-workspace-id ` | Yes | Workspace on the other side of the direct fork edge. | -| `--mappings ` | No | Mappings keyed by resource type and source identifier. (JSON, or @path / @- to read a file or stdin). | -| `--dependent-values ` | No | Destination-dependent choices keyed by source workflow, block, and field identities. (JSON, or @path / @- to read a file or stdin). | +| `--mappings ` | No | Proposed mapping entries addressed by resource type and `sourceId`. Preview does not save them; apply commits them with the sync. (JSON, or @path / @- to read a file or stdin). | +| `--dependent-values ` | No | Destination-specific choices addressed by source workflow ID, source block ID, and field key. Omission keeps saved overrides; an explicit empty array clears them. (JSON, or @path / @- to read a file or stdin). | | `--copy-resources ` | No | Explicit source resources to copy before syncing the workflows. (JSON, or @path / @- to read a file or stdin). | | `--drop-references ` | No | Source-deleted references explicitly acknowledged for removal; live source references cannot be dropped. (JSON, or @path / @- to read a file or stdin). | | `--trigger-mappings ` | No | Public trigger path choices from preview.triggerSlots, addressed by source workflow and block IDs. Duplicate or unavailable choices are rejected. (JSON, or @path / @- to read a file or stdin). | +| `--request-id ` | Yes | Stable client request ID. Reuse it with identical inputs after an uncertain response; changed inputs return 409. A new ID can apply another operation. | +| `--preview-fingerprint ` | Yes | Fingerprint returned by a preview with the same choices. A changed plan returns 409; preview again. The example hash is illustrative; use the actual preview value. | +| `--wait` | No | Wait for the committed operation to finish; missing configuration and failure exit nonzero. | +| `--wait-timeout ` | No | Maximum operation wait in seconds (default 3600; 0 waits indefinitely). | +| `-y, --yes` | Yes | Confirm this operation. | -## Pull workspace +API request and response schemas: [pullWorkspace](/api-reference/workspace-sync/pullWorkspace). + +## Operation status + +### List workspace operations ```bash -sim workspaces pull [options] +sim workspaces operations list [options] ``` -Pull Workspace (OAuth login or personal API key required) - **Options** | Option | Required | Description | | --- | --- | --- | -| `--other-workspace-id ` | Yes | Workspace on the other side of the direct fork edge. | -| `--mappings ` | No | Mappings keyed by resource type and source identifier. (JSON, or @path / @- to read a file or stdin). | -| `--dependent-values ` | No | Destination-dependent choices keyed by source workflow, block, and field identities. (JSON, or @path / @- to read a file or stdin). | -| `--copy-resources ` | No | Explicit source resources to copy before syncing the workflows. (JSON, or @path / @- to read a file or stdin). | -| `--drop-references ` | No | Source-deleted references explicitly acknowledged for removal; live source references cannot be dropped. (JSON, or @path / @- to read a file or stdin). | -| `--trigger-mappings ` | No | Public trigger path choices from preview.triggerSlots, addressed by source workflow and block IDs. Duplicate or unavailable choices are rejected. (JSON, or @path / @- to read a file or stdin). | -| `--request-id ` | Yes | Stable client request ID for reconciliation and identical retries. | -| `--preview-fingerprint ` | Yes | Fingerprint of the reviewed preview and its choices. | -| `--wait` | No | Wait for the committed operation to finish; missing configuration and failure exit nonzero. | -| `--wait-timeout ` | No | Maximum operation wait in seconds (default 3600; 0 waits indefinitely). | -| `-y, --yes` | Yes | Confirm this operation. | +| `--limit ` | No | Maximum items to return (0 for everything). Defaults to `100`. | +| `--cursor ` | No | Continue from nextCursor returned by a previous result. | +| `--request-id ` | No | Find an uncertain mutation by the original client request ID; keep the same filter while paging. | -## Push workspace +API request and response schemas: [listWorkspaceOperations](/api-reference/workspace-sync/listWorkspaceOperations). + +### Get workspace operation ```bash -sim workspaces push [options] +sim workspaces operations get +``` + +**Arguments** + + + +| Argument | Required | Description | +| --- | --- | --- | +| `operationId` | Yes | Durable operation identifier to use for polling. | + + + +API request and response schemas: [getWorkspaceOperation](/api-reference/workspace-sync/getWorkspaceOperation). + +### Wait for workspace copy and deployment readiness [#wait-for-copy-and-deployment-readiness-exit-3-for-configuration-1-for-failure-or-4-for-timeout] + +```bash +sim workspaces operations wait [options] ``` -Push Workspace (OAuth login or personal API key required) +**Arguments** + + + +| Argument | Required | Description | +| --- | --- | --- | +| `operationId` | Yes | Operation ID returned by import, fork, push, or pull | + + **Options** @@ -452,47 +526,47 @@ Push Workspace (OAuth login or personal API key required) | Option | Required | Description | | --- | --- | --- | -| `--other-workspace-id ` | Yes | Workspace on the other side of the direct fork edge. | -| `--mappings ` | No | Mappings keyed by resource type and source identifier. (JSON, or @path / @- to read a file or stdin). | -| `--dependent-values ` | No | Destination-dependent choices keyed by source workflow, block, and field identities. (JSON, or @path / @- to read a file or stdin). | -| `--copy-resources ` | No | Explicit source resources to copy before syncing the workflows. (JSON, or @path / @- to read a file or stdin). | -| `--drop-references ` | No | Source-deleted references explicitly acknowledged for removal; live source references cannot be dropped. (JSON, or @path / @- to read a file or stdin). | -| `--trigger-mappings ` | No | Public trigger path choices from preview.triggerSlots, addressed by source workflow and block IDs. Duplicate or unavailable choices are rejected. (JSON, or @path / @- to read a file or stdin). | -| `--request-id ` | Yes | Stable client request ID for reconciliation and identical retries. | -| `--preview-fingerprint ` | Yes | Fingerprint of the reviewed preview and its choices. | -| `--wait` | No | Wait for the committed operation to finish; missing configuration and failure exit nonzero. | -| `--wait-timeout ` | No | Maximum operation wait in seconds (default 3600; 0 waits indefinitely). | -| `-y, --yes` | Yes | Confirm this operation. | +| `--wait-timeout ` | No | Maximum total wait (default 3600; 0 waits indefinitely). | -## Rollback workspace fork +Exit codes: 0 completed (including completion with warnings), 1 follow-up work failed, 3 destination configuration is required, 4 timed out. The mutation may already be committed; reconcile using the same operation or request ID rather than repeating it with a new ID. + +API request and response schemas: [getWorkspaceOperation](/api-reference/workspace-sync/getWorkspaceOperation). + +## Exclusions and recovery + +### Update workspace fork exclusions + +OAuth login or personal API key required. ```bash -sim workspaces fork-rollback [options] +sim workspaces sync-exclusions [options] ``` -Rollback Workspace Fork (OAuth login or personal API key required) - **Options** | Option | Required | Description | | --- | --- | --- | -| `--other-workspace-id ` | Yes | Workspace on the other side of the direct fork edge. | -| `-y, --yes` | Yes | Confirm this operation. | +| `--workflow ` | Yes | Workflow identifiers in the current workspace. (space-separated, or @path / @- with one value per line; @@value for a literal leading @). | +| `--fork-sync-excluded ` | Yes | Whether the named workflows should be skipped as sync sources and targets. Accepted values: `true`, `false`. | -## Unlink workspace fork +API request and response schemas: [updateWorkspaceForkExclusions](/api-reference/workspace-sync/updateWorkspaceForkExclusions). + +### Rollback workspace fork + +OAuth login or personal API key required. + +This restores the latest sync using its prior deployed versions. ```bash -sim workspaces unlink [options] +sim workspaces fork-rollback [options] ``` -Unlink Workspace Fork (OAuth login or personal API key required) - **Options** @@ -504,21 +578,32 @@ Unlink Workspace Fork (OAuth login or personal API key required) -## Update workspace fork exclusions +API request and response schemas: [rollbackWorkspaceFork](/api-reference/workspace-sync/rollbackWorkspaceFork). + +### Unlink workspace fork + +OAuth login or personal API key required. + +This removes the fork relationship and its persisted mappings. ```bash -sim workspaces sync-exclusions [options] +sim workspaces unlink [options] ``` -Update Workspace Fork Exclusions (OAuth login or personal API key required) - **Options** | Option | Required | Description | | --- | --- | --- | -| `--workflow ` | Yes | Workflow identifiers in the current workspace. (space-separated, or @path / @- with one value per line; @@value for a literal leading @). | -| `--fork-sync-excluded ` | Yes | Whether the named workflows should be skipped as sync sources and targets. Accepted values: `true`, `false`. | +| `--other-workspace-id ` | Yes | Workspace on the other side of the direct fork edge. | +| `-y, --yes` | Yes | Confirm this operation. | + +API request and response schemas: [unlinkWorkspaceFork](/api-reference/workspace-sync/unlinkWorkspaceFork). + +## Related docs + +- [Workspace sync](/cli/workflow-sync) +- [Workspaces](/platform/workspaces) diff --git a/apps/docs/content/docs/desktop/index.mdx b/apps/docs/content/docs/desktop/index.mdx index 134bc8574ce..58f48c67fa4 100644 --- a/apps/docs/content/docs/desktop/index.mdx +++ b/apps/docs/content/docs/desktop/index.mdx @@ -1,155 +1,187 @@ --- title: Sim Desktop -description: Install the macOS app — Sim in its own window, with a built-in browser, a terminal, and access to local folders. +description: Install the macOS app and configure browser, terminal, local file, and available Mac app controls. --- import { Callout } from 'fumadocs-ui/components/callout' import { Step, Steps } from 'fumadocs-ui/components/steps' import { Image } from '@/components/ui/image' -Sim Desktop is the macOS app for your Sim workspace. Everything the web app does, it does — plus the things a browser tab cannot: a built-in browser and terminal, read-only access to folders you pick, and native notifications when a task finishes. +Sim Desktop opens your Sim workspace in a macOS app. It adds a built-in browser, terminal sessions, local file tools, and native notifications. Available builds and deployments can also provide native Mac app control. Your account, workspaces, and workflows are shared with the web app. Sim Desktop — Chat on the left, the built-in browser on the right -## Download +## Download and requirements **[Download Sim Desktop for macOS](https://www.sim.ai/api/desktop/update/download)** -One universal build runs natively on both Apple Silicon and Intel Macs. It is signed and notarized by Sim, so Gatekeeper accepts it with no override. +The official build is signed and notarized. One universal installer supports Apple Silicon and Intel Macs running **macOS 12 Monterey or later**. Use the web app on other platforms. - - That link is never version-pinned — it is a redirect resolved at request time, so it always lands on the newest release. Bookmark it, share it, or put it in an MDM policy; it stays correct. +The download link redirects to the latest available desktop installer for that deployment. Results can be cached for five minutes. To install a specific version, download `Sim--universal.dmg` from [GitHub releases](https://github.com/simstudioai/sim/releases). - It resolves against sim.ai. Every deployment serves the same endpoint on its own origin, so if you self-host use yours — `https://sim.example.com/api/desktop/update/download` — to get the build your deployment offers. - +You need outbound access to your Sim deployment and GitHub's release downloads. For a self-hosted deployment: -To install a specific version instead of the newest one, pick it from [the releases page](https://github.com/simstudioai/sim/releases) and download that release's `Sim--universal.dmg`. +- Use your own download endpoint, such as `https://sim.example.com/api/desktop/update/download`. +- Allow the Sim server to reach both `api.github.com` and `github.com` for release lookup and manifests. Blocking either can make the download endpoint return `502`. +- Use a certificate trusted by macOS. The app rejects certificate errors without an override; install a private CA in the system trust store if required. -## Install +See [Desktop app on your deployment](/platform/self-hosting/desktop) for server URLs, update channels, and network troubleshooting. - +## Install and sign in - + + -### Open the disk image and drag Sim to Applications +Open the disk image and drag Sim to **Applications**. Launch it from there. - Install to `/Applications`. macOS App Translocation runs an app from a randomized read-only path when it is launched from Downloads, which silently breaks auto-updates. + Automatic self-update requires a Developer ID build installed in Applications. Builds elsewhere use the manual installer update path. + - +Fresh official installs open sim.ai. If you self-host, choose **Sim → Server…** in the menu bar and enter your deployment's origin before signing in. -### Sign in + + -Launch Sim and sign in as you normally would. +Sign in with your existing Sim account. Google, Microsoft, and SSO sign-ins finish in your default browser, which hands the session back to the app. -Google, Microsoft, and SSO sign-ins finish in your default browser — those providers refuse to render inside an embedded browser. Sim opens the page, you approve, and the browser hands the session back to the app. The app gets its own session, so signing out of one surface does not sign out the other. +The app has its own session. Signing out of the app does not sign you out of Sim in your browser, or the reverse. + - - -### Point it at your deployment, if you self-host - -Fresh installs open sim.ai. To use your own deployment, choose **Sim → Server…** in the menu bar and enter its URL. See [Desktop App on Your Deployment](/platform/self-hosting/desktop) for what changes when you switch. +## Browser, terminal, and local files - +| Capability | Behavior | +| --- | --- | +| **Browser** | Open websites in tabs with their own sessions and saved passwords. Chat can use the sites you sign into here. | +| **Terminal** | Open local shell sessions beside Chat. Chat can run commands in those sessions; tmux and shell integration are supported. | +| **Local file tools** | Read and search folders you approve, import files, and use authorized files in browser uploads. | +| **Notifications** | Receive a notification when Chat finishes responding. Clicking it opens that chat. Errors and turns with queued follow-up messages do not produce completion notifications. | +| **Control Center** | Open recent chats from Sim's menu-bar icon. | +| **Launch at login** | Optionally open Sim when you sign in to your Mac. The app restores its previous location when launched. | - +Browser and Terminal are enabled by default. Turn them off with **Let Chat browse the web** or **Let Chat run commands** in their Settings sections. -## What the desktop app adds +### Local file access -- **A built-in browser.** A real browser inside the app, with its own tabs, saved passwords, and sessions. Chat can drive it — sign in once and your agents work on the sites you are already signed into. -- **A built-in terminal.** Real shell sessions in a panel next to Chat, with tmux and shell integration, that Chat can run commands in. -- **Local folder access.** When a task needs a folder on your Mac, Chat offers to open the native folder picker. The grant is read-only, scoped to the folder you picked, and revocable. -- **Notifications.** A native notification when a Chat task finishes. Clicking it opens that chat. Tasks that end in an error, or that have another message queued behind them, do not notify. -- **Control Center.** A menu-bar icon with your recent chats, so Sim is one click away from any app. -- **Launch at login.** Sim starts with your Mac, and however you launch it, it opens where you left off. +By default, local file tools ask for folder access when they need an unapproved path. A selected-folder grant is scoped to that folder, read-only through the filesystem tool interface, and revocable. Use **File → Folder Access…** to manage selected folders. -Both the browser and the terminal are capabilities you grant, not defaults you are stuck with — each has a single switch in settings that turns it off entirely. +**Settings → Account → Desktop → Full file access** is off by default. Enabling it lets local file tools access files without individual folder approvals. - **What a folder grant does and does not do.** Granting a folder does not copy or upload it, and an agent cannot attach or stage a file from it — that stays your deliberate act. But when an agent reads or searches inside the grant, what it reads is a tool result, and tool results go to your Sim server and to the model like anything else in the conversation. The file stays on your Mac; what an agent reads out of it does not. + Granting a folder does not automatically upload its contents. Later reads send returned content to your Sim deployment and model. Chat can also import authorized local files or stage a granted file for upload to a website through the browser. -## Keyboard shortcuts +### Native Mac-app control -These are the app's own shortcuts. The [workflow editor and table shortcuts](/keyboard-shortcuts) work the same in the app as in the browser. +**Computer Use** appears under **Settings → Account → Desktop** only when the deployment and installed app provide it. It requires **macOS 14 or later** and is off by default on each Mac. Browser, Terminal, and local file permissions are separate controls. -| Shortcut | Action | -|---|---| -| `Cmd` + `K` | Search | -| `Cmd` + `B` | Toggle the sidebar | -| `Cmd` + `N` | New chat | -| `Cmd` + `Shift` + `N` | New window | -| `Cmd` + `,` | Settings | -| `Cmd` + `[` | Back | -| `Cmd` + `R` | Reload | -| `Cmd` + `0` / `+` / `-` | Reset, increase, or decrease zoom | +To enable it when available: -With the built-in browser or terminal focused, the tab shortcuts act on its tabs rather than on the window: +1. Open **Computer Use** and turn **Allow Mothership to use Mac apps** to **On** to allow Sim to use native apps. +2. Use **Open System Settings** to grant **Accessibility** for app interaction and **Screen Recording** for screenshots. Grant these permissions yourself, then return to Sim to refresh their status. +3. When Sim requests an app, choose **Allow for This Task**, **Always Allow**, or **Cancel**. **Always Allow** saves that app's permission on this Mac. -| Shortcut | Action | -|---|---| -| `Cmd` + `T` | New tab | -| `Cmd` + `W` | Close tab | -| `Cmd` + `Shift` + `T` | Reopen the last closed tab | -| `Ctrl` + `Tab` / `Ctrl` + `Shift` + `Tab` | Next / previous tab | -| `Cmd` + `1`–`8` | Jump to that tab | -| `Cmd` + `9` | Jump to the last tab | -| `Cmd` + `L` | Focus the address bar (browser only) | -| `Cmd` + `F` | Find on the page (browser only) | +Sim can read approved app windows and interact through clicks, text, keyboard shortcuts, scrolling, and supported accessibility controls. Screenshots and returned app content can be sent to your Sim deployment and model. Some actions require bringing the app to the foreground; app compatibility and macOS permissions can still limit what succeeds. + +The conversation shows the active app and action. Select **Stop**, or press **Cmd + Shift + Escape** when that shortcut is available, to cancel active and queued computer actions. Stopping cannot undo input already delivered to an app. Verify the app's current state before repeating an interrupted action. + +Use **Revoke** under **Approved apps** to remove a saved permission, or switch Computer Use off. Signing out or changing deployments clears the device opt-in and app approvals. Computer Use cannot operate Sim's own permission controls or macOS System Settings. + +### Terminal access + +Terminal commands run with your macOS account's permissions. They can modify files outside selected-folder grants; those grants do not confine the shell. Disable **Settings → Account → Terminal → Let Chat run commands** to remove this capability. + +Command confirmation depends on Chat's tool-permission settings and whether the run is interactive. With approvals enabled, command runs can wait for approval unless the tool is auto-allowed. Noninteractive runs do not wait for a per-command decision. ## Settings -The desktop app adds three sections under **Settings → Account**. They appear only when you are running the app, and they apply to this Mac rather than to your account. +Desktop settings appear under **Settings → Account** when the app exposes the corresponding capability. They apply to this Mac. ### Desktop -- **Launch Sim at login** -- **Show Sim in Control Center** — the menu-bar icon -- **Automatically download updates** -- **Enable desktop notifications**, with **Play notification sounds** and **Notify only when Sim isn't focused** +| Setting | Behavior | +| --- | --- | +| **Launch Sim at login** | Start Sim when you sign in to macOS. Off by default. | +| **Prevent sleep while a chat is running** | Keep the Mac awake during Chat activity. On by default. | +| **Show Sim in Control Center** | Show Sim's menu-bar icon and recent chats. | +| **Automatically download updates** | Download available updates in the background. | +| **Full file access** | Allow local file tools to access files without individual folder approvals. Off by default. | +| **Enable desktop notifications** | Enable completion notifications. | +| **Play notification sounds** | Play a sound with notifications. | +| **Notify only when Sim isn't focused** | Suppress completion notifications while you are working in Sim. | -It also shows the installed version, and the version waiting to be applied when an update is ready. +This section also shows the installed version and a downloaded version waiting for restart. ### Browser -- **Let Chat browse the web** — the master switch for the built-in browser -- **Search suggestions**, **Theme**, **Default zoom**, and **Download location** -- **Browsing data** — clear cookies, site data, and cached images and files +| Setting or action | Behavior | +| --- | --- | +| **Let Chat browse the web** | Enable or disable the built-in browser. | +| **Search suggestions** | Send address-bar typing to Google for live completions. | +| **Theme**, **Default zoom** | Set the browser's appearance and page zoom. | +| **Download location** | Choose where browser downloads are saved. | +| **Passwords** | Manage saved browser passwords. | +| **Browsing data** | Clear cookies, site data, and cached images and files. | ### Terminal -- **Let Chat run commands** — the master switch for the built-in terminal -- **Theme** and **Default zoom** +Use **Let Chat run commands** to enable or disable Terminal. **Theme** and **Default zoom** control its appearance. -The menu bar carries the rest: **Sim → Settings…** (`Cmd` + `,`), **Server…** to change deployments, **Check for Updates…**, and **Sign Out**. +The **Sim** menu also contains **Settings…**, **Server…**, **Check for Updates…**, and **Sign Out**. -## Updates +## Keyboard shortcuts + +The [workflow and table shortcuts](/keyboard-shortcuts) also work in Desktop. Focus determines whether a shortcut acts on Sim, the browser, or Terminal. + +| Shortcut | Action | +| --- | --- | +| `Cmd` + `K` | Open search | +| `Cmd` + `B` | Toggle the sidebar | +| `Cmd` + `N` | New chat | +| `Cmd` + `Shift` + `N` | New window | +| `Cmd` + `,` | Settings | +| `Cmd` + `[` / `]` | Back / forward in Sim or the focused browser | +| `Cmd` + `R` | Reload Sim or the focused browser; clear the focused terminal's screen | +| `Cmd` + `0` / `+` / `-` | Reset / increase / decrease zoom in the focused surface | -Sim checks the deployment it is pointed at rather than a global feed. How it applies what it finds depends on how the app was installed. Nothing is ever forced mid-session either way. +When Browser or Terminal is focused: -**Installed in `/Applications`, signed by Sim** — what the download link above gives you. The app replaces itself. With **Automatically download updates** on, it downloads in the background and offers to restart; choose **Later** and the update applies the next time you quit. With it off, nothing downloads until you ask: **Sim → Check for Updates…** reports the available version and waits for you to choose **Download**. +| Shortcut | Action | +| --- | --- | +| `Cmd` + `T` | New tab | +| `Cmd` + `W` | Close the focused tab | +| `Cmd` + `Shift` + `T` | Reopen the last closed tab | +| `Ctrl` + `Tab` / `Ctrl` + `Shift` + `Tab` | Next / previous tab | +| `Cmd` + `1`–`8` | Jump to that tab | +| `Cmd` + `9` | Jump to the last tab | +| `Cmd` + `L` | Focus the browser address bar | +| `Cmd` + `F` | Find on the browser page | -**Anywhere else** — outside `/Applications`, or a build not signed with a Developer ID. The app cannot replace itself, so it offers you the installer to download and swap in by hand. +The last two shortcuts apply to Browser. With Sim focused, `Cmd` + `L` opens Logs. -Updates come from the deployment you are connected to, so a self-hosted install controls which build its own users are offered. That control depends on the feed staying reachable: if it is not, a self-updating stable build falls back to Sim's public GitHub releases rather than stalling. See [Desktop App on Your Deployment](/platform/self-hosting/desktop). +## Updates -## Requirements +The app checks the deployment it is connected to for updates. It does not force a restart during your session. -- **macOS 12 Monterey or later**, on Apple Silicon or Intel. -- **Outbound access to your Sim deployment**, and to `github.com`, which is where installers and updates are downloaded from. -- **If you self-host**, your Sim server needs its own outbound access to both `api.github.com`, which is what resolves *which* release to offer, and `github.com`. An allowlist carrying only `github.com` leaves the download endpoint answering `502`. -- **A system-trusted TLS certificate**, if you self-host. The app rejects certificate errors outright and offers no override, so a private CA must be installed in the macOS keychain. +| Installation | Update behavior | +| --- | --- | +| Developer ID build in **Applications** | The app can replace itself. With **Automatically download updates** on, it downloads in the background and offers to restart. Choose **Later** to apply the downloaded update when you next quit. With the setting off, **Sim → Check for Updates…** offers a version and waits for **Download**. | +| Build outside **Applications**, or without Developer ID signing | The app offers an installer for you to download and install manually. | - - The desktop app is macOS-only today. The web app works in any browser on any platform, and your account, workspaces, and workflows are the same either way. - +If the deployment's update feed is unavailable, an eligible stable build falls back to Sim's public GitHub releases. Prerelease builds skip the check instead. See [Desktop app on your deployment](/platform/self-hosting/desktop#what-an-installed-app-does-when-the-feed-fails) for feed failures and release selection. + +## Related docs + +- [Desktop app on your deployment](/platform/self-hosting/desktop) +- [Chat](/chat) +- [Keyboard shortcuts](/keyboard-shortcuts) diff --git a/apps/docs/content/docs/files/editor.mdx b/apps/docs/content/docs/files/editor.mdx index b40166a2c80..1dbb06ff48f 100644 --- a/apps/docs/content/docs/files/editor.mdx +++ b/apps/docs/content/docs/files/editor.mdx @@ -1,55 +1,61 @@ --- title: Editor -description: A rich markdown editor for your files — type markdown and watch it render, or edit visually. +description: Format Markdown documents, edit their source, and download them from Files. --- -import { Image } from '@/components/ui/image' -import { Card, Cards } from 'fumadocs-ui/components/card' -import { Callout } from 'fumadocs-ui/components/callout' - -Every markdown file in your workspace opens in a **rich editor**. Type markdown and it renders as you go, or format visually with the toolbar and slash menu. The file is saved as plain markdown. - -
- A markdown file rendered in the editor: headings, bold, italic, and a link, a nested bullet list, and a table -
+Open a Markdown file in **Files** to read or edit it. Select **New file** to create a document. Rich editing requires edit access and supported document size and syntax; files remain stored as Markdown. ## Formatting text -Select any text to bring up the formatting toolbar — bold, italic, strikethrough, inline code, and links. The same marks appear instantly as you type the markdown for them, like `**bold**` or `*italic*`. Links show a hover card so you can open, copy, edit, or remove them without hunting through the source. +Select text to open the formatting toolbar for bold, italic, strikethrough, inline code, and links. You can also type Markdown, such as `**bold**` and `*italic*`. A link's hover card lets you open, copy, edit, or remove it. -## Structure +| Action | Shortcut or Markdown | +| --- | --- | +| Bold | **Cmd/Ctrl + B** | +| Italic | **Cmd/Ctrl + I** | +| Link selected text | **Cmd/Ctrl + K** | +| Heading | `# ` through `###### ` | +| Blockquote | `> ` | +| Divider | `---` | -Headings, blockquotes, and dividers keep long documents scannable. Type `# ` through `###### ` for headings, `> ` for a quote, and `---` for a divider. +Bullet, numbered, and nested lists are supported. Task lists have checkboxes you can tick in the document when editing is allowed. -## Lists and checklists +## Insert blocks [#slash-menu-and-shortcuts] -Bullet, ordered, and nested lists all work, plus task lists you can tick right in the document. +Type `/` at the start of a block or after whitespace to open the insertion menu. Choose a heading, list, table, code block, image, or another available block. The menu does not open inside tables, code blocks, inline code, or links. ## Tables -Insert a table from the slash menu, then click any cell for the floating table toolbar — add or remove rows and columns, toggle the header row, or delete the table. Drag a column border to resize it. +Insert a table from the slash menu. Select a cell to open the table toolbar, then add or remove rows and columns, or delete the table. The header row stays in place; you can edit its text. Column resizing and merged cells are not supported. ## Code blocks -Fenced code blocks are syntax-highlighted, with a language picker in the corner. Pick `mermaid` to render a live diagram instead of code. +Fenced code blocks have syntax highlighting and a language picker. Choose `mermaid` to render a diagram. Select **Show source** when you need to edit its definition. ## Images -Paste or drag an image straight into the document, then drag a corner to resize it. +Paste or drag an image into the document, or insert one from the slash menu. Drag a corner to resize it. Uploaded images are stored as files and referenced from the Markdown document. -## Slash menu and shortcuts +## Markdown fidelity -Type `/` anywhere to insert any block — heading, list, table, code block, image, and more — without leaving the keyboard. Familiar shortcuts work too: **Cmd/Ctrl + B** for bold, **Cmd/Ctrl + I** for italic, and **Cmd/Ctrl + K** to add a link over selected text. +Rich editing can normalize Markdown syntax, such as changing `_italic_` to `*italic*` or a setext heading to a `#` heading. It does not promise byte-for-byte preservation of the entire document. -## Markdown fidelity +YAML frontmatter is kept separately and restored when the document is saved. Footnotes, HTML comments, and raw HTML constructs retain their source text. Preserving that source does not mean every HTML construct renders as a visual editing control. + +If a document cannot safely round-trip through rich editing, it opens with a read-only rich preview and an **Edit source** action for members with edit access. Examples include hard line breaks inside headings, non-canonical HTML entities such as `©`, and some reference or image constructs. + +Rich editing supports up to 262,144 characters. **Edit source** can open text files up to 50 MiB, but saving sends the entire content in a JSON request capped at 10 MiB, including encoding and escaping. Download or process files elsewhere when these limits prevent editing. + +A file may also be temporarily read-only while Sim is writing it or the collaborative editor is connecting. + +## Download a document + +Select **Download** in the viewer. For an open Markdown document, the download can use the visible snapshot without saving it or advancing the collaborative file. Downloading a snapshot is separate from saving changes to the workspace. -The editor round-trips your markdown exactly — it saves what you wrote, with no reformatting churn. +When a Markdown export includes eligible stored images, Sim downloads a ZIP containing the document and an `assets/` folder, with image references rewritten to those assets. An export without bundled assets is a Markdown file. Missing or oversized assets can retain their original links, so check the exported document before sharing it elsewhere. - -A few constructs still can't round-trip: a `
` inside a table cell, a hard line break inside a heading, and non-canonical HTML entities such as `©`. Files over 256 KB also open read-only. Footnotes, HTML comments, and raw HTML are preserved byte-for-byte and stay editable. -
+## Related docs - - - - +- [Files](/files) +- [Using files in workflows](/files/using-in-workflows) +- [Generating files](/files/generating) diff --git a/apps/docs/content/docs/files/generating.mdx b/apps/docs/content/docs/files/generating.mdx index 7ad2759531d..af204fa6122 100644 --- a/apps/docs/content/docs/files/generating.mdx +++ b/apps/docs/content/docs/files/generating.mdx @@ -1,66 +1,76 @@ --- title: Generating files -description: How a workflow produces a document, report, or media file and saves it to the workspace Files store. +description: Save text or file objects produced by a workflow to workspace Files. --- -import { Callout } from 'fumadocs-ui/components/callout' -import { Card, Cards } from 'fumadocs-ui/components/card' +A workflow can produce text, such as a summary or CSV, or a file object, such as an image or audio clip. Save the result to workspace **Files** when it needs a stable workspace identity for later runs, editing, or sharing. -A generated file is an artifact a workflow run creates: a report, a CSV, a rendered audio clip. It starts as a value a block produces and becomes a workspace file when a [File](/integrations/file) block writes it to the [Files](/files) store. Once saved, it has a name, a size, and a URL, and any later run can read it back. +A file returned by a block can belong only to the execution. Returning it and saving it to Files are separate actions. +## Save text with Write [#saving-content-with-the-file-block] -{/* VISUAL: flow diagram: [Agent/Function block produces content] → [File block, Write] → [Files panel, file visible] */} +To save an Agent's summary as Markdown: -## What produces file content +1. Connect the Agent to a [File](/integrations/file) block. +2. Select **Write**. +3. Set **File Name** to `research_summary.md`. +4. Set **Content** to `` and leave **File** empty. +5. Choose a destination folder if needed, then run the workflow. -Most generated files start as the output of an earlier block. Two patterns are common. +The saved file appears in workspace **Files**. Write returns: -A block returns **text content** you want to keep. An [Agent](/workflows/blocks/agent) writes an analysis or summary; a [Function](/workflows/blocks/function) builds a CSV or formats a report. That text is part of the block's output, read by reference as `` or ``. To make it a file, you pass that value into a File block set to Write. +| Field | Meaning | +| --- | --- | +| `id` | Canonical workspace file ID | +| `name` | Saved name, including any suffix added to avoid a duplicate | +| `size` | Stored file size in bytes | +| `url` | File access URL; it does not grant public access | +| `version` | Content version recorded by the write | +| `revision` | Opaque token identifying the written content | -A block returns a **file object** directly. ElevenLabs text-to-speech returns an `audioFile`; an image generator returns a generated image; the File block's own Read operation returns parsed files. These are already [UserFile](/files/passing-files) objects (an object with `id`, `name`, `url`, `size`, and `type`), so they appear in the output panel as files with no Write step. You can hand one to a downstream block, or write its content to the Files store to persist it. +The content type is inferred from the extension: `.md` becomes `text/markdown`, and `.csv` becomes `text/csv`. **Content Type** in advanced mode overrides it. Setting `application/pdf` on a text string does not render a PDF; use an actual PDF file for that format. - -A block's output is remembered under the block's name for the rest of the run, and a later block reads it by key, like `` or ``. Producing content and saving it are two separate steps: the producing block holds the value, the File block persists it. - +A [Function](/workflows/blocks/function) can build text deterministically, such as CSV or JSON. Use `` as **Content** when the returned value is the text you want to store. See [Using files in workflows](/files/using-in-workflows) for the full read → summarize → save example. -## Saving content with the File block +## Save an existing file -The [File](/integrations/file) block's **Write** operation creates a new workspace file. It takes two required fields: a `fileName` (like `report.md`) and the `content` string to store. It returns the saved file's details. +If a block already returns a file object, pass it to Write's **File** input and leave **Content** empty. Set **File Name** and the destination folder. Provide exactly one source: text in **Content**, or an existing object in **File**. -{/* VISUAL: File Write anatomy: inputs (fileName, content, contentType?) → outputs (id, name, size, url) */} +For example, ElevenLabs text-to-speech returns ``. An image generator returns an image file, and a remote Function can return ``. These objects can go directly to compatible attachment or upload inputs. Write's **File** input copies their bytes into workspace Files so later runs can reuse them. -To save an Agent's analysis, connect Agent into a File block, set the operation to Write, and reference the Agent's output: `fileName` = `research_summary.md`, `content` = ``. When the workflow runs, the File block writes the file and produces: +At the tool level, `file_write` accepts `fileInput` and can inherit the source name when `fileName` is omitted. The current block editor still requires **File Name**. -- `id`: the canonical file ID, used to fetch the file later. -- `name`: the final file name after any deduplication (see below). -- `size`: the byte count. -- `url`: an absolute URL to download or preview the file. +## Create, overwrite, or append -The content type is detected from the file extension: `.csv` becomes `text/csv`, `.pdf` becomes `application/pdf`, `.md` becomes `text/markdown`. To set it yourself, fill in `contentType` in advanced mode. +By default, Write keeps an existing file with the same name in the destination folder and adds a numeric suffix to the new file: `data.csv`, `data (1).csv`, then `data (2).csv`. -If a file with the same name already exists in the workspace, Write does not overwrite it. It appends a numeric suffix instead: a second `data.csv` is saved as `data (1).csv`, a third as `data (2).csv`. To add to an existing file rather than create a new one, use the **Append** operation, which writes content to the end of a named file. +Turn on **Overwrite Existing File** to replace the file at the exact destination name and folder. If that path does not exist, Write creates it. Use **Append** to add text to the end of an existing file instead. Select the file directly, or use its name with a folder scope to avoid targeting an ambiguous name. -## Where the file goes +For file tools or API operations that accept `expectedRevision`, use it to guard a content change based on an earlier read. A version number can stay the same across coalesced collaborative or workflow writes, so it is not an exact content precondition. For Write, `expectedRevision` requires `overwrite: true`. See the [file content API](/api-reference/files/updateFileContent) and [version history API](/api-reference/files/listFileVersions). -A saved file lands in the workspace [Files](/files) store, the same place uploads live. It shows up in the Files panel in the sidebar with its name, size, type icon, and modified date, grouped by category: document, image, audio, video, or code. From there you can preview it, rename it, move it into a folder, or download it by URL. +## Generate files with Function [#what-produces-file-content] -{/* VISUAL: Files panel UI: generated files listed with name, size, type icon, owner, modified date, folder */} +A remote Function can write files under `/tmp/sim/outputs`. Sim returns those files as the block's `files` output, ready for a compatible downstream input: -Files are scoped to the workspace, not to one workflow. A file written by one workflow is visible to every other workflow in the same workspace. Any later run can read it back with the File block's Read or Get operation, or by selecting it in a file picker. +```python +with open('/tmp/sim/outputs/summary.csv', 'w') as handle: + handle.write('category,count\ncompleted,12\nfailed,2\n') +``` -During a run, the file also appears in the output panel as the File block's output, shown as a structured object with its `id`, `name`, `url`, and `size`. The output panel shows you one run as it happens, while the Files store is where the file stays afterward. +Pass `` to File **Write** to keep this execution artifact in workspace Files. Automatic exports allow up to 20 files and 50 MiB total; exceeding a cap fails the export rather than returning a partial set. -{/* VISUAL: output panel tree: file object (id, name, url, size, type) during a run, beside the same file in the Files store */} +The Chat workbench uses a per-call `SIM_OUTPUT_DIR`; outputs written there are exported to workspace Files. Use the environment-provided directory in that context. The separate Function tool also supports explicit `outputPath` and `outputSandboxPath` persistence. These are tool capabilities, not fields in the current Function block editor. -## Returning a generated file from a deployment +## Reuse and return a file [#where-the-file-goes] -When a workflow is deployed as an [API](/workflows/deployment/api), a generated file can be part of the response. Reference the file in a [Response](/workflows/blocks/response) block, or include its ID in the object you return. The caller uses the `url` or `id` to fetch the file from the workspace store. The file itself stays in the Files store, and the response carries a pointer to it, not the bytes. +Saved files belong to the workspace. Authorized later runs can select them in a file picker or read them by canonical ID with **Read**; use **Get Content** when the next step needs extracted text. Renaming or moving a file does not require another workflow to generate it again. -## Next +A [Response](/workflows/blocks/response) block can return a file object or a saved file ID to an API caller. The response does not create public access. API-key callers download saved workspace files through the Files API, or run-produced files through the run-file endpoint. Optional base64 output can include eligible bytes within its limits. See [Passing files](/files/passing-files#receiving-files-in-api-responses). - - - - - - +## Related docs [#next] + +- [Files](/files) +- [Using files in workflows](/files/using-in-workflows) +- [Passing files](/files/passing-files) +- [File block](/integrations/file) +- [API deployment](/workflows/deployment/api) diff --git a/apps/docs/content/docs/files/index.mdx b/apps/docs/content/docs/files/index.mdx index 555aaefa26f..dd157140834 100644 --- a/apps/docs/content/docs/files/index.mdx +++ b/apps/docs/content/docs/files/index.mdx @@ -1,24 +1,74 @@ --- title: Files -description: Files are the documents, images, spreadsheets, and PDFs your workflows read and produce. +description: Upload, create, organize, and share workspace documents and media. --- -import { Card, Cards } from 'fumadocs-ui/components/card' +**Files** stores the documents and media you upload, create, or save to a workspace. Use it when you need the file itself: a contract to review, an image to attach, or a report to download and reuse. -A **file** is a document, image, spreadsheet, or PDF in your workspace. Files are how documents and media move into and out of your agents. Your team uploads them, you create them in the editor, or a workflow produces them, and they all live in one store shared across the workspace. +Use [Tables](/tables) for structured rows and fields, and a [knowledge base](/knowledgebase) when an agent needs to search across documents. Adding a file to Files does not automatically add it to a knowledge base. -Any [workflow](/workflows) can read a file or produce one. You might upload a contract for an agent to review, generate a report from a table, or hand a workflow the document it needs to answer a question. +## Upload or create a file -## How files fit the workspace +1. Open **Files** in the workspace sidebar. +2. Select **Upload**, or drag files into the list. Open a folder first to upload into it. +3. Select **New file** to create a Markdown document, or **New folder** to organize files. +4. Open a file to view it. Members with edit access can edit supported text files. -- **[Workflows](/workflows)** read files, like a PDF to summarize, and produce them, like a rendered report. See [using files in workflows](/files/using-in-workflows). -- **[Knowledge bases](/knowledgebase)** are built from files you upload, turning their contents into searchable memory. -- **[Deployments](/workflows/deployment)** can take a file as input and return one as output. +Workspace uploads support files up to 5 GiB each, subject to available workspace storage. This storage limit does not mean every viewer, workflow block, or external service can process a file that size. See [file limits](/files/passing-files#file-limits) before using a large file in a workflow. -Use a file when the document or media itself is what matters. Use a [table](/tables) when you need structured rows and fields, and a [knowledge base](/knowledgebase) when an agent needs to search across many documents. +## Preview, edit, and download - - - - - +The viewer depends on the file's format, size, and your access: + +| Format | Available view | +| --- | --- | +| Markdown | Rich editing, with source editing when rich editing cannot preserve the document | +| Text and code | Text editor | +| CSV, HTML, SVG, Mermaid, and chart files | Format-specific previews; supported text files can also be edited | +| PDF, DOCX, PPTX, and XLSX | Document, slide, or spreadsheet preview | +| Common images, audio, and video | Image view or browser playback | +| Unsupported formats | Download the file to open it elsewhere | + +HEIC and HEIF previews use server conversion. TIFF files are download-only. Browser media support and viewer size limits still apply. See [Editor](/files/editor) for Markdown formatting, source editing, and export behavior. + +Use **Download** in the file menu or viewer. Downloading multiple files or a folder produces a ZIP archive, subject to the [archive download limits](/api-reference/files/bulkDownloadFiles). A generated document's download can contain rendered bytes whose size and type differ from its stored generation source. + +## Organize files + +Use folders to group related files. The list can be searched, filtered, and sorted by properties such as type, size, owner, and last update. Open a file's menu to **Rename**, **Move to**, or **Pin** it. + +**Delete** removes the file from active Files and makes it eligible for the workspace's deletion lifecycle. Recovery and later cleanup depend on the effective [data retention policy](/platform/enterprise/data-retention); deletion does not promise immediate removal of every stored byte. + +## Access and sharing + +Workspace files are private to members and callers with the required workspace access. Read access allows viewing and downloading; write access is required to upload, create, edit, rename, move, or delete files. Enterprise permission groups can restrict Files and sharing. + +To share a file outside the workspace: + +1. Open its menu and select **Share**. +2. Choose an available access mode. +3. Select **Share**, then **Copy link**. + +| Access mode | Who can view and download | +| --- | --- | +| **Public** | Anyone with the link | +| **Password** | Anyone with the link and password | +| **Email** | Allowed emails or domains after verification with a one-time code | +| **SSO** | Allowed emails signed in through SSO, when this mode is available | + +An administrator can disable public sharing or particular access modes. Sharing requires write access and a user identity; a workspace API key cannot enable a file share. To revoke a link, reopen **Share** and select **Unshare**. **Copy Link** in the file menu copies the workspace URL; it does not enable public sharing. + +## Reuse files in agents + +A workflow can read a workspace file when its execution identity has access. See [Using files in workflows](/files/using-in-workflows) for a read → summarize → save example. + +A file produced during a workflow run can remain an execution artifact without appearing in Files. [Save it to Files](/files/generating) when later runs need it. Execution files follow the run's lifecycle and are not retained indefinitely. + +[Chat attachments](/chat/files) stay private to the conversation until explicitly saved to workspace Files. Saving an attachment makes it a workspace resource; it does not create a public share link. + +## Related docs + +- [Editor](/files/editor) +- [Using files in workflows](/files/using-in-workflows) +- [Generating files](/files/generating) +- [Passing files](/files/passing-files) diff --git a/apps/docs/content/docs/files/passing-files.mdx b/apps/docs/content/docs/files/passing-files.mdx index 22d22c94df5..90e07a59ac5 100644 --- a/apps/docs/content/docs/files/passing-files.mdx +++ b/apps/docs/content/docs/files/passing-files.mdx @@ -1,178 +1,187 @@ --- title: Passing files -description: How file objects move between blocks, into workflows via the API, and back out in responses. +description: Reference files between blocks, supply files to the v2 API, and download run outputs. --- -import { Callout } from 'fumadocs-ui/components/callout' -import { Tab, Tabs } from 'fumadocs-ui/components/tabs' +import { Tab, Tabs } from '@/components/ui/tabs' -A file moves through a workflow as a standardized **file object**. Blocks receive it, act on it, and pass it on — this page covers the object's shape, how to reference it between blocks, and how files enter and leave through the API. +Pass a file object to a compatible file input, or reference one of its properties when a block needs a specific value. Workflow file objects, API upload descriptors, and the API's run-file download records have different shapes. -## File Objects +## File objects -When blocks output files (like Gmail attachments, generated images, or parsed documents), they return a standardized file object: +Blocks that return platform files use a `UserFile` object. For example, a workspace file includes: ```json { - "id": "f_8c2...", + "id": "wf_V1StGXR8z5jdHi6BmyT7q", "name": "report.pdf", - "url": "https://...", + "url": "https://www.sim.ai/api/files/serve/ENCODED_STORAGE_KEY?context=workspace", "size": 245678, "type": "application/pdf", - "base64": "JVBERi0xLjQK..." + "key": "workspace/WORKSPACE_ID/FILE_STORAGE_KEY", + "context": "workspace" } ``` -You can access any of these properties when referencing files from previous blocks. +The IDs, key, and URL above illustrate the fields. Use the values Sim returns; do not construct them yourself. -## The File Block +| Field | Meaning | +| --- | --- | +| `id` | Opaque file identifier | +| `name` | Filename, including its extension | +| `url` | Access URL; authentication and lifetime depend on its source | +| `size` | Recorded file size in bytes | +| `type` | MIME type | +| `key` | Storage locator used by Sim; it is not a public access grant | +| `context` | Optional storage context, such as `workspace` or `execution` | +| `base64` | Optional encoded bytes; not included on every object | +| `version` | Optional content version for a workspace file | -The **File block** brings a file into a workflow. It accepts files from any source and outputs standardized file objects every block understands. +The internal `key` and `context` fields may be omitted from output pickers and displayed logs. Their absence in a preview does not mean a file reference is unusable. -**Inputs:** -- **Uploaded files** - Drag and drop or select files directly -- **External URLs** - Any publicly accessible file URL -- **Files from other blocks** - Pass files from Gmail attachments, Slack downloads, etc. +Generated documents can store generation source separately from the rendered download. Their recorded size or type can differ from the bytes a download returns. -**Outputs:** -- A list of `UserFile` objects with consistent structure (`id`, `name`, `url`, `size`, `type`, `base64`) -- `contents` - Extracted text per file (the Get Content operation) -- `combinedContent` - All fetched files' text merged into one string (the Fetch operation) +**Read** returns file objects. **Get Content** returns extracted text in `contents`; **Fetch** returns file objects and `combinedContent`. For the operation settings, see [Using files in workflows](/files/using-in-workflows#the-file-block). -**Example usage:** +## Pass files between blocks [#passing-files-between-blocks] -``` -// Get all files from the File block - +Use the output picker or type `<` in a reference-capable input to select an earlier block's output. Keep the array index when selecting one file: -// Get the first file +```text + - -// Get the first file's extracted text (Get Content operation) + + ``` -The File block automatically: -- Detects file types from URLs and extensions -- Extracts text from PDFs, CSVs, and documents -- Generates base64 encoding for binary files -- Creates presigned URLs for secure access - -Use the File block when you need to normalize files from different sources before passing them to other blocks like Vision, STT, or email integrations. +Pass the full object to a file input when possible. The receiving block determines which formats, object or array inputs, and sizes it supports. Sim does not convert every file format for every block. -## Passing Files Between Blocks +Use `.base64` only when the object includes it. JavaScript without imports can explicitly read bytes with `await sim.files.readBase64(file)` or text with `await sim.files.readText(file)` under the Function helper limits. In remote Function code, `` requests a file mount; it is a special indexed reference, not a UserFile property. See [Function files](/workflows/blocks/function#files). -Reference files from previous blocks using the tag dropdown. Click in any file input field and type `<` to see available outputs. +## Supply files to the API [#triggering-workflows-with-files] -**Common patterns:** +Before calling the workflow, add a **Files** input named `document` to the entry trigger's input format and deploy that version. The UI uses the field type `file[]`; `files` remains a legacy compatibility alias. With a Start block named `Start`, the first processed file is available as ``. -``` -// Single file from a block - - -// Pass the whole file object - - -// Access specific properties - - -``` - -Most blocks accept the full file object and extract what they need automatically. You don't need to manually extract `base64` or `url` in most cases. - -## Triggering Workflows with Files - -When calling a workflow via API that expects file input, include files in your request: +Set `WORKFLOW_ID` and `SIM_API_KEY` in your shell. On self-hosted Sim, replace the Cloud origin with your deployment URL. Put workflow fields inside the v2 request's `input` object. + This example uploads a small text file containing `Hello, Sim.` followed by a newline. For another file, replace the encoded bytes, MIME type, and name together. + ```bash - curl -X POST "https://www.sim.ai/api/v2/workflows/YOUR_WORKFLOW_ID/execute" \ - -H "Content-Type: application/json" \ - -H "x-api-key: YOUR_API_KEY" \ + curl --fail-with-body -X POST \ + "https://www.sim.ai/api/v2/workflows/$WORKFLOW_ID/execute" \ + -H "X-API-Key: $SIM_API_KEY" \ + -H 'Content-Type: application/json' \ -d '{ - "document": { - "name": "report.pdf", - "base64": "JVBERi0xLjQK...", - "type": "application/pdf" + "input": { + "document": [{ + "type": "file", + "data": "data:text/plain;base64,SGVsbG8sIFNpbS4K", + "name": "notes.txt", + "mime": "text/plain" + }] } }' ``` + Replace the example URL with a downloadable file URL that passes your deployment's network policy. + ```bash - curl -X POST "https://www.sim.ai/api/v2/workflows/YOUR_WORKFLOW_ID/execute" \ - -H "Content-Type: application/json" \ - -H "x-api-key: YOUR_API_KEY" \ + curl --fail-with-body -X POST \ + "https://www.sim.ai/api/v2/workflows/$WORKFLOW_ID/execute" \ + -H "X-API-Key: $SIM_API_KEY" \ + -H 'Content-Type: application/json' \ -d '{ - "document": { - "name": "report.pdf", - "url": "https://example.com/report.pdf", - "type": "application/pdf" + "input": { + "document": [{ + "type": "url", + "data": "https://example.com/report.pdf", + "name": "report.pdf", + "mime": "application/pdf" + }] } }' ``` -The workflow's Start block should have an input field configured to receive the file parameter. +For a new file, `type` selects `file` or `url`; it is not the MIME type. `data` is a base64 data URL or a download URL, `name` is required, and `mime` is optional. The engine stores accepted new input files in execution storage and supplies an array of UserFile objects to the file-typed field before blocks run. + +Authorized workspace-member callers can also supply an existing stored reference such as `{ "id": "CANONICAL_FILE_ID" }` or `{ "key": "STORAGE_KEY" }`. Public or system callers cannot use an arbitrary ID or key to read workspace files; their supplied stored references are limited to files already authorized for that execution. A caller-provided identifier does not grant access to neighboring files or another workspace. -## Receiving Files in API Responses +## Download files from API responses [#receiving-files-in-api-responses] -When a workflow outputs files, they're included in the response: +Return the file object or saved file ID through a [Response](/workflows/blocks/response) block. A synchronous v2 response wraps the result in `data.output` and includes `data.runId`, `data.status`, and `data.error`. Check the run status even when the HTTP request succeeds. + +For a completed run that returned an execution-produced file: + +1. Set `RUN_ID` to the returned run ID. +2. Read the run with `includeOutput=true`. +3. Take the file's `id` or `downloadPath` from `data.files` and download it with the same authentication. + +```bash +curl --fail-with-body \ + "https://www.sim.ai/api/v2/workflows/$WORKFLOW_ID/runs/$RUN_ID?includeOutput=true" \ + -H "X-API-Key: $SIM_API_KEY" +``` + +Each projected entry in `data.files` has this shape: ```json { - "success": true, - "output": { - "generatedFile": { - "name": "output.png", - "url": "https://...", - "base64": "iVBORw0KGgo...", - "type": "image/png", - "size": 34567 - } - } + "id": "file_123", + "name": "output.png", + "size": 34567, + "type": "image/png", + "downloadPath": "/api/v2/workflows/WORKFLOW_ID/runs/RUN_ID/files/file_123", + "base64": null } ``` -Use `url` for direct downloads or `base64` for inline processing. +Set `FILE_ID` to the returned file ID: -## Blocks That Work with Files +```bash +curl --fail-with-body \ + "https://www.sim.ai/api/v2/workflows/$WORKFLOW_ID/runs/$RUN_ID/files/$FILE_ID" \ + -H "X-API-Key: $SIM_API_KEY" \ + --output output.png +``` -**File inputs:** -- **File** - Parse documents, images, and text files -- **Agent** - Read images with a vision-capable model, or documents as text -- **Mistral Parser** - Extract text from PDFs +The ordinary `/api/files/serve/...` URL in a workflow file object requires a session and does not accept `X-API-Key`. Use the [run-file download endpoint](/api-reference/workflow-runs/downloadWorkflowRunFileV2) for execution artifacts. If you saved a workspace file with Write and returned its ID, use [Download file](/api-reference/files/downloadFile) at `/api/v2/files/{fileId}?workspaceId={workspaceId}`. -**File outputs:** -- **Gmail** - Email attachments -- **Slack** - Downloaded files -- **TTS** - Generated audio files -- **Video Generator** - Generated videos -- **Image Generator** - Generated images +Execution files follow the run's retention lifecycle and may later return `404`. Save them to Files when later runs need a workspace resource. Returning a pointer or downloading it does not make a public share link. -**File storage:** -- **Supabase** - Upload/download from storage -- **S3** - AWS S3 operations -- **Google Drive** - Drive file operations -- **Dropbox** - Dropbox file operations +To inline eligible output bytes, request `includeFileBase64: true`. The execute request's `base64MaxBytes` can lower the 16 MiB total inline ceiling; it cannot raise it. Async execution rejects these options. On a run read, base64 requires `includeOutput=true` and has a per-file ceiling; an oversized file can return `413` with its download path. Use authenticated downloads for large outputs. See [Execute workflow](/api-reference/workflows/executeWorkflowV2) and [Get workflow run](/api-reference/workflow-runs/getWorkflowRunV2) for the full option contracts. - - Files are automatically available to downstream blocks. The engine handles all file transfer and format conversion. - +## File limits -## Best Practices +There is no single limit for every upload or read path. Storage quota, parser limits, sandbox budgets, and the receiving provider's limits apply independently. -1. **Use file objects directly** - Pass the full file object rather than extracting individual properties. Blocks handle the conversion automatically. +| Path | Current hard limit | +| --- | --- | +| Workspace direct upload | 5 GiB per file, subject to workspace storage quota | +| Legacy buffered workspace upload | 100 MiB per file | +| New base64 or URL input processed for a workflow file field | 20 MiB per file | +| File Fetch | 100 MiB download; 30-second download timeout | +| File Get Content | 64 MiB source per file and 64 MiB combined extracted text | +| File Write text or existing-file input | 50 MiB per file | +| Function buffered mounts | 10 MiB per file; 50 MiB total | +| Function URL mounts | 500 MiB per file; 2 GiB total | +| Function automatic exports | 20 files; 50 MiB total | -2. **Check file types** - Ensure the file type matches what the receiving block expects. An Agent using a vision-capable model can read images, while the File block handles documents. +Workspace uploads use upload sessions for large transfers; API callers should follow the [file upload API](/api-reference/files/createFileUpload) rather than assume a multipart JSON or buffered upload shares the 5 GiB ceiling. A large stored file can still exceed a parser, model, or third-party upload limit. See [Function](/workflows/blocks/function) and the receiving block's reference before processing it. -3. **Consider file size** - Large files increase run time. For very large files, consider using storage blocks (S3, Supabase) for intermediate storage. +## Blocks that work with files -import { FAQ } from '@/components/ui/faq' +| Task | Examples | +| --- | --- | +| Read or extract content | [File](/integrations/file), [Agent](/workflows/blocks/agent), [Mistral Parser](/integrations/mistral_parse) | +| Analyze an image or transcribe audio | Vision, STT | +| Receive or send attachments | [Gmail](/integrations/gmail), [Slack](/integrations/slack) | +| Generate media | TTS, Image Generator, Video Generator | +| Store files externally | [Supabase](/integrations/supabase), [S3](/integrations/s3), [Google Drive](/integrations/google_drive), [Dropbox](/integrations/dropbox) | - +These integrations support particular file operations; check their format and authentication requirements. Agent attachment support depends on the selected model and provider. diff --git a/apps/docs/content/docs/files/using-in-workflows.mdx b/apps/docs/content/docs/files/using-in-workflows.mdx index a97a9883f00..d7dff297457 100644 --- a/apps/docs/content/docs/files/using-in-workflows.mdx +++ b/apps/docs/content/docs/files/using-in-workflows.mdx @@ -1,98 +1,98 @@ --- title: Using files in workflows -description: Read a file's contents in a workflow, pass a file to a block that needs one, or save a new file from a run. +description: Read a workspace file, summarize it with an Agent, and save the result. --- -import { Callout } from 'fumadocs-ui/components/callout' import { WorkflowPreview, FILE_SUMMARY_WORKFLOW } from '@/components/workflow-preview' -A file is a document, image, spreadsheet, or PDF in your workspace. A workflow can read a file to act on its contents, pass a file to a block or tool that needs one (attach a PDF to an email, send an image to a vision model), or produce a new file and save it. The [File](/integrations/file) block is how a file enters or leaves a workflow; the work in between is done by whatever block the task calls for. - -What you do with a file depends on the task, so this page covers the File block's operations and how a file moves between blocks rather than one fixed recipe. The example we'll use throughout reads `report.pdf`, asks an agent to summarize it, and saves the summary as `summary.md`, which exercises reading, processing, and writing in one workflow. +Use a File block to read `report.pdf`, an Agent to summarize it, and another File block to save `summary.md`. You can also pass a file directly to a compatible block, such as an email attachment or image input. -## The File block +Before running the example, upload `report.pdf` to workspace **Files** and choose an Agent model and provider that support PDF attachments. The execution identity must have access to the file and permission to create the summary. -The **File** block is one block with five operations, chosen from a dropdown. Each operation is a different way a file, or its contents, enters or leaves the workflow. +## Read the file [#reading-a-file-in] -| Operation | What it does | Outputs | -| --- | --- | --- | -| **Read** | Take an existing workspace file, by file picker or by file ID. | `files` | -| **Get Content** | Extract a workspace file's text, by file picker or by file ID. | `contents` | -| **Fetch** | Download and parse a file from an external URL. | `files`, `combinedContent` | -| **Write** | Create a new workspace file from a name and text content. | `id`, `name`, `size`, `url` | -| **Append** | Add text to the end of an existing workspace file. | `id`, `name`, `size`, `url` | +1. Add a [File](/integrations/file) block named `File`. +2. Select **Read** and choose `report.pdf` in the file picker. +3. Connect it to an Agent block named `Agent`. -Read hands the next block the **file itself**; Get Content hands it the **text inside**. Fetch brings in both for an external URL. Write and Append put a file out. A workflow uses only the operations its task needs, often just Read. The two sections below cover Read and Write; the other operations are variants noted alongside. +Read returns `files`, an array of file objects. Reference the first file as ``, or the array as ``. Each object carries its ID, name, URL, byte size, MIME type, and storage key. See the [file object fields](/files/passing-files#file-objects). -{/* VISUAL: File block config UI. Operation dropdown open showing Read / Get Content / Fetch / Write / Append */} +In advanced mode, Read can take a canonical workspace file ID. Use that for a file saved earlier in the same run. If another block already returned the file object you need, pass that object directly to a compatible input. -## Reading a file in +## Summarize with Agent [#processing-the-file] -In our example, the first File block is set to **Read**, with `report.pdf` chosen from the file picker. When it runs, it produces `files`: a list of **file objects**, one per file read. The first is ``. +In the Agent block: -When the next step needs the file's *text* rather than the file itself, use **Get Content** instead: it extracts the text and outputs `contents`, an array with one string per file, read as ``. +1. Set **Files** to ``. +2. Add the instruction “Summarize this document” to **Messages**. +3. Select a model and provider that support the file's format. -A **file object** is the standard shape Sim uses for every file. It carries the file's details: +The summary is available as ``. Attachment support varies by model and provider. Sim does not automatically turn an unsupported attachment into prompt text; use **Get Content** and reference the extracted string in **Messages** for a text-only path. -```jsonc -{ - "id": "wf_V1StGXR8z5jdHi6B…", // workspace file ID - "name": "report.pdf", - "url": "https://…", // where to access it - "size": 248120, // bytes - "type": "application/pdf" -} -``` +## Save the summary [#writing-a-file-out] -You rarely type a reference by hand. Wherever a block parameter accepts a file or a value, the builder lists the available outputs and you pick the one you want. Read mode also takes a file ID directly in advanced mode, which is how you read a file produced earlier in the same run. +1. Connect the Agent to a second File block. +2. Select **Write**. +3. Set **File Name** to `summary.md`. +4. Set **Content** to `` and leave **File** empty. +5. Run the workflow, then open **Files** to verify the saved summary. - -**Fetch** brings in files that live outside the workspace. Point it at a URL, and add request headers (such as `Authorization: Bearer …`) when the download needs authentication. It outputs `files` like Read does, plus `combinedContent`: the fetched files' text merged into one string. - +Write returns `id`, `name`, `size`, `url`, `version`, and `revision`. By default, a duplicate name in the destination folder gets a numeric suffix. Turn on **Overwrite Existing File** only when you want to replace that file's contents. -{/* VISUAL: File block in Read mode, file picker open with report.pdf selected; callout on the files[] output */} +Saving is optional. You can return the summary, send it to Slack, or email it as text without creating a workspace file. To save a binary file returned by another block, use Write's **File** input instead of **Content**; see [Generating files](/files/generating). -## Processing the file +## Choose another file operation [#the-file-block] -Once a file is read, a processing block reads that output by name. Two blocks do this, and they consume the file differently. +These operations cover common file-processing paths: -### Agent block +| Operation | Use it for | Outputs | +| --- | --- | --- | +| **Read** | Obtain workspace file objects by picker, canonical ID, or folder selection | `files` | +| **Get Content** | Extract text from supported files | `contents`, and `lineRanges` when a line window is requested | +| **Fetch** | Download and parse an HTTP(S) file URL, with optional request headers | `files`, `combinedContent` | +| **Write** | Save text or an existing file object to workspace Files | `id`, `name`, `size`, `url`, `version`, `revision` | +| **Append** | Add text to an existing file | `id`, `name`, `size`, `url`, `version`, `revision` | -An [Agent](/workflows/blocks/agent) block has a **Files** input. Reference the read file there, ``, and write the instruction in the prompt: "Summarize this document." The agent receives the file object, not just its text, so a **vision-capable model** can analyze images and scanned pages directly. Other models work from the file's text content. +The current File block also supports listing, searching, applying edits, archives, sharing, and folder operations. See the [File block reference](/integrations/file) for their inputs and limits. -In our example the Agent reads ``, summarizes it, and keeps the summary under its own name as ``. +### Extract text -{/* VISUAL: Agent block config. Files input bound to , prompt "Summarize this document" */} +Select **Get Content** when the next step needs text rather than the original file. Its `contents` array has one extracted string per selected file: `` reads the first one. Optional offset and limit fields request a line window; line numbers refer to extracted text, not PDF pages or spreadsheet rows. -### Function block +Read and Get Content can select folders. A folder selection expands at run time and includes nested folders by default, so newly added files can be picked up by a later run. Turn off the subfolder option to include direct files only. -A [Function](/workflows/blocks/function) block runs code, and it usually works with file **text**. Read the file with **Get Content** and pass the extracted text, ``, and the code can parse, filter, or reshape it and return the result as its own output. A Function can also take the file object itself and read it in code with the `sim.files` helpers, like `await sim.files.readText(file)` — see [the Function block](/workflows/blocks/function) for those. Use a Function when the file is structured text (a CSV or JSON dump) and you want exact, deterministic processing instead of a model's interpretation. +### Fetch a URL - -The two blocks differ in what they take. An **Agent** takes the file object on its Files input, while a **Function** typically takes the file's text from Get Content's `contents`. Both store their result under their own name for the next block to read. - +Select **Fetch**, enter the file URL, and provide request headers when needed, such as `Authorization: Bearer …`. The URL must pass the deployment's network validation and download limits. Fetch returns file objects in `files` and extracted text in `combinedContent`. It does not automatically save the fetched file to workspace Files. -## Writing a file out +### Process with Function -Writing a file is optional, and many workflows skip it. The agent's summary could be returned in the response, posted to Slack, or emailed as-is without ever becoming a workspace file. Write a file when you specifically need a new one to keep, download, or hand to a later run. +For deterministic CSV or JSON processing, use **Get Content** and reference its text in a [Function](/workflows/blocks/function). For example, parse a JSON file after extraction: -The last block in our example is a File block set to **Write**. Give it a file name and the content to save: +```javascript +return JSON.parse(); +``` + +For a text file, JavaScript without imports can read the original file bytes with a helper: -- `fileName`: `summary.md` -- `content`: `` +```javascript +const file = ; +return await sim.files.readText(file); +``` -Write creates a new workspace file and returns its `id`, `name`, `size`, and `url`. If a file with that name already exists, Write keeps both by adding a numeric suffix to the new one. The saved file lands in your workspace [files](/files), ready for the next run, a download, or another workflow. +`readText` decodes file bytes; it does not extract PDF text. Use Get Content for document parsing. Python, Shell, and JavaScript with imports can use an indexed file-path reference such as `` to request a sandbox mount under `/tmp/sim/inputs`. This special reference resolves to the mounted path; `.path` is not a stored property you can read after assigning the whole object to a variable. -{/* VISUAL: run log showing the File Write step with the returned file id, name, and url */} +Files written under `/tmp/sim/outputs` return as Function `files` output. Pass them to a compatible attachment/upload input, or use File Write to save them. See [Generating files](/files/generating#what-produces-file-content). - -**Append** adds to a file instead of replacing it. Target an existing workspace file by name and give it the content to add to the end. Use it to accumulate across runs, such as appending each run's observation to one `notes.md`. - +### Append to an existing file -## Composing the steps +Select **Append**, choose an existing file, and provide the text to add. Use it for a running `notes.md` or log. Selecting a file directly avoids ambiguous names; when using a name, specify a folder scope if the name exists in several folders. -Each block references the previous one by name, so you compose only the steps a task needs. A contract read by an Agent that returns a verdict stops at processing, and an uploaded image described by a vision model never touches Write, while a fetched CSV cleaned by a Function and saved as a new file uses all three. Reading a file in is common, and writing one out is only for when the result is itself a file. +## Related docs [#composing-the-steps] -For the file-object schema in full, base64 access, and how files move across API and chat triggers, see [Passing files](/files/passing-files). +- [Passing files](/files/passing-files): object fields, API input, and authenticated downloads +- [Generating files](/files/generating): text and binary persistence +- [Function](/workflows/blocks/function): code, file mounts, and sandbox exports +- [File block](/integrations/file): complete operation reference diff --git a/apps/docs/content/docs/getting-started/index.mdx b/apps/docs/content/docs/getting-started/index.mdx index 4156a12b51b..7ffba324222 100644 --- a/apps/docs/content/docs/getting-started/index.mdx +++ b/apps/docs/content/docs/getting-started/index.mdx @@ -1,95 +1,136 @@ --- -title: Getting Started -description: Build your first agent in 10 minutes — a people researcher with web search tools and structured output. +title: Getting started +description: Build and test a research agent with web search tools and structured output. --- import { Callout } from 'fumadocs-ui/components/callout' -import { Card, Cards } from 'fumadocs-ui/components/card' import { Step, Steps } from 'fumadocs-ui/components/steps' -import { Video } from '@/components/ui/video' -import { Image } from '@/components/ui/image' -Build a people research agent in 10 minutes. It takes a name through a chat interface, searches the web with AI search tools, and returns structured JSON with the person's location, profession, and education. +Build an agent that receives a person's name, searches for their professional background, and returns `location`, `profession`, and `education` fields. You will test it in the workflow builder before deploying it. -The finished people research workflow +## Prerequisites -## Tutorial +- A workspace where you can create and edit workflows. +- An available model that supports tool calls and structured output. +- Access to Exa and Linkup search tools. Use Sim-provided credentials where offered, or enter your own provider keys where prompted. Self-hosted deployments must supply the credentials they use. + +Model and tool calls can incur usage charges. See [Costs](/platform/costs) and [Credentials](/platform/credentials) for hosted credentials and your own keys. + +## Build the agent - - In the sidebar, click the **+** next to **Workflows** and name the new workflow "Getting Started". The **Start block** is already on the canvas — it's the entry point that receives your chat input. + + +Click **+** beside **Workflows** in the sidebar. Right-click the new workflow, choose **Rename**, and name it `People research`. + +The new workflow contains a **Start** block. Its built-in `input` field receives messages from the workflow test chat; you do not need to add a custom field for this tutorial. + + + + +Open **Toolbar** and drag **Agent** into the workflow. Check that **Start** connects to **Agent**. If no connection appears, drag from Start's output handle to Agent's input handle. + +Select **Agent** to open its fields in **Editor**. Choose a model that supports tools and structured output, and configure its credentials if prompted. + + + + +In **Messages**, create these two messages. Use the role dropdown to choose **System** or **User**, and the plus button to add another message. + +| Role | Content | +| --- | --- | +| **System** | `Research the person named in the user's message using the available search tools. Find their location, profession, and education. Use Unknown for anything you cannot verify. Include sources in your answer.` | +| **User** | `` | - Drag an **Agent block** onto the canvas and configure its **Messages**: - - **System**: "You are a people research agent. When given a person's name, use your search tools to find their location, profession, educational background, and other relevant details." - - **User**: insert `` so the agent reads whatever the chat receives. +`` inserts the message passed into Start. See [References](/workflows/connections) for using block outputs in another block. - Leave the **Model** on the default (`claude-sonnet-5-5`), or pick any other. + + -
- -
-
+In Agent's **Tools**, open **Add tool...** and add **Exa** and **Linkup**. Select Exa's search operation and configure the fields shown for each tool, including credentials where required. - - In the Agent block's **Tools** section, add **Exa** and **Linkup**. The agent decides when to call them. +The agent chooses which tools to call. A tool with a missing credential or required setting can fail when the agent calls it. -
- -
-
+
+ - - Open the **Chat panel**, select `agent.content` as the output to display, and send: *"John is a software engineer from San Francisco who studied Computer Science at Stanford University."* +Click **Open chat** beside the workflow's More actions menu. This opens the workflow test chat, which has an **Outputs** dropdown. The **Chat** tab in the panel is where you talk to Sim about building the workflow. - The agent searches, then returns what it found. +In **Outputs**, select **Agent → content**. Send: - {/* Why this callout exists: the largest funnel drop in platform data (2026-06) is created-a-workflow -> first-successful-run, 92% -> 49% — this is the stall point it targets. */} - - If the run doesn't go green, open the output dropdown and read what each block returned — the failure is almost always visible there. The two most common causes are a missing API key on a tool and a reference pointing at a value that isn't there. For the full method, see [tracing a failure backward](/logs-debugging). - +```text +Research the professional background of Tim Berners-Lee. Find his profession, +education, and a publicly documented location. Mark anything you cannot verify +as Unknown. +``` -
- -
-
+Expand **Logs** at the bottom of the builder and select Agent's row. Inspect its output, tool calls, and sources. Check that the results identify the intended person and support the returned facts. - - In the Agent block's **Response Format**, click the magic wand (✨) and prompt: *"create a schema named person, that contains location, profession, and education"*. The schema is generated for you. + + -
- -
-
+In Agent's **Response Format**, paste this schema: - - Back in the **Chat panel**, select the new structured output option and send: *"Sarah is a marketing manager from New York who has an MBA from Harvard Business School."* +```json +{ + "name": "person", + "description": "A researched professional profile", + "strict": true, + "schema": { + "type": "object", + "properties": { + "location": { + "type": "string", + "description": "A publicly documented location, or Unknown" + }, + "profession": { + "type": "string", + "description": "The person's profession, or Unknown" + }, + "education": { + "type": "string", + "description": "The person's education, or Unknown" + } + }, + "required": ["location", "profession", "education"], + "additionalProperties": false + } +} +``` - The agent now returns JSON with `location`, `profession`, and `education` fields — ready for any downstream block to read by name. +You can also use the generation control beside **Response Format** to create a schema from a description. Check the generated schema before running it. -
- -
-
+`person` names the schema. Its properties become outputs directly on Agent; it does not add a nested `person` field. Replace the System message with: + +```text +Research the person named in the user's message using the available search tools. +Return only the location, profession, and education fields defined by the response +format. Use Unknown for anything you cannot verify. +``` + +Keep the User message set to ``. + +
+ + +Send the same prompt in the workflow test chat. In **Outputs**, select Agent's `location`, `profession`, and `education` fields. Open Agent's complete output in **Logs** and check their values before using them downstream. + +When the model returns the schema's fields as valid JSON, they are available as ``, ``, and ``. Structured output requests a shape; it does not verify the facts. + + + A model can return malformed JSON even when a response format is configured. Sim can then fall back to `content` and add `_responseFormatWarning`. Inspect the output and correct the response or model configuration before relying on the schema fields. + + +
-## Next - - - - The full model: blocks, connections, triggers, and how runs execute. - - - Everything the block you just used can do — tools, memory, skills, structured output. - - - supported services your agents can act on, from Gmail to HubSpot. - - - Ship the workflow as an API, a chat, or an MCP server. - - +## Fix a failed run + +Select the failed block in **Logs** and read its error, input, and output. Check the credentials on the model or tool, then confirm that each reference points to an existing output. Rerun after correcting the failure. See [Logs and debugging](/logs-debugging) for tracing a failure through earlier blocks. + +## Related docs + +- [Agent block](/workflows/blocks/agent): Tools, memory, skills, and response formats. +- [Connections](/workflows/connections): Pass outputs between blocks. +- [Deploy a workflow](/workflows/deployment): Expose the agent through an API, chat, or MCP server. +- [Integrations](/integrations): Configure tools for other services. diff --git a/apps/docs/content/docs/index.mdx b/apps/docs/content/docs/index.mdx index 9c342ce5adf..de576fd7832 100644 --- a/apps/docs/content/docs/index.mdx +++ b/apps/docs/content/docs/index.mdx @@ -1,55 +1,8 @@ --- title: Documentation +description: Start with the Sim introduction or build your first agent. --- -import { Card, Cards } from 'fumadocs-ui/components/card' +Read the [Introduction](/introduction) to learn how Sim works, or follow [Getting started](/getting-started) to build and test your first agent. -Welcome to Sim, the open-source AI workspace where teams build, deploy, and manage AI agents. Create agents visually with the workflow builder, conversationally through Chat, or programmatically with the API — connected to the integration catalog and every major LLM. - -## Quick Start - - - - Learn what you can build with Sim - - - Build your first agent in 10 minutes - - - Learn about the building blocks - - - Explore the integration catalog - - - -## Core Concepts - - - - Understand how data flows between blocks - - - Work with workflow and environment variables - - - Inspect workflow runs and diagnose failures - - - Start agents via API, webhooks, or schedules - - - -## Advanced Features - - - - Set up workspace roles and permissions - - - Connect external services with Model Context Protocol - - - Integrate Sim into your applications - - +This URL redirects to the Introduction in the documentation site. diff --git a/apps/docs/content/docs/introduction/index.mdx b/apps/docs/content/docs/introduction/index.mdx index f099f381c63..c9afe906d42 100644 --- a/apps/docs/content/docs/introduction/index.mdx +++ b/apps/docs/content/docs/introduction/index.mdx @@ -1,102 +1,52 @@ --- title: Introduction -description: Sim is the open-source AI workspace where teams build, deploy, and manage AI agents. +description: Build, deploy, and manage AI agents in a shared workspace. --- -import { Card, Cards } from 'fumadocs-ui/components/card' -import { Callout } from 'fumadocs-ui/components/callout' -import { Image } from '@/components/ui/image' -import { Video } from '@/components/ui/video' -import { FAQ } from '@/components/ui/faq' - -Sim is the open-source AI workspace where teams build, deploy, and manage AI agents. Build visually in the workflow builder, conversationally in **Chat**, or with code through the API. Connect the integration catalog and every major LLM to create agents that automate real work. - -
- Sim workflow editor with an empty canvas, Editor panel, and workspace navigation -
- -## How you build - -When you open Sim, the first thing you meet is **Chat**, a conversation over your whole workspace. You describe the system you want, and Sim scaffolds it: workflows, tables, knowledge bases, and the wiring between them. You then open what it built, run it, and refine it. - -- **Chat.** Describe a system in natural language and Sim creates and edits the resources for you. The fastest way to start. -- **Workflow builder.** Design agent logic visually by connecting blocks in the builder. The clearest way to see and fine-tune what runs. -- **API and SDK.** Build and trigger agents programmatically. - -You can mix these on one system, scaffolding in Chat and then fine-tuning in the builder. - - -Sim generates the architecture, and you verify the execution. Even when you build conversationally, it helps to understand the resources Sim creates, so you can inspect, run, and improve them. - - -## The anatomy of a workspace - -A Sim system is not a single chat response. It is a set of resources that live in a **workspace** and connect to each other. The sidebar mirrors that anatomy, and these are its parts. - -- **[Chat](/chat)** is your AI command center. Talk to Sim — build and manage everything in natural language. -- **[Workflows](/workflows)** are visual programs made of blocks, where your logic runs. Most other resources become useful through a workflow. -- **[Agents and tools](/agents)** are how a workflow acts. An agent reasons with a model, and tools let it take actions like sending an email or querying an API. -- **[Tables](/tables)** hold structured rows your workflows read, write, and process. -- **[Knowledge bases](/knowledgebase)** are searchable memory. An agent retrieves relevant passages from your documents to ground its answers. -- **[Files](/files)** are the documents and media your workflows store, read, and produce. -- **[Deployments](/workflows/deployment)** expose a workflow to the outside world as an API, a chat, or an MCP server. -- **[Logs](/logs-debugging)** record every run, block by block, so you can verify what happened. - -
- -
- -## What you can build - -- **AI assistants and chatbots.** Conversational agents that search the web, manage calendars, send email, and act on your business systems. -- **Business process automation.** Data entry, report generation, customer responses, and content workflows. -- **Data processing and analysis.** Extract from documents, analyze datasets, and sync data across platforms. -- **API integration workflows.** Unified endpoints that orchestrate multi-service logic and event-driven automation. - -## Integrations - -Sim provides native integrations with supported services: - -- **AI models.** OpenAI, Anthropic, Google Gemini, Groq, Cerebras, and local models via Ollama or VLLM. -- **Communication.** Gmail, Slack, Microsoft Teams, Telegram, WhatsApp. -- **Productivity.** Notion, Google Workspace, Airtable. -- **Development.** GitHub, Jira, Linear, automated browser testing. -- **Search and data.** Google Search, Perplexity, Firecrawl, Exa AI. -- **Databases.** PostgreSQL, MySQL, Supabase, Pinecone, Qdrant. - -For anything not built in, [MCP support](/agents/mcp) connects any external service or tool. - -## Deployment options - -- **Cloud-hosted.** Launch immediately at [sim.ai](https://www.sim.ai) with managed infrastructure, scaling, and observability. -- **Self-hosted.** Deploy on your own infrastructure with Docker Compose or Kubernetes, with support for local models. - -## Next steps - - - - Build your first agent in 10 minutes - - - Build and manage your workspace in natural language - - - The executable center, and the blocks it's built from - - - The building blocks of a workflow - - - - +Sim is the open-source AI workspace where teams build, deploy, and manage AI agents. Connect models and tools, store shared data, and inspect what happens when an agent runs. + +## Choose how to build + +| Method | Use it to | +| --- | --- | +| **[Chat](/chat)** | Describe what you need and ask Sim to create or edit workspace resources. Open what it creates, run it, and check the result. | +| **[Workflow builder](/workflows)** | Connect blocks into agent logic, configure their inputs, and inspect execution step by step. | +| **[API and SDKs](/api-reference)** | Create resources and run deployed workflows from your application. | + +You can start in Chat and refine the same workflow in the builder. On self-hosted deployments, Chat depends on the deployment's configuration and can be disabled. + +Follow [Getting started](/getting-started) to build an agent with web search tools and structured output. + +## Workspace resources + +A workspace holds the resources your team and agents use: + +| Resource | Purpose | +| --- | --- | +| **[Workflows](/workflows)** | Executable logic made of connected blocks. Use Agent blocks for model reasoning and tools for actions such as sending email or querying an API. | +| **[Tables](/tables)** | Structured rows that workflows can read, update, and process. | +| **[Files](/files)** | Documents and media you upload, create, and share with agents. | +| **[Knowledge bases](/knowledgebase)** | Searchable documents. Retrieve relevant passages for an agent to use in its answers. | +| **[Logs](/logs-debugging)** | Run records and block inputs, outputs, errors, timing, and costs. | + +[Deploy a workflow](/workflows/deployment) to make it available through an API, a chat interface, or an MCP server. MCP (Model Context Protocol) lets AI applications discover and call tools exposed by a server. + +## Models and integrations + +Use the [integration catalog](/integrations) to connect supported models, communication services, productivity apps, search tools, and databases. These tools let agents research a topic, process documents, update business systems, and return results to another application. + +For tools outside the catalog, connect an [external MCP server](/agents/mcp) or create a [custom tool](/agents/custom-tools). Configure the credentials and permissions each service requires. + +## Choose a deployment + +- **Sim Cloud:** Sign in at [sim.ai](https://www.sim.ai) to use the managed service. +- **Self-hosted:** Run Sim on your infrastructure with [Docker Compose](/platform/self-hosting/docker) or [Kubernetes](/platform/self-hosting/kubernetes). You can connect local models through Ollama or vLLM. Chat and external integrations can still require network access. + +The core source is available on [GitHub](https://github.com/simstudioai/sim) under the Apache 2.0 license. Enterprise features use a separate license that requires an active Enterprise subscription for production use. See [self-hosting](/platform/self-hosting) for installation requirements and configuration. + +## Related docs + +- [Getting started](/getting-started): Build and test a research agent. +- [Chat](/chat): Build and manage workspace resources conversationally. +- [Workflows](/workflows): Blocks, connections, triggers, and execution. +- [Quick reference](/quick-reference): Look up builder actions. diff --git a/apps/docs/content/docs/keyboard-shortcuts/index.mdx b/apps/docs/content/docs/keyboard-shortcuts/index.mdx index f0aebc459a0..778fa9dd122 100644 --- a/apps/docs/content/docs/keyboard-shortcuts/index.mdx +++ b/apps/docs/content/docs/keyboard-shortcuts/index.mdx @@ -1,95 +1,103 @@ --- -title: Keyboard Shortcuts -description: Keyboard and mouse shortcuts for the workflow editor and for tables. +title: Keyboard shortcuts +description: Keyboard and pointer controls for workspace navigation, workflows, and tables. --- -import { Callout } from 'fumadocs-ui/components/callout' +`Mod` means `Cmd` on macOS and `Ctrl` on Windows and Linux. Editing shortcuts act on the focused surface. Some workspace commands also work while you are typing; an editor can keep a shortcut it owns. -Sim has keyboard shortcuts for the workflow editor and for tables. Each set works when that surface is focused and you are not typing in a field. The macOS app adds its own window, tab, and navigation shortcuts on top of these — see [Sim Desktop](/desktop#keyboard-shortcuts). +The macOS app adds window, tab, and browser controls. See [Sim Desktop](/desktop#keyboard-shortcuts). - - **Mod** is `Cmd` on macOS and `Ctrl` on Windows and Linux. - +## Workspace navigation -## Workflow editor +| Shortcut | Action | +| --- | --- | +| `Mod` + `K` | Open search | +| `Mod` + `B` | Collapse or expand the sidebar, outside an editable field | +| `Mod` + `Shift` + `P` | Create a workflow, outside an editable field | +| `Mod` + `L` | Open Logs; a focused Desktop browser uses it for the address bar | -### Mouse +## Workflow builder -| Action | Control | -|--------|---------| -| Pan the canvas | Middle-drag, left-drag in Hand mode, or scroll / trackpad | -| Select multiple blocks | `Shift` + drag on empty space, or left-drag in Select mode | -| Drag a block | Left-drag on the block header | -| Add to selection | `Mod` / `Shift` + click on blocks | +### Keyboard actions -### Actions +Keep focus outside an editable field for running, clipboard, history, layout, and Toolbar shortcuts. | Shortcut | Action | -|----------|--------| -| `Mod` + `Enter` | Run the workflow (or cancel if running) | +| --- | --- | +| `Mod` + `Enter` | Run the workflow, or stop it while running | +| `Mod` + `Shift` + `A` | Add an Agent block to the active workflow | | `Mod` + `Z` | Undo | | `Mod` + `Shift` + `Z` | Redo | | `Mod` + `C` / `X` / `V` | Copy / cut / paste selected blocks | -| `Delete` or `Backspace` | Delete selected blocks or edges | -| `Shift` + `L` | Auto-layout the canvas | -| `Mod` + `Shift` + `F` | Fit to view | -| `Mod` + `F` | Search and replace in the workflow | -| `Mod` + `Shift` + `Enter` | Accept Copilot changes | -| `Mod` + `Alt` + `F` | Focus the Toolbar search | +| `Delete` or `Backspace` | Delete selected blocks or connections | +| `Shift` + `L` | Auto-layout the workflow | +| `Mod` + `Shift` + `F` | Fit the workflow to the view | +| `Mod` + `F` | Open workflow search and replace | +| `Mod` + `Shift` + `Enter` | Accept Sim's proposed workflow changes | +| `Mod` + `Alt` + `F` | Open Toolbar and focus its search | +| `Mod` + `D` | Clear the workflow console; persisted run logs remain | + +### Pointer controls + +| Task | Control | +| --- | --- | +| Pan the builder | Middle-drag, left-drag in Hand mode, or scroll / use a trackpad | +| Select multiple blocks | Left-drag on empty space in Select mode, or `Shift` + drag in Hand mode | +| Move a block | Left-drag its header | +| Add blocks to the selection | `Mod` or `Shift` + click | ## Tables -These work when a table is focused and no cell is being edited. +Select a cell and keep the table focused. Navigation and selection shortcuts apply while no cell is being edited. Editing, cut, paste, clearing cells, and adding rows require the corresponding permissions; table locks can prevent changes. ### Navigation | Shortcut | Action | -|----------|--------| +| --- | --- | | Arrow keys | Move one cell | | `Mod` + Arrow keys | Jump to the edge of the table | | `Tab` / `Shift` + `Tab` | Move to the next / previous cell | -| `Escape` | Clear the selection | +| `Escape` | Close table find if open; otherwise clear the selection | ### Selection | Shortcut | Action | -|----------|--------| +| --- | --- | | `Shift` + Arrow keys | Extend the selection by one cell | | `Mod` + `Shift` + Arrow keys | Extend the selection to the edge | | `Shift` + `Space` | Select the current row | | `Mod` + `Space` | Select the current column | +| `Mod` + `A` | Select all table rows; press again to clear the selection | ### Editing | Shortcut | Action | -|----------|--------| -| `Enter` or `F2` | Start editing the selected cell | -| Any character | Start editing with that character | -| `Escape` | Cancel editing | -| `Shift` + `Enter` | Insert a new row below | -| `Space` | Expand row details | +| --- | --- | +| `Enter` or `F2` | Open the selected cell's editor; toggle a boolean cell | +| Any character | Start editing the selected cell with that character | +| `Escape` | Cancel the current edit | +| `Shift` + `Enter` | Insert a row below; open the new-row form when required fields need values | +| `Space` | Open the selected row's editor | +| `Mod` + `D` | Fill selected cells down from the top of the selection | -### Clipboard +### Clipboard and history | Shortcut | Action | -|----------|--------| +| --- | --- | | `Mod` + `C` / `X` / `V` | Copy / cut / paste cells | -| `Delete` or `Backspace` | Clear the selected cells | +| `Delete` or `Backspace` | Clear selected cells | +| `Mod` + `Z` | Undo | +| `Mod` + `Y` | Redo | -### History +### Find | Shortcut | Action | -|----------|--------| -| `Mod` + `Z` | Undo | -| `Mod` + `Shift` + `Z` or `Mod` + `Y` | Redo | +| --- | --- | +| `Mod` + `F` | Open table find | +| `Escape` | Close table find | -## Global +## Related docs -| Shortcut | Action | -|----------|--------| -| `Mod` + `K` | Open search | -| `Mod` + `Shift` + `A` | Create a new agent | -| `Mod` + `Shift` + `P` | Create a new workflow | -| `Mod` + `L` | Go to logs | -| `Mod` + `D` | Clear the terminal console | -| `Mod` + `B` | Collapse / expand the sidebar | +- [Quick reference](/quick-reference) +- [Tables](/tables) +- [Sim Desktop](/desktop#keyboard-shortcuts) diff --git a/apps/docs/content/docs/knowledgebase/chunking-strategies.mdx b/apps/docs/content/docs/knowledgebase/chunking-strategies.mdx index 7ce25cf3b5f..949371f5109 100644 --- a/apps/docs/content/docs/knowledgebase/chunking-strategies.mdx +++ b/apps/docs/content/docs/knowledgebase/chunking-strategies.mdx @@ -1,120 +1,144 @@ --- title: Chunking strategies -description: The chunking settings and strategies, for the rare case you need to override Auto. +description: Choose passage sizes and boundaries for knowledge base documents. --- -import { Callout } from 'fumadocs-ui/components/callout' -import { FAQ } from '@/components/ui/faq' +**Auto** is the default chunking strategy. Start with its default settings, inspect the chunks returned by real questions, then change settings when passages combine unrelated topics or lose needed context. - -**Advanced.** Leave the strategy on **Auto** and the settings on their defaults unless you have a specific reason to change them and know how chunk boundaries affect retrieval. Auto inspects each file and routes it to the right chunker on its own. The rest of this page is for the case where you've confirmed Auto isn't producing the chunks you want. - +Choose a different strategy when you need specific boundaries: -If you do override Auto, the short version: - -- Sentence integrity matters (Q&A, legal text) → **[Sentence](#sentence)** -- Content has structural markers Text misses (code, custom formats) → **[Recursive](#recursive)** -- You need uniform chunk sizes → **[Token](#token)** -- Content has explicit delimiters → **[Regex](#regex)** -- Each record must be its own chunk → **[convert to JSONL](#one-record-per-chunk)** +| Need | Strategy | +| --- | --- | +| General prose | [Text](#text) | +| Custom structure or code markers | [Recursive](#recursive) | +| Whole sentences where possible | [Sentence](#sentence) | +| A fixed sliding window | [Token](#token) | +| Explicit delimiters | [Regex](#regex) | +| Structured records | [Auto with JSONL](#one-record-per-chunk), with batching and oversized-record limits | ## Settings -| Setting | Unit | Default | Range | Description | -|---------|------|---------|-------|-------------| -| Max Chunk Size | tokens | 1,024 | 100–4,000 | Upper bound on chunk size. 1 token ≈ 4 characters. | -| Min Chunk Size | characters | 100 | 100–2,000 | Tiny fragments below this are dropped. | -| Overlap | tokens | 200 | 0–500 | Tokens repeated between adjacent chunks to preserve context. | +Set these values when creating a base: + +| Setting | Unit | Default | Range | Behavior | +| --- | --- | --- | --- | --- | +| **Max Chunk Size** | Estimated tokens | 1,024 | 100–4,000 | Size target before overlap; splitters can append overlapping text afterward. | +| **Min Chunk Size** | Characters | 100 | 1–2,000 | Minimum fragment size in strategies that apply it; it is not enforced by every splitter. | +| **Overlap** | Estimated tokens | 200 | 0–500 | Context repeated between adjacent chunks in strategies that support overlap. | + +Overlap must be smaller than Max Chunk Size. Min Chunk Size must be smaller than Max Chunk Size converted to characters (`maxSize × 4`). + +The prose splitters estimate one token as roughly four characters. Tabular chunking uses a denser estimate of roughly three characters per token. These estimates guide splitting; they are not exact model-tokenizer counts. -[Pinecone's chunking guide](https://www.pinecone.io/learn/chunking-strategies/) covers the size and overlap tradeoffs. +Text, Recursive, Sentence, and Regex retain small fragments rather than applying the minimum-size filter. Token can filter small windows, with a fallback that retains them when filtering would remove every window. JSON/YAML applies the minimum in some paths; tabular chunking groups rows independently of this setting. -Every strategy splits the document at boundaries, then packs adjacent splits together up to the max chunk size, so a chunk usually spans several splits and a split boundary is not a chunk boundary. This is why a precise [Regex](#regex) can still produce chunks containing multiple matches. +Overlap increases stored text and can produce similar hits from neighboring chunks. Text, Recursive, and non-strict Regex append overlap after forming chunks, so the final chunk can exceed the base size target. Token uses overlapping windows, and Sentence tries to repeat whole sentences. -## Strategies +## Auto -### Auto +Auto chooses from the parsed document type, MIME type, and tabular content shape: -Sim inspects the file and routes to the right chunker: +- JSON, JSONL, and YAML use structural chunking when they parse as objects or arrays. +- CSV and Excel content is grouped by row with headers preserved. Delimited text can also be detected as tabular content. +- Other content, including ordinary PDF, Word, text, Markdown, HTML, and PowerPoint documents, uses Text. -- `.json`, `.jsonl`, `.yaml`, `.yml` → structural chunking (records are never split mid-way; small records may still be batched together up to the chunk size) -- `.csv`, `.xlsx`, `.xls`, `.tsv` → grouped by row, with headers preserved -- Everything else (`.pdf`, `.docx`, `.txt`, `.md`, `.html`, `.pptx`, …) → Text strategy +Use `.json`, `.jsonl`, `.yaml`, or `.yml` when you need structural parsing. A plain `.txt` upload is not automatically treated as JSON just because it contains valid JSON. `.tsv` is not an offered knowledge-base upload extension; use an accepted format such as `.csv`. -Routing is based on detected MIME type and content shape, not just the extension — a `.txt` file containing valid JSON is still routed structurally. +Structural chunking keeps records together when they fit, batches small records, and splits oversized records or rows. Auto is not a guarantee of one record per chunk. -Pick Auto unless you've confirmed it isn't producing the chunks you want. +## Text -### Text +Text splits general prose using a separator hierarchy: -Hierarchical splitter that walks down a separator list: horizontal rules → markdown headings → paragraphs (`\n\n`) → lines (`\n`) → sentence punctuation (`. ! ?`) → clause punctuation (`; ,`) → spaces. It tries the largest separator first and falls back when a piece is still too large. +Horizontal rules → Markdown headings → paragraphs (`\n\n`) → lines (`\n`) → sentence punctuation (`. `, `! `, `? `) → clause punctuation (`; `, `, `) → spaces. +It tries larger structural boundaries first and falls back when a piece is too large. Adjacent pieces can be packed together up to the size target before overlap is added. +## Recursive -Use it for general prose. +Recursive uses the same approach with a separator hierarchy you provide. For example, split code on `\nclass `, then `\nfunction `, then `\n\n`. -### Recursive +Enter custom separators in the creation form. The v2 API also accepts the built-in `plain`, `markdown`, and `code` recipes through `strategyOptions.recipe` with `strategy: "recursive"`. Use Recursive when your content has markers the Text hierarchy misses. -Same algorithm as Text, but you supply your own separator hierarchy or pick a built-in recipe (`plain`, `markdown`, `code`). +## Sentence +Sentence splits at sentence boundaries, with abbreviation handling, then packs whole sentences up to the size target. A sentence that exceeds the target is split at word boundaries. +Use it when an incomplete sentence would change the meaning, such as Q&A or legal text. Overlap prefers whole sentences; when none fits, it falls back to a text tail. -Use Recursive when your content has structural markers the default Text separators miss — splitting code on `\nclass `, `\nfunction `, then `\n\n`, for example. +## Token -### Sentence +Token uses a fixed sliding window aligned to word boundaries. It does not recognize paragraphs or sentences, and its token sizes are estimates rather than exact tokenizer counts. -Splits on sentence boundaries (`. `, `! `, `? `, with abbreviation handling) and packs whole sentences up to the chunk size. A sentence is never split mid-way unless it individually exceeds the limit. +Use it when a regular window is more useful than structural boundaries. +## Regex +Regex splits text at a pattern you supply, then normally packs adjacent segments up to the size target. A pattern such as `(?=\n\s*\{\s*"id"\s*:)` can find record boundaries, but small segments can still share a chunk. -Use it when sentence integrity matters — Q&A, legal text, or anything where mid-sentence cuts hurt comprehension. +A consuming delimiter is removed from the split text. Positive lookaround preserves it: `(?=X)` splits before `X`, and `(?<=X)` splits after it. -### Token +Patterns can be up to **500 characters**. Negative lookaround, backreferences, and repeat counts above **1,000** are unsupported. Positive lookaround is supported. -Fixed-size sliding window aligned to word boundaries. No awareness of paragraphs or sentences. +### Strict boundaries -LlamaIndex provides the same as `TokenTextSplitter`. Useful when downstream processing requires uniform chunk sizes; otherwise prefer Text or Sentence. +Enable **Each match is its own chunk (don't merge)** under **Chunk Boundaries** to keep each nonempty segment separate: -### Regex +- Adjacent segments are not merged. +- Overlap is disabled. +- Oversized segments produced by a successful split are divided at word boundaries. -Splits on every match of a regex pattern you supply, then packs splits up to the chunk size by default — the same merge behavior as every other chunker. A precise boundary regex like `(?=\n\s*\{\s*"id"\s*:)` will still produce chunks containing multiple matches if those matches are small enough to fit together. This is standard across LangChain, LlamaIndex, Chonkie, and [Unstructured](https://docs.unstructured.io/api-reference/partition/chunking-documents). +The checkbox refers to the segments separated by matches, not to returning only the matched delimiter text. -Use Regex when your content has explicit delimiters that don't fit any other strategy. +For example, given: -#### Strict boundaries +```text +Question: How long do refunds take? +Answer: Refunds are issued within 14 days. -The regex strategy has an opt-in **"Each match is its own chunk (don't merge)"** checkbox. When enabled: +Question: Where can I find invoices? +Answer: Open Billing in workspace settings. +``` -- Every regex match becomes its own chunk -- Adjacent splits are not packed together -- Overlap is disabled -- Splits that exceed the chunk size are still sub-split at word boundaries +Use this pattern to split before the next question while retaining its label: +```text +(?=\nQuestion:) +``` +With strict boundaries enabled, each question-and-answer segment is separate, provided it fits the size target. Check the generated chunks to confirm the pattern matches your actual source. -Turn it on when each match is a discrete record (one QA pair, one log entry) and you need each isolated for retrieval. +### If the pattern does not split + +The prose splitters normalize text before splitting: + +- `\r\n` and lone `\r` become `\n`. +- Three or more newlines become `\n\n`. +- Tabs become spaces, and repeated spaces collapse to one. + +Adjust patterns that depend on the original whitespace. In non-strict mode, content that already fits the size target returns as one chunk without applying the pattern. If an oversized document produces no splits, non-strict mode falls back to word boundaries; strict mode returns it as a single chunk. Fix the pattern before relying on strict record boundaries. ## One record per chunk -Each record (each QA pair, each log line, each row) as its own chunk is structural chunking, not regex chunking. Two paths: +For structured input, JSONL makes record boundaries explicit: + +```json title="records.jsonl" +{"id":"refunds","question":"How long do refunds take?","answer":"Within 14 days."} +{"id":"invoices","question":"Where can I find invoices?","answer":"In Billing settings."} +``` -1. **Convert to JSONL** (one record per line) and upload. Sim's Auto strategy treats it as structured data and never splits a record mid-way. Small records may still be batched together up to the chunk size. Lowering the size reduces batching; use strict Regex boundaries when each match must become its own chunk. See [LlamaIndex's `JSONNodeParser`](https://docs.llamaindex.ai/en/stable/module_guides/loading/node_parsers/) and [Unstructured's element-based chunking](https://docs.unstructured.io/api-reference/partition/chunking-documents). +Auto can batch these small records into one chunk. Lowering Max Chunk Size reduces batching, but records that exceed the target can still be split. Use strict Regex boundaries when each delimited segment must stay separate, subject to its oversized-segment behavior. -2. **Use Regex with strict boundaries enabled** when you can't restructure the source. +Structural parsing is useful for nested records and escaped values. It does not guarantee recovery of malformed entries; inspect parsing errors and the resulting chunks. -Prefer option 1. Structural parsers handle nested records, escaped delimiters, and malformed entries that regex won't. +## Change settings on an existing base -## Further reading +The UI selects the strategy at creation and displays existing chunking settings as read-only. To use a different strategy through the UI, create a base with that strategy and upload the documents again. -- [LangChain — Text Splitters](https://python.langchain.com/docs/concepts/text_splitters/) -- [LlamaIndex — Node Parsers](https://docs.llamaindex.ai/en/stable/module_guides/loading/node_parsers/) -- [Chonkie](https://github.com/chonkie-inc/chonkie) -- [Unstructured — Chunking](https://docs.unstructured.io/api-reference/partition/chunking-documents) -- [Pinecone — Chunking Strategies](https://www.pinecone.io/learn/chunking-strategies/) +The [Update knowledge base API](/api-reference/knowledge-bases/updateKnowledgeBase) can change the sizes, overlap, strategy, and strategy options. It replaces the configuration object rather than merging it: read the current configuration, change the intended fields, and send back every setting you want to retain. Omitted size fields take their defaults, and an omitted strategy uses Auto. Changed settings apply to later document processing; existing chunks are not automatically rebuilt. -## FAQ +## Related docs - +- [Debugging retrieval](/knowledgebase/debugging-retrieval) — decide whether the problem comes from chunk boundaries. +- [Using a knowledge base in a workflow](/knowledgebase/using-in-workflows) — inspect retrieved content and order. +- [Knowledge Base](/knowledgebase) — supported uploads and processing. diff --git a/apps/docs/content/docs/knowledgebase/connectors.mdx b/apps/docs/content/docs/knowledgebase/connectors.mdx index aa2f2e03144..905b61ac805 100644 --- a/apps/docs/content/docs/knowledgebase/connectors.mdx +++ b/apps/docs/content/docs/knowledgebase/connectors.mdx @@ -1,225 +1,234 @@ --- title: Connectors -description: Automatically sync documents from external sources into your knowledge base +description: Sync external documents into a knowledge base and manage their access and lifecycle. --- import { Callout } from 'fumadocs-ui/components/callout' import { Step, Steps } from 'fumadocs-ui/components/steps' -import { Image } from '@/components/ui/image' -import { FAQ } from '@/components/ui/faq' -For organization Search with each person's source permissions, use the [Search connector guides](/search). This page covers connectors inside general knowledge bases. +Connectors sync documents from external services into a knowledge base. New content is indexed, changed content is reprocessed, and content removed from the selected source scope leaves search after reconciliation. -Connectors continuously sync documents from external services into your knowledge base, so you never have to upload files manually. New content is added, changed content is re-processed, and deleted content is removed — all automatically. +This guide covers indexed knowledge bases. [Organization Search](/search) has its own live-provider catalog and queries supported providers on demand; adding a knowledge-base connector does not enable it there. -This page covers indexed workspace knowledge bases. [Organization Search](/search) has a separate live-provider catalog and queries its supported providers on demand; adding a knowledge-base connector does not automatically enable it in Search. +## Choose a connection method -## Available Connectors +Creating a connection requires workspace write access. For supported providers, **Connection method** controls who can search imported documents: -The current Connect Source picker showing searchable connectors including Airtable, Asana, Ashby, Azure DevOps, Bitbucket, Box, and ClickUp +| Method | Access | +| --- | --- | +| **Workspace** | Everyone with access to the workspace can search the synced documents. The connection does not mirror each person's source permissions. | +| **Member accounts** | Members sync through their connected accounts; source access determines which documents they can read. | +| **Admin or service account** / **Service account** | An administrative credential syncs content and supported source permissions. | -Sim ships with 66 built-in connectors: +The available methods depend on the provider and deployment configuration. A workspace Admin must configure permission-aware methods or switch a connection out of Workspace mode. The [Search source guides](/search) explain provider-specific permission setup. -| Category | Connectors | -|----------|-----------| -| **Productivity** | Coda, Notion, Confluence, Asana, Linear, Jira, Jira Service Management, Monday, Trello, ClickUp, Google Calendar, Google Sheets, Google Forms, Microsoft Excel, Typeform | -| **Cloud Storage** | Google Drive, Dropbox, OneDrive, SharePoint, Box, Amazon S3, SFTP | -| **Documents** | Google Docs, Google Slides, Mintlify, WordPress, Webflow, DocuSign | -| **Development** | GitHub, GitLab, Bitbucket, Azure DevOps, Sentry | -| **Communication** | Slack, Discord, Microsoft Teams, Google Chat, Reddit, X, YouTube | -| **Email** | Gmail, Outlook | -| **CRM** | HubSpot, Salesforce | -| **Support** | Intercom, ServiceNow, Zendesk, Zoho Desk | -| **Incident Management** | incident.io, Rootly, PagerDuty | -| **Data** | Airtable, Databricks | -| **Note-taking** | Obsidian | -| **Meetings** | Zoom, Google Meet, Gong, Grain, Granola, Fathom, Fireflies, Circleback | -| **Recruiting** | Greenhouse, Ashby | -| **HR** | Workday Help | -| **Compliance** | Google Vault | - -## Adding a Connector - -From inside a knowledge base, click **+ New connector** in the top right to open the connector picker. Select a service, then complete the setup steps: +For GitLab in Workspace mode, a PAT with `read_api` and access to the selected project is enough. The administrator-token and non-admin CSV permission paths apply to its permission-aware method; see [GitLab](/search/gitlab). + +## Create a connection + +Open a knowledge base, choose **New connector**, and select the service. ### Authenticate -Most connectors use **OAuth** — select an existing credential from the dropdown or click **Connect new account** to authorize through the service. Tokens are refreshed automatically. - -Other connectors use **API keys** or **personal access tokens** instead. The setup modal tells you which credential each connector expects — for example: - -| Connector | Where to get the key | -|-----------|---------------------| -| **Obsidian** | Install the [Local REST API](https://github.com/coddingtonbear/obsidian-local-rest-api) plugin, then copy the key from its settings | -| **Coda** | API token from Account settings → API connections, saved as a Coda service account credential | -| **Fireflies** | Generate from the Integrations page in your Fireflies account | -| **Typeform** | Personal access token from your Typeform account settings | -| **Azure DevOps** | Personal access token with Wiki (Read), Work Items (Read), and Code (Read) scopes | -| **GitLab** | Personal access token with `read_api` scope and access to the selected project | -| **YouTube** | YouTube Data API key from the Google Cloud Console | -| **Amazon S3** | Secret Access Key (the Access Key ID, region, and bucket are entered as config fields) | -| **Sentry** | Auth token with `project:read` and `event:read` scopes | -| **PagerDuty** | REST API key from Integrations → API Access Keys | -| **SFTP** | Password or unencrypted private key, plus a required SHA-256 host key fingerprint (host, port, username, and root path are entered as config fields) | -| **Mintlify** | API key — optional for public documentation sites, which sync from `llms.txt` | -| **Databricks** | Personal access token from your workspace's user settings (the workspace host is entered as a config field) | -| **Workday Help** | Register an API client for integrations in your tenant, then enter the client secret and refresh token together as `clientSecret:refreshToken` (the client ID, tenant host, and tenant name are entered as config fields) | - -Enter an API key directly, or type `{{` to select an accessible personal or workspace secret. Sim resolves the secret when you connect and stores an encrypted copy of the token. Later changes to the secret do not automatically update the connector. +For OAuth, select an accessible credential or choose **Connect <service> account**. The account picker can offer **Connect another <service> account** when accounts already exist. OAuth tokens refresh automatically while the grant remains valid. - - If you rotate an API key in the external service, update it in Sim as well — OAuth tokens refresh automatically, but API keys do not. - +API-key and personal-access-token connections use the credential shown in their setup field. These examples identify the credential and any required companion fields: -For GitLab in a regular knowledge base, a project-readable PAT is enough. Imported content uses the knowledge base's access rules; it does not mirror each person's GitLab permissions. The administrator-token and non-admin CSV setup paths apply when using [GitLab source permissions](/search/gitlab). +| Connector | Credential or prerequisite | +| --- | --- | +| Obsidian | Install the [Local REST API](https://github.com/coddingtonbear/obsidian-local-rest-api) plugin and copy its API key from the plugin settings. | +| Coda | Generate an [API token](https://help.coda.io/hc/en-us/articles/39763414725389-Manage-your-Coda-account-settings) under **Account settings → API settings**; save it as a Coda service account credential. | +| Fireflies | Copy the API key from **Settings → Developer settings** ([setup guide](https://guide.fireflies.ai/articles/3737786777-learn-about-fireflies-api)). | +| Typeform | Generate a [personal access token](https://help.typeform.com/hc/en-us/articles/13599952215572-Typeform-API-personal-access-token) under **Your settings → Personal tokens**. | +| Azure DevOps | PAT with Project and Team Read, Wiki Read, Work Items Read, and Code Read. | +| GitLab | PAT with `read_api` and access to the selected project; permission-aware methods have additional requirements. | +| YouTube | YouTube Data API key from Google Cloud Console. | +| Amazon S3 | Secret Access Key; enter Access Key ID, region, and bucket as configuration fields. | +| Sentry | Auth token with `project:read` and `event:read`. | +| PagerDuty | Create a [REST API key](https://support.pagerduty.com/main/docs/api-access-keys) under **Integrations → Developer Tools → API Access Keys**. | +| SFTP | Password or unencrypted private key, plus a required SHA-256 host-key fingerprint; enter host, port, username, and root path as configuration fields. | +| Mintlify | Access Token only when the documentation site needs a bearer token. Public sites can sync from `llms.txt` without one. | +| Databricks | Create a [personal access token](https://docs.databricks.com/aws/en/dev-tools/auth/pat) under **Settings → Developer → Access tokens → Manage**; enter the workspace host separately. | +| Workday Help | Register an API client for integrations and enter `clientSecret:refreshToken`; configure client ID, tenant host, and tenant name separately. | + +Enter a key directly or type `{{` to select an accessible secret. A reference must be the whole value, such as `{{SOURCE_API_KEY}}`. Sim resolves it at setup and stores an encrypted token snapshot. Updating the secret later does not update that connection. + +If an OAuth grant is revoked, reconnect the account. API keys and PATs do not refresh automatically; a rotated directly entered key needs a replacement connection using the new key. For credentials managed as connected accounts or service accounts, update the credential through its supported account flow. Review the removal options for the old connection before replacing it. -### Configure - -Each connector has source-specific fields that control what gets synced. Examples: +### Configure the source -- **Notion** — sync an entire workspace, a specific database, or a single page tree -- **GitHub** — specify a repository, branch, and optional file extension filter -- **GitLab** — specify a project path or ID and your instance host (leave blank for GitLab.com), then choose repository files, wiki pages, issues, or merge requests. Each connector syncs one project; submodules need their own connectors. -- **Confluence** — enter your Atlassian domain and choose spaces, or **All** for all spaces accessible at each sync. Optionally filter by content type or label. PDF, Word (`.docx`, Word 97–2003 `.doc`), Excel (`.xlsx`), and PowerPoint (`.pptx`) attachments on matching pages and blog posts are included as separate documents, and so are PNG, JPEG, WebP, and GIF images when **Image Attachments** is on. -- **Azure DevOps** — choose what to sync (wiki pages, work items, repository files, or all), with optional work item type/state filters, a custom WIQL query, and repository/branch/path filters -- **Amazon S3** — point at a bucket with an optional key prefix and a customizable file extension allowlist; S3-compatible stores (Cloudflare R2, MinIO) are supported via a custom endpoint -- **YouTube** — sync a channel (by `@handle` or ID) or playlist, with an optional published-after date filter and the option to exclude Shorts -- **Sentry** — filter issues by search query (e.g. `is:unresolved`), environment, and time window; self-hosted Sentry is supported via a custom host -- **Obsidian** — provide your vault URL (`https://127.0.0.1:27124` by default) and optionally restrict to a folder path -- **Fireflies** — optionally filter by host email or cap the number of transcripts synced +Fill in the service's source fields. Examples: -Configuration is validated on save — if a repository doesn't exist or a domain is unreachable, you'll see an error immediately. +- **Notion:** choose a workspace, database, or page tree. +- **GitHub:** specify a repository, branch, and optional file-extension filter. +- **GitLab:** select one project by path or ID and an instance host, or leave the host blank for GitLab.com in Workspace mode. Choose repository files, wiki pages, issues, or merge requests. Submodules need separate connections. +- **Confluence:** enter the Atlassian site and select spaces, or **All** for spaces accessible at each sync. Filter by content type or label if needed. See [Confluence attachments](#confluence-attachments) for files and images. +- **Azure DevOps:** choose wiki pages, work items, repository files, or all. Optional fields include work-item type/state, a WIQL query, and repository/branch/path filters. +- **Amazon S3:** choose a bucket, optional key prefix, and file-extension allowlist. A custom endpoint supports S3-compatible stores such as Cloudflare R2 or MinIO. +- **YouTube:** choose a channel by `@handle` or ID, or a playlist. Optional filters include published-after date and **Exclude Shorts**, which skips videos shorter than 60 seconds. +- **Sentry:** set a query such as `is:unresolved`, environment, or time window. A custom host supports self-hosted Sentry. +- **Obsidian:** enter the vault URL and, optionally, a folder path. The plugin's local default is `https://127.0.0.1:27124`. +- **Fireflies:** optionally filter by host email or cap the transcript count. -Confluence attachment indexing requires `read:attachment:confluence`. For a service account, include it when creating the scoped API token; see the [Confluence scope list](/search/confluence#using-a-service-account). Attachments are checked even when the parent page has not changed. Files over 100 MB appear as skipped; convert Word 6/95 files to `.docx`, and `.xls` and `.ppt` files to `.xlsx` and `.pptx`, before attaching them. Spaces that were already connected pick up newly supported formats on their next sync. + +Sim Cloud cannot connect to localhost or private-network vault URLs. An Obsidian connection needs an allowed public HTTPS endpoint. On self-hosted deployments, the vault must be reachable from the Sim server and allowed by its [outbound-network policy](/platform/self-hosting/security#the-ssrf-boundary). + -Each image is read once by a vision model, which writes out what it holds: a table becomes one line per row with its column headers, a scan becomes its full text, and a screenshot or diagram becomes its visible text plus a description of what it shows. That text is what search finds. Logos, icons, and other decorative images are kept as documents but have nothing to search, so they show 0 chunks. Images under 2 KB, SVG, and HEIC files are not indexed. Image reading uses a Gemini key: the workspace's own key when one is added, otherwise the platform's, and each image is billed as a model call. Without any Gemini key, images are left out of the sync until one is added. One sync reads at most 500 new or changed images, and the rest are picked up by the next sync; a full resync does not read unchanged images again. New Confluence connectors read images by default. Connectors created before image support keep images off until you set **Image Attachments** to **Read with AI** in the connector's settings; the next sync then reads them. To stop indexing images, set it to **Don't index**: the next sync removes the images already indexed, and switching back reads them again, billed per image. +Sim validates source configuration when saving. A missing repository, inaccessible source, or invalid configuration can fail setup; permission-aware member syncing can also discover per-account failures during a later sync. -### Choose sync frequency +### Choose the sync frequency -| Frequency | Notes | -|-----------|-------| -| Every hour | Best for fast-moving sources | -| Every 6 hours | Good balance for most sources | -| **Daily** (default) | Suitable for content that changes infrequently | -| Weekly | For stable, rarely-updated sources | -| Manual only | Sync only when you trigger it manually | +| **Sync Frequency** | Interval | +| --- | --- | +| **Live** | Every 5 minutes. | +| **Every hour** | Every 60 minutes. | +| **Every 6 hours** | Every 360 minutes. | +| **Daily** | Every 1,440 minutes; the default. | +| **Weekly** | Every 10,080 minutes. | +| **Manual only** | No scheduled content sync; use **Sync now**. | -Sub-hourly frequencies require a Max or Enterprise plan. +Sub-hourly syncing requires usable Max or Enterprise access on hosted workspaces with billing enabled. Self-hosted or billing-disabled workspaces do not have that plan gate. + +Permission-aware methods can check permissions hourly even when the content schedule is longer. With Manual only, documents can become unavailable after 24 hours without a successful permission check. Read the schedule hint shown for the selected connection method. -### Configure metadata tags (optional) +### Select metadata tags + +If the connector exposes **Metadata tags**, uncheck fields you do not need. Setup enables them by default. For example, Notion can populate Labels and Last Modified; GitHub can populate Repository and File Path. -If the connector supports metadata tags, you'll see checkboxes for each available tag type (e.g., Labels, Last Modified, Notebook). All are enabled by default — uncheck any you don't need. +Tags share the base's [17-slot capacity](/knowledgebase/tags). Compatible existing definitions can be reused; new ones consume slots. When capacity is exhausted, some metadata can be omitted, or setup can fail if none of the selected tags can be mapped. Uncheck optional fields or review existing definitions before retrying. -Tag slots are shared across all documents in a knowledge base. See [Tags](/knowledgebase/tags) for details. +Choose tags before connecting: the Settings tab does not offer a metadata-tag editor, and changing source configuration does not automatically free existing definitions' slots. -### Connect & Sync +### Connect and verify + +Choose **Connect & Sync** to save the connection and queue its first sync. Documents appear as they are fetched and processed; they become searchable only after indexing completes and the caller has access. -Click **Connect & Sync** to save the connector and trigger the first sync. Documents will start appearing as they're processed. +Open **Connected Sources** to check the connection's status and sync history. If the initial sync could not be queued, follow its error and start **Sync now** after correcting the cause. -## Managing Connectors - -Open **Connected Sources** from the knowledge base to see all active connectors. Each card shows the connector's status, the last sync time and document count, and the next scheduled sync: - -Connected Sources panel showing a Google Docs connector with Active status, last sync details, and a sync history log with dated entries +## Manage a connection -The action buttons on each connector card: +**Connected Sources** shows the connected service, status, document count, and available last/next sync details. Open **Connection actions** for: -| Button | Action | -|--------|--------| -| **↻** (Refresh) | Trigger a manual sync immediately. Disabled while syncing or disabled; a 5-minute cooldown applies after each manual trigger | -| **⚙** (Settings) | Open the edit modal to change source config or sync frequency | -| **⏸ / ▶** (Pause / Resume) | Pause scheduled syncs without removing the connector. Resume works from both paused and disabled states | -| **🗑** (Delete) | Remove the connector. A confirmation modal appears with an option to also delete all synced documents | -| **∨** (Chevron) | Expand to show sync history | +| Action | Effect | +| --- | --- | +| **Sync now** | Queue a manual sync. Unavailable while queued or syncing; resume paused or disabled connections first. | +| **Settings** | Edit source configuration or sync frequency and open the Documents tab. | +| **Pause syncing** / **Resume syncing** | Stop or resume scheduled syncing. A paused connection must be resumed before a manual sync. | +| **Sync history** / **Hide history** | Show or hide recent sync runs. | +| **Remove connection** | Stop syncing and remove the connection, subject to its document-removal options. | -### Editing a Connector +After a healthy sync completes with no failed documents, a **one-minute cooldown** applies before another manual sync. Error recovery and failed runs bypass that cooldown. -Click the settings icon to open the edit modal. It has two tabs: +Before removing a connection, review its document consequence. In Workspace mode, **Also delete synced documents** is optional; otherwise the documents remain as plain documents. Permission-aware connections require deletion of their synced documents when removed. Logical removal can finish before physical storage cleanup completes. -**Settings** — change any source-specific config fields (e.g., switch the GitHub branch) and update the sync frequency. +### Sync history -**Documents** — browse all documents this connector has synced and manage exclusions (see [Excluding Documents](#excluding-documents) below). +History shows the latest **10 runs**, with time, state, document-change counts, and error or notice details. Counts identify documents added, updated, deleted, failed, or skipped; **No changes** means no content changes were recorded. -### Sync History +**In progress…** means work is running. **Continuing** can mean a large listing is resuming across runs rather than failing. **Partial**, **Failed**, or **Interrupted** entries need their accompanying notice or error inspected. Member-account connections also report member sync progress and accounts that need reconnecting. -Expand any connector card by clicking the chevron to see a log of recent syncs: +## Exclude documents -- Each row shows the date/time and a summary of what changed: **+N** (added, green), **~N** (updated, amber), **-N** (deleted, red), **!N** (failed, red), or **No changes** -- A spinner indicates a sync currently in progress -- Error rows show a red icon and the failure message +1. Open **Settings** for the connection and select **Documents**. +2. Use the document-status picker to inspect **Included**, **Excluded**, **Failed**, or **Skipped** documents. +3. Select **Exclude** on a document to remove it from search and skip it on later syncs, even if the source changes. -The log retains the most recent 10 sync runs. +To reverse this, select **Excluded** and choose **Restore**. Retained completed content can become available again; the next sync refreshes it from the source. For failed or skipped documents, read the reason and fix the source or configuration. Retry failed documents when offered, or sync again after correcting skipped source content. -## Excluding Documents +## Sync behavior and recovery -Sometimes a connector syncs documents you don't want in your knowledge base — drafts, templates, confidential pages, and so on. You can exclude them individually. +A sync lists the selected source scope and compares it with stored content. New documents are processed; changed documents are re-chunked and re-embedded. Unchanged content usually avoids re-indexing, although the source may still be listed or read to verify changes and permissions. -Edit Google Docs modal showing the Documents tab with Active (37) and Excluded (0) filter buttons and a 'No excluded documents' message +A base can have multiple connections. Each owns its documents, and a Knowledge block can search their combined content within the caller's access. Their metadata definitions share the same tag slots. -To exclude a document, open the connector's settings modal, go to the **Documents** tab, and click **Exclude** next to any document. Excluded documents are skipped on every subsequent sync even if the source content changes. +### Content removed from the source scope -To reverse an exclusion, switch to the **Excluded** tab and click **Restore** — the document will be pulled in on the next sync. +Content deleted or removed from the selected source view leaves search after a successful reconciliation. Examples include: -## How Syncing Works +- Archived Confluence pages or Webflow CMS items. +- Asana tasks whose projects are all archived; a task still reachable through an active project remains included. +- Retired ServiceNow articles when no explicit workflow-state selection overrides the default. +- Files in Google Drive trash or Outlook messages in Deleted Items. +- Canceled incident.io incidents under the default filter; **All (including canceled)** or an explicit selection can include them. -On each run the connector fetches documents from the source and compares them against what's already stored. Only changed documents are reprocessed — new content is added, updated content is re-chunked and re-embedded, deleted content is removed. A connector syncing thousands of documents will only do real work when something actually changes. +An incomplete source listing keeps unlisted documents instead of treating them all as deleted. Incremental listings also do not prove that an unlisted item was removed. Restoring content at the source makes it eligible for a later sync; its document ID is not guaranteed to change. -### Content Removed From View +### Statuses -Content that still exists at the source but is no longer current is treated the same as deleted, and is removed from your knowledge base. This covers an archived Confluence page, a task in an archived Asana project, an archived Webflow CMS item, a retired ServiceNow knowledge article, a spreadsheet in the Google Drive trash, a message moved to Outlook's Deleted Items, and a cancelled incident.io incident. +| Status | Meaning | +| --- | --- | +| **Active** | Available for its schedule or manual sync. | +| **Pending** | A sync is queued. | +| **Syncing** | A sync is in progress. | +| **Paused** | Syncing is suspended; resume before starting another run. | +| **Error** | A sync failed. Read the error; scheduled retries use backoff. | +| **Disabled** | Syncing requires intervention, including after 10 consecutive full-sync failures. | -This keeps agents from citing content your team has already retired. Restoring the item at the source brings it back on the next sync as a new document. +A single-document failure can leave the rest of the sync running. Transient failures can be retried; unsupported or invalid content needs a source/configuration change. Read the Documents filters and history to distinguish failed indexing from a failed source listing. -### Connector Status +Full-sync failures increase the retry delay. After **10 consecutive failures**, the connection is disabled. Correct the source or credential issue, reconnect an invalid OAuth grant when needed, and choose **Resume syncing**. Resume alone does not repair a revoked credential. -| Status | Meaning | -|--------|---------| -| **Active** | Running normally on schedule | -| **Syncing** | A sync is currently in progress | -| **Paused** | Scheduled syncs are suspended; manual sync is still available | -| **Error** | The last sync failed; will retry on the next scheduled run with backoff | -| **Disabled** | Syncing has been paused automatically after 10 consecutive failures | +## Confluence attachments -A disabled connector requires intervention — either reconnect the OAuth account or use the Resume button to re-enable syncing. +Matching pages and blog posts include PDF, Word (`.docx` and Word 97–2003 `.doc`), Excel (`.xlsx`), and PowerPoint (`.pptx`) attachments as separate documents. Attachment indexing requires `read:attachment:confluence`; include it in a service account's scoped token. See [Confluence setup](/search/confluence#using-a-service-account). -### Handling Failures +Attachments are checked even when the parent page is unchanged. Files over **100 MiB** appear as skipped. Convert Word 6/95 files to `.docx`, `.xls` to `.xlsx`, and `.ppt` to `.pptx`. Existing connections pick up supported attachments on later syncs. -If a single document fails (e.g., a permission issue or timeout), the sync continues and retries that document next time. If an entire sync fails, the connector backs off and retries with increasing delays. After 10 consecutive full-sync failures the connector is automatically set to **Disabled** to avoid spinning indefinitely. +### Image attachments -## Metadata Tags +**Image Attachments → Read with AI** converts PNG, JPEG, WebP, and GIF attachments into searchable text. GIF extraction uses the first frame. Tables become rows with headers, scans become extracted text, and diagrams or screenshots include visible text and a description. Decorative images remain documents with zero chunks. -Connectors can auto-populate [tags](/knowledgebase/tags) with metadata from the source — for example, a Notion connector can tag documents with their Labels and Last Modified date; a GitHub connector can tag documents with Repository and File Path. These tags are then available for filtered search in the Knowledge block. +Images smaller than **2 KiB**, SVG, HEIC, and AVIF files are not indexed through this image path. It needs a Gemini key: an available workspace key first, otherwise the deployment's key. Without a key, images are deferred until one is configured. -You can disable specific tag types during setup or at any time from the connector settings to free up tag slots for manual tagging or other connectors. +New knowledge-base Confluence connections enable image reading by default. Connections created before image support keep it off until you choose **Read with AI**; their next sync then indexes images. - - Tag slots are shared across all documents in a knowledge base. If multiple connectors each populate tags, they draw from the same pool of 17 slots. - +The default admission limit is **500 new or changed images per sync**. Remaining images wait for another sync. Self-hosted operators can configure `KB_IMAGE_EXTRACTIONS_PER_SYNC`. Unchanged images reuse their extraction, including during a full resync; transient or malformed responses can cause additional model requests. -## Multiple Connectors +Image extraction follows [model billing](/platform/costs): BYOK usage is billed by the provider, while platform-key usage follows the deployment's Sim billing policy. Choose **Don't index** to stop image indexing; the next sync removes indexed images. Switching back processes them again and incurs the applicable model usage. -Knowledge base document list showing synced Google Docs documents with Name, Size, Tokens, Chunks, Uploaded date, Status, and Tags columns +## Available connectors -You can add as many connectors as you need to a single knowledge base. Each manages its own documents independently, and all content is searchable together through the Knowledge block. Keep tag slot usage in mind when combining connectors that each populate metadata tags. +The source picker lists the available services. Built-in connectors include: - +| Category | Connectors | +| --- | --- | +| Productivity | Coda, Notion, Confluence, Asana, Linear, Plane, Jira, Jira Service Management, Monday, Trello, ClickUp, Google Calendar, Google Sheets, Google Forms, Microsoft Excel, Typeform | +| Cloud storage | Google Drive, Dropbox, OneDrive, SharePoint, Box, Amazon S3, SFTP | +| Documents | Google Docs, Google Slides, Mintlify, WordPress, Webflow, DocuSign | +| Development | GitHub, GitLab, Bitbucket, Azure DevOps, Sentry | +| Communication | Slack, Discord, Microsoft Teams, Google Chat, Reddit, X, YouTube | +| Email | Gmail, Outlook | +| CRM | HubSpot, Salesforce | +| Support | Intercom, ServiceNow, Zendesk, Zoho Desk | +| Incident management | incident.io, Rootly, PagerDuty | +| Data | Airtable, Databricks | +| Note-taking | Obsidian | +| Meetings | Zoom, Google Meet, Gong, Grain, Granola, Fathom, Fireflies, Circleback, Otter | +| Recruiting | Greenhouse, Ashby | +| HR | Workday Help | +| Compliance | Google Vault | + +## Related docs + +- [Tags and filtering](/knowledgebase/tags) — definitions, slot capacity, and operators. +- [Debugging retrieval](/knowledgebase/debugging-retrieval) — verify indexed content and access. +- [Using a knowledge base in a workflow](/knowledgebase/using-in-workflows) — retrieve synced passages. +- [Organization Search](/search) — live providers and permission-aware source setup. diff --git a/apps/docs/content/docs/knowledgebase/debugging-retrieval.mdx b/apps/docs/content/docs/knowledgebase/debugging-retrieval.mdx index 84908c1839f..1e4166872cf 100644 --- a/apps/docs/content/docs/knowledgebase/debugging-retrieval.mdx +++ b/apps/docs/content/docs/knowledgebase/debugging-retrieval.mdx @@ -1,84 +1,91 @@ --- title: Debugging retrieval -description: Why a Knowledge block search returns no results, wrong results, or duplicates, and how to fix each one. +description: Check missing, irrelevant, or duplicate Knowledge block results. --- -import { Callout } from 'fumadocs-ui/components/callout' +Inspect the Knowledge block's output in [Logs](/logs-debugging) before changing the Agent's prompt. Check which chunks came back, whether they answer the question, and which documents they came from. -A [Knowledge block](/integrations/knowledge) search reads a query, embeds it as a vector, and returns the chunks of your documents that are closest to it. When the search misbehaves, it does so in one of three ways: it returns nothing, it returns the wrong chunks, or it returns the same content twice. Each one has a short list of causes you can check in the search results, in the document list, and in your tag filters. +## Read the results -## What a result looks like +A search returns a `results` array. An empty array means no eligible chunk was returned. For a populated result, inspect: -A search returns a `results` array. Each entry is one chunk of one document, with the fields you use to diagnose retrieval: - -| Field | What it is | +| Field | What to check | | --- | --- | -| `documentName` | The source document the chunk came from. | -| `sourceUrl` | Where the document was uploaded or synced from (`null` for manual uploads). | -| `content` | The chunk text that matched. | -| `chunkIndex` | The chunk's position in the document (`0` is the first chunk). | -| `similarity` | How close the chunk is to your query, `0` to `1` (higher is closer). | -| `rerankerScore` | An optional relevance score, present only when [Cohere reranking](/integrations/knowledge) is on. | -| `metadata` | The chunk's tag values, by their display names. | +| `content` | Does the passage contain the answer and enough context to interpret it? | +| `documentName`, `documentId` | Is this the intended source document? | +| `sourceUrl` | Open the external source when available; uploaded files without an external source have `null`. | +| `chunkIndex` | Find the passage within the document. Index `0` is the first chunk. | +| `metadata` | Compare the document's tag values, keyed by display name, with your filters. | +| `rank` | The result's one-based position in the returned order. | +| `rankScore` | Retrieval score, or reranker score when reranking is applied. | +| `similarity` | Cosine similarity to the query. It does not determine Hybrid or reranker ordering. | +| `rerankerScore` | Present when a reranker applied its relevance ordering. | -{/* VISUAL: two result panels side by side. Left: empty `results: []`. Right: one populated result object with documentName, content, chunkIndex, similarity 0.92, metadata, sourceUrl annotated. */} +Read the content alongside the scores. A high similarity means the passage is close in meaning; it does not guarantee that it answers the question. There is no universal relevance cutoff across embedding models and document collections. Recency policy can also affect returned order, so use `rank` to read that order. -The **similarity score** is the first thing to read. As a rough guide: above `0.8` is usually relevant, `0.6` to `0.8` is marginal, and below `0.6` is often noise. A search with a query always scores chunks this way. A tag-only search (filters, no query) returns every matching chunk with `similarity: 1`, because there's no query to measure distance against. +Tag-only retrieval has no query to compare and returns `similarity: 1` for every match. It returns up to **Number of Results** without vector ranking. ## Empty results -An empty `results` array means no chunk matched. There are three causes, listed here in the order worth checking. - -### The documents aren't ready +### Check processing -Only documents that finished processing are searchable. Every document carries a `processingStatus`, and the Knowledge block silently skips anything that isn't `completed`. A knowledge base full of half-processed documents looks empty even though the upload succeeded. +Use **List Documents** to inspect `processingStatus`. Only `completed` documents are eligible for search: -| `processingStatus` | Meaning | Searchable | +| `processingStatus` | Meaning | Eligible for search | | --- | --- | --- | -| `pending` | Queued, not started. | No | -| `processing` | Being chunked and embedded. | No | -| `completed` | Ready. | Yes | -| `failed` | Chunking or embedding errored. | No | +| `pending` | Queued for processing. | No | +| `processing` | Text extraction, chunking, or embedding is in progress. | No | +| `completed` | Processing finished. | Yes, if enabled, included, and accessible. | +| `failed` | Processing failed. | No | -{/* VISUAL: the four processingStatus states in a row, with a checkmark only on `completed`. */} +An upload or sync request can succeed before indexing finishes. For `pending` or `processing`, wait and check the status again. For `failed`, inspect `processingError` with **Get Document**, fix the cause, and choose **Retry** from the document menu. Replace or re-upload the file when the error calls for different content or a supported format. -Run the block's **List Documents** operation and check the status of each document. If a document is `pending` or `processing`, wait for it to finish. If it's `failed`, read its `processingError` (via **Get Document**) and re-upload. See [chunking strategies](/knowledgebase/chunking-strategies) for what happens during processing. +The UI can also show **Skipped**, a separate indexing outcome for content that cannot be indexed safely. Read its reason. Decorative connector images can complete with zero chunks; they have no text to retrieve. -### The query doesn't match the content +### Check enabled state and access -If your documents are `completed` but the search still returns nothing, the query may not be close to anything stored. Confirm the content actually exists: run **List Chunks** and read what's in the knowledge base. If the answer is there but the search misses it, the problem is wording, not data. Try a simpler query, or use a term that appears in the content. See [wrong results](#wrong-results-or-low-relevance) below for the deeper version of this. +Confirm that both the document and its relevant chunks are enabled. **Update Chunk** with `enabled: false` removes a chunk from search without deleting it; connector-managed chunks are read-only. -### Tag filters exclude everything +Excluded, archived, or deleted documents do not appear in search. For connector documents, inspect whether they are included and whether the acting principal has current source access. A workspace-shared connection and a permission-aware connection can expose different document sets. See [Connectors](/knowledgebase/connectors). -[Tag filters](/knowledgebase/tags) restrict the document set before the vector search runs, and they combine with AND logic: a document must match every filter to be searched. A filter like `Department equals 'engineering'` returns nothing if no document carries that tag value. +### Check tag filters -Check the tag values actually set on your documents (**Get Document** shows them), and confirm the filter value matches exactly. To rule filters out as the cause, remove them and search by query alone. +[Tag filters](/knowledgebase/tags) combine with AND. `Department equals "engineering"` excludes documents without that value, and an additional date or status filter can exclude the remaining documents. -## Wrong results or low relevance +Use **Get Document** to inspect assigned values and **List Tags** to check definitions. Text matching is case-insensitive; other types need valid values. Remove filters temporarily and search by query alone to isolate the cause. + +Connector metadata uses the same tag slots as manual definitions. Check the definition and its actual values instead of assuming an available slot belongs to your manual tag. -Wrong results are chunks that come back but don't answer the query, even though better content exists in the knowledge base. The vector search found something semantically near the query, but it wasn't near enough to be a good match. Read the `similarity` scores: a top result at `0.65` is the search telling you nothing good matched. +### Check the stored content + +Use **List Chunks** for the expected document and read the text Sim indexed. If the answer is absent, update the uploaded content or the connector source. If it is present, try a more specific query and check the [retrieval mode](/knowledgebase/using-in-workflows#retrieval-mode). + +## Wrong results or low relevance -Common causes: +If chunks return but do not answer the question, work through these changes: -- **The query relies on an exact term or identifier.** Semantic search can match paraphrases, but a product code or error ID may need literal matching. Try [Hybrid retrieval](/knowledgebase/using-in-workflows#retrieval-mode) and include the exact identifier in the query. -- **Chunks are too large.** A 1,024-token chunk blends many topics into one embedding, so its score is diluted across all of them. Smaller chunks (256 to 512 tokens) often retrieve more precisely. See [chunking strategies](/knowledgebase/chunking-strategies). -- **Context is split across a chunk boundary.** The sentence that answers the query sits in one chunk and the subject it refers to sits in the previous one, so neither chunk scores well on its own. Overlap during chunking reduces this. +1. **Use the exact identifier.** For error codes, SKUs, or ticket keys, include the literal string and try **Hybrid (full-text + vector)**. +2. **Narrow the scope.** Use a tag filter when the question belongs to a known department, date range, or document category. Check that the filter describes the intended content. +3. **Retrieve more candidates.** Increase **Number of Results** if the useful passage falls outside the returned set. +4. **Try reranking.** Enable **Rerank Results** when the initial set contains relevant passages but the order is unhelpful. Its advanced candidate-count setting can widen the second pass. +5. **Inspect chunk boundaries.** Large chunks can mix topics; small ones can separate an answer from its subject or definition. Try a different size on representative content and compare the results. For example, evaluate 256–512-token chunks against the default 1,024-token setting rather than assuming one size suits every source. -Two fixes that don't require re-chunking: narrow the search with a tag filter first so the vector search runs over fewer, more relevant documents, or turn on **Cohere reranking**. Reranking re-scores the initial vector results with a model tuned for relevance and adds a `rerankerScore` to each result. It's worth enabling when you see marginal results (`0.6` to `0.75`) that a human would call relevant. It costs one search unit per call and adds latency, and if the reranker is unavailable the search falls back to vector ordering automatically. +Overlap can preserve context across adjacent chunks. Its default is 200 tokens for strategies that apply overlap. See [chunking strategies](/knowledgebase/chunking-strategies) before changing boundaries or reprocessing documents. - -A high `similarity` score is not a guarantee the chunk answers the query, only that it's close in meaning. Vet the top results yourself, or use reranking, before trusting a search to ground an agent's answer. - +Reranking adds a model call and latency. Completed hosted-key calls are metered as one search unit; BYOK calls are billed by the provider. If the reranker is unavailable, the search retains its retrieval order and does not add `rerankerScore`. See [workflow retrieval](/knowledgebase/using-in-workflows) and [Costs](/platform/costs). ## Duplicates -Duplicates are the same or near-identical content appearing more than once in `results`. Read the `documentName` and `chunkIndex` of the repeated entries to tell which case you have. +Compare `documentId`, `documentName`, and `chunkIndex` on repeated results: -- **Same document, adjacent `chunkIndex` values.** This is overlap. Chunking repeats some tokens between consecutive chunks (200 by default) to preserve context, so neighboring chunks share text and can both match. Lowering overlap reduces the repetition, at the cost of context at chunk boundaries. See [chunking strategies](/knowledgebase/chunking-strategies). -- **Different `documentName`, identical content.** The same material was uploaded as two documents, or [synced from a connector](/knowledgebase/connectors) that holds it in more than one place. Consolidate the duplicate documents, or check the connector's source. +- **Same document, adjacent chunk indexes:** overlap can make neighboring chunks share text and both match. Lower overlap to reduce repetition, then check whether queries still retrieve enough context. +- **Different documents, identical content:** the material may have been uploaded twice or synced from multiple locations. Consolidate duplicate uploads or exclude the unwanted connector document. -## Disabled chunks and claimed tag slots +Do not sort Hybrid results by `similarity` to remove apparent ordering differences. Keep the returned order and inspect whether repeated chunks provide distinct context. -A chunk can be disabled with the **Update Chunk** operation (`enabled: false`), which removes it from all searches without deleting it. A disabled chunk never appears in results, even when it's the best match. If a chunk you know is relevant is missing from a search, confirm it isn't disabled. +## Related docs -The same goes for tag slots when you use [connectors](/knowledgebase/connectors). Synced documents auto-populate tag values (a repository name, a last-modified date), and those occupy the same slots manual tags would. A filter that returns nothing can be filtering on a slot the connector already claimed. +- [Using a knowledge base in a workflow](/knowledgebase/using-in-workflows) — settings and result fields. +- [Chunking strategies](/knowledgebase/chunking-strategies) — sizes, overlap, and record boundaries. +- [Tags and filtering](/knowledgebase/tags) — types and filter operators. +- [Connectors](/knowledgebase/connectors) — source access, exclusions, and sync errors. diff --git a/apps/docs/content/docs/knowledgebase/export-import.mdx b/apps/docs/content/docs/knowledgebase/export-import.mdx index 3b1d1672f5a..0b151f397df 100644 --- a/apps/docs/content/docs/knowledgebase/export-import.mdx +++ b/apps/docs/content/docs/knowledgebase/export-import.mdx @@ -1,13 +1,40 @@ --- title: Export -description: Download a knowledge base as one archive of its documents, chunks, tags, and settings. +description: Download a knowledge base's documents, chunks, tags, and settings in one archive. --- -An **export** is a single archive that holds a knowledge base: every document, the chunks Sim split it into, the tag definitions and values, and the chunking settings. Use it to keep a copy of a base outside Sim. +Export a knowledge base as a `.simkb.zip` archive. It carries the base's configuration, tag definitions and values, stored document files, and completed chunk text, with vectors included by default. -To export, right-click a base in the knowledge base list and choose **Export**, or open the base and click the **Export** button in the header. The download is named `.simkb.zip`. +## Access and scope -## What the archive contains +Export requires at least workspace read access and the **Knowledge Base Export** capability. Enterprise permission groups can restrict members' exports. The API accepts supported personal credentials or a workspace API key; OAuth callers need `api:read`. A workspace API key uses its workspace role and operation policy rather than a member's permission group. See [API authentication](/api-reference/authentication). + +The archive includes active, included documents readable by the workspace as a whole. It does not include every document a particular member can personally access through source permissions. Archived, deleted, and excluded documents are left out. + +Documents with neither a stored file nor completed chunks are omitted. A document still processing can contribute its stored file, but not unfinished chunk text. Disabled flags are preserved for documents and chunks that are included. + +## Download the archive + +Right-click a base in the knowledge base list and choose **Export**, or open the base and choose **Export** in its header. The download is named `.simkb.zip`. + +### API + +```http +GET /api/v2/knowledge/{knowledgeBaseId}/export?workspaceId={workspaceId}&vectors=true +``` + +The response is the ZIP archive. Set `vectors=false` to leave out embeddings. See [Export knowledge base](/api-reference/knowledge-bases/exportKnowledgeBase) for the request contract. + +### CLI + +```bash +sim knowledge export --output-file kb.zip +sim knowledge export --output-file kb.zip --no-vectors +``` + +The CLI uses the selected workspace profile. An existing output file requires `--force` to overwrite it. See the [CLI reference](/cli/reference). + +## Archive contents ```text .simkb.zip @@ -18,46 +45,43 @@ To export, right-click a base in the knowledge base list and choose **Export**, └── .ndjson ``` -- **`manifest.json`** describes the export (format version 1): the base name, description, and chunking config; the embedding model and dimension and whether vectors are included; the tag definitions; and a document list with each document's filename, MIME type, size, enabled flag, tag values, entry paths, and chunk, token, and character counts. -- **`files/`** holds each document's original file, when it has one. -- **`chunks/`** holds one NDJSON file per document, with one JSON line per chunk: its index, content, token count, start and end offsets, enabled flag, and the vector when vectors are included. +Files and chunk entries are present when the document has that content. -The export includes every document a workspace member can read, its file and its chunk text. Documents synced from a [connector](/knowledgebase/connectors) export as plain documents: their text and, where Sim stored it, their file. +| Entry | Contents | +| --- | --- | +| `manifest.json` | Format version `1`, export time, base name and description, chunking configuration, embedding model and dimensions, whether vectors are included, tag definitions, and the document list. | +| `files//` | The document's original stored file, when available. | +| `chunks/.ndjson` | One JSON line per chunk: index, content, token count, start/end offsets, enabled flag, and an optional vector. NDJSON is newline-delimited JSON. | -## What stays behind - -An export never includes: +Each document entry records its filename, MIME type, file size, enabled flag, tag values, entry paths, and chunk, token, and character counts. [Connector](/knowledgebase/connectors) documents export as plain documents with their text and any stored file. -- Access-control lists -- Connector links and credentials -- Who uploaded each document -- Internal storage keys +## Vectors and portability -Live [Organization Search](/search) queries providers directly and has no index to export. If an operator selects the legacy indexed Search backend, its organization index is not included in a workspace knowledge-base export. +Vectors are the embeddings used to compare chunks with a query. Each exported vector is encoded as base64 float32 values in its chunk's NDJSON line. -## Vectors +The manifest records the base's embedding model and dimensions. Reusing its vectors requires both to match the destination configuration; equal dimensions alone do not make vectors from different models comparable. Use `vectors=false` or `--no-vectors` when you need a text-and-file archive without vectors. -Vectors are embeddings, the numbers a model produces so search can compare chunks. They are included by default. Each chunk's vector is stored as base64-encoded float32 values in its NDJSON line. +## What stays behind -Vectors are only valid for a deployment that uses the same embedding model and dimension. The manifest records both for the base you exported. To skip vectors, set `vectors=false` on the API or pass `--no-vectors` to the CLI. +The archive does not include: -## Limits and governance +- Access-control lists or source-permission grants. +- Connector links and credentials. +- Uploader identities. +- Internal storage keys or secret-provenance sidecars. -A base with more than 2,000 documents cannot be exported. The request returns `413`. +Live [Organization Search](/search) queries providers directly and has no document index to export. A legacy indexed organization Search backend is also outside a workspace knowledge-base export. -Organization admins can withhold export through the permission group setting **Knowledge Base Export** (enterprise). Every export records an audit event. +## Limits and audit -## API +Export preflight accepts at most **2,000** active, included, workspace-readable document rows. A larger eligible set returns `413`, even if some empty documents would otherwise be omitted from the archive. -```http -GET /api/v2/knowledge/{knowledgeBaseId}/export?workspaceId={workspaceId}&vectors=true -``` +The bundle format also bounds each document to **5,000 chunks** and each chunk's content to **100,000 characters**. These are format limits, independent of vector inclusion. -The response is the archive. See the [API reference](/api-reference/getting-started) for authentication. +Each authorized export records an audit event with the base, vector option, and document count. -## CLI +## Related docs -```bash -sim knowledge export --output-file kb.zip -sim knowledge export --output-file kb.zip --no-vectors -``` +- [Knowledge Base](/knowledgebase) — uploads, processing, and embedding compatibility. +- [Connectors](/knowledgebase/connectors) — source content and access methods. +- [Access control](/platform/enterprise/access-control) — permission-group restrictions. diff --git a/apps/docs/content/docs/knowledgebase/index.mdx b/apps/docs/content/docs/knowledgebase/index.mdx index 19b210b6438..7f907823470 100644 --- a/apps/docs/content/docs/knowledgebase/index.mdx +++ b/apps/docs/content/docs/knowledgebase/index.mdx @@ -1,54 +1,70 @@ --- title: Knowledge Base -description: A store of documents your agents can search by meaning. +description: Store documents that your agents can search and use in their answers. --- -import { Video } from '@/components/ui/video' import { Card, Cards } from 'fumadocs-ui/components/card' -import { FAQ } from '@/components/ui/faq' -A **knowledge base** is a store of documents your agents can search by meaning. You upload files, Sim splits them into chunks and indexes them, and a [Knowledge block](/knowledgebase/using-in-workflows) retrieves the chunks most relevant to a query. This is how an agent answers from your own content instead of the model's general training. +A **knowledge base** stores documents for your agents to search. Sim extracts their text, splits it into passages called chunks, and creates embeddings: numerical representations used to match a question to relevant content. The [Knowledge block](/knowledgebase/using-in-workflows) retrieves those chunks for an Agent to use in its answer. -
- -
+Upload files for a fixed collection, or use a [connector](/knowledgebase/connectors) to keep content in sync with an external source. [Organization Search](/search) has a separate live-provider catalog; connecting a source to a knowledge base does not enable it in Search. -## How a document becomes searchable +## Create a knowledge base -When you upload a document, Sim processes it in the background: +1. Open **Knowledge Base** in your workspace and choose **New base**. +2. Enter a name and, optionally, a description. Leave **Chunking Strategy** on **Auto** unless you need different boundaries. See [chunking strategies](/knowledgebase/chunking-strategies) for the settings. +3. Add files when creating the base, or open it and choose **New documents**. +4. Wait for processing to finish before searching. A successful upload starts processing; it does not mean the document is indexed yet. -1. **Extract** the text, with a parser for each file type and OCR for scanned PDFs. -2. **Chunk** it into passages, with a size and overlap you can tune. -3. **Embed** each chunk as a vector so it can be matched by meaning, not just keywords. +Creating a base and adding documents require workspace write access and the relevant [permission-group capabilities](/platform/enterprise/access-control). -A document is searchable once its status reads `completed`. Open any document to view, edit, merge, or split its chunks. +## Supported files and limits -Every knowledge base records the embedding model and the vector width it was built with, and keeps them for its lifetime. Two bases built differently cannot be searched in one request — vectors are only comparable when they come from the same model at the same size — so search them separately, or rebuild one to match. On Sim Cloud every base uses `text-embedding-3-small` at 1,536 dimensions; self-hosted deployments choose both with [`KB_EMBEDDING_MODEL` and `EMBEDDING_OUTPUT_DIMS`](/platform/self-hosting/environment-variables), including models on their own Ollama. +| Content | File extensions | +| --- | --- | +| PDF | `.pdf` | +| Word | `.doc`, `.docx` | +| Text and Markdown | `.txt`, `.md` | +| HTML | `.html`, `.htm` | +| Excel and CSV | `.xls`, `.xlsx`, `.csv` | +| PowerPoint | `.pptx` | +| Structured data | `.json`, `.jsonl`, `.yaml`, `.yml` | -## What you can upload +Each file can be up to **100 MiB**. One upload action accepts at most **20 files**, with **500 MiB** total. Legacy `.ppt` files are not supported; convert them to `.pptx` first. -Sim accepts PDF, Word, text, Markdown, HTML, Excel, PowerPoint, CSV, JSON, and YAML files, up to 100 MB each (best under 50 MB). Scanned PDFs work too: with Azure or [Mistral OCR](https://docs.mistral.ai/ocr/) configured, Sim extracts text from image-based pages. +Scanned PDFs need Azure-hosted Mistral OCR or [Mistral OCR](https://docs.mistral.ai/studio/document-processing/basic_ocr) configured on the deployment. Password-protected, malformed, or overly complex files can fail processing even when they meet the upload-size limit. Read the document's error to find the required change. -## Shaping what a search returns +## Verify processing -Two things control retrieval quality, and each has its own page: +Sim processes documents in the background: -- **Chunking** decides how a document is split. Smaller chunks are more precise; larger ones keep more context. See [chunking strategies](/knowledgebase/chunking-strategies). -- **Tags** label documents so a search can filter to a subset. See [tags and filtering](/knowledgebase/tags). +1. **Extract** text using the parser for the file type, with OCR for scanned PDFs. +2. **Chunk** the text using the base's settings. +3. **Embed** the chunks so a query can match them by meaning. -To keep a base in sync with an outside source like Google Drive, use a [connector](/knowledgebase/connectors). +A document becomes eligible for search when `processingStatus` is `completed`. It and its chunks must also be enabled, included, and readable by the caller. See [debugging retrieval](/knowledgebase/debugging-retrieval) for status and access checks. -## Next +Open a completed document to inspect its chunks. For uploaded documents, you can edit, add, disable, or delete chunks. Connector-managed chunks are read-only; change their content at the source and sync again. + +## Retrieve and refine + +Add a [Knowledge block](/knowledgebase/using-in-workflows) before an Agent, then reference `` in the Agent's prompt. The block can retrieve by query, by [tags](/knowledgebase/tags), or by both. Its retrieval mode controls whether a query uses semantic matching alone or combines it with keyword matching. + +Inspect the returned content before changing settings. Use tags to select the relevant document set, and adjust [chunking](/knowledgebase/chunking-strategies) when passages lose context or combine unrelated topics. + +## Embedding compatibility + +Each base records its embedding model and dimensions at creation and retains them for later document processing. The default configuration uses `text-embedding-3-small` at 1,536 dimensions. Self-hosted operators can choose a supported model and width with [`KB_EMBEDDING_MODEL` and `EMBEDDING_OUTPUT_DIMS`](/platform/self-hosting/environment-variables), including an embedding model on their own Ollama server. + +A query search across multiple bases requires the same embedding model and dimensions in every base. Search incompatible bases separately, or rebuild them with matching configuration. Tag-only searches do not compare vectors and do not require this compatibility. Each Knowledge block selects one base; use separate blocks when a workflow needs several. + +## Related docs - - - - - + + + + + + - - diff --git a/apps/docs/content/docs/knowledgebase/tags.mdx b/apps/docs/content/docs/knowledgebase/tags.mdx index 1d84bb9835c..deb57a44c42 100644 --- a/apps/docs/content/docs/knowledgebase/tags.mdx +++ b/apps/docs/content/docs/knowledgebase/tags.mdx @@ -1,109 +1,90 @@ --- title: Tags and filtering +description: Define document metadata and use it to narrow Knowledge block searches. --- -import { Callout } from 'fumadocs-ui/components/callout' import { Image } from '@/components/ui/image' -import { FAQ } from '@/components/ui/faq' -Tags let you attach structured metadata to documents so the Knowledge block can filter results precisely — by department, date, priority, status, or any dimension you define. +Tags attach structured metadata to documents. Use them to select a department, date range, priority, or status before retrieving chunks. -## How Tags Work +A **tag definition** belongs to the knowledge base and gives a tag its name and type. A **tag value** belongs to a document. For example, define a Text tag named `Department`, then set `Department = "engineering"` on the documents that need it. -Tags have two layers: +## Types and capacity -1. **Tag definitions** — created at the knowledge base level. A definition has a name (e.g., "Department") and a type (Text, Number, Date, or Boolean). Definitions are shared across all documents. -2. **Tag values** — set per document. Once a definition exists, you assign a value to it on each document that needs it (e.g., `Department = "engineering"`). +Each knowledge base has **17 tag slots**, shared by its documents and connectors: -## Tag Slots +| Type | Slots | Values | +| --- | --- | --- | +| Text | 7 | Strings up to 512 characters; matching is case-insensitive. | +| Number | 5 | Valid numbers. | +| Date | 2 | Valid dates in `YYYY-MM-DD` format. | +| Boolean | 3 | `true` or `false`. | -Each knowledge base has **17 tag slots** distributed across four types: +The type picker shows usage, such as **Text (0/7)**, and only offers types with available slots. A connector's metadata tags use the same pool; choose the metadata you need during [connector setup](/knowledgebase/connectors). -| Type | Slots | Accepted values | -|------|-------|-----------------| -| **Text** | 7 | Any string — matching is case-insensitive | -| **Number** | 5 | Any valid number | -| **Date** | 2 | `YYYY-MM-DD` format | -| **Boolean** | 3 | `true` or `false` | +## Define and manage tags -The type dropdown in the creation form shows current slot usage for each type (e.g., `Text (0/7)` means none of the 7 text slots are in use yet). +You need workspace write access to create or delete definitions. - - Slots are shared across all documents and connectors in a knowledge base. Connectors that auto-populate metadata tags draw from the same pool. Plan your schema with that in mind. - +1. Click the knowledge base name in the header and choose **Tags**. +2. Choose **Add Tag**. +3. Enter a **Tag Name**, choose a **Type**, and select **Create Tag**. Press Enter to submit or Escape to cancel. -## Defining Tags +Tags in the knowledge base header's dropdown menu -Tag definitions live at the knowledge base level. To manage them, click the knowledge base name in the header to open the context menu and select **Tags**: +Names can be up to 100 characters and must be unique within the base, ignoring case. The Tags modal shows each definition's document count. Click a definition to view the documents with assigned values. -Knowledge base header showing the dropdown menu with Rename, Tags, and Delete options +The modal supports creating and deleting definitions. To rename a definition without clearing its values, use [Update knowledge tag](/api-reference/knowledge-bases/updateKnowledgeTag) in the API. -This opens the Tags modal, which lists all defined tags and shows how many documents each one is assigned to. Click **Add Tag** to define a new one: +Deleting a definition clears its values from every document and chunk that uses the slot. The confirmation dialog shows the affected documents. Review this consequence before selecting the trash icon and confirming. -Tags modal showing 0 defined tags, a Tag Name input field, and a Type dropdown set to Text (0/7), with Cancel and Create Tag buttons +## Set document values -Enter a **Tag Name** and pick a **Type**, then click **Create Tag**. The name must be unique within the knowledge base. The type dropdown only shows types that still have available slots. Press Enter to submit or Escape to cancel. +Right-click a document and choose **Tags**. Set the values for its defined tags in the document's tag panel. -To delete a tag definition, click the trash icon next to it. Deleting a definition removes the tag value from every document it was assigned to — the modal shows you which documents are affected before you confirm. +The **Tags** column shows assigned values; documents without values show dashes. Use **Filter** to narrow the document list by tag values. -Clicking any existing tag definition opens a dialog showing all documents that have a value set for it, along with their current tag values. +## Filter a workflow search -## Setting Tag Values on Documents +Open the Knowledge block and add **Tag Filters**. Each filter has: -Once a definition exists, you assign values document by document. Right-click any document (or click the `…` menu) to open the document context menu, then select **Tags**: +- **Tag** — a definition from the selected base. +- **Operator** — a comparison supported by that type. +- **Value** — a fixed value or a workflow reference, such as ``. -This opens the tag panel for that document where you can set a value for each defined tag. +For example, use `Department equals "engineering"` with a query about incident handling. The filter restricts candidate documents, and the query retrieves relevant chunks within them. -## Viewing Tags in the Document List +Add filters with the **+** button. Filters combine with AND, including filters on the same tag; a document must match every condition. A document without the required tag value will not match a comparison. -The **Tags** column in the document list shows the current tag values for each document at a glance. Documents with no tags assigned show `– – –`: +### Operators -Knowledge base document list showing Name, Size, Tokens, Chunks, Uploaded, Status, and Tags columns — Document1.txt shows no tags (– – –) while Document2.txt shows the value 'Waleed' +| Type | UI operators | +| --- | --- | +| Text | **equals**, **not equals**, **contains**, **does not contain**, **starts with**, **ends with** | +| Number | **equals**, **not equals**, **greater than**, **greater than or equal**, **less than**, **less than or equal**, **between** | +| Date | **equals**, **after**, **on or after**, **before**, **on or before**, **between** | +| Boolean | **is**, **is not** | -Use the **Filter** and **Sort** controls in the top right to narrow the list by tag values or sort by them. +**between** takes a lower and upper value and includes both bounds. Date comparisons apply to the specified calendar days. Text operators match literal text without case sensitivity. -## Using Tags in the Knowledge Block +### Query and tags -In a workflow, open the Knowledge block and configure **Tag Filters** to restrict which documents are searched: +| Input | Behavior | +| --- | --- | +| Tags only | Return matching chunks up to **Number of Results**, without vector ranking. Each match has `similarity: 1`. | +| Query only | Retrieve from readable documents using the selected retrieval mode. | +| Query and tags | Filter documents first, then retrieve within the matching set. | -Knowledge block editor showing Operation: search, Knowledge Base: test, Search Query field (optional), Number of Results, and a Tag Filters section with Filter 1 containing Tag: Name, Operator: equals, and a Value field +Tag-only retrieval does not generate a query embedding. Adding tags to a query narrows candidates but does not reduce the query-embedding charge. See [Using a knowledge base in a workflow](/knowledgebase/using-in-workflows) for retrieval modes and output fields. -Each filter has three parts: -- **Tag** — select a tag definition from the knowledge base -- **Operator** — depends on the tag type (see below) -- **Value** — the value to match against +## Connector metadata -Add as many filters as you need with the **+** button. Multiple filters are combined with AND logic — a document must match all filters to be included in the search. +Connectors can define and populate tags from source metadata. Notion can set **Labels** and **Last Modified**; GitHub can set **Repository** and **File Path**. You can use these definitions in the same filters as manual tags. -### Operators by Type +Metadata checkboxes are available during connector setup. Uncheck fields you do not need before connecting. Compatible existing definitions can be reused; new definitions consume available slots. Existing definitions retain their slots until deleted. The connector's Settings tab does not offer a metadata-tag editor, and changing source configuration does not automatically free tag slots. -| Type | Available operators | -|------|-------------------| -| **Text** | `equals`, `not equals`, `contains`, `does not contain`, `starts with`, `ends with` | -| **Number** | `equals`, `not equals`, `greater than`, `greater than or equal`, `less than`, `less than or equal`, `between` | -| **Date** | `equals`, `after`, `on or after`, `before`, `on or before`, `between` | -| **Boolean** | `is`, `is not` | +## Related docs -Tag values in filter fields can be static strings or workflow variable references (e.g., ``), so filtering can adapt dynamically at runtime. - -## Search Modes - -The Knowledge block behaves differently depending on what you provide: - -| What you provide | Behaviour | -|-----------------|-----------| -| **Tags only** (no search query) | Returns matching chunks up to Number of Results, without vector ranking | -| **Query only** (no tag filters) | Semantic vector search across all documents in the knowledge base | -| **Both tags and query** | Tag filters run first to narrow the document set, then vector search runs within that subset | - -The combined mode is the most precise — tag filtering cuts down the candidate set cheaply before the more expensive vector similarity comparison runs. - -## Connector-Populated Tags - -Connectors can auto-populate tags with metadata from the source. A Notion connector might set **Last Modified** and **Labels**; a GitHub connector might set **Repository** and **File Path**. These work exactly like manually defined tags and are available in Knowledge block filters. - -You can disable specific metadata tag types during connector setup or in connector settings to free up slots for manual use. See [Connectors](/knowledgebase/connectors) for details. - - +- [Connectors](/knowledgebase/connectors) — select source metadata during setup. +- [Using a knowledge base in a workflow](/knowledgebase/using-in-workflows) — combine query and tag inputs. +- [Debugging retrieval](/knowledgebase/debugging-retrieval) — diagnose filters that exclude expected results. diff --git a/apps/docs/content/docs/knowledgebase/using-in-workflows.mdx b/apps/docs/content/docs/knowledgebase/using-in-workflows.mdx index afd4bec3100..f27e89856c2 100644 --- a/apps/docs/content/docs/knowledgebase/using-in-workflows.mdx +++ b/apps/docs/content/docs/knowledgebase/using-in-workflows.mdx @@ -1,62 +1,44 @@ --- title: Using a knowledge base in a workflow -description: How the Knowledge block searches a knowledge base and what it returns, so an agent can ground its answers in your documents. +description: Retrieve document chunks with the Knowledge block and pass them to an Agent. --- import { WorkflowPreview, OutputBundle, SUPPORT_KB_WORKFLOW } from '@/components/workflow-preview' -A **Knowledge block** searches a [knowledge base](/knowledgebase) and hands the matching passages to a later block, so an [Agent](/workflows/blocks/agent) can answer from your documents instead of the model's memory alone. This page covers searching, narrowing with tags, reranking, and reading the results. +Use a **Knowledge block** to retrieve passages from a [knowledge base](/knowledgebase), then pass them to an [Agent](/workflows/blocks/agent). In this example, the workflow searches product docs for a customer's question and answers from the returned content. -In this workflow, the Knowledge block searches a base of product docs for the customer's question, and the Agent answers from the passages it returns. +## Search and answer -## Search +1. Set the Knowledge block's **Operation** to **Search**. +2. Select a **Knowledge Base**. +3. Set **Search Query** to ``, the customer's question. +4. Connect the Knowledge block to an Agent. Reference `` in the Agent's prompt, and tell it to answer from the returned `content` and cite `documentName` or `sourceUrl` where available. -A **Knowledge block** set to **Search** takes a query, compares it against the chunks in a base, and returns the closest matches. (The block can also manage documents and chunks, but Search is what a workflow uses to retrieve context.) You point it at a knowledge base and give it a query; in our example the query is ``, the customer's question. +**Number of Results** (`topK`) defaults to **10** and accepts **1–100** chunks. Increase it when relevant passages fall outside the returned set; decrease it when the Agent receives too much unrelated content. -Search is semantic, not keyword matching. The block turns the query into a vector and finds the chunks whose meaning is closest, so "refund timelines" can match a passage that says "we process returns within 14 days" with no shared words. +Search only returns completed, enabled, included documents and enabled chunks that the acting principal can read. An upload or connector sync can finish its initial request before indexing completes. See [debugging retrieval](/knowledgebase/debugging-retrieval) if expected content is missing. -**Number of Results** (topK) sets how many chunks come back, 10 by default. Fewer give the agent a tight, focused set; more widen the net at the cost of noise and tokens. +## Query and tag filters -You can also search by tags, instead of or alongside a query: +A query matches chunks by meaning. For example, “refund timelines” can match “we process returns within 14 days.” Hybrid retrieval also uses keywords, as described under [Retrieval mode](#retrieval-mode). -| What you provide | What it does | +| Input | Behavior | | --- | --- | -| Query only | Semantic search across every document in the base. The default. | -| Tags only | Returns matching chunks up to Number of Results, without vector ranking. | -| Query and tags | Tags narrow the document set first, then semantic search runs within it. The most precise. | +| Query only | Search readable documents using the selected retrieval mode. | +| Tags only | Return matching chunks up to **Number of Results**, without vector ranking or a query-embedding call. | +| Query and tags | Narrow the document set with tags, then retrieve within that set. | -## Tag Filters +Provide a query, tag filters, or both. -**Tag Filters** restrict a search to documents carrying specific [tags](/knowledgebase/tags). Each filter has three parts: a **Tag** (a tag defined on the base, like `Department`), an **Operator** (`equals`, `contains`, `greater than`, and others depending on the tag's type), and a **Value** to match. +**Tag Filters** have a **Tag**, **Operator**, and **Value**. For example, `Department equals "Billing"` restricts the search to billing documents. Add filters with the **+** button; they combine with AND, so a document must match all of them. Values can be fixed strings or references such as ``. -In our example, adding `Department equals "Billing"` makes the search consider only billing documents. Add more filters with the **+** button; multiple filters combine with AND, so a document must match all of them. A filter value can be a fixed string or a reference like ``, so the scope can change per run. +Tags narrow candidates; they do not reduce the query-embedding charge. See [Tags and filtering](/knowledgebase/tags) for types, operators, and slot limits. -Filters run before the vector comparison, so they make a search both more precise and cheaper. See [Tags and filtering](/knowledgebase/tags) for the full operator list by tag type. +## Outputs -## Retrieval Mode - -**Retrieval Mode** is an advanced setting that chooses how matches are found. - -| Mode | What it does | -| --- | --- | -| Vector only | The default. Ranks purely on meaning, as described above. | -| Hybrid | Also runs a keyword search over the same chunks and blends the two rankings. | - -Semantic search is strong on paraphrase and weak on literal strings: an error code, a ticket key like `PROJ-1234`, a SKU, or a rare product name carries little meaning for the model, so the chunk containing it may not rank near the top. Hybrid adds a keyword pass that matches those tokens exactly, then merges the two lists so a chunk found by either signal can surface. - -Turn it on when your documents are full of identifiers, codes, or names people search for verbatim. Leave it off for prose-heavy bases where questions are asked in natural language. Hybrid costs no extra API calls — the keyword pass runs entirely in the database. - -## Rerank Results - -**Rerank Results** is an optional second pass. Vector search ranks by raw similarity; reranking re-scores the top matches with a dedicated relevance model (Cohere's rerank models) and reorders them, which sharpens the ordering when the best answer isn't the literal closest vector. - -Leave it off for most searches. Turn it on when retrieval returns roughly the right documents but in the wrong order. When enabled, you pick a **Rerank Model**; self-hosted deployments also supply a Cohere API key. - -## Retrieved chunks - -The Search operation produces an **output** stored under the block's name, the same as any other block. Its main value is `results`: an array of the matched chunks, ranked best first. A later block reads it by reference, for example ``. +The block stores its output under its name. A later block reads `results` with ``: -Each result in the array is an object with these fields: +This example shows one result from Vector only retrieval without reranking. Each result can include: -| Field | What it is | +| Field | Meaning | | --- | --- | -| `content` | The chunk's text. This is what the agent reads. | -| `documentName` | The source document's filename, for citation. | -| `sourceUrl` | A link to the original, if the document came from a [connector](/knowledgebase/connectors). `null` for uploaded files. | -| `chunkIndex` | The chunk's position within its document. | -| `similarity` | How close the chunk is to the query, higher is better. For example `0.92`. | -| `metadata` | The document's attributes, including its tags. | -| `documentId` | The source document's identifier. | +| `content` | The chunk text the Agent reads. | +| `documentName` | The source document's name, useful for citation. | +| `sourceUrl` | The original source link when available; `null` for uploaded files without an external source. | +| `documentId` | The source document's ID. | +| `chunkIndex` | The chunk's position in its document; `0` is the first chunk. | +| `metadata` | Document tags, keyed by their display names. | +| `similarity` | Cosine similarity to the query; higher values mean a closer match. It remains this value in Hybrid mode and is `1` for tag-only matches. | +| `rankScore` | Retrieval score: cosine similarity for Vector only, fused score for Hybrid, or reranker score when reranking is applied. | +| `rank` | One-based position in the returned order. Recency policy can affect this order. | +| `rerankerScore` | Relevance score, present when reranking is applied. | + +The output also includes `query` and `totalResults`, the number of returned chunks. Keep the returned order when passing results to the Agent; sorting by `similarity` can discard Hybrid, recency, or reranker ordering. + +See [data flow](/workflows/data-flow) for references between blocks. + +## Retrieval mode + +**Retrieval Mode** is available in advanced mode: + +| Setting | Behavior | +| --- | --- | +| **Automatic** | The default. Use the workspace's retrieval policy. | +| **Hybrid (full-text + vector)** | Combine keyword and semantic rankings. | +| **Vector only** | Retrieve by semantic similarity. | + +Automatic uses Hybrid with a recency boost where member-scoped knowledge access is enabled, and Vector only without that boost elsewhere. An explicit mode overrides the retrieval choice; recency boosting remains a workspace policy. + +Try Hybrid for error codes, ticket keys such as `PROJ-1234`, SKUs, or rare names that readers search for verbatim. The keyword pass runs in the database and adds no model API call. + +## Rerank results -The output also carries `query` (the text that was searched) and `totalResults` (the count). +Enable **Rerank Results** when retrieval finds relevant passages but puts them in an unhelpful order. Select a **Rerank Model**; self-hosted deployments also supply a **Cohere API Key**. -To ground an answer, wire the Knowledge block before an [Agent](/workflows/blocks/agent) block and reference the chunks in the Agent's prompt with ``. The agent reads the `content` of each result and can cite `documentName` and `sourceUrl`. See [how blocks reference output](/workflows/data-flow) for how one block reads another's output by name. +Reranking sends candidates to a relevance model for a second pass. By default, Sim retrieves up to four times **Number of Results**, capped at 100 candidates. In advanced mode, **Documents Sent to Reranker** lets you choose the candidate count; Sim uses at least the requested result count and at most 100. These candidates are chunks, rather than whole source files. -## When retrieval looks wrong +A reranker model call adds latency. Completed calls using a hosted key are metered as one search unit; with your own key, the provider bills your account. See [Costs](/platform/costs) for the deployment's billing policy. -When the agent's answer is off, the cause is usually in retrieval, not the agent. Read the Knowledge block's output in the [run logs](/logs-debugging) and check the chunks it actually returned: +If reranking is unavailable, the search still succeeds: results keep their retrieval order and omit `rerankerScore`. Tag-only searches and searches with no candidates skip reranking. -- **No results, or wrong documents.** A tag filter may be excluding what you want, or the documents may not be indexed yet. A document is only searchable once its processing status is `completed`; while it is `pending`, `processing`, or `failed`, its chunks won't appear. -- **Low similarity scores across the board.** The query is too vague, or the information simply isn't in the base. Rewrite the query to match how the documents phrase things. -- **Right documents, wrong order.** Turn on Rerank Results, or raise Number of Results so the relevant chunk is included. -- **An exact code, ID, or name isn't found.** Switch Retrieval Mode to Hybrid so a keyword pass runs alongside the semantic one. +## Related docs -See [debugging retrieval](/knowledgebase/debugging-retrieval) for the full diagnostic path, and [chunking strategies](/knowledgebase/chunking-strategies) for how chunk boundaries shape what a search can return. +- [Debugging retrieval](/knowledgebase/debugging-retrieval) — check returned content, processing, filters, and ranking. +- [Tags and filtering](/knowledgebase/tags) — define the metadata used by **Tag Filters**. +- [Chunking strategies](/knowledgebase/chunking-strategies) — change how documents become passages. +- [Knowledge block reference](/integrations/knowledge) — document, chunk, tag, and connector operations. diff --git a/apps/docs/content/docs/logs-debugging/alerts.mdx b/apps/docs/content/docs/logs-debugging/alerts.mdx index 9fc6f54df4a..24e9f9a7282 100644 --- a/apps/docs/content/docs/logs-debugging/alerts.mdx +++ b/apps/docs/content/docs/logs-debugging/alerts.mdx @@ -5,6 +5,10 @@ description: Send an alert when a watched workflow fails or exceeds an operation Use a [Sim Workspace Events trigger](/workflows/triggers/sim) to run an alert workflow when another workflow fails, slows down, exceeds a cost threshold, or goes quiet. Add delivery blocks for the channel you use, such as Slack, email, or an incident API. +## Before you start + +You need permission to create and deploy the alert workflow, a credential for its delivery service, and a watched test workflow where you can reproduce the condition. + ## Example: notify Slack after repeated failures 1. Create a workflow with **Sim Workspace Events** as its trigger. @@ -18,12 +22,23 @@ Workflow has failed repeatedly. Latest run: ``` -6. Deploy the alert workflow to activate it. Trigger representative failures in a watched test workflow, then inspect the alert workflow's [run log](/logs-debugging) and the Slack message. +6. Deploy the alert workflow to activate it. + +## Verify the alert + +Trigger three consecutive failures in a watched test workflow. Inspect the alert workflow's [run log](/logs-debugging), confirm its delivery block completed, and check the Slack message for the source workflow and run ID. ## Choose another condition Choose **Run Error** to respond to each failed run. Other conditions include failure rate, error count, latency, cost, and inactivity. Cost thresholds use credits. See the [event and rule reference](/workflows/triggers/sim) for settings, defaults, and event-specific outputs. -Rule-based subscriptions have a one-hour cooldown after firing; plain events such as Run Error do not. Rate-based rules need at least five runs in their window. A subscription does not receive events about its own workflow, and runs started by this trigger do not emit new workspace events. +Run-backed alert rules have a one-hour cooldown after firing. **No Activity** has a per-watched-workflow cooldown of at least one hour or the inactivity window, whichever is longer. Plain events such as Run Error have no rule cooldown. Rate-based rules need at least five runs in their window. A subscription does not receive events about its own workflow, and runs started by this trigger do not emit new workspace events. + +## If an alert is missing + +Delivery behavior comes from the action blocks you configure. Check that the alert workflow is deployed, the source workflow matches its filter, the condition and cooldown allow it to fire, and the delivery block completed successfully. + +## Related docs -Delivery behavior comes from the action blocks you configure. If an alert is missing, check that the alert workflow is deployed, the source workflow matches its filter, the condition and cooldown allow it to fire, and the delivery block completed successfully. +- [Sim Workspace Events](/workflows/triggers/sim) for event settings and outputs +- [Logs](/logs-debugging) for tracing a failed alert run diff --git a/apps/docs/content/docs/logs-debugging/index.mdx b/apps/docs/content/docs/logs-debugging/index.mdx index 14edf8f61a9..78c106702d8 100644 --- a/apps/docs/content/docs/logs-debugging/index.mdx +++ b/apps/docs/content/docs/logs-debugging/index.mdx @@ -1,96 +1,64 @@ --- title: Logs -description: A log is the recorded trace of one workflow run, and debugging is reading that trace backward from the block that failed. +description: Trace a workflow failure through the inputs, outputs, and errors recorded for its run. --- import { Image } from '@/components/ui/image' -A **log** is the recorded trace of one workflow run. Every time a workflow runs, Sim writes down what triggered it, which blocks ran in what order, and for each block its exact input, its output, and any error. That trace is the ground truth for debugging: it replays what each block received, what it did, and what it returned, so you can find where something went wrong. +Open **Logs** to inspect a recorded workflow run. Start with its error, then follow the resolved inputs back to the block that supplied an unexpected value. The [Run logs reference](/logs-debugging/logging) explains filters, refresh, the editor console, and snapshots. +## Read a run trace +Each run has a unique execution ID, a trigger, status, duration, and recorded cost in credits. Triggers include manual, API, schedule, webhook, MCP, and **Sim agent** for runs started through Chat. -The **Logs page** lists every run across your workspace, one row per run. The [Logging reference](/logs-debugging/logging) covers the page itself: the columns, filters, and sidebar. This page covers what a log captures and how to trace a failure back to its cause. - -The Logs page: one row per run with workflow, date, status, cost in credits, trigger, and duration - -## What a log records - -### The run - -Each row on the Logs page is one **run**. It records the **trigger** that started it (manual, api, schedule, chat, webhook, mcp, mothership, copilot, or workflow), a **status**, a **duration**, and the **cost** in credits. It also carries an **execution ID** that uniquely names the run. - -The status shows the run's outcome at a glance, with failed runs badged **Error**. When you are hunting a failure, you filter the list to the errors and start there. - -### The blocks - -Open a run and **Log Details** shows the trace. The **Trace** tab lists each block as a span with its timing, in the order they ran; each **block execution** records the [block](/workflows#blocks)'s name and type, its own status, its **input**, its **output**, and an error message if it failed. +Select a run to open **Log Details**. **Overview** contains run metadata and available workflow input, output, cost, and files. **Trace** shows timed spans for blocks, nested workflows, model requests, and tool calls. Access settings can hide trace, snapshot, or cost details. The current Log Details Trace tab showing workflow, agent, model, and tool spans with their durations -This is the level you debug at, because a run fails when one of its blocks fails, and a block usually fails because of the input it received. In this run, one glance at the spans shows where the time went: Agent 1 took 7.84s of the 7.86s total. - -### Input and output - -Each block in the sidebar has two tabs. The **Input** tab shows the resolved values the block actually ran with: the literal values you typed, and the earlier outputs it read by reference. Exact values successfully substituted from Secrets through `{{KEY}}` are masked in this trace copy; see [Execution log protection](/platform/credentials#execution-log-protection). The **Output** tab shows what the block produced, formatted as an object, with markdown rendered for agent-generated text. - -The input tab is the important one. A block reads earlier outputs by name, written ``, and the input tab shows what those references resolved to at run time. If a reference pointed at a value that was not there, you see it here as missing or wrong, not as the tag you wrote. See [how blocks pass data](/workflows/data-flow) for how those references resolve. - -The same inspector follows you into the editor: during manual and chat runs, the console shows each block's Output and Input live, with values as a typed tree. - -The editor's run console: blocks with their durations on the left, and the selected Agent's Output tab showing content, model, and tokens as a typed tree - -### The snapshot +Select a span to read its collapsible **Input**, **Output** or **Error**, and any **Thinking** or **Error message** sections. Input shows the values after references resolve; output shows what that step returned. Compare these values with the [data references](/workflows/data-flow) in your workflow. -A workflow changes over time. A log does not. Clicking **View Snapshot** opens a frozen copy of the workflow exactly as it was when that run happened: the blocks, the connections, the configuration. This matters when a run failed last week and you have edited the workflow since. The snapshot shows the version that actually ran, not today's version. +Protected resolved secret values are masked in the log-facing copy. Workspace **Unredacted** exceptions and transformed values have different boundaries; see [Execution log protection](/platform/credentials#execution-log-protection). -## Tracing a failure backward +A handled block error can appear in a successful run. For a failed run, find the unhandled error rather than assuming every error span caused the final status. -Debugging follows the same repeatable loop each time. You start at the block that failed and walk back to the block that caused it. +## Trace a failure backward -1. **Find the failed block.** Open the errored run. The sidebar marks the block whose status is **error**. Read its error message. -2. **Read its input.** Open the block's Input tab. This is what it actually ran with, after every reference resolved. -3. **Verify the input.** Ask whether that input is what the block expected. An empty field, a value of the wrong type, a missing nested key: the mismatch is usually visible here. -4. **Walk back to the source.** A bad input came from somewhere. Find the earlier block whose output the failed block referenced, and open that block's Output tab. Either it produced the wrong value, or it never ran. -5. **Fix and rerun.** Correct the reference, the configuration, or the upstream block, then run the workflow again. -6. **Compare the traces.** Open the new run's log next to the old one. The block that was **error** is now **success**, and its input is the value you expected. That confirms the fix. - -{/* VISUAL: the debugging loop as a flowchart: failed block → read input → verify expectation → walk back to source block → fix → rerun → compare logs. */} - -{/* VISUAL: side-by-side of a failed run and a successful run, same blocks, highlighting the one input/output that changed between them. */} +1. Open the failed run and select its failed span in **Trace**. Read the error message. +2. Expand **Input** to see what the step received after references resolved. +3. Check required fields, types, and nested keys against the block's expected input. +4. Find the upstream block referenced by the incorrect input. Inspect its output and confirm that it ran. +5. Correct the reference, configuration, or upstream behavior, then run the workflow again. +6. Compare the new trace with the failed run. Confirm that the input is correct and the step completes successfully. ### Common failures -Most errors come down to a handful of input mismatches. Knowing the shape speeds up step 3. - -- **Missing input.** A field the block needs was left empty, or its reference resolved to nothing. -- **Wrong reference.** The tag names an output that does not exist, or uses the wrong field name. -- **Type mismatch.** A string where an object was expected, or the reverse. -- **Missing nested key.** The referenced object exists, but the specific field inside it does not. -- **Empty agent message.** An [Agent](/workflows/blocks/agent) returned nothing, so the next block had nothing to read. -- **External error.** A tool or API the block called returned an error of its own, surfaced in the block's error message. +| Failure | What to check | +| --- | --- | +| Missing input | A required field is empty or its reference resolves to no value. | +| Wrong reference | The block or output field named in the reference does not exist. | +| Type mismatch | A step receives a string where it expects an object, or another incompatible type. | +| Missing nested key | The object exists, but the requested field does not. | +| Empty agent message | An [Agent](/workflows/blocks/agent) returns no content for the next step to read. | +| External error | A tool or API returns an error; inspect its message and request inputs. | -When a value is the wrong shape, reshape it in a [Function](/workflows/blocks/function) block, whose result becomes its own output that later blocks can read. +Use a [Function](/workflows/blocks/function) block to reshape a value when the next step expects a different structure. -## AI-assisted debugging +## Troubleshoot in Chat -Sim can read a run's logs and propose a fix from the trace: the error message, the input the block received, and the output the upstream block produced. The logs stay the ground truth. You confirm a proposed fix the same way you confirm your own: rerun the workflow and compare the new trace against the failed one. +When available on a failed run, select **Troubleshoot in Chat** to give Sim its debugging context. This action depends on Chat being enabled and the run supporting troubleshooting. Verify any proposed fix by rerunning the workflow and comparing traces. ## Retention -Logs are kept so you can debug a run after it happened. Free plans retain logs for **7 days**, after which they are archived to cloud storage and removed from the database. Pro, Team, and Enterprise plans retain logs indefinitely. +Sim Cloud Free defaults to 30 days of log retention. Paid plans and billing-disabled deployments have no plan-based default expiry; configured policies can still remove older logs. See [Data retention](/enterprise/data-retention) for the effective policy and cleanup behavior. + +## Related docs + +- [Run logs](/logs-debugging/logging) for filters, details, console, and snapshots +- [Alerts](/logs-debugging/alerts) for failure and operational notifications +- [Data flow](/workflows/data-flow) for resolving block references diff --git a/apps/docs/content/docs/logs-debugging/logging.mdx b/apps/docs/content/docs/logs-debugging/logging.mdx index d974e26782a..de4264fbf5b 100644 --- a/apps/docs/content/docs/logs-debugging/logging.mdx +++ b/apps/docs/content/docs/logs-debugging/logging.mdx @@ -1,97 +1,60 @@ --- -title: Logging -description: Where run logs live — the real-time console, the Logs page, and what each entry records. +title: Run logs +description: Find recorded runs, inspect their details, and compare them with the workflow that ran. --- -import { Callout } from 'fumadocs-ui/components/callout' -import { Tab, Tabs } from 'fumadocs-ui/components/tabs' import { Image } from '@/components/ui/image' -Every workflow run is logged. There are two places to read them: the **Console** for the run you're watching, and the **Logs page** for everything. - -## Real-time Console - -During manual or chat runs, the Console panel in the editor shows each block as it runs — active-block highlighting, outputs as they complete, per-block timing, and success/error status. - -
- The current run console with block timings and the selected block output -
- -## Logs page - -Every run from every trigger — manual, API, chat, schedule, webhook — lands on the Logs page, with filtering by time range, status, trigger type, folder, and workflow, full-text search, and a **Live mode** that streams new entries in as they're recorded. - -
- The current workspace Logs page -
- -## Log details - -Click any entry to open its sidebar: the run's timeline (start/end, total duration, per-block timing) and each block's data flow. - -
- The current Log Details sidebar with run metadata, output, and credit total -
- - - - The block's result — JSON-formatted structured data, markdown rendering for AI content, and a copy button. - - - What the block received — resolved variable values, referenced outputs, and environment variables. Exact secret values activated by a successful `{{KEY}}` substitution are masked in this trace view. See [Execution log protection](/platform/credentials#execution-log-protection). - - - -## Workflow snapshots - -**View Snapshot** opens a frozen copy of the workflow exactly as it was at run time — structure, block states, connections — and each block is clickable to its inputs and outputs. This is how you debug a run of a workflow you've since changed. - -
- Workflow Snapshot -
- - -Snapshots exist for runs after the enhanced logging system was introduced. Older migrated logs show "Logged State Not Found". - +Use **Logs** to find recorded runs in your workspace. Use the workflow builder's console to watch a manual or chat run as it executes. For a debugging procedure, see [Trace a failure](/logs-debugging). -## Retention +## Find a run -- **Free**: 7 days — logs are archived to cloud storage, then deleted. -- **Pro / Team / Enterprise**: retained indefinitely. +The list shows workflow, date, status, cost in credits, trigger, and duration. Filter by time range, status, trigger, folder, or workflow. Search text matches run IDs; it does not search arbitrary input or output text. Structured filters also support date, duration, and cost. For example: -## Next +```text +status:error workflow:"Support" duration:>5s +``` -- [Alerts](/logs-debugging/alerts) for notifications on failures and slow runs -- [Cost calculation](/platform/costs) for what each run costs -- [External API](/api-reference/getting-started) for programmatic log access +The list holds a stable snapshot. Select **Refresh**, **N new logs**, or **Updates available** to load new or changed runs. With editing access, select **Export** to download a CSV using the current filters. + +Workspace Logs list with workflow, date, status, credits, trigger, and duration columns + +## Read log details + +Select an entry to open **Log Details**. The run records its execution ID, workflow ID, trigger, start and end timestamps, duration in milliseconds, final output, trace spans, and associated files where available. Use the copy controls to copy identifiers or data. + +### Overview + +**Overview** shows run metadata and available **Workflow Input**, **Workflow Output**, and cost details. Current usage-ledger itemization can include **Base Run**, model and tool usage, and token totals. Older runs may have a total without itemized rows. + +### Trace + +**Trace** shows the block and child spans with their timing and status. Select a span to inspect stacked, collapsible **Input**, **Output** or **Error**, and any **Thinking** or **Error message** sections. Inputs contain resolved variable values and referenced outputs. Structured data can be inspected and copied; agent text can render as Markdown. + +Workspace access settings govern which trace, workflow data, snapshot, and cost details are visible. Protected resolved secret values are masked in the log-facing copy, subject to documented exceptions. See [Permission groups](/enterprise/access-control) and [Execution log protection](/platform/credentials#execution-log-protection). -import { FAQ } from '@/components/ui/faq' +## Watch a manual run - +During manual or chat runs, the workflow builder's console highlights active blocks and shows outputs as they complete, per-block timing, and success or error status. Select a block and use its **Output** and **Input** tabs to inspect values as a typed tree. These console tabs are separate from the recorded run's trace sections. + +## Open the run snapshot + +Select **View Snapshot** to inspect the saved workflow structure, block configurations, and connections from that run, where available. Inspect its blocks and recorded inputs and outputs to compare the version that ran with your current draft. + +Some older migrated logs have no saved workflow state and show **Logged State Not Found**. A log's existence does not guarantee that a snapshot is available or that your access settings allow it. + +## Retention + +Sim Cloud Free defaults to 30 days. Paid plans and billing-disabled deployments have no plan-based default log expiry. Organization or workspace policies can change effective retention; cleanup removes expired data rather than providing a recoverable archive. See [Data retention](/enterprise/data-retention). + +## Related docs + +- [Debug a run](/logs-debugging) for tracing errors through resolved values +- [Alerts](/logs-debugging/alerts) for notifications on failures and slow runs +- [Costs](/platform/costs) for run charges and credit units +- [API getting started](/api-reference/getting-started) for programmatic log access diff --git a/apps/docs/content/docs/mcp/authentication.mdx b/apps/docs/content/docs/mcp/authentication.mdx index de694a2066c..471f62bf165 100644 --- a/apps/docs/content/docs/mcp/authentication.mdx +++ b/apps/docs/content/docs/mcp/authentication.mdx @@ -1,15 +1,15 @@ --- title: Authentication -description: Sign in with OAuth, or connect with an API key +description: Choose OAuth access or an API key, and revoke access when it is no longer needed. --- import { Callout } from 'fumadocs-ui/components/callout' +Use OAuth for an app that supports browser sign-in. Use an API key for a client that needs a fixed credential. Both remain subject to the credential's current resource access and operation permissions. + ## OAuth -Most apps sign in with OAuth. The first time you connect, your app opens Sim in -the browser, you sign in, and you approve its access. The app then holds a -token that renews itself; you do not copy any secret. +On first connection, your app opens Sim in the browser. Sign in and review the requested access before approving it. The app stores a one-hour access token, so you do not copy a secret. With `offline_access`, it can refresh access for up to 30 days from the initial grant; after that, sign in again. Refreshing does not extend that fixed lifetime. The approval screen names the app and what it can do: @@ -18,9 +18,7 @@ The approval screen names the app and what it can do: | Read-only | `api:read` | Reading workspaces, workflows, runs, tables, files, knowledge bases, and logs | | Full | `api:write` | Everything above, plus creating, changing, running, deploying, and deleting | -Most apps request full access. To connect an app for reads only, configure it -to request the `api:read` scope; changes then fail with an insufficient-scope -error. +For reads only, configure the app to request `api:read`; changes then fail with an insufficient-scope error. A token's scope does not grant a workspace role or bypass resource permissions. Tokens are issued for the Sim MCP server itself. An app cannot take one to another service and use it there. @@ -53,18 +51,22 @@ claude mcp add --transport http sim https://mcp.sim.ai/mcp \ } ``` -A personal key acts as you in every workspace you can access. A workspace key -reaches only its own workspace, and a few account-level operations refuse it; -`search_operations` marks them `personalCredentialOnly`. +A personal key uses your current access in the workspaces you can reach. A workspace key reaches only its own workspace and follows workspace-key operation and role policies rather than its creator's human permission group. Some operations refuse workspace keys; `search_operations` marks them `personalCredentialOnly`. + +The Cursor process must receive `SIM_API_KEY` for its environment interpolation to work. For a self-hosted deployment, replace the Cloud URL in both examples with your server URL. - An API key does not expire until you revoke it. Prefer OAuth for any app that - can open a browser, and store keys in your app's secret or environment + Keys created in Sim settings have no default expiration. Revoke a key when it is no longer needed. Prefer OAuth for an app that + supports browser sign-in, and store keys in your app's secret or environment settings rather than in a shared config file. ## Organization policy -The server follows your organization's access policy. If an administrator turns -off **OAuth apps** or **personal API keys** for your permission group, requests -with that credential are refused in the affected workspaces. +Organization policy can restrict personal credentials in affected workspaces. The **Personal API Keys** policy applies to personal API-key and OAuth requests; OAuth requests also require **OAuth App Access**. OAuth approval and refresh remain subject to organization policy. See [Permission groups](/enterprise/access-control) for policy resolution. + +## Related docs + +- [Connect an app](/mcp/overview) for server URLs and client configuration +- [API authentication](/api-reference/authentication) for key creation and credential scope +- [Tools](/mcp/tools) for read and write operation behavior diff --git a/apps/docs/content/docs/mcp/overview.mdx b/apps/docs/content/docs/mcp/overview.mdx index dee6082ea4f..8d4994f4067 100644 --- a/apps/docs/content/docs/mcp/overview.mdx +++ b/apps/docs/content/docs/mcp/overview.mdx @@ -1,24 +1,22 @@ --- title: Sim MCP -description: Build, run, and manage everything in your Sim workspace from Claude, Codex, Cursor, and other MCP apps +description: Connect an AI app to Sim's JSON API operations through MCP. --- -import { Callout } from 'fumadocs-ui/components/callout' -import { Tab, Tabs } from 'fumadocs-ui/components/tabs' +import { Tab, Tabs } from '@/components/ui/tabs' -The Sim MCP server gives an AI app the whole Sim API through the -[Model Context Protocol](https://modelcontextprotocol.io). Your agent can list -workspaces, run and deploy workflows, query and edit tables, manage files and -knowledge bases, read run logs, and more. It covers the same operations as the -[API](/api-reference/getting-started) and the [CLI](/cli). +Connect an AI app to Sim to manage workspaces, run and deploy workflows, and work with tables, files, knowledge bases, and logs. Sim MCP exposes JSON API operations through the [Model Context Protocol](https://modelcontextprotocol.io), a standard for connecting AI apps to tools. See [Tools](/mcp/tools) for supported requests and limits. + +## Choose the server URL | Deployment | Server URL | | --- | --- | | Sim Cloud | `https://mcp.sim.ai/mcp` | | Self-hosted | `https:///api/mcp`, or your [`SIM_MCP_URL`](/platform/self-hosting/environment-variables) | -The server uses the Streamable HTTP transport. Sign in with OAuth, the default -in every app below, or send an [API key](/mcp/authentication#api-keys). +The server uses Streamable HTTP. Sign in with OAuth or send an [API key](/mcp/authentication#api-keys). Replace the Cloud URL in every example below when connecting to a self-hosted deployment. + +Claude's hosted connectors call from Anthropic's infrastructure, so your server must be reachable from it over the internet. A `localhost` URL works with clients that connect from your machine, such as Claude Code, Codex, Cursor, and VS Code. See [Claude's network requirements](https://support.claude.com/en/articles/11175166-get-started-with-custom-connectors-using-remote-mcp). ## Connect an app @@ -32,9 +30,9 @@ in every app below, or send an [API key](/mcp/authentication#api-keys). browser. - Add `https://mcp.sim.ai/mcp` as a custom connector under **Settings → + Add `https://mcp.sim.ai/mcp` as a custom connector under **Customize → Connectors**, then connect it and sign in to Sim. For Team or Enterprise, - an owner first adds it under **Organization settings → Connectors**. See + an authorized organization administrator first adds it under **Organization settings → Connectors**. If asked for an OAuth client strategy, choose **Register automatically**. See [Claude's custom connector instructions](https://support.claude.com/en/articles/11175166-get-started-with-custom-connectors-using-remote-mcp). @@ -70,15 +68,7 @@ in every app below, or send an [API key](/mcp/authentication#api-keys). -Any other app that supports remote MCP servers with OAuth works the same way: -give it the server URL and choose **Streamable HTTP** if asked. - - - Claude's hosted connectors call your server from Claude's infrastructure, so a - self-hosted Sim must be reachable from the internet. A `localhost` URL works - only with apps that run on your machine, such as Claude Code, Codex, Cursor, - and VS Code. - +For another app that supports remote MCP servers with OAuth, enter the server URL and choose **Streamable HTTP** if asked. Follow that app's connection and sign-in procedure. ## Try it @@ -92,18 +82,22 @@ Ask your app: The agent finds the right operation, reads its inputs, and calls it. See [Tools](/mcp/tools) for how that works. -## What your agent can do +## Access and approvals -The server acts as you. It sees the workspaces you can see, with your role in -each, and every call is authorized, rate limited, and logged exactly like the -same request to the API. Reads leave your resources unchanged, and apps can ask -you to confirm each change. See [Authentication](/mcp/authentication) to limit -an app to reads. +Access follows the connection credential, workspace role, and operation policy. Each call uses the API's authorization, rate limits, validation, and logging. Personal credentials use your current access; workspace API keys are limited to their workspace. See [Authentication](/mcp/authentication) to choose credential scope or read-only OAuth access. + +The server separates read and write tools; your app controls whether it asks for confirmation before a change. ## Other Sim MCP surfaces -This server is for operating Sim. Two other MCP features do different jobs: +These features have separate purposes: - [Search MCP](/search/mcp) searches your organization's live provider sources with current access checks. - [MCP deployment](/workflows/deployment/mcp) exposes your own workflows as tools, and [MCP tools](/agents/mcp) connect external servers to Sim agents. + +## Related docs + +- [Authentication](/mcp/authentication) for scopes, credentials, and revocation +- [Tools](/mcp/tools) for operation discovery, calls, and result limits +- [API getting started](/api-reference/getting-started) and [CLI](/cli) for other ways to operate Sim diff --git a/apps/docs/content/docs/mcp/tools.mdx b/apps/docs/content/docs/mcp/tools.mdx index 6bf6e0fee84..600892d00e3 100644 --- a/apps/docs/content/docs/mcp/tools.mdx +++ b/apps/docs/content/docs/mcp/tools.mdx @@ -1,12 +1,11 @@ --- title: Tools -description: How an agent finds, reads, and calls Sim operations through four tools +description: Discover an operation, inspect its request, and call it with the correct access. --- -The Sim API has more than 200 operations. Instead of one tool per operation, -which would crowd your app's tool list and your agent's context, the server -exposes four tools. The agent searches for an operation, reads its inputs, and -calls it. +Sim MCP exposes four tools for discovering and calling its supported JSON API operations. Search for an operation, inspect its inputs, then call the read or write tool named in its description. + +## Tools | Tool | Does | | --- | --- | @@ -15,8 +14,9 @@ calls it. | `call_read_operation` | Runs an operation that only needs read access, such as `listWorkspaces`, `queryRows`, or `getWorkflowRun`. | | `call_write_operation` | Runs an operation that needs write access: one that creates, changes, runs, or deletes something, or reaches out to another service, such as `createTable`, `executeWorkflow`, or `listMcpServerTools`. | -Reads and writes are separate tools so your app can approve reads once and still -ask you before each change. +The operation's required access determines the tool, rather than its HTTP method: a read can use POST, and a GET that contacts another service can require write access. Your app controls tool approvals. + +`search_operations` returns the total number of matches and at most `limit` operations: 25 by default, 100 maximum. Catalog search has no cursor. Narrow the keywords or `domain` when matches exceed that limit; this is separate from paginating API resources. ## Calling an operation @@ -36,11 +36,25 @@ fills the parts of the request it needs: | --- | --- | | `params` | Path parameters, such as `tableId` or `workflowId` | | `query` | Query-string parameters; most operations need `workspaceId` | -| `body` | The JSON request body (write operations only) | -| `headers` | Headers the operation declares, such as `upload-token` | +| `body` | The JSON request body when the operation declares one, including read operations such as `queryRows` | +| `headers` | Only headers the operation declares, such as `upload-token` | -The result is the same JSON the API returns, usually `{ "data": … }`. List -operations page with `limit` and `cursor`. A failed call returns the API's error, +For example, `queryRows` uses the read tool with a JSON body: + +```json +{ + "operation": "queryRows", + "params": { "tableId": "tbl_8f2c" }, + "body": { "workspaceId": "ws_91ab", "limit": 50 } +} +``` + +Keep authentication in your app's connection configuration. You cannot pass undeclared authentication or protocol headers, including `X-API-Key`, `Authorization`, or `Accept`, through the call's `headers` field. + +## Results and errors + +The result is the same JSON the API returns, usually `{ "data": … }`. Paginated list +operations use `limit` and `cursor`; check the operation because some lists do not support pagination. A failed API call returns its error, such as `{ "error": { "code": "NOT_FOUND", "message": "…" } }`, so the agent can correct its request. @@ -48,8 +62,14 @@ correct its request. - **Same rules as the API.** Permissions, rate limits, and request validation are the API's own; nothing is looser through MCP. -- **1 MiB per result.** Page through larger lists with `limit` and `cursor`. +- **1 MiB per API result.** Request smaller pages for paginated lists. A single-resource result may also exceed the limit. The size check happens after the API executes: if a write returns a size error, check the resource state before repeating it because the change may already have succeeded. - **No streaming.** Run a workflow without `stream: true` to wait for its result, or with `async: true` and poll `getWorkflowRun`. - **No file bytes.** Downloads, knowledge base exports, and multipart document uploads are not available over MCP; use the [CLI](/cli/files) or the API. + +## Related docs + +- [Authentication](/mcp/authentication) for scopes and credential access +- [API getting started](/api-reference/getting-started) for response and pagination contracts +- [Workflow runs](/workflows/deployment/api) for synchronous and asynchronous execution diff --git a/apps/docs/content/docs/meta.json b/apps/docs/content/docs/meta.json index 649510a1483..255c174d82c 100644 --- a/apps/docs/content/docs/meta.json +++ b/apps/docs/content/docs/meta.json @@ -1,7 +1,7 @@ { - "title": "Sim Documentation", + "title": "Sim documentation", "pages": [ - "---Get Started---", + "---Get started---", "./introduction/index", "./getting-started/index", "./desktop/index", diff --git a/apps/docs/content/docs/platform/connected-accounts.mdx b/apps/docs/content/docs/platform/connected-accounts.mdx index 3127c214355..43272029f90 100644 --- a/apps/docs/content/docs/platform/connected-accounts.mdx +++ b/apps/docs/content/docs/platform/connected-accounts.mdx @@ -1,118 +1,123 @@ --- title: Credential Groups -description: Collect accounts in one organization credential group and control which workspaces can use them. +description: Collect account connections for an organization and grant workspaces access by integration. --- import { Callout } from 'fumadocs-ui/components/callout' -**Credential Groups** collects people's accounts in one shared pool for your organization, also called a **credential group**. An organization admin chooses the providers, invites people to connect, and allows specific workspaces to use the pool. Workflows in those workspaces can find an account by email through the [Credential block](/workflows/blocks/credential). +**Credential Groups** collects people's account connections in one organization pool. Organization administrators configure providers, request connections, and choose which integrations each workspace may use. Workflows find an account by invitation email through the [Credential block](/workflows/blocks/credential). -Each organization has at most one pool. Creating it does not give any workspace access; the workspace allowlist starts empty. +An organization has at most one pool. Its workspace access starts empty. -## Availability +## Availability and access -Sim Cloud requires an active Enterprise plan. Organization owners and admins manage the pool, subject to the organization's permission settings. A workspace admin who is not an organization admin cannot change the pool or its workspace access. +Sim Cloud requires an active Enterprise plan. On self-hosted deployments, enable `CREDENTIAL_GROUPS=true`, or `ENTERPRISE_ENABLED=true` for the enterprise suite. Personal workspaces cannot use an organization pool. -For self-hosted deployments, set `CREDENTIAL_GROUPS=true`, or `ENTERPRISE_ENABLED=true` to enable the whole enterprise suite. Availability is organization-scoped; personal workspaces cannot use an organization pool. +Organization owners and admins manage **Settings → Credential Groups**, subject to permission settings. Workspace Admin access alone does not allow changing the pool or its grants. -Manage the pool under **Settings → Credential Groups**. It remains available independently of Search. Search administrators use **Settings → Sources**, while members connect personal Search accounts under **Integrations** in the main sidebar. These surfaces can share grants without sharing their purpose or resource settings. +Credential Groups is available independently of Search. Search administrators configure **Settings → Sources**; members connect personal Search accounts under **Integrations**. Adding a provider to Credential Groups does not create a Search source or start indexing. Managed MCP connections support live tool calls. -## Set up connected accounts +## Set up the pool -Open your organization’s **Settings → Credential Groups**. Select **Set up connected accounts** if this is your first time. +Open the organization's **Settings → Credential Groups**. If no pool exists, select **Set up Credential Groups**. -The page has three tabs: - -| Tab | What you manage | +| Tab | Purpose | | --- | --- | -| **Providers** | Services people can connect and their shared configuration | -| **People** | Connection requests, each person's connected accounts, and revocation | -| **Workspace access** | Workspaces allowed to use the organization's accounts | +| **Integrations** | Add providers and manage their shared configuration | +| **People** | Request connections, inspect accounts, resend invitations, and revoke access | +| **Access** | Grant a workspace all or selected integrations | -### 1. Add providers +### 1. Add integrations -In **Providers**, select **Add provider** and search the catalog. Complete any required configuration before adding the provider. Added providers appear in the list; use **Configure** to edit their settings or **Remove** in the row menu to remove them. +In **Integrations**, select **Add integration**, search the catalog, and complete any required setup. Use **Configure** to change an added provider's settings or **Remove** in its menu to remove it. -| Provider | Organization setup | +| Provider | Required organization setup | | --- | --- | -| OAuth providers, such as Gmail or Google Drive | Add the provider from the available catalog. Each invited person authorizes their account. | -| Slack | Supply the Slack App ID, Slack workspace ID, OAuth client ID, and client secret, then complete app verification. The organization uses one app and Slack workspace. Existing workspace Slack bots remain separate. | -| Fireflies and Granola | Add the provider. Sim supplies the MCP endpoint and handles OAuth client registration. People only complete their own authorization. | -| HubSpot (member access) | The deployment supplies a registered HubSpot MCP OAuth app. People sign in and allow CRM read access. See [HubSpot Search](/search/hubspot). | -| Databricks | Enter a name, the tenant's MCP URL, a registered OAuth client ID, and a client secret if required by that client. | - -For Databricks, **Add** validates and saves the configuration before the provider appears in the list. Cancelling the form leaves nothing added. Use an official Databricks HTTPS MCP endpoint, such as `https://your-workspace.cloud.databricks.com/api/2.0/mcp/sql`, and the OAuth client registered for your deployment. People connecting later use this organization configuration. +| OAuth providers such as Gmail or Google Drive | Add the provider; each invited person authorizes their account | +| Slack | Supply the Slack App ID, Slack workspace ID, OAuth client ID, and client secret, then verify the app; the organization uses one app and Slack workspace | +| Fireflies and Granola | Add the provider; Sim supplies the MCP endpoint and handles OAuth client registration | +| HubSpot member access | The deployment must supply a registered HubSpot MCP OAuth app; people authorize CRM read access; see [HubSpot Search](/search/hubspot) | +| Databricks | Enter a name, the tenant's HTTPS MCP URL, a registered OAuth client ID, and a client secret if that client requires one | -When editing Databricks, leaving the client secret blank preserves the saved secret. Changing the MCP URL or OAuth client requires people to reconnect. +Existing workspace Slack bots and their triggers remain separate from the organization's personal Slack connections. -Adding a provider makes account connections available; it does not add a Search source or start document indexing. Search source setup is managed under **Settings → Sources**. Live Search queries providers on demand. Credential Groups has no indexing controls or status indicators. Managed MCP providers support live tool calls. +For Databricks, use an official endpoint such as `https://your-workspace.cloud.databricks.com/api/2.0/mcp/sql` and the OAuth client registered for the deployment. **Add** validates and saves the configuration before the provider appears; cancelling adds nothing. Leaving the client secret blank while editing preserves it. Changing the endpoint or OAuth client requires people to reconnect. -### 2. Invite people +### 2. Request connections -Open **Settings → Credential Groups → People**. Set up the provider before inviting people; a Search source does not replace required OAuth or managed MCP configuration. +Configure the providers before inviting people. A Search source does not replace required OAuth or managed MCP setup. -1. Select **Request connections**. -2. Enter their email addresses and select **Send requests**. -3. Each person opens the invitation, signs in to Sim with the verified invitation email, and authorizes the providers they want to connect. -4. They select **Submit** to finish the connection form. +1. Open **People** and select **Request connections**. +2. Enter email addresses and select **Send requests**. +3. Each invitee opens the invitation, signs in with its verified Sim email, and authorizes the providers they want to contribute. +4. They select **Submit** to finish the form. -Invitees can contribute accounts without joining your organization. The invitation grants access to their connection form; it does not grant access to your workspaces or workflows. +Invitees can contribute accounts without joining your organization. The invitation gives access to the connection form, not to your workspaces or workflows. -Use the invitation email in workflow lookups. For example, if you invite `alex@example.com`, **Find Organization Account** with that email and **Gmail** finds Alex's active Gmail contribution. +Use the invitation email for workflow lookups. For example, inviting `alex@example.com` lets **Find Organization Account** look up Alex's active Gmail contribution with that email and **Gmail**. #### How the email is associated with a Sim user -On first use, the invitation email must match the signed-in user's verified Sim email. Sim then binds the invitation to that user's account. Another person cannot take it over by opening the link, and a later email change does not transfer it to a different Sim user. The invitation email remains the workflow lookup key. +On first use, the invitation email must match the signed-in user's verified Sim email. Sim binds the invitation to that user account. Opening the link as another person cannot take it over, and a later email change does not transfer it to another Sim user. The invitation email remains the workflow lookup key. -The verified Sim user who starts authorization must complete it. A provider account can use a different email from the invitation; the saved contribution belongs to the bound Sim user. Managed MCP connections likewise use that Sim user’s authorization. Keep using the invitation email for workflow lookups. Search separately checks current provider identity and any source-specific requirements. +The verified Sim user who starts authorization must complete it. The provider account may have a different email; its contribution belongs to the bound Sim user. Managed MCP connections use that person's authorization too. Search separately checks current provider identity and source-specific access requirements. -In **People**, open a person's actions menu and select **Resend** when they need another invitation. **Revoke** stops the organization from using that person's contributions. The person cannot undo an administrator's revocation by reconnecting on their own. +Use **Resend** in a person's menu when they need the invitation again. **Revoke** stops the organization from using their contributions. They cannot undo an administrator's revocation by reconnecting themselves. -### 3. Allow workspaces +### 3. Grant workspace access -Open **Workspace access** and select **Add workspaces** to choose one or more workspaces. The list shows workspaces that have access; use a row's **Remove** action to withdraw it. Adding or removing a workspace applies immediately. Only workspaces in this organization can be allowed. +1. Open **Access** and select **Add workspace**. +2. Choose one workspace in this organization. +3. Under **Integrations**, choose specific integration types or **All integrations**. +4. Select **Add workspace** to save the grant. - -An allowed workspace gives every authorized manual and deployed workflow in that workspace access to **every active account in the pool**. This includes scheduled, webhook, and public deployments that pass their normal workflow authorization. There is no separate workflow allowlist or restriction to the running user's own contributions. +A selected grant requires at least one integration. **All integrations** also includes integrations added to the pool later. Use **Edit access** to change the selection, **Save access** to save it, or **Remove access** to withdraw the grant. + + +Every normally authorized workflow in the workspace can use active accounts for its allowed integration types, including scheduled, webhook, and public deployments. There is no separate workflow allowlist or restriction to the running person's own contributions. Choose **All integrations** only when this exposure is intended. -For example, allowing the Support workspace lets its authorized workflows use Alex's Gmail contribution even when someone else runs the workflow. Allowing the workspace does not grant anyone permission to edit or run a workflow they could not otherwise access. +For example, allowing Gmail in the Support workspace lets its authorized workflows use Alex's Gmail contribution even when someone else runs them. The grant does not give anyone permission to edit or run a workflow they could not otherwise access. -Removing a workspace stops subsequent use of the pool. It does not recall provider requests already in flight or remove data a workflow has already received. Chat continues to use each person's own connections; workspace access does not give Chat access to other people's accounts. +Changes apply to subsequent calls. Removing access cannot recall a provider request already in flight or erase data already received. Standalone Chat continues to use each person's own connections; the workspace grant does not give Chat other people's accounts. -## Use accounts in workflows +## Use account references in workflows -Use the **Credential** block's organization operations in an allowed workspace: +In an eligible workspace, use the Credential block's organization operations: -- **Find Organization Account** selects an OAuth account by invitation email and provider. -- **List Organization Accounts** returns a page of OAuth accounts, optionally filtered by email and providers. -- **Find Organization MCP Connection** selects a person's managed MCP connection by invitation email and MCP provider. -- **List Organization MCP Connections** returns a page of managed MCP connections, optionally filtered by email and provider. +| Operation | Result | +| --- | --- | +| **Find Organization Account** | One OAuth account matching the invitation email and provider | +| **List Organization Accounts** | A page of OAuth accounts, optionally filtered by email and providers | +| **Find Organization MCP Connection** | One managed MCP connection matching the invitation email and MCP provider | +| **List Organization MCP Connections** | A page of managed MCP connections, optionally filtered by email and provider | -The organization is determined by the workflow's workspace. You do not enter a credential group ID or organization ID in the block. +The workflow's workspace determines the organization. You do not enter a credential group or organization ID. -The outputs are account references, without tokens. Use an OAuth `credentialId` in the corresponding integration block's credential field. For managed MCP, `credentialId` identifies the person's connection; `mcpServerId` identifies shared configuration and cannot select that person's authorization by itself. +Outputs contain account references, not tokens. Use an OAuth `credentialId` in a compatible integration block's credential field. For managed MCP, `credentialId` selects the person's connection. `mcpServerId` identifies shared configuration and cannot select that person's authorization by itself. See the [Credential block reference](/workflows/blocks/credential#organization-accounts) for inputs, outputs, pagination, and connection-event triggers. ## Reconnect or stop sharing -People can open **Settings → Account → Connected accounts** to view accounts they contributed, including contributions to organizations they have not joined. **Reconnect** starts authorization again. **Disconnect** stops the organization from using that account in subsequent calls. +Contributors can open **Settings → Account → Connected accounts** to inspect their contributions, including contributions to organizations they have not joined. **Reconnect** starts authorization again. **Disconnect** stops subsequent organization use of that account. -For administrators, the controls have different scopes: +Administrative controls have different scopes: | Action | Effect | | --- | --- | -| Remove a provider | Stops use of that provider's contributions in the pool | -| Revoke a person | Stops use of all that person's contributions to the organization | -| Remove a workspace from the allowlist | Stops that workspace's workflows from using the pool | - -## Current limits and troubleshooting - -- **One pool per organization:** there are no additional groups, per-workflow grants, or per-account workspace allowlists. -- **One Databricks configuration:** multiple tenant endpoints cannot be added as separate Databricks providers in the same pool. -- **Organization operations are missing:** confirm the feature is enabled for the organization and the workflow's workspace is allowed. -- **An invitation rejects your sign-in:** use the verified Sim account matching the invitation email. The provider account can have a different email; the invitation stays bound to the verified Sim user. -- **A Find operation fails:** it requires exactly one active matching connection. Check the invitation email, provider, connection status, and workspace access. It never chooses an arbitrary account when there are zero or multiple matches. -- **A list seems incomplete:** organization list operations return up to 100 connections per page. Follow `nextCursor` while `hasMore` is true. -- **A legacy Credential Group block fails:** replace it with the appropriate Credential block operation or trigger, update its output references, and redeploy the workflow. +| Remove an integration | Stops use of that provider's contributions in the pool | +| Revoke a person | Stops use of all their contributions to the organization | +| Change a workspace grant | Limits it to the selected integration types | +| Remove a workspace grant | Stops its workflows from using the pool | + +## Limits and troubleshooting + +- **Pool and grant limits:** one pool per organization and up to 1,000 workspace grants. Grants select integration types, not individual people's accounts. There is no separate per-workflow allowlist. +- **Databricks:** one tenant configuration per pool; multiple endpoints cannot be added as separate Databricks providers. +- **Missing organization operations:** check organization availability, the workspace grant, and its selected integration types. +- **Rejected sign-in:** use the verified Sim account matching the invitation email. The provider account can have a different email. +- **Failed Find operation:** it requires exactly one active match. Check email, provider, connection status, and allowed integration type. Zero or multiple matches cause an error; Sim does not choose an arbitrary account. +- **Incomplete list:** list operations return up to 100 connections per page. Follow `nextCursor` while `hasMore` is true. +- **Migration-review error:** an operator must review existing pool policies and Search dependencies before enabling workflow sharing. Setting the feature flag does not migrate old grants; affected people may need to reconnect. +- **Legacy Credential Group block:** replace it with the appropriate Credential operation or trigger, update output references, and redeploy. diff --git a/apps/docs/content/docs/platform/costs.mdx b/apps/docs/content/docs/platform/costs.mdx index 583f1aceb73..9f77c9e5829 100644 --- a/apps/docs/content/docs/platform/costs.mdx +++ b/apps/docs/content/docs/platform/costs.mdx @@ -1,528 +1,317 @@ --- -title: Cost calculation +title: Credits, billing and limits +description: Understand Cloud usage charges, BYOK, subscriptions, spend controls, and execution limits. --- import { Callout } from 'fumadocs-ui/components/callout' -import { Tab, Tabs } from 'fumadocs-ui/components/tabs' -import { Image } from '@/components/ui/image' +import { Tab, Tabs } from '@/components/ui/tabs' -Sim calculates workflow usage from the base run charge, billable model usage, and hosted tool usage. +Sim Cloud measures billable usage in **credits**: **1 credit = $0.005**, or **$1 = 200 credits**. For example, $10 of usage is 2,000 credits. -## Credits +The plan and execution tables below describe Cloud defaults. Enterprise agreements and deployment configuration can change them. Billing-disabled self-hosted deployments do not apply Sim plan-based usage billing; provider and infrastructure costs still apply. See [Self-hosted limits](#self-hosted-limits). -Sim uses **credits** as the unit of measurement for all usage. **1 credit = $0.005**. +## What a workflow run costs -All plan limits, usage meters, and billing thresholds are displayed in credits throughout the Sim UI. Dollar amounts in this documentation are provided for reference. +A billable workflow run can include: -## How Costs Are Calculated +| Component | Charge | +| --- | --- | +| Base run | 1 credit ($0.005), including runs without model calls | +| Hosted models | Recorded model usage at the applicable Sim rate | +| Hosted tools | Operation charges when using Sim-provided provider keys | +| Sandbox runtime | Applicable runtime charges, such as a Pi sandbox | -Workflow runs can include these cost components: +With your own provider keys, you pay the provider directly for those calls. The workflow base charge and unrelated hosted-tool or sandbox usage still apply. Local Ollama or vLLM inference avoids an external model API charge, but still needs infrastructure and any enabled Sim run charge. -**Base Run Charge**: 1 credit ($0.005) per run - -**AI Model Usage**: Variable cost based on token consumption. - -**Hosted Tool Usage**: Per-operation charges for tools using Sim-provided keys. +For a simple uncached model call, with prices in USD per million tokens: ```text -modelCost = (inputTokens × inputPrice + outputTokens × outputPrice) / 1,000,000 -totalCredits = baseRunCharge + (billableModelCost + hostedToolCost) × 200 +modelCostUSD = (inputTokens × inputPrice + outputTokens × outputPrice) / 1,000,000 +runCredits = 1 + billableModelCostUSD × 200 + hostedToolCostUSD × 200 + sandboxCostUSD × 200 ``` - - AI model prices are per million tokens. A workflow with no billable model usage or hosted tool usage incurs only the base run charge. - +Cached input, cache writes, model routing, and provider-specific usage can change the calculation. Use the recorded run cost to compare configurations. Internal child executions that share their parent's base charge do not add another base fee. -## Model Breakdown in Logs +### Inspect recorded usage -For workflows using AI blocks, you can view detailed cost information in the logs: +Open a run in **Logs → Overview** to inspect its cost rows, **Total**, and available input/output token counts. Current runs list ledger items such as **Base Run** and model or tool charges. Older runs may contain only a total. Displayed credit rows are apportioned so they add up to the displayed total. -
- Model Breakdown -
+Chat, Knowledge Base processing, and dictation also record usage outside ordinary workflow runs. The **Agent block** source label in organization Insights refers to the **Sim Chat** workflow block, whose usage is metered separately from its containing workflow. Ordinary Agent model calls are part of Workflow usage. See [Usage monitoring](/platform/enterprise/usage-tracking) for attribution. -The model breakdown shows: -- **Token Usage**: Input and output token counts for each model -- **Cost Breakdown**: Individual costs per model and operation -- **Model Distribution**: Which models were used and how many times -- **Total Cost**: Aggregate cost for the entire workflow run +### Hosted tool rates -## Pricing Options +These are configured hosted-tool base rates in USD, not a provider's retail subscription price. Actual usage is recorded per operation. A provider credit, such as a Firecrawl credit, is a different unit from a Sim credit. -With Sim-provided model keys, model usage is billed through Sim. With your own keys, you pay the provider directly; the workflow base charge still applies. Check the provider's current pricing when estimating a run, and use the run's recorded usage to compare configurations. +| Provider | Operation | Base rate | +| --- | --- | --- | +| Firecrawl | Scrape, Crawl, Search, Extract, Map | $0.001 per Firecrawl credit reported by the operation | +| Exa | Search, Get Contents, Find Similar Links, Answer | Cost returned by the API | +| Serper | Search with up to 10 results | $0.001 | +| Serper | Search with more than 10 results | $0.002 | +| Perplexity | Search | $0.005 per request | +| Perplexity | Chat | Token-based, depending on the model | +| Linkup | Standard search | $0.006 | +| Linkup | Deep search | $0.055 | +| Parallel AI | Turbo or Fast search, up to 10 returned results | $0.001 | +| Parallel AI | Basic or Advanced search, up to 10 returned results | $0.005 | +| Parallel AI | Search results beyond 10 | $0.001 per additional returned result | +| Parallel AI | Extract | $0.001 per URL | +| Parallel AI | Deep Research | $0.005–$2.40, depending on processor tier | +| Jina AI | Read URL | $0.20 per million tokens | +| Jina AI | Search | $0.20 per million tokens, with a 10,000-token minimum | +| Google Cloud | Translate / Detect | $0.00002 per character | +| Google Maps | Geocode, Directions, Elevation, Timezone, Reverse Geocode, Geolocate, Validate Address | $0.005 per request | +| Google Maps | Distance Matrix | $0.005 per returned matrix element | +| Google Maps | Snap to Roads | $0.01 per request | +| Google Maps | Place Details | $0.017 per request | +| Google Maps | Places Search | $0.032 per request | +| Google Cloud | PageSpeed; Books Search and Details | No hosted-tool charge | +| Brandfetch | Search | No hosted-tool charge | +| Brandfetch | Get Brand | $0.04 per request | -## Hosted Tool Pricing +Supported providers can use your own keys instead. A workflow containing a no-charge tool still has its base run charge. -When workflows use tool blocks with Sim's hosted API keys, costs are charged per operation. Use your own keys via BYOK to pay providers directly instead. +## Bring your own key (BYOK) - - - **Firecrawl** - Web scraping, crawling, search, and extraction - - | Operation | Cost | - |-----------|------| - | Scrape | $0.001 per credit used | - | Crawl | $0.001 per credit used | - | Search | $0.001 per credit used | - | Extract | $0.001 per credit used | - | Map | $0.001 per credit used | - +Store your provider keys under **Settings → BYOK** to use them instead of Sim-hosted keys. BYOK avoids Sim's model or tool usage charge for the provider calls it covers; you pay that provider directly. - - **Exa** - AI-powered search and research - - | Operation | Cost | - |-----------|------| - | Search | Dynamic (returned by API) | - | Get Contents | Dynamic (returned by API) | - | Find Similar Links | Dynamic (returned by API) | - | Answer | Dynamic (returned by API) | - +### Key scope and precedence - - **Serper** - Google search API +| Scope | Applies to | Who manages it | Cloud availability | +| --- | --- | --- | --- | +| **Workspace** | One workspace | Workspace Admin | Any plan | +| **Organization** | Current and future workspaces in the organization | Organization Owner or Admin | Active Pro for Teams, Max for Teams, or Enterprise | - | Operation | Cost | - |-----------|------| - | Search (≤10 results) | $0.001 | - | Search (>10 results) | $0.002 | - +Saved-key precedence is resolved separately for each provider: - - **Perplexity** - AI-powered chat and web search +1. Use that provider's workspace key pool when one is configured. +2. Otherwise, use its eligible organization key pool. +3. Otherwise, use the next available configured source, including a Sim-hosted key where supported. - | Operation | Cost | - |-----------|------| - | Search | $0.005 per request | - | Chat | Token-based (varies by model) | - +A workspace OpenAI key does not override the organization's Anthropic key. The settings page marks inherited providers so you can inspect inheritance before adding an override. A nonempty workspace pool is exclusive; a corrupt workspace key is not a reason to borrow an organization key. - - **Linkup** - Web search and content retrieval +### Add or remove keys - | Operation | Cost | - |-----------|------| - | Standard search | ~$0.006 | - | Deep search | ~$0.055 | - +1. Open **Settings → BYOK**. +2. Choose **Workspace**, or **Organization** if you are an organization administrator. +3. Select **Add Key** for the provider, enter the key, and save. - - **Parallel AI** - Web search, extraction, and deep research - - | Operation | Cost | - |-----------|------| - | Search (≤10 results) | $0.005 | - | Search (>10 results) | $0.005 + $0.001 per additional result | - | Extract | $0.001 per URL | - | Deep Research | $0.005–$2.40 (varies by processor tier) | - +You can store several keys for a provider in each scope. Requests rotate across the keys in the selected pool. Keys are encrypted at rest; the browser receives a masked display value, not the full saved key. - - **Jina AI** - Web reading and search +Deleting the last workspace key lets that provider inherit an eligible organization key or use its next available configured source. Deleting an organization key affects workspaces that inherited it. Key deletion takes effect on subsequent resolution. - | Operation | Cost | - |-----------|------| - | Read URL | $0.20 per 1M tokens | - | Search | $0.20 per 1M tokens (minimum 10K tokens) | - +If the organization's plan lapses, its keys stop applying and workspaces use their next available source. Saved organization keys remain, and organization administrators can delete them; adding or updating them requires an active organization plan. - - **Google Cloud** - Translate, Maps, PageSpeed, and Books APIs - - | Operation | Cost | - |-----------|------| - | Translate / Detect | $0.00002 per character | - | Maps (Geocode, Directions, Distance Matrix, Elevation, Timezone, Reverse Geocode, Geolocate, Validate Address) | $0.005 per request | - | Maps (Snap to Roads) | $0.01 per request | - | Maps (Place Details) | $0.017 per request | - | Maps (Places Search) | $0.032 per request | - | PageSpeed | Free | - | Books (Search, Details) | Free | - - - - **Brandfetch** - Brand assets, logos, colors, and company info - - | Operation | Cost | - |-----------|------| - | Search | Free | - | Get Brand | $0.04 per request | - - - -## Bring Your Own Key (BYOK) - -Use your own API keys for supported providers instead of Sim's hosted keys to pay base prices with no markup. + +The Pi block's **Create PR**, **Update PR**, and **Plan** modes run a model client inside a sandbox. The resolved key, including an inherited organization key, is exposed to that sandbox. To keep an organization key out, configure a workspace key for that provider. Pi web search requires an explicit block key and does not fall back to stored keys. See [Pi](/workflows/blocks/pi). + -### Supported Providers +### Provider catalog -The BYOK settings page groups providers the same way. +The settings page groups keys into **Models**, **Search & web**, and **Enrichment**. It is the current catalog; the following lists describe the supported uses. - | Provider | Usage | - |----------|-------| - | OpenAI | LLM calls and Knowledge Base embeddings | - | Anthropic | LLM calls | - | Google | LLM calls | - | Mistral | LLM calls and Knowledge Base OCR | - | Z.ai | LLM calls | + | Provider | Use | + | --- | --- | + | OpenAI | Model calls and Knowledge Base embeddings | + | Anthropic | Model calls | + | Google | Model calls | + | Mistral | Model calls and Knowledge Base OCR | + | Z.ai | Model calls | | Cohere | Embeddings and Knowledge Base reranking | - | xAI | LLM calls | - | Kimi | LLM calls | - | Fireworks | LLM calls | - | Together AI | LLM calls | - | Baseten | LLM calls | - | Ollama Cloud | LLM calls | + | xAI | Model calls | + | Kimi | Model calls | + | TypeSafe | Jev evaluation models | + | Fireworks | Model calls | + | Together AI | Model calls | + | Baseten | Model calls | + | Nebius | Model calls | + | Ollama Cloud | Model calls | + | Kie | Model calls | | Fal.ai | Image and video generation | - | Provider | Usage | - |----------|-------| - | Firecrawl | Web scraping, crawling, search, and extraction | - | Exa | AI-powered search and research | - | Context.dev | Web scraping, crawling, search, and brand intelligence | + | Provider | Use | + | --- | --- | + | Firecrawl | Scraping, crawling, search, and extraction | + | Exa | Search and research | + | Context.dev | Scraping, crawling, search, and brand intelligence | + | TinyFish | Web agent automation, search, and page fetching | | Serper | Google search API | - | Linkup | Web search and content retrieval | - | Parallel AI | Web search, extraction, and deep research | - | Perplexity | AI-powered chat and web search | + | Linkup | Search and content retrieval | + | Parallel AI | Search, extraction, and deep research | + | Perplexity | Chat and web search | | Jina AI | Web reading and search | | Google Cloud | Translate, Maps, PageSpeed, and Books APIs | - | Provider | Usage | - |----------|-------| - | Brandfetch | Brand assets, logos, colors, and company info | - | Hunter | Email finder, verification, and domain search | + | Provider | Use | + | --- | --- | + | Brandfetch | Brand assets and company information | + | Hunter | Email finding, verification, and domain search | | People Data Labs | Person and company enrichment, search, and identity | - | Findymail | Email finder, verification, and phone lookup | + | Findymail | Email finding, verification, and phone lookup | | Prospeo | Person and company enrichment and search | | Wiza | Prospect search, individual reveal, and company enrichment | | Datagma | Email, phone, person, and company enrichment | | Dropcontact | Contact enrichment and email finding | - | LeadMagic | Email finding, validation, and B2B profile enrichment | + | LeadMagic | Email finding, validation, and profile enrichment | | Icypeas | Email finding and verification | | Enrow | Email finding and verification | - | ZeroBounce | Real-time email validation and deliverability checks | - | NeverBounce | Real-time email verification and list cleaning | - | MillionVerifier | Real-time email verification and deliverability checks | + | ZeroBounce | Email validation and deliverability checks | + | NeverBounce | Email verification and list cleaning | + | MillionVerifier | Email verification and deliverability checks | -### Key scopes - -A key is stored at one of two scopes. - -| Scope | Applies to | Who can manage | Plan | -|-------|------------|----------------|------| -| **Workspace** | That workspace only | Workspace **admin** | Any plan on Sim Cloud | -| **Organization** | Every current and future workspace in the organization | Organization **admin** or **owner** | Any organization plan on Sim Cloud — Pro for Teams, Max for Teams, or Enterprise | - -Organization keys let you set a provider key once instead of repeating it in every workspace. A new workspace added to the organization picks them up automatically. +## Cloud plans and credit allowances -### Which key a run uses +Current monthly pricing and allocations are: -Precedence is resolved **per provider**, not per workspace: +| Plan | Monthly price | Included credits | Weekly refresh | +| --- | --- | --- | --- | +| Free | $0 | 1,000 one-time | None | +| Pro | $25 per seat | 6,000/month per seat | 2,000/week per seat | +| Max | $100 per seat | 25,000/month per seat | 4,000/week per seat | +| Enterprise | By agreement | By agreement | By agreement | -1. The workspace's own key for that provider, if it has one -2. Otherwise, the organization's key for that provider -3. Otherwise, Sim's hosted key, with the multiplier applied +Pro and Max are available for individuals or teams. Team subscriptions pool credits across internal seats. For example, Max for Teams with three seats has a 75,000-credit monthly allocation and a 12,000-credit weekly refresh allowance. External collaborators do not add seats, but their work in an organization-owned workspace is billed to that organization. -So a workspace that stores its own OpenAI key still inherits the organization's Anthropic key. A workspace key always wins over the organization key for the same provider — adding one is how you override inheritance for a single workspace. +See [current pricing](https://www.sim.ai/pricing) and **Settings → Subscription** for the plan available to your account. Internal membership, external eligibility, and workspace migration are explained in [Roles and permissions](/platform/permissions#internal-and-external-membership). -The BYOK settings page tags every provider your workspace is inheriting, so you can see which keys come from the organization before you override them. +### Weekly refresh -### Setup +Each seven-day window from the billing period's start excludes usage up to the weekly refresh allowance from billable usage. It is an allowance against that week's usage, not an accumulating wallet balance. Unused allowance does not carry forward. Team allowances scale with seats. -1. Navigate to **Settings** → **BYOK** in your workspace -2. Choose **Workspace** or **Organization** (organization admins only) -3. Click **Add Key** for your provider -4. Enter your API key and save +### Annual billing -You can store several keys per provider per scope. Requests are distributed evenly across the keys in whichever scope is in effect. +Pro and Max annual subscriptions have a 15% discount while retaining their advertised included credits. Team pricing uses the same per-seat rate. - - BYOK keys are encrypted at rest and are never returned to the browser in full — the settings page only ever shows a masked value. - +| Plan | Monthly billing | Annual equivalent per month | Annual price per seat | +| --- | --- | --- | --- | +| Pro | $25 | $21.25 | $255 | +| Max | $100 | $85 | $1,020 | - - The Pi block's **Create PR**, **Update PR**, and **Plan** modes run the model client inside a sandbox, so the resolved key — including an inherited organization key — is exposed to that sandbox. To keep an organization key out of it, give the workspace its own key for that provider. Pi's optional web search never falls back to a stored key; it always requires an explicit key on the block. - +Use subscription settings to choose the billing interval. The usage display names the current billing period; check it when comparing usage across an interval change. -Deleting a workspace key makes that workspace fall back to the organization key if one exists, and to Sim's hosted keys otherwise. Deleting an organization key makes every workspace that was inheriting it fall back the same way. +## Control spending -If your organization's plan lapses, organization keys stop applying and those workspaces fall back to Sim's hosted keys with the multiplier. The keys are retained, and organization admins can still delete them, but adding or updating them requires an active organization plan. +By default, paid usage is capped at the included allowance and any applied credit balance. Under **Settings → Subscription**, either: -## Voice Input +- Turn on **Allow usage to go past included usage** under **Enable on-demand usage** to remove the normal usage cap. +- Set a higher **Usage limit** to allow overage up to a specific ceiling. -Voice input uses ElevenLabs Scribe v2 Realtime for speech-to-text transcription. It is available in Chat and in deployed chat voice mode. +Applied credit balance increases the covered allowance. A balance grant alone does not enable on-demand billing. Disabling on-demand returns the limit to the covered amount; the control is disabled while current usage is already above that amount, until usage falls back or the period resets. -| Context | Cost per session | Max duration | -|---------|-----------------|--------------| -| Chat (workspace) | ~5 credits ($0.024) | 3 minutes | -| Deployed chat (voice mode) | ~2 credits ($0.008) | 1 minute | +Organization owners and admins manage organization billing and spend limits. Workspace Admin access alone does not grant that authority. Organization **Manage credits** controls a member's usage cap; it is not a credit-purchase control. -Each voice session is billed when it starts. In deployed chat voice mode, each conversation turn (speak → agent responds → speak again) is a separate session. Multi-turn conversations are billed per turn. +### Subscription and overage example - - Voice input requires `ELEVENLABS_API_KEY` to be configured. When the key is not set, voice input controls are hidden. - +If a Pro account has 7,000 billable credits after weekly-refresh deductions and applied credits, its charge is $25 for the subscription plus $5 for the 1,000-credit overage. Continuing beyond the allowance requires on-demand usage or a higher limit. -## Plans +For team plans, overage is calculated against the organization's pooled allowance. Usage in organization-owned workspaces is billed to that organization, including external collaborators' work. Attributed human usage can also count toward the person's organization member cap. The organization receives one bill. Enterprise usage and limits follow the agreement rather than ordinary Pro/Max overage billing. -Sim has two paid plan tiers - **Pro** and **Max**. Either can be used individually or with a team. Team plans pool credits across all seats in the organization. +### Threshold billing -| Plan | Price | Credits Included | Weekly Refresh | -|------|-------|------------------|----------------| -| **Community** | $0 | 1,000 (one-time) | - | -| **Pro** | $25/mo | 6,000/mo | +2,000/week | -| **Max** | $100/mo | 25,000/mo | +4,000/week | -| **Enterprise** | Custom | Custom | - | +The default incremental billing threshold is $100 of unbilled overage, equivalent to 20,000 credits. Sim automatically settles eligible overage during the billing period instead of waiting for one large period-end bill. -To use Pro or Max with a team, select **Get For Team** in subscription settings and choose the tier and number of seats. Credits are pooled across the organization at the per-seat rate (e.g. Max for Teams with 3 seats = 75,000 credits/mo pooled). +| Point in period | Total overage | New settlement | +| --- | --- | --- | +| Day 10 | $120 | $120 | +| Day 15 | $180 | None; only $60 remains unbilled | +| Day 20 | $260 | $140, the unbilled amount since the first settlement | -Internal organization members use seats and contribute to the team's pooled credit allocation. External workspace members do not join your organization or count toward its seat total. They appear in the roster with an External label. +Any remaining eligible overage is settled at period end. Applied balances and billing eligibility affect the amount charged. -### Weekly Refresh Credits +## Cloud limits -Paid plans include a weekly credit allowance that does not count toward your plan limit. Each week, usage up to the weekly refresh amount is excluded from billable usage. This allowance resets every 7 days from your billing period start and does not carry over - use it or lose it. - -| Plan | Weekly Refresh | -|------|----------------| -| **Pro** | 2,000 credits/week ($10.00) | -| **Max** | 4,000 credits/week ($20.00) | - -For team plans, the weekly refresh scales with seats (e.g. Max for Teams with 3 seats = 12,000 credits/week). - -### Annual Billing - -All paid plans are available with annual billing at a **15% discount**. Switch between monthly and annual billing in Settings → Subscription. - -| Plan | Monthly | Annual (per month) | Annual Total | -|------|---------|-------------------|--------------| -| **Pro** | $25/mo | $21.25/mo | $255/yr | -| **Max** | $100/mo | $85/mo | $1,020/yr | - -Team plans follow the same pricing per seat. - -### On-Demand Billing - -By default, your usage is capped at the credits included in your plan. To allow usage beyond your plan's included amount, you can either enable **on-demand billing** or manually edit your usage limit to any value above your plan's minimum. - -- **Enable On-Demand**: Removes the usage cap entirely. You pay for any overage at the end of the billing period. -- **Edit Usage Limit**: Set a specific cap above your plan's included amount to control how much overage you're willing to allow. -- **Disable On-Demand**: Resets your usage limit back to the plan's included amount (only available if your current usage hasn't already exceeded it). - - - On-demand billing for team plans is managed by organization owners and - administrators. Workspace admin permission alone does not grant billing - authority. - - -## Plan Limits +These defaults follow the paid tier: Pro and Pro for Teams share Pro limits; Max and Max for Teams share Max limits. Enterprise values may be customized. Request rate, concurrent runs, storage, and run duration are separate limits. ### Workspaces -| Plan | Personal Workspaces | Shared (Organization) Workspaces | -|------|---------------------|----------------------------------| -| **Free** | 1 | — | -| **Pro** | Up to 3 | — | -| **Max** | Up to 10 | — | -| **Team / Enterprise** | — | Unlimited (Owners and Admins) | - -Team and Enterprise plans unlock shared workspaces that belong to your organization. Every workspace created under a Team or Enterprise plan is organization-owned: Owners and Admins can create unlimited shared workspaces, while organization Members cannot create workspaces. When someone joins the organization as an internal member, personal workspaces they own move into the organization and their usage is billed to it from then on. Internal members count toward your seat total — Enterprise invites require an available seat at invite time, while Team plans add a seat automatically when the invitee accepts. External workspace members get access to specific workspaces without joining your organization or using one of your seats; they must already be on a paid Sim plan (their own Pro or Max subscription, or another organization that seats them), and invitees who already belong to another organization always join this way. When a Team or Enterprise subscription is cancelled or downgraded, existing shared workspaces remain accessible to current members but new invites are disabled until the organization is upgraded again. - -### Rate Limits - -| Plan | Sync (req/min) | Async (req/min) | -|------|----------------|-----------------| -| **Free** | 50 | 200 | -| **Pro** | 150 | 1,000 | -| **Max** | 300 | 2,500 | -| **Enterprise** | 600 | 5,000 | - -Rate limits follow the paid tier: Pro and Pro for Teams share the Pro limits, while Max and Max for Teams share the Max limits. - -### Concurrent Executions +Free accounts have one personal workspace by default and Pro accounts up to three. Organization workspaces are uncapped for eligible organization owners and admins. For Max and other current account limits, check the workspace creation controls and [pricing](https://www.sim.ai/pricing), rather than assuming a personal-workspace cap from another deployment. -| Plan | Concurrent Executions | -|------|-----------------------| -| **Free** | 10 | -| **Pro** | 50 | -| **Max** | 200 | -| **Enterprise** | 1,000 by default (customizable) | +Accepting internal membership moves owned personal workspaces into the organization. See [Joining an organization](/platform/permissions#joining-an-organization) for the ownership and seat consequences. -The concurrency limit applies per billing account. For organization-based plans, the limit is shared by all workspaces, members, and API keys under that organization. Teams plans follow their tier: Pro for Teams uses the Pro limit and Max for Teams uses the Max limit. An admitted async execution holds a slot while queued and running; synchronous executions hold one while running. Workflow-in-workflow blocks execute inside the parent run and do not consume another concurrency slot. +### Rate limits -### File Storage +| Plan | Synchronous runs/minute | Asynchronous runs/minute | +| --- | --- | --- | +| Free | 50 | 200 | +| Pro | 150 | 1,000 | +| Max | 300 | 2,500 | +| Enterprise default | 600 | 5,000 | -| Plan | Storage | -|------|---------| -| **Free** | 5 GB | -| **Pro** | 50 GB | -| **Max** | 500 GB | -| **Enterprise** | 500 GB (customizable) | +Execution rate buckets can burst above the sustained per-minute rate. General API endpoint requests have a separate request bucket; these run rates do not describe every API call. See [API usage and limits](/api-reference/getting-started). -Storage follows the paid tier: Pro and Pro for Teams share the Pro limit, while Max and Max for Teams share the Max limit. Organization storage is pooled across the organization's workspaces. +### Concurrent executions -### Run Time Limits +| Plan | Concurrent runs | +| --- | --- | +| Free | 10 | +| Pro | 50 | +| Max | 200 | +| Enterprise default | 1,000; customizable | -| Plan | Sync | Async | -|------|------|-------| -| **Free** | 5 minutes | 90 minutes | -| **Pro / Max / Team** | 50 minutes | 90 minutes | -| **Enterprise** | 50 minutes | 90 minutes by default; configurable up to 7 days | +The limit applies per billing account. An organization's workspaces, members, and API keys share its concurrency pool. An admitted async run holds a slot while queued and running; a synchronous run holds one while running. Workflow-in-workflow blocks execute within the parent run and do not consume another slot. -**Sync runs** complete immediately and return results directly. These are triggered via the API with `async: false` (default) or through the UI. -**Async runs** (triggered via API with `async: true`, webhooks, schedules, polling triggers, or table workflow columns) run in the background. A direct async API request can shorten the account policy for that request, but cannot extend it. +### File storage - - If a workflow exceeds its time limit, it will be terminated and marked as failed with a timeout error. Design long-running workflows to use async runs or break them into smaller workflows. - - -## Billing Model - -Sim uses a **base subscription + overage** billing model: +| Plan | Storage default | +| --- | --- | +| Free | 5 GiB | +| Pro | 50 GiB | +| Max | 500 GiB | +| Enterprise | 500 GiB; customizable | -### How It Works +Organization storage is pooled across its workspaces. Storage limits are independent of the credit allowance. -**Pro Plan ($25/month - 6,000 credits):** -- Monthly subscription includes 6,000 credits of usage -- Usage under 6,000 credits → No additional charges -- Usage over 6,000 credits (with on-demand enabled) → Pay the overage at month end -- Example: 7,000 credits used = $25 (subscription) + $5 (overage for 1,000 extra credits at $0.005/credit) +### Run time limits -**Team Plans:** -- Usage is pooled across internal team members in the organization -- Usage in an organization-owned workspace is billed to that workspace's organization, including work performed by external collaborators -- Each authenticated actor's usage is also counted toward their member cap for that organization -- Overage is calculated from total team usage against the pooled limit -- Organization owner receives one bill +| Plan | Synchronous run | Asynchronous run | +| --- | --- | --- | +| Free | 5 minutes | 90 minutes | +| Pro / Max, including team subscriptions | 50 minutes | 90 minutes | +| Enterprise default | 50 minutes | 90 minutes; configurable up to 7 days | -**Enterprise Plans:** -- Fixed monthly price, no overages -- Custom usage limits per agreement +Synchronous execution waits for the workflow to finish and returns its result, or streams it when streaming is selected. Asynchronous API calls, webhooks, schedules, polling triggers, and table workflow columns run in the background. -### Threshold Billing +A direct async API request can shorten the account's timeout for that request; it cannot extend it. A run exceeding its limit fails with a timeout error. Individual blocks, remote sandboxes, and providers can have shorter independent limits. See [How workflows run](/workflows/how-it-runs). -When on-demand is enabled and unbilled overage reaches $100, Sim automatically bills the full unbilled amount. +### Self-hosted limits -**Example:** -- Day 10: $120 overage → Bill $120 immediately -- Day 15: Additional $60 usage ($180 total) → Already billed, no action -- Day 20: Another $80 usage ($260 total, $140 unbilled) → Bill $140 immediately +Billing-disabled deployments have no default plan-based workspace cap, workflow timeout, or storage enforcement. Operators can opt into rate, storage, and workflow timeout enforcement with the corresponding free-tier environment settings. The hosted billing-account concurrency reservation applies only when hosting and billing are enabled. -This spreads large overage charges throughout the month instead of one large bill at period end. +This does not remove protocol, provider, block, sandbox, or deployment resource limits. See [Self-hosting configuration](/platform/self-hosting/environment-variables) for exact settings. -## Usage Monitoring +## Monitor usage through the UI or API -Monitor your usage and billing in Settings → Subscription: +Use **Settings → Subscription** to inspect the current allowance, usage limit, billing period, on-demand setting, and plan. Organization administrators can inspect [Usage monitoring](/platform/enterprise/usage-tracking) for source, workspace, and member attribution. -- **Current Usage**: Real-time credit usage for the current billing period -- **Usage Limits**: Plan limits with a visual progress bar -- **On-Demand Billing**: Toggle on-demand billing to allow usage beyond your plan's included credits -- **Plan Management**: Upgrade, downgrade, or switch between monthly and annual billing +For workspace billing information, use [Get billing status](/api-reference/billing/getBillingStatus). [List billing logs](/api-reference/billing/listBillingLogs) exposes billable events. Billing and run-resource responses use credits, while Logs endpoints explicitly report USD; use each endpoint's documented unit. -### Programmatic Usage Tracking +The legacy `GET /api/users/me/usage-limits` endpoint accepts an API key in `X-API-Key`. It reports the authenticated account or key owner's usage and subscription, which can differ from a workflow's workspace payer. Its `usage.currentPeriodCost` and `usage.limit` are in USD. It also returns storage `usedBytes`, `limitBytes`, and `percentUsed`. -You can query your current usage and limits programmatically using the API: - -**Endpoint:** -```text -GET /api/users/me/usage-limits -``` - -**Authentication:** -- Include your API key in the `X-API-Key` header - -**Example Request:** -```bash -curl -X GET -H "X-API-Key: YOUR_API_KEY" -H "Content-Type: application/json" https://www.sim.ai/api/users/me/usage-limits -``` +Its rate fields are: -**Example Response:** -```json -{ - "success": true, - "rateLimit": { - "sync": { - "isLimited": false, - "requestsPerMinute": 150, - "maxBurst": 300, - "remaining": 300, - "resetAt": "2025-09-08T22:51:55.999Z" - }, - "async": { - "isLimited": false, - "requestsPerMinute": 1000, - "maxBurst": 2000, - "remaining": 2000, - "resetAt": "2025-09-08T22:51:56.155Z" - }, - "authType": "api" - }, - "usage": { - "currentPeriodCost": 12.34, - "limit": 100, - "plan": "pro_6000" - } -} -``` - -**Rate Limit Fields:** -- `requestsPerMinute`: Sustained rate limit (tokens refill at this rate) -- `maxBurst`: Maximum tokens you can accumulate (burst capacity) -- `remaining`: Current tokens available (can be up to `maxBurst`) - -**Response Fields:** -- `currentPeriodCost` reflects usage in the current billing period (in dollars) -- `limit` is derived from individual limits (Free/Pro/Max) or pooled organization limits (Team/Enterprise) -- `plan` is the highest-priority active plan associated with your user - -## Purchasing Additional Credits - -Pro and Team plan users can buy additional credits at any time in **Settings → Subscription → Credit Balance**: - -- **Range**: $10 to $1,000 per purchase -- **Conversion**: 1 credit = $0.005 (a $10 purchase adds 2,000 credits) -- **Availability**: Credits are added immediately after payment -- **Expiration**: Purchased credits do not expire -- **Refunds**: Purchases are non-refundable -- **Team plans**: Only organization owners and admins can purchase credits. Purchased credits are added to the team's shared pool. - - - Enterprise users should contact support for credit adjustments. - +| Field | Meaning | +| --- | --- | +| `requestsPerMinute` | Sustained token refill rate | +| `maxBurst` | Maximum accumulated tokens | +| `remaining` | Available tokens, up to `maxBurst` | +| `resetAt` | Reported bucket reset time | -## Cost Optimization Strategies +See [API authentication](/api-reference/authentication) before selecting a personal or workspace key for monitoring. -- **Model Selection**: Choose models based on task complexity. Simple tasks can use GPT-4.1-nano while complex reasoning might need o1 or Claude Opus. -- **Prompt Engineering**: Well-structured, concise prompts reduce token usage without sacrificing quality. -- **Local Models**: Use Ollama or VLLM for non-critical tasks to eliminate API costs entirely. -- **Caching and Reuse**: Store frequently used results in variables or files to avoid repeated AI model calls. -- **Batch Processing**: Process multiple items in a single AI request rather than making individual calls. +## Voice dictation usage -## Next Steps +Chat dictation uses ElevenLabs Scribe v2 Realtime. A workspace or organization dictation session has a three-minute maximum and records its charge when the token is issued, even if you stop speaking earlier. Its configured base cost is $0.024 per session, before the deployment's applicable cost policy. -- Review your current usage in [Settings → Subscription](https://www.sim.ai/settings/subscription) -- Learn about [Logging](/logs-debugging/logging) to track run details -- Explore the [External API](/api-reference/getting-started) for programmatic cost monitoring -- Check out [workflow optimization techniques](/workflows#blocks) to reduce costs +The deployment must configure `ELEVENLABS_API_KEY`; dictation controls are hidden when the service is unavailable. Deployed-chat voice mode is a separate surface; see [Chat deployments](/workflows/deployment/chat) for its setup rather than applying the dictation session limit to it. -import { FAQ } from '@/components/ui/faq' +## Related docs - +- [Secrets](/platform/credentials) +- [Logs](/logs-debugging/logging) +- [API getting started](/api-reference/getting-started) diff --git a/apps/docs/content/docs/platform/credentials.mdx b/apps/docs/content/docs/platform/credentials.mdx index 742fbe1f48d..30c1218e444 100644 --- a/apps/docs/content/docs/platform/credentials.mdx +++ b/apps/docs/content/docs/platform/credentials.mdx @@ -1,206 +1,176 @@ --- title: Secrets -description: Manage API keys and environment variables for your workflows +description: Save sensitive values, control access, and understand runtime resolution and protection. --- import { Callout } from 'fumadocs-ui/components/callout' import { Image } from '@/components/ui/image' -import { FAQ } from '@/components/ui/faq' -Secrets are key-value pairs that store sensitive data like API keys, tokens, and passwords. Instead of hardcoding values into your workflows, you store them as secrets and reference them by name at runtime. +Secrets store API keys, tokens, passwords, and other values by name. Reference a saved value with `{{KEY}}` instead of placing a literal secret in a workflow field. Saved secret values are encrypted before storage. -## Managing Secrets +## Scope and access -To manage secrets, open your workspace **Settings** and navigate to the **Secrets** tab. +Open **Settings → Secrets** in your workspace. The editor has **Workspace** and **Personal** sections. -Secrets tab showing Workspace and Personal sections with inline key-value rows - -Secrets are organized into two sections: - -- **Workspace** — shared with all members of your workspace -- **Personal** — private to you - -External workspace members count as workspace members for workspace-scoped secrets. They can use workspace secrets according to their workspace permission level, even though they are not members of your organization. - -### Adding a Secret - -Type a key name (e.g. `OPENAI_API_KEY`) into the **Key** column and its value into the **Value** column in the last empty row. A new empty row appears automatically as you type. Existing values are masked by default. +| Scope | Storage and management | Runtime access | +| --- | --- | --- | +| **Workspace** | Stored for this workspace; workspace Admins and that secret's Credential Admins can manage and reveal it | Workspace Admins and members with an active Credential Member or Admin grant can use it | +| **Personal** | Stored once for its owner across their workspaces; the editor manages your own values | Resolves under the authorized personal identity and current credential grants | -When you're done, click **Save** to persist all changes. +Workspace members, including external collaborators, can see workspace secret names. Seeing a name or having Write workspace access does not automatically grant use or reveal access. Creating a workspace secret requires **Write** or **Admin**. Managing an existing one requires Admin authority on the secret or workspace. - -Keys must use only letters, numbers, and underscores — no spaces or special characters. - +Personal secrets belong to their owner. Workspace and organization Admin roles do not grant access to them. Existing explicit personal credential grants can participate in runtime resolution, but the current Secrets editor and membership API do not create new personal-secret shares. -### Bulk Import +Credential Members can reveal a workspace secret only when its Admin enables [Show value in logs and Chat](#visibility). See [Roles and permissions](/platform/permissions#credential-access) for credential grants. -You can populate multiple secrets at once by pasting `.env`-style content into any key or value field. The parser supports standard `KEY=VALUE` pairs, `export KEY=VALUE`, quoted values, and inline comments. +## Add, import, edit, or delete a secret -### Editing and Deleting +Secrets editor with Workspace and Personal rows, masked values, Details, and Save -Click directly into any key or value cell to edit it. To delete a secret, click the trash icon on its row and save. +1. In the last empty row of the appropriate section, enter a **Key** such as `OPENAI_API_KEY` and its **Value**. +2. Use only letters, numbers, and underscores in the key. A new empty row appears as you type; saved values are masked by default. +3. Select **Save** to persist the changes. -## Using Secrets in Workflows +To import several values, paste `.env` content into a key or value field. The parser supports `KEY=VALUE`, `export KEY=VALUE`, quoted values, and inline comments. -To reference a secret in any input field, type `{{` to open the variable dropdown. Your available secrets are listed grouped by scope (workspace, then personal). +Edit cells directly. To delete a secret, select its row's trash icon and save. Update workflow references before deleting it: blocks that require the deleted value cannot resolve it. -Typing {{ in an input opens a dropdown showing available secrets +## Use a secret -Select the secret you want to use. The reference appears highlighted in blue and is resolved to its actual value at runtime. +Type `{{` in an input to open the variable picker. Available secrets are grouped by scope. Selecting one inserts a reference such as `{{OPENAI_API_KEY}}`; Sim resolves it to the real authorized value at runtime. A resolved secret reference shown as {{OPENAI_API_KEY}} -### Execution log protection +Among secrets the execution actor may use, the **workspace value takes precedence** over a personal value with the same name. An inaccessible workspace secret does not shadow an authorized personal value. -When a saved secret is successfully substituted through a `{{KEY}}` reference, Sim masks exact, case-sensitive occurrences of its resolved value in log-facing content. This includes the editor's live block-log display, Logs Overview input and output, stored execution traces, log-read API responses, and the Logs block's **Get Run Details** output. Function and Agent span inputs, outputs, and errors, Agent thinking, and Agent tool-call arguments, results, and errors are protected. The replacement is normally shown as `{{KEY}}`. +### Resolution identity -Secret resolution and functional workflow behavior are unchanged: blocks, tools, and downstream steps receive the real runtime value. Stored functional execution data, workflow execution responses, streams, callbacks, block state, and snapshots are not rewritten. Log-facing views and read APIs receive a separate protected copy, so the Logs Overview **Workflow Input** and **Workflow Output** are masked without changing the underlying workflow result. Model requests receive another protected projection: exact secret values known to the run are replaced with `{{KEY}}` before model-visible messages, prompts, tool arguments, or tool continuations leave Sim. +Workspace secrets authorize against the execution actor: an identifiable caller, or the workspace's configured billing account for background execution. The run sees only the workspace secrets that identity may use. -Code that reads a secret straight off the runtime environment — `environmentVariables['KEY']`, `environmentVariables.KEY`, or `const { KEY } = environmentVariables` in JavaScript, `environmentVariables['KEY']` or `environmentVariables.get('KEY')` in Python, `$KEY` or `${KEY}` in shell — also activates masking, provided Sim can see the read in the code before it runs. A hardcoded literal never does: Sim has no way to know it came from a secret. +The personal namespace depends on the trigger: - -Direct reads are found by reading the code, not by running it, so recognition stops where the code stops being readable ahead of time. An unrecognized read is not masked, and does not appear under **See usage**. +| Run started by | Personal namespace | +| --- | --- | +| Clicking **Run** or using a personal API key | The person running it | +| A workspace API key, schedule, webhook, or deployed chat | The workflow owner | +| An unauthenticated public API URL | None | -Where a read is recognized, Sim reports it rather than trying to prove it is not one. Code that shadows the environment binding with its own object, overwrites a variable before reading it, or assigns to the name instead of reading it is still reported. Naming a secret costs only an exact value the code never emits; failing to name one leaves it unmasked. **See usage** can therefore occasionally list a secret the code had available but did not read. +The workflow-owner fallback supports background workflows authored against that owner's keys; it is not a grant to borrow any person's secrets. An owner who has left the workspace or is suspended cannot supply that personal namespace. A stale workspace execution identity can also lose its secret access. -Assigning to the injected binding does not change the stored secret — it is an ordinary object built from the run's payload and discarded when the run ends. Edit a secret under **Settings → Secrets**. +Use workspace secrets with appropriate grants for production and public deployments. If an owner leaves, blocks requiring their personal values may fail even though workspace-backed blocks can continue. A public API caller receives no personal namespace. -A read is **not** recognized when: +## Secret details -- **The name is built at runtime.** `environmentVariables[keyName]`, `$@`, `${!indirect}`, `eval`, `printenv`, or a sourced file hide which secret is being read. -- **The read is of a different object.** `other.environmentVariables['KEY']` reads something that merely shares the name. -- **The read cannot be told apart from text.** A `$KEY` inside single quotes or a quoted heredoc (`<<'EOF'`) never expands, and Sim treats anything its scanner cannot place as not running. +Select **Details** on a row to open its detail page. You can inspect the key and, when authorized, reveal or edit the value. Return to **Secrets** or save changes from the detail page. -Both masking and model-bound projection match only exact values in either case. Encoded, hashed, fragmented, or otherwise transformed versions are not matched, and a value assembled or emitted piece by piece cannot be matched at all — determining whether arbitrary code will eventually reveal a value is not decidable in general. Treat these as a safety net, not a boundary: do not deliberately return, print, or transmit secrets. - +Workspace secrets also have: -### Copilot code execution +- **Description** for an optional purpose or rotation note. +- **Members** and **Share** to grant teammates Credential **Member** or **Admin** access. +- **Visibility** to control **Show value in logs and Chat**. -Copilot's Function and code-execution tools receive a saved secret only when their code explicitly contains a valid `{{KEY}}` reference. Direct `environmentVariables.KEY` access, shell `$KEY`, dynamic names, literals, and configured-but-unused secrets do not mount a value. Code execution requires workspace write access, and the caller must be allowed to **use** the secret — the same set a workflow resolves for them: your own Personal secrets, and Workspace secrets you hold an active grant on as a Credential Member or Credential Admin, which a workspace admin holds on every key. A secret you hold no grant on does not mount, and neither does one whose grant is revoked or still pending. +Description, member-sharing, and visibility controls do not apply to personal secrets. -This matches what a workflow Function block already resolves for the same person, deliberately. Being able to run a secret is not normally the same as being able to read it: Credential Members can reveal a workspace secret under **Settings → Secrets** only when a Credential Admin has enabled **Show value in logs and Chat**. **See usage** remains visible only to that secret's admins, so a Credential Member using a secret in code is recorded for whoever can rotate it. +### Visibility -Headless surfaces use their saved **Secret access** setting: +By default, Sim protects recognized secret values in log-facing and model-bound content. **Show value in logs and Chat** opts one workspace secret out of that protection. With it enabled: -- **Sim Chat block** — under **Show additional fields** -- **Scheduled Tasks** — in the task modal -- **Inbox** — under **Settings → Inbox → Secrets** +- Run logs, Chat, and code output can show its real value instead of `{{KEY}}`. +- Files written with the value can remain readable and attachable. +- The Secrets API list can include its value when the caller has the required access. +- Credential Members can reveal it under **Settings → Secrets**, without gaining edit permission. -Choose **All secrets** or **Selected secrets**. Existing configurations default to **All secrets** for compatibility. **All secrets** still means only secrets explicitly referenced with `{{KEY}}` that the execution actor may use; it never injects the full environment. Inbox messages from allowed external senders do not receive raw-secret access at all — an inbound message that Sim cannot match to a workspace member runs with no secret actor, so no `{{KEY}}` resolves for it. + +The value can become visible to anyone who can see the workspace's runs, including public shared-log links and exports, regardless of the secret's member restrictions. Enable this only for values safe to print, such as a non-sensitive base URL. + -Code receives the real authorized value at runtime. Before any Copilot-visible tool result is returned, exact occurrences of activated secret values are replaced with `{{KEY}}`; local side effects and runtime results are not rewritten. Encoded, hashed, URL-encoded, otherwise transformed, or network-exfiltrated values cannot be inferred and masked reliably, so code should not deliberately return, transform, print, or transmit secrets to unintended destinations. +Only a workspace or Credential Admin can change this workspace-only setting. It affects future runs: already masked logs stay masked, and previously written plaintext remains even after protection is restored. If another protected secret has the same value, protection wins. -## Secret Details +### See usage -Click **Details** on any secret row to open its detail view. +Select **See usage** to open its **Logs** and **References** views: -Secret details view showing Key, Value, Description, and Members sections +- **Logs** lists runs that resolved the secret: source workflow, Sim agent or MCP server; trigger; resolution identity; last use; and a link to the most recent run. Rows are grouped by day, so repeated scheduled runs can share one row. +- **References** shows saved workflow fields, custom tools, and MCP configuration that name the secret. A saved reference can exist before anything has run; it is different from recorded use. -From here you can: +Only Admins of a workspace secret, or the owner of a personal secret, can inspect its usage. Other members see a disabled action because the trail identifies workflows, people, and run IDs. Two owners with the same personal key name see their own records independently. -- View the **Key** and reveal the **Value** when visibility is enabled; Credential Admins can edit it -- Toggle **Visibility** — show the value unmasked in run output; see [Visibility](#visibility) -- Edit the **Description** — an optional note telling teammates what the secret is for. Workspace secrets only; a personal secret is not shared, so it has none -- Manage **Members** — invite teammates by email and assign them an **Admin** or **Member** role -- Open **See usage** — where this secret has actually been used +Usage is recorded separately from execution logs, so log expiry does not delete the usage record. It records recognized resolution, subject to the limits below. An empty trail means no use was recognized; it does not prove the secret was never used. Check both usage and references before rotating or deleting a key. -Click **Save** to apply changes, or **Back** to return to the list. +## Execution log protection -### Visibility +After a saved secret is successfully substituted through `{{KEY}}`, Sim masks exact, case-sensitive occurrences of its resolved value in log-facing content, unless it is exempt under **Show value in logs and Chat**. The replacement is normally `{{KEY}}`. -By default, a secret's resolved value is masked everywhere Sim shows run output (see [Execution log protection](#execution-log-protection)). For values that aren't actually sensitive — a non-secret shared base URL — that masking makes your own logs harder to read. +Protected content includes: -**Show value in logs and Chat** turns masking off for one workspace secret. With it on: +- The editor's live block logs and Logs **Overview** workflow input and output. +- Stored execution traces, log-read API responses, and the Logs block's **Get Run Details** output. +- Function and Agent span inputs, outputs, and errors. +- Agent thinking and tool-call arguments, results, and errors. -- Run logs, Chat, and code output show the real value instead of `{{KEY}}` -- Files a run writes with the value in them stay readable and attachable -- The Secrets API list includes the value for this secret, so external agents can read it directly instead of scraping logs -- Credential Members can reveal the value under **Settings → Secrets**, without gaining permission to edit it +Blocks, tools, and downstream steps still receive the real runtime value. Sim protects a separate copy for logs; it does not rewrite stored functional execution data, execution responses, streams, callbacks, block state, or snapshots. A workflow that returns a secret can therefore put it in its functional response even when the corresponding Logs view is masked. -The value becomes visible to **anyone who can see this workspace's runs** — including publicly shared log links and log exports, and regardless of member restrictions on the secret itself. Only turn it on for values you'd be comfortable printing in a log. +Model requests receive a separate protected projection. Exact recognized secret values are replaced before model-visible messages, prompts, tool arguments, or tool continuations leave Sim. This follows the same visibility exception and exact-value limitations; it does not remove secrets from the runtime operations that need them. -The switch applies to future runs only. Logs written while the secret was masked stay masked, and anything written while it was visible keeps the value even if you turn masking back on. If another secret holds the same value, that value stays masked — masking always wins a conflict. Workspace secrets only; the same people who can edit the description can flip it. +### Direct environment reads in workflow code -### See usage +Sim also activates protection when it recognizes a direct secret read in workflow code before execution: -**See usage** lists the runs that resolved this secret: when it was last used, what used it (a workflow, the Sim agent, or an MCP server), how it was triggered, who it resolved under, and a link to the most recent run in Logs. Rows are grouped by day, so a workflow on a schedule reads as one row per day rather than thousands. +| Language | Recognized forms | +| --- | --- | +| JavaScript | `environmentVariables['KEY']`, `environmentVariables.KEY`, `const { KEY } = environmentVariables` | +| Python | `environmentVariables['KEY']`, `environmentVariables.get('KEY')` | +| Shell | `$KEY`, `${KEY}` | -This answers the question worth asking before rotating a key: who has been using it, inside what, and how recently. +The scanner reads code rather than executing it. It can report a named key even if code shadows the environment binding with its own object, overwrites a variable before reading it, or assigns to the name rather than reading it. **See usage** can therefore include a secret that the run had available but did not read. -Only Credential Admins on a workspace secret, or the owner of a personal one, can see its usage. For everyone else the action is visible but disabled because the trail names workflows, people, and run IDs. Two people who each hold a personal secret under the same name see only their own runs. +Assigning to the injected environment object does not change the stored secret. The object is built for the run and discarded afterward. Edit stored values under **Settings → Secrets**. - -Usage is recorded independently of execution logs, so it outlives them: logs expire under your workspace's retention setting, while the record of who touched a credential does not. It records what a run resolved, subject to the recognition limits under [Execution log protection](#execution-log-protection) — a read Sim cannot attribute is left out rather than guessed at, so treat an empty trail as "nothing recognized," not proof a secret was never used. - +The scanner does not recognize a secret read when: + +- Its name is built at runtime, as in `environmentVariables[keyName]`, `${!indirect}`, or `$@`. +- `eval`, `printenv`, or a sourced file hides which key is read. +- The code reads another object, such as `other.environmentVariables['KEY']`. +- It cannot distinguish executable expansion from text. A shell `$KEY` inside single quotes or a quoted heredoc such as `<<'EOF'` does not expand. -## Workspace vs. Personal +An unrecognized read does not activate masking or appear under **See usage**. A hardcoded literal by itself does not activate secret protection. -| Feature | Workspace | Personal | -|---|---|---| -| **Who sees the name** | All workspace members, including external workspace members | Only you | -| **Who sees the value** | Workspace admins and that secret's Credential Admins; Credential Members when **Show value in logs and Chat** is enabled | Only you | -| **Use in workflows and code** | Workspace admins and members with an active Credential Member or Credential Admin grant | Only you can use | -| **Best for** | Production workflows, shared services | Testing, personal API keys | -| **Who can edit** | Workspace admins and that secret's Credential Admins | Only you | +### Protection limits - -Among secrets available to the execution actor, the **workspace secret takes precedence**. An inaccessible workspace secret does not shadow an authorized personal secret. + +Masking and model projection match exact values. Encoded, URL-encoded, hashed, transformed, fragmented, or piece-by-piece values are outside that protection. Do not deliberately return, print, or transmit a secret to an unintended destination. Protection is a safety net, not a boundary for arbitrary code. -### Resolution Order +## Secrets in Chat code execution -When a workflow runs, secrets resolve in this order: +Sim's Function and code-execution tools in Chat mount a saved secret only when their code explicitly includes a valid `{{KEY}}` reference. Direct `environmentVariables.KEY` reads, shell `$KEY`, dynamic names, hardcoded literals, and configured-but-unused secrets do not mount values through this path. -1. **Workspace secrets** are checked first, and always resolve against the identity running the workflow — the caller when one can be identified, otherwise the workspace's billing account. A run only sees the workspace secrets that identity is allowed to use. -2. **Personal secrets** are used as a fallback, from whichever identity is running: +Code execution requires workspace **Write** access. The execution actor must be allowed to use every requested secret: their personal namespace and active credential grants, or workspace Admin access to workspace secrets. Pending, revoked, or absent grants do not mount a value. This is use authority, separate from the authority to reveal a value in Settings or inspect its usage. -| Run started by | Personal secrets come from | -| --- | --- | -| Clicking Run, or a personal API key | The person running it | -| A workspace API key, schedule, webhook, or deployed chat | The workflow owner | -| A public API URL with no authentication | Nobody — personal secrets do not resolve | +Code receives the real authorized value. Before a tool result returns to Sim, exact occurrences of activated protected values are replaced with `{{KEY}}`. Local side effects and functional runtime results are unchanged. Protection does not prevent code from sending a real value over the network; the same transformation and transmission limits apply. + +### Headless secret selection + +The **Sim Chat** block exposes **Secret access** under **Show additional fields**. Inbox exposes it under **Settings → Inbox → Secrets**. Choose **All secrets** or **Selected secrets**. -The workflow owner is the fallback only where nobody can be identified but somebody in the workspace set the trigger up, since those workflows are usually built against the owner's own keys. A public URL can be called by anyone, so it never borrows a person's keys at all — put every secret such a workflow needs in **Workspace**. +Existing configurations default to **All secrets** for compatibility. This means explicitly referenced secrets that the execution actor may use; it does not inject the full environment. **Selected secrets** narrows that set. A reference outside the selected set rejects the code request rather than running it with a partial environment. -If the workflow owner later leaves the workspace, the run keeps working: it resolves workspace secrets as normal and simply resolves no personal ones, so any block that needed a personal secret fails on its own with the missing key named. Move that secret to **Workspace** to fix it for good. +Inbox messages from allowed external senders do not receive raw-secret access. If Sim cannot match the sender to a workspace member, it runs without a secret actor, so `{{KEY}}` cannot resolve through this path. Allowing an email sender is not a credential grant. -## Best Practices +Recurring work uses deployed workflow [Schedule triggers](/workflows/triggers/schedule). Configure secret access on the blocks that execute it; see [Chat actions and configuration](/chat/tasks) for the current setup flow. -- **Use workspace secrets for production** so workflows work regardless of who triggers them -- **Use personal secrets for development** to keep test keys separate -- **Name keys descriptively** — `STRIPE_SECRET_KEY` over `KEY1` -- **Never hardcode secrets** in workflow input fields — always use `{{KEY}}` references +## Related docs - +- [Roles and permissions](/platform/permissions) +- [Workflow variables](/workflows/variables) +- [Logs](/logs-debugging/logging) diff --git a/apps/docs/content/docs/platform/enterprise/access-control.mdx b/apps/docs/content/docs/platform/enterprise/access-control.mdx index d5ccb0d225c..cb77f55df4e 100644 --- a/apps/docs/content/docs/platform/enterprise/access-control.mdx +++ b/apps/docs/content/docs/platform/enterprise/access-control.mdx @@ -1,257 +1,140 @@ --- -title: Access Control -description: Restrict which models, blocks, and platform features each group of users can access +title: Permission groups +description: Limit models, blocks, tools, and platform actions for people in your organization's workspaces --- import { Callout } from 'fumadocs-ui/components/callout' -import { FAQ } from '@/components/ui/faq' -import { Image } from '@/components/ui/image' -Access Control lets organization admins define permission groups that restrict what each set of users can do — which AI model providers they can use, which workflow blocks they can place, and which platform features are visible to them. Permission groups are scoped to the **organization**. The organization's **default group** governs everyone org-wide; every other group targets a **specific set of workspaces** and, by default, governs **all members of those workspaces** (including external members) — or only specific members once you add them. A user is governed by exactly one group in any given workspace. Restrictions are enforced both in the workflow executor and in Chat, based on the organization that owns the workflow's workspace. +Permission groups restrict what people can use in an organization's workspaces. Set a provider or block allowlist, deny individual models or tool operations, or limit platform actions such as exports and deployments. Workspace membership and roles still determine which resources a person can access; a group does not grant access. ---- - -## How it works - -Each group belongs to a specific organization and has a name, an optional description, a **workspace scope**, an optional **member** list, and a configuration that defines what its members can and cannot do. Personal or grandfathered workspaces that do not belong to an organization have no permission groups. - -Sim resolves the governing group for a user in a workspace deterministically: - -1. a non-default group targeting that workspace that the user is an **explicit member** of takes precedence; otherwise -2. a non-default group targeting that workspace that has **no members** (so it governs all members of the workspace, including external members) applies; otherwise -3. the organization's **default group** applies (if one is set); otherwise -4. no restrictions apply. - -Assignment-time checks keep this unambiguous: a workspace has at most one all-members group, and a user is an explicit member of at most one group per workspace. - -When a user runs a workflow or uses Chat, Sim reads the resolved group's configuration and applies it: - -- **In the executor:** If a workflow uses a disallowed block type or model provider, execution halts immediately with an error. This applies to both manual runs and scheduled or API-triggered deployments. -- **In Chat:** Disallowed blocks are filtered out of the block list so they cannot be added to a workflow. Disallowed tool types (MCP, custom tools, skills) are **not** filtered during generation — Sim is told about the restriction but may still produce a step that uses one. Such a run fails at execution with an error naming the restriction. - ---- - -## Setup - -### 1. Open Permission groups settings - -Go to **Settings → Organization → Permission groups** from any workspace in your organization. Permission groups are defined once at the organization level and apply to every workspace under it. Only organization owners and admins can manage them. - -Access Control settings showing a list of permission groups: Contractors, Sales, Engineering, and Marketing, each with Details and Delete actions - -### 2. Create a permission group - -Click **+ Create** and enter a name (required) and optional description. A group either targets a **specific set of workspaces** (pick them from the multi-select) or is the **organization default group**. A workspace-scoped group applies to **all members** of its workspaces by default, including external members — you can narrow it to specific people later. Marking the group as the **default** makes it govern every workspace in the organization and every member not covered by another group (including external members); only one group per organization can be the default, and the default always applies to all workspaces. - -### 3. Configure permissions - -Click **Details** on a group to open its configuration. It has four tabs — **General**, **Model Providers**, **Blocks**, and **Platform**. Name, description, and the permission settings are buffered until you save; the workspace scope, the default-group switch, and member changes are applied immediately, so **Discard** does not undo them. - -Throughout the editor, a **checked** box means allowed. Clearing a checkbox is what applies a restriction. - -#### General - -Holds the group's **Name** and **Description**, the **Default group** switch, the **Workspaces** the group governs, and its **Members**. - -A workspace-scoped group with **no members** applies to everyone in its workspaces (including external members). Add members here — searching your organization by name or email — to restrict the group to only those people; removing every member returns it to governing everyone. The default group ignores members and governs every workspace in the organization. - -#### Model Providers - -Controls which AI model providers members of this group can use. - -Model Providers tab showing a grid of AI providers including Ollama, vLLM, OpenAI, Anthropic, Google, Azure OpenAI, and others with checkboxes to allow or restrict access - -The list shows all providers available in Sim. - -- **All checked (default):** All providers are allowed. -- **Subset checked:** Only the selected providers are allowed. Any workflow block or agent using a provider not on the list will fail at execution time. - -Expand a provider row to reach its **model denylist**. Clearing individual models blocks exactly those models while leaving the rest of the provider available — useful when a provider is sanctioned but a specific model is not. +Organization owners and admins manage groups under **Settings → Organization → Permission groups**. Billing-enabled deployments require Enterprise. Billing-disabled deployments use the feature configuration described under [Self-hosted setup](#self-hosted-setup). Workspaces without an organization have no permission groups. -#### Blocks +## Create and configure a group -Controls which workflow blocks members can place and execute. +1. Open **Settings → Organization → Permission groups** and click **Create group**. +2. Enter a name and optional description. Select at least one workspace, or make the group the **Default group** for the organization. +3. Open the group's row. Configure its **General**, **Model Providers**, **Blocks**, and **Platform** tabs. +4. Click **Save** to save its name, description, and permission configuration. -Blocks tab showing Core Blocks (Agent, API, Condition, Function, Knowledge, etc.) and Tools (integrations like 1Password, Ahrefs, Airtable, and more) with checkboxes to allow or restrict each - -Blocks are split into two sections: **Core Blocks** (Agent, API, Condition, Function, etc.) and **Tools** (all integration blocks). - -- **All checked (default):** All blocks are allowed. -- **Subset checked:** Only the selected blocks are allowed. Workflows that already contain a disallowed block will fail when run — they are not automatically modified. - -Expand an integration block to reach its **tool denylist**. Clearing individual tools blocks those operations while leaving the rest of the integration usable — for example, allowing a member to read from a service but not to delete in it. - - - The `start_trigger` block (the entry point of every workflow) is always allowed and cannot be restricted. + +Changes to workspace scope, the default-group switch, and membership take effect immediately. **Discard** only discards the buffered name, description, and permission changes. -#### Platform - -Controls the modules, actions, and credentials available to group members. Every row refuses at the API, not only in the UI — clearing a box revokes the access; it does not merely hide a tab. - -Platform tab showing feature toggles grouped by category - -**Modules** +In the provider, block, and platform permission lists, a checked box allows the item. Clear it to restrict the item. The **Project Issues** project checklist is an exception: checked projects are restricted. -| Feature | What clearing it withholds | -|---------|---------------------------| -| Chat | Revokes Chat. Members cannot ask Sim to build or edit anything. | -| Sim Mailer | Revokes the Sim Mailer inbox. Members cannot read or send mail. | -| Sandboxes | Revokes the Sandboxes module. Members cannot view, create, or change a workspace sandbox. | +### General -**Knowledge Base** +The **General** tab sets the name, description, workspaces, members, and default-group status. Sim selects a single governing group for each person and workspace: -| Feature | What clearing it withholds | -|---------|---------------------------| -| Knowledge Base | Revokes the Knowledge Base module. Members cannot open, search, or query any knowledge base. | -| Knowledge Base Creation | Prevents creating knowledge bases, leaving existing ones queryable. | -| Knowledge Base Uploads | Prevents uploading local documents, leaving sanctioned connectors as the only source. | +1. A non-default group targeting that workspace with the person as an explicit member. +2. Otherwise, a non-default group targeting that workspace in inheritance membership mode with no named members. It governs all workspace members, including external members. +3. Otherwise, the organization's default group, if configured. +4. Otherwise, no permission-group restrictions. -The **Knowledge Base** row also carries a **connector allowlist** — *Connectors knowledge bases may sync from*. Leave it untouched to allow every connector, or select a subset to limit which external sources a knowledge base may sync. +The default is a fallback. Its restrictions are not combined with a selected workspace group. Only one group can be the organization default; it applies across the organization's workspaces and ignores a named-member list. -**Tables** +An ordinary workspace group starts by governing all members of its selected workspaces. Adding named members narrows it to those people. Removing its last member can make it govern everyone again. **SCIM explicit-membership groups behave differently:** an empty explicit group governs nobody. See [SCIM provisioning](/platform/enterprise/scim). -| Feature | What clearing it withholds | -|---------|---------------------------| -| Tables | Revokes the Tables module. Members cannot read or write any table. | -| Table Creation | Prevents creating tables, leaving existing ones usable. | -| Table Export | Prevents downloading a whole table as CSV or JSON. | +Assignment checks allow at most one all-members group per workspace and at most one explicit group per person on a shared workspace. Conflicting individual assignments are rejected; conflicting people in bulk additions are skipped. Scope changes or removing the last inheritance-mode member can also be rejected if they would create a conflict. Sim does not silently move memberships between groups. -**Files** +A non-default group needs a workspace when created, but you can later remove all its workspaces. It then governs nobody until you add a workspace. External workspace members cannot be selected as named organization members; the workspace's all-members group or organization default can still govern them. -| Feature | What clearing it withholds | -|---------|---------------------------| -| Files | Revokes the Files module. Members cannot list, upload, or download workspace files. | -| Public Sharing | Revokes public file sharing. Members cannot create a share link. | -| Bulk Download | Prevents downloading folders as an archive. | +### Model Providers -The **Public Sharing** row also carries an **auth-mode allowlist** — *Auth modes public file-share links may use* (Anyone with link, Password, Email, SSO). Select a subset to force share links onto stronger authentication. +All providers are allowed by default. Select a subset to allow only those providers. Expand a provider to deny individual models while leaving its other models available. -**Deployment** +The **Agent default** chooses the initial model for new Agent blocks. Choose an allowed model, or **Platform default** to use Sim's default. This setting does not itself restrict models or rewrite existing blocks. -| Feature | What clearing it withholds | -|---------|---------------------------| -| Public API | Revokes public API access. Calls to a deployed workflow are refused. | -| API Deployment | Prevents deploying a workflow as an API endpoint. | -| MCP Server | Prevents exposing a workflow as an MCP server. | -| Chat Deployment | Prevents publishing a workflow as a chat. | -| Webhook Triggers | Prevents making a workflow reachable from an inbound webhook. | +### Blocks -The **Chat Deployment** row also carries an **auth-mode allowlist** — *Auth modes chat deployments may use* (Public, Password, Email, SSO). +**Core Blocks** contains blocks such as Agent, API, and Function; **Tools** contains integration blocks. All are allowed by default. Select a subset to restrict block types, then expand an integration to deny individual operations—for example, allow reads while refusing deletes. -**Tools** +The `start_trigger` entry block is always allowed. Existing workflows are not rewritten when a restriction changes. A run fails if it reaches a blocked type, provider, model, or tool operation. -| Feature | What clearing it withholds | -|---------|---------------------------| -| MCP Tools | Blocks agents from calling MCP tools. | -| Custom Tools | Blocks agents from calling user-defined custom tools. | -| Skills | Blocks agents from loading skills. | -| Tool Auto-Approval | Prevents auto-approving tool calls, so every call must be confirmed. | +### Platform -**Logs** +Most platform restrictions refuse the protected operation at the server as well as limiting its UI. **Trace Spans** and **Execution Cost** instead control which fields an otherwise authorized log read or export returns. -| Feature | What clearing it withholds | -|---------|---------------------------| -| Trace Spans | Withholds per-block trace spans from logs and from the API. | -| Log Export | Prevents downloading execution logs as a CSV. | -| Execution Cost | Withholds execution cost. Logs and member exports omit cost and token spend; organization-level data drains, configurable by org admins only, are not projected. | +| Category | Permission | Effect when restricted | +| --- | --- | --- | +| Modules | Chat | Prevents using Chat to ask Sim to build or edit. | +| Modules | Sim Mailer | Prevents reading or sending through the Sim Mailer inbox. | +| Modules | Sandboxes | Prevents viewing, creating, or changing workspace sandboxes. | +| Knowledge Base | Knowledge Base | Prevents opening, searching, or querying knowledge bases. | +| Knowledge Base | Knowledge Base Creation | Prevents creating bases; existing permitted bases remain usable. | +| Knowledge Base | Knowledge Base Uploads | Prevents local document uploads. | +| Knowledge Base | Knowledge Base Export | Prevents exporting a knowledge base. | +| Tables | Tables | Prevents table reads and writes. | +| Tables | Table Creation | Prevents creating tables. | +| Tables | Table Export | Prevents whole-table CSV or JSON downloads. | +| Files | Files | Prevents listing, uploading, or downloading workspace files. | +| Files | Public Sharing | Prevents creating file-share links. | +| Files | Bulk Download | Prevents downloading folders as archives. | +| Deployment | Public API | Refuses governed public API access to deployed workflows. | +| Deployment | API Deployment | Prevents deploying workflows as API endpoints. | +| Deployment | MCP Server | Prevents exposing workflows through MCP servers. | +| Deployment | Chat Deployment | Prevents deploying workflows as chats. | +| Deployment | Webhook Triggers | Prevents exposing workflows through inbound webhooks. | +| Tools | MCP Tools | Prevents agents from calling MCP tools. | +| Tools | Custom Tools | Prevents agents from calling custom tools. | +| Tools | Skills | Prevents agents from loading skills. | +| Tools | Tool Auto-Approval | Prevents storing an always-allow preference for tool calls. | +| Logs | Trace Spans | Withholds per-block spans from log reads and API responses. | +| Logs | Log Export | Prevents CSV execution-log downloads. | +| Logs | Execution Cost | Omits cost and token spend from governed logs and member exports. Organization-admin data drains are not projected this way. | +| Collaboration | Invitations | Prevents workspace or organization invitations in the applicable scope. | +| Collaboration | Workspace Creation | Prevents creating workspaces. | +| Collaboration | Member Directory | Withholds other members' names and emails; organization owners and admins retain roster access. | +| Credentials & Access | Integrations | Prevents viewing, adding, or removing integration connections. | +| Credentials & Access | Secrets | Prevents reading, adding, or changing workspace environment variables. | +| Credentials & Access | API Keys | Prevents listing, creating, or revoking workspace API keys. | +| Credentials & Access | Personal API Keys | Prevents using personal API keys against the workspace. | +| Credentials & Access | Personal Credentials | Prevents connecting personal credentials, leaving workspace-shared credentials available. | +| Credentials & Access | CLI Access | Prevents CLI login approval and use of CLI OAuth tokens for the public API. API keys retain their separate policies. | +| Credentials & Access | OAuth App Access | Prevents OAuth apps from accessing governed workspaces. | -**Collaboration** +Additional lists narrow selected capabilities: -| Feature | What clearing it withholds | -|---------|---------------------------| -| Invitations | Prevents inviting anyone to a workspace or to the organization. | -| Workspace Creation | Prevents creating new workspaces. A new one is not covered by any workspace-scoped group until you add it, though the organization's default group still governs it. | -| Member Directory | Withholds the member directory. Members cannot see the names or email addresses of other members. Organization owners and admins keep access — the roster routes exempt those roles. | +- **Knowledge Base** has a connector allowlist. Leave it unrestricted to allow all connectors, or select permitted sources. +- **Public Sharing** has an auth-mode allowlist: Anyone with link, Password, Email, and SSO. +- **Chat Deployment** has an auth-mode allowlist: Public, Password, Email, and SSO. +- **Project Issues** restricts issue access for the checked projects. Governed teammates must have workspace access to every active environment in a selected project. -**Credentials & Access** +Restricting **Tool Auto-Approval** prevents remembering approval for future calls. It does not undo approval of the current call or force confirmation for tools that do not require it. Future calls that require confirmation prompt again. -| Feature | What clearing it withholds | -|---------|---------------------------| -| Integrations | Revokes integration connections. Members cannot view, add, or remove an OAuth connection. | -| Secrets | Revokes secrets. Members cannot read, add, or change a workspace environment variable. | -| API Keys | Revokes workspace API keys. Members cannot list, create, or revoke one. | -| Personal API Keys | Prevents members from using a personal API key against this workspace. | -| Personal Credentials | Prevents connecting personal credentials, leaving only workspace-shared ones. | -| CLI Access | Prevents approving a CLI login or using Sim CLI OAuth tokens for the public API. Existing API keys retain their own restrictions. | -| OAuth App Access | Prevents OAuth apps from accessing the group's workspaces. The organization default group also governs authorization, token issuance and refresh, and account-level billing and audit reads. | +#### Organization-level permissions -##### Rows read from the organization default group +**Workspace Creation** and **Member Directory** read only the organization default, because those actions have no workspace scope. Other groups show them as inactive with an **Organization** tag, and **Select All** skips them. A newly created workspace uses the organization default until you add it to a workspace group. -Two rows — **Workspace Creation** and **Member Directory** — are read only from the organization's **default group**, because the act they govern names no workspace. On any other group the editor renders them inert, tags them **Organization**, and skips them in **Select All**. Set them on the default group. +**Integrations**, **API Keys**, **Invitations**, **Personal API Keys**, **CLI Access**, and **OAuth App Access** use the selected workspace group for workspace operations. Account-level operations use the organization default: minting a personal key, sending organization invitations, approving CLI login, authorizing or refreshing OAuth, and account-level billing or audit reads. -Six more rows — **Integrations**, **API Keys**, **Invitations**, **Personal API Keys**, **CLI Access**, and **OAuth App Access** — apply on the group in front of you for anything scoped to one of its workspaces. Account-level actions use the organization's default group, including minting a personal key, sending an organization-wide invitation, approving a CLI login, and authorizing or refreshing an OAuth app. - -### 4. Choose who it applies to - -A user is governed by one group per workspace, so adding a user is rejected when it would conflict with another of their groups on a shared workspace (skipped rather than added in bulk). The default group ignores members entirely — it always governs everyone not covered by a workspace group. - -A workspace also has at most one all-members group. Adding a workspace to a group, or removing a group's last member, is rejected when doing so would violate that — memberships and scopes are never silently moved. - -Manage which workspaces a group governs from the **Workspaces** list on the same **General** tab. A non-default group is created targeting at least one workspace, but you can later remove all of them — a group with no workspaces simply governs nothing until you add one back. - -External workspace members (people who have access to a workspace but belong to a different organization) can't be added as named members, but a workspace-scoped group with no members — and the organization default group — still governs them. - ---- +## How enforcement applies -## Enforcement +A human's governing group applies to session, personal API-key, OAuth, and delegated operations. Workflow restrictions are checked during execution, including deployments invoked by API, schedule, or webhook, using the operation's authorized identity. They do not replace workspace roles, credential access, or OAuth scopes. -### Workflow execution +A **workspace API key** acts as the workspace. It has workspace-role and operation policies but no human user's permission group; Sim does not apply the key creator's group as a substitute. A human's permission to create or manage that key is still governed. -Restrictions are enforced at the point of execution, not at save time. If a group's configuration changes after a workflow is built: - -- **Block restrictions:** Any workflow run that reaches a disallowed block halts immediately with an error. The workflow is not modified — only execution is blocked. -- **Model provider restrictions:** Any block or agent that uses a disallowed provider halts immediately with an error. -- **Tool restrictions (MCP, custom tools, skills):** Agents that use a disallowed tool type halt immediately with an error. - -This applies regardless of how the workflow is triggered — manually, via API, via schedule, or via webhook. - -### Chat - -When a user opens Chat, their permission group is read before any block or tool suggestions are made: - -- Blocks not in the allowed list are filtered out of the block picker entirely — they do not appear as options. -- Generation is not gated for these three tool kinds, so Sim can still produce a step that uses one. The restriction is enforced when the run reaches it: execution fails with an error naming it. - ---- - - - ---- +Chat filters restricted blocks from its available block catalog. Generated steps can still reference a restricted MCP tool, custom tool, or skill; execution rejects the restricted operation when reached. After changing a group, verify both the person's available UI and a representative authorized run. For an existing workflow that fails, remove the restricted item or change the governing policy. ## Self-hosted setup -Self-hosted deployments use environment variables instead of the billing/plan check. - -### Environment variables +On billing-disabled deployments, enable permission groups through the enterprise feature configuration or explicitly set: ```bash ACCESS_CONTROL_ENABLED=true NEXT_PUBLIC_ACCESS_CONTROL_ENABLED=true ``` -You can also set a server-level block allowlist using the `ALLOWED_INTEGRATIONS` environment variable. This is applied as an additional constraint on top of any permission group configuration — a block must be allowed by both the environment allowlist and the user's group to be usable. +The enterprise master configuration can enable the feature; an explicit feature value takes precedence. Billing-enabled self-hosted deployments still require Enterprise. See [self-hosted enterprise setup](/platform/enterprise/self-hosted). + +`ALLOWED_INTEGRATIONS` adds an instance-wide block allowlist. A block must satisfy both that list and the applicable group policy; `start_trigger` remains available. ```bash -# Only these block types are available across the entire instance ALLOWED_INTEGRATIONS=slack,gmail,agent,function,condition ``` -Once enabled, permission groups are managed through **Settings → Organization → Permission groups** the same way as Sim Cloud. +## Related docs + +- [Workspace permissions](/platform/workspaces) +- [SCIM provisioning](/platform/enterprise/scim) +- [Audit logs](/platform/enterprise/audit-logs) diff --git a/apps/docs/content/docs/platform/enterprise/audit-logs.mdx b/apps/docs/content/docs/platform/enterprise/audit-logs.mdx index 39c7a63ddb6..13980ad02fe 100644 --- a/apps/docs/content/docs/platform/enterprise/audit-logs.mdx +++ b/apps/docs/content/docs/platform/enterprise/audit-logs.mdx @@ -1,77 +1,77 @@ --- -title: Audit Logs -description: Track configuration and security events across your organization's workspaces +title: Audit logs +description: Investigate configuration and security events across your organization --- -import { FAQ } from '@/components/ui/faq' -import { Image } from '@/components/ui/image' +Audit logs record the actor, time, and affected resource for configuration and security events. Organization owners and admins can investigate changes across the organization's workspaces, export CSV, or send events to a [data drain](/platform/enterprise/data-drains). -Audit logs record configuration and security events across your organization, including the actor, time, and affected resource. Use them to investigate changes and incidents. +Billing-enabled deployments require Enterprise. Billing-disabled deployments use audit-log feature configuration and still need an organization for the organization viewer and API. Workspace admin access alone does not grant organization audit access. ---- +## Find events + +Open **Settings → Organization → Audit logs**. Search actions, actors, resource names, or descriptions, then narrow by resource type and date. Links from a workspace's Insights view also scope the feed to that workspace; remove the workspace chip to return to the organization feed. -## Viewing audit logs +| Column | Content | +| --- | --- | +| **Timestamp** | Time of the recorded action. | +| **Event** | Action identifier, such as `workflow.created`. | +| **Description** | Human-readable action summary. | +| **Actor** | Email or name when available; a system fallback for actions without one. | -### In the UI +By default, queries include actors who are current organization members and anonymous actions. API and CSV queries can set `includeDeparted=true` to include departed and external workspace actors. External workspace members may act on workspace resources without joining the organization; invitation metadata records internal or external membership. -Go to **Settings → Organization → Audit logs** in your workspace. Logs are displayed in a table with the following columns: +Historical visibility depends on current workspace ownership and stored organization attribution. Workspace moves or physical deletion can change which events an organization query returns. Export events you need to retain under independent archive controls. -Audit Logs settings showing a table of events with columns for Timestamp, Event, Description, and Actor, along with search and filter controls +## Export and integrate -| Column | Description | -|--------|-------------| -| **Timestamp** | When the action occurred. | -| **Event** | The action taken, e.g. `workflow.created`. | -| **Description** | A human-readable summary of the action. | -| **Actor** | The email address of the user who performed the action. | +Download CSV from the viewer, paginate the API, or use an audit-log drain for continuous delivery. CSV includes resource, workspace, and actor IDs; IP address; user agent; surface; and per-action metadata. The JSON API omits IP addresses and user agents. -Use the search bar, event type filter, and date range selector to narrow results. +CSV is capped at **10,000 rows or 64 MiB**. An oversized record can also stop it early. `X-Export-Truncated: 1` indicates a partial download; narrow the filters and export again. CSV export is itself an audited operation. -### Via API +### Organization API -Audit logs are also accessible through the Sim API for integration with external SIEM or log management tools. +For new integrations, use the [v2 audit-log reference](/api-reference/audit-logs/listAuditLogs). It supports `orgId`, `actorEmail`, UTC date filters, and the v2 pagination envelope. The v1 request below remains supported; changing only its URL to v2 does not preserve its query or response contract. ```http GET /api/v1/audit-logs -X-API-Key: +X-API-Key: ``` -**Query parameters:** +The key's owner must be an organization owner or admin. Workspace API keys are refused. Rate limits apply, and `X-RateLimit-*` headers report the current quota. -| Parameter | Type | Description | -|-----------|------|-------------| -| `action` | string | Filter by event type (e.g. `workflow.created`) | -| `resourceType` | string | Filter by resource type (e.g. `workflow`) | -| `resourceId` | string | Filter by a specific resource ID | -| `workspaceId` | string | Filter by workspace | -| `actorId` | string | Filter by a current organization member’s user ID. For a departed-actor filter, use the CSV export with `includeDeparted=true`. | -| `startDate` | string | ISO 8601 date — return logs on or after this date | -| `endDate` | string | ISO 8601 date — return logs on or before this date | -| `includeDeparted` | boolean | Include logs from members who have since left the organization (default `false`) | -| `limit` | number | Results per page (1–100, default 50) | -| `cursor` | string | Opaque cursor for fetching the next page | +| v1 query parameter | Behavior | +| --- | --- | +| `action` | Event identifier, such as `workflow.created`. | +| `resourceType` | Resource type; accepts comma-separated types. | +| `resourceId` | Specific resource ID. | +| `workspaceId` | Workspace in the caller's organization. | +| `actorId` | Current organization member's user ID. Departed-actor filtering is supported by CSV with `includeDeparted=true`. | +| `startDate`, `endDate` | ISO 8601 lower and upper date bounds. | +| `includeDeparted` | Includes actors outside current organization membership; default `false`. | +| `limit` | Page size, 1–100; default 50. | +| `cursor` | Opaque next-page cursor. | -**Example response:** +A v1 page contains `data`, an optional `nextCursor`, and `limits`. Each entry has `id`, `action`, `resourceType`, nullable resource ID/name, description, actor ID/name/email, workspace ID, arbitrary per-action `metadata`, and `createdAt`. ```json { "data": [ { - "id": "abc123", + "id": "audit-event-id", "action": "workflow.created", "resourceType": "workflow", - "resourceId": "wf_xyz", - "resourceName": "Customer Onboarding", - "description": "Created workflow \"Customer Onboarding\"", - "actorId": "usr_abc", + "resourceId": "workflow-id", + "resourceName": "Customer onboarding", + "description": "Created workflow \"Customer onboarding\"", + "actorId": "user-id", "actorName": "Alice Smith", - "actorEmail": "alice@company.com", - "workspaceId": "ws_def", + "actorEmail": "alice@example.com", + "workspaceId": "workspace-id", "metadata": {}, "createdAt": "2026-04-20T21:16:00.000Z" } ], - "nextCursor": "eyJpZCI6ImFiYzEyMyJ9", + "nextCursor": "opaque-next-page-cursor", "limits": { "workflowExecutionRateLimit": { "sync": { "requestsPerMinute": 60, "maxBurst": 10, "remaining": 59, "resetAt": "2026-04-20T21:17:00.000Z" }, @@ -82,88 +82,57 @@ X-API-Key: } ``` -Paginate by passing the `nextCursor` value as the `cursor` parameter in the next request. When `nextCursor` is absent, you have reached the last page. Each entry also includes `actorName`; `metadata` is an arbitrary per-action JSON object. The `limits` object reports your current rate-limit and usage status. - -The organization audit API requires a personal API key belonging to an organization owner or admin. Workspace API keys are refused. Rate limits apply — the response includes `X-RateLimit-*` headers with your current limit and remaining quota. - ---- +The limits above are illustrative. Pass `nextCursor` as the next request's `cursor`; its absence ends pagination. Keep filters unchanged across pages. -## Event types +## Recorded events and limits -Audit log events follow a `resource.action` naming pattern. The table below lists the main categories. +Events use identifiers such as `resource.action`. These categories are representative, not an exhaustive event catalog. | Category | Example events | -|----------|---------------| -| **Authentication** | `auth.login_succeeded`, `auth.login_failed`, `auth.logout`, `auth.impersonation_started`, `auth.impersonation_ended`, `auth.sessions_revoked` | -| **Workflows** | `workflow.created`, `workflow.deleted`, `workflow.deployed`, `workflow.locked` | -| **Workspaces** | `workspace.created`, `workspace.updated`, `workspace.deleted` | -| **Members** | `member.invited`, `member.removed`, `member.role_changed` | -| **Permission groups** | `permission_group.created`, `permission_group.updated`, `permission_group.deleted` | -| **Environments** | `environment.updated`, `environment.deleted` | -| **Knowledge bases** | `knowledge_base.created`, `knowledge_base.deleted`, `connector.synced` | -| **Tables** | `table.created`, `table.updated`, `table.deleted` | -| **API keys** | `api_key.created`, `api_key.revoked` | -| **Credentials** | `credential.created`, `credential.deleted`, `oauth.disconnected` | -| **Organization** | `organization.updated`, `org_member.added`, `org_member.role_changed`, `organization.sso_provider.updated` | -| **Exports and drains** | `audit_logs.exported`, `data_drain.created`, `data_drain.updated`, `data_drain.ran`, `data_drain.tested` | - -Authentication failures and password-reset requests use an anonymous actor and identify the target account separately. Impersonation and administrative session revocations identify the operator and the target organization. Table-row mutations record operation summaries and counts without copying row contents. - -Most audit writes are best effort: a database outage or process loss can prevent persistence even when the underlying action succeeds. Deployment activation uses an awaited, idempotent audit insert before its outbox checkpoint. Audit logs are not a complete tool-invocation stream or a transactionally guaranteed ledger for every operation. - -Organization visibility depends on current workspace ownership or stored organization attribution. Older workspace events without organization metadata may no longer appear in organization queries after the workspace is physically deleted. - -Workspace invitation events include whether the invite is for an internal organization member or an external workspace member in their metadata. External workspace members can appear as actors on workspace-scoped events, and appear in the roster with an External label without becoming organization members. - ---- - - - ---- +| --- | --- | +| Authentication | `auth.login_succeeded`, `auth.login_failed`, `auth.logout`, `auth.impersonation_started`, `auth.impersonation_ended`, `auth.sessions_revoked` | +| Workflows | `workflow.created`, `workflow.deleted`, `workflow.deployed`, `workflow.locked` | +| Workspaces | `workspace.created`, `workspace.updated`, `workspace.deleted` | +| Members | `member.invited`, `member.removed`, `member.role_changed` | +| Permission groups | `permission_group.created`, `permission_group.updated`, `permission_group.deleted` | +| Environments | `environment.updated`, `environment.deleted` | +| Knowledge bases | `knowledge_base.created`, `knowledge_base.deleted`, `connector.synced` | +| Tables | `table.created`, `table.updated`, `table.deleted` | +| API keys | `api_key.created`, `api_key.revoked` | +| Credentials | `credential.created`, `credential.deleted`, `oauth.disconnected` | +| Organization | `organization.updated`, `org_member.added`, `org_member.role_changed`, `organization.sso_provider.updated` | +| Exports and drains | `audit_logs.exported`, `data_drain.created`, `data_drain.updated`, `data_drain.ran`, `data_drain.tested` | + +Authentication failures and password-reset requests use an anonymous actor and record the target account separately. Impersonation and administrative session revocations identify the operator and target organization. Table-row mutations record summaries and counts without copying row contents. + +Most audit writes are best effort: an outage or process loss can prevent persistence after an action succeeds. Deployment activation uses an awaited, idempotent insert before its outbox checkpoint. The feed is not a complete tool-call stream or a guaranteed transactional ledger for every operation. + +The interface and API provide no audit-entry editing or deletion. Database administrators can alter stored records, and entries are not cryptographically sealed. Use a drain to retain your own archive. ## Self-hosted setup -Self-hosted deployments use environment variables instead of the billing/plan check. - -### Environment variables +On billing-disabled deployments, enable audit logs through enterprise configuration or explicitly set: ```bash AUDIT_LOGS_ENABLED=true NEXT_PUBLIC_AUDIT_LOGS_ENABLED=true ``` -Once enabled, audit logs are viewable in **Settings → Organization → Audit logs** and accessible via the API. +Explicit feature values take precedence over the enterprise master setting. Billing-enabled self-hosted deployments retain the Enterprise gate. See [self-hosted enterprise setup](/platform/enterprise/self-hosted). + +### Deployment-admin API -`GET /api/v1/audit-logs` authenticates with an `x-api-key` whose owner is an admin or owner of an organization, so it is unreachable on a deployment where nobody belongs to one yet. On Sim Cloud it additionally requires an active Enterprise subscription; self-hosted, `AUDIT_LOGS_ENABLED` takes that role. The admin-key equivalent needs neither an organization nor a plan: +Operators can use a separate instance-wide API with `ADMIN_API_KEY`, without an organization or plan: ```http GET /api/v1/admin/audit-logs x-admin-key: ``` -It accepts the same filters plus `actorEmail`, drops `includeDeparted`, and paginates with `limit` (max 250) and `offset` instead of the organization endpoint's `limit` (max 100) and `cursor`. It returns entries across the whole deployment rather than one organization. `GET /api/v1/admin/audit-logs/` returns a single entry. Set `ADMIN_API_KEY` to use it — see the [self-hosted enterprise guide](/platform/enterprise/self-hosted). +This endpoint returns events across the deployment, including IP addresses and user agents. It supports the organization endpoint's event/resource/workspace/date filters plus `actorEmail`, omits `includeDeparted`, and uses `limit` (default 50, maximum 250) and `offset` (default 0) pagination. `GET /api/v1/admin/audit-logs/` returns one entry. Keep the deployment-admin key separate from personal organization keys. + +## Related docs + +- [Data drains](/platform/enterprise/data-drains) +- [Permission groups](/platform/enterprise/access-control) +- [Audit-log CLI](/cli/audit-logs) diff --git a/apps/docs/content/docs/platform/enterprise/custom-blocks.mdx b/apps/docs/content/docs/platform/enterprise/custom-blocks.mdx index 7184c315202..f3f310fd922 100644 --- a/apps/docs/content/docs/platform/enterprise/custom-blocks.mdx +++ b/apps/docs/content/docs/platform/enterprise/custom-blocks.mdx @@ -1,144 +1,82 @@ --- -title: Custom Blocks +title: Custom blocks description: Publish a deployed workflow as a reusable block for your organization --- -import { FAQ } from '@/components/ui/faq' +import { Callout } from 'fumadocs-ui/components/callout' import { Image } from '@/components/ui/image' -Custom blocks let you package a deployed workflow as a reusable block for your whole organization. Once published, the block appears in the workflow editor's block toolbar alongside built-in blocks like Agent and Function. Anyone in your organization can drop it into a workflow, fill in its inputs, and use its outputs — without needing access to the workflow behind it. +Publish a workflow as a custom block so teammates can provide its inputs and use selected outputs without access to its source workflow. The block always runs the source's latest deployment. Use it for a shared knowledge lookup, an authenticated internal API, an enrichment step, or a prompt and guardrail maintained in one place. -A custom block always runs the **latest deployed version** of its source workflow, so improving the block is as simple as redeploying that workflow. +Publishing and managing a block requires admin access to its source workspace. Billing-enabled deployments require an Enterprise organization. On billing-disabled deployments, enable the custom-block feature through enterprise configuration or `CUSTOM_BLOCKS_ENABLED=true` and `NEXT_PUBLIC_CUSTOM_BLOCKS_ENABLED=true`. An organization is still required; see [self-hosted enterprise setup](/platform/enterprise/self-hosted). ---- - -## Common uses - -Consumers see only the inputs and outputs by default, unless the author enables **Trace runs in consumer logs**. Identity splits at execution: the source workflow's owner supplies personal variables and delegated calls, and the source workspace supplies workspace variables and carries the billing. Common patterns: - -- **Internal API gateway.** Wrap an authenticated internal or partner endpoint — "Create Ticket", "Charge Account", "Provision User" — behind a block that takes only the business inputs. Teammates call it without the base URL, API key, or auth headers, and when the endpoint changes you update one workflow instead of every consumer's. -- **Blessed knowledge lookup.** Package a vetted retrieval pipeline — chunking, filters, reranking — as "Search Company Docs" with a single query input, so teams reuse the approved retrieval instead of each rebuilding it. -- **Governed LLM step.** Share a prompt, model, and guardrail combination like "Summarize (house style)". You control the model and prompt org-wide; changing them is a redeploy, not a hunt through everyone's workflows. -- **Data enrichment.** Expose "Enrich Company" or "Lookup Customer by Email" that hides the provider keys and returns clean fields. -- **Compliance gate.** Offer "Redact PII" or "Policy Check" as a standardized step teams drop into their flows, with the rules maintained in one place. - ---- - -## Before you start +## Publish a block -- **Deploy the workflow first.** Only deployed workflows can be published as a block. If the workflow isn't deployed, deploy it, then come back. -- **Be a workspace admin.** Publishing and managing custom blocks requires workspace admin access. +1. Deploy the source workflow. +2. Open **Settings → Workspace → Custom blocks** and click **Create block**. +3. Select its **Workspace** and **Workflow**. The picker lists organization workspaces and deployed workflows. You must be an admin of the selected source workspace. +4. Set the block's presentation and interface using the fields below. +5. Review its trace policy, then click **Save**. ---- - -## Publishing a block - -### 1. Open Custom blocks settings - -Go to **Settings → Organization → Custom blocks** and click **Create block**. +Only one custom block can be published per source workflow. The source is fixed after publication; publishing another workflow requires a separate block. -Custom blocks settings page listing a published block with its icon, name, and description, with a Create block button in the header +### Name and icon +| Field | Behavior | +| --- | --- | +| **Icon** | Optional square PNG, JPEG, SVG, or WebP, up to 5 MiB. Falls back to the organization logo, then a default glyph. | +| **Name** | Toolbar display name, up to 60 characters. | +| **Description** | Summary of what consumers can do, up to 280 characters. | -### 2. Choose the source workflow +### Inputs -| Field | Description | -|-------|-------------| -| **Workspace** | The workspace that holds the workflow you want to publish. Only workspaces in your organization are listed. | -| **Workflow** | The workflow to publish. Only deployed workflows appear. If a workflow isn't deployed, deploy it first, then return here. | +Every input on the deployed workflow's **Start** block becomes a custom-block field, with its name, type, and description. You cannot select only some Start inputs. -The block runs the source workflow's latest deployment. You publish one block per workflow, and the source workflow can't be changed later — to point at a different workflow, delete the block and publish a new one. +For each input, set an optional placeholder of up to 200 characters and use **Required** when consumers must supply it. You can store overrides for up to 50 inputs. Inputs are read from the latest deployment: adding or renaming a Start input and redeploying updates the custom block automatically; overrides for deleted inputs are ignored. -### 3. Name and describe the block +### Outputs -| Field | Description | -|-------|-------------| -| **Icon** | Optional. A square image (PNG, JPEG, SVG, or WebP) shown on the block. Falls back to your organization's logo, then a default glyph. | -| **Name** | The block's display name in the toolbar (e.g. `Invoice Parser`). Max 60 characters. | -| **Description** | A short summary of what the block does. Max 280 characters. | +Choose the values consumers can reference, grouped by their source block and output path. Expose at least one and at most 50 outputs. Each needs a unique name of up to 60 characters; `success`, `error`, and `cost` are reserved. -### 4. Configure inputs +Review exposed output paths when you change the source workflow. Redeployment updates execution but does not author a new output interface for you. -Every input on the source workflow's **Start** block is exposed as a field on the custom block. You don't choose which inputs to include — they all carry over, along with each input's name, type, and description. +### Trace policy -For each input you can add an optional **placeholder** (max 200 characters) — the hint text shown in the empty field to tell consumers what to enter. +**Trace runs in consumer logs** is off by default. The source workflow still has its own execution log; its internal trace is omitted from the consumer's log. Consumers with independent source-workspace access can still read logs there. -Because inputs are read live from the deployed workflow, renaming or adding a Start input and redeploying updates the block's fields automatically. + +Enabling consumer tracing exposes source block names, inputs, outputs, and prompts to anyone authorized to read the consuming workflow's logs, including people without source-workspace access. Review the data the source can handle before enabling it. + -### 5. Choose outputs +Changing the trace policy applies to future runs; it does not rewrite earlier logs. Failures return a reference ID so the publisher can find the source run while nested error details remain redacted for consumers. -Pick which of the workflow's outputs consumers can use, and give each one a name. Outputs are grouped by the block they come from, so you can expose exactly the values that matter and hide everything internal. +## Use a custom block -- **At least one output is required.** -- Each exposed output needs a unique **name** (max 60 characters) — that's the name consumers reference in their workflows. +Open the workflow builder's toolbar and find **Custom Blocks**. Drag a published block into the workflow, fill its inputs, and reference its named outputs downstream. Availability is subject to [permission groups](/platform/enterprise/access-control). -Create block form filled in: Workspace and Workflow selectors, an uploaded icon, Name and Description fields, an expanded input with a placeholder, and two selected outputs each given a name +Workflow toolbar showing published blocks in the Custom Blocks section -### 6. Choose whether runs are traced +The source workflow's owner supplies personal variables and delegated calls. Its workspace supplies workspace variables and carries billing. Consumer inputs cross that boundary; consumers do not acquire the owner's credentials or source-workspace access. Review inputs and exposed outputs as the block's public interface. -**Trace runs in consumer logs** is off by default. Leave it off and your block stays a single step in every workflow that uses it: nothing about the run is recorded anywhere a consumer can reach. +Run a representative consumer workflow after publishing. Verify the required inputs, selected outputs, trace visibility, and source run in Logs. -Turn it on and the block's steps appear inside the trace of every workflow that runs it, org-wide. That means anyone who can read those workflows' logs sees your workflow's block names, inputs, outputs, and prompts — including people with no access to this workspace. It is the same information curated outputs and redacted errors otherwise keep on your side of the block, so turn it on when you want consumers to be able to debug your block themselves, and leave it off otherwise. +## Update, disable, or delete a block -You can change this at any time; it applies to runs from that point on. Failures always return a reference id either way, so you can find a run in your own logs even with tracing off. +Open the block under **Settings → Workspace → Custom blocks**. Blocks from other source workspaces are visible for organization reuse; managing them requires admin access to their source workspace. -### 7. Save - -Click **Save changes**. The block is published immediately and becomes available to everyone in your organization in the workflow editor's block toolbar. - ---- +- Edit the name, description, icon, input overrides, outputs, or trace policy. Editing the publication does not change the source workflow. +- To change execution, edit and redeploy the source. Every consumer then uses that deployment; there is no version pin or separate republish step. +- Setting the publication's `enabled` field to `false` through the API hides it from new selections and makes existing placements unavailable at execution. Set it to `true` to restore availability. This is separate from disabling a placed canvas block. +- Deleting permanently removes the publication. Existing placements remain in consumer workflows and fail because their custom block is missing. -## Using a custom block + +Replace custom-block placements in affected drafts and deployments before deleting. The usage warning includes both. Deletion does not rewrite consumer graphs or delete the source workflow. + -In the workflow editor, open the block toolbar. Published custom blocks appear under a **Custom blocks** section. Drag one into your workflow like any other block, fill in its inputs (using the placeholders as a guide), and reference its outputs in downstream blocks. +Undeploying the source makes the block unavailable until the source is deployed again. Deleting the source workflow also removes its publication and leaves consumer placements broken. To switch to another source, publish that workflow as a new block and replace old placements before removing the old publication. -Workflow editor block toolbar with a Custom Blocks section listing two published blocks below Core Blocks - -Consumers don't need any access to the source workflow. The block runs on its own, using only the inputs provided, and returns only the outputs you exposed. Its internal steps, models, and intermediate values stay hidden unless the block's publisher turned on **Trace runs in consumer logs**, in which case they appear under the block in the run's trace. - -A custom block connected to a Start block in the workflow editor, with its query input filled in and the run output showing the returned fields - ---- - -## Managing blocks - -Open a block from **Settings → Organization → Custom blocks** to edit or delete it. - -- **Editing** changes only the block's presentation, interface, and trace policy — name, description, icon, input placeholders, exposed outputs, and whether runs are traced in consumer logs. The source workflow can't be re-pointed. -- **Changing what the block does** is done by editing and **redeploying the source workflow**. The block picks up the new deployment automatically; there's nothing to republish. -- **Deleting** a block is permanent. Workflows already using it will have that block removed, so replace it before deleting if it's in active use. - ---- - -## Good to know - -- **Always current.** A custom block runs the source workflow's latest deployment. There are no versions to pin or manage. -- **Access control.** Custom blocks appear in [Access Control](/platform/enterprise/access-control) alongside built-in blocks, so you can allowlist or restrict them per permission group. -- **Disabled blocks.** A disabled block can't be added to new workflows, but existing placements keep working. -- **Removed blocks.** Deleting a block (or deleting its source workflow) removes it from workflows that used it. -- **Not deployed.** If the source workflow is undeployed, the block shows a clear error when run. Redeploy the workflow to fix it. - ---- +## Related docs - +- [Workflow deployment](/workflows/deployment) +- [Permission groups](/platform/enterprise/access-control) +- [Execution logs](/logs-debugging/logging) diff --git a/apps/docs/content/docs/platform/enterprise/data-drains.mdx b/apps/docs/content/docs/platform/enterprise/data-drains.mdx index 41b61a04e40..2ff716d4a2b 100644 --- a/apps/docs/content/docs/platform/enterprise/data-drains.mdx +++ b/apps/docs/content/docs/platform/enterprise/data-drains.mdx @@ -1,269 +1,196 @@ --- -title: Data Drains -description: Continuously export workflow logs, audit logs, and Chat data to your own object store, data warehouse, observability platform, or HTTPS endpoint on a schedule +title: Data drains +description: Export retained logs and Chat data to storage, a warehouse, Datadog, or a webhook endpoint. --- -import { FAQ } from '@/components/ui/faq' -import { Image } from '@/components/ui/image' +import { Callout } from 'fumadocs-ui/components/callout' -Data Drains let organization owners and admins on Enterprise plans continuously export Sim data to a destination they control — a customer-owned S3 bucket, Google Cloud Storage bucket, Azure Blob container, BigQuery table, Snowflake table, Datadog logs intake, or an HTTPS webhook. A drain runs on a schedule, picks up rows after its last acknowledged delivery, and writes them to the destination. Viewing drain configuration and run history is restricted to owners and admins as well, since destinations expose internal bucket names, table identifiers, and webhook URLs. +Data drains periodically export one source of retained Sim data to a destination you control. Organization owners and admins manage configuration and run history because those records expose destination identifiers and URLs. Billing-enabled deployments require Enterprise; billing-disabled deployments use the feature and scheduler configuration under [Self-hosted setup](#self-hosted-setup). -Drains are independent of [Data Retention](/platform/enterprise/data-retention) but designed to compose with it — see [Pairing with Data Retention](#pairing-with-data-retention) below. +A new drain starts with all retained history. Delivery is at least once: retries, partial acceptance, or a crash after delivery can duplicate rows. Deduplicate downstream by each source row's `id`. ---- - -## Setup - -Go to **Settings → Organization → Data drains** in your workspace, then click **New drain**. - -Data Drains settings page showing two configured drains — one exporting workflow logs to Amazon S3 daily, another exporting Chat conversations to an HTTPS webhook hourly - -New data drain dialog with fields for name, source, cadence, destination, and S3 credentials +## Create and verify a drain -Each drain has four pieces: +1. Prepare the destination and credentials. Sim does not create buckets, containers, datasets, or tables. +2. Open **Settings → Organization → Data drains** and click **Create drain**. +3. On **New drain**, enter a name unique within the organization, choose one source, a destination, and **Every hour** or **Every day**. +4. Fill the destination fields below and click **Create**. +5. Open the drain's detail page. Use **Test connection**, then **Run now** and check **Recent runs** and the destination's received rows. -1. A **source** — the category of data to export -2. A **destination** — where the data goes -3. A **schedule** — how often it runs -4. A **name** — unique within your organization +The detail page shows the last ten runs with status, trigger, time, row count, bytes, and failure details. Destination locators are also available through API run reads. **Run now** requires an enabled drain; an overlapping run can be refused. The **Enabled** switch pauses future runs without deleting configuration or the cursor. ---- - -## Sources +## Sources and row format -A drain exports exactly one source. To export multiple sources, create multiple drains. +Create separate drains for different sources. Every delivered row is JSON-safe NDJSON: one JSON object per line, with an `id` for deduplication. -| Source | Description | -|---|---| -| **Workflow logs** | Workflow execution records (one row per execution, only after the run reaches a terminal state). | -| **Job logs** | Background job records (deployed APIs, schedules, webhooks). Only terminal-state rows are exported. | -| **Audit logs** | Organization- and workspace-scoped audit events — logins, permission changes, resource creation/deletion, drain configuration changes. | -| **Chats** | Chat snapshots, including organization-owned chats outside a workspace. | -| **Chat runs** | Chat run records (terminal state only), with safe correlation context. Internal controller tokens and billing recovery receipts are excluded. | +| UI source | Wire value | Records | +| --- | --- | --- | +| Workflow logs | `workflow_logs` | Terminal workflow executions. | +| Job logs | `job_logs` | Terminal background jobs for deployed APIs, schedules, and webhooks. | +| Audit logs | `audit_logs` | Organization and workspace audit events, including departed actors. | +| Chats | `copilot_chats` | Chat snapshots, including organization-owned chats outside a workspace. | +| Chat runs | `copilot_runs` | Terminal Chat runs with correlation context; controller tokens and billing recovery receipts are excluded. | -Each row is delivered as a single line of NDJSON. The shape of each row is part of the public schema and stable across versions; every row carries an `id` field that downstream consumers can use to dedupe. +Workflow, job, and Chat-run cursors use terminal timestamps; audit and Chat cursors use creation time. Reads use the primary database and leave a five-minute stability window. This reduces late-commit gaps but does not guarantee change-data capture. -Workflow, job, and Chat run drains advance by their terminal timestamp; audit and Chat drains advance by creation time. A new drain exports all retained history. Reads use the primary database and leave a five-minute stability window before selecting new records. This reduces late-commit gaps but is not a change-data-capture guarantee. Drains deliver rows at least once. A failed run can deliver a row again, so consumers should deduplicate by its `id`. Mutable fields on **Chats** (messages, title, `lastSeenAt`) are a point-in-time snapshot and won't be re-emitted if the chat is later updated. Treat the export as append-only and reconstitute current state from your own system of record if you need it. +Chats are point-in-time snapshots. Later changes to messages, title, or `lastSeenAt` are not emitted again. An append-only archive therefore does not track every subsequent change to a conversation. ---- +The export uses each source's row schema. Inspect representative rows before defining warehouse columns; BigQuery receives top-level fields directly. Drains do not apply a new blanket PII scrub. Workflow log masking depends on the stored [data-retention redaction policy](/platform/enterprise/data-retention) used when the data was persisted; configuring `PII_URL` alone does not sanitize exported history. -## Destinations +## Destination reference -### Amazon S3 (or any S3-compatible store) +### Amazon S3 and compatible stores -Writes one NDJSON object per delivered chunk to your bucket. +Writes one NDJSON object per chunk. -- **Bucket** — the bucket name. Must already exist; Sim does not create buckets. -- **Region** — AWS region (e.g. `us-east-1`). -- **Prefix** *(optional)* — folder path inside the bucket. Trailing slash optional. -- **Access key ID / Secret access key** — IAM credentials with `s3:PutObject` on the bucket. The "Test connection" button performs a real write probe to verify, then deletes it. -- **Endpoint** *(optional)* — for non-AWS stores like MinIO, Cloudflare R2, or GCS S3-interop. Leave blank for AWS S3. -- **Force path-style** *(optional)* — required for MinIO/Ceph, must be off for AWS S3 and R2. +| Field | Requirement | +| --- | --- | +| **Bucket** | Existing bucket. | +| **Region** | AWS region, such as `us-east-1`. | +| **Prefix** | Optional object prefix; trailing slash is optional. | +| **Access key ID / Secret access key** | Credentials with `s3:PutObject`. `s3:DeleteObject` allows cleanup of the zero-byte connection-test probe; without it, the probe can remain. | +| **Endpoint** | Optional HTTPS endpoint for a compatible store; leave blank for AWS. Sim Cloud requires public addresses. Self-hosted Sim can use private MinIO/Ceph or loopback endpoints permitted by its [outbound-network policy](/platform/self-hosting/security#the-ssrf-boundary). | +| **Force path-style** | Enable if the provider requires it. Leave off for standard AWS virtual-hosted addressing. | -Object keys are deterministic: +Objects use `AES256` server-side encryption and this layout: -``` +```text {prefix}/{source}/{drainId}/{yyyy}/{mm}/{dd}/{runId}-{seq}.ndjson ``` -Objects are written with `AES256` server-side encryption. +The final SDK hostname is validated and its resolved address pinned. Signed request paths are preserved without redirects. An outbound gateway that cannot preserve signed targets fails closed. ### Google Cloud Storage -Writes one NDJSON object per delivered chunk to your GCS bucket. - -- **Bucket** — the bucket name. Must already exist; Sim does not create buckets. -- **Prefix** *(optional)* — folder path inside the bucket. Trailing slash optional. -- **Service account JSON key** — paste the full JSON key for a service account with `storage.objects.create` (and `storage.objects.delete` if you want "Test connection" to clean up its probe). Sim authenticates via OAuth2 service-account JWT and uploads through the GCS JSON API. +Supply an existing **Bucket**, optional **Prefix**, and the full **Service account JSON key**. The service account needs `storage.objects.create`; `storage.objects.delete` lets the connection test remove its probe. Sim uses OAuth2 service-account JWT authentication and the GCS JSON API. -Object names follow the same `{prefix}/{source}/{drainId}/{yyyy}/{mm}/{dd}/{runId}-{seq}.ndjson` layout as S3. Object metadata mirrors the S3 destination's `sim-*` keys via `x-goog-meta-*` headers. +Object names use the S3 layout above. `sim-*` object metadata uses `x-goog-meta-*` headers. ### Azure Blob Storage -Writes one NDJSON block blob per delivered chunk to your container. +Supply **Account name** (3–24 lowercase characters), an existing **Container**, optional **Prefix**, and an **Account key** with write access. Each chunk becomes an NDJSON block blob using the same object layout. Metadata keys are lowercased for Azure. -- **Account name** — your storage account (3–24 lowercase chars). -- **Container** — must already exist; Sim does not create containers. -- **Prefix** *(optional)* — folder path inside the container. -- **Account key** — a storage account access key with write access to the container. - -Blob names follow the same `{prefix}/{source}/{drainId}/{yyyy}/{mm}/{dd}/{runId}-{seq}.ndjson` layout. The `sim-*` metadata is exposed as Azure blob metadata (collapsed to lowercase per Azure's identifier rules). - -For sovereign clouds, set **Endpoint suffix** to `blob.core.usgovcloudapi.net` (US Gov), `blob.core.chinacloudapi.cn` (China), or `blob.core.cloudapi.de` (Germany). +**Endpoint suffix** supports `blob.core.usgovcloudapi.net` for US Gov and `blob.core.chinacloudapi.cn` for China. Sim also accepts the legacy Germany suffix `blob.core.cloudapi.de`; verify that the particular account still uses that endpoint before selecting it. ### Google BigQuery -Streams each row into a target table via the `tabledata.insertAll` API, with per-row insertId dedup. +Supply **Project ID**, **Dataset ID**, **Table ID**, and a **Service account JSON key**. Domain-scoped project IDs such as `example.com:my-project` are accepted. The table must already exist with compatible columns for the source's top-level fields; rows are not wrapped in one JSON or STRING column. Sim sets `ignoreUnknownValues: false`. + +The account needs `roles/bigquery.dataEditor` for inserts and `roles/bigquery.metadataViewer` for the `tables.get` connection probe. Sim uses OAuth2 service-account JWT authentication and `tabledata.insertAll`. -- **Project ID** — your GCP project (supports domain-scoped IDs like `example.com:my-project`). -- **Dataset ID / Table ID** — must already exist; Sim does not create tables. The table schema must match the source row shape, with a compatible column for each top-level field. Sim sends those fields directly and sets `ignoreUnknownValues` to `false`; it does not wrap the row in a single JSON or STRING column. -- **Service account JSON key** — needs `roles/bigquery.dataEditor` (insert) and `roles/bigquery.metadataViewer` (for the `tables.get` probe used by "Test connection"). Sim authenticates via OAuth2 service-account JWT. +Each row's `insertId` uses `{drainId}-{runId}-{sequence}-{index}`; IDs exceeding 128 characters are hashed. BigQuery offers best-effort deduplication for repeated IDs for up to one minute, so duplicates remain possible during any retry. Partial `insertErrors` fail the chunk and report row indices; rows already accepted can be repeated. Deduplicate source IDs downstream. See [BigQuery streaming behavior](https://docs.cloud.google.com/bigquery/docs/write-api-rest). -Each row is sent with an `insertId` of `{drainId}-{runId}-{sequence}-{index}`. BigQuery dedupes inserts with the same `insertId` for ~60 seconds, so retries inside that window won't duplicate. If a chunk reports partial failure (`insertErrors`), the run fails with the offending row indices and an outer-driver retry may duplicate rows that already succeeded — the dispatcher's bounded retry minimizes this risk. Enforced per-request limits: 10 MB body, 50,000 rows. +Sim's request guards are **10 MiB and 50,000 rows**. The tighter source-record and chunk limits below normally apply first. ### Snowflake -Inserts each row into a target VARIANT column via the Snowflake SQL API v2 with key-pair JWT auth. +Supply **Account**, **User**, **Warehouse**, **Database**, **Schema**, **Table**, and an unencrypted PKCS8 RSA **Private key (PEM)**. Prefer `-`; legacy `..` identifiers are also accepted. Register the matching public key on the user with `ALTER USER ... SET RSA_PUBLIC_KEY = '...'`. -- **Account** — the Snowflake account identifier. Preferred form is `-` (no dots). Legacy `..` is also accepted. -- **User / Warehouse / Database / Schema / Table** — must already exist. The user needs `INSERT` privilege on the table and `USAGE` on the warehouse, database, and schema. -- **Column** *(optional)* — target VARIANT column name. Defaults to `DATA` (matches Snowflake's unquoted identifier folding). -- **Role** *(optional)* — Snowflake role to assume. -- **Private key (PEM)** — PKCS8-encoded RSA private key. Register the matching public key on the Snowflake user via `ALTER USER ... SET RSA_PUBLIC_KEY = '...'`. +The user needs `INSERT` on the existing table and `USAGE` on its warehouse, database, and schema. **Role** is optional. **Column** is an existing VARIANT column, defaulting to `DATA`. -Each chunk becomes a single `INSERT INTO "DB"."SCHEMA"."TABLE" ("col") SELECT PARSE_JSON(column1) FROM VALUES (?), ...` with one TEXT binding per row. Identifiers are quoted to preserve case. The destination handles Snowflake's async 202-then-poll pattern transparently. Per-row JSON payloads are capped at 16 MB to match Snowflake's VARIANT limit. +Sim uses key-pair JWT authentication and SQL API v2. Each chunk uses `INSERT INTO "DB"."SCHEMA"."TABLE" ("col") SELECT PARSE_JSON(column1) FROM VALUES (?), ...`, with one TEXT binding per row. Identifiers are quoted to preserve case. The runner polls asynchronous `202` responses. Sim guards destination JSON at 16 MiB per row; the source-record limit is the tighter 1 MiB. This is a Sim limit rather than a statement of Snowflake's current maximum. ### Datadog Logs -POSTs each row as a log entry to Datadog's v2 logs intake. +Choose **Site** from `us1`, `us3`, `us5`, `eu1`, `ap1`, `ap2`, or `gov`. Supply a logs-write **API key**, not an Application key. **Service** defaults to `sim`; optional **Tags** are comma-separated. -- **Site** — your Datadog site: `us1`, `us3`, `us5`, `eu1`, `ap1`, `ap2`, or `gov`. -- **Service** *(optional)* — value for the reserved `service` field. Defaults to `sim`. -- **Tags** *(optional)* — comma-separated `ddtags` appended to every entry alongside auto-injected `sim_drain_id:`, `sim_run_id:`, and `sim_source:` tags. -- **API key** — a Datadog API key (not an Application key) with logs-write permission. +Sim posts to v2 logs intake, exposes top-level row fields as log attributes, and adds `sim_drain_id:`, `sim_run_id:`, and `sim_source:` tags. It sets the reserved `ddsource`, `service`, `ddtags`, and `message` fields, overriding source fields with those names. -Top-level row fields are auto-indexed as Datadog log attributes. The reserved fields `ddsource`, `service`, `ddtags`, and `message` are always set by Sim and override anything in the row. Payloads above 1 KB are gzip-compressed. Enforced limits match Datadog's intake: 5 MB of uncompressed JSON per request, 1000 entries per request, and 1 MB per entry. Expanded log entries are split into bounded requests before compression. +Expanded entries are split before compression. Requests are limited to **5,000,000 uncompressed bytes**, **1,000 entries**, and **1,000,000 bytes per entry**, with a defensive 6 MiB wire-size cap. Payloads larger than 1,024 bytes use gzip. -### HTTPS Webhook +### HTTPS webhook -POSTs each chunk as NDJSON to your endpoint. +Supply **URL**, **Signing secret**, optional **Bearer token**, and optional **Signature header name** (default `X-Sim-Signature`). On Sim Cloud, the URL must use HTTPS and resolve to public addresses. Self-hosted deployments apply their [outbound-network policy](/platform/self-hosting/security#the-ssrf-boundary): approved private endpoints and loopback are available, with HTTP only where that policy permits it. Sim blocks cloud-metadata addresses and pins the resolved address for the run to prevent DNS rebinding. -- **URL** — must be HTTPS. Sim resolves the hostname and refuses to deliver to private, loopback, or cloud-metadata IPs. The resolved IP is pinned for the duration of a run to prevent DNS rebinding. -- **Signing secret** — shared secret used for HMAC-SHA256 signing. -- **Bearer token** *(optional)* — sent as `Authorization: Bearer `. -- **Signature header name** *(optional)* — defaults to `X-Sim-Signature`. +Each chunk includes: -Each request includes: - -``` +```http Content-Type: application/x-ndjson User-Agent: Sim-DataDrain/1.0 X-Sim-Timestamp: X-Sim-Signature-Version: v1 -X-Sim-Signature: t=,v1= -X-Sim-Drain-Id: -X-Sim-Run-Id: -X-Sim-Source: -X-Sim-Sequence: -X-Sim-Row-Count: +X-Sim-Signature: t=,v1= +X-Sim-Drain-Id: +X-Sim-Run-Id: +X-Sim-Source: +X-Sim-Sequence: +X-Sim-Row-Count: Idempotency-Key: - ``` -The signature is computed as `HMAC-SHA256(secret, "${timestamp}.${body}")` and serialized as `t=,v1=`. Verify by recomputing over the same string and rejecting timestamps older than ~5 minutes — this defends against captured-request replay attacks. +Sim signs the exact string `${timestamp}.${body}` with HMAC-SHA256 and the signing secret. Recompute using the original request body and reject old timestamps—for example, those older than five minutes—to limit replay. A bearer token, when configured, is sent as `Authorization: Bearer `. -Failed deliveries retry up to 3 times with exponential backoff (500ms, 1s, 2s with ±20% jitter), respecting `Retry-After` on 429/503. Non-retryable 4xx responses fail the run immediately. +Delivery retries up to three times after the initial attempt: 500 ms, 1 s, and 2 s with ±20% jitter. `Retry-After` is respected on `429` and `503`; non-retryable `4xx` responses fail immediately. ---- +## Checkpoints, bounds, and failures -## Schedule +An opaque cursor advances only after acknowledged delivery. Later failures resume after the last acknowledged chunk, but a crash between remote acceptance and checkpointing can replay data. A database claim prevents overlapping runs for one drain and fences stale workers. -| Cadence | Drain runs | -|---|---| -| **Hourly** | Once per hour. | -| **Daily** | Once per day. | +| Bound | Limit | +| --- | --- | +| Database page | 100 rows | +| Source record, transcript, or execution archive before materialization | 1 MiB | +| NDJSON chunk | 4 MiB | +| One run | 100 chunks, 10,000 rows, or 100 MiB | +| Work window / hard deadline | 20 minutes / 25 minutes | -You can also disable a drain with the **Enabled** toggle (it stops running but is preserved), or trigger an out-of-schedule run with **Run now** on any drain row. +A queued run that reaches its work window schedules continuation. Oversized records and missing execution archives fail visibly without advancing past the incomplete record. ---- +The webhook idempotency key covers retries of one chunk within one run. A later replay has a new run ID; partially accepted destination requests can also repeat rows. Keep source-ID deduplication even when the destination offers its own deduplication. -## Delivery semantics +## Pair with data retention -Drains use an **opaque cursor** that checkpoints each acknowledged chunk. If a later chunk fails, the next run resumes after the last acknowledged checkpoint. A crash between remote delivery and checkpointing can replay a chunk. + +Retention does not wait for a drain. Failed delivery or backlog can let cleanup delete records before export. Set a cadence shorter than the retention window and monitor recent runs, progress, and destination receipt. + -A database claim prevents overlapping runs for the same drain and fences stale workers. Each run is bounded to 10,000 rows, 100 chunks, 100 MB of NDJSON, and a 20-minute work window, with a 25-minute hard deadline. A queued run that reaches a window limit schedules a continuation. Chunks are capped at 4 MB; individual database records, chat transcripts, and execution archives are capped at 1 MB before materialization. Oversized records fail visibly without advancing past them. Missing execution archives also fail rather than reporting an incomplete record as delivered. +| Source | Retention category | +| --- | --- | +| Workflow logs and Job logs | Log retention | +| Chats and Chat runs | Task cleanup | +| Audit logs | No age-based audit-retention setting currently | -This is **at-least-once delivery**. Deduplicate by the source row’s `id`. The webhook `Idempotency-Key` protects retries of a chunk within one run; a replay in a later run has a new run ID. A destination that partially accepts a request may also repeat previously accepted rows on retry. +For a 30-day log window, **Every hour** or **Every day** provides opportunities to export before expiry; cadence alone does not guarantee every row arrives. Source deletion, workspace scope changes, late commits, and persistent failures can still leave gaps. -The **last 10 runs** for each drain are visible by expanding its row in the settings page, with status, row count, bytes written, destination locator (`s3://...` or webhook URL), and the error message if it failed. +Your destination owns exported data lifecycle and erasure after delivery. Sim does not remove external objects when source data or a drain is deleted. ---- +## Rotate credentials or delete a drain -## Security +Destination credentials are encrypted at rest using key-rotation-aware encryption and are not returned by API reads. An API update can supply a complete replacement credential payload; omitting credentials preserves the stored secret. Source and destination type cannot be changed on an existing drain. -- Destination credentials are encrypted at rest using the same key-rotation–aware encryption that protects OAuth tokens. -- Credentials are **never** returned by the Sim API after creation. Updates accept new credentials; omitting them leaves the existing encrypted blob in place. -- Webhook URLs and the final S3 SDK hostname are SSRF-validated with the resolved IP pinned to the connection. Private, loopback, and metadata IPs are rejected. S3 signed request paths are preserved without following redirects. A configured outbound gateway that cannot preserve signed request targets fails closed. -- Every create, update, delete, manual run, and test-connection call is recorded in the [Audit Log](/platform/enterprise/audit-logs). - ---- +The current settings detail page edits **Enabled** only. Changing credentials there requires recreating the drain, which starts retained-history backfill again and can duplicate archived data. Use a supported API credential replacement when cursor continuity matters; do not delete the existing drain merely to rotate a key. -## Pairing with Data Retention - -Drains and [Data Retention](/platform/enterprise/data-retention) are independent modules. Sim does **not** gate retention on drain progress — if a drain is failing, retention will still purge data on its own schedule. Keep the two configurations independent and pair them deliberately. - -To safely use both together, set the drain cadence shorter than the retention period for the same data category: - -| Drain source | Pairs with retention setting | -|---|---| -| Workflow logs, Job logs | **Log retention** | -| Chats, Chat runs | **Task cleanup** | -| Audit logs | *(no retention setting today — audit logs are kept indefinitely)* | - -For example, with **Log retention** set to 30 days, set the workflow-logs drain to **Hourly** or **Daily** so every row is exported well before retention purges it from Sim. Monitor recent drain runs in the settings page; if a drain has been failing for longer than your retention window, you may lose rows that retention purges before they are exported. - -After data lands in your bucket or webhook system, archive lifecycle (transitions to Glacier, expiration, GDPR right-to-erasure propagation) is governed by your own infrastructure — Sim has no further visibility into that data once delivery succeeds. - ---- - - - ---- +**Delete** removes configuration and run history, without deleting exported bytes. Create, update, delete, manual-run, and connection-test actions emit best-effort [audit events](/platform/enterprise/audit-logs). ## Self-hosted setup -### Environment variables +Enable the feature through enterprise configuration or explicitly set: ```bash DATA_DRAINS_ENABLED=true NEXT_PUBLIC_DATA_DRAINS_ENABLED=true ``` -On a self-hosted deployment the feature resolves on when `DATA_DRAINS_ENABLED` is `true`, or when it is unset and `ENTERPRISE_ENABLED` is `true`. An explicit `DATA_DRAINS_ENABLED=false` wins over the master switch. That resolved value — not the bare variable — gates the **Settings → Organization → Data drains** page, the server-side mutating endpoints, and the cron dispatcher. When it resolves off the page is hidden, drain create/update/delete/run requests return `404`, and the dispatcher is a no-op. +An explicit feature value takes precedence over `ENTERPRISE_ENABLED`. When disabled, the page is hidden, mutating drain requests return `404`, and the dispatcher does no work. Billing-enabled deployments retain the Enterprise gate. Keep server and public feature configuration aligned; `bunx sim-setup doctor` checks the pair. See [self-hosted enterprise setup](/platform/enterprise/self-hosted). -Inside a workspace the browser reads that resolved value from the server, so the page follows the server whether or not `NEXT_PUBLIC_DATA_DRAINS_ENABLED` is set. Set it to the same value anyway: it backs the client fallback on surfaces rendered outside a workspace, and on a Compose install or source checkout `npx sim-setup doctor` reports the pair disagreeing. - -### Scheduling the dispatcher - -The dispatcher is an HTTP endpoint, not a self-scheduling job — something has to call it: - -``` -GET /api/cron/run-data-drains -``` - -It authenticates with a bearer token equal to `CRON_SECRET` and returns `401` when that variable is unset, so a self-hosted deployment must set it: +The dispatcher requires scheduled calls to `GET /api/cron/run-data-drains`. Set the same `CRON_SECRET` on the app and its caller; the endpoint returns `401` when it is unset. Generate a secret if needed, then install it in both configurations: ```bash openssl rand -hex 32 ``` -Set the same value as `CRON_SECRET` on both the app and whatever invokes the endpoint. Generating it in your shell does not configure either one. - -Both shipped deployments schedule this endpoint hourly for you — Helm through `cronjobs.jobs.runDataDrains`, Docker Compose through its `cron` service. A deployment that runs neither schedules it itself: +Helm's `cronjobs.jobs.runDataDrains` and Docker Compose's `cron` service call it hourly when their schedulers are enabled. If neither runs, configure an external scheduler: ```bash -curl -H "Authorization: Bearer $CRON_SECRET" \ +curl --fail-with-body \ + -H "Authorization: Bearer $CRON_SECRET" \ https://sim.example.com/api/cron/run-data-drains ``` -Each due drain is dispatched as a `run-data-drain` background job. With Trigger.dev enabled, it runs in the configured Trigger.dev project. Otherwise the database queue executes the registered drain runner. Per-drain database claims apply in both modes. The database fallback limits active drain jobs to two per app process; Trigger.dev workers use serialized per-drain jobs. See [background jobs](/platform/self-hosting/background-jobs). +Trigger.dev is optional. The database backend executes the registered runner with at most two active drain jobs per app process; Trigger.dev uses serialized per-drain jobs. Database claims apply in both modes. Verify scheduler calls and actual destination receipt after enabling the feature. + +## Related docs + +- [Data retention](/platform/enterprise/data-retention) +- [Audit logs](/platform/enterprise/audit-logs) +- [Background jobs](/platform/self-hosting/background-jobs) diff --git a/apps/docs/content/docs/platform/enterprise/data-retention.mdx b/apps/docs/content/docs/platform/enterprise/data-retention.mdx index 4b57215fced..67f58f4a62d 100644 --- a/apps/docs/content/docs/platform/enterprise/data-retention.mdx +++ b/apps/docs/content/docs/platform/enterprise/data-retention.mdx @@ -1,233 +1,172 @@ --- -title: Data Retention -description: Control how long execution logs, deleted resources, and Chat data are kept before permanent deletion — and redact PII from workflow data +title: Data retention +description: Configure cleanup periods and PII redaction for your organization's workspace data --- import { Callout } from 'fumadocs-ui/components/callout' -import { FAQ } from '@/components/ui/faq' import { Image } from '@/components/ui/image' -Data Retention lets organization owners and admins on Enterprise plans control two things: +Data retention controls age-based cleanup of logs, deleted resources, Chat data, and previous file versions. The same policy can redact PII in workflow inputs, block outputs, or persisted logs. -1. **Retention periods** — how long execution logs, soft-deleted resources, and Chat data are kept before they are permanently deleted. -2. **PII redaction** — masking personally identifiable information out of your workflow data at up to three points: workflow input, block outputs, and logs. +Organization owners and admins set the organization policy and workspace overrides. Billing-enabled deployments require Enterprise to configure these policies. Billing-disabled deployments can configure them; applying cleanup also requires the feature and a scheduler. See [self-hosted setup](#self-hosted-setup). -Both are configured once at the **organization level** and apply to every workspace, with optional **per-workspace overrides** for workspaces that need different rules. - ---- +## Defaults -## Setup +Cloud plan defaults apply when no configurable policy takes precedence: -Go to **Settings → Organization → Data retention** in your workspace. +| Deployment or plan | Execution/job logs | Soft-deleted resources | Chat task cleanup | Previous file versions | +| --- | --- | --- | --- | --- | +| Free Cloud | 30 days | 30 days | No default age expiry | 30 days | +| Pro or Max Cloud, including Teams | No default age expiry | 90 days | No default age expiry | 180 days | +| Enterprise | No default age expiry | No default age expiry | No default age expiry | No default age expiry | +| Billing-disabled self-hosting | No plan-based age expiry | No plan-based age expiry | No plan-based age expiry | No plan-based age expiry | -Data Retention settings showing the Retention policies list with the Organization default row and its summary of retention periods and PII stages +Enterprise and billing-disabled deployments retain data without an age-based expiry until configured otherwise. This does not prevent manual deletion, storage cleanup, or the file-version count limits below. PII redaction is off until a stored policy enables a stage and selects entities or patterns. -The page shows your **retention policies** as a list: +## Configure a policy -- The **Organization** row (tagged *Default*) holds the settings that apply to every workspace without its own override. -- Each **workspace override** row below it applies to one or more specific workspaces. +1. Open **Settings → Organization → Data retention**. +2. Open the **Organization** default row, or choose **Add override** for selected workspaces. +3. Choose retention periods and any PII stages, entities, languages, and custom patterns. +4. Save the policy and verify its summary in the policy list. -Open a row to edit it, or click **Add override** to create a workspace override. Each policy has a **Retention** section, and — when PII redaction is enabled — a **PII redaction** section. +The three UI retention fields offer **1 day**, **3 days**, **7 days**, **14 days**, **30 days**, **60 days**, **90 days**, **180 days**, **1 year**, **5 years**, or **Forever**. One year is 365 days and five years is 1,825 days. The API accepts integer hours from 24 to 43,800, or `null` for Forever. ---- + +Shortening a retention period makes older data eligible for permanent deletion on the next successful cleanup passes. Once removed, that data cannot be recovered by restoring the old policy. + -## Retention periods +Cleanup runs in bounded scheduled passes rather than at the exact expiry time. **Forever** disables age-based deletion for that category; it does not remove count caps or undo a manual deletion. -Each policy has three independent retention settings, each with the same set of options: **1 day, 3 days, 7 days, 14 days, 30 days, 60 days, 90 days, 180 days, 1 year, 5 years,** or **Forever**. +### Workspace overrides -Setting a period to **Forever** means that category of data is never automatically deleted. On a workspace override, each field can also be set to **Inherit from organization** to fall back to the organization default for just that field. +An override can target one or more workspaces, and a workspace can belong to only one override. Each retention field can **Inherit from organization** independently or set a period, including Forever. An omitted API field inherits; `null` explicitly disables age expiry. -### Log retention +PII settings use **Inherit** or **Override** for the whole policy. Override replaces the organization's redaction policy for that workspace; stages are not merged. Removing an override restores organization defaults. -Controls how long **execution logs** are kept. +Workspace override with Log retention set to 30 days, other retention fields inherited, and a PII Inherit or Override choice -When the retention period expires, log records are permanently deleted, along with any files associated with those executions in cloud storage. This covers: +## What each retention field removes -- Workflow execution logs -- Background job logs (deployed APIs, schedules, and webhooks) +### Log retention -### Soft deletion cleanup +Cleans workflow execution logs and background job logs for deployed APIs, schedules, and webhooks, based on `startedAt`. Related execution files are also scheduled for storage cleanup; logical record deletion does not guarantee immediate physical removal of every object. -Controls how long **soft-deleted resources** remain recoverable before permanent removal. +Logs and referenced files for an active paused execution are protected while that execution still has live paused state. They become eligible after that protection ends and the retention window applies. -When you delete a workflow, folder, knowledge base, table, or file, it is initially soft-deleted and can be recovered from Recently Deleted. Once the soft deletion cleanup period expires, those resources are permanently removed and cannot be recovered. +### Soft deletion cleanup -Resources covered: +Permanently removes resources that have remained soft-deleted beyond the window: -- Workflows -- Workflow folders -- Knowledge bases (and their documents) -- Tables -- Files +- Workflows and workflow folders +- Knowledge bases and their documents +- Tables and files - MCP server configurations - Agent memory - Chat conversations -### Task cleanup +Recover supported resources through Recently Deleted before cleanup removes them. Not every stored resource in this list has a corresponding recovery action in that interface. Permanent cleanup cannot be undone. -Controls how long **Chat data** is kept, including: +### Task cleanup -- Chat conversations and run history -- Run checkpoints and async tool calls -- Inbox tasks +Removes old Chat conversations, run history, checkpoints, async tool calls, and inbox tasks. Chat conversations and runs use their last update time; inbox tasks use creation time. This is separate from execution-log retention and soft-deletion cleanup. ### Previous file versions -Every change to a file's content keeps the previous content as a version you can read or revert to through the API, CLI, or MCP server. This setting controls how long a version is kept after a newer one replaces it. The newest ten versions of each file are always kept, whatever their age. - -Without a setting, previous versions are kept until a file reaches 500 of them. The setting isn't on the settings page yet: set `fileVersionRetentionHours` through the data retention API, either for the organization or in a workspace override. +`fileVersionRetentionHours` is available through the data-retention API, including workspace overrides; it is not yet a settings-page field. Read or revert versions through the [Files API](/api-reference/files/listFileVersions), [CLI](/cli/files), or MCP. -Each setting is independent. You can configure a short log retention period alongside a long soft deletion cleanup period, or any combination that fits your compliance requirements. - ---- +File edits can coalesce into an editing session rather than create a version for every keystroke. Sessions have a ten-minute window and five-minute idle threshold. Age cleanup protects the current version and nine newest previous versions, regardless of age. Superseded versions also have a 500-version ceiling; Free cleanup keeps at most 99 previous versions. Forever prevents age expiry but does not remove that ceiling. ## PII redaction -When PII redaction is enabled for your organization, each policy gains a **PII redaction** section that masks personally identifiable information — names, emails, phone numbers, credit-card numbers, national IDs, and more — from your workflow data. Sim detects and masks PII with [Microsoft Presidio](https://microsoft.github.io/presidio/); each match is replaced with a placeholder token such as ``. +A stored policy must enable a redaction stage and select entity types or custom patterns. A reachable `PII_URL` alone does not enable redaction. Matches are replaced with tokens such as `` using the Presidio service. -Redaction is configured per **stage** — the point in a run where masking is applied. Select a stage, then choose which entity types and custom patterns to redact for it: +| Stage | Effect | +| --- | --- | +| **Logs** | Masks workflow data as logs are persisted. Execution uses the original data. | +| **Workflow input** | Masks inputs before execution, so the workflow computes on masked values. | +| **Block outputs** | Masks outputs before downstream blocks consume them. | -| Stage | What it does | -|---|---| -| **Logs** | Redacts workflow logs when they are persisted. Observability-only — the workflow still runs on the original data. | -| **Workflow input** | Redacts the workflow input **before execution**. The workflow runs on the masked data, which may change its output. | -| **Block outputs** | Masks every block output **before the next block reads it**. Runs in-flight and may change output and execution performance. | - -PII redaction section with the Block outputs stage selected, showing the entity type grid grouped by Common, United States, United Kingdom, and Other regions +PII redaction controls with Block outputs selected and entity types grouped by region -The **Workflow input** and **Block outputs** stages alter what the workflow computes on, not just what is stored. Redacted data is masked during the run and may affect workflow output. Enable them only where that trade-off is acceptable. +Workflow input and Block outputs redaction alter computation. Test affected workflows with representative values before applying these stages: masking can change outputs and add execution latency. -### Entity types and language +### Entity types and languages -For each stage, choose the **entity types** to redact from the searchable grid. They are grouped as: +Choose entities separately for each stage: -- **Common** — person name, email, phone, credit card, IP address, location, date or time, URL, IBAN, crypto wallet, nationality/religious/political group, medical license, VIN -- **United States** — SSN, passport, driver's license, bank account, ITIN -- **United Kingdom** — NHS number, National Insurance number -- **Other regions** — Spanish (NIF, NIE), Italian (fiscal code, driver's licence, VAT code, passport, identity card), Polish (PESEL), Singaporean (NRIC/FIN, UEN), Australian (ABN, ACN, TFN, Medicare), Indian (PAN, Aadhaar, vehicle registration, voter ID, passport), and Finnish (personal identity code) identifiers +| Group | Available entity families | +| --- | --- | +| Common | Person name, email, phone, credit card, IP address, location, date/time, URL, IBAN, crypto wallet, nationality/religious/political group, medical license, VIN | +| United States | SSN, passport, driver's license, bank account, ITIN | +| United Kingdom | NHS number, National Insurance number | +| Other regions | Spanish NIF/NIE; Italian fiscal code, driver's licence, VAT code, passport, identity card; Polish PESEL; Singaporean NRIC/FIN and UEN; Australian ABN, ACN, TFN, Medicare; Indian PAN, Aadhaar, vehicle registration, voter ID, passport; Finnish personal identity code | -The **Block outputs** stage is restricted to regex- and checksum-based recognizers, to support in-flight masking without name-model detection. Types that need name-model detection — person name, location, date or time, and nationality/religious/political group — are not offered for that stage. +English, Spanish, Italian, Polish, and Finnish are supported. The selected language filters which recognizers and identifiers are available. -Detection is language-aware: pick the **language** whose recognizers should apply. English, Spanish, Italian, Polish, and Finnish are supported, and the grid filters to the identifiers available for the selected language. - - -Some recognizers match loosely and over-redact — US Social Security Number, US bank account number, and Date or time have no checksum and match aggressively. Enable these only where false positives are acceptable. - +**Block outputs** supports regex- and checksum-based recognizers only. It does not offer person name, location, date/time, or nationality/religious/political group detection that depends on name models. SSN, US bank-account, and date/time recognizers can match loosely without a checksum; enable them where false positives are acceptable. ### Custom patterns -Beyond the built-in entity types, each stage can redact anything a **regular expression** matches — employee IDs, internal URLs, ticket numbers. Give each pattern a name, a regex, and a replacement token; every match is replaced with the replacement text wrapped in angle brackets (e.g. `EMPLOYEE_ID` → ``). - ---- - -## Per-workspace overrides - -Retention and PII redaction are configured at the **organization level** and apply to every workspace by default. When a workspace needs different rules, add a **workspace override**. - -Add workspace override panel showing the workspace picker, retention fields set to Inherit from organization, and the PII redaction Inherit or Override switch - -- An override targets one or more workspaces (a workspace can belong to only one override). -- Each **retention** field either sets its own period or **inherits** the organization value. -- **PII redaction** on an override is either **Inherit** (use the organization's redaction) or **Override** (workspace-specific). Choosing Override replaces the organization's redaction rules entirely for that workspace — it is not merged stage-by-stage. - -Removing an override returns its workspaces to the organization defaults. - ---- - -## Defaults +Add up to 20 patterns per stage. Each has a name, regular expression, and replacement text. For example, replacement `EMPLOYEE_ID` produces `` for each match. Use patterns for identifiers such as employee IDs, internal URLs, or ticket numbers. -By default, retention settings are unconfigured — no data is automatically deleted in any category, and no PII is redacted, until you configure it. Setting a retention period to **Forever** has the same effect as leaving it unconfigured, but makes the intent explicit and lets you change it later without configuring from scratch. +### Scope and failures ---- - - +Redaction applies to text strings at the configured workflow stages. It does not retroactively sanitize retained history, inspect every binary file, or intercept every arbitrary outbound request. Detection can miss PII or mask unrelated text; review the selected recognizers and patterns against your data. ---- +If log redaction fails, affected strings are replaced with `[REDACTION_FAILED]` rather than stored unmasked. Failure at Workflow input or Block outputs stops the run instead of passing unredacted values downstream. ## Self-hosted setup -### Retention periods +### Enable cleanup and schedule it + +On billing-disabled deployments, enable retention through enterprise configuration or explicitly set: ```bash -NEXT_PUBLIC_DATA_RETENTION_ENABLED=true DATA_RETENTION_ENABLED=true +NEXT_PUBLIC_DATA_RETENTION_ENABLED=true ``` -Once enabled, retention settings are configurable through **Settings → Organization → Data retention** the same way as Sim Cloud. - -### Scheduling the deletion pass +An explicit feature value takes precedence over the enterprise master configuration. No plan-based default window is introduced: configure the windows you intend to apply. -`DATA_RETENTION_ENABLED` permits deletion; it does not perform it. Deletion runs when a scheduled request reaches one of four endpoints, each authenticated with a bearer token equal to `CRON_SECRET`: +Deletion requires all three: an enabled feature, an effective retention period, and a scheduled authenticated request. Set `CRON_SECRET` on the app and use the same secret on the scheduler. | Category | Endpoint | -|----------|----------| +| --- | --- | | Execution and job logs | `GET /api/logs/cleanup` | | Soft-deleted resources | `GET /api/cron/cleanup-soft-deletes` | -| Chats and Chat runs | `GET /api/cron/cleanup-tasks` | +| Chat data and runs | `GET /api/cron/cleanup-tasks` | | Previous file versions | `GET /api/cron/cleanup-file-versions` | -Neither shipped deployment schedules these four endpoints — not the Helm chart, not Docker Compose's `cron` service. An operator who sets `DATA_RETENTION_ENABLED=true` alone still deletes nothing. Add them to `cronjobs.jobs`, or call them daily from an external scheduler. +The shipped Helm and Docker Compose schedules omit these four endpoints. Add calls through Helm's `cronjobs.jobs` or an external scheduler; enabling the feature alone performs no deletion. ```bash -# Use the value already configured as CRON_SECRET on the app — a token -# generated here and not installed there returns 401. -curl -H "Authorization: Bearer $CRON_SECRET" \ +curl --fail-with-body \ + -H "Authorization: Bearer $CRON_SECRET" \ https://sim.example.com/api/logs/cleanup ``` -Each call fans the work out as background jobs. Trigger.dev is not required: when it is not configured the dispatcher runs the cleanup chunks inline instead of enqueuing them, so deletion completes on a default self-host. +Use the secret already configured on the app. A newly generated token that was not installed there returns `401`. Schedule each category you use, then check cleanup results. Trigger.dev is optional: without it, the dispatcher runs bounded cleanup chunks inline. A successful request is not a guarantee that all eligible stored bytes disappeared in one pass. -### PII redaction +### Deploy the PII service -PII redaction runs against a standalone [Presidio](https://microsoft.github.io/presidio/) service. Deploy it (see `apps/pii`) and point Sim at it: +Deploy `apps/pii`, which exposes `/analyze` and `/anonymize`, and set its reachable URL: ```bash -# The Presidio service exposing /analyze and /anonymize -# Helm — setting pii.enabled wires this for you, and a manual value is then -# ignored. Set it by hand only for an external Presidio with pii.enabled: -# false. The bundled Service is -sim-pii, or -pii when the -# release name already contains "sim". -PII_URL=http://..svc.cluster.local:5001 -# Docker Compose — no shipped file defines a PII service. Add one to the -# same project, then use its service name. -# PII_URL=http://pii:5001 +PII_URL=http://pii:5001 ``` -All PII stages are configurable under **Settings → Organization → Data retention**. +On Helm, `pii.enabled` deploys and wires the bundled service automatically; a manual `PII_URL` is ignored while it is enabled. For an external service, set `pii.enabled: false` and supply `PII_URL`. The bundled service is `-sim-pii`, or `-pii` when the release name already contains `sim`. + +Docker Compose does not ship a PII service. Add one to the project or point to a reachable external service. After verifying service access, save a policy with enabled stages and selected entities or patterns under **Data retention**. + +## Related docs + +- [Data drains](/platform/enterprise/data-drains) +- [Files](/files) +- [Execution logs](/logs-debugging/logging) +- [Self-hosted enterprise setup](/platform/enterprise/self-hosted) diff --git a/apps/docs/content/docs/platform/enterprise/forks.mdx b/apps/docs/content/docs/platform/enterprise/forks.mdx index c33c941c936..a12c77c1517 100644 --- a/apps/docs/content/docs/platform/enterprise/forks.mdx +++ b/apps/docs/content/docs/platform/enterprise/forks.mdx @@ -1,416 +1,201 @@ --- -title: Workspace Forks -description: Clone a workspace, keep it linked to its parent, and push or pull deployed workflow changes +title: Workspace forks +description: Create a linked workspace and push or pull deployed workflow changes between environments --- import { Callout } from 'fumadocs-ui/components/callout' -import { FAQ } from '@/components/ui/faq' import { Image } from '@/components/ui/image' -Workspace Forks let you clone a workspace into a child, keep the two linked, and move **deployed** workflow changes between them later. Think of **Deploy** as a git commit: only what you have deployed is what Forks can copy or sync. **Sync** is always a force push or force pull — the target side is overwritten for the workflows in the sync. There is no merge UI. +A fork creates a child workspace linked to its source. Later, push or pull deployed workflow changes across that direct parent–child relationship. One workspace has at most one parent, and a parent can have many children. Siblings and grandparents cannot sync directly. -One workspace has at most one parent. A parent can have many children. You can only sync along a **direct** parent↔child edge — not with a grandparent or sibling. +Only deployed, synced workflows move. Sync replaces eligible target workflows rather than merging their editor changes. Target-native workflows and excluded workflows remain outside the sync. ---- - -## Who can use Forks +## Availability and permissions -| Requirement | Detail | -|-------------|--------| -| **Plan** | Enterprise on Sim Cloud | -| **Role** | Workspace **admin** — non-admins never see the Forks tab | -| **Self-hosted** | Set `FORKING_ENABLED` / `NEXT_PUBLIC_FORKING_ENABLED` (see [Self-hosted setup](#self-hosted-setup)) | +Billing-enabled deployments require Enterprise, including when self-hosted. Billing-disabled deployments require forking enabled in the deployment feature configuration; see [Self-hosted setup](#self-hosted-setup). Workspace-creation policies and storage/resource limits still apply. -On Sim Cloud, your organization may also need the feature turned on for your account before the tab appears. - ---- +| Action | Required access | +| --- | --- | +| View forks or create a child | Admin of the source/current workspace. | +| Sync or edit mappings | Admin of both workspaces on the direct edge. | +| Change a workflow's sync checkbox | Admin of that workflow's workspace. | +| Change the new-workflow default | Admin of any workspace in the lineage. | +| Roll back | Admin of the target that received the sync. | +| Disconnect | Admin of the acting side; other-workspace membership is not required. | +| Open the other workspace | Membership in that workspace. | -## Setup +## Create a fork -### 1. Open Forks +1. Open **Settings → Workspace → Workspace forks** in the source. +2. Click **Create fork** and name the child. The default is `{workspace} (fork)`. +3. Review **Copy resources**. Resources start selected; deselect only those you intend to reconnect or replace. +4. Review the cleared-reference warning and click **Fork**. +5. Open the child, configure credentials and secrets, and check **Activity** for background-copy results. Deploy its workflows when they are ready. -Go to **Settings → Workspace → Workspace forks** in the workspace you want to fork from (or manage). +Fork dialog warning that deselected resources clear references in copied workflows -Workspace Forks settings page showing Parent and Forks sections with Docs, See activity, and Create fork actions +Deployed workflows arrive as drafts. Undeployed workflows and uncommitted drafts stay in the source. If no eligible workflow is copied, the child receives a blank starter workflow. Deselecting a referenced resource clears the corresponding child fields. -You will see: +The child stays in the source's organization and Project, inherits workspace mode and personal-key policy, and receives a snapshot of workspace memberships and roles, including external members. The creator becomes a child admin. Later membership changes do not sync automatically. -- **Parent** — if this workspace was forked from another -- **Forks** — children of this workspace -- **See activity** — history of forks, syncs, and rollbacks -- **Create fork** — start a new child +Workspace-specific permission-group scopes and retention overrides are not copied onto the new workspace; organization fallback policies still apply. Table rows, knowledge documents, and file contents can continue copying after workspace creation. A created workspace is not proof that every copy finished. -### 2. Create a fork +## Push or pull changes -Click **Create fork**. Name the child (defaults to `{workspace} (fork)`), then review **Copy resources**. +From the **child**, open **Settings → Workspace → Workspace forks**, open the **Parent** menu, and choose **Edit mappings**. Child rows on the parent offer **Open workspace** and **Disconnect**. Opening is disabled when you lack other-workspace access; disconnecting remains available to an admin on your side. -Fork workspace modal with name field and Copy resources list fully selected - -Everything under **Copy resources** starts **selected**. That is usually what you want: tables, knowledge bases, files, custom tools, skills, and MCP servers the child will need. - - - If you deselect a resource, references to it in the forked workflows are **cleared** in the child. You will see a warning before you confirm. - +### 1. Choose direction and review workflows -Fork workspace modal showing a warning that deselected resources will clear references in the fork +- **Push** sends this workspace's deployed workflows to the other workspace. +- **Pull** brings the other workspace's deployed workflows into this workspace. -Click **Fork**. The child workspace is created immediately. Deployed workflows land as **drafts** in the child. Large content (table rows, knowledge base files, file blobs) may finish copying in the background — watch **Activity** on the source workspace. +Review which workflows will be created, replaced, or archived and compare the source deployment with the target. Missing counterparts are created. A mapped counterpart is archived when its source was deleted; merely undeploying the source does not archive it. Native target workflows are left alone. - - Only **deployed** workflows are forked, and only the ones that are [synced](#synced-workflows). Drafts and undeployed work stay in the parent. If there is nothing to copy, the child starts with a blank starter workflow. + +Sync overwrites the eligible target workflows, including target draft edits. Review the affected workflow and archive lists before confirming. There is no merge operation. -### 3. Open the parent edge (from the child) - -Open the **child** workspace → **Settings → Workspace → Workspace forks**. On the **Parent** row, open the menu and choose **Edit mappings**. - -Child rows (when you are on the parent) only offer **Open workspace** and **Disconnect** — mapping and sync are owned by the child configuring how it relates to its parent. +### 2. Map or copy resources -**Open workspace** is disabled with a tooltip if you do not have access to the other workspace. **Disconnect** stays available so you can still sever the link. +| Choice | Use | +| --- | --- | +| **Map** | Keep each environment's existing resource and rewrite source references to its target counterpart. | +| **Copy** | Create an independent target clone of a table, file, knowledge base, tool, skill, or supported MCP configuration. | -### 4. Understand mappings +For example, copy a Leads table into staging for experiments, but map each environment's Slack credential to its own connection. Mappings take precedence over copying. Resources used by the synced workflows default to selected for copy; **Not used by any workflow** resources default off. -A **mapping** means: “this resource in the source is the same logical thing as that resource in the target.” When you sync, workflow fields that pointed at the source resource are rewritten to the target resource so blocks keep working. +Credentials and environment-variable values are never copied. Map credentials to the same integration kind and secret names to target names such as `{{API_KEY}}`. Values remain in their own workspace. A secret reference used only inside a Note block does not block sync. -| Approach | When to use it | -|----------|----------------| -| **Map** | Both sides already have (or should keep) their own resource — e.g. each workspace’s Slack credential, Gmail account, or secret value | -| **Copy** | The target should receive a **new** clone of the source resource — a new table, knowledge base, file, or MCP server config | +Environment-variable mapping does not sanitize every literal value. Review inline configuration, copied MCP headers, and OAuth client configuration for values that should differ between environments. -**Credentials** and **Secrets** are **map-only**. They are never copied. Secret *values* never leave their workspace; only names like `{{API_KEY}}` appear in workflow text. +### 3. Reconfigure dependent fields -Mappings are saved on the fork relationship. You can click **Save** without syncing. Sync always uses the saved mappings. +Mapping a credential or parent resource can invalidate choices such as Gmail labels, Slack channels, or knowledge documents. Pick those fields again for the target; required fields block **Sync** until configured. -After you map or copy a parent resource (credential, knowledge base, table, …), **dependent fields** — Gmail labels, Slack channels, knowledge base documents, and similar — often need a fresh pick in the target. Required dependents block **Sync** until they are filled. Workspace file-folder scopes are mapped by canonical path; an empty folder selection creates no mapping requirement, and **Include Subfolders** does not block by itself. +A mapped resource's dependent Document field marked required for sync -### 5. Map, reconfigure, then Sync +Resolve **Blocking sync** entries by mapping, selecting a supported resource for copy, deploying a referenced source workflow, or fixing its source reference. For a resource deleted at the source, you may explicitly drop its reference. That choice clears every occurrence of that resource in the sync, rather than only the displayed field. Live source resources cannot be dropped this way. -On the sync page you will see direction (**Push** / **Pull**), deployed workflow changes, **Mappings**, optional **Copy resources**, and any **Blocking sync** items. +Published custom blocks keep invoking their published source environment. Map them to a custom block published in the target; copying a workflow does not turn that invocation into a local implementation. See [custom-block authority](/platform/enterprise/custom-blocks). -Sync detail page with Push and Pull direction, deployed workflows, and mapping status badges +### 4. Review trigger URLs and save -- **Push** — overwrite the **other** workspace with this workspace’s deployed workflows -- **Pull** — overwrite **this** workspace with the other’s deployed workflows +In **Trigger URLs in** the target, review preserved URLs and any offered adoption choices for arriving triggers. Existing target trigger slots retain their own URLs. An arriving slot can use an offered retiring target path or request a new one. Retired webhook URLs stop serving; update external callers where needed. -Both are force operations. Confirm carefully. +Save mapping and dependent-field changes. While they are unsaved, the header offers **Save** and **Discard**; after saving, it returns to **Sync**. Copy selections and trigger choices belong to the current sync review; saving mappings does not persist every review choice. -Copy resources section showing resources used by workflows and a Not used by any workflow group +### 5. Confirm and verify completion -Resources referenced by the workflows in the sync default to selected for copy. Unused ones sit under **Not used by any workflow** (off by default). If you **map** a resource, it leaves the copy list — maps win. +Click **Sync**, review the overwrite confirmation, and confirm. If the source or reviewed scope changed, reload and review again rather than applying a stale comparison. -Dependent field reconfigure card under a mapped resource with a required field marked +A push/pull acknowledgement can precede content copying and deployment activation. Open **See activity** or **Activity**, expand the operation, and inspect copy progress, deployment results, and warnings. If deployment requires configuration or fails, open the affected workflow, fix it, and redeploy. Verify the target's active deployment and trigger/chat endpoints before sending traffic there. -**Sync** stays disabled until: +### Automated preview and retry protocol -- Every blocking reference is mapped, copied, or fixed in the source -- Required credentials and secrets are mapped -- Required dependent fields are filled -- Sync details have finished loading +The [API and CLI sync guide](/api-reference/workflow-sync) covers preview fingerprints, mappings, dependent values, copy choices, and trigger choices. Apply exactly the reviewed request with its `previewFingerprint` and a stable `requestId`. -### 6. Confirm and run +After an uncertain response, retry the identical payload with the original request ID or find the original operation by request ID. A fresh ID can repeat the mutation. A changed payload under the same ID or a stale preview is refused; obtain a new preview and ID for a revised request that was not committed. -Click **Sync**. You will get an overwrite confirmation. - -Overwrite target workspace confirmation dialog warning that syncing overwrites changes on the target - -On success you will see a toast such as **Pushed to "…"** or **Pulled from "…"**. If some workflows fail to redeploy, you get a warning to open and redeploy them manually. - ---- +An operation receipt with `applied: true` means the transaction committed, including when follow-up work fails. Poll under the receipt's `workspaceId` while `status` is `processing`; inspect `issues`, `copyProgress`, admitted deployment `ready` values, and `pendingComponents`. Terminal status alone does not make a copied draft live. Fork-creation receipts belong to the source; push/pull receipts belong to the current workspace named in the request URL. ## Synced workflows -The **Synced workflows** section on the Forks page lists this workspace's deployed workflows in their sidebar folder structure, each with a checkbox. **Checked means the workflow syncs.** Uncheck one — or a whole folder at once — to keep it out of forking entirely. Think of an unchecked workflow as `.gitignore`d: - -- **Never sent** — pushes from this workspace do not carry it, the other side pulling from this workspace does not receive it, and creating a new fork does not copy it -- **Never touched** — a sync into this workspace will not overwrite or archive it, even if its counterpart was deleted on the other side. It stays deployed and keeps serving, and a previously-synced counterpart on the other side keeps running on its last deployed version. +The **Synced workflows** list shows this workspace's deployed workflows in folder order. Checked workflows participate. Uncheck a workflow or folder to exclude it: -The checkbox list belongs to **this workspace's copy** only. Unchecking a workflow here does not unsync its counterpart in the parent or a fork — each workspace manages its own list. If the pair has synced before, the link between them is kept, so re-checking later resumes updating the same counterpart instead of creating a duplicate. +- It is not sent by push, received when the other side pulls, or copied into new forks. +- Sync into this workspace does not replace or archive it, even if its counterpart was deleted. It keeps its current deployment. -On the sync page, unsynced workflows still appear in the **Deployed workflows** list, greyed out, with a tooltip naming which workspace they are unsynced in. The sync will not touch them. +Each workspace manages its own checkboxes. Unchecking here does not change the counterpart's checkbox. Existing identity mappings remain, so rechecking resumes updates to the same counterpart instead of creating a duplicate. Excluded workflows appear greyed out in the sync review with their workspace named. -**Example:** a staging fork leaves `Scratch experiment` unchecked so it can never reach production, and production leaves `Billing hotfix` unchecked so no push from staging can ever overwrite it. +For example, staging can exclude a scratch experiment while production excludes a local billing hotfix that staging must not overwrite. ### Sync new workflows by default -Above the list, **Sync new workflows by default** decides where a **newly created** workflow starts: - -| Setting | A new workflow… | -|---------|-----------------| -| **Sync** (default) | joins fork sync — it arrives checked and syncs as soon as you deploy it | -| **Don't sync** | starts outside fork sync — it arrives unchecked and only syncs after you check it | - -Three things to know: - -- **It applies to the whole fork lineage.** The toggle writes every workspace in the lineage — the root, every ancestor, every descendant — so a parent and its forks can never disagree about what "new" means. Any workspace admin in the lineage can change it, and each workspace whose value changes gets its own audit entry naming the workspace the change came from. A new fork inherits the value at creation. -- **It is forward-only.** Flipping it never moves an existing workflow in or out of sync. The checkbox list above stays the record of what syncs. -- **"New" means genuinely new.** Creating, duplicating, or importing a workflow takes this setting, as does the blank starter workflow a fork gets when there is nothing to copy. A workflow that arrives as a **copy** — from a fork, or from a push or pull — ignores this setting. Only synced workflows are copied, and they always arrive synced, so a workflow you deliberately synced never lands unsynced on the other side. - -**Example:** a template workspace turns this off so every scratch workflow the team creates stays local, then checks only the handful meant to reach the forks. - ---- - -## Activity - -**See activity** (or the Activity view from the Forks header) lists forks, pushes, pulls, and rollbacks that involve this workspace — including events recorded on the other side of the edge. - -Activity view showing Fork and Push events with expandable detail rows - -Expand a row for names of workflows and resources that were created, updated, or archived, and any warnings (for example failed background copies or deploy failures). A push or pull that copies resources fills their content in the background, and that progress and outcome show in the same row. +| Setting | New workflow behavior | +| --- | --- | +| **Sync** (default) | Starts checked and can sync after deployment. | +| **Don't sync** | Starts unchecked until an admin selects it. | ---- - -## Rollback vs Disconnect +This setting applies to the whole lineage: root, ancestors, descendants, and siblings. Any workspace admin in that lineage can change it; changed workspaces receive audit entries naming the originating workspace. New forks inherit it. -| Action | What it does | Keep in mind | -|--------|--------------|--------------| -| **Rollback** | Undoes the **last sync into this workspace** — restores each affected workflow to its prior deployed version and removes workflows that sync created | Copied resources from past syncs **may remain**. Rollback does not delete tables, KBs, or files that were copied in. | -| **Disconnect** | Permanently removes the fork relationship | Both workspaces stay. Saved mappings and sync history for the pair are deleted. Forking again creates a **new** child, not a reconnect. | - ---- +The change is forward-only. It does not alter existing checkboxes. Creating, duplicating, importing, or creating a blank starter workflow uses this default. Workflows arriving through fork, push, or pull are already selected for sync and arrive synced regardless of the default. -## Permissions - -| Action | Who | -|--------|-----| -| See Forks / create a fork | Admin on this workspace (+ feature available) | -| Sync / edit mappings | Admin on **both** sides of the edge | -| Check / uncheck **Synced workflows** | Admin on the workspace those workflows live in | -| Change **Sync new workflows by default** | Admin on any one workspace in the lineage — the change applies to every member | -| Rollback | Admin on the workspace the sync landed in | -| Disconnect | Admin on **this** side only (you can disconnect even without access to the other workspace) | -| Open the other workspace | You must be a member of that workspace | - ---- - -## Resource reference - -How each resource behaves at **fork** time vs **sync** time. Use this when you are deciding what to select under **Copy resources**, or why Sync is asking you to map something. - -### At a glance +## Resource behavior | Resource | Fork | Sync | -|----------|------|------| -| Deployed workflows | Copied as drafts when [synced](#synced-workflows) | Updated / created / archived (force overwrite) | -| Undeployed workflows | Not copied | Not synced | -| [Unsynced workflows](#synced-workflows) | Never | Never — not sent, not overwritten, not archived | -| Files | Optional copy (default on) | Map or copy | -| File folders referenced by workflows | Mirrored with their ancestor folders, even when empty | Map by canonical path | -| Tables | Optional copy (default on) | Map or copy | -| Knowledge bases (+ documents) | Optional copy; uploaded documents come with the KB, [connector-synced ones do not](#connector-synced-documents-are-not-copied) | Map or copy; documents follow the KB | -| Custom tools | Optional copy (default on) | Map or copy | -| Skills | Optional copy (default on) | Map or copy | -| External MCP servers | Optional copy (config only; sign-in cleared) | Map or copy (config only; sign-in cleared) | -| Workflow MCP servers | Optional copy (server shells + attachments when workflows copy) | Kept in sync automatically with the workflows | -| Deployed chats | Carried with a **new** chat URL | Created on the target if it has no chat yet | -| Credentials | Never — fields cleared | Map only | -| Secrets | Values never; `{{KEY}}` names kept | Map key names only | -| Public API | Child starts private | Flag follows the workflow | -| Schedules / webhooks / triggers | Not live until you deploy in the child | Follow whatever you deploy on the target | -| History, API keys, memory, scheduled jobs | Never | Never | - ---- - -### Workflows - -Only **deployed** workflows move, and only the ones checked under [Synced workflows](#synced-workflows). An unsynced workflow never moves in either direction. - -| Feature | Behavior | -|---|----------| -| **Fork** | Each synced deployed workflow becomes a **draft** in the child. Run history is not copied. Only folders that contain a copied workflow are kept. | -| **Sync** | The change list shows what will be updated, created, or archived. The target is overwritten for those workflows. | - -**Example:** Parent has `Support triage` deployed and `WIP experiment` as a draft. The fork gets only `Support triage` as a draft. A later push updates the child from the parent’s latest deploy of `Support triage`. - ---- - -### Files - -| Feature | Behavior | -|---|----------| -| **Fork** | Listed under **Copy resources** (default on). A copied file keeps its containing folder structure. Folder scopes referenced by copied workflows are mirrored with their ancestors even when they are empty; mirroring a scope does not implicitly copy every file inside it. Deselect a file → that file field clears. | -| **Sync** | Map to a file that already exists on the target, or copy. Files used by the sync’s workflows default to selected. Selected workspace file-folder scopes are mapped separately by canonical path. The same path is suggested automatically when it exists on both sides; otherwise create or choose the intended target folder before syncing. | - -**Example:** A workflow attaches `Brand/brand-guide.pdf` and searches an empty `/Incoming` folder. Fork with Files selected → the child gets its own file under `/Brand`, and `/Incoming` is also created so the search scope still points somewhere valid without copying unrelated files into it. - -Only concrete, active workspace folder selections participate in this mapping. Leaving **Folder** empty means “anywhere in the workspace” and never blocks sync. **Include Subfolders** only changes how a selected scope is expanded. Folder selectors backed by external providers are credential-scoped provider values, not workspace file-folder mappings. - ---- - -### Tables +| --- | --- | --- | +| Deployed workflows | Eligible workflows become drafts; only their needed workflow folders are copied. | Create or replace counterparts; archive mapped counterparts deleted at source. | +| Workspace files | Optional copy; references clear when omitted. | Map or copy. | +| Tables | Optional copy, with rows possibly filled in later. | Map an existing dataset or copy a new one. | +| Knowledge bases | Optional copy with settings, tags, and uploaded documents. | Map or copy the base; documents follow it. | +| Custom tools | Optional definition copy. | Map or copy. | +| Skills | Optional content copy; references to other copied resources are rewritten. | Map or copy. | +| External MCP servers | Optional connection-configuration copy; OAuth sign-in cleared. | Map or copy; copied servers need sign-in. | +| Workflow MCP servers | Optional server shells and attachments to copied workflows. | Attachments stay aligned automatically. | +| Published custom blocks | Remain invocations of their published source. | Map to a publication in the target. | +| Chat deployments | Configuration and a new URL; child workflow must be deployed before serving. | Create only when the target has no existing chat record and is ready to deploy. | +| Credentials | Never copied; workflow fields cleared. | Map only, with compatible integration kind. | +| Secrets | Values never copied; `{{KEY}}` names retained. | Map names only. | +| Public API | Child starts private. | Source flag follows the workflow. | +| Schedules, webhooks, triggers | Inactive until the child deploys. | Activation follows target deployment. | +| Run history, Sim API keys, memory, scheduled jobs, BYOK keys | Not copied. | Not copied. | -| Feature | Behavior | -|---|----------| -| **Fork** | Optional copy (default on). Rows may finish copying in the background after the fork is created. Deselect → table fields clear. | -| **Sync** | Map if both sides should keep pointing at “the same” logical table through the mapping, or copy for an independent dataset on the target. | +### Files and folder scopes -**Example:** An enrichment workflow uses a “Leads” table. Copy on fork so the child can experiment without touching production data. On sync, map if you intentionally want both sides aligned to paired tables, or copy a new table when the target should get a fresh clone. +Copied files keep their containing folder structure. Referenced workspace folder scopes and their ancestors are mirrored even when empty; that does not copy every file within the scope. On sync, map folder scopes by canonical path. Matching paths are suggested; otherwise create or choose the intended target folder. ---- - -### Knowledge bases and documents - -| Feature | Behavior | -|---|----------| -| **Fork** | Optional copy (default on). Tag definitions come with the knowledge base, along with every **uploaded** document in it. Deselect → knowledge base / document fields clear. | -| **Sync** | Map or copy the knowledge base. Documents are not mapped by themselves — they follow the knowledge base (copied with it, or re-picked when you map to an existing one). | - -**Example:** An agent searches knowledge base “Product docs.” Fork with that knowledge base selected → the child gets the base, tags, and the uploaded documents. On sync, mapping to the child’s existing “Product docs” means re-picking which document the tool should use. +For example, copying `Brand/brand-guide.pdf` and a workflow's empty `/Incoming` search scope creates both folders without copying unrelated incoming files. An empty **Folder** means anywhere in the workspace and does not block sync. **Include Subfolders** changes scope expansion only. External-provider folder choices remain credential-dependent values rather than workspace-folder mappings. -#### Connector-synced documents are not copied +### Connector-synced documents are not copied -Connectors themselves never cross a fork edge — the child gets no Confluence, Notion, Google Drive, or other sync running against it. Documents that a **connector** put in the knowledge base are therefore not copied either. Only documents you **uploaded** come across. +Knowledge-base copies include active uploaded documents, tag definitions, and settings. Connectors and their managed documents do not cross the edge. - Fork a knowledge base whose content is entirely connector-synced and the child gets the base, its tags, and its settings — but **no documents**. Add the connector in the child to fill it. +A knowledge base containing only connector-managed content arrives with no documents. Add a connector in the child to populate it, or download source documents and upload them as an intentional frozen snapshot. -This is deliberate. A copied connector document would arrive detached from any connector, so nothing would ever update, re-sync, or remove it — and when you added the connector in the child it would ingest every page again *alongside* the stale copy. Chain a few forks (prod → UAT → staging) and each hop leaves another dead generation behind, so one page comes back several times in a single knowledge search. Skipping them keeps the child’s own connector the single owner of that content. - -| To get connector content into the child | Do this | -|---|---| -| Keep it live | Add the same connector in the child and let it sync. It re-ingests everything, so nothing is lost. | -| Keep a frozen snapshot | Download the documents from the source and upload them to the child’s knowledge base — uploaded documents copy on every later fork. | - -A document whose connector was **deleted** in the source is no longer connector-managed, so it copies like any other uploaded document. - ---- - -### Custom tools - -| Feature | Behavior | -|---|----------| -| **Fork** | Optional copy (default on). The tool definition comes along so agent / tool picks keep working. | -| **Sync** | Map when both sides already maintain the same tool; copy when the target should receive the source’s definition as a new tool. | - -**Example:** A `lookup_customer` custom tool used by an agent. Fork with Custom tools selected → the child’s agent still has the tool. On push, a brand-new tool on the child can be copied into the parent if you leave it selected under **Copy resources**. - ---- - -### Skills - -| Feature | Behavior | -|---|----------| -| **Fork** | Optional copy (default on). Skill content comes along. Links inside the skill to files or other Sim resources are updated when those resources were also copied. Deselect → skill fields on agents clear. | -| **Sync** | Map or copy, same idea as custom tools. | - -**Example:** A “Support tone” skill on an agent. Deselecting it on fork clears the skill on the child’s agent until you attach one again. - ---- - -### External MCP servers - -Servers you connect to an external MCP endpoint (not “publish this workflow as MCP”). - -| Feature | Behavior | -|---|----------| -| **Fork** | Optional copy (default on). **Connection settings** (URL, headers, transport) copy. **Sign-in / OAuth is not copied** — OAuth servers show up disconnected until someone signs in again in the child. Tool picks on MCP and agent blocks follow the new server. | -| **Sync** | Map or copy under the same rules. Mapping is typical when each workspace has its own server aimed at the same upstream system. | - -**Example:** An MCP server for an internal API. After fork, open MCP settings in the child and complete OAuth (or confirm API headers) before those tools will run. On sync, map child ↔ parent servers so tool selections survive push and pull. - ---- - -### Workflow MCP servers +Skipping managed documents avoids stale detached copies alongside the child's later connector ingestion. If a document's connector was deleted at the source, it is no longer connector-managed and can copy like an uploaded document. When mapping to an existing knowledge base, reselect dependent documents from that target base. -Servers that **publish workflows as MCP tools**. +### MCP and chat configuration -| Feature | Behavior | -|---|----------| -| **Fork** | Optional under **Copy resources**. You get matching server shells in the child. When the workflow was also forked, its tool attachment on that server is carried over. | -| **Sync** | These are not shown in the mapping list. Attachments stay aligned as you sync — tools are added, updated, or removed to match the source. | +External MCP copies include URL, headers, transport, and supported OAuth client configuration, but never OAuth tokens. Reauthorize copied servers and inspect literal headers before using them. Workflow MCP attachments follow synced workflows rather than appearing as a separate resource-mapping list. -**Example:** Parent exposes `Support triage` on a workflow MCP server. Fork with Workflow MCP servers selected → the child gets a matching server and the attachment to the child’s copy of the workflow. +Chat copies include authentication configuration, such as password hashes or allowed emails, and block selection, with a new URL. Conversation history is not copied. On sync, any existing target chat record—including an archived one—prevents creating another. Deploy child workflows before testing copied chat URLs. ---- - -### Deployed chats +## Activity, rollback, and disconnect -| Feature | Behavior | -|---|----------| -| **Fork** | Live chat deployments on copied workflows come along with a **new chat URL**. Conversation history is not copied — only the chat setup (including which blocks feed the chat). | -| **Sync** | If the target workflow has **no** chat yet, the source’s live chat is created there (again with a new URL). Existing chats on the target are left alone. Workflows that are not ready to deploy do not get a chat. | +**See activity** includes forks, pushes, pulls, and rollbacks involving this workspace, including operations recorded from the other side. Expand an event for changed resources, copy progress, and warnings. -**Example:** Parent has a public chat on `Support triage`. The fork gets its own chat URL right away. A later push onto a parent workflow that never had a chat can create one there. - ---- +### Rollback -### Credentials +Rollback applies only to the last sync into the target. It restores eligible workflows' prior deployed versions, unarchives workflows that sync archived, and archives/undeploys workflows that sync created. It does not restore arbitrary prior drafts or remove copied tables, files, or knowledge bases. Created chats are archived with their workflows. -| Feature | Behavior | -|---|----------| -| **Fork** | **Never copied.** Credential fields in workflows are cleared. Connect or pick credentials in the child. | -| **Sync** | **Map only.** Every credential used by the synced workflows must be mapped to a credential on the target (same kind of integration). Sync stays blocked until that is done. Then re-pick dependents (labels, calendars, channels, …). | - -**Example:** A Gmail block using “Support inbox.” Fork clears it. Before the first sync, map it to the child’s “Support inbox” credential and re-pick the label. - ---- +Check restored deployment readiness. Activation can remain pending or fail after the restore commits; the undo point is retained while restored versions are not live so retrying can drive the remaining activations. Hard-deleted workflows or versions cannot be restored and are reported as skipped. A newer sync requires reviewing the newest undo point. -### Secrets (environment variables) +### Disconnect -| Feature | Behavior | -|---|----------| -| **Fork** | **Values never leave the source.** Workflow text still contains `{{KEY}}` names. Create matching secrets (or the names you will map to) under the child’s **Secrets**. | -| **Sync** | Map source key names to target key names. Values stay in each workspace. Unmapped required secrets block Sync. | +Disconnect permanently deletes the edge, its mappings and saved dependent choices, workflow identity links, and pair sync history. Both workspaces and their data remain. Disconnecting also separates the fork subtree's Project grouping. The old edge cannot be reconnected; a later fork creates a new child. -Notes are documentation: a `{{KEY}}` that appears only inside a Note block never needs mapping and never blocks Sync. +## Troubleshoot sync -**Example:** Workflows use `{{OPENAI_API_KEY}}`. After fork, add that secret in the child (or map `OPENAI_API_KEY` to whatever name the child uses) before runs and syncs succeed. - ---- - -### Public API - -| Feature | Behavior | -|---|----------| -| **Fork** | Child workflows start **private** — not exposed as public API endpoints, even if the parent was. | -| **Sync** | The source workflow’s public API setting is carried. Push a public endpoint and the target becomes public too. | - ---- +If **Sync** is disabled, resolve the listed blockers, required credentials or secrets, and required dependent fields. Wait for details to load; reload after a failed load. Save edited mappings before continuing. -### Not carried +If a newly deployed workflow is missing from the plan, check its **Synced workflows** checkbox. Changing the lineage default affects future creations only. If a copied table or knowledge base looks empty, inspect Activity before repeating the fork or sync. For an OAuth MCP server, reconnect in the target. For a copied chat, check workflow deployment and any existing target chat record. -These do not move at fork or sync time: - -- Undeployed workflows and local drafts -- Execution / run history -- Sim API keys -- Memory stores and scheduled jobs -- BYOK provider keys -- Permission groups (the child inherits the organization, but groups are not specially applied by forking) - -Schedules, webhooks, and triggers are not live in the child until you **deploy** there — same “deploy = commit” rule. - ---- - -## Edge cases to keep in mind - -- **Force overwrite** — Sync does not merge editor changes. Anything only on the target that conflicts with the source’s deployed workflows can be lost. Use the confirm dialog’s archive list carefully. -- **Deselect on fork** — Cleared references are intentional. Prefer copying the resource, or plan to reconnect it in the child. -- **Background copy** — Right after fork, large tables / knowledge bases / files may still be copying. Check **Activity** if something looks empty. -- **OAuth MCP** — Expect a reconnect in the child (and after a copied server on sync). -- **Rollback ≠ undo copies** — Workflow versions roll back; copied resources can remain as orphans. -- **Disconnect is permanent** — You cannot “reconnect” the same edge; you would fork again into a new workspace. -- **No grandparent sync** — Only the direct parent↔child pair. -- **The sync default is lineage-wide** — **Sync new workflows by default** is one shared setting for the whole lineage, so changing it from a fork also changes it in the parent and every sibling fork. - ---- - - +## Self-hosted setup ---- +On billing-disabled deployments, enable forking through enterprise configuration or explicitly set: -## Self-hosted setup +```bash +FORKING_ENABLED=true +NEXT_PUBLIC_FORKING_ENABLED=true +``` -Self-hosted deployments turn Forks on with an environment variable instead of the Enterprise plan. +Explicit feature values take precedence over the master configuration. Billing-enabled self-hosted deployments still require Enterprise. See [self-hosted enterprise setup](/platform/enterprise/self-hosted). -| Variable | Description | -|----------|-------------| -| `FORKING_ENABLED`, `NEXT_PUBLIC_FORKING_ENABLED` | Enables workspace forking when billing is not used as the entitlement gate | +## Related docs -Once enabled, use the same **Settings → Workspace → Workspace forks** UI as Sim Cloud. Only workspace admins can manage forks. +- [API and CLI workflow sync](/api-reference/workflow-sync) +- [Workflow deployment](/workflows/deployment) +- [Custom blocks](/platform/enterprise/custom-blocks) +- [Knowledge-base connectors](/knowledgebase/connectors) diff --git a/apps/docs/content/docs/platform/enterprise/index.mdx b/apps/docs/content/docs/platform/enterprise/index.mdx index 52acd3e5216..0e30e3f342e 100644 --- a/apps/docs/content/docs/platform/enterprise/index.mdx +++ b/apps/docs/content/docs/platform/enterprise/index.mdx @@ -1,21 +1,21 @@ --- title: Enterprise -description: Enterprise features for business organizations +description: Configure organization access, provisioning, security, and operations --- -Sim Enterprise adds organization controls for access, provisioning, operations, and branding. Organization owners and admins configure these features in Settings. +Sim Enterprise adds controls for organization access, member provisioning, security, operations, and branding. On Sim Cloud, these features require an Enterprise subscription. Organization owners and admins manage organization controls in **Settings → Organization**. | Feature | Use it to | -|---|---| +| --- | --- | | [Permission groups](/platform/enterprise/access-control) | Restrict features, models, blocks, and tools by workspace and member | | [Single sign-on](/platform/enterprise/sso) | Connect a SAML or OIDC identity provider | -| [Verified domains](/platform/enterprise/verified-domains) | Prove domain ownership for SSO and provisioning | -| [Directory provisioning](/platform/enterprise/scim) | Sync users and group-based access from your directory | -| [Security](/platform/enterprise/security) | Manage session policies and view configured outbound IP addresses | -| [Session policies](/platform/enterprise/session-policies) | Set session lifetimes and revoke member sessions | +| [Verified domains](/platform/enterprise/verified-domains) | Prove domain ownership for sign-in and provisioning | +| [Directory provisioning](/platform/enterprise/scim) | Sync members and group-based access from your directory | +| [Security](/platform/enterprise/security) | Find session controls and configured outbound IP addresses | +| [Session policies](/platform/enterprise/session-policies) | Limit session lifetimes and revoke member sessions | | [Audit logs](/platform/enterprise/audit-logs) | Investigate configuration and security events | -| [Insights](/platform/enterprise/usage-tracking) | Explore credit usage, workflow performance, and recorded chat activity | -| [Data retention](/platform/enterprise/data-retention) | Set retention windows and configure PII redaction | +| [Insights](/platform/enterprise/usage-tracking) | Explore credit usage, workflow performance, and recorded Chat activity | +| [Data retention](/platform/enterprise/data-retention) | Configure retention windows and PII redaction | | [Data drains](/platform/enterprise/data-drains) | Export logs and Chat records to your own destination | | [Custom blocks](/platform/enterprise/custom-blocks) | Share a workflow as a block across the organization | | [Workspace forks](/platform/enterprise/forks) | Copy a workspace and sync deployed workflow changes | @@ -23,17 +23,13 @@ Sim Enterprise adds organization controls for access, provisioning, operations, ## Self-hosted setup -Self-hosted deployments unlock enterprise features through environment configuration instead of billing. One switch turns on the whole set: +On a self-hosted deployment with billing disabled, enable enterprise features through environment variables: ```bash ENTERPRISE_ENABLED=true NEXT_PUBLIC_ENTERPRISE_ENABLED=true ``` -Each feature also keeps its own flag, so you can enable them one at a time or switch a single feature back off. +Individual feature flags override the master switch. Most enterprise settings also need an organization that owns the workspace. Choose one instance-wide organization or provision separate organizations through the Admin API. -Most of these features read their settings from the organization that owns a workspace, so a deployment also needs an organization model — either one instance-wide organization that every user joins automatically, or organizations you provision yourself through the Admin API. - -See the [self-hosted enterprise guide](/platform/enterprise/self-hosted) for the full variable list, both organization patterns, the Admin API reference, and troubleshooting. - -Once enabled, each feature is configured through the same Settings UI as Sim Cloud. When invitations are disabled (`DISABLE_INVITATIONS`, `NEXT_PUBLIC_DISABLE_INVITATIONS`), use the Admin API (`x-admin-key` header) to manage organization membership and workspace access. Internal members join the organization; external workspace members only receive access to a specific workspace. +See [Self-hosted enterprise](/platform/enterprise/self-hosted) for flags, organization setup, background schedules, and Admin API examples. Once enabled, configure features through the same Settings UI as Sim Cloud. diff --git a/apps/docs/content/docs/platform/enterprise/meta.json b/apps/docs/content/docs/platform/enterprise/meta.json index c87d6bad42d..40747acf94a 100644 --- a/apps/docs/content/docs/platform/enterprise/meta.json +++ b/apps/docs/content/docs/platform/enterprise/meta.json @@ -8,13 +8,13 @@ "security", "session-policies", "access-control", + "forks", "custom-blocks", - "whitelabeling", "audit-logs", "usage-tracking", "data-retention", "data-drains", - "forks" + "whitelabeling" ], "defaultOpen": false } diff --git a/apps/docs/content/docs/platform/enterprise/scim/entra.mdx b/apps/docs/content/docs/platform/enterprise/scim/entra.mdx index 8009198537f..b5dd7863028 100644 --- a/apps/docs/content/docs/platform/enterprise/scim/entra.mdx +++ b/apps/docs/content/docs/platform/enterprise/scim/entra.mdx @@ -1,127 +1,144 @@ --- title: Microsoft Entra provisioning -description: Connect Microsoft Entra ID to Sim and verify user and group provisioning +description: Connect Microsoft Entra ID and verify member and group provisioning --- import { Callout } from 'fumadocs-ui/components/callout' import { Step, Steps } from 'fumadocs-ui/components/steps' import { Image } from '@/components/ui/image' -Use a non-gallery enterprise application in Microsoft Entra ID to create, update, and deactivate Sim members. Configure [single sign-on](/platform/enterprise/sso) separately for authentication. +Use a non-gallery enterprise application in Microsoft Entra ID to create, update, and deactivate Sim organization members. Configure [single sign-on](/platform/enterprise/sso) separately for authentication. ## Before you start -- An Enterprise organization in Sim, with an owner or administrator who can manage provisioning. -- Each user email domain [verified in Sim](/platform/enterprise/verified-domains). -- An Entra administrator who can create enterprise applications and manage provisioning. -- A Sim deployment reachable by Entra over HTTPS. Self-hosted deployments must also meet the [SCIM rollout requirements](/platform/enterprise/scim#deployment-and-upgrades). +- Use an Enterprise organization in Sim and an organization owner or admin account. +- [Verify each provisioned email domain](/platform/enterprise/verified-domains). +- Use an Entra administrator who can create enterprise applications and manage provisioning. +- Make Sim reachable by Entra over HTTPS. Self-hosted deployments must meet the [SCIM rollout requirements](/platform/enterprise/scim#deployment-and-upgrades). -Automated user provisioning is available with Entra ID Free. Group provisioning and group-based application assignment require Entra ID P1 or higher. See [Microsoft's licensing comparison](https://learn.microsoft.com/en-us/entra/fundamentals/licensing). +Automated user provisioning is available with Entra ID Free. Group provisioning and group-based application assignment require P1 or higher. See [Microsoft licensing](https://learn.microsoft.com/en-us/entra/fundamentals/licensing). -Start with dedicated test users. Provisioned members use a seat and receive workspace access only through a mapping or an existing grant. +Start with dedicated test accounts. Provisioned members use a seat and receive workspace access through mappings or existing grants. ## Connect Entra to Sim - ### Enable provisioning in Sim -Open **Settings → Organization → Single sign-on → Provisioning** and turn on **Enable directory provisioning**. Copy the **Base URL** from **Connection**. Under **Tokens**, choose an expiry and select **Issue token**. Copy the token before closing its dialog; Sim shows it once. +Open **Settings → Organization → Single sign-on → Provisioning** and enable **Enable directory provisioning**. Copy **Connection → Base URL**. Under **Tokens**, choose an expiry and select **Issue token**. Copy the token before closing its dialog; Sim shows it once. ### Create the enterprise application -In Microsoft Entra ID, open **Enterprise applications → New application → Create your own application**. Enter a name, such as **Sim provisioning**, select **Integrate any other application you don't find in the gallery (Non-gallery)**, and select **Create**. - +In Entra, open **Enterprise applications → New application → Create your own application**. Name the app, for example **Sim provisioning**, choose **Integrate any other application you don't find in the gallery (Non-gallery)**, and select **Create**. ### Configure the connection -In the new application's **Provisioning** page, select **New configuration**. Choose **Bearer authentication** and enter: +Open the app's **Provisioning** page, select **New configuration**, and choose **Bearer authentication**. | Field | Value | | --- | --- | -| Tenant URL | The HTTPS Base URL copied from Sim, ending in `/api/scim/v2` | -| Secret token | Your Sim token, without a `Bearer ` prefix | +| **Tenant URL** | Sim's HTTPS Base URL ending in `/api/scim/v2` | +| **Secret token** | Your Sim token, without a `Bearer ` prefix | -Select **Test connection**, then **Create** after the test succeeds. Entra adds the bearer prefix itself. A successful connection test verifies connectivity and authentication; continue with a test assignment to verify provisioning. +Select **Test connection**, then **Create** after it succeeds. Entra adds the bearer prefix. A successful test confirms connectivity and authentication; a test assignment verifies provisioning. -Entra provisioning connection settings with the deployment URL redacted and secret token masked +Entra Bearer authentication fields with a redacted Tenant URL and masked Secret token - These steps use Entra's current provisioning experience. In the legacy experience, choose **Automatic** provisioning, enter the same credentials under **Admin Credentials**, test the connection, and save. See [Microsoft's SCIM configuration guide](https://learn.microsoft.com/en-us/entra/identity/app-provisioning/use-scim-to-provision-users-and-groups). + In Entra's legacy provisioning experience, choose **Automatic**, enter the same values under **Admin Credentials**, test, and save. See [Microsoft SCIM configuration](https://learn.microsoft.com/en-us/entra/identity/app-provisioning/use-scim-to-provision-users-and-groups). - -### Limit the scope and review mappings +### Set scope and attribute mappings + +In the configuration's **Properties**, keep **Scope** set to **Sync only assigned users and groups**. Review accidental deletion protection before broadening the rollout. -Under the provisioning configuration's **Properties**, keep **Scope** set to **Sync only assigned users and groups**. Review accidental deletion protection before broadening the rollout. +Under **Users and groups → Add user/group**, choose a test account and select **Assign**. On the Free plan, assign accounts individually. -In the application's **Users and groups**, select **Add user/group**, choose a test user, and select **Assign**. On the Free plan, assign users individually. +Under **Attribute mapping**, review the user mappings: -Under **Attribute mapping**, review the user mappings. The defaults map `userPrincipalName` to `userName`, `mail` to the work email, and `displayName` to `displayName`. Use a valid email address from a verified Sim domain; if your UPN differs from the user's email, adjust the mappings before provisioning. Keep `userName` as the matching attribute. +| Entra attribute | SCIM attribute | +| --- | --- | +| `userPrincipalName` | `userName`, retained as the matching attribute | +| `mail` | Work email | +| `displayName` | `displayName` | -If **Mail** is empty, Entra omits the work email and Sim uses `userName` as the account email. That UPN must be a valid email address in a verified Sim domain. +Use an email in a verified Sim domain. If the UPN differs from the account email, adjust mappings before provisioning. When **Mail** is empty, Entra omits the work email and Sim uses `userName` as the account email; that UPN must be a valid email address in a verified domain. -Entra provisioning properties restricted to assigned users and groups +Entra Properties showing assigned-only provisioning scope, accidental deletion protection, and Skip out of scope deletions disabled - -## Verify a user lifecycle +## Verify the user lifecycle -Open **Provision on demand**, search for the assigned test user, and select **Provision**. Review the import, scope, matching, and action results. In Sim, confirm that the member appears under **Organization → Members** and that **Single sign-on → Provisioning → Activity** shows successful requests. +1. Open **Provision on demand**, search for the assigned test account, and select **Provision**. Inspect the import, scope, matching, and action results. +2. In Sim, confirm the member under **Organization → Members** and successful requests under **Single sign-on → Provisioning → Activity**. +3. Change its display name in Entra and provision again. Confirm the new name in Sim. An unchanged repeat should report that source and target already match. +4. Remove the app assignment, then provision that account on demand again. Confirm Sim deactivates the member. +5. Reassign and provision it to verify reactivation of the same account. Assignment changes can take a few minutes to reach provisioning. -Successful on-demand user provisioning in Entra with account details redacted +Successful Entra on-demand import, scope, matching, and action checks with account details redacted -Change the test user's display name in Entra and provision them again. Confirm the new name in Sim. Repeating provisioning without changes should report that the source and target already match. +### Deactivation and directory deletion -Remove the test user's app assignment, then run on-demand provisioning for that user again. Confirm that Sim deactivates the existing member. Reassign the user and provision again to verify reactivation of the same account. Assignment changes can take a few minutes to become available to provisioning. +| Entra change | Provisioning behavior | +| --- | --- | +| App unassignment | Deactivates the Sim member. Entra then stops managing the account and does not send a later directory deletion. | +| Soft deletion while still managed | Deactivates the Sim member. | +| Permanent deletion while still managed | Sends SCIM `DELETE`, which removes organization membership. Entra normally permanently deletes accounts 30 days after soft deletion; an administrator can purge earlier. | -Sim deactivation suspends access while retaining organization membership, ownership, and the seat. For users still managed by the provisioning job, soft deletion deactivates the Sim member and permanent deletion sends a SCIM `DELETE` that removes organization membership. Entra normally permanently deletes users 30 days after soft deletion, or sooner if an administrator purges them. After app unassignment, Entra stops managing the user and does not send a later directory deletion. See [Microsoft's deprovisioning lifecycle](https://learn.microsoft.com/en-us/entra/identity/app-provisioning/how-provisioning-works#deprovisioning) and [Sim's deactivation behavior](/platform/enterprise/scim#what-it-does). +Sim deactivation suspends access while retaining membership, ownership, and the seat. See [Microsoft's deprovisioning lifecycle](https://learn.microsoft.com/en-us/entra/identity/app-provisioning/how-provisioning-works#deprovisioning) and [Sim's lifecycle behavior](/platform/enterprise/scim#what-it-does). - Disabled or deleted Entra users cannot be selected for on-demand provisioning. [Start automatic provisioning](#start-automatic-provisioning) and complete the initial cycle before testing those changes through a scheduled cycle. See [Microsoft's on-demand limitations](https://learn.microsoft.com/en-us/entra/identity/app-provisioning/provision-on-demand). + Disabled or deleted Entra accounts do not appear in on-demand search. Start automatic provisioning and finish the initial cycle before testing those changes through a scheduled cycle. See [Microsoft on-demand limitations](https://learn.microsoft.com/en-us/entra/identity/app-provisioning/provision-on-demand). -## Provision groups and map access - -With Entra ID P1 or higher, create a dedicated security group with **Assigned** membership and add your test users as direct members. Assign that group to the enterprise application under **Users and groups**. Review the group mapping under **Attribute mapping** and keep group provisioning enabled. +## Provision groups and verify access -Run **Provision on demand** for the group and select its test members, or wait for a scheduled cycle. On-demand provisioning supports one group with up to five selected members at a time. Nested group membership is not supported; see [Microsoft's assignment guidance](https://learn.microsoft.com/en-us/entra/identity/enterprise-apps/assign-user-or-group-access-portal). +With P1 or higher, create a security group with **Assigned** membership and add test accounts as direct members. Assign it under **Users and groups**. Review **Attribute mapping** and keep group provisioning enabled. -Once the group appears under **Single sign-on → Provisioning → Group mappings** in Sim, map it to a workspace, permission group, or the organization admin role. Start with a workspace mapping and confirm that the test members gain access. +1. Run **Provision on demand** for one group and select up to five test members, or wait for a scheduled cycle. Nested membership is unsupported; see [Microsoft group assignment](https://learn.microsoft.com/en-us/entra/identity/enterprise-apps/assign-user-or-group-access-portal). +2. Once the group appears under **Single sign-on → Provisioning → Group mappings** in Sim, map it to a workspace, permission group, or organization admin role. Start with a workspace mapping and confirm access. +3. Remove a test member from the group while retaining a separate direct app assignment. After synchronization, confirm the directory workspace grant is withdrawn while the account remains active. +4. Add the member back and verify access returns. -Remove a test user from the group while keeping a separate direct app assignment. After the group membership sync, confirm that the directory workspace grant is withdrawn while the user remains an active organization member. Add them back and verify that access returns. Read [how Sim withdraws directory access](/platform/enterprise/scim#how-access-is-withdrawn) before mapping groups that overlap with existing manual access. +Read [How access is withdrawn](/platform/enterprise/scim#how-access-is-withdrawn) before mapping groups that overlap manual access. ## Start automatic provisioning -After the test succeeds, return to the provisioning **Overview** and select **Start provisioning**. Wait for the initial cycle to complete and inspect **Provisioning logs** for failures. Entra normally runs subsequent cycles about every 40 minutes; changes are not immediate. See [Microsoft's provisioning lifecycle](https://learn.microsoft.com/en-us/entra/identity/app-provisioning/how-provisioning-works). +After testing, return to the provisioning **Overview** and select **Start provisioning**. Wait for the initial cycle and inspect **Provisioning logs** for failures. Subsequent cycles normally run about every 40 minutes; changes are not immediate. See [Microsoft's provisioning lifecycle](https://learn.microsoft.com/en-us/entra/identity/app-provisioning/how-provisioning-works). -Keep the scope limited to assigned users and groups as you add more members. Use **Provision on demand** for a small test; use the regular cycle to verify directory account disablement and deletion. +Keep the scope limited to assigned accounts and groups. Use on-demand provisioning for small tests, and regular cycles for directory disablement or deletion. -During a scheduled lifecycle test, leave the job running after changing the test user. **Restart provisioning** clears the change watermark and begins a new initial cycle; changing mappings or scoping filters also resets it. Wait for the incremental cycle and inspect that user's provisioning log before making further changes. +Leave the job running during a scheduled lifecycle test. **Restart provisioning** clears its change watermark and starts another initial cycle; changing mappings or scoping filters also resets it. Wait for the incremental cycle and inspect the account's log before changing more settings. -## Rotate the token +## Rotate a token -Issue a replacement token in Sim while the current token remains active. In Entra, open the provisioning configuration's **Connectivity** page, replace **Secret token**, select **Test connection**, and save. Confirm a successful provisioning request before revoking the old token in Sim. Sim allows two active tokens so rotation can overlap. +Issue a replacement token in Sim while the current one remains active. In Entra's provisioning configuration, open **Connectivity**, replace **Secret token**, select **Test connection**, and save. Confirm a successful provisioning request before revoking the old token. Sim allows two active tokens for overlapping rotation. ## Troubleshooting | Symptom | Check | | --- | --- | -| Connection test fails | Enter only the token in **Secret token**. Check the complete HTTPS Tenant URL, token expiry, and whether provisioning is enabled in Sim. | -| User is out of scope | Assign the user to this enterprise application and check the provisioning scope and scoping filters. Allow time for assignment changes to propagate. | -| User creation fails | Verify the email domain in Sim, available seats, and whether the account belongs to another Sim organization. Review the mapped UPN and work email. | -| Repeat provisioning reports **Skipped** | Inspect the reason. **RedundantExport** means the source and target already match. | -| Directory disablement or deletion has not reached Sim | Check the user's scheduled provisioning log, the `IsSoftDeleted` mapping to `active`, enabled **Update** actions, and accidental deletion protection. Confirm **Skip out of scope deletions** is disabled. A successful connection test alone does not verify a lifecycle change. | -| Group assignment is unavailable | Check your Entra license. The Free plan supports individual user assignment but requires an upgrade for group assignment and provisioning. | -| Member has no workspace access | Provision the directory group and add a workspace mapping in Sim. User provisioning creates organization membership. | -| Disabled member still uses a seat | Sim suspends access on deactivation. Removing organization membership is a separate offboarding action. | - -Use Entra's **Provisioning logs** and Sim's **Provisioning → Activity** to inspect failures. Invalid or revoked tokens appear only in Entra because Sim cannot associate those requests with a connection. +| Connection test fails | Enter the token alone. Check the full HTTPS Tenant URL, token expiry, and Sim provisioning switch. | +| Account is out of scope | Check app assignment, provisioning scope, and scoping filters. Allow time for assignment propagation. | +| User creation fails | Verify the domain, available seats, and whether the account belongs to another Sim organization. Check mapped UPN and work email. | +| Repeat provisioning is **Skipped** | Inspect its reason. **RedundantExport** means source and target already match. | +| Disablement or deletion has not reached Sim | Inspect the scheduled log, `IsSoftDeleted` mapping to `active`, enabled **Update** actions, and accidental deletion protection. Confirm **Skip out of scope deletions** is disabled. A connection test does not verify lifecycle changes. | +| Group assignment is unavailable | Check licensing. Free supports individual assignment; group assignment and provisioning require an upgrade. | +| Member has no workspace access | Provision the directory group and add a Sim workspace mapping. User provisioning adds organization membership. | +| A disabled member still uses a seat | Deactivation suspends access; organization removal is separate. | + +Use Entra's **Provisioning logs** and Sim's **Provisioning → Activity**. Invalid or revoked tokens appear only in Entra because Sim cannot associate them with a connection. + +## Related docs + +- [Directory provisioning](/platform/enterprise/scim) +- [Single sign-on](/platform/enterprise/sso) +- [Verified domains](/platform/enterprise/verified-domains) diff --git a/apps/docs/content/docs/platform/enterprise/scim/index.mdx b/apps/docs/content/docs/platform/enterprise/scim/index.mdx index c75d13bbaf5..a3630aefa7c 100644 --- a/apps/docs/content/docs/platform/enterprise/scim/index.mdx +++ b/apps/docs/content/docs/platform/enterprise/scim/index.mdx @@ -1,51 +1,58 @@ --- title: Directory provisioning (SCIM) -description: Create, update, and deactivate Sim members automatically from your identity provider +description: Sync organization members and group-based access from your identity provider --- import { Callout } from 'fumadocs-ui/components/callout' import { Step, Steps } from 'fumadocs-ui/components/steps' -import { Tab, Tabs } from 'fumadocs-ui/components/tabs' -import { Image } from '@/components/ui/image' -import { FAQ } from '@/components/ui/faq' +import { Tab, Tabs } from '@/components/ui/tabs' -Directory provisioning connects your identity provider to Sim over SCIM 2.0. Your provider creates members when someone joins, updates them when their details change, and deactivates them when it sends a deactivation request — without anyone touching Sim. +Directory provisioning uses SCIM 2.0, a standard protocol for syncing accounts, to create, update, and deactivate organization members from your identity provider. Map directory groups to workspace access, permission groups, or the organization admin role. -It pairs with [SSO](/platform/enterprise/sso). SSO proves who someone is when they sign in. Directory provisioning decides who exists and what they can reach, before and after that. +Configure [SSO](/platform/enterprise/sso) separately for authentication. SCIM can manage membership without a saved SSO provider. - - Included with Enterprise plans. The settings are under **Single sign-on → Provisioning**. On self-hosted deployments, enable the SSO settings page to reach this tab. A saved SSO provider is not required for SCIM; [verify each email domain](/platform/enterprise/verified-domains) before provisioning users at that domain. Self-hosted deployments get it with the other enterprise features through `ENTERPRISE_ENABLED=true` and `NEXT_PUBLIC_ENTERPRISE_ENABLED=true`, or turn just this feature on or off with `SCIM_ENABLED` and `NEXT_PUBLIC_SCIM_ENABLED`, alongside the [SSO variables](/platform/enterprise/sso#self-hosted-setup). - +## Before you start + +- On Sim Cloud, use an Enterprise organization and an organization owner or admin account. +- [Verify every email domain](/platform/enterprise/verified-domains) you will provision. Sim refuses account creation or an email change to an unverified domain. +- On self-hosted deployments, enable SSO to reach **Single sign-on → Provisioning**, and enable SCIM. The enterprise master pair enables both; individual setup uses `SSO_ENABLED`, `NEXT_PUBLIC_SSO_ENABLED`, `SCIM_ENABLED`, and `NEXT_PUBLIC_SCIM_ENABLED`. See [Self-hosted SSO setup](/platform/enterprise/sso#self-hosted-setup) and [Deployment and upgrades](#deployment-and-upgrades). ## What it does -| Your provider does this | Sim does this | +| Directory request | Sim behavior | | --- | --- | -| Assigns a person to the Sim app | Creates or links their account; new organization members join as Members | -| Updates their name or email | Updates the Sim account, and ends their sessions if the address changed | -| Deactivates them | Blocks sign-in and stops their personal API keys. Everything they own, and every grant they hold, is left untouched; shared workspace keys keep working | -| Reactivates them | Lifts the suspension; current group memberships and mappings determine access | -| Sends a SCIM DELETE request | Removes their organization membership, ends their sessions, deletes their personal API keys, and reassigns what they owned | -| Adds them to a group | Grants whatever that group maps to | +| Provision a person | Creates or links an account and adds new organization members as Members. Workspace access requires a mapping or existing grant. | +| Update name or email | Updates the account. An email change ends its sessions. | +| Deactivate a person | Suspends sign-in and personal API keys, and blocks scheduled runs or triggers acting as that person. Ownership, credentials, grants, and workspace history are retained. Shared workspace keys keep working. | +| Reactivate a person | Lifts the suspension. Current group memberships and mappings govern directory access. | +| Send SCIM `DELETE` | Removes organization membership, ends sessions, deletes personal API keys, and reassigns owned resources. The Sim account survives. | +| Add or remove group membership | Applies or withdraws the group's mapped access. | -Deactivation preserves ownership, credentials, and workspace history. It also blocks scheduled runs and triggers acting as that person. Changes to group membership or mappings can still withdraw access while someone is suspended. +Deactivation itself does not withdraw grants. Group or mapping changes can still withdraw access and reassign ownership while someone is suspended. A deactivated member keeps their seat until removed from the organization. -## Turn it on +Deactivation deletes the member's sessions and stops personal API-key authentication when it completes. Organization security-version invalidation reaches cached browser sessions on other application instances within up to 60 seconds. - +Sim refuses directory suspension or removal of an organization owner. Transfer ownership in Sim first. - -### Verify your domain +### Match an existing account + +Sim links an account already in your organization or in no organization, using its verified-domain email. An account in another organization causes a conflict: a Sim account can belong to only one organization, so remove it there before provisioning here. -Sim only provisions people whose email is in a domain your organization has verified. See [Verified domains](/platform/enterprise/verified-domains). +New members follow the organization's seat policy. Fixed-seat plans reject a join when full; add seats and let the provider retry. Team seat policies grow the billed seat count with membership. Cloud SCIM availability still requires Enterprise. + +## Enable provisioning + + + +### Verify domains -This is what stops another tenant's directory from claiming an address it does not own. +Verify each provisioned email domain under **Settings → Organization → Single sign-on → Domains**. This prevents a directory from claiming addresses its organization does not own. -### Enable directory provisioning +### Enable the connection -Open **Settings → Organization → Single sign-on → Provisioning** and turn on **Enable directory provisioning**. Sim shows your SCIM base URL: +Open **Single sign-on → Provisioning** and turn on **Enable directory provisioning**. Copy the **Base URL** under **Connection**: ``` https:///api/scim/v2 @@ -55,168 +62,145 @@ https:///api/scim/v2 ### Issue a token -In **Tokens**, choose whether the token expires (never, 90 days, or a year) and select **Issue token**. It appears once — copy it straight into your provider. +Under **Tokens**, choose **Never expires**, **Expires in 90 days**, or **Expires in 1 year**, then select **Issue token**. Copy the token before closing the dialog; Sim shows it once. -Two tokens can be active at a time, so you can rotate without downtime: issue the new one, update your provider, confirm a sync succeeds, then revoke the old one. +At most two tokens can be active. To rotate, issue a replacement, update the provider, confirm a successful provisioning request, then revoke the old token. -### Configure your provider +### Configure the provider -For a step-by-step walkthrough, see [Okta provisioning](/platform/enterprise/scim/okta). +Follow [Okta provisioning](/platform/enterprise/scim/okta) for integration selection, setup, and lifecycle checks. The evaluation **SCIM 2.0 Test App (Header Auth)** template expects the complete `Authorization` header in **API Token**: -If you use OIDC for sign-in, create a separate provisioning integration: Okta cannot add SCIM to a custom OIDC app. In the Okta Integration Network catalog, add **SCIM 2.0 Test App (Header Auth)** for a private integration. See [Okta's setup guide](https://developer.okta.com/docs/guides/scim-provisioning-integration-connect/main/). - -In that app, open **Provisioning → Integration → Configure API Integration**, enable API integration, and enter: - -- **Base URL**: `https:///api/scim/v2` -- **API Token**: `Bearer ` (include `Bearer` and a space) - -Select **Test API Credentials**, then save. Under **Provisioning → To App**, enable Create Users, Update User Attributes, and Deactivate Users. Assign a test user first, then use **Push Groups** for groups you want to map in Sim. Keep assignment groups separate from groups you push, as required by Okta. - -For an existing custom SAML or SWA app instead, follow [Okta's custom-app SCIM guide](https://help.okta.com/en-us/Content/Topics/apps/apps_app_integration_wizard_scim.htm). Its SCIM connection fields differ: set the unique identifier to `userName`, choose HTTP Header authentication, and enable the relevant provisioning actions. +``` +Bearer +``` -Okta never deletes users over SCIM. Unassigning someone, or deactivating them in Okta, sends a deactivation — which Sim applies as a suspension. +Classic OIDC apps need a separate provisioning integration; OIDC apps created in the newer Okta Integration Wizard can support SCIM. The guide separates evaluation templates from production integration requirements. Keep app-assignment groups separate from Group Push groups. +Okta sends deactivation rather than SCIM user `DELETE`, so offboarding suspends access while retaining membership and the seat. -For a step-by-step walkthrough, see [Microsoft Entra provisioning](/platform/enterprise/scim/entra). - -Create a non-gallery enterprise application. Open **Provisioning → New configuration** and choose **Bearer authentication**. In the legacy experience, set Provisioning Mode to **Automatic** instead. - -- **Tenant URL**: `https:///api/scim/v2` -- **Secret token**: your Sim token, without a `Bearer ` prefix - -Test the connection and create the configuration. Keep **Sync only assigned users and groups** as the scope, assign a test user, and verify them with **Provision on demand** before starting automatic provisioning. Group provisioning requires Entra ID P1 or higher; individual user provisioning is available on the Free plan. +Follow [Microsoft Entra provisioning](/platform/enterprise/scim/entra) to create a non-gallery application, configure **Bearer authentication**, and test assigned users before starting the automatic job. -Entra runs an initial cycle over everyone in scope, then incremental cycles roughly every 40 minutes. Unassignment normally sends a deactivation. Soft-deleted directory users are retained for 30 days; hard deletion can then send a SCIM DELETE during a provisioning cycle. An administrator can hard-delete earlier, and users already unassigned may no longer be managed. See [Microsoft’s provisioning lifecycle](https://learn.microsoft.com/en-us/entra/identity/app-provisioning/how-provisioning-works). +Use the Sim Base URL as **Tenant URL**. Enter the token alone in **Secret token**, without `Bearer `. User provisioning is available with Entra ID Free; group provisioning requires P1 or higher. +Entra's incremental cycles normally run about every 40 minutes. Unassignment and soft deletion deactivate a Sim member; permanent deletion can send SCIM `DELETE` while the provisioning job still manages the account. See the guide for the 30-day directory deletion window, early purge, and on-demand limits. -Add **SCIM Provisioner with SAML (SCIM v2 Core)**. Use the SCIM 2.0 connector, since Sim does not support SCIM 1.1. +Add **SCIM Provisioner with SAML (SCIM v2 Core)**. Use version 2.0; Sim does not support SCIM 1.1. -- **SCIM Base URL**: `https:///api/scim/v2` -- **SCIM Bearer Token**: your Sim token - -In **Parameters**, map `scimusername` to the user's email. Check that **SCIM JSON Template** uses `urn:ietf:params:scim:schemas:core:2.0:User` and sends that email as `userName` or in `emails`. Save, enable the API connection, then enable provisioning. See [OneLogin's custom connector guide](https://onelogin.service-now.com/kb?id=kb_article_view&sysparm_article=KB0013904). +| Field | Value | +| --- | --- | +| **SCIM Base URL** | `https:///api/scim/v2` | +| **SCIM Bearer Token** | Your Sim token | -Choose what happens when a user is deleted in OneLogin. **Suspend** maps to a Sim suspension; **Delete** removes their membership. If administrative approval is enabled, approve the pending provisioning actions in OneLogin before expecting a sync. See [OneLogin's provisioning test guide](https://developers.onelogin.com/docs/scim/test-your-scim/). +In **Parameters**, map `scimusername` to the account's email. Confirm that **SCIM JSON Template** uses `urn:ietf:params:scim:schemas:core:2.0:User` and sends the email as `userName` or in `emails`. Save, enable the API connection, then enable provisioning. See [OneLogin custom connectors](https://onelogin.service-now.com/kb?id=kb_article_view&sysparm_article=KB0013904). +Choose the deletion behavior: **Suspend** suspends the Sim account; **Delete** removes organization membership. If administrative approval is enabled, approve pending actions before expecting synchronization. See [OneLogin provisioning tests](https://developers.onelogin.com/docs/scim/test-your-scim/). -Open an application's **Provisioning** tab and configure a **Custom SCIM** integration. You can use an existing application, a custom SAML application, or a URL Bookmark for provisioning without SAML. - -- **Base URL**: `https:///api/scim/v2` -- **Token** (also called **Token Key**): your Sim token -- **Test User Email**: an unused address in a domain verified by your Sim organization +Open the application's **Provisioning** tab and configure **Custom SCIM**. Use an existing application, a custom SAML application, or a URL Bookmark for provisioning without SAML. -Select **Test Connection**, enable group management if you plan to map groups, then select **Activate**. Activation creates and deletes a test user and, with group management enabled, a test group. See [JumpCloud's custom SCIM guide](https://jumpcloud.com/support/provision-and-manage-users-and-groups-in-apps-using-custom-scim-identity-management-integration). +| Field | Value | +| --- | --- | +| **Base URL** | `https:///api/scim/v2` | +| **Token** or **Token Key** | Your Sim token | +| **Test User Email** | An unused address in a domain verified by your Sim organization | +Select **Test Connection**, enable group management if you will map groups, then select **Activate**. Activation creates and deletes a test account and, with group management enabled, a test group. The test email must not already exist in Sim. See [JumpCloud custom SCIM](https://jumpcloud.com/support/provision-and-manage-users-and-groups-in-apps-using-custom-scim-identity-management-integration). -### Map your groups +### Map directory groups -Groups mean nothing to Sim until you say what they stand for. In **Single sign-on → Provisioning → Group mappings**, point each pushed group at one or more of: +Under **Provisioning → Group mappings**, map each synced group to one or more targets: -- a **permission group**, which governs models, integrations, and capabilities -- a **workspace**, at Read, Write, or Admin -- the **organization admin role** +- A **Permission group**, which governs models, integrations, and capabilities. +- A **Workspace**, with **Read**, **Write**, or **Admin** access. +- The **Organization admin** role. -A group can carry several mappings. When two groups grant the same workspace at different levels, the stronger one wins. The organization's default permission group cannot be a target: it governs by having no members. +When multiple groups grant the same workspace at different levels, the strongest grant wins. The organization's default permission group cannot be a mapping target. -Under **Provisioning rules**, select **Manage rules**. **Match permission groups by name** maps new or renamed directory groups to existing permission groups with the exact same name, including capitalization. After enabling it for groups already synced, select **Reconcile now** or wait for the next scheduled reconciliation. Sim creates no permission groups; renaming a directory group updates its automatic mapping and preserves mappings added manually. + + Mapping a permission group permanently switches it to explicit membership: it applies only to its members, and an empty mapped group applies to nobody. A group that previously applied to everyone in its workspaces stops doing so when mapped. Use permission groups created for directory membership rather than existing organization-wide groups. + -Mapping a permission group to a directory group switches that permission group to explicit membership permanently: it governs exactly the people in it, and an empty group governs nobody. A permission group that governed everyone in its workspaces stops doing so the moment it is mapped, so map groups you created for the directory rather than your organization-wide ones. +Under **Provisioning rules → Manage rules**, **Match permission groups by name** maps new or renamed directory groups to existing non-default permission groups with an exact, case-sensitive name match. Sim does not create permission groups. A rename updates automatic mappings and preserves manually added ones. +For groups already synced before enabling name matching, select **Reconcile now** or wait for scheduled reconciliation. - -Provisioning tab with an active SCIM connection, tokens, provisioning rules, group mappings, and recent activity - ## How access is withdrawn -Sim records every grant it makes on your behalf. When someone leaves a group, what the directory granted is taken back. +Sim tracks grants made through directory mappings. Removing a member from a group or removing its mapping withdraws the tracked access. -**Lock managed membership**, on by default for a new connection, makes the directory the source of truth for provisioned members: Sim refuses invitations, workspace grants, workspace role changes, and organization role changes for them, because the next sync would revert them anyway. Access a member already held by hand when a mapping started covering it counts as directory access from then on, so it is withdrawn with the mapping. Removals stay possible so an administrator can always act in an emergency. +**Lock managed membership** is enabled by default on a new connection. It makes the directory authoritative for provisioned members: Sim refuses manual invitations, workspace grants, workspace role changes, and organization role changes for them. Manual access already held when a mapping begins covering it becomes directory-managed and is withdrawn with that mapping. Administrators can still remove access in an emergency. -With locking off, access held before the directory mapping is preserved. If someone had manual Read access and the directory raises it to Admin, removing the mapping restores Read. A workspace role raised by hand above the directory's level is also left alone. The upgrade limitation below applies to grants recorded by older versions. +With locking off, prior manual workspace access is preserved. If a member had manual Read access and a directory mapping raises it to Admin, removing the mapping restores Read. A role manually raised above the directory's level also remains. [Older grants have a baseline limitation](#deployment-and-upgrades). + +You can manually invite people the directory does not manage. For managed members with locking on, grant access through directory groups. ## Provisioning and SSO together -An active provisioned member can sign in once SSO is configured for their verified domain. Provisioning and SSO resolve to the same account. +An active provisioned member can authenticate through SSO configured for the same verified domain. Both systems resolve to the same account. + +To prevent SSO from adding new organization members, enable **Provisioning rules → Manage rules → Disable just-in-time provisioning**. While the SCIM connection is active and entitled, this overrides **Sign-in → First sign-in → Automatic**. Existing members can still sign in, including members added by invitation; they do not all have to be SCIM-provisioned. -To stop SSO from creating organization memberships, open **Provisioning rules → Manage rules** and enable **Disable just-in-time provisioning**. While the SCIM connection is active and entitled, this overrides **Sign-in → First sign-in → Automatic**. Existing organization members can still sign in, including members added by invitation; the setting does not require every existing member to have been provisioned by SCIM. +## Inspect activity and reconcile access -## Watching a sync +Connection switches, rules, tokens, and mappings save immediately. **Provisioning** has no page-level Save button. -Changes to the enable switch, provisioning rules, tokens, and mappings save immediately. There is no page-level Save button on this tab. +**Provisioning → Activity** shows recent authenticated requests, their status, and failure details. A wrong, expired, or revoked token cannot be associated with a connection, so its authentication error appears only in the provider's logs. -**Single sign-on → Provisioning → Activity** lists recent authenticated requests with their status and, for a failure, what was wrong. Providers report a failed cycle without saying what they sent, so this is usually the fastest way to see the cause. A request that fails to authenticate has no connection to log against, so a wrong or revoked token shows up only as your provider's own authentication error. +**Reconcile now** reapplies group mappings and changed connection rules. For scheduled reconciliation, call `GET /api/cron/scim-reconcile` with the configured `CRON_SECRET`. Helm and production Docker Compose include an hourly schedule when their cron service is configured and running. This endpoint runs directly; it does not require Trigger.dev. See [Background schedules](/platform/enterprise/self-hosted#schedule-the-background-jobs). -The scheduled reconciliation task re-applies group mappings hourly when the background task runner is configured and running. You can run it on demand with **Reconcile now**, which is also how a change to the connection settings reaches members before the next sync. +## Disable provisioning + +Turning the connection off stops synchronization; it does not reverse suspension or prior access changes. Deactivated members stay deactivated. To restore an account without the directory, remove it from the organization and invite it again. ## Deployment and upgrades -Apply the database migrations before deploying the new application code. The SCIM tables and suspension fields are additive, so the older application can continue running against the expanded schema during rollout. - -Keep `SCIM_ENABLED=false` and `NEXT_PUBLIC_SCIM_ENABLED=false` on the new deployment until all older application instances and workers have been drained. Older versions do not enforce SCIM suspensions or explicit permission-group membership. Enable provisioning only after every instance runs the new code. These explicit flags also override the hosted default. - -Once SCIM has suspended users or established managed access, rolling back to code that predates SCIM is not safe: it cannot enforce those restrictions. Disabling the SCIM connection stops synchronization but does not undo suspensions or restore old membership semantics. - -Migration `0325_scim_manual_workspace_baseline` adds tracking of prior manual workspace access. It cannot reconstruct levels overwritten by older SCIM code. Review those existing directory-owned grants before withdrawing mappings with membership locking off, and restore prior manual access explicitly where needed. - -## Reference - -- Base URL: `https:///api/scim/v2` -- Authentication: `Authorization: Bearer ` -- Resources: `/Users`, `/Groups`, plus `/ServiceProviderConfig`, `/ResourceTypes`, and `/Schemas` -- Filters: `eq` only, up to ten terms joined with `and`. Users: `id`, `userName`, `externalId`, `emails.value` (also `emails[type eq "work"].value`), `active`. Groups: `id`, `displayName`, `externalId` -- Limits: sustained 1,500 requests per minute per connection with a burst capacity of 3,000, 1 MB per request, 5,000 members per group -- `userName` is stored and returned lower-cased. Unmodeled top-level attributes and custom schema extensions are retained, and a PUT preserves ones it omits. Passwords are neither stored nor returned; Sim controls `id`, `meta`, and group membership -- Group display names are unique within a connection, ignoring case -- Page size: up to 100 per request - - +Apply database migrations before the new application code. The SCIM tables and suspension fields are additive, allowing older code to run against the expanded schema during rollout. + + + Keep `SCIM_ENABLED=false` and `NEXT_PUBLIC_SCIM_ENABLED=false` until all older application instances and workers are drained. Older code does not enforce SCIM suspension or explicit permission-group membership. These explicit flags also override the hosted default. + + +After SCIM has suspended accounts or established managed access, rolling back to code that predates SCIM is unsafe: it cannot enforce those restrictions. Disabling synchronization does not undo suspension or restore earlier membership semantics. + +Migration `0325_scim_manual_workspace_baseline` tracks prior manual workspace access, but cannot reconstruct levels overwritten by older SCIM code. Review existing directory-owned grants before withdrawing mappings with locking off. Restore prior manual access explicitly where needed. + +## Protocol reference + +| Item | Contract | +| --- | --- | +| Base URL | `https:///api/scim/v2` | +| Authentication | `Authorization: Bearer ` | +| Resources | `/Users`, `/Groups`, `/ServiceProviderConfig`, `/ResourceTypes`, `/Schemas` | +| Filters | `eq` only, up to 10 terms joined by `and` | +| User filter fields | `id`, `userName`, `externalId`, `emails.value`, `emails[type eq "work"].value`, `active` | +| Group filter fields | `id`, `displayName`, `externalId` | +| Request rate | Sustained 1,500 requests per minute per connection; burst capacity 3,000 | +| Request body | Maximum 1,000,000 bytes (1 MB) | +| Group membership | Maximum 5,000 members per group | +| List page | Maximum 100 resources per request | + +Sim stores and returns `userName` in lowercase. Group display names are unique within a connection, ignoring case. Unmodeled top-level attributes and custom schema extensions are retained; a `PUT` preserves those it omits. Passwords are neither stored nor returned. Sim controls `id`, `meta`, and group membership. + +## Related docs + +- [Single sign-on](/platform/enterprise/sso) +- [Verified domains](/platform/enterprise/verified-domains) +- [Okta provisioning](/platform/enterprise/scim/okta) +- [Microsoft Entra provisioning](/platform/enterprise/scim/entra) +- [Permission groups](/platform/enterprise/access-control) diff --git a/apps/docs/content/docs/platform/enterprise/scim/okta.mdx b/apps/docs/content/docs/platform/enterprise/scim/okta.mdx index 7fcd660cbd3..f5cf8d12c66 100644 --- a/apps/docs/content/docs/platform/enterprise/scim/okta.mdx +++ b/apps/docs/content/docs/platform/enterprise/scim/okta.mdx @@ -1,109 +1,141 @@ --- title: Okta provisioning -description: Connect a private Okta SCIM integration to Sim and verify user and group provisioning +description: Connect Okta to Sim and verify member and group provisioning --- import { Callout } from 'fumadocs-ui/components/callout' import { Step, Steps } from 'fumadocs-ui/components/steps' import { Image } from '@/components/ui/image' -Use an Okta SCIM integration to create, update, and deactivate Sim members. This guide covers provisioning; configure [single sign-on](/platform/enterprise/sso) separately for authentication. +Connect an Okta SCIM 2.0 integration to create, update, and deactivate Sim organization members. Configure [single sign-on](/platform/enterprise/sso) separately for authentication. ## Before you start -- An Enterprise organization in Sim, with an owner or administrator who can manage provisioning. -- Each user email domain [verified in Sim](/platform/enterprise/verified-domains). -- An Okta administrator account with access to application provisioning. -- A Sim deployment reachable by Okta over HTTPS. For self-hosted deployments, use its public URL and apply the [SCIM rollout requirements](/platform/enterprise/scim#deployment-and-upgrades). +- Use an Enterprise organization in Sim and an organization owner or admin account. +- [Verify each provisioned email domain](/platform/enterprise/verified-domains). +- Use an Okta administrator with access to application provisioning. +- Make the Sim deployment reachable by Okta over HTTPS. Self-hosted deployments must meet the [SCIM rollout requirements](/platform/enterprise/scim#deployment-and-upgrades). -Start with a test user and a dedicated group before assigning your organization. Provisioned members use a seat; they receive workspace access only through a mapping or an existing grant. +Start with a test account and a dedicated group. Provisioned members use a seat and receive workspace access through mappings or existing grants. -## Connect Okta to Sim +## Choose an integration - +SCIM support depends on how the Okta app was created: + +| Integration | SCIM setup | +| --- | --- | +| OIDC app created with the newer **Okta Integration Wizard** | Can support SCIM; follow the instructions for that creation experience | +| OIDC app created with **Classic experience** | Does not support adding SCIM; use a separate provisioning integration | +| Custom SAML or SWA app created with **Classic experience** | Enable SCIM under **General → App Settings → Provisioning**, then configure its SCIM fields | + +See [Okta's custom-app SCIM instructions](https://help.okta.com/en-us/Content/Topics/apps/apps_app_integration_wizard_scim.htm). If the provisioning option is missing, confirm that the feature is enabled for your Okta organization. + + + The Header Auth Test App walkthrough below is for evaluation. [Okta support limits SCIM Test Apps to development and testing](https://support.okta.com/help/s/article/What-are-SCIM-20-Test-Apps?language=en_US), although its developer guide also describes private template integrations. For production, confirm a supported integration route for your Okta organization using the corresponding official instructions. This guide does not establish a published or certified Sim OIN integration. + + +### Connect a supported custom app + +1. In Sim, open **Settings → Organization → Single sign-on → Provisioning** and enable **Enable directory provisioning**. Copy **Connection → Base URL**, choose a token expiry under **Tokens**, and select **Issue token**. Copy it before closing the dialog; it is shown once. +2. In the supported Okta app, enable SCIM. For a Classic SAML or SWA app, open **General → App Settings → Edit**, set **Provisioning** to **SCIM**, and save. +3. Open **Provisioning → Integration** and configure **SCIM connector base URL** with Sim's Base URL. Set **Unique identifier field for users** to `userName`. +4. Enable the supported push actions needed for your deployment: **Push New Users**, **Push Profile Updates**, and **Push Groups** for group-based access. +5. Configure **HTTP Header** authentication to send `Authorization: Bearer `. Use the chosen integration's documented credential fields; they differ from the Test App's **API Token** field below. +6. Test and save the connection. Under **Provisioning → To App**, enable user creation, attribute updates, and deactivation. Leave password synchronization disabled. + +Use an application username and primary email in a domain verified by Sim. If Okta usernames differ from email addresses, review the attribute mappings before assigning members. Then complete the lifecycle and group checks below. + +## Evaluate with the Header Auth Test App +These steps use Okta's [private SCIM template guide](https://developer.okta.com/docs/guides/scim-provisioning-integration-connect/main/). The screenshots show the Test App configuration. + + ### Enable provisioning in Sim -Open **Settings → Organization → Single sign-on → Provisioning** and turn on **Enable directory provisioning**. Copy the **Base URL** from **Connection**. Under **Tokens**, choose an expiry and select **Issue token**. Copy the token before closing its dialog; Sim shows it once. +Open **Settings → Organization → Single sign-on → Provisioning** and enable **Enable directory provisioning**. Copy **Connection → Base URL**. Under **Tokens**, choose an expiry and select **Issue token**. Copy the token before closing its dialog. -### Add the Okta integration - -In the Okta Admin Console, open **Applications and Resources → Applications → Browse App Catalog**. Search for **SCIM 2.0 Test App (Header Auth)** and select **Add Integration**. Give the app a recognizable name, such as **Sim provisioning**. +### Add the evaluation app -For a provisioning-only app, hide its application icon from users and turn off automatic sign-in from the landing page. On **Sign-On Options**, select **Secure Web Authentication**, use your Sim HTTPS login URL, and set **Application username format** to **Email**. Complete the app setup. These template settings do not configure Sim SSO. +In Okta, open **Applications and Resources → Applications → Browse App Catalog**. Search for **SCIM 2.0 Test App (Header Auth)**, select **Add Integration**, and name it, for example **Sim provisioning evaluation**. - - Okta cannot add SCIM to a custom OIDC app. Keep this provisioning app alongside your OIDC sign-in app. For an existing custom SAML or SWA app, use [Okta's custom-app SCIM instructions](https://help.okta.com/en-us/Content/Topics/apps/apps_app_integration_wizard_scim.htm); those connection fields differ from the catalog template below. - +For a provisioning-only app, hide its icon from members and turn off automatic sign-in from the landing page. Under **Sign-On Options**, choose **Secure Web Authentication**, use your Sim HTTPS login URL, and set **Application username format** to **Email**. Complete setup. These template options do not configure Sim SSO. ### Configure API integration -In the new Okta app, open **Provisioning → Integration → Configure API Integration** and select **Enable API integration**. +Open **Provisioning → Integration → Configure API Integration** and select **Enable API integration**. | Field | Value | | --- | --- | -| Base URL | The URL copied from Sim, ending in `/api/scim/v2` | -| API Token | `Bearer ` — include `Bearer` and a space before the token | +| **Base URL** | Sim's HTTPS URL ending in `/api/scim/v2` | +| **API Token** | `Bearer ` — include the prefix and a space | -Select **Test API Credentials** and save after the test succeeds. A successful connection test checks connectivity and authentication; continue with a test assignment to verify provisioning. +Select **Test API Credentials**, then save. The Header Auth template sends **API Token** as the complete `Authorization` header. Entering the token alone produces **A bearer token is required**. -The Header Auth template sends this field as the complete `Authorization` header. Entering only the token produces **A bearer token is required**. +Header Auth Test App API integration showing a successful credential test, a redacted Base URL, and a masked token -Okta API integration with a successful credential test; the test deployment URL is redacted +A successful credential test confirms connectivity and authentication. Assign a test account to verify provisioning itself. ### Enable provisioning actions -Under **Provisioning → To App**, select **Edit**, enable **Create Users**, **Update User Attributes**, and **Deactivate Users**, then save. Leave **Sync Password** disabled: Sim does not synchronize passwords through SCIM. +Under **Provisioning → To App → Edit**, enable **Create Users**, **Update User Attributes**, and **Deactivate Users**, then save. Leave **Sync Password** disabled; Sim does not synchronize passwords through SCIM. -Use an email address from a verified Sim domain for the application username and primary email. Review the attribute mappings if your Okta usernames differ from users' email addresses. +Use a verified-domain email for both the application username and primary email. Review mappings if Okta usernames differ from email addresses. -Okta provisioning actions with Create Users, Update User Attributes, and Deactivate Users enabled, and Sync Password disabled +Header Auth Test App actions with user creation, attribute updates, and deactivation enabled, and password synchronization disabled - -This uses Okta's [private integration template](https://developer.okta.com/docs/guides/scim-provisioning-integration-connect/main/). It does not make the integration a published or certified Okta Integration Network application. +## Verify the user lifecycle -## Verify a user lifecycle +1. Assign a test account from **Assignments**. Confirm it appears in Sim's organization and **Provisioning → Activity** shows successful requests. +2. Update **Display name** in Okta and confirm the change in Sim. Sim uses mapped `displayName`, falling back to the structured name when omitted. +3. If the account belongs to a pushed group, remove it from that group and confirm the downstream removal before unassigning the app. +4. Unassign the account and confirm Sim marks it deactivated. +5. Reassign it and confirm the existing member becomes active again. -Assign one test user to the app from **Assignments**. In Sim, confirm that the account appears in the organization and that **Provisioning → Activity** shows successful requests. Update the user's **Display name** in Okta and confirm it in Sim. Sim uses the mapped `displayName`, falling back to the structured name when it is omitted. +Okta sends deactivation, not SCIM user `DELETE`. Sim suspends access while retaining organization membership, ownership, and the seat. Removing organization membership is a separate offboarding action. See [Sim deactivation behavior](/platform/enterprise/scim#what-it-does) and [Okta's offboarding order](https://help.okta.com/en-us/Content/Topics/users-groups-profiles/app-assignments-group-push.htm). -Unassign the test user and check that Sim marks them as deactivated. Reassign the same user and confirm that the existing member becomes active again. If the user belongs to a pushed group, remove them from that group and confirm the downstream removal **before** unassigning the app; see [Okta's offboarding order](https://help.okta.com/en-us/Content/Topics/users-groups-profiles/app-assignments-group-push.htm). +## Push groups and verify access -Okta deactivates users over SCIM; it does not send a SCIM DELETE. Sim suspends access while retaining the user's organization membership, ownership, and seat. See [deactivation behavior](/platform/enterprise/scim#what-it-does) before using unassignment for offboarding. +Use separate groups for app assignment and Group Push; Okta does not support using the same group for both. Assign accounts to the app first. -## Push groups and map access +1. Under **Push Groups → Find groups by name**, select the group. +2. Leave **Push group memberships immediately** enabled. For a new downstream group, save with **Create Group** selected. +3. In Sim, open **Single sign-on → Provisioning → Group mappings** and map the synced group to a workspace, permission group, or organization admin role. Workspace access requires a workspace mapping. Name matching can map existing permission groups automatically. +4. Confirm a test member gains workspace access. Remove it from the pushed group while keeping its app assignment, and confirm the directory grant is withdrawn. Add it back and verify access returns without another account being created. -Use separate groups for app assignment and Group Push. Okta does not support using the same group for both purposes. Assign the users to the app first. Under **Push Groups → Find groups by name**, select the group, leave **Push group memberships immediately** enabled, and save with **Create Group** selected for a new downstream group. +Header Auth Test App Group Push selecting an engineering group and Create Group for the downstream group -Okta Group Push selecting an engineering group and creating its downstream group in Sim +With **Lock managed membership** enabled, Sim blocks manual invitations and grants for provisioned members. Read [How access is withdrawn](/platform/enterprise/scim#how-access-is-withdrawn) before mapping groups that overlap existing manual access. -Once the group appears under **Single sign-on → Provisioning → Group mappings** in Sim, map it to a workspace, permission group, or the organization admin role. Workspace access requires a workspace mapping. If name matching is enabled, Sim can automatically map matching permission groups. +## Rotate a token -Use a workspace mapping for the first test. Confirm that the member gains access, then remove them from the pushed group while keeping their app assignment. Confirm that the directory grant is withdrawn. Add them back and verify access is restored without creating another account. +Issue a replacement token in Sim while the current one remains active. Update the chosen integration's credential field. For the Header Auth template, replace **Provisioning → Integration → API Token** with `Bearer `. -With **Lock managed membership** enabled, manage access for provisioned members through directory groups; manual invitations and grants are blocked. Read [how access is withdrawn](/platform/enterprise/scim#how-access-is-withdrawn) before mapping groups that overlap with existing manual access. - -## Rotate the token - -Issue a replacement token in Sim while the current token remains active. In Okta, edit **Provisioning → Integration** and replace **API Token** with `Bearer `. Test the credentials, save, and confirm a successful provisioning request before revoking the old token in Sim. Sim allows two active tokens so rotation can overlap. +Test credentials, save, and confirm a successful provisioning request before revoking the old token. Sim allows two active tokens for overlapping rotation. ## Troubleshooting | Symptom | Check | | --- | --- | -| Credential test fails | Include `Bearer ` before the token. Use the complete HTTPS base URL and a current Sim token, and confirm provisioning is enabled and reachable. | -| User creation fails | Confirm the email domain is verified, a seat is available, and the account does not belong to another Sim organization. | -| User exists but has no workspace access | Push the directory group and add a Sim workspace mapping. Assignment alone creates organization membership. | -| Name or membership changes do not arrive | Check the app assignment, provisioning actions, attribute mappings, and Group Push status in Okta. | -| A pushed group is missing members | Confirm those users are active in Okta and successfully assigned to the app. After activation, repush the group; see [Okta's Group Push troubleshooting](https://help.okta.com/en-us/Content/Topics/users-groups-profiles/usgp-group-push-troubleshoot.htm). | -| A deactivated member still uses a seat | Deactivation suspends access. Removing organization membership is a separate offboarding action. | - -Use **View Logs** in the Okta app and **Provisioning → Activity** in Sim to inspect failures. Requests with an invalid or revoked token appear only in Okta because Sim cannot associate them with a connection. +| Credential test fails | For Header Auth, include `Bearer `. Check the complete HTTPS URL, token expiry, provisioning switch, and network reachability. | +| User creation fails | Verify the email domain, available seats, and whether the account belongs to another Sim organization. | +| Member has no workspace access | Push the group and add a workspace mapping. App assignment creates organization membership. | +| Name or membership updates do not arrive | Check app assignment, provisioning actions, attribute mappings, and Group Push status. | +| A pushed group is missing members | Confirm those accounts are active and successfully assigned to the app. After activation, repush the group; see [Okta Group Push troubleshooting](https://help.okta.com/en-us/Content/Topics/users-groups-profiles/usgp-group-push-troubleshoot.htm). | +| A deactivated member still uses a seat | Deactivation suspends access; remove organization membership to complete that offboarding step. | + +Use **View Logs** in the Okta app and **Provisioning → Activity** in Sim. Invalid or revoked tokens appear only in Okta because Sim cannot associate them with a connection. + +## Related docs + +- [Directory provisioning](/platform/enterprise/scim) +- [Single sign-on](/platform/enterprise/sso) +- [Verified domains](/platform/enterprise/verified-domains) diff --git a/apps/docs/content/docs/platform/enterprise/security.mdx b/apps/docs/content/docs/platform/enterprise/security.mdx index 0a67efba9cd..4b1ba001f2d 100644 --- a/apps/docs/content/docs/platform/enterprise/security.mdx +++ b/apps/docs/content/docs/platform/enterprise/security.mdx @@ -1,34 +1,33 @@ --- title: Security -description: Manage organization session policies and view configured outbound IP addresses +description: Find session controls and configured outbound IP addresses --- -Organization owners and admins open **Settings → Security** to manage session policies and view outbound IP addresses. +Organization owners and admins open **Settings → Organization → Security** to manage session policies and view outbound IP addresses. On Sim Cloud, this page requires an Enterprise organization. ## Session policies -Set **Max session lifetime** and **Idle timeout** in hours, then select **Save**. Leave either field empty to use its default behavior. **Discard** restores your saved values. +Set session lifetime and idle limits, or use **Sign out all members** to revoke member sessions except your current session. This action does not revoke API keys. -**Sign out all members** opens a confirmation before revoking the organization's browser sessions, except your current session. It does not revoke API keys. - -See [Session policies](/platform/enterprise/session-policies) for limits, defaults, and how changes affect existing sessions. +See [Session policies](/platform/enterprise/session-policies) for setup, defaults, limits, and enforcement. ## Outbound IP addresses -Copy your organization's configured addresses in `/32` format and allowlist **every listed address** on the destination firewall. These addresses apply to supported HTTPS connections from Sim and its background workers. - -Contact Sim support or your deployment administrator to configure dedicated IPs and confirm connection coverage. +Copy your organization's configured addresses in `/32` format and allowlist **every listed address** on the destination firewall. Contact Sim support or your deployment administrator to configure dedicated IPs and confirm coverage for the connections you use. ### Connection coverage -Dedicated routing supports public IPv4 destinations over HTTPS on port 443. It applies to supported Search connector API requests, HTTP request blocks, MCP and A2A connections, and HTTP requests made through Sim's local Function runtime. Background jobs use the same organization assignment. - -Native database connections, AWS SDK integrations, remote sandbox traffic, and browser requests keep their existing network paths. Other provider SDKs and OAuth authorization or token refresh calls require separate coverage confirmation. Dedicated IPs do not change access permissions in connected services. +Dedicated routing supports public IPv4 destinations over HTTPS on port 443. Its coverage depends on the connection: -Google Drive, Fireflies, Google Workspace user and group discovery, and Atlassian OAuth site discovery currently use their existing network paths. +| Connection | Routing behavior | +| --- | --- | +| Supported Search connector API requests, HTTP request blocks, MCP and A2A connections, and HTTP requests through Sim's local Function runtime | Use the organization's dedicated routing assignment; background jobs use the same assignment | +| Native database connections, AWS SDK integrations, remote sandbox traffic, and browser requests | Keep their existing network paths | +| Google Drive, Fireflies, Google Workspace user and group discovery, and Atlassian OAuth site discovery | Currently keep their existing network paths | +| Other provider SDKs and OAuth authorization or token refresh calls | Require separate coverage confirmation | -If dedicated routing is unavailable, affected requests fail instead of using shared IPs. Organizations without dedicated routing keep their existing behavior. +Dedicated IPs do not change permissions in connected services. If dedicated routing is unavailable, affected requests fail instead of using shared IPs. Organizations without dedicated routing keep their existing behavior. -## Availability +## Self-hosted availability -On Sim Cloud, Security settings require an Enterprise organization and an owner or admin role. On self-hosted deployments, the outbound IP section is available to organization administrators; session controls appear only when session policies are enabled. See [self-hosted enterprise configuration](/platform/enterprise/self-hosted). +The outbound IP section is available to organization administrators on self-hosted deployments. Session controls appear when session policies are enabled. See [Self-hosted enterprise](/platform/enterprise/self-hosted). diff --git a/apps/docs/content/docs/platform/enterprise/self-hosted.mdx b/apps/docs/content/docs/platform/enterprise/self-hosted.mdx index bc8c776d41b..d3d2555c045 100644 --- a/apps/docs/content/docs/platform/enterprise/self-hosted.mdx +++ b/apps/docs/content/docs/platform/enterprise/self-hosted.mdx @@ -1,35 +1,28 @@ --- -title: Self-hosted Enterprise -description: Run the full enterprise feature set on a self-hosted deployment without billing +title: Self-hosted enterprise +description: Enable enterprise features and configure organizations on a self-hosted deployment --- import { Callout } from 'fumadocs-ui/components/callout' import { Step, Steps } from 'fumadocs-ui/components/steps' -import { Tab, Tabs } from 'fumadocs-ui/components/tabs' +import { Tab, Tabs } from '@/components/ui/tabs' -On Sim Cloud, enterprise features are unlocked by an Enterprise subscription. Self-hosted deployments have no subscription, so they are unlocked by environment configuration instead. +On a self-hosted deployment with billing disabled, enable enterprise features through environment variables. Then create an organization and attach its workspaces: branding, PII redaction, permission groups, custom blocks, data drains, and organization audit scope depend on the organization that owns a workspace. -There are two parts to getting this right, and skipping the second is the most common reason features appear to do nothing: - -1. **Enable the features** with `ENTERPRISE_ENABLED`. -2. **Give them an organization to apply to.** White-labeling, PII redaction, permission groups, custom blocks, data drains, and audit scoping all read their settings from the organization that owns a workspace. A deployment where everyone works in personal workspaces has no organization for those settings to come from. +This guide covers the standard billing-disabled configuration. If billing is enabled, subscription gates apply and instance-organization variables are ignored. ## Enable the feature set -Set the master switch and its client twin. Both are required. The server value decides access and most of what a workspace shows: settings sections and nearly all block fields read the deployment's server-resolved configuration, so the sidebar and the API answer the same question. The `NEXT_PUBLIC_` value covers what still reads the browser's own configuration: the SSO entry point on the login page, which renders before any workspace loads, and the Function block's Sandbox selector. On a Compose install or source checkout, `npx sim-setup doctor` reports a twin that disagrees with its server flag; see [Verify your install](/platform/self-hosting/verify). +Set both the server flag and its browser twin, then restart the application: ```bash ENTERPRISE_ENABLED=true NEXT_PUBLIC_ENTERPRISE_ENABLED=true ``` -That turns on organizations, permission groups, SSO, white-labeling, audit logs, -usage tracking, custom blocks, session policies, data retention, data drains, workspace -forks, the Sandbox entitlement, and the inbox. - -### Turning one feature off +The server flag controls access and the server-resolved workspace settings. The browser twin also enables controls that read browser configuration directly, including SSO on the login page and the Function block's **Sandbox** selector. On a Compose install or source checkout, `bunx sim-setup doctor` reports mismatched twins. See [Verify your install](/platform/self-hosting/verify). -Every feature keeps its own flag, and an explicitly set flag always wins over the master switch. To run the suite without data drains: +Individual flags override the master switch. For example, to enable the suite with data drains disabled: ```bash ENTERPRISE_ENABLED=true @@ -38,125 +31,70 @@ DATA_DRAINS_ENABLED=false NEXT_PUBLIC_DATA_DRAINS_ENABLED=false ``` -The individual flags also work on their own if you would rather opt in one at a time and leave the master switch unset. - -Three features do not need a flag at all: **custom branding**, **session policies**, and the **Sim Mailer inbox** are already on wherever billing is disabled, which is every self-hosted deployment. They preserve behavior that predates these flags. Set the corresponding variable to `false` to turn one off. - -| Feature | Server variable | Client variable | -|---------|-----------------|-----------------| -| Everything below | `ENTERPRISE_ENABLED` | `NEXT_PUBLIC_ENTERPRISE_ENABLED` | -| Organizations | `ORGANIZATIONS_ENABLED` | `NEXT_PUBLIC_ORGANIZATIONS_ENABLED` | -| Permission groups | `ACCESS_CONTROL_ENABLED` | `NEXT_PUBLIC_ACCESS_CONTROL_ENABLED` | -| SAML and OIDC sign-in | `SSO_ENABLED` | `NEXT_PUBLIC_SSO_ENABLED` | -| Directory provisioning (SCIM) | `SCIM_ENABLED` | `NEXT_PUBLIC_SCIM_ENABLED` | -| Custom branding — on by default | `WHITELABELING_ENABLED` | `NEXT_PUBLIC_WHITELABELING_ENABLED` | -| Audit logs | `AUDIT_LOGS_ENABLED` | `NEXT_PUBLIC_AUDIT_LOGS_ENABLED` | -| Insights | `USAGE_MONITORING_ENABLED` | `NEXT_PUBLIC_USAGE_MONITORING_ENABLED` | -| Custom blocks | `CUSTOM_BLOCKS_ENABLED` | `NEXT_PUBLIC_CUSTOM_BLOCKS_ENABLED` | -| Session policies — on by default | `SESSION_POLICIES_ENABLED` | `NEXT_PUBLIC_SESSION_POLICIES_ENABLED` | -| Data retention deletion | `DATA_RETENTION_ENABLED` | `NEXT_PUBLIC_DATA_RETENTION_ENABLED` | -| Data drains | `DATA_DRAINS_ENABLED` | `NEXT_PUBLIC_DATA_DRAINS_ENABLED` | -| Credential Groups | `CREDENTIAL_GROUPS` | — | -| Workspace forks | `FORKING_ENABLED` | `NEXT_PUBLIC_FORKING_ENABLED` | -| Sim Mailer inbox — on by default | `INBOX_ENABLED` | `NEXT_PUBLIC_INBOX_ENABLED` | -| Sandboxes | `SANDBOXES_ENABLED` | `NEXT_PUBLIC_SANDBOXES_ENABLED` | - -Sandboxes also need a remote execution provider and a dedicated Function base image before they can run anything. `SANDBOXES_ENABLED` grants the server-side entitlement, and the server also verifies the provider credentials and an immutable Function base before it reports Sandboxes as available. Until then a workspace offers no Shell language, and **Settings → Sandboxes** stays in the sidebar but shows an upgrade notice instead of the sandbox list. `NEXT_PUBLIC_SANDBOXES_ENABLED` asserts that readiness to the browser rather than checking it: it reveals the Function block's Sandbox selector, and `npx sim-setup doctor` compares it with the selected provider's readiness. Set it only after the selected provider has credentials and a valid immutable Function base configured. - -JavaScript without `import` or `require` does not use the remote provider and continues to run in the local isolated VM when all Sandbox flags are off. Python, Shell, JavaScript with external imports, and selected custom Sandboxes fail with an explicit configuration error until the remote Function base is ready. - -See [Sandboxes](/platform/self-hosting/sandboxes) for the provider credentials, the Function base-image build, and the promotion procedure. - - - Data retention is the one feature that deletes data. Its flag controls the cleanup pass, not the settings screen — retention windows are always configurable. Nothing is ever deleted until you enable it, and even then only against windows you configured explicitly. Sim never applies the hosted plan defaults to a self-hosted deployment. - - -## Schedule the background jobs - -Data drains and retention are started by cron-driven HTTP endpoints rather than by the app on their own schedules. What happens next differs: retention's cleanup runs inline in the app process, while each due data drain is handed to a background job. Every endpoint authenticates with a bearer token equal to `CRON_SECRET` and returns `401` when it is unset: - -```bash -openssl rand -hex 32 -``` - -Persist that value as `CRON_SECRET` on the app **and** on whatever calls these endpoints. Generating it in a shell configures neither, and a mismatch returns `401`, so the work silently never runs. - -| Feature | Endpoint | Suggested schedule | Scheduled for you | -|---------|----------|--------------------|-------------------| -| Data drains | `GET /api/cron/run-data-drains` | Hourly | Yes — Helm and Docker Compose both call it | -| Retention — logs | `GET /api/logs/cleanup` | Daily | **No** — schedule it yourself | -| Retention — soft deletes | `GET /api/cron/cleanup-soft-deletes` | Daily | **No** — schedule it yourself | -| Retention — Chat tasks | `GET /api/cron/cleanup-tasks` | Daily | **No** — schedule it yourself | -| Retention — file versions | `GET /api/cron/cleanup-file-versions` | Daily | **No** — schedule it yourself | -| OAuth token cleanup | `GET /api/cron/cleanup-oauth-tokens` | Hourly | Yes — Helm and Docker Compose both call it | - - - Both shipped deployments schedule the data-drain dispatcher and OAuth token cleanup, but **not** the four configurable data-retention endpoints. Setting `DATA_RETENTION_ENABLED=true` alone deletes no retained product data — those windows are evaluated only when one of the four endpoints is called. Add them to `cronjobs.jobs` yourself, or drive them from an external scheduler. - - OAuth token cleanup runs independently of sign-in activity, removing expired and revoked credentials. See [Sign in with Sim](/platform/self-hosting/authentication#sign-in-with-sim) for provider configuration. - - -```bash -curl -H "Authorization: Bearer $CRON_SECRET" \ - https://sim.example.com/api/logs/cleanup -``` - -The two features differ in what they need to run the work. Retention's cleanup dispatcher executes inline when Trigger.dev is not configured, so it completes on a default self-host. Data drains have no inline path: without `TRIGGER_DEV_ENABLED` and a configured Trigger.dev project, each due drain is claimed and enqueued to the database, and nothing drains that queue for this job type. See [background jobs](/platform/self-hosting/background-jobs). +You can also leave the master switch unset and enable individual features. The [feature flag reference](#feature-flag-reference) lists them all. ## Choose an organization model -### Pattern 1: one organization for the whole instance +### One organization for the instance -Best when everyone on the deployment belongs to the same company. Set a name and every user joins that organization automatically at signup, with their workspaces created org-owned. +Use this when everyone on the deployment belongs to the same company. Set the instance organization's name: ```bash INSTANCE_ORG_NAME="Acme Inc" ``` -Optionally pin the slug and the owner: +New accounts join it at signup, and their workspaces are created as organization-owned. Optionally set its slug and an existing account to own it: ```bash INSTANCE_ORG_SLUG=acme-inc INSTANCE_ORG_OWNER_EMAIL=admin@acme.com ``` -The organization is created the first time a user signs up. If `INSTANCE_ORG_OWNER_EMAIL` is not set, or names a user who does not exist yet, the first user to sign up becomes the owner; move ownership later with the Admin API. Provisioning is idempotent and safe across multiple replicas. - - - Instance-organization mode only applies when billing is disabled. With billing enabled, organizations are created through the normal subscription flow and these variables are ignored. - +The organization is created on the first signup after enabling this mode. If the owner email is unset or does not match an existing account, the account that triggers creation becomes the owner. Transfer ownership later through the Admin API if needed. Creation is idempotent across replicas. -#### Existing deployments +#### Backfill existing accounts and workspaces -Users and workspaces created before you set `INSTANCE_ORG_NAME` stay where they are. Move them across once with the backfill script, which adds every user to the organization and attaches their workspaces: +Setting `INSTANCE_ORG_NAME` does not move existing accounts or workspaces. Run the consolidation script from the repository root. If the organization does not exist yet, provide an owner email that matches an **existing Sim account**: ```bash -# Preview -DATABASE_URL=... INSTANCE_ORG_NAME="Acme Inc" \ +# Preview the changes +DATABASE_URL=... \ +INSTANCE_ORG_NAME="Acme Inc" \ +INSTANCE_ORG_OWNER_EMAIL=admin@acme.com \ bun run apps/sim/scripts/consolidate-users-into-organization.ts -# Apply -DATABASE_URL=... INSTANCE_ORG_NAME="Acme Inc" \ +# Apply the same changes +DATABASE_URL=... \ +INSTANCE_ORG_NAME="Acme Inc" \ +INSTANCE_ORG_OWNER_EMAIL=admin@acme.com \ bun run apps/sim/scripts/consolidate-users-into-organization.ts --apply ``` -It is a dry run unless you pass `--apply`, and it is safe to re-run. Users who already belong to a different organization are reported and skipped, since a user can only belong to one. +The script adds accounts to the organization and attaches their workspaces. It is a dry run unless you pass `--apply`, and is safe to rerun. Accounts already in another organization are reported and skipped because an account can belong to only one organization. When the instance organization already exists, the script uses its current owner. -### Pattern 2: many organizations you manage yourself +### Separate organizations managed through the Admin API -Best when one deployment serves several teams that should not see each other's data. Leave `INSTANCE_ORG_NAME` unset and provision organizations through the Admin API. +Leave `INSTANCE_ORG_NAME` unset when one deployment serves multiple teams. Create organizations, add members, and attach workspaces through the Admin API. + +Generate an admin key once: + +```bash +openssl rand -hex 32 +``` -Set an admin key first: +Persist that value as `ADMIN_API_KEY` in the **application's environment**, then restart the application. Use the same value in the shell or client issuing the following requests: ```bash -ADMIN_API_KEY=$(openssl rand -hex 32) +ADMIN_API_KEY='' ``` +Generating or assigning a value in the caller's shell does not configure the running application. Requests use the exact `x-admin-key` header. + ### Create an organization -The owner must not already belong to another organization. +The owner account must exist and must not belong to another organization. ```bash curl -X POST https://sim.example.com/api/v1/admin/organizations \ @@ -164,6 +102,8 @@ curl -X POST https://sim.example.com/api/v1/admin/organizations \ -H "Content-Type: application/json" \ -d '{"name": "Acme Inc", "ownerId": "user_123", "slug": "acme-inc"}' ``` + +Use the returned organization ID as `ORG_ID` in subsequent commands. Creating the organization does not attach a workspace. @@ -178,25 +118,34 @@ curl -X POST https://sim.example.com/api/v1/admin/organizations/$ORG_ID/members -### Move a workspace into the organization +### Attach a workspace -Organization-scoped features only apply to workspaces the organization owns. +Enterprise settings apply only to workspaces the organization owns. Generate a fresh UUID for each new move. From the repository root: ```bash +OPERATION_ID=$(bun -e 'import { generateId } from "@sim/utils/id"; process.stdout.write(generateId())') + curl -X POST https://sim.example.com/api/v1/admin/dashboard/workspaces/$WORKSPACE_ID/move \ -H "x-admin-key: $ADMIN_API_KEY" \ -H "Content-Type: application/json" \ - -d "{\"destinationOrganizationId\": \"$ORG_ID\"}" + -d "{\"operationId\": \"$OPERATION_ID\", \"destinationOrganizationId\": \"$ORG_ID\"}" +``` + +Keep the same `OPERATION_ID` when retrying this move; generate a new one only for a new operation. Inspect `data.followUpJobs` in the response for pending or failed follow-up work. Check it again with: + +```bash +curl "https://sim.example.com/api/v1/admin/dashboard/workspaces/$WORKSPACE_ID/move-operations/$OPERATION_ID?destinationOrganizationId=$ORG_ID" \ + -H "x-admin-key: $ADMIN_API_KEY" ``` ### Configure organization settings -Branding, retention, and session policies can be set from the API instead of the UI. +Use the Settings UI or these API requests: - - + + ```bash curl -X PATCH https://sim.example.com/api/v1/admin/organizations/$ORG_ID/whitelabel \ -H "x-admin-key: $ADMIN_API_KEY" \ @@ -224,57 +173,127 @@ curl -X PATCH https://sim.example.com/api/v1/admin/organizations/$ORG_ID/session -### Reading enterprise data with the admin key +When invitations are disabled with `DISABLE_INVITATIONS` and `NEXT_PUBLIC_DISABLE_INVITATIONS`, use the Admin API to manage organization membership and workspace access. Internal members join the organization. External workspace members receive access to a specific workspace without joining the organization. + +### Read audit logs and permission groups -Two enterprise reads have admin-key equivalents that need no organization and no Enterprise plan, which is what makes them usable on a billing-free deployment: +Admin-key reads do not require an organization or Enterprise subscription: ```bash -# Audit log entries across the whole deployment, with the same filters as the UI +# Deployment audit entries, with filters also available in the UI curl "https://sim.example.com/api/v1/admin/audit-logs?limit=50&workspaceId=$WORKSPACE_ID" \ -H "x-admin-key: $ADMIN_API_KEY" -# A single entry +# One audit entry curl "https://sim.example.com/api/v1/admin/audit-logs/$AUDIT_LOG_ID" \ -H "x-admin-key: $ADMIN_API_KEY" -# Permission groups, optionally scoped to one organization +# Permission groups, optionally scoped to an organization curl "https://sim.example.com/api/v1/admin/access-control?organizationId=$ORG_ID" \ -H "x-admin-key: $ADMIN_API_KEY" ``` -The organization-scoped `/api/v1/audit-logs` endpoint documented in the [audit logs guide](/platform/enterprise/audit-logs) needs an API key whose owner is an admin or owner of an organization, so reach for the admin endpoints when no organization exists yet. +The organization-scoped `/api/v1/audit-logs` endpoint uses an API key whose owner is an organization admin or owner. Use the admin endpoint when no organization exists yet. See [Audit logs](/platform/enterprise/audit-logs). -Deleting an organization requires echoing its slug, because the delete cascades to members, invitations, and permission groups, and detaches its workspaces: +### Delete an organization + +Deleting an organization removes its memberships, invitations, permission groups, and organization settings. Its workspaces are detached and survive. A non-terminal subscription prevents deletion; cancel it first. + +Confirm the target by passing its exact slug: ```bash curl -X DELETE "https://sim.example.com/api/v1/admin/organizations/$ORG_ID?confirmSlug=acme-inc" \ -H "x-admin-key: $ADMIN_API_KEY" ``` -## Verifying it worked +## Schedule the background jobs -If a feature is enabled but nothing appears, check these in order. +Configure a scheduler to call the maintenance endpoints. Generate a cron secret: -**The settings section is missing.** The server-side variable is not set, or the app was not restarted after adding it. Variables are read at boot from the container environment, so a restart is enough — no rebuild. +```bash +openssl rand -hex 32 +``` -**Settings → Sandboxes shows an upgrade notice instead of the sandbox list.** The Sandbox entitlement resolves off — `SANDBOXES_ENABLED=false`, or `SANDBOXES_ENABLED` unset without the `ENTERPRISE_ENABLED` master switch — or the selected provider failed the server's readiness check: missing credentials, or a Function base that is not an immutable reference. The page stays in the sidebar either way. See [Sandboxes](/platform/self-hosting/sandboxes). +Persist the same value as `CRON_SECRET` on the application and its scheduler. Each endpoint requires `Authorization: Bearer ` and returns `401` if the secret is unset or does not match. -**The section appears but the login page has no SSO option, or the Function block has no Sandbox selector.** The `NEXT_PUBLIC_` twin is unset or `false` while the server-side feature resolves on. A workspace follows the server, but the login page renders before any workspace loads and reads the twin, and the Sandbox selector does too. Set both. On a Compose install or source checkout, `npx sim-setup doctor` reports a twin that disagrees with its server flag; for Sandboxes it compares `NEXT_PUBLIC_SANDBOXES_ENABLED` with the selected provider's readiness instead. +| Feature | Endpoint | Suggested schedule | Included in Helm and production Compose schedules | +| --- | --- | --- | --- | +| Data drains | `GET /api/cron/run-data-drains` | Hourly | Yes | +| SCIM reconciliation | `GET /api/cron/scim-reconcile` | Hourly | Yes | +| Retention: logs | `GET /api/logs/cleanup` | Daily | No | +| Retention: soft deletes | `GET /api/cron/cleanup-soft-deletes` | Daily | No | +| Retention: Chat tasks | `GET /api/cron/cleanup-tasks` | Daily | No | +| Retention: file versions | `GET /api/cron/cleanup-file-versions` | Daily | No | +| OAuth token cleanup | `GET /api/cron/cleanup-oauth-tokens` | Hourly | Yes | -**The feature is on but has no effect inside a workspace.** The workspace is not owned by an organization. Check `workspace_mode` and `organization_id`: +Included schedules still require the cron service to be configured and running. For an external scheduler, a request looks like: + +```bash +curl -H "Authorization: Bearer $CRON_SECRET" \ + https://sim.example.com/api/logs/cleanup +``` + + + Configuring retention windows and enabling deletion are separate actions. Set `DATA_RETENTION_ENABLED=true` to allow retention cleanup, and schedule the four retention endpoints yourself, for example through Helm's `cronjobs.jobs`. Neither the flag alone nor the shipped cron schedules expire retained product data. Billing-disabled deployments use only explicitly configured windows, without hosted-plan defaults. + + +Retention and data-drain work use the configured job backend. Without Trigger.dev, they have in-process execution paths; with Trigger.dev configured, external workers run the jobs. SCIM reconciliation runs directly through its authenticated cron endpoint and does not require Trigger.dev. See [Background jobs](/platform/self-hosting/background-jobs) for operational setup and [Data retention](/platform/enterprise/data-retention) for effective policy. + +OAuth token cleanup removes expired and revoked credentials independently of sign-in activity. See [Sign in with Sim](/platform/self-hosting/authentication#sign-in-with-sim) for provider configuration. + +## Feature flag reference + +Explicit individual flags override the master switch, including when set to `false`. With billing disabled and no enterprise flags set, custom branding, session policies, and the Sim Mailer inbox remain enabled by default. Other features require opt-in. + +| Feature | Server variable | Browser variable | +| --- | --- | --- | +| Enterprise suite | `ENTERPRISE_ENABLED` | `NEXT_PUBLIC_ENTERPRISE_ENABLED` | +| Organizations | `ORGANIZATIONS_ENABLED` | `NEXT_PUBLIC_ORGANIZATIONS_ENABLED` | +| Permission groups | `ACCESS_CONTROL_ENABLED` | `NEXT_PUBLIC_ACCESS_CONTROL_ENABLED` | +| SAML and OIDC sign-in | `SSO_ENABLED` | `NEXT_PUBLIC_SSO_ENABLED` | +| Directory provisioning | `SCIM_ENABLED` | `NEXT_PUBLIC_SCIM_ENABLED` | +| Custom branding — enabled by default | `WHITELABELING_ENABLED` | `NEXT_PUBLIC_WHITELABELING_ENABLED` | +| Audit logs | `AUDIT_LOGS_ENABLED` | `NEXT_PUBLIC_AUDIT_LOGS_ENABLED` | +| Insights | `USAGE_MONITORING_ENABLED` | `NEXT_PUBLIC_USAGE_MONITORING_ENABLED` | +| Custom blocks | `CUSTOM_BLOCKS_ENABLED` | `NEXT_PUBLIC_CUSTOM_BLOCKS_ENABLED` | +| Session policies — enabled by default | `SESSION_POLICIES_ENABLED` | `NEXT_PUBLIC_SESSION_POLICIES_ENABLED` | +| Retention deletion | `DATA_RETENTION_ENABLED` | `NEXT_PUBLIC_DATA_RETENTION_ENABLED` | +| Data drains | `DATA_DRAINS_ENABLED` | `NEXT_PUBLIC_DATA_DRAINS_ENABLED` | +| Credential groups | `CREDENTIAL_GROUPS` | — | +| Workspace forks | `FORKING_ENABLED` | `NEXT_PUBLIC_FORKING_ENABLED` | +| Sim Mailer inbox — enabled by default | `INBOX_ENABLED` | `NEXT_PUBLIC_INBOX_ENABLED` | +| Sandboxes | `SANDBOXES_ENABLED` | `NEXT_PUBLIC_SANDBOXES_ENABLED` | + +### Sandbox readiness + +A Sandbox entitlement also requires a remote execution provider with credentials and an immutable Function base image. Until the server verifies readiness, the Function block offers no **Shell** language, and **Settings → Sandboxes** shows an upgrade notice instead of a sandbox list. + +`NEXT_PUBLIC_SANDBOXES_ENABLED` exposes the Function block's **Sandbox** selector; it asserts readiness rather than checking it. Set it only after configuring the selected provider and Function base. `bunx sim-setup doctor` compares it with provider readiness. + +JavaScript without `import`, `require`, a selected sandbox, or a sandbox file-path reference runs in local Node child workers in the app container when Sandbox flags are off. Python, Shell, JavaScript with external imports, and selected custom Sandboxes require the remote Function base and fail with a configuration error until it is ready. See [Sandboxes](/platform/self-hosting/sandboxes). + +## Verify the setup + +| Symptom | Check | +| --- | --- | +| A settings section is missing | Check its server flag and restart the app after changing environment variables. These values load at boot; a rebuild is not needed. | +| The login page has no SSO option, or Function has no Sandbox selector | Set the matching `NEXT_PUBLIC_` flag. Run `bunx sim-setup doctor` to check twins and Sandbox readiness. | +| **Settings → Sandboxes** shows an upgrade notice | Check Sandbox entitlement, provider credentials, and the immutable Function base. | +| An enabled feature has no effect in a workspace | Confirm that the workspace belongs to an organization. Use the backfill or workspace move procedure if needed. | +| Retention deletes nothing | Check `DATA_RETENTION_ENABLED`, explicit windows, scheduler requests, and `CRON_SECRET`. | + +To inspect workspace ownership: ```sql SELECT id, name, workspace_mode, organization_id FROM workspace; ``` -A workspace showing `personal` or a null `organization_id` will not pick up branding, PII redaction, permission groups, or drains. Use the backfill script or the workspace move endpoint. - -**Retention is configured but nothing is deleted.** Either `DATA_RETENTION_ENABLED` is unset — configuring windows and running the cleanup pass are separate switches by design — or nothing is calling the cleanup endpoints. The Helm chart does not schedule them; see [Schedule the background jobs](#schedule-the-background-jobs). +A workspace with `personal` mode or a null `organization_id` does not inherit organization branding, PII redaction, permission groups, or drains. -## Related +## Related docs - [Environment variables](/platform/self-hosting/environment-variables) -- [Single Sign-On](/platform/enterprise/sso) -- [Access control](/platform/enterprise/access-control) +- [Single sign-on](/platform/enterprise/sso) +- [Permission groups](/platform/enterprise/access-control) - [Roles and permissions](/platform/permissions) - [Workspaces](/platform/workspaces) diff --git a/apps/docs/content/docs/platform/enterprise/session-policies.mdx b/apps/docs/content/docs/platform/enterprise/session-policies.mdx index b4b0d4267dd..c38b5cc2d2f 100644 --- a/apps/docs/content/docs/platform/enterprise/session-policies.mdx +++ b/apps/docs/content/docs/platform/enterprise/session-policies.mdx @@ -1,76 +1,41 @@ --- -title: Session Policies -description: Set session lifetime limits and sign out every member of your organization at once +title: Session policies +description: Limit member session lifetimes and revoke organization sessions --- -import { FAQ } from '@/components/ui/faq' +Session policies control how long organization members stay signed in. Organization owners and admins can configure them on Enterprise plans, or on self-hosted deployments where session policies are enabled. -Session Policies let organization owners and admins on Enterprise plans control how long member sign-in sessions last, and sign out every member org-wide in one action. Policies apply to every member of the organization on every device. +The limits apply to member sign-in sessions across devices, including SSO sessions. Your identity provider can enforce additional session rules. ---- - -## Setup - -Go to **Settings → Security → Session policies** in your organization settings. - -Both limits are optional. Leave a field empty to keep the default behavior: sessions last 30 days and extend automatically while a member stays active. - ---- - -## Settings +## Set session limits -### Max session lifetime +Open **Settings → Organization → Security → Session policies**. Enter whole numbers in hours, then select **Save**. **Discard** restores the saved values. -Caps how long a session can exist from the moment a member signs in, regardless of activity. When the limit is reached, the member must sign in again. +| Setting | Behavior | Accepted values | +| --- | --- | --- | +| **Max session lifetime (hours)** | Caps a session's age from sign-in, regardless of activity. A value of `168` requires sign-in again at least weekly. | 1–8760 hours | +| **Idle timeout (hours)** | Expires a session after inactivity. Activity refreshes the session within any maximum lifetime. | 48–8760 hours | -Use this to enforce periodic re-authentication — for example, a value of `168` requires everyone to sign in again at least weekly. Accepts 1 to 8760 hours (1 year). +Both fields are optional. Leaving a field empty removes that organization limit. With neither limit set, sessions use the default 30-day sliding expiry and extend automatically while a member stays active. -### Idle timeout +The idle minimum is 48 hours because session activity refreshes are recorded at most once every 24 hours. A shorter limit could expire a session while its member is actively using Sim. -Signs a member out after this many hours without activity. Activity extends the session, so members who use Sim regularly stay signed in; dormant sessions expire. - -Accepts 48 to 8760 hours. The 48-hour minimum exists because session activity is recorded at most once per day — a shorter window could sign out members who are actively working. +## How enforcement works -### Sign out all members +- New sign-ins receive an expiry constrained by the current policy. +- Saving a tighter policy shortens existing member sessions. Changes reach other application instances within about a minute. +- Saving a looser policy does not immediately extend stored session expiries. Later session refreshes and new sign-ins use the current limits. -The **Sign out all members** action immediately revokes every member session in the organization except your own. Members are signed out on their next request — typically within a minute — and must sign in again. +When a session expires, the member must sign in again on their next request. Workflow changes that have already synced remain saved; don't rely on session recovery to preserve an edit that has not synced. -Use this after a security incident, an offboarding wave, or before tightening a policy you want to take effect everywhere at once. +## Sign out all members ---- +Use **Sign out all members** after a security incident or when you need members to authenticate again. Confirm the action to revoke the organization's member sessions, except **your current session**. Your sessions on other devices are also revoked. -## How enforcement works - -- **New sign-ins** get an expiry that respects the policy from the moment the session is created. -- **Existing sessions** are shortened immediately when you save a tighter policy — no member keeps a longer session than the new policy allows. -- **Loosening a policy never extends existing sessions.** Members pick up the longer limit the next time they sign in. -- Changes propagate to active members within about a minute; there is no need to redeploy or wait for sessions to naturally expire. - ---- +Members must sign in again on their next request, typically within a minute. Revocation affects sign-in sessions only: API keys, deployed workflows, webhooks, and schedules keep working. Manage those credentials and resources separately when offboarding a member or responding to an incident. -## FAQ +## Related docs - +- [Single sign-on](/platform/enterprise/sso) +- [Directory provisioning](/platform/enterprise/scim) +- [Self-hosted enterprise](/platform/enterprise/self-hosted) diff --git a/apps/docs/content/docs/platform/enterprise/sso.mdx b/apps/docs/content/docs/platform/enterprise/sso.mdx index 501115becd7..289016189dd 100644 --- a/apps/docs/content/docs/platform/enterprise/sso.mdx +++ b/apps/docs/content/docs/platform/enterprise/sso.mdx @@ -1,466 +1,363 @@ --- -title: Single Sign-On (SSO) -description: Configure SAML 2.0 or OIDC-based single sign-on for your organization +title: Single sign-on (SSO) +description: Configure SAML or OpenID Connect sign-in for your organization --- import { Callout } from 'fumadocs-ui/components/callout' -import { Tab, Tabs } from 'fumadocs-ui/components/tabs' -import { FAQ } from '@/components/ui/faq' -import { Image } from '@/components/ui/image' +import { TabsList, TabsTrigger } from 'fumadocs-ui/components/tabs' +import { Tab, Tabs } from '@/components/ui/tabs' -Single Sign-On lets your team sign in to Sim through your company's identity provider instead of managing separate passwords. Sim supports both OIDC and SAML 2.0, and an organization can use more than one identity provider at a time. +Single sign-on (SSO) lets members authenticate through your organization's identity provider. Sim supports OpenID Connect (OIDC) and SAML 2.0, with multiple providers per organization. ---- +SSO authenticates accounts. First-sign-in provisioning can add organization membership, but workspace access is granted separately. Use [directory provisioning](/platform/enterprise/scim) to manage members and group-based access from your directory. ## Before you start - - [Verify your email domain](/platform/enterprise/verified-domains) first. SSO cannot be saved until the domain shows as **Verified**, and DNS changes take time to propagate. +- On Sim Cloud, use an Enterprise organization and an organization owner or admin account. +- On self-hosted deployments, enable the [SSO flags](#self-hosted-setup) and create an organization. +- [Verify the email domain](/platform/enterprise/verified-domains) before saving its provider. +- Choose a **Provider ID** before configuring the identity provider. It is globally unique across Sim organizations, appears in callback URLs, and cannot be changed after saving. Use an organization-specific ID such as `acme-okta`. - The verified domain is what authorizes your identity provider. Removing it later immediately disables SSO sign-in for everyone on that domain until it is verified again. + + Domain verification authorizes your identity provider to sign in accounts on that domain. Removing the verified domain in Sim stops new SSO sign-ins through its providers until verification is restored. It does not end existing sessions. -Decide your **Provider ID** before configuring your identity provider. It becomes part of the callback URL you register there, and it is **fixed once saved** — changing it later means deleting the provider and setting it up again. - ---- - -## Setup - -### 1. Open SSO settings +## Configure a provider -Go to **Settings → Organization → Single sign-on**. The page has three tabs: +Open **Settings → Organization → Single sign-on**. The page has these tabs: -| Tab | Manage | +| Tab | Configure | | --- | --- | -| **Sign-in** | OIDC or SAML configuration, callback URLs, and first-sign-in membership | -| **Domains** | DNS verification shared by SSO and SCIM | +| **Sign-in** | Identity providers, callback URLs, first-sign-in membership, and allowed sign-in methods | +| **Domains** | Domain ownership shared by SSO and SCIM | | **Provisioning** | SCIM connection, tokens, rules, group mappings, and activity | -Use **Domains** to verify ownership, then return to **Sign-in** to configure your provider. Switching tabs preserves an unsaved sign-in draft while you stay on this page; use **Save** or **Update** to commit it. The selected tab and provider are included in the URL, so they can be bookmarked or shared. On self-hosted deployments, Provisioning appears when SCIM is enabled. +On self-hosted deployments, **Provisioning** appears when SCIM is enabled. Switching tabs preserves an unsaved sign-in draft while you remain on this page. Select **Save** or **Update** to commit changes. The selected tab and provider are in the URL, so you can bookmark or share them. -An organization can run several identity providers at once: Okta for `eng.acme.com` and Microsoft Entra ID for `acme.com`, for example. **Sign-in** lists them; select **Add identity provider** for another, or a row to view, edit, or delete one. Sim routes each sign-in by the email domain. When a domain has more than one provider, the one marked **Primary** is used, which is how you [switch identity providers](#switching-identity-providers) without downtime. +Under **Sign-in**, select **Add identity provider**, or select an existing provider to view it. Use **Domains** to verify ownership first. -### 2. Choose a protocol +### Choose a protocol -| Protocol | Use when | -|----------|----------| -| **OIDC** | Your IdP supports OpenID Connect — Okta, Microsoft Entra ID, Auth0, Google Workspace | -| **SAML 2.0** | Your IdP is SAML-only — ADFS, Shibboleth, or older enterprise IdPs | +Use OIDC when your provider supports OpenID Connect, or SAML 2.0 for a SAML connection. The provider guides below cover Okta, Microsoft Entra ID, Google Workspace, and AD FS. -### 3. Fill in the form +### Enter the required fields -Sign-in tab showing the OIDC configuration form with advanced options collapsed - -**Fields required for both protocols:** - -| Field | What to enter | -|-------|--------------| -| **Provider ID** | A short slug identifying this connection. Letters, numbers, and dashes only. It must be **unique across every Sim organization**, so include something specific to you, such as `azure-ad-acme`. If the ID is taken, Sim asks you to choose another. | -| **Issuer URL** | The identity provider's issuer URL. Must be HTTPS. | -| **Domain** | Your organization's email domain, e.g. `company.com`. Users with this domain will be routed through SSO at sign-in. | -| **First sign-in → On first SSO sign-in** | **Automatic** adds a user authenticated through this verified SSO connection to the organization as a Member and consumes a billed seat. Team seat counts grow with membership; fixed-seat plans require available capacity. **Invite only** authenticates the user without creating organization membership. Neither mode grants workspace access automatically. | - -**OIDC additional fields:** +| Field | Value | +| --- | --- | +| **Provider ID** | Letters, numbers, and dashes only. Choose a globally unique ID, such as `acme-okta`. Sim rejects an ID already used by another organization. | +| **Issuer URL** | Your identity provider's HTTPS issuer URL | +| **Domain** | The verified email domain served by this connection, such as `acme.com` | +| **On first SSO sign-in** | **Automatic** adds new organization members; **Invite only** authenticates without adding membership. See [membership behavior](#membership-and-account-linking). | -| Field | What to enter | -|-------|--------------| -| **Client ID** | The application client ID from your IdP. | -| **Client secret** | The client secret from your IdP. | -| **Scopes** | Under **Advanced options**. Comma-separated OIDC scopes; default: `openid,profile,email`. | +For OIDC, also enter **Client ID** and **Client secret**. Sim discovers authorization, token, UserInfo, and JWKS endpoints from `{issuer}/.well-known/openid-configuration`. Under **Advanced options**, you can set **Scopes** (default `openid,profile,email`) and override authorization, token, or JWKS endpoints if discovery does not supply usable values. - - For OIDC, Sim automatically fetches endpoints (`authorization_endpoint`, `token_endpoint`, `userinfo_endpoint`, `jwks_uri`) from your issuer's `/.well-known/openid-configuration` discovery document. You only need to provide the issuer URL. - +For SAML, also enter **Entry point URL**, the provider's SSO service URL, and **Identity provider certificate**, its Base64 X.509 certificate. Under **Advanced options**, you can configure Audience, Callback URL override, signed-assertion requirements, NameID format, and IdP metadata XML. Metadata does not replace the required certificate. -**SAML additional fields:** +**Attribute mapping** lets either protocol override the email, name, and stable user-ID claim names. Leave a mapping blank to use the protocol default. -| Field | What to enter | -|-------|--------------| -| **Entry point URL** | The IdP's SSO service URL where Sim sends authentication requests. | -| **Identity provider certificate** | The Base-64 encoded X.509 certificate from your IdP for verifying assertions. | +### Register the callback URL -### 4. Copy the callback URL +Copy **Callback URL** for OIDC or **ACS URL (Reply URL)** for SAML, then register it in your identity provider: -Copy **Callback URL** for OIDC or **ACS URL (Reply URL)** for SAML. This is the endpoint that receives your identity provider's authentication response. Register it in your IdP before saving. On Sim Cloud, `` is `www.sim.ai`; self-hosted deployments use their own domain. If you set a SAML **Callback URL override** under Advanced options, the copyable ACS URL uses that override. - -**OIDC providers** (Okta, Microsoft Entra ID, Google Workspace, Auth0): -``` -https:///api/auth/sso/callback/{provider-id} -``` +| Protocol | Callback format | +| --- | --- | +| OIDC | `https:///api/auth/sso/callback/{provider-id}` | +| SAML | `https:///api/auth/sso/saml2/callback/{provider-id}` | -**SAML providers** (ADFS, Shibboleth): -``` -https:///api/auth/sso/saml2/callback/{provider-id} -``` +Sim Cloud uses `www.sim.ai`; self-hosted deployments use their public domain. Use your chosen **Provider ID** in both systems. For SAML, register the **SP Entity ID** as the provider's audience/Entity ID. If you set a **Callback URL override**, Sim's copyable ACS URL uses that override. -### 5. Save and test +## Provider guides -Click **Save**. To test, sign out and use the **Sign in with SSO** button on the login page. Enter an email address at your configured domain — Sim will redirect you to your identity provider. + + + Okta (OIDC) + Microsoft Entra ID (OIDC) + Microsoft Entra ID (SAML) + Google Workspace (OIDC) + AD FS (SAML) + + ---- +1. In the Okta Admin Console, open **Applications and Resources → Applications → Create App Integration**. These steps use **Classic experience**; select **OIDC - OpenID Connect**, then **Web Application**. +2. Set **Sign-in redirect URI** to your chosen Sim callback: + ``` + https:///api/auth/sso/callback/acme-okta + ``` +3. Under **Assignments**, grant access to the people or groups who should sign in. +4. Copy **Client ID** and **Client Secret** from **General**. +5. Copy your Okta organization domain from the Admin Console account menu, for example `dev-1234567.okta.com`. Do not use its `-admin` hostname. -## Editing and advanced configuration +| Sim field | Value | +| --- | --- | +| **Provider type** | OIDC | +| **Provider ID** | `acme-okta` | +| **Issuer URL** | `https://dev-1234567.okta.com` | +| **Domain** | `acme.com` | +| **Client ID** | From the Okta app | +| **Client secret** | From the Okta app | -For a saved connection, open **Sign-in**, select the provider, and select **Edit**. The Provider ID remains fixed. **Delete** removes that sign-in path only: accounts and memberships it admitted stay. If you delete the primary provider and the domain has another verified provider, that one becomes primary; otherwise people at the domain sign in another way until a provider serves it again. A saved OIDC client secret appears as a mask with a suffix when available; **Replace** lets you enter a new secret, and **Keep saved** cancels that replacement. Select **Update** to save the provider, or **Discard** to abandon changes. +Use the organization issuer for ordinary sign-in. A custom authorization server requires API Access Management and uses `https:///oauth2/`. The `default` custom server is included in the Integrator Free Plan but not every production organization. See [Okta authorization servers](https://developer.okta.com/docs/concepts/auth-servers/) and [Find your Okta domain](https://developer.okta.com/docs/guides/find-your-domain/main/). -**Advanced options** contains OIDC scopes and optional authorization, token, and JWKS endpoint overrides. For SAML, it contains Audience, Callback URL override, signed-assertion requirements, NameID format, and optional IdP metadata XML. **Attribute mapping** lets either protocol override the email, name, and stable user-ID claim names. Leave a mapping blank to use the protocol default. +To launch Sim from an Okta dashboard tile, set **Login initiated by** to **Either Okta or App**, show the icon, and choose the flow that redirects to the app to initiate OIDC login. Set **Initiate login URI** to the saved provider's **Initiate login URL** from Sim: -SCIM settings save immediately in the **Provisioning** tab. Its **Disable just-in-time provisioning** rule overrides Automatic first-sign-in membership while the connection is active and entitled. Existing members can still sign in. See [directory provisioning](/platform/enterprise/scim#provisioning-and-sso-together). +``` +https:///sso/launch/acme-okta +``` -Follow the [Okta](/platform/enterprise/scim/okta) or [Microsoft Entra](/platform/enterprise/scim/entra) provisioning walkthrough to connect a SCIM app and verify synchronization separately from sign-in. +See [Okta OIDC setup](https://help.okta.com/en-us/content/topics/apps/apps_app_integration_wizard_oidc.htm). For SCIM, the creation experience matters: Classic OIDC apps need a separate provisioning integration, while the newer Okta Integration Wizard can support SCIM on OIDC. See [Okta provisioning](/platform/enterprise/scim/okta). -## Switching identity providers + + -To move a domain from one identity provider to another, for example from Microsoft Entra ID to Okta, set up the new provider next to the current one and switch when it works. Nobody loses access along the way. +1. Open **Microsoft Entra ID → App registrations → New registration**. +2. Under **Redirect URI**, select **Web** and enter: + ``` + https:///api/auth/sso/callback/acme-entra + ``` +3. Open **Certificates & secrets → New client secret**. Copy the secret value immediately; it is shown once. +4. From **Overview**, copy **Application (client) ID** and **Directory (tenant) ID**. +5. Keep `email` in Sim's OIDC scopes. You can also request **email** under **Token configuration → Add optional claim → ID**. Confirm that the account supplies an email in your verified domain: a user principal name is not necessarily that address, and the email claim is not guaranteed for every account. +6. If **Enterprise applications → your app → Properties → Assignment required** is **Yes**, assign the people or groups who should sign in. Entra rejects unassigned accounts before they reach Sim. -1. **Add the new provider** under **Sign-in** with the same verified domain. It is saved alongside the current provider, which stays **Primary**, so sign-in does not change yet. -2. **Test it.** Open the new provider and copy its **Test sign-in link**. Anyone at the domain who opens the link signs in through the new provider; everyone else still uses the current one. -3. **Make it primary.** Select **Make primary** on the new provider. From their next sign-in, everyone at the domain goes through it. People already signed in stay signed in. -4. **Remove the old provider** once you are confident, or keep it to switch back with **Make primary**. +| Sim field | Value | +| --- | --- | +| **Provider type** | OIDC | +| **Provider ID** | `acme-entra` | +| **Issuer URL** | `https://login.microsoftonline.com/{tenant-id}/v2.0` | +| **Domain** | `acme.com` | +| **Client ID** | Application (client) ID | +| **Client secret** | Secret value | -The first time someone signs in through the new provider, Sim links it to their existing account by email address, so their workspaces and membership carry over. This requires the new provider to send the same email addresses as the old one. +See [Microsoft app registration](https://learn.microsoft.com/en-us/entra/identity-platform/quickstart-register-app) and [ID token claims](https://learn.microsoft.com/en-us/entra/identity-platform/id-token-claims-reference). ---- + + -## Provider Guides +1. Open **Enterprise applications → New application → Create your own application**. Choose **Integrate any other application you don't find in the gallery**. +2. Open **Single sign-on** and select **SAML**. +3. In **Basic SAML Configuration**, set **Identifier (Entity ID)** to Sim's **SP Entity ID**, and **Reply URL (Assertion Consumer Service URL)** to Sim's **ACS URL (Reply URL)**. +4. Under **Attributes & Claims**, retain the standard schema claim URIs for email, name, and name identifier, or configure matching **Attribute mapping** in Sim. +5. Under **SAML Certificates**, download **Certificate (Base64)** for Sim's required certificate field. You can also download **Federation Metadata XML** for **IdP metadata XML** under Advanced options; it does not replace the certificate. +6. From the application's **Set up** panel, copy **Login URL** and **Microsoft Entra Identifier**. +7. Under **Users and groups**, assign the people who should sign in. Entra rejects unassigned accounts before they reach Sim. - +| Sim field | Value | +| --- | --- | +| **Provider type** | SAML | +| **Provider ID** | `acme-entra-saml` | +| **Issuer URL** | Microsoft Entra Identifier, such as `https://sts.windows.net/{tenant-id}/` | +| **Domain** | `acme.com` | +| **Entry point URL** | Login URL | +| **Identity provider certificate** | Contents of Certificate (Base64) | - + + The Entity ID registered in Entra must match Sim's **SP Entity ID** exactly. Sim validates the assertion's audience against it; a mismatch prevents sign-in. + -### Okta (OIDC) +See [Microsoft SAML setup](https://learn.microsoft.com/en-us/entra/identity/enterprise-apps/add-application-portal-setup-sso). -**In Okta** ([official docs](https://help.okta.com/en-us/content/topics/apps/apps_app_integration_wizard_oidc.htm)): + + -1. Go to **Applications → Create App Integration** -2. Select **OIDC - OpenID Connect**, then **Web Application** -3. Set the **Sign-in redirect URI** to your Sim callback URL: +1. In Google Cloud Console, configure **Google Auth platform → Audience** as **Internal** if sign-in should be restricted to your Google Workspace organization. Branding and consent settings live under **Google Auth platform → Branding**. +2. Open **APIs & Services → Credentials → Create Credentials → OAuth 2.0 Client ID** and choose **Web application**. +3. Add this **Authorized redirect URI**: ``` - https:///api/auth/sso/callback/okta + https:///api/auth/sso/callback/acme-google ``` -4. Under **Assignments**, grant access to the relevant users or groups -5. Copy the **Client ID** and **Client Secret** from the app's **General** tab -6. To open Sim from the Okta dashboard, set **Login initiated by** to **Either Okta or App**, show the app icon to users, choose **Redirect to app to initiate login (OIDC Compliant)**, and set **Initiate login URI** to the provider's **Initiate login URL** from Sim: - ``` - https:///sso/launch/okta - ``` -7. Copy your Okta organization domain from the account menu in the Admin Console, e.g. `dev-1234567.okta.com`. The Admin Console's `-admin` hostname is a different URL. See [Find your Okta domain](https://developer.okta.com/docs/guides/find-your-domain/main/). - -**In Sim:** +4. Copy **Client ID** and **Client Secret**. -| Field | Value | -|-------|-------| -| Provider Type | OIDC | -| Provider ID | `okta` | -| Issuer URL | `https://dev-1234567.okta.com` | -| Domain | `company.com` | -| Client ID | From Okta app | -| Client Secret | From Okta app | +| Sim field | Value | +| --- | --- | +| **Provider type** | OIDC | +| **Provider ID** | `acme-google` | +| **Issuer URL** | `https://accounts.google.com` | +| **Domain** | `acme.com` | +| **Client ID** | From Google Cloud Console | +| **Client secret** | From Google Cloud Console | -For ordinary OIDC sign-in, use your Okta organization issuer as shown. A custom authorization server requires API Access Management; its issuer is `https:///oauth2/`. The `default` custom server is included in Okta's Integrator Free Plan but is not available in every production organization. See [Okta's authorization server guide](https://developer.okta.com/docs/concepts/auth-servers/). +**Internal** restricts the OAuth app to your Workspace organization; Sim's verified **Domain** selects the email domain this SSO connection serves. See [Google OpenID Connect](https://developers.google.com/identity/openid-connect/openid-connect) and [OAuth consent setup](https://developers.google.com/workspace/guides/configure-oauth-consent). + - - -### Microsoft Entra ID (OIDC) - -**In Azure** ([official docs](https://learn.microsoft.com/en-us/entra/identity-platform/quickstart-register-app)): - -1. Go to **Microsoft Entra ID → App registrations → New registration** -2. Under **Redirect URI**, select **Web** and enter your Sim callback URL, using the Provider ID you chose: +1. Open **AD FS Management → Relying Party Trusts → Add Relying Party Trust**. +2. Choose **Claims aware**, then **Enter data about the relying party manually**. +3. Set **Relying party identifier** to Sim's **SP Entity ID**. Sim Cloud normally shows `https://www.sim.ai`; copy the value from your own deployment. +4. Add a **SAML Assertion Consumer Service** endpoint with HTTP POST binding: ``` - https:///api/auth/sso/callback/azure-ad-acme + https:///api/auth/sso/saml2/callback/acme-adfs ``` -3. After registration, go to **Certificates & secrets → New client secret** and copy the value immediately — it won't be shown again -4. Go to **Overview** and copy the **Application (client) ID** and **Directory (tenant) ID** -5. Keep `email` in Sim's OIDC scopes. On Entra's v2.0 endpoint, this scope requests the email claim; alternatively, add **email** under **Token configuration → Add optional claim → ID**. Confirm the account supplies an email in your verified domain: a user principal name is not necessarily that email, and the claim is not guaranteed for every account. See [Microsoft's ID token claims reference](https://learn.microsoft.com/en-us/entra/identity-platform/id-token-claims-reference) -6. If **Enterprise applications → Sim → Properties → Assignment required** is **Yes**, assign the users or groups who should sign in. Microsoft rejects unassigned users before they reach Sim - -**In Sim:** - -| Field | Value | -|-------|-------| -| Provider Type | OIDC | -| Provider ID | `azure-ad-acme` (must be globally unique) | -| Issuer URL | `https://login.microsoftonline.com/{tenant-id}/v2.0` | -| Domain | `company.com` | -| Client ID | Application (client) ID | -| Client Secret | Secret value | - - - - - -### Microsoft Entra ID (SAML 2.0) +5. Under **Certificates**, export the **Token-signing certificate** using **View Certificate → Details → Copy to File → Base-64 encoded X.509 (.CER)**. Paste the text, including its header and footer, into Sim. +6. Copy the **Federation Service identifier** from **Service → Federation Service Properties**, and the SSO endpoint, such as `https://adfs.acme.com/adfs/ls`. -Use this when your tenant is configured for SAML rather than OIDC. Both are supported; OIDC is simpler if you have the choice. - -**In Azure** ([official docs](https://learn.microsoft.com/en-us/entra/identity/enterprise-apps/add-application-portal-setup-sso)): - -1. Go to **Enterprise applications → New application → Create your own application**, choose **Integrate any other application you don't find in the gallery** -2. Open **Single sign-on** and select **SAML** -3. Edit **Basic SAML Configuration** and set both values from Sim's SSO settings page: - - **Identifier (Entity ID)** — the **SP Entity ID** field - - **Reply URL (Assertion Consumer Service URL)** — the **ACS URL (Reply URL)** field -4. Under **Attributes & Claims**, confirm the default claims are present. Sim reads the standard schema claim URIs for email, name, and name identifier -5. Under **SAML Certificates**, download **Certificate (Base64)**. Its contents go in Sim's required **Identity provider certificate** field. You can optionally also download **Federation Metadata XML** and paste it into Sim's **IdP metadata XML** field under **Advanced options** — it does not replace the certificate -6. From the **Set up** panel for your application, copy the **Login URL** and the **Microsoft Entra Identifier** -7. Under **Users and groups**, assign the people who should be able to sign in — Microsoft rejects unassigned users before they reach Sim - -**In Sim:** +| Sim field | Value | +| --- | --- | +| **Provider type** | SAML | +| **Provider ID** | `acme-adfs` | +| **Issuer URL** | Federation Service identifier, such as `https://adfs.acme.com/adfs/services/trust` | +| **Domain** | `acme.com` | +| **Entry point URL** | `https://adfs.acme.com/adfs/ls` | +| **Identity provider certificate** | Contents of the exported Base64 certificate | -| Field | Value | -|-------|-------| -| Provider Type | SAML | -| Provider ID | `azure-ad-acme` (must be globally unique) | -| Issuer URL | **Microsoft Entra Identifier**, e.g. `https://sts.windows.net/{tenant-id}/` | -| Domain | `company.com` | -| Entry point URL | **Login URL** from Entra | -| Identity provider certificate | Contents of the Base64 certificate | - - - The **Identifier (Entity ID)** you set in Entra is what Sim validates the assertion's audience against. If it does not match the **SP Entity ID** shown in Sim exactly, sign-in fails with an audience mismatch. + + **Issuer URL** identifies AD FS; **SP Entity ID** identifies Sim. Sim's form requires an HTTPS issuer. AD FS may use an `http://` Federation Service identifier: work with your AD FS administrator to resolve that mismatch before changing an existing federation's identifier. - +See [Microsoft relying-party setup](https://learn.microsoft.com/en-us/windows-server/identity/ad-fs/operations/create-a-relying-party-trust). - - -### Google Workspace (OIDC) + + -**In Google Cloud Console** ([official docs](https://developers.google.com/identity/openid-connect/openid-connect)): +## Save and verify sign-in -1. Go to **APIs & Services → Credentials → Create Credentials → OAuth 2.0 Client ID** -2. Set the application type to **Web application** -3. Add your Sim callback URL to **Authorized redirect URIs**: - ``` - https:///api/auth/sso/callback/google-workspace - ``` -4. Copy the **Client ID** and **Client Secret** +Select **Save** for a new provider. Sign out, select **Sign in with SSO** on your deployment's login page, and enter an email in the verified domain. Sim selects the domain's provider, redirects to it, and returns the authenticated account to Sim. -**In Sim:** +If multiple providers serve the domain, ordinary sign-in uses the one marked **Primary**. Other providers can be reached through their **Test sign-in link**. -| Field | Value | -|-------|-------| -| Provider Type | OIDC | -| Provider ID | `google-workspace` | -| Issuer URL | `https://accounts.google.com` | -| Domain | `company.com` | -| Client ID | From Google Cloud Console | -| Client Secret | From Google Cloud Console | - - - To restrict sign-in to your Google Workspace domain, configure the OAuth consent screen and ensure your app is set to **Internal** (Workspace users only) under **User type**. Setting the app to Internal limits access to users within your Google Workspace organization. + + Start SAML testing from Sim's **Sign in with SSO** flow. Sim rejects unsolicited SAML assertions, so a test started from an identity-provider app portal can fail even with a correct configuration. - - - +An OIDC dashboard can use the saved provider's **Initiate login URL**. Sim starts that provider's sign-in without asking for an email when the domain is verified and the launch includes a matching issuer. An already signed-in account goes directly to Sim. -### ADFS (SAML 2.0) +## Membership and account linking -**In ADFS** ([official docs](https://learn.microsoft.com/en-us/windows-server/identity/ad-fs/operations/create-a-relying-party-trust)): +Under **First sign-in → On first SSO sign-in**, choose: -1. Open **AD FS Management → Relying Party Trusts → Add Relying Party Trust** -2. Choose **Claims aware**, then **Enter data about the relying party manually** -3. Set the **Relying party identifier** (Entity ID) to the **SP Entity ID** shown in Sim's SSO settings. SAML compares the assertion's audience against it, so it must match exactly: - ``` - https://www.sim.ai - ``` -4. Add an endpoint: **SAML Assertion Consumer Service** (HTTP POST) with the URL: - ``` - https:///api/auth/sso/saml2/callback/adfs - ``` -5. Export the **Token-signing certificate** from **Certificates**: right-click → **View Certificate → Details → Copy to File**, choose **Base-64 encoded X.509 (.CER)**. Paste the file's text into **Identity provider certificate**, including the certificate header and footer. -6. Note the **ADFS Federation Service endpoint URL** (e.g. `https://adfs.company.com/adfs/ls`) +| Mode | Organization membership | +| --- | --- | +| **Automatic** | Adds a new account as a **Member** without an organization invitation. Team seat counts grow with membership; fixed-seat plans require available capacity. IdP role claims do not select the organization role. | +| **Invite only** | Authenticates the account without creating membership. Existing membership and workspace access remain available; grant new access separately. | -**In Sim:** +Neither mode grants workspace access. After sign-in, members enter a workspace they can access or see a no-access state until an administrator grants access. For directory-managed workspace grants, push a group through [SCIM](/platform/enterprise/scim) and map it to a workspace. -| Field | Value | -|-------|-------| -| Provider Type | SAML | -| Provider ID | `adfs` | -| Issuer URL | `https://adfs.company.com/adfs/services/trust` (the ADFS Federation Service identifier) | -| Domain | `company.com` | -| Entry point URL | `https://adfs.company.com/adfs/ls` | -| Identity provider certificate | Contents of the exported Base64 certificate | - - - The **Issuer URL** is the identity provider's own identifier, found in ADFS under **Service → Federation Service Properties → Federation Service identifier**. It is not Sim's URL — Sim's identifier is the **SP Entity ID** shown in the SSO settings, which you register in ADFS as the relying party identifier. - - Sim requires this field to use `https`. ADFS often defaults its Federation Service identifier to an `http://` URI; if yours does, change it to `https` in ADFS so both sides agree. - +Pending invitations and existing external workspace access take precedence over automatic membership, preserving their intended roles and grants. External workspace members access a specific workspace without joining the organization or consuming its seats. - +When a new SSO identity asserts the email of an existing Sim account, Sim links it automatically. The provider's verified domain authorizes that linking for OIDC and SAML without requiring an `email_verified` claim. Sim matches the asserted email; it does not resolve aliases or different user principal names to an existing address. Send the same email when switching providers to preserve the account and its access. - +An active, entitled SCIM connection can override **Automatic** with **Disable just-in-time provisioning**. Existing members, including invited members, can still sign in. See [Provisioning and SSO together](/platform/enterprise/scim#provisioning-and-sso-together). ---- - -## How sign-in works after setup +## Require single sign-on -Once SSO is configured, users with your domain (`company.com`) can sign in through your identity provider: +In **Sign-in**, set **Allowed sign-in methods** to **Single sign-on**. This option becomes available when the organization has an identity provider on a verified domain. -1. User goes to `sim.ai` and clicks **Sign in with SSO** -2. They enter their work email (e.g. `alice@company.com`) -3. Sim looks up the provider that serves `company.com` and redirects them to it -4. After authenticating, they are returned to Sim -5. If **First sign-in** is **Automatic**, Sim adds them to the organization as a Member, growing a Team seat count or validating available fixed-seat capacity -6. They land in an accessible workspace, or see a clear no-access state until an admin grants workspace access +- The requirement applies when a session is created. Turning it on leaves current sessions active; members meet it at their next sign-in. Use **Settings → Organization → Security → Sign out all members** to revoke current member sessions too. +- Members who try password, email-code, or social sign-in see a message directing them to the identity provider. +- Organization owners retain the deployment's other enabled sign-in methods for recovery. An owner who has only used SSO can set a password through **Forgot password** and turn off the requirement if the provider fails. +- The requirement stops enforcing if no sign-in provider remains on a verified domain, or the organization loses SSO entitlement. It can be switched back to other methods at any time. +- Desktop handoff from an already authenticated browser remains available because it derives from an admitted session. -People can also open Sim straight from an OIDC identity provider's app dashboard, such as the Okta tile. Open **Sign-in**, select the provider, and copy its **Initiate login URL** from **Identity provider**. Set it as the app's initiate login URI in your identity provider. Sim starts sign-in through that provider without asking for an email, and only when the provider's domain is verified and the request comes from its own issuer. People who are already signed in go straight to Sim. +Turning the requirement off permits the deployment's other configured sign-in methods again. Enabling an SSO provider alone does not disable them. -With **Automatic** provisioning, no invitation is required for organization membership. The join follows the organization's seat policy and does not infer a role from IdP claims: every newly provisioned user starts as a Member. Team subscriptions grow their billed seat count with membership; fixed-seat plans reject the join when capacity is full. With **Invite only**, SSO proves identity but does not create new membership or workspace access; new access must be granted separately, while existing organization membership and workspace access remain available. +### Offboard a member - - Start SAML sign-in from Sim's **Sign in with SSO** flow. Sim rejects unsolicited SAML assertions, so an IdP-initiated SAML test from an app portal can fail even when the configuration is correct. - +Disabling an account in the identity provider stops future SSO authentication. SSO alone does not revoke current Sim sessions or other sign-in methods. Remove the member in Sim as part of offboarding, or use [SCIM deactivation](/platform/enterprise/scim#what-it-does) to suspend access. SCIM suspension stops sign-in and personal API keys while preserving ownership; shared workspace keys continue working. -SSO provisioning creates internal organization members but does not grant workspace access. To grant workspace access from your identity provider, use [directory provisioning](/platform/enterprise/scim) and map a pushed group to a workspace. External workspace members are different: they are invited to a specific workspace without joining your organization or consuming one of your seats. Existing invitations and external access take precedence over automatic provisioning so their intended role and workspace grants are preserved. +## Edit or replace a provider -## Require single sign-on +Select a saved provider under **Sign-in**, then select **Edit**. Its **Provider ID** stays fixed. Select **Update** to save, or **Discard** to abandon edits. -By default members can sign in with a password, an email code, or your identity provider. To make single sign-on the only way in, open **Settings → Organization → Single sign-on → Sign-in** and set **Allowed sign-in methods** to **Single sign-on**. It becomes available once the organization has an identity provider on a verified domain. +Saved OIDC secrets appear masked, with a suffix when available. **Replace** enters a new secret; **Keep saved** cancels replacement. SCIM settings in **Provisioning** save immediately and have no page-level Save action. -- The requirement is checked when a session is created, so turning it on signs nobody out. Members keep working and meet the requirement at their next sign-in. To end current sessions too, use **Sign out all members** under **Settings → Organization → Security**. -- Organization owners keep every sign-in method. If the identity provider breaks, an owner can still sign in with a password — setting one through **Forgot password** if they only ever signed in through the identity provider — and turn the requirement back off. -- If the last identity provider is deleted or its domain verification lapses, the requirement stops being enforced instead of locking the organization out, and you can switch back to any method at any time. -- Desktop app handoff from an already signed-in browser keeps working, because that session derives from one the requirement already admitted. -- A member who tries a password, an email code, or a social sign-in such as Google or GitHub sees a message telling them to sign in through their identity provider. +Deleting a provider removes its sign-in path, while accounts and memberships remain. If another verified provider serves the same domain, it becomes primary when the deleted provider was primary. Otherwise accounts must use another allowed sign-in method until a provider serves the domain again. - - Turning the requirement off restores password and email sign-in immediately for everyone. - +### Switching identity providers ---- +Configure and test a new provider before switching a domain: -/api/auth/sso/callback/{provider-id}. For SAML providers it is: https:///api/auth/sso/saml2/callback/{provider-id}. You must register this URL in your identity provider before SSO will work." - }, - { - question: "How do I update or replace an existing SSO configuration?", - answer: "Open Settings → Organization → Single sign-on → Sign-in, select the provider, and select Edit. Change the fields and select Update. The Provider ID cannot be changed; replacing it means deleting the provider and adding a new one." - } -]} /> +1. Add it with the same verified domain. The current provider remains **Primary**. +2. Open the new provider and copy **Test sign-in link**. Test accounts use that provider; ordinary sign-in still uses the current primary. +3. Confirm the new provider asserts the same account emails, then select **Make primary**. New sign-ins use it; existing sessions remain active. +4. Keep the old provider to switch back with **Make primary**, or delete it after verification. ---- +Different domains can also use different providers, such as Okta for `eng.acme.com` and Entra for `acme.com`. SCIM remains organization-wide alongside these providers. ## Self-hosted setup -Self-hosted deployments use environment variables instead of the billing/plan check. - -### Environment variables +For a deployment with billing disabled, enable SSO and its browser twin: ```bash -# Required SSO_ENABLED=true NEXT_PUBLIC_SSO_ENABLED=true -# Optional: directory provisioning (SCIM), configured from Single sign-on → Provisioning -SCIM_ENABLED=true -NEXT_PUBLIC_SCIM_ENABLED=true - -# Required if you want users auto-added to your organization on first SSO sign-in +# Organization membership on first SSO sign-in ORGANIZATIONS_ENABLED=true NEXT_PUBLIC_ORGANIZATIONS_ENABLED=true -# Optional: comma-separated provider IDs to trust for automatic account linking. -# This applies to non-SSO providers only — SSO linking is authorized by the -# verified domain on the provider itself, not by this list. -SSO_TRUSTED_PROVIDER_IDS=custom-oidc,partner-saml +# Optional directory provisioning tab +SCIM_ENABLED=true +NEXT_PUBLIC_SCIM_ENABLED=true ``` - - When someone signs in with SSO and an account with the same email already exists - (for example, they previously signed up with email/password), Sim links the SSO - identity to that account automatically. That linking is authorized by the verified - domain attached to the provider, so it works for both OIDC and SAML and does not - depend on your IdP asserting `email_verified`. - +The enterprise master pair also enables these features. See [Self-hosted enterprise](/platform/enterprise/self-hosted) for organization setup. -You can register providers through the **Settings UI** (same as cloud) or by running the registration script directly against your database. +`SSO_TRUSTED_PROVIDER_IDS` is an optional comma-separated list for non-SSO provider account linking. It does not authorize SSO linking; SSO trust comes from the provider's verified domain. -Restricted networks can opt out of the DNS challenge with the server-only `SSO_SKIP_DOMAIN_VERIFICATION=true` setting. Add the domain and click **Verify** before saving SSO. This trusts administrator claims across the instance and is ignored on Sim Cloud. See [skipping DNS verification](/platform/enterprise/verified-domains#skip-dns-verification) for the trust implications and [DNS network requirements](/platform/enterprise/verified-domains#restricted-networks) for the default setup. +Restricted networks can use the server-only `SSO_SKIP_DOMAIN_VERIFICATION=true` setting. Add the domain and select **Verify** before saving SSO. See [DNS requirements](/platform/enterprise/verified-domains#restricted-networks) and [bypass trust consequences](/platform/enterprise/verified-domains#skip-dns-verification). ### Script-based registration -Use this when you need to register an SSO provider without going through the UI — for example, during initial deployment or CI/CD automation. +Deployment operators can register directly against the database from the repository root. Provide `DATABASE_URL` or `POSTGRES_URL`, an existing account's `SSO_USER_EMAIL`, and `SSO_ORGANIZATION_ID` to bind the provider to the organization. Without the organization ID, the provider is user-scoped and does not add organization membership at first sign-in. + + + Direct registration replaces the stored configuration for the same **Provider ID** and records its organization domain as verified without the DNS challenge. Run it only with operator authority and the intended organization ID. This bypasses the ordinary Settings verification flow. + + +OIDC example: ```bash -# OIDC example (Okta) +DATABASE_URL=... \ SSO_ENABLED=true \ -NEXT_PUBLIC_APP_URL=https://your-instance.com \ +NEXT_PUBLIC_APP_URL=https://sim.example.com \ SSO_PROVIDER_TYPE=oidc \ -SSO_PROVIDER_ID=okta \ +SSO_PROVIDER_ID=acme-okta \ SSO_ISSUER=https://dev-1234567.okta.com \ -SSO_DOMAIN=company.com \ -SSO_USER_EMAIL=admin@company.com \ +SSO_DOMAIN=acme.com \ +SSO_USER_EMAIL=admin@acme.com \ +SSO_ORGANIZATION_ID=org_123 \ SSO_OIDC_CLIENT_ID=your-client-id \ SSO_OIDC_CLIENT_SECRET=your-client-secret \ bun run packages/db/scripts/register-sso-provider.ts ``` +SAML example: + ```bash -# SAML example (ADFS) +DATABASE_URL=... \ SSO_ENABLED=true \ -NEXT_PUBLIC_APP_URL=https://your-instance.com \ +NEXT_PUBLIC_APP_URL=https://sim.example.com \ SSO_PROVIDER_TYPE=saml \ -SSO_PROVIDER_ID=adfs \ -SSO_ISSUER=https://adfs.company.com/adfs/services/trust \ -SSO_SAML_AUDIENCE=https://your-instance.com \ -SSO_DOMAIN=company.com \ -SSO_USER_EMAIL=admin@company.com \ -SSO_SAML_ENTRY_POINT=https://adfs.company.com/adfs/ls \ +SSO_PROVIDER_ID=acme-adfs \ +SSO_ISSUER=https://adfs.acme.com/adfs/services/trust \ +SSO_SAML_AUDIENCE=https://sim.example.com \ +SSO_DOMAIN=acme.com \ +SSO_USER_EMAIL=admin@acme.com \ +SSO_ORGANIZATION_ID=org_123 \ +SSO_SAML_ENTRY_POINT=https://adfs.acme.com/adfs/ls \ SSO_SAML_CERT="-----BEGIN CERTIFICATE----- ... -----END CERTIFICATE-----" \ bun run packages/db/scripts/register-sso-provider.ts ``` -The script outputs the callback URL to configure in your IdP once it completes. +The script prints the callback URL to register in the identity provider. These commands configure the database; persist the SSO feature flags in the running application's environment separately. -To remove a provider: +To remove one provider: ```bash -SSO_USER_EMAIL=admin@company.com \ +DATABASE_URL=... \ +SSO_USER_EMAIL=admin@acme.com \ +SSO_PROVIDER_ID=acme-okta \ bun run packages/db/scripts/deregister-sso-provider.ts ``` + +Omitting `SSO_PROVIDER_ID` removes **all providers owned by that account**. + +## Related docs + +- [Verified domains](/platform/enterprise/verified-domains) +- [Directory provisioning](/platform/enterprise/scim) +- [Okta provisioning](/platform/enterprise/scim/okta) +- [Microsoft Entra provisioning](/platform/enterprise/scim/entra) +- [Session policies](/platform/enterprise/session-policies) diff --git a/apps/docs/content/docs/platform/enterprise/usage-tracking.mdx b/apps/docs/content/docs/platform/enterprise/usage-tracking.mdx index 21a1343a2c2..fba4f443d8f 100644 --- a/apps/docs/content/docs/platform/enterprise/usage-tracking.mdx +++ b/apps/docs/content/docs/platform/enterprise/usage-tracking.mdx @@ -1,176 +1,107 @@ --- title: Insights -description: Explore organization credit usage, workflow performance, and recorded chat activity +description: Compare organization credit usage with workflow performance and recorded Chat activity --- -import { Callout } from 'fumadocs-ui/components/callout' -import { FAQ } from '@/components/ui/faq' -import { Image } from '@/components/ui/image' +Insights shows credit consumption by source, member, workspace, and model, alongside retained workflow and Chat activity. Use it to find spending drivers, investigate workflow performance, and export credit events for reporting. -Insights shows how your organization consumes credits across every part of the platform — which members, which workspaces, which models, and which product features. Use it to monitor spend against your commitment, find what is driving it, and export the underlying events for chargeback. +Organization owners and admins open **Settings → Organization → Insights**. Regular members cannot view organization usage, including their own contribution. Billing-enabled deployments require Enterprise; billing-disabled deployments use the feature configuration under [Self-hosted setup](#self-hosted-setup). -Spend figures are in **credits** (1 credit = $0.005). See [cost calculation](/platform/costs) for how credits are derived. +## Choose a period ---- - -## Viewing usage - -Go to **Settings → Organization → Insights** in your workspace. - -The period selector applies to every tab: - -| Period | What it covers | -|--------|----------------| -| **Current period** | Your organization's current billing period | -| **Previous period** | The period immediately before it | -| **Last 7 days** / **Last 30 days** | A rolling window ending now | -| **Custom range** | Any range up to 92 days | - - - Daily bars are drawn in your browser's timezone, while a billing period begins at a fixed UTC instant. The first and last bar of a period can therefore be partial, and two admins in different timezones will see the same total split across slightly different days. - - -### Tabs +| Period | Scope | +| --- | --- | +| **Current period** | Organization's current billing period. | +| **Previous period** | Immediately preceding billing period. | +| **Last 7 days** / **Last 30 days** | Rolling window ending now. | +| **Custom range** | Selected dates, up to 92 days. | -| Tab | Answers | -|-----|---------| -| **Overview** | Credit consumption, recorded activity, workflow failure rate, and usage by source | -| **Activity** | Run trends and performance, grouped by workspace, workflow, chat member, or trigger | -| **Members** | Which people are driving usage | -| **Workspaces** | Which workspaces are driving usage — select one to drill in | -| **Models** | Which models we are paying for | +The period applies to every tab. Daily bars use your browser's timezone, while billing periods begin at a fixed UTC instant. The first and last bars can be partial. Different timezones can split the same total differently across days. -Selecting a workspace opens its detail view, which splits that workspace's usage into **Sources** (what kind of work) and **Workflows** (the individual workflow runs). **Open logs** jumps to [audit logs](/platform/enterprise/audit-logs) filtered to that workspace. +Spend is in **credits**, where 1 credit = $0.005; the UI rounds displayed credits. [Logs](/logs-debugging/logging) and Logs API costs are in USD, while Billing and run-resource API amounts use their documented credit units. Check the endpoint contract before comparing amounts. See [cost calculation](/platform/costs). -A workspace's detail view with a Sources section listing Sim Chat and Workflow, and a Workflows section ranking individual workflows by credits +## Read the tabs -**Sources** adds up to the workspace's total, while **Workflows** covers only the workflow-run part of it. In the example above, Sources totals 4,435 credits but the workflows list only accounts for the 161 credits under Workflow — the other 4,274 came from Chat, which no workflow produced. +| Tab | Shows | +| --- | --- | +| **Overview** | Credit consumption, recorded activity, workflow failure rate, and sources. | +| **Activity** | Run trends and performance by workspace, workflow, chat member, or trigger. | +| **Members** | Credit consumption attributed to people. | +| **Workspaces** | Credit consumption by workspace; select one to drill in. | +| **Models** | Paid model usage. | ---- +A workspace detail splits usage into **Sources** and **Workflows**. Sources covers all attributed credits; Workflows covers only the workflow-run ledger. For example, 4,274 Chat credits plus 161 Workflow credits totals 4,435, while the workflow list accounts for 161. **Open logs**, where available, opens [audit logs](/platform/enterprise/audit-logs) filtered to that workspace. ## Activity and performance -The **Activity** tab shows workflow runs, recorded chat runs, members with chat activity, and workflow failure rate. Group the breakdown by **Workspaces**, **Workflows**, **Members**, or **Triggers**, and sort by run volume, failure count, or average workflow duration. Member breakdowns rank chat runs only. Results are paginated; totals and sorting include the whole selected period, not just the visible page. Select a workspace to narrow the activity view, then use **All workspaces** to clear that filter. - -- **Workflow runs** count retained execution records whose start time falls in the selected period, including runs that are still running, paused, or cancelled. -- **Recorded chat runs** count distinct recorded execution IDs across workspace and organization chats. Continuations count once, in the period containing their first retained start. Calls without a persisted chat run are not included. -- **Members with chat activity** count distinct users attributed to those chat runs. This measures recorded chat activity, not logins, all active users, or people billed for automated workflows. -- **Workflow failure rate** is failed runs divided by completed plus failed runs. Paused, cancelled, and unfinished runs do not enter the denominator. A dash means there are no completed or failed runs to measure. -- **Average duration** uses the recorded duration of completed or failed workflows. Missing durations are excluded; a dash means no duration is available. +In **Activity**, group by **Workspaces**, **Workflows**, **Members**, or **Triggers**. Sort by run volume, failure count, or average workflow duration. Members rank recorded Chat runs. Pages limit visible rows; totals and sorting cover the whole selected period. Select a workspace to narrow results and use **All workspaces** to clear it. -Activity follows retained history and current organization/workspace ownership. Deleting history or moving a workspace can change historical activity totals. Status and duration reflect the latest recorded outcome, even for a run that started in an earlier period. The activity view does not read chat transcripts or workflow trace payloads. +| Metric | Definition | +| --- | --- | +| Workflow runs | Retained execution records starting in the period, including running, paused, and cancelled runs. | +| Recorded chat runs | Distinct recorded execution IDs across workspace and organization chats. Continuations count once, at the first retained start; calls without a persisted run are excluded. | +| Members with chat activity | Distinct users attributed to those recorded runs. This is not a login or all-active-member count. | +| Workflow failure rate | Failed ÷ (completed + failed). Paused, cancelled, and unfinished runs are excluded; a dash means no completed/failed sample. | +| Average duration | Known nonnegative durations of completed or failed workflows. Missing durations are excluded; a dash means none are available. | -Credit totals continue to come from the billing ledger. Activity counts need not match billing-event counts, and the credit export does not export activity. Exact per-chat cost, connector/skill adoption, and generated-artifact attribution are not available in this view. +These metrics follow retained history and current workspace/organization ownership. Deletion or moving a workspace can change historical totals. Outcome and duration reflect the latest recorded state even when a run started earlier. Activity does not read Chat transcripts or workflow trace payloads. ---- +Credits come from a separate billing ledger, so activity counts need not match credit-event counts. The credit export does not export activity. This view does not provide exact per-chat cost, connector/skill adoption, or attribution of generated artifacts. -## What each source means +## Credit sources -A **source** is the part of the platform that consumed the credits. Every charge belongs to exactly one source, so the Sources breakdown always adds up to your total. +Each charge has one source. The exact **Agent block** label in Insights refers to the **Sim Chat** workflow block (`mothership_block`), rather than the ordinary Agent block. -| Source | Platform features that bill to it | -|--------|-----------------------------------| -| **Workflow** | Every workflow run — model calls made on Sim's hosted keys, hosted-key tool calls (web search, scraping, and similar), and the per-run base charge | -| **Sim Chat** | The Chat panel, agent calls made through the API, and the email Inbox | -| **Agent block** | The Agent block running inside a workflow | -| **Knowledge Base** | Embedding documents on upload or connector sync, and semantic search queries | -| **Wand** | Inline AI generation in editors | -| **Enrichment** | Table column enrichment | -| **Voice input** | Voice sessions | -| **Voice output** | Spoken responses in deployed chats | -| **API tool call** | A hosted-key tool invoked directly through the tool execution API, outside any workflow run | -| **Sim Chat (MCP)** | Retired. Appears only for historical periods | +| Source | Recorded charges | +| --- | --- | +| **Workflow** | Workflow model calls on hosted keys, hosted-key tool calls, and the per-run base charge. | +| **Sim Chat** | Chat panel, API agent calls, and email Inbox usage, combined. | +| **Agent block** | Sim Chat workflow-block usage, metered separately from its containing workflow. | +| **Knowledge Base** | Upload/connector embedding and semantic search. | +| **Wand** | Inline AI generation in editors. | +| **Enrichment** | Table enrichment. | +| **Voice input** | Voice sessions. | +| **Voice output** | Spoken responses in deployed chats. | +| **API tool call** | Direct hosted-key tool calls through the tool API outside a workflow run. | +| **Sim Chat (MCP)** | Retired source visible in historical periods. | -### Nuances worth knowing +An ordinary Agent block's hosted model calls remain under Workflow. The Workflow base charge applies even without model calls. To assess a workflow using the Sim Chat block, read its Workflow charges and the separately metered Agent block source; neither charge is counted twice. -These follow from how charges are recorded, and they explain most questions about why a number looks the way it does. +A hosted-key tool called inside a workflow belongs to Workflow; the same tool called directly belongs to API tool call. Chat panel, API agent, and Inbox charges cannot be separated by source. Dedicated workspace attribution can distinguish them when those surfaces actually name different workspaces. Usage without a workspace appears under **No workspace** and remains part of the organization total. -**Workflow covers the whole run, not just the base charge.** A workflow row includes three things: the models it called on Sim's hosted keys, any hosted-key tool calls, and the per-run base charge. The base charge applies to every run, including runs with no model calls. +### Reconcile totals -**Agent block is billed separately from the workflow that contains it.** An Agent block runs inside a workflow but is metered on its own, so its credits appear under **Agent block** rather than **Workflow**. Nothing is counted twice — but it also means Workflow alone understates what your workflows cost. Read the two lines together. +Members, Workspaces, and Sources are separate groupings of the same ledger. Each covers the period's charges; adding groupings together double-counts. Rounding can obscure small differences. -**Sim Chat covers three surfaces.** The Chat panel, headless agent calls through the API, and the Inbox all record as **Sim Chat** and cannot be separated from one another. If you need per-surface attribution today, separate them by workspace instead. +Models covers model charges only. Base charges, hosted tools, and fixed charges explain why it can be lower than the total. The current billing period lets you compare consumption with Billing; rolling windows do not align with invoices, and consumption is not a complete invoice including other fees or taxes. -**Only workflow runs carry workflow attribution.** Chat, Agent block, Wand, Knowledge Base, and voice usage are not produced by a workflow and have no workflow attached. That is the gap between a workspace's **Sources** and **Workflows** sections shown above. +## Bring your own keys -**Hosted-key tool calls bill in two places, depending on who made them.** A hosted-key tool called *inside* a workflow run is folded into that run and appears under **Workflow**. The same tool called directly through the tool execution API belongs to no run, so it records under **API tool call** instead. +A workflow model call using a workspace or organization provider key has zero model credits while its token usage is still recorded. Those tokens are not broken out in the Insights panel's credit totals. This statement describes verified workflow-model recording; other own-key surfaces do not have an equivalent breakdown here. -**Some usage has no workspace.** Agent calls made through the API may not name a workspace, particularly from headless or self-hosted callers. That usage is grouped under **No workspace** on the Workspaces tab. It is still counted in your total. +BYOK does not remove the workflow base charge or separate hosted-tool and sandbox charges. Confirm which key was used when investigating an expected zero-cost model call. -**Models excludes non-model charges.** The Models tab covers model usage only, so it will read lower than your period total — the difference is per-run base charges, hosted-key tool charges, and fixed charges such as voice sessions. +## Export credit events - - Each tab is a different slice of the same charges, not an additional set of them. Members, Workspaces, and Sources each add up to your period total on their own; adding two tabs together double-counts. - +Click **Export** for the selected period and filters, or **All events** for the individual ledger entries and their filters. CSV columns are `Date, Source, Description, Workflow, Credits`; credits are numeric with four decimal places and can be summed. ---- +Exports stop at **100,000 events**. A truncated export still downloads and shows a notice; narrow the date range and export the remaining periods. Fractional CSV values can differ from whole-credit UI rounding. -## Bring your own keys (BYOK) - -When a workspace or organization supplies its own provider key, Sim does not charge for that model usage. Those calls are still recorded, measured in **tokens** rather than credits — the credit cost is zero by definition — and they are not included in the credit totals anywhere in the panel. - - - This usage is not broken out in the panel today. Of what is recorded, only model usage in workflow runs is covered: tool calls and Chat usage made on your own keys are not recorded at all. - - ---- - -## Exporting - -**Export credits** downloads the events behind the current period and filters as a CSV with columns `Date, Source, Description, Workflow, Credits`. Credits are exported as plain numbers so the column can be summed, and carry decimals — an individual event often costs a fraction of a credit. - -**Credit events** opens the full ledger — every credit-consuming event, newest first, with its own filters and export. - -Very large exports are capped. When that happens the download still succeeds and Sim tells you it was truncated; narrow the date range to capture everything. - ---- - - - ---- +For automation, use the organization usage [summary](/api-reference/organizations/getOrganizationUsageSummary), [breakdown](/api-reference/organizations/getOrganizationUsageBreakdown), and [events](/api-reference/organizations/listOrganizationUsageEvents) APIs. [Billing CLI](/cli/billing) account reads are a separate view from this organization report. ## Self-hosted setup -Self-hosted deployments use environment variables instead of the billing/plan check. - -### Environment variables +Enable Insights through enterprise configuration or explicitly set: ```bash USAGE_MONITORING_ENABLED=true NEXT_PUBLIC_USAGE_MONITORING_ENABLED=true ``` -Once enabled, Insights is viewable in **Settings → Organization → Insights** for organization owners and admins. +Explicit values take precedence over the enterprise master configuration. Billing-enabled deployments retain the Enterprise gate. Organization owner/admin access is still required. See [self-hosted enterprise setup](/platform/enterprise/self-hosted). + +## Related docs + +- [Costs and credits](/platform/costs) +- [Audit logs](/platform/enterprise/audit-logs) +- [Data retention](/platform/enterprise/data-retention) diff --git a/apps/docs/content/docs/platform/enterprise/verified-domains.mdx b/apps/docs/content/docs/platform/enterprise/verified-domains.mdx index b396a2191b4..ed883d87934 100644 --- a/apps/docs/content/docs/platform/enterprise/verified-domains.mdx +++ b/apps/docs/content/docs/platform/enterprise/verified-domains.mdx @@ -1,96 +1,74 @@ --- -title: Verified Domains -description: Prove ownership of your email domains for single sign-on and directory provisioning +title: Verified domains +description: Prove email-domain ownership for single sign-on and directory provisioning --- import { Callout } from 'fumadocs-ui/components/callout' import { Image } from '@/components/ui/image' -import { FAQ } from '@/components/ui/faq' -Verified Domains let organization owners and admins on Enterprise plans prove they control an email domain (like `acme.com`) with a DNS TXT record. Verify a domain before configuring single sign-on for it or provisioning members at that domain through SCIM. +Verify an email domain before configuring SSO for it or provisioning members at that domain through SCIM. Organization owners and admins prove ownership with a DNS TXT record. On Sim Cloud, domain verification requires an Enterprise organization. - - Configuring SSO for a domain requires it to be verified first. Verifying proves your organization controls the domain — without it, anyone could point another company's domain at their own identity provider. The domain-verification migration preserved domains configured for SSO before this requirement was introduced. - - ---- +A verified domain authorizes your organization to use its identity provider for addresses on that domain. Each domain belongs to one organization; subdomains such as `eng.acme.com` must be verified separately from `acme.com`. ## Verify a domain -Go to **Settings → Organization → Single sign-on → Domains**. The **Verified domains** section is shared by sign-in and directory provisioning. +Open **Settings → Organization → Single sign-on → Domains**. The **Verified domains** section is shared by sign-in and directory provisioning. -Domains tab showing a verified domain and the DNS record for a pending domain +Domains tab showing a verified domain and the DNS record for a pending domain -1. Enter the domain, for example `acme.com`, and click **Add domain**. -2. Sim shows a DNS **TXT record** to publish — a host (`_sim-challenge.acme.com`) and a unique value (`sim-domain-verification=…`). -3. Add that TXT record at your DNS provider. -4. Click **Verify**. Sim looks up the record; on success the domain is marked **Verified**. +1. Enter the domain, for example `acme.com`, and select **Add domain**. +2. Copy the TXT host and value shown by Sim: `_sim-challenge.acme.com` and `sim-domain-verification=…`. +3. Add that TXT record at your DNS provider. Keep existing records; the challenge uses its own host. +4. Select **Verify**. Sim looks up the record and marks the domain **Verified** when it matches. - Some DNS providers append the zone automatically. If yours does, enter `_sim-challenge` when managing the `acme.com` zone, or `_sim-challenge.eng` to verify `eng.acme.com` from that zone. Check the resulting record name: it must match the full host Sim shows, without a repeated domain such as `_sim-challenge.acme.com.acme.com`. + Some DNS providers append the zone automatically. In the `acme.com` zone, use `_sim-challenge` if your provider adds the zone, or `_sim-challenge.eng` for `eng.acme.com`. The resulting name must match Sim's full host, without a repeated suffix such as `_sim-challenge.acme.com.acme.com`. -DNS changes can take time to propagate. If verification does not succeed immediately, check the record name and value, then wait and retry. Keep the TXT record published. Sim verifies it when you select **Verify**; removing the DNS record does not itself revoke a completed verification. +DNS changes can take time to propagate. If verification fails, check the record name and value, then wait and retry. Keep the record published. Sim checks it when you select **Verify**; removing the DNS record does not automatically revoke a completed verification. -Add each domain you own separately. Subdomains (`eng.acme.com`) are verified independently of the apex. +Domains configured for SSO before domain verification was introduced were preserved as verified by the migration. New claims require verification. ---- +## Remove a verified domain -## FAQ - -. Add the supplied TXT value there without replacing existing records on your domain.', - }, - { - question: 'What happens to domains we already use for SSO?', - answer: - 'Domains configured before domain verification was introduced were preserved as verified by the migration. New domains must complete DNS verification.', - }, - { - question: 'Can two organizations verify the same domain?', - answer: - 'No. A verified domain belongs to exactly one organization. Once verified, another organization cannot claim it.', - }, - { - question: 'What if I remove a verified domain?', - answer: - 'New SSO sign-ins for that domain stop immediately, including through an existing provider. SCIM cannot create users or change an email to that domain until it is verified again. Removing the domain does not itself end existing sessions. Re-add and verify it to restore the ownership proof.', - }, - ]} -/> +Removing a domain in Sim stops new SSO sign-ins for that domain, including through an existing provider. SCIM can no longer create accounts or change an account's email to that domain until it is verified again. Existing sessions are not ended by domain removal. ---- +Re-add and verify the domain to restore its ownership proof. Another organization cannot claim it while it remains verified for yours. ## Self-hosted setup -Domain verification appears on the single sign-on page when SSO is enabled: +Enable SSO to expose **Domains** in the single sign-on settings: ```bash SSO_ENABLED=true NEXT_PUBLIC_SSO_ENABLED=true ``` -`ENTERPRISE_ENABLED` turns both on together, but it needs its own browser twin — set `NEXT_PUBLIC_ENTERPRISE_ENABLED` alongside it, or the server and the settings page enable SSO while the login page still hides its SSO entry point. See the [self-hosted enterprise guide](/platform/enterprise/self-hosted). +You can instead enable the enterprise suite with both `ENTERPRISE_ENABLED=true` and `NEXT_PUBLIC_ENTERPRISE_ENABLED=true`. Set the browser twin too: the login page's SSO entry point reads it before a workspace loads. See [Self-hosted enterprise](/platform/enterprise/self-hosted). -Once enabled, verify domains from **Settings → Organization → Single sign-on → Domains**. The older `/workspace//settings/domains` path still resolves to the same page. +The older `/workspace//settings/domains` path still resolves to **Single sign-on → Domains**. ### Restricted networks -Sim queries `1.1.1.1` and `8.8.8.8` directly from the application server. Allow outbound DNS on UDP and TCP port 53 to these addresses. The lookup uses public DNS rather than the server's local resolver or an HTTP proxy, so the TXT record must be published in a publicly delegated DNS zone. A Route 53 private hosted zone is not visible to these resolvers. +The application server queries `1.1.1.1` and `8.8.8.8` directly. Allow outbound DNS on UDP and TCP port 53 to both addresses. Verification uses public DNS, not the server's local resolver or an HTTP proxy. + +Publish the TXT record in a publicly delegated zone. Private zones, including Route 53 private hosted zones, are not visible to these resolvers. ### Skip DNS verification -For a deployment where the operator trusts every organization owner and admin to claim email domains, set this server-only variable and restart the application: + + This option delegates domain-claim authority to every organization owner and admin in the self-hosted instance. They can authorize an identity provider for any unclaimed email domain without proving ownership. Enable it only when the operator trusts those administrators to make that decision. It is off by default and ignored on Sim Cloud. + + +Set the server-only variable and restart the application: ```bash SSO_SKIP_DOMAIN_VERIFICATION=true ``` -For Helm deployments, use an application image built from a revision that includes this setting. Upgrading the chart alone does not make an older application image support the variable. Override `app.image.tag` with a compatible released image or a build you publish yourself; set `app.image.repository` as well for a custom repository: +Under **Domains**, add the domain and select **Verify**. No TXT record or DNS access is needed. Sim records the domain as verified for SSO account linking and SCIM provisioning; another organization still cannot claim it. Existing pending domains can be verified the same way. + +For Helm, the application image must support this variable. Updating the chart alone does not add support to an older image. Override `app.image.tag` with a compatible released image or your own build, and set `app.image.repository` if using a custom repository: ```yaml app: @@ -100,12 +78,11 @@ app: SSO_SKIP_DOMAIN_VERIFICATION: "true" ``` -If `app.image.digest` is set, replace it with a compatible image digest instead — it takes precedence over the tag. +If `app.image.digest` is set, replace it with a compatible digest instead; it takes precedence over the tag. -Add the domain under **Domains**, then click **Verify**. No TXT record or DNS access is needed. The domain is recorded as verified for SSO account linking and SCIM provisioning, and another organization still cannot claim the same domain. Existing pending domains can be verified the same way. +Removing the variable or setting it to `false` restores DNS verification for pending and future claims. Already verified domains stay verified. Remove a domain in **Domains** to revoke its trust. - - This option is off by default and ignored on Sim Cloud. It applies to every organization in the self-hosted instance: an organization administrator can authorize their identity provider for any unclaimed email domain without proving ownership. Enable it only when those administrators are trusted to make that decision. - +## Related docs -Removing the variable or setting it to `false` restores DNS verification for pending and future claims. Domains already verified remain verified; remove a domain in **Domains** to revoke its trust. +- [Single sign-on](/platform/enterprise/sso) +- [Directory provisioning](/platform/enterprise/scim) diff --git a/apps/docs/content/docs/platform/enterprise/whitelabeling.mdx b/apps/docs/content/docs/platform/enterprise/whitelabeling.mdx index f2c3de3e524..046bc2b223a 100644 --- a/apps/docs/content/docs/platform/enterprise/whitelabeling.mdx +++ b/apps/docs/content/docs/platform/enterprise/whitelabeling.mdx @@ -1,147 +1,85 @@ --- title: White-labeling -description: Replace Sim branding with your own logo, colors, and links +description: Set organization branding or a self-hosted deployment's default identity, colors, and links --- -import { FAQ } from '@/components/ui/faq' -import { Image } from '@/components/ui/image' +Organization white-labeling sets the logo, colors, and links shown inside your organization's workspaces. Authorized external workspace members also see the workspace's organization branding. Public login, manifest, and file-share surfaces use the separate [instance-wide branding](#instance-wide-branding) baseline. -White-labeling lets you replace Sim's default branding — logo, colors, and support links — with your own. Members of your organization see your brand instead of Sim's throughout the workspace. +Organization owners and admins configure white-labeling. Billing-enabled deployments require Enterprise. On billing-disabled deployments, organization white-labeling defaults on; explicit `WHITELABELING_ENABLED=false` and `NEXT_PUBLIC_WHITELABELING_ENABLED=false` disable it. See [self-hosted enterprise setup](/platform/enterprise/self-hosted). ---- - -## Setup - -### 1. Open White-labeling settings - -Go to **Settings → Organization → White-labeling** in your workspace. - -Whitelabeling settings showing brand identity fields (Logo, Wordmark, Brand name), color pickers for primary and accent colors, and link fields for support email and documentation URL - -### 2. Configure brand identity - -| Field | Description | -|-------|-------------| -| **Logo** | Shown in the collapsed sidebar. Square image (PNG, JPEG, SVG, or WebP). Max 5 MB. | -| **Wordmark** | Shown in the expanded sidebar and application loading screens. Wide image (PNG, JPEG, SVG, or WebP). Max 5 MB. | -| **Brand name** | Replaces "Sim" in the sidebar and select UI elements. Max 64 characters. | - -Loading screens use the wordmark, never the square logo. Without a wordmark, they show the brand name; when the name is still Sim, they use the built-in Sim wordmark. - -### 3. Configure colors - -All colors must be valid hex values (e.g. `#701ffc`). - -| Field | Description | -|-------|-------------| -| **Primary color** | Main accent color used for buttons and active states. | -| **Primary hover color** | Color shown when hovering over primary elements. | -| **Accent color** | Secondary accent for highlights and secondary interactive elements. | -| **Accent hover color** | Color shown when hovering over accent elements. | - -### 4. Configure links - -Replace Sim's default support and legal links with your own. - -| Field | Description | -|-------|-------------| -| **Support email** | Shown in help prompts. Must be a valid email address. | -| **Documentation URL** | Link to your internal documentation. Must be a valid URL. | -| **Terms of service URL** | Link to your terms page. Must be a valid URL. | -| **Privacy policy URL** | Link to your privacy page. Must be a valid URL. | - -### 5. Save - -Click **Save changes**. The new branding is applied immediately for all members of your organization. - ---- +## Configure organization branding -## What gets replaced +1. Open **Settings → Organization → White-labeling**. +2. Set identity, colors, and links using the fields below. +3. Click **Save**. Refresh other open tabs to pick up changes. -Organization white-labeling replaces the following visual elements: +### Identity -- **Sidebar logo and wordmark** — your uploaded images replace the Sim logo -- **Brand name** — appears in the sidebar and select UI labels -- **Primary and accent colors** — applied to buttons, active states, and highlights -- **Support and legal links** — help prompts and footer links point to your URLs +| Field | Use and limit | +| --- | --- | +| **Logo** | Square image in the collapsed sidebar. PNG, JPEG, SVG, or WebP; maximum 5 MiB. | +| **Wordmark** | Wide image in the expanded sidebar and loading screens. Same formats and 5 MiB limit. | +| **Brand name** | Sidebar and selected UI labels; maximum 64 characters. | -Organization white-labeling applies only to members of your organization. Public-facing surfaces — the login modal, the PWA manifest, and public file-share pages — read the **instance-wide** branding described below instead, and are unaffected by organization settings. +Loading screens use the wordmark rather than the square logo. Without a wordmark, they use the brand name; the default name Sim uses the built-in Sim wordmark. ---- +### Colors - +Use valid hex values, such as `#701ffc`. ---- +| Field | Use | +| --- | --- | +| **Primary color** | Buttons and active states. | +| **Primary hover color** | Hover state for primary elements. | +| **Accent color** | Highlights and secondary interactive elements. | +| **Accent hover color** | Hover state for accent elements. | -## Self-hosted setup +### Links -Self-hosted deployments use environment variables instead of the billing/plan check, and white-labeling is **already enabled** on one: it defaults on wherever billing is disabled. Configure branding through **Settings → Organization → White-labeling** the same way. +| Field | Use | +| --- | --- | +| **Support email** | Help prompts; must be a valid email address. | +| **Documentation URL** | Documentation link. | +| **Terms of service URL** | Terms link. | +| **Privacy policy URL** | Privacy link. | -### Environment variables +The URL fields require valid URLs. Check the collapsed and expanded sidebar, a loading screen, and the support/legal links after saving. -To turn it off: +## Scope and fallback -```bash -WHITELABELING_ENABLED=false -NEXT_PUBLIC_WHITELABELING_ENABLED=false -``` +Saved organization values override the instance baseline inside that organization's workspace. Clearing an organization value restores the corresponding instance or Sim default. The settings read requires organization membership; updates require an owner or admin. Workspace visitors receive branding through their authorized workspace context. ---- +Organization branding does not replace the signed-out login identity, PWA manifest, or public file-share identity. Those surfaces read instance settings. The manifest retains built-in icons; public file shares hide the Sim wordmark when an instance logo is configured rather than rendering a custom wordmark there. ## Instance-wide branding -Instance-wide branding is a separate mechanism from the organization settings above. It is read from environment variables at every render, needs **no organization** and **no** `WHITELABELING_ENABLED`, and applies across the deployment, including surfaces organization settings never reach — though not uniformly. The PWA manifest keeps the built-in icons, and public file-share pages only hide the Sim wordmark rather than rendering yours. It covers the surfaces organization white-labeling never reaches: the login modal, the PWA manifest, and public file-share pages. +Instance settings need no organization or `WHITELABELING_ENABLED`. They supply a deployment baseline and reach signed-out surfaces as well as workspace fallback values. Set the environment variables on your self-hosted app and apply them through your deployment's update process. -Where both are set, an organization's saved settings take precedence for members of that organization; the instance-wide values are the deployment's baseline. - -### Identity +### Identity variables ```bash NEXT_PUBLIC_BRAND_NAME=Acme NEXT_PUBLIC_BRAND_LOGO_URL=/branding/logo.png NEXT_PUBLIC_BRAND_WORDMARK_URL=/branding/wordmark.svg NEXT_PUBLIC_BRAND_FAVICON_URL=/branding/favicon.ico -# The CSP's style-src allows only 'self' and fonts.googleapis.com, and takes -# no configured hosts — in practice this means same-origin. NEXT_PUBLIC_CUSTOM_CSS_URL=/branding/custom.css ``` -`NEXT_PUBLIC_BRAND_FAVICON_URL` and `NEXT_PUBLIC_CUSTOM_CSS_URL` have no organization-level equivalent — these variables are the only way to set a favicon or inject custom CSS. - -### Colors +Favicon and custom CSS have no organization-setting equivalent. Asset URLs reference files; they do not upload them. Custom CSS must be same-origin under the current `style-src` policy, which permits the app origin and Google Fonts rather than configurable external stylesheet hosts. -All colors must be valid hex values. +### Color variables ```bash -NEXT_PUBLIC_BRAND_PRIMARY_COLOR=#701ffc -NEXT_PUBLIC_BRAND_PRIMARY_HOVER_COLOR=#6518e6 -NEXT_PUBLIC_BRAND_ACCENT_COLOR=#9d54ff -NEXT_PUBLIC_BRAND_ACCENT_HOVER_COLOR=#8c3dff -# Not a background: this only tells Sim whether your brand ground is dark, -# which it uses to pick contrasting text. -NEXT_PUBLIC_BRAND_BACKGROUND_COLOR=#0c0c0c +NEXT_PUBLIC_BRAND_PRIMARY_COLOR="#701ffc" +NEXT_PUBLIC_BRAND_PRIMARY_HOVER_COLOR="#6518e6" +NEXT_PUBLIC_BRAND_ACCENT_COLOR="#9d54ff" +NEXT_PUBLIC_BRAND_ACCENT_HOVER_COLOR="#8c3dff" +NEXT_PUBLIC_BRAND_BACKGROUND_COLOR="#0c0c0c" ``` -`NEXT_PUBLIC_BRAND_BACKGROUND_COLOR` likewise has no organization-level equivalent. +`NEXT_PUBLIC_BRAND_BACKGROUND_COLOR` helps choose contrasting text for your brand's background. It does not paint the application background and has no organization equivalent. -### Links +### Link variables ```bash NEXT_PUBLIC_SUPPORT_EMAIL=support@acme.com @@ -150,28 +88,30 @@ NEXT_PUBLIC_TERMS_URL=https://acme.com/terms NEXT_PUBLIC_PRIVACY_URL=https://acme.com/privacy ``` -Setting `NEXT_PUBLIC_BRAND_NAME`, `NEXT_PUBLIC_BRAND_LOGO_URL`, `NEXT_PUBLIC_BRAND_WORDMARK_URL`, or `NEXT_PUBLIC_BRAND_PRIMARY_COLOR` marks the deployment as branded; the remaining variables refine it. +Setting the brand name, logo URL, wordmark URL, or primary color marks the deployment as branded. The other values refine its appearance and links. -### Serving the assets on Kubernetes +### Serve assets on Kubernetes -The `NEXT_PUBLIC_BRAND_*_URL` variables point at files the app serves — they do not upload anything. On the Helm chart, supply those files through the branding ConfigMap, which is mounted into the app container: +The Helm chart can mount branding files into the app's public directory: ```yaml branding: enabled: true - # Serving path for the mounted files mountPath: /app/apps/sim/public/branding - # Text files (CSS, JSON, SVG) as plain text files: - custom.css: | - .sidebar { background-color: #0c0c0c; } wordmark.svg: | Acme - # Binary files (PNG, JPG, ICO) base64-encoded - # base64 -i logo.png | tr -d '\n' binaryFiles: - logo.png: "iVBORw0KGgoAAAANSUhEUgAA..." - favicon.ico: "AAABAAEAEBAAAAEAIABoBAAA..." + logo.png: "" + favicon.ico: "" ``` -With the default `mountPath`, a file named `logo.png` is served at `/branding/logo.png` — the value to give `NEXT_PUBLIC_BRAND_LOGO_URL`. Outside Helm, host the logo, wordmark, and favicon anywhere the browser can reach and point those variables at absolute URLs. `NEXT_PUBLIC_CUSTOM_CSS_URL` is the exception — the CSP's `style-src` takes no configured hosts, so in practice it must be same-origin. +Use plain text for CSS, JSON, or SVG in `files`; use base64 for PNG, JPEG, or ICO in `binaryFiles`. Replace the example binary placeholders with the actual encodings. With the default mount path, `logo.png` is served at `/branding/logo.png`. + +Outside Helm, serve the assets yourself and use URLs reachable by your users' browsers and allowed by your deployment's content security policy. Keep custom CSS same-origin. Verify signed-out login and a public file share separately from the organization's workspace. + +## Related docs + +- [Self-hosted enterprise setup](/platform/enterprise/self-hosted) +- [Kubernetes deployment](/platform/self-hosting/kubernetes) +- [Self-hosting security](/platform/self-hosting/security) diff --git a/apps/docs/content/docs/platform/meta.json b/apps/docs/content/docs/platform/meta.json index 4e7ffeec952..6f64105d4b9 100644 --- a/apps/docs/content/docs/platform/meta.json +++ b/apps/docs/content/docs/platform/meta.json @@ -4,8 +4,8 @@ "workspaces", "organization", "permissions", - "connected-accounts", "credentials", + "connected-accounts", "costs" ] } diff --git a/apps/docs/content/docs/platform/organization.mdx b/apps/docs/content/docs/platform/organization.mdx index 44eac34e676..c139846db4c 100644 --- a/apps/docs/content/docs/platform/organization.mdx +++ b/apps/docs/content/docs/platform/organization.mdx @@ -1,73 +1,58 @@ --- title: Organizing a workspace -description: Folders, colors, and naming conventions for keeping a growing workspace understandable. +description: Group workflows with folders, nesting, ordering, and locks. --- -import { Card, Cards } from 'fumadocs-ui/components/card' +Folders group workflows in the sidebar. Use them to organize a workspace by team, customer, or purpose. -Folders group workflows in the sidebar. Nest or reorder them to organize a [workspace](/platform/workspaces) by team, customer, or purpose. +You need **Write** or **Admin** access to arrange unlocked folders. Only a workspace **Admin** can lock or unlock them. -{/* VISUAL: before/after sidebar. Left: a flat list of ~20 workflows, no grouping. Right: the same workflows under 3-4 top-level color-coded folders ("Internal", "Customer-Facing", "Ops"), some expanded to show nested subfolders. */} +## Name and nest folders -## The parts of a folder +Use category names for folders and action names for workflows. For example: -Here's an example: a folder named **Customer Deployments**, colored red, holding five workflows and two subfolders. +```text +Customer operations + Customer A + Send weekly summary + Check overdue invoices + Customer B + Send weekly summary +Internal + Update support metrics +``` -### Name +Choose **Create folder** from a folder's menu to add a subfolder. Choose **Rename** to change its name. Keep the hierarchy shallow enough that teammates can find a workflow without opening many levels. -Choose category names such as `Internal`, `Customer-Facing`, or `Ops`. Use the same naming convention across your workspace. +## Reorder and move folders -{/* VISUAL: a single sidebar folder row showing the expand chevron, color dot, and name "Customer Deployments". */} +Drag a folder up or down to change its order within a level. Drag it onto another folder to nest it there. Put frequently used folders near the top. -### Color +Folder names, nesting, and order organize navigation. They do not give different members access to different branches of the workspace. -Folder colors appear as dots beside their names and default to gray (`#6B7280`). Change the color from the folder menu. Use color alongside clear names so the grouping is still understandable without color. +## Lock a folder -{/* VISUAL: a short vertical stack of folders with distinct color dots: red "Production", gray "Internal", another color for "Customer-Facing", showing color as the grouping signal. */} +Choose **Lock** from the folder's menu to prevent editing. New folders are unlocked by default. -### Nesting +A folder lock applies to its workflows and subfolders. A child cannot clear a lock inherited from its parent; unlock the parent first. Otherwise authorized workflows can still run while locked. -Nest folders when a category needs subgroups, for example `Production` → `Customer A` → `Deployments`. Keep the hierarchy shallow enough to scan. +Use a lock to prevent accidental changes to production logic. Workspace roles and resource permissions still govern access and execution. -{/* VISUAL: a three-level nested tree: "Production" (red, top level) > "Customer A" (yellow) > "Deployments" (purple), each row indented one step, showing the parent-to-child chain. */} +## Delete and restore a folder -### Order +Deleting a folder also removes its contents from active lists. Check the affected workflows before choosing **Delete** and confirming the deletion. -Folders display in a set **order**, top to bottom, that you control by dragging them in the sidebar. Drag a folder up or down to reorder it within its level, or drag it onto another folder to move it inside as a subfolder. Order is a convention too: put the folders a team touches daily at the top. +Deleted items remain recoverable under **Settings → Recently deleted** until retention cleanup removes them. Restore them there when needed. Recovery is subject to the workspace's effective [data retention policy](/platform/enterprise/data-retention). -### Locking +A locked folder cannot be deleted until its lock is cleared. -A **locked** folder is read-only: its workflows can be viewed but not edited. Locking is off by default. Lock a `Production` folder so members can open and run its workflows without changing them by accident. Locking a folder also locks everything inside it, so a locked parent protects its subfolders and their workflows in one move. Who can lock and unlock follows the workspace [roles and permissions](/platform/permissions). +## Choose folders or another workspace -{/* VISUAL: the folder context menu open on a folder row, showing the options: rename, change color, lock, duplicate, export, new subfolder, delete. */} +Keep work in folders when it shares the same team, access rules, and settings. Create another workspace when it needs its own members, credentials, secrets, or resource ownership—for example, a separate customer project with different collaborators. -### Archiving +Use the same category names across related resources so a table, secret, and workflow are easy to associate. This is a naming convention, not an enforced relationship. -**Archiving** a folder removes it from your active sidebar without deleting it. An archived folder drops out of the normal view, and you restore it when you need it again. Use archiving for cleanup: a finished customer engagement or a retired experiment leaves the sidebar but stays recoverable. There is no permanent hard-delete in the folder menu, so archiving is the safe way to get something out of the way. +## Related docs -## Conventions - -Naming conventions make the structure legible to someone who did not build it. Nothing here is enforced, so the value comes from applying one rule consistently across the workspace. - -- **Group by audience or function at the top level.** A common split is `Internal`, `Customer-Facing`, and `Ops`. Someone new can find the right branch from the top-level names alone. -- **Name folders as categories, workflows as actions.** A folder is a noun (`Billing`); a workflow is a thing it does (`Send overdue reminder`). The folder path plus the workflow name should read as a sentence. -- **Use color for the top level, names for everything below.** Color carries the coarse grouping; names carry the detail. Mixing both at every level turns into noise. -- **Mirror the convention everywhere.** The same category words you use for folders are worth reusing for [tables](/platform/workspaces), [secrets](/platform/credentials), and [integrations](/integrations), so a team learns one vocabulary instead of three. - -## One workspace or several - -Folders organize workflows within a workspace. Use a separate workspace when the work needs its own members, settings, or resource ownership. - -- **Group in folders** when everything belongs to the same team and the same access rules, and you only want it easier to navigate. -- **Split into workspaces** when a set of work needs its own members, its own integrations and secrets, or its own isolation. The classic case is one workspace per customer, where the workspace itself is the deliverable the customer owns. - -See [Workspace fundamentals](/platform/workspaces) for what the boundary scopes and [Roles and permissions](/platform/permissions) for how members and seats work across workspaces. - -## Next - - - - - - - +- [Workspace fundamentals](/platform/workspaces) +- [Roles and permissions](/platform/permissions) diff --git a/apps/docs/content/docs/platform/permissions.mdx b/apps/docs/content/docs/platform/permissions.mdx index 2c8a14342a7..2a9d6ff86c4 100644 --- a/apps/docs/content/docs/platform/permissions.mdx +++ b/apps/docs/content/docs/platform/permissions.mdx @@ -1,258 +1,138 @@ --- title: Roles and permissions -description: How organization, workspace, and credential roles work together — and how they inherit. +description: Understand organization roles, workspace access, credential grants, and invitations. --- -import { Callout } from 'fumadocs-ui/components/callout' -import { Video } from '@/components/ui/video' - -Access in Sim is organized into three nested levels — your **organization**, the **workspaces** inside it, and the **credentials** (connected accounts and secrets) inside those. Each level has its own roles, and roles **inherit downward**: an admin at one level is automatically an admin at the level below. Inheritance only ever *adds* access — it never takes access away from someone who already has it. +Organization roles, workspace roles, and credential grants control different kinds of access. Administrator roles inherit downward, while resource grants and permission groups govern specific credentials and actions. ## How roles inherit -Each level has its own set of roles: - -| Level | Roles | -|-------|-------| -| **Organization** | Owner, Admin, Member | -| **Workspace** | Read, Write, Admin | -| **Credentials** (shared connections and secrets) | Member, Admin | - -Higher roles flow down automatically: - -- An organization **Owner or Admin** is automatically an **Admin of every workspace** in the organization — no per-workspace invite required. -- A workspace **Admin** is automatically an **Admin of every shared credential** in that workspace — OAuth connections, service accounts, and workspace secrets. - -Put together, an organization Owner or Admin can administer every workspace and every shared credential in the organization, top to bottom. - -Inherited roles are **automatic and locked**. In member lists they show greyed out with a short tooltip saying where the role comes from (for example, *"Organization admins are automatically workspace admins"*), and they can't be lowered there — you change them at the level they come from. - - -**Personal secrets are the one exception.** A user's personal environment variables stay private to them and are never shared or inherited — not by workspace Admins, not by organization Owners or Admins, not by anyone. - - -## Workspaces and Organizations - -Sim has two kinds of workspaces: - -- **Personal workspaces** live under your individual account. The number you can create depends on your plan. -- **Shared (organization) workspaces** live under an organization and are available on Team and Enterprise plans. Any organization Owner or Admin can create them. When you invite someone to a shared workspace you choose their **Membership**: **Member** or **Admin** makes them an internal member of the organization — they use a seat, and their own workspaces move in with them (see [Joining an organization](#joining-an-organization)) — while **External** gives them access to the selected workspaces only. Invitees who already belong to another organization always become external, because a Sim account belongs to at most one organization. - -### Workspace Limits by Plan - -| Plan | Personal Workspaces | Shared Workspaces | -|------|---------------------|-------------------| -| **Free** | 1 | — | -| **Pro** | Up to 3 | — | -| **Max** | Up to 10 | — | -| **Team / Enterprise** | — | Unlimited (Owners and Admins) | - -On Team and Enterprise plans, every workspace you create belongs to the organization. Organization Owners and Admins can create unlimited shared workspaces; organization Members cannot create workspaces. Personal workspaces you owned before joining move into the organization when you accept the invite — see [Joining an organization](#joining-an-organization). Enterprise invites require an available seat at invite time; on Team plans, a seat is added automatically when the invitee accepts. +| Level | Roles | What it governs | +| --- | --- | --- | +| Organization | Owner, Admin, Member | Organization membership, settings, billing, and workspace creation | +| Workspace | Read, Write, Admin | Resources and actions inside one workspace | +| Shared credential | Member, Admin | Use and management of an account connection or workspace secret | - - When a Team or Enterprise subscription is cancelled or downgraded, existing shared workspaces stay accessible to current members. New invitations are blocked until the organization is upgraded again. - +An organization **Owner** or **Admin** automatically has **Admin** access to every workspace in that organization. A workspace **Admin** automatically administers its shared credentials: OAuth connections, service accounts, and workspace secrets. -## How to Invite Someone to a Workspace +Inherited roles are locked in member lists. Their tooltip names the source, such as **Workspace owner** or **Organization admins are automatically workspace admins**. Change the role at its source; it cannot be lowered in a child resource's member list. Inheritance adds a role but does not bypass a permission-group restriction on an action. -
- -
+Personal secrets belong to their owner. Workspace and organization Admin roles do not grant access to them. Workflow resolution respects current credential grants; the current Secrets editor manages your own personal values and does not offer personal-secret sharing. -One invite covers everything you give a person at once: enter their emails, select **one or more workspaces**, set the workspace access level, and choose their **Membership**. The same dialog opens from the workspace header and from organization settings. +## Workspace permission levels -Invites to the same person add up rather than stacking. If you invite someone to another workspace while their first invite is still pending, the new workspace is added to that invitation — they get one link that grants everything, and accept once. +| Action | Read | Write | Admin | +| --- | --- | --- | --- | +| View workflows and available execution records | Yes | Yes | Yes | +| Create, edit, or delete unlocked workflows | No | Yes | Yes | +| Run a draft in the workflow builder | No | Yes | Yes | +| Deploy workflows | No | No | Yes | +| Create workspace secrets | No | Yes | Yes | +| Manage an existing workspace secret | With that secret's Admin grant | With that secret's Admin grant | Yes | +| Invite or remove workspace members; manage workspace settings | No | No | Yes | +| Delete the workspace | No | No | Yes | -Because one pending invite can span several workspaces, revoking is scoped to where you do it. Revoking from a workspace's **Teammates** list withdraws that workspace's access only and leaves the rest of the invitation pending; the invitation is cancelled outright when you remove its last workspace. To cancel the whole thing at once, revoke it from organization settings — that needs organization admin, or admin on every workspace the invite covers. +Write and Admin members can collaborate on workflow editing in real time. Credential grants and permission-group controls still apply to the relevant action. Read access to a secret name does not mean its value can be revealed or used. -## Workspace Permission Levels +Authenticated execution of an already deployed workflow through the API has a **Read** workspace-role floor. The API credential must also satisfy the endpoint's credential policy and OAuth scope where applicable. Manual draft execution requires **Write** and a supported human credential. See [API authentication](/api-reference/authentication). -When inviting someone to a workspace, you can assign one of three permission levels: +### Workspace owner -| Permission | What They Can Do | -|------------|------------------| -| **Read** | View workflows, see execution results, but cannot make any changes | -| **Write** | Create and edit workflows, run workflows, manage environment variables | -| **Admin** | Everything Write can do, plus invite/remove users and manage workspace settings | +The workspace owner is an Admin with a fixed role, not another permission tier. Other Admins can manage the workspace and delete it. -## Internal Members vs External Workspace Members +Organization owners and admins cannot be removed through a workspace's member list; change their organization role or membership first. If a removable owner of an organization workspace is removed, ownership transfers to the workspace's protected billing account, normally the organization's owner. That account cannot be removed from the workspace. The owner of a personal workspace cannot remove themselves. -Workspace permissions are separate from organization membership: +## Organization roles -- **Internal organization members** belong to your organization, appear in the organization roster, and count toward your seat total. Invite new teammates this way when they should be part of your company or team in Sim. -- **External workspace members** have access only to the workspaces they are invited to. They are not part of your organization: they do not count toward your seats, their own workspaces stay theirs, and they appear in your roster with an **External** label so admins can always see and revoke their access. Use external access for clients, partners, and contractors. +| Role | Access | +| --- | --- | +| **Owner** | Admin capabilities, plus transferring organization ownership; one owner per organization | +| **Admin** | Manage members and roles, organization settings, billing and seats; inherit Admin access to every organization workspace | +| **Member** | Work in workspaces they are granted; view the member directory when permitted; cannot administer the organization | -You pick between the two with the **Membership** option when sending an invite. Three rules apply: +On billing-enabled deployments, organization owners and admins create shared workspaces under an active team or Enterprise plan. On billing-disabled deployments, organization members may also create them, subject to deployment settings and permission-group restrictions. -- **External is only available for people already on a paid Sim plan** — their own Pro or Max subscription, or membership in another organization that seats them. External collaborators do not use one of your seats, so they have to be paying for Sim somewhere else. Inviting someone on the free plan as External is rejected with a message telling you to invite them as a Member or Admin instead, which adds a seat. -- **Invitees who already belong to another organization are always external**, whatever you pick, because an account belongs to at most one organization. -- **Inviting someone as a Member to the organization itself always includes access to at least one workspace**, so every new member has somewhere to land. +## Invite someone to a workspace -Invitees see what they are agreeing to before they accept. The accept screen names every workspace they are being given, says whether they are joining as a member, an admin, or an external collaborator, says whether that uses one of your seats, and names any of their own workspaces that will move into the organization. +Open **Invite teammates** from the workspace header. For an organization workspace: -External workspace members still receive a workspace permission level — Read, Write, or Admin — and that permission controls what they can do inside the workspace. +1. Enter the **Emails** to invite. +2. Select one or more **Workspaces**. +3. Choose **Workspace access**: **Read**, **Write**, or **Admin**. +4. Choose **Organization membership**: **Member**, **Admin**, or **External**. +5. Send the invitation. -## Joining an organization - -Accepting an invite that makes you an **internal member** does more than grant access — it brings your work under the organization: - -- **Your workspaces move with you.** Every personal workspace you own, archived ones included, becomes an organization workspace. The accept screen names the workspaces that will move before you accept. -- **You keep Admin on them.** You remain their administrator; organization Owners and Admins also gain Admin access through the normal [role inheritance](#how-roles-inherit), and usage in those workspaces is billed to the organization from then on. -- **Your collaborators are not pulled in.** Anyone you had shared those workspaces with keeps their access as an **external member** — they never join the organization or consume a seat as a side effect of your joining. -- **The workspaces stay if you leave.** If you later leave or are removed from the organization, workspaces you brought in remain with the organization. - -Accepting an **external** invite changes none of this: you get access to the invited workspace only, and everything you own stays yours. +Only an organization owner or admin can grant organization Admin membership. A workspace Admin can grant workspace access without gaining organization billing authority. -## What Each Permission Level Can Do +For an internal builder, choose Member with Write workspace access. For an external stakeholder who only needs visibility, choose External with Read access, subject to the eligibility rules below. -Here's a detailed breakdown of what users can do with each permission level: +### Invite someone to the organization -### Read Permission +An organization-only invitation uses **Emails** and **Role**. It grants membership without selecting workspaces. Organization Members need a workspace grant to work there; Owners and Admins inherit workspace Admin access. -**What they can do:** -- View all workflows in the workspace -- See workflow execution results and logs -- Browse workflow configurations and settings -- View environment variables (but not edit them) +A Sim account can belong to at most one organization. An organization-only invitation to someone in another organization is rejected until they leave it. A workspace invitation can instead give them external access. -**What they cannot do:** -- Create, edit, or delete workflows -- Run or deploy workflows -- Change any workspace settings -- Invite other users +### Pending invitations and revocation -### Write Permission +Pending workspace invitations to the same person can combine selected workspaces into one invitation link. They accept the combined grants once. -**What they can do:** -- Everything Read users can do, plus: -- Create, edit, and delete workflows -- Run workflows -- Add, edit, and delete workspace environment variables -- Use all available tools and integrations -- Collaborate in real-time on workflow editing +Revoking from a workspace's **Teammates** list withdraws only that workspace's grant. Other grants remain pending; removing the last one cancels the invitation. Revoking from organization settings cancels the whole invitation and requires organization admin authority or Admin access to every workspace it covers. -**What they cannot do:** -- Invite or remove users from the workspace -- Change workspace settings -- Delete the workspace +## Internal and external membership -### Admin Permission +**Internal members** belong to the organization and use seats on billing-enabled team plans. **External collaborators** have only the selected workspace grants. They do not join your organization, use one of its seats, or bring their own workspaces into it. They appear in the roster with an **External** label and still have Read, Write, or Admin workspace access. -**What they can do:** -- Everything Write users can do, plus: -- Deploy workflows -- Invite new users to the workspace with any permission level -- Remove users from the workspace -- Manage workspace settings and integrations -- Administer every shared credential in the workspace (OAuth connections, service accounts, and workspace secrets) -- Delete workflows created by other users -- Delete the workspace - -**What they cannot do:** -- Change a role that's inherited from a higher level — an organization admin's workspace role, or the owner's, is locked and managed where it comes from - ---- +On Sim Cloud and other billing-enabled deployments: -## Workspace Owner +- An external collaborator must already have paid Sim access through their own Pro or Max plan or membership in another paid organization. Otherwise, invite them as Member or Admin to add a seat. +- Someone already in another organization joins an invited workspace as external, rather than becoming an internal member of a second organization. +- Enterprise invitations require available fixed seat capacity. Team plans add a seat when a new internal member accepts. +- Inviting from a paid personal workspace can create an organization and convert the subscription to its team tier when the invitation is accepted. +- Existing shared workspaces remain accessible to current members after the organization plan lapses. New invitations are blocked until an eligible plan is restored. -Every workspace has one **Owner** — usually the person who created it. The Owner is simply an Admin whose role is fixed: in the member list it shows as a locked **Admin** (tooltip *"Workspace owner"*), so it can't be lowered. An Owner has no abilities a regular Admin lacks. +Billing-disabled deployments do not require paid external access or paid seats. Workspace and organization authorization still applies. -Any Admin — whether invited directly or an admin by way of their organization role — can manage members and settings and delete the workspace. On a shared workspace an Admin can also remove the Owner; ownership then passes to the organization's owner, so the workspace always has one. (The organization's owner is the one account that can't be removed this way — they're the final fallback.) On your personal workspace you are the Owner and can't be removed. +See [Credits, billing and limits](/platform/costs) for credit pooling, spend controls, and current plan limits. ---- - -## Common Scenarios +## Joining an organization -### Adding a New Developer to Your Team -1. **Organization level**: Invite them as an **Organization Member** -2. **Workspace level**: Give them **Write** permission so they can create and edit workflows +The acceptance screen names the granted workspaces, membership role, seat consequence, and personal workspaces that will move. Review these before accepting an internal invitation: -### Adding a Project Manager -1. **Organization level**: Invite them as an **Organization Member** -2. **Workspace level**: Give them **Admin** permission so they can manage the team and see everything +- Every personal workspace you own moves into the organization, including archived workspaces. +- You keep Admin access to those workspaces. Organization Owners and Admins also gain Admin access through inheritance. +- Usage in the moved workspaces is attributed to the organization. +- Existing collaborators keep their workspace access as external collaborators; they do not join the organization or consume a seat as a side effect. +- The moved workspaces remain with the organization if you later leave or are removed. -### Adding a Stakeholder or Client -1. **Membership**: If they should not join your organization, set Membership to **External** — this needs them to already be on a paid Sim plan, since external collaborators do not use one of your seats -2. **Workspace level**: Give them **Read** permission so they can see progress but not make changes +An external invitation grants only the invited workspace access. Your owned workspaces stay where they are. ---- +### Removal and credential effects -## Environment Variables +Removing an internal organization member revokes their organization workspace access and reassigns their workflows so deployed work can continue. Workspaces they brought into the organization remain there. -Users can create two types of environment variables: +Credentials backed by their personal identity, such as OAuth accounts and their personal environment keys, can stop resolving in those workspaces. The removal dialog identifies affected credentials before confirmation. Reconnect affected accounts with a remaining member, and move production secrets to workspace scope with appropriate grants. -### Personal Environment Variables -- Only visible to the individual user, and never shared or inherited — not even by workspace or organization admins -- Available in all workflows they run -- Managed in **Settings**, then go to **Secrets** +Removing a member's last organization workspace grant can also remove their organization membership and seat. Organization owners and admins retain inherited workspace access until their organization role or membership changes. -### Workspace Environment Variables -- **Read**: see variable names (the values stay hidden unless you're an admin of that secret) -- **Write**: add new variables, and edit or delete ones you created -- **Admin**: add, edit, delete, and view the values of any workspace variable -- Workspace variables are a kind of workspace credential, so they follow the [Credential Access](#credential-access) rules below — workspace Admins are admins of all of them -- Available to all workspace members. If a workspace variable and a personal variable share the same name, the **workspace** value wins when a workflow runs +## Credential access ---- +Shared OAuth connections, service accounts, and workspace secrets have two credential roles: -## Credential Access +| Role | Access | +| --- | --- | +| **Member** | Use the credential in authorized workflows | +| **Admin** | Use, edit, delete, and share the credential | -Workspace credentials — OAuth connections, service accounts, and workspace environment variables — have two roles of their own: +Creators administer their credentials. Workspace Admins inherit Admin access to every shared credential; those inherited roles cannot be demoted in the credential's member list. Read and Write workspace members need an active credential grant to use a shared credential. Pending or revoked grants do not authorize use. -- **Credential Member**: can use the credential in workflows. -- **Credential Admin**: can use it and also edit, delete, and share it. +For workspace secrets, Admin authority also allows revealing the value. A Credential Member can reveal it only when **Show value in logs and Chat** is enabled. Personal secrets do not inherit workspace Admin access. Among values the execution actor may use, a workspace secret takes precedence over a personal secret with the same name; an inaccessible workspace value does not shadow an authorized personal value. -These roles follow your workspace role: +See [Secrets](/platform/credentials) for management, runtime identity, and disclosure controls. [Credential Groups](/platform/connected-accounts) use separate organization account-pool grants. -- **Workspace Admins are automatically Credential Admins** of every shared credential in the workspace (OAuth connections, service accounts, and workspace environment variables). Because organization Owners and Admins are workspace Admins everywhere, they are Credential Admins too. These automatic roles are fixed — they show greyed out with a tooltip in the credential's member list and cannot be changed. -- **Read and Write members need an active credential grant** to use a shared credential. Credential Members have use access; Credential Admins can also edit, delete, and share it. You are an admin of credentials you create. -- **Personal environment variables** are the exception: they stay private to their owner and are never shared with workspace admins. +## Permission groups - - A Credential Admin can both use and manage a credential, so a workspace Admin can run workflows that use any shared OAuth connection in the workspace — including one another member added. - +Enterprise-entitled organizations can restrict model providers, integrations, individual tools, deployments, invitations, and other platform actions with [permission groups](/platform/enterprise/access-control). A group restricts access; it does not grant workspace membership or a credential role. ---- +Sim chooses one governing group for a person in each workspace: an explicit member group first, then an empty inheritance-mode group for that workspace, then the organization default. An empty explicit-membership group, including a SCIM-managed group, governs nobody. Removing the last member of an inheritance-mode group can broaden it to all workspace members. -## Organization Roles - -An organization has three roles: **Owner**, **Admin**, and **Member**. - -### Organization Owner -**What they can do:** -- Everything an Admin can do -- Transfer organization ownership to another user -- Only one Owner exists per organization - -### Organization Admin -**What they can do:** -- Invite and remove team members from the organization -- Create new shared workspaces under the organization -- Manage billing, seat count, and subscription settings -- Access every shared workspace in the organization as a workspace Admin automatically (no per-workspace invite), including administering the credentials inside them -- Promote members to Admin or demote Admins to Member - - - Owners and Admins have the same day-to-day permissions. The only action reserved for the Owner is transferring ownership. - - -### Organization Member -**What they can do:** -- Access shared workspaces they've been specifically invited to -- View the list of organization members -- Cannot invite new people, create shared workspaces, or manage organization settings - -import { FAQ } from '@/components/ui/faq' - - +These restrictions govern human principals, including personal API keys and OAuth credentials, in the resource's owning workspace. A workspace API key has no user's group; it follows its workspace scope, allowed endpoint policies, and role ceiling. Creating or managing that key remains an authorized action. diff --git a/apps/docs/content/docs/platform/self-hosting/architecture.mdx b/apps/docs/content/docs/platform/self-hosting/architecture.mdx index 7002b69976d..6d2eb34ba1f 100644 --- a/apps/docs/content/docs/platform/self-hosting/architecture.mdx +++ b/apps/docs/content/docs/platform/self-hosting/architecture.mdx @@ -1,112 +1,116 @@ --- title: Architecture -description: Every service Sim runs, what it depends on, and where state lives +description: Services, dependencies, request paths, and durable state in a self-hosted deployment --- import { Callout } from 'fumadocs-ui/components/callout' -import { FAQ } from '@/components/ui/faq' -Understanding what runs where makes every other operational decision — scaling, backup, network policy, upgrades — straightforward. +Sim runs an app, a realtime server, PostgreSQL, Redis, and a scheduler. This page shows their dependencies and the state you need to preserve. ## Services -| Service | Image | Port | Stateless | Required | +| Service | Image | Port | State | Required | |---|---|---|---|---| -| **app** | `ghcr.io/simstudioai/simstudio` | 3000 | Only with object storage configured | Yes | -| **realtime** | `ghcr.io/simstudioai/realtime` | 3002 | Yes | Yes | -| **migrations** | `ghcr.io/simstudioai/migrations` | — | Yes (runs once) | Yes | -| **postgresql** | `pgvector/pgvector:pg17` | 5432 | **No** | Yes | -| **redis** | `redis:7-alpine` | 6379 | Mostly | Yes past one replica; bundled by default | -| **cron** | `ghcr.io/simstudioai/cron` (Compose) / `curlimages/curl` (CronJobs) | — | Yes | Yes, unless you disable scheduled jobs | -| **pii** | `ghcr.io/simstudioai/pii` | 5001 | Yes | Optional | -| **ollama** | `ollama/ollama` | 11434 | **No** (model cache) | Optional | -| **telemetry** | `otel/opentelemetry-collector-contrib` | 4317/4318 | Yes | Optional | +| **app** | `ghcr.io/simstudioai/simstudio` | 3000 | Local uploads unless shared storage is configured | Yes | +| **realtime** | `ghcr.io/simstudioai/realtime` | 3002 | In-flight collaboration state | Yes | +| **migrations** | `ghcr.io/simstudioai/migrations` | — | One-shot schema and data migrations | Yes | +| **postgresql** | `pgvector/pgvector:pg17` | 5432 | Durable application data | Yes | +| **redis** | `redis:7-alpine` | 6379 | Cache, coordination, and live events | Bundled by default; required across replicas | +| **cron** | `ghcr.io/simstudioai/cron` (Compose) / `curlimages/curl` (Kubernetes) | — | None | Required for scheduled work | +| **pii** | `ghcr.io/simstudioai/pii` | 5001 | None | Optional | +| **ollama** | `ollama/ollama` | 11434 | Model cache | Optional | +| **telemetry** | `otel/opentelemetry-collector-contrib` | 4317/4318 | None | Optional | -### app +### App -The Next.js application: the editor UI, every API route, and the workflow execution engine. Workflow runs happen **inside the app process** by default, using an isolated-vm sandbox, which is why memory rather than CPU is the constraining resource. The chart requests 4 Gi and caps the app at 8 Gi; `docker-compose.prod.yml` sets only an 8 GB limit, with no reservation. Configuring a remote sandbox provider (E2B or Daytona) moves code execution out of the process; see [Security](/platform/self-hosting/security). +The Next.js app serves the workflow builder, API routes, and workflow orchestration. Local JavaScript runs in Node child workers using isolated-vm inside the app container. The app and those workers share the container's memory budget. The Helm chart requests 4 GiB and limits the app to 8 GiB; `docker-compose.prod.yml` sets an 8 GB memory limit without a reservation. -Any replica can serve any request **once object storage is configured**. Until then the app writes uploads to its own container filesystem, which makes it stateful — see [Where state lives](#where-state-lives). Scale it horizontally only after reading [Scaling & HA](/platform/self-hosting/scaling) for the Redis, storage, and connection-pool prerequisites. +E2B or Daytona moves supported code execution to a remote sandbox. `TRIGGER_DEV_ENABLED` routes asynchronous jobs to Trigger.dev; the default deployment uses database-backed jobs. See [Sandboxes](/platform/self-hosting/sandboxes) for the provider and image requirements. -### realtime +Any replica can serve files once shared object storage is configured. Before adding replicas, configure storage, Redis, and database connection capacity as described in [Scaling and high availability](/platform/self-hosting/scaling). -A Bun Socket.IO server handling collaborative editing, live execution updates, and collaborative documents. Clients connect at `/socket.io`. +### Realtime -It shares the database and `BETTER_AUTH_SECRET` with the app (Better Auth's shared-database-session pattern), so it authenticates the same users without a separate login. +The Bun Socket.IO server carries collaborative editing, live execution updates, and collaborative documents. Clients connect at `/socket.io`. + +Realtime shares PostgreSQL and `BETTER_AUTH_SECRET` with the app, using Better Auth's shared-database-session pattern. It authenticates the same accounts without a separate login. - Scaling realtime past one replica **requires** `REDIS_URL` — the Socket.IO Redis adapter is what carries events between pods. Without it, two users on different pods silently stop seeing each other's edits. + More than one realtime replica requires `REDIS_URL`. The Socket.IO Redis adapter carries events between replicas; without it, members connected to different pods do not see each other's edits. -### migrations +A realtime server must exist for editing and live updates. Set `realtime.enabled: false` in Helm only when `app.env.SOCKET_SERVER_URL` points to a realtime instance you run separately. -Applies Drizzle schema migrations, then exits. In Docker Compose it is a one-shot service; in Kubernetes it is an **init container on the app Deployment**, so migrations run before any app pod becomes ready and re-run (as a no-op) on every rollout. +### Migrations -Migrations are forward-only. See [Upgrades](/platform/self-hosting/upgrades). +The migrator applies Drizzle SQL and registered data migrations, then exits. Compose runs it as a one-shot service. Helm runs it as an app init container, so migrations complete before that app pod starts. Later pods and rollouts run the migrator again; already-applied migrations are skipped. -### postgresql +Migrations are forward-only. See [Upgrades](/platform/self-hosting/upgrades) for backup and rollback procedures. -PostgreSQL 17 with the **pgvector** extension, which is required — knowledge base embeddings are stored and searched as vectors. The `pgvector/pgvector:pg17` image ships it; a managed instance needs the extension enabled (Sim's migrations issue `CREATE EXTENSION` automatically where permissions allow). +### PostgreSQL -This holds essentially all durable state: workflows, runs, logs, users, organizations, credentials, knowledge base chunks and embeddings, and table data. +Sim requires PostgreSQL with the pgvector extension for knowledge base embeddings. The bundled image uses PostgreSQL 17 and includes pgvector. On managed PostgreSQL, make the extension available; migrations issue `CREATE EXTENSION` where permissions allow. -### redis +PostgreSQL holds workflows, runs, logs, accounts, organizations, credentials, knowledge base chunks and embeddings, table data, and upload-session state. -Backs pub/sub, the Socket.IO adapter, the idempotency store, execution progress markers, distributed execution limits, and the CLI-auth approval store. The idempotency store and execution progress markers fall back to Postgres or in-process state. The pairing-code approval store has no fallback, so API-key login through pairing requires Redis. OAuth login uses a separate path. Pub/sub falls back to a **process-local** emitter, which is fine on one replica and drops every cross-pod event on more than one. See [Redis](/platform/self-hosting/redis). +### Redis -### cron +Redis carries live events and stores shared coordination state. Some stores fall back to PostgreSQL or process-local state, but cross-pod collaboration has no local fallback. CLI API-key pairing also requires Redis, even with one replica; OAuth login uses a separate path. See [Redis](/platform/self-hosting/redis) for the full fallback matrix. -Scheduled jobs call internal endpoints — schedule execution, polling triggers, webhook-subscription renewal, connector syncs, outbox processing, data drains, workspace file-search dispatch, table row TTL cleanup, inbox-entitlement reconciliation, and sandbox-image cleanup. Kubernetes runs them as CronJobs; Docker Compose runs them from a single supercronic service. Same paths, same schedules. See [Background Jobs](/platform/self-hosting/background-jobs). +### Scheduler -## Where state lives +Scheduled workflows, polling triggers, connector syncs, subscription renewal, and maintenance jobs call authenticated app endpoints. Helm provides CronJobs; Compose provides a supercronic service. See [Background jobs](/platform/self-hosting/background-jobs) for the shipped inventory and the additional upload-session cleanup schedule operators must configure. + +### Optional Chat service -Three places once the deployment is configured for production. Everything else is disposable. +The chart can also render the optional `copilot` service, its separate PostgreSQL database, and its migration job. These are separate from the app and workflow database. Enabling them requires the service's image, license, credentials, and database configuration; see the chart's `copilot` values and [reference architectures](/platform/self-hosting/reference-architectures). + +## Where state lives | Store | Contents | Backup | |---|---|---| -| **PostgreSQL** | All application data | `pg_dump` / managed snapshots + PITR | -| **Object storage** | Uploaded files, KB documents, execution outputs, avatars, logos | Bucket versioning + lifecycle | -| **Secrets** | `ENCRYPTION_KEY`, `API_ENCRYPTION_KEY`, `BETTER_AUTH_SECRET`, `INTERNAL_API_SECRET`, `CRON_SECRET` | Secret manager | +| **PostgreSQL** | Application data, including any separately enabled Chat-service database | `pg_dump`, managed snapshots, and point-in-time recovery | +| **Object storage** | Files, knowledge base documents, execution outputs, avatars, and logos | Bucket versioning and lifecycle policies | +| **Secrets** | `ENCRYPTION_KEY`, `API_ENCRYPTION_KEY`, `BETTER_AUTH_SECRET`, `INTERNAL_API_SECRET`, `CRON_SECRET` | Secret manager and separate recovery copies | - **Object storage is not configured by default, and the fallback is not durable.** Sim only uses S3, Azure Blob, or GCS when the corresponding variables are set (`S3_BUCKET_NAME` + `AWS_REGION`, `AZURE_STORAGE_CONTAINER_NAME` + credentials, or `GCS_BUCKET_NAME`). With none set it writes uploads to a directory inside the app container — and neither `docker-compose.prod.yml` nor the Helm chart mounts a volume there. Files are lost when the container is recreated and are invisible to other replicas. Configure [object storage](/platform/self-hosting/object-storage) before storing anything you care about, and before scaling past one replica. + Neither the production Compose file nor the Helm chart mounts a volume for local uploads. Without configured cloud storage or your own volume, recreating the app container loses those files. Local files are also invisible to other replicas. Configure [object storage](/platform/self-hosting/object-storage) before storing durable files or scaling. - `ENCRYPTION_KEY` is not recoverable and not derivable. It encrypts workspace and personal environment variables, stored provider API keys, MCP OAuth credentials, and deployment/chat secrets at rest — a database restore paired with a *different* key yields a working app in which none of that can be decrypted. Back it up separately from the database, and never rotate it casually. + Back up `ENCRYPTION_KEY` separately from PostgreSQL. A database restore with a different key cannot decrypt workspace and personal environment variables, stored provider keys, MCP OAuth credentials, or deployment/chat secrets. Recovery requires the original key or re-encryption before rotation. -Redis is a cache and message bus. Losing it drops in-flight live updates; it does not lose committed data. +Redis is a cache and message bus, not the owner of committed application data. Losing it interrupts in-flight coordination and live updates; completed data remains in PostgreSQL and object storage. ## Request paths -**Editor / API** — browser → ingress/reverse proxy → app:3000 → Postgres, Redis, object storage. - -**Collaboration** — browser → ingress → realtime:3002 (`/socket.io`, WebSocket upgrade) → Redis pub/sub → other realtime pods. The proxy must pass upgrade headers and allow long-lived idle connections; see [Networking](/platform/self-hosting/networking). +| Traffic | Path | +|---|---| +| Editor / API | Browser → ingress or reverse proxy → app:3000 → PostgreSQL, Redis, storage | +| Collaboration | Browser → ingress → realtime:3002 (`/socket.io`, WebSocket upgrade) → Redis → other realtime pods | +| Cloud upload | Browser → app opens upload session → signed transfer instructions → browser uploads directly to storage → app verifies completion and records metadata | +| Local upload | Browser → app opens upload session → bytes stream through `/api/v2/uploads/...` to local disk | +| Workflow execution | Manual, API, webhook, or schedule trigger → app enqueues or orchestrates run → local code workers or remote sandbox → results/logs to PostgreSQL, progress markers to Redis | +| Background work | Scheduler → `Authorization: Bearer $CRON_SECRET` → internal app endpoint | -**File upload (object storage configured)** — browser asks the app to open an upload session → app returns signed transfer instructions → browser sends the bytes **directly to object storage** (one `PUT` up to 50 MB, multipart parts above that) → browser tells the app the session is complete and the app records metadata. This is why buckets need a CORS policy naming your Sim origin. Downloads are proxied back through the app. - -**File upload (local disk)** — the same upload session opens, but the transfer instructions point back at the app's own `/api/v2/uploads/...` endpoints instead of a bucket, so the bytes stream through the app. No CORS configuration is involved, and no bucket is used. - -**Workflow execution** — trigger (manual, API, webhook, or schedule) → app enqueues or runs inline → isolated-vm sandbox → results and logs to Postgres, progress markers to Redis. - -**Background work** — CronJob → `Authorization: Bearer $CRON_SECRET` → app endpoint → same execution path. +Cloud uploads use a single `PUT` through 50 MiB and multipart above that. Local uploads use a single `PUT` through 8 MiB and multipart above that. Cloud buckets need CORS for the Sim origin and must be reachable from browsers; downloads are proxied through the app. Local uploads need no bucket CORS configuration. ## Network boundaries | From | To | Purpose | |---|---|---| -| Internet | app:3000, realtime:3002 | Users | -| app, realtime | postgresql:5432 | Data | -| app, realtime | redis:6379 | Pub/sub, cache | -| app | Object storage endpoint | Files (server side) | -| **Browser** | **Object storage endpoint** | Presigned uploads — must be publicly reachable | -| app | Model provider APIs, integration APIs, SMTP/email provider | Outbound | -| cron | app:3000 (internal Service / compose network) | Scheduled triggers | - -The chart's optional NetworkPolicy blocks cloud metadata endpoints (`169.254.169.254`) by default but allows ingress from any pod in the cluster unless you scope `networkPolicy.ingressFrom`. See [Security](/platform/self-hosting/security). - - +| Internet | app:3000, realtime:3002 | Browser/API traffic | +| App, realtime | PostgreSQL:5432, Redis:6379 | Data and coordination | +| App | Object-storage endpoint | Storage operations and proxied downloads | +| Browser | Object-storage endpoint | Signed uploads | +| App | Model/integration APIs and email provider | Outbound calls | +| Scheduler | Internal app:3000 | Scheduled work | + +The proxy must support WebSocket upgrades, streams, and long-lived connections. The chart's optional NetworkPolicy excludes cloud metadata addresses from broad egress, but its default ingress peer is broad. Configure the actual peers and managed-datastore paths before enabling it. + +## Related docs + +- [Reference architectures](/platform/self-hosting/reference-architectures) +- [Networking](/platform/self-hosting/networking) +- [Security and hardening](/platform/self-hosting/security) diff --git a/apps/docs/content/docs/platform/self-hosting/authentication.mdx b/apps/docs/content/docs/platform/self-hosting/authentication.mdx index c47590f6750..0303f0e92ff 100644 --- a/apps/docs/content/docs/platform/self-hosting/authentication.mdx +++ b/apps/docs/content/docs/platform/self-hosting/authentication.mdx @@ -1,25 +1,27 @@ --- title: Authentication -description: Login providers, SSO, and controlling who can sign up +description: Configure sign-in, registration, SSO, and Sim OAuth access --- import { Callout } from 'fumadocs-ui/components/callout' +Configure the deployment's public origin and shared session secret before choosing login providers or restricting registration. + ## Required configuration -```bash +```text BETTER_AUTH_SECRET= BETTER_AUTH_URL=https://sim.yourdomain.com NEXT_PUBLIC_APP_URL=https://sim.yourdomain.com ``` - - `BETTER_AUTH_URL` and `NEXT_PUBLIC_APP_URL` must be your exact public origin — correct scheme, no trailing slash. Leaving either as `localhost` in a deployed instance breaks sign-in, and the failure looks like a redirect loop rather than a configuration error. +Replace the secret placeholder with the output of `openssl rand -hex 32`. Use your exact public origin, including scheme, with no trailing slash. Production Compose derives `BETTER_AUTH_URL` from `NEXT_PUBLIC_APP_URL`; see [Docker](/platform/self-hosting/docker). - `BETTER_AUTH_SECRET` must be **identical** on the app and realtime services. They share sessions through the database; a mismatch means realtime rejects every authenticated socket connection. + + The app and realtime services must use the same `BETTER_AUTH_SECRET`. They share database sessions; a mismatch prevents authenticated socket connections. An incorrect public origin can cause rejected sign-in or redirect loops. -If users reach Sim from more than one origin — an apex and `www`, or an alias domain — list the extras: +If the deployment serves additional origins, list them explicitly: ```bash TRUSTED_ORIGINS=https://www.example.com,https://app.example.com @@ -27,27 +29,27 @@ TRUSTED_ORIGINS=https://www.example.com,https://app.example.com ## Email and password -Enabled by default. Users sign up with an email address and password. +Email/password sign-in and signup are enabled by default. To require email verification: ```bash EMAIL_VERIFICATION_ENABLED=true ``` -Requires a configured email provider — see [Email](/platform/self-hosting/email). Without one the mailer no-ops silently, so users can never verify and never sign in. Do not enable this before email works. +Verification is enforced only when a mail provider is configured. Test [email delivery](/platform/self-hosting/email) before requiring verification: a configured provider that cannot deliver still prevents new accounts from completing verification. Without a provider, verification is not enforced and invitations and password-reset mail are not delivered. ## Social login -Three providers are supported for signing in to Sim itself. +These providers sign members in to Sim itself. Integration account connections use separate callback paths. -| Provider | Variables | Callback URL | -|---|---|---| +| Provider | Variables | Login callback | +| --- | --- | --- | | Google | `GOOGLE_CLIENT_ID` / `GOOGLE_CLIENT_SECRET` | `https:///api/auth/callback/google` | | GitHub | `GITHUB_CLIENT_ID` / `GITHUB_CLIENT_SECRET` | `https:///api/auth/callback/github` | | Microsoft | `MICROSOFT_CLIENT_ID` / `MICROSOFT_CLIENT_SECRET` | `https:///api/auth/callback/microsoft` | -A provider appears on the login page once its credentials are set. Microsoft additionally requires both variables to be present before it is registered at all. +Set both credentials to make a provider available on the login page. Microsoft is registered only when both values are present. -Turn one off without removing its credentials — useful when the same Google or Microsoft app powers integrations but you do not want it as a login method: +To keep credentials for integrations while disabling the corresponding login method: ```bash DISABLE_GOOGLE_AUTH=true @@ -55,65 +57,82 @@ DISABLE_GITHUB_AUTH=true DISABLE_MICROSOFT_AUTH=true ``` - - `GOOGLE_CLIENT_ID` and `MICROSOFT_CLIENT_ID` are shared with the integration connectors. One app registration can serve both login and integrations — register that provider's own login callback — `/api/auth/callback/google` for Google, `/api/auth/callback/microsoft` for Microsoft — alongside the connector callbacks (`/api/auth/oauth2/callback/google-email` and friends) on the same OAuth client. See [Integrations & OAuth](/platform/self-hosting/integrations-oauth). +Google and Microsoft share their client credentials with integrations. Register their login callback alongside the integration callbacks on the same client; see [Integrations and OAuth](/platform/self-hosting/integrations-oauth). + +## Control registration and sign-in [#controlling-who-can-sign-up] + +| Variable | Effect | +| --- | --- | +| `DISABLE_REGISTRATION=true` | Blocks new email/password, email OTP, and social accounts. Existing accounts can sign in, including to accept workspace invitations. SSO registration is unaffected. | +| `DISABLE_EMAIL_SIGNUP=true` | Blocks new email/password and email OTP registrations. Existing accounts can still sign in through those methods. | +| `EMAIL_PASSWORD_SIGNUP_ENABLED=false` | Disables email/password and email OTP sign-in and signup, including for existing accounts. | +| `ALLOWED_LOGIN_DOMAINS` | Comma-separated email domain allowlist, such as `acme.com,acme.co.uk`. Applies to email/password and email OTP sign-in as well as email signup. | +| `ALLOWED_LOGIN_EMAILS` | Comma-separated address allowlist. An address or its domain may satisfy the allowlists. | +| `BLOCKED_SIGNUP_DOMAINS` | Comma-separated blocked domains. Blocks signup, sign-in, and executions for addresses in those domains, including subdomains. | +| `BLOCKED_EMAILS` | Comma-separated banned addresses. Blocks signup, sign-in, and executions. | +| `SIGNUP_MX_VALIDATION_ENABLED=true` | Checks email/password signup for a domain with no MX record or a blocked mail backend. | +| `BLOCKED_EMAIL_MX_HOSTS` | MX-host substrings to reject when MX validation is enabled. | + + + Email allowlists do not filter first-time Google, GitHub, or Microsoft sign-in. To restrict social access, disable login providers you have not vetted or restrict membership through your identity provider and use SSO. MX validation applies only to email/password signup, not sign-in or email OTP. Registration-disabled and blocked-domain/address controls also cover social accounts. +For example, an installation using SSO while allowing existing company email accounts to sign in can set: + +```bash +ALLOWED_LOGIN_DOMAINS=acme.com +DISABLE_EMAIL_SIGNUP=true +SSO_ENABLED=true +NEXT_PUBLIC_SSO_ENABLED=true +``` + +This does not restrict enabled social providers to `acme.com`. Configure or disable those login methods separately. + ## SSO (SAML and OIDC) -SAML and OIDC single sign-on is an enterprise feature, available on self-hosted deployments through configuration rather than billing: +For a standard billing-disabled self-hosted deployment, enable the enterprise suite: ```bash ENTERPRISE_ENABLED=true NEXT_PUBLIC_ENTERPRISE_ENABLED=true ``` -Or enable just SSO: +Or enable SSO alone: ```bash SSO_ENABLED=true NEXT_PUBLIC_SSO_ENABLED=true ``` -Providers are then registered in the app under **Settings → Organization → SSO**. A provider can be scoped to an organization or registered without one. Most other enterprise features do read their settings from the organization that owns a workspace, so a deployment using them still needs an organization model — set `INSTANCE_ORG_NAME` to place every user in one shared organization, or provision organizations through the Admin API. +Set both the server flag and its UI counterpart. Register providers under **Settings → Organization → Single sign-on**. A provider can belong to an organization or be registered without one. + +Most other enterprise features read settings from the organization that owns a workspace. Set `INSTANCE_ORG_NAME` to place new members in one organization, or provision organizations through the Admin API. See [SSO](/platform/enterprise/sso) and [Self-hosted enterprise features](/platform/enterprise/self-hosted) for provider setup, organization patterns, and billing-enabled behavior. + +## Behind a load balancer + +Tell Better Auth which forwarding hops to trust when resolving client IPs: + +```bash +AUTH_TRUSTED_PROXIES=10.0.0.0/24,192.0.2.10 +``` -See the [SSO guide](/platform/enterprise/sso) for identity-provider setup and the [self-hosted enterprise guide](/platform/enterprise/self-hosted) for the organization patterns. +Use your proxy addresses or CIDRs. Better Auth reads `X-Forwarded-For` from right to left, skips trusted proxies, and uses the first untrusted address for session records and IP checks. A range that also trusts client traffic defeats this boundary. See [Security](/platform/self-hosting/security). ## Sign in with Sim -Your deployment acts as an OAuth 2.0 authorization server using authorization -code with PKCE. OAuth sign-in is available whenever authentication is enabled; -see [CLI authentication](/cli/authentication). +Sim also acts as an OAuth 2.0 authorization server, using authorization code with PKCE. It supports API authorization rather than OpenID Connect identity: it does not issue ID tokens. See [CLI authentication](/cli/authentication). -Apply database migrations before deploying a new app version. When upgrading -from a version without the OAuth token-family lifecycle, drain older app -instances before accepting OAuth traffic so every instance enforces the same -refresh and revocation rules. +Access tokens are opaque and last one hour. Refresh tokens rotate on use, and each login has a fixed thirty-day lifetime that refresh does not extend. Validation checks current grants: revoking access under **Settings → General → Authorized apps** stops the app on its next request. Scheduled token cleanup runs independently of sign-in activity. -`DISABLE_AUTH=true` disables OAuth sign-in and discovery because authorization -requires a real Better Auth user session. Older servers without OAuth support -return 404 from `/.well-known/oauth-authorization-server`, and the CLI falls -back to the pairing-code handoff. +`DISABLE_AUTH=true` disables OAuth sign-in and discovery because these require a real member session. Older servers without OAuth support return `404` from `/.well-known/oauth-authorization-server`; the CLI can fall back to pairing-code login. -Access tokens are opaque and last an hour; refresh tokens rotate on every use. -Each login has a fixed thirty-day lifetime that refreshing does not extend. -Token validation checks current grants, so revoking a grant under -**Settings → General → Authorized apps** stops the app on its very next request. -Scheduled OAuth token cleanup runs independently of sign-in activity. +### Client registration [#registering-an-app] -Organization admins can restrict **OAuth App Access** under **Credentials & Access** -in [permission groups](/platform/enterprise/access-control). Workspace requests use -the group governing that workspace. Authorizing apps, issuing and refreshing tokens, -and account-level billing and audit reads use the organization's default group. -**CLI Access** also applies to the Sim CLI. Members can still review and revoke -existing grants when OAuth app access is restricted. +MCP clients can use the public registration endpoint at `/api/auth/oauth2/register`. It accepts reviewed callback formats, requires PKCE, and accepts at most 10 redirect URIs in a JSON body capped at 32 KiB. Its per-IP bucket holds 20 registration tokens and refills 20 each minute. Registration grants no resource access by itself. Members must consent, and each MCP grant is narrowed to the API or Search resource it addresses. -### Registering an app +The available scopes are `offline_access`, `api:read`, `api:write`, and `search:read`. API and Search resource scope families remain distinct. Public registration permits HTTPS callbacks, loopback HTTP callbacks, and the explicitly supported Cursor native callback; it does not accept arbitrary custom URI schemes. -Dynamic client registration is switched off, so clients are created by an -operator. Both `db:migrate` and the development `db:push` command install the -OAuth lifecycle triggers and register the Sim CLI. Repeating either command -preserves existing grants and client customizations. Register other apps with: +Operators create first-party and confidential clients. Both `db:migrate` and the development `db:push` command install OAuth lifecycle triggers and register the Sim CLI, preserving existing grants and client customizations on repeat runs. From a source checkout, register another app with: ```bash DATABASE_URL=… \ @@ -125,77 +144,44 @@ OAUTH_SCOPES=api:read \ bun run apps/sim/scripts/create-oauth-client.ts ``` -Add `OAUTH_CLIENT_PUBLIC=true` for a native or CLI app that cannot keep a -secret; it then authenticates with PKCE alone. The provider exposes -`offline_access`, `api:read`, and `api:write` for API authorization; it does not -expose OpenID Connect identity scopes or issue ID tokens. A confidential -client's secret is printed once and cannot be read back. Confidential clients -use `client_secret_basic`; the registration command prints the token -authentication method alongside the client ID. +Add `OAUTH_CLIENT_PUBLIC=true` for a native or CLI app that cannot keep a secret. Confidential clients use `client_secret_basic`; the command prints the authentication method and prints the client secret once. The secret cannot be read back. -Redirect URIs must be `https`, or `http` on a loopback address, and are matched -exactly — except a loopback URI, where any port matches, because a native app -cannot know its port in advance. +Operator-registered redirect URIs must use HTTPS or HTTP on a loopback address. They match exactly, except that loopback callbacks may use any port. -## Controlling who can sign up +### Authorization and upgrades -| Variable | Effect | -|---|---| -| `DISABLE_REGISTRATION=true` | Blocks all new accounts — email/password, email OTP, and social sign-in. Only existing accounts can sign in, including to accept a workspace invitation. SSO is unaffected | -| `DISABLE_EMAIL_SIGNUP=true` | Blocks new email/password registrations; existing email login keeps working | -| `EMAIL_PASSWORD_SIGNUP_ENABLED=false` | Disables the whole email path — sign-in, signup, and email OTP — for existing users too. Use `DISABLE_EMAIL_SIGNUP` to block only new accounts | -| `ALLOWED_LOGIN_DOMAINS` | Comma-separated domain allowlist, e.g. `acme.com,acme.co.uk`. Gates email sign-**in** as well as signup | -| `ALLOWED_LOGIN_EMAILS` | Comma-separated address allowlist, applied the same way | -| `BLOCKED_SIGNUP_DOMAINS` | Comma-separated domain blocklist | -| `BLOCKED_EMAILS` | Comma-separated address blocklist. Bans the address from the platform outright — signup, sign-in, and workflow executions | -| `SIGNUP_MX_VALIDATION_ENABLED=true` | Reject domains with no MX record or a denylisted mail backend | -| `BLOCKED_EMAIL_MX_HOSTS` | MX-host substrings to block; used only with the above | - - - `ALLOWED_LOGIN_DOMAINS`, `ALLOWED_LOGIN_EMAILS`, and `SIGNUP_MX_VALIDATION_ENABLED` gate the **email/password** path only — and `SIGNUP_MX_VALIDATION_ENABLED` narrower still, running on email signup alone, not on email sign-in or email OTP. A first-time sign-in through Google, GitHub, or Microsoft creates an account through the social provider and is not filtered by them. To restrict who may sign in through a social provider, disable the ones you have not vetted (`DISABLE_GOOGLE_AUTH`, `DISABLE_GITHUB_AUTH`, `DISABLE_MICROSOFT_AUTH`) or restrict membership at the identity provider and use SSO. +Organization admins can restrict **OAuth App Access** under **Credentials & Access** in [permission groups](/platform/enterprise/access-control). Workspace requests use the group governing that workspace; authorization, issuance, refresh, and account-level billing/audit reads use the organization's default group. **CLI Access** also applies to the Sim CLI. Members can still inspect and revoke existing grants when OAuth app access is restricted. - `DISABLE_REGISTRATION` and `BLOCKED_SIGNUP_DOMAINS` apply to every path, social included. - +Apply database migrations before a new app version. When upgrading from a version without the OAuth token-family lifecycle, drain older app instances before accepting OAuth traffic so all instances enforce the same refresh and revocation rules. -For a company deployment, the usual pairing is domain-restricted signup plus SSO: - -```bash -ALLOWED_LOGIN_DOMAINS=acme.com -DISABLE_EMAIL_SIGNUP=true -SSO_ENABLED=true -NEXT_PUBLIC_SSO_ENABLED=true -``` - -Both SSO flags are needed: the server-side one grants access, and the `NEXT_PUBLIC_` one makes the login page render the SSO entry point. - -## Behind a load balancer - -Tell Better Auth which forwarding hops to trust when resolving the client IP: - -```bash -AUTH_TRUSTED_PROXIES=10.0.0.0/24,192.0.2.10 -``` - -Better Auth walks `X-Forwarded-For` right to left, skips these hops, and uses the first untrusted address as the client IP for session records and its own IP-based checks. Use your proxies' actual addresses — a broad private range that also covers client traffic defeats the purpose. See [Security](/platform/self-hosting/security). - -## Disabling authentication entirely +## Disable authentication [#disabling-authentication-entirely] ```bash DISABLE_AUTH=true ``` -Bypasses authentication and creates an anonymous session for every request. +Requests use a shared anonymous session. - Everyone who can reach the instance becomes a fully privileged user — including anything that can reach it through an SSRF bug elsewhere on your network. Use this only for a single-user instance on a private network, never behind an internet-facing ingress. + Anyone who can reach the instance can act through that session. Use this only for a single-user installation on a private network; do not expose it through an internet-facing ingress. ## Other controls | Variable | Effect | -|---|---| -| `DISABLE_INVITATIONS=true` / `NEXT_PUBLIC_DISABLE_INVITATIONS=true` | Disable workspace invitations globally | -| `DISABLE_PUBLIC_API=true` / `NEXT_PUBLIC_DISABLE_PUBLIC_API=true` | Disable the public API globally | -| `ADMIN_API_KEY` | Enables the Admin API for GitOps operations and organization provisioning | +| --- | --- | +| `DISABLE_INVITATIONS=true` / `NEXT_PUBLIC_DISABLE_INVITATIONS=true` | Disable workspace invitations globally. | +| `DISABLE_PUBLIC_API=true` / `NEXT_PUBLIC_DISABLE_PUBLIC_API=true` | Disable the public API globally. | +| `ADMIN_API_KEY` | Enables Admin API GitOps operations and organization provisioning. | + +Set both server and `NEXT_PUBLIC_` flags where a pair is listed. The server flag enforces the restriction; its counterpart controls the UI. + +## Verify authentication + +Sign out and sign back in at the public origin, then open a workflow in two browser windows and confirm edits propagate. Test each enabled login method. If verification is required, create a test account and confirm the message arrives and the verification succeeds. Use [Verify your install](/platform/self-hosting/verify) for deployment checks. + +## Related docs -The `NEXT_PUBLIC_` twin controls what the UI shows; the server-side variable enforces it. Set both. +- [Email](/platform/self-hosting/email) +- [Integrations and OAuth](/platform/self-hosting/integrations-oauth) +- [Verified domains](/platform/enterprise/verified-domains) diff --git a/apps/docs/content/docs/platform/self-hosting/background-jobs.mdx b/apps/docs/content/docs/platform/self-hosting/background-jobs.mdx index d2807cdb3ec..2f38820dd4f 100644 --- a/apps/docs/content/docs/platform/self-hosting/background-jobs.mdx +++ b/apps/docs/content/docs/platform/self-hosting/background-jobs.mdx @@ -1,13 +1,13 @@ --- -title: Background Jobs +title: Background jobs description: Scheduled workflows, polling triggers, and the cron endpoints that drive them --- import { Callout } from 'fumadocs-ui/components/callout' -A large part of Sim runs on a schedule rather than in response to a user request: scheduled workflows, every polling trigger, connector syncs, the outbox, data drains, and retention. All of it is driven by **HTTP endpoints that something external must call on a timer**. +Scheduled workflows, polling triggers, connector syncs, and maintenance jobs depend on authenticated HTTP endpoints called by an external scheduler. -Both deployments ship a scheduler and enable it by default: Kubernetes as CronJobs, Docker Compose as a `cron` service. Both authenticate with `CRON_SECRET`, and both use the same schedules. +Helm enables CronJobs by default; Docker Compose includes a `cron` service. Both use `CRON_SECRET` and the same shipped schedules. Upload-session cleanup needs an additional operator-configured job, described below. ## Authentication @@ -26,59 +26,32 @@ openssl rand -hex 32 ``` - `CRON_SECRET` is **required** whenever background jobs are enabled — which is the Helm chart's default. The chart refuses to render without it. If it is unset, the endpoints reject every call and all scheduled work silently stops. + Background jobs require `CRON_SECRET`. Helm rejects a missing inline value when CronJobs are enabled. With a pre-created Secret or External Secrets, supply the key in that Secret; otherwise cron pods cannot start. Endpoints reject calls without the matching secret. Point cron at an **internal** address where possible (the in-cluster Service, or `localhost` on a single node). These endpoints should not be reachable from the internet; if they are, `CRON_SECRET` is the only thing protecting them. -## The jobs - -| Job | Endpoint | Schedule | Drives | -|---|---|---|---| -| Schedule execution | `/api/schedules/execute` | `*/1 * * * *` | **Scheduled workflows** | -| Gmail poll | `/api/webhooks/poll/gmail` | `*/1 * * * *` | Gmail trigger | -| Outlook poll | `/api/webhooks/poll/outlook` | `*/1 * * * *` | Outlook trigger | -| IMAP poll | `/api/webhooks/poll/imap` | `*/1 * * * *` | IMAP trigger | -| RSS poll | `/api/webhooks/poll/rss` | `*/1 * * * *` | RSS trigger | -| Google Sheets poll | `/api/webhooks/poll/google-sheets` | `*/1 * * * *` | Sheets trigger | -| Google Drive poll | `/api/webhooks/poll/google-drive` | `*/1 * * * *` | Drive trigger | -| Google Calendar poll | `/api/webhooks/poll/google-calendar` | `*/1 * * * *` | Calendar trigger | -| HubSpot poll | `/api/webhooks/poll/hubspot` | `*/1 * * * *` | HubSpot trigger | -| Time pause/resume | `/api/resume/poll` | `*/1 * * * *` | Workflows paused on a timer | -| Outbox processing | `/api/webhooks/outbox/process` | `*/1 * * * *` | Transactional-outbox retries for billing, membership, enterprise issuance, and workflow-deployment side effects | -| Workspace file search dispatch | `/api/cron/workspace-file-search-dispatch` | `*/1 * * * *` | Dispatches indexing work for workspace file search | -| Knowledge projection | `/api/cron/knowledge-projection` | `*/1 * * * *` | Brings knowledge base search up to date with document, permission, and chunk changes | -| Table row-change fold | `/api/cron/fold-table-row-changes` | `*/1 * * * *` | Folds the table row-change log into each table's stored row count and version | -| Connector sync | `/api/knowledge/connectors/sync` | `*/5 * * * *` | Knowledge base connector syncs | -| Connector member sync | `/api/knowledge/connectors/member-sync` | `*/5 * * * *` | Per-member content/access sync for indexed connectors; live Search sources are skipped | -| Connector directory sync | `/api/knowledge/connectors/directory-sync` | `*/5 * * * *` | Refreshes stored groups for indexed administrator-mode connectors; live Search sources are skipped | -| Workspace events poll | `/api/workspace-events/poll` | `*/15 * * * *` | Workspace event triggers | -| Table row TTL cleanup | `/api/cron/cleanup-table-row-ttl` | `*/15 * * * *` | Deletes table rows whose TTL column has expired | -| Stale execution cleanup | `/api/cron/cleanup-stale-executions` | `*/30 * * * *` | Fails runs whose worker died without finishing — workflow executions, background jobs, table jobs and table runs — so they stop showing as running | -| OAuth token cleanup | `/api/cron/cleanup-oauth-tokens` | `0 * * * *` | Deletes access and refresh tokens after the retention tail | -| SCIM reconciliation | `/api/cron/scim-reconcile` | `17 * * * *` | Re-applies directory group mappings | -| Data drains | `/api/cron/run-data-drains` | `0 * * * *` | Enterprise data drains | -| Renew subscriptions | `/api/cron/renew-subscriptions` | `0 */12 * * *` | Renews Microsoft Teams chat subscriptions (Graph caps them at ~3 days) | -| Billing cycle close | `/api/cron/billing-cycle-close` | `0 */6 * * *` | Billing only — final overage collection and per-period tracker reset | -| Reconcile billing seats | `/api/cron/reconcile-billing-seats` | `0 * * * *` | Billing only — safe to disable when self-hosted | -| Reconcile inbox entitlement | `/api/cron/reconcile-inbox-entitlement` | `0 3 * * *` | Inbox access reconciliation | -| Cleanup sandbox images | `/api/cron/cleanup-sandbox-images` | `30 4 * * *` | Reclaims sandbox images | -| Idempotency key cleanup | `/api/webhooks/cleanup/idempotency` | `0 5 * * *` | Deletes deduplication records older than seven days | - - - **Subscription renewal** covers Microsoft Teams chat triggers, whose Microsoft Graph subscriptions are hard-capped at about three days. Without it, Teams triggers work for a couple of days and then quietly stop. Gmail, Outlook, Drive, Calendar, and Sheets triggers are **polled** instead — they depend on the per-minute poll jobs above, not on this one. - - ## Kubernetes -Enabled by default. Nothing to do beyond setting `CRON_SECRET`. +CronJobs are enabled by default. Supply `CRON_SECRET` through the app Secret and ensure cron pods can reach the internal app Service. ```yaml cronjobs: enabled: true ``` -Each job runs a small `curlimages/curl` pod that calls the app's **in-cluster Service** (not the ingress), with `concurrencyPolicy: Forbid` so a slow run never overlaps itself. The Service load-balances that single call to one replica, so a job never fans out across pods. The chart keeps three completed and one failed Job per CronJob, but `ttlSecondsAfterFinished` defaults to 600, so a finished Job is deleted ten minutes after it ends — inspect a failure promptly or collect the logs. It sets no `backoffLimit`, so the Kubernetes default of six applies and the chart exposes no key to change it. `cronjobs.activeDeadlineSeconds` (default `300`) bounds the **whole Job** — retries and the controller's back-off included — so whichever limit is reached first ends the Job — six retries after the initial failure, up to seven attempts, or five minutes of attempts plus back-off. The same deadline cuts off a single hung request. One attempt is already several HTTP calls: the container retries three times, ten seconds apart, with `curl --retry 2` inside each. +Each `curlimages/curl` pod calls the internal app Service, which routes the request to one replica. `concurrencyPolicy: Forbid` prevents overlapping Jobs for that CronJob; the app also handles overlap for detached work. + +| Setting | Shipped behavior | +|---|---| +| Completed/failed Job history | Three successful and one failed Job | +| Finished-Job TTL | 600 seconds; collect logs before deletion | +| Job deadline | 300 seconds by default; outbox uses 900, idempotency cleanup 360 | +| Kubernetes retry limit | No chart `backoffLimit` key; Kubernetes defaults to six retries after the initial failure | +| Request retries | Three shell attempts, ten seconds apart; each uses `curl --retry 2 --retry-delay 5` | +| Request timeout | 60 seconds by default, with per-job overrides; outbox uses 810 seconds | + +The Job deadline includes attempts and controller backoff. It can end a Job before the retry limit is reached and also stops a hung request. Disable individual jobs you do not need — billing reconciliation is the obvious one on a self-hosted install: @@ -96,24 +69,28 @@ Check they are running: ```bash kubectl get cronjobs -n simstudio kubectl get jobs -n simstudio --sort-by=.metadata.creationTimestamp | tail -kubectl logs -n simstudio job/ +kubectl logs -n simstudio 'job/' ``` -A CronJob whose `LAST SCHEDULE` is stale, or whose jobs are failing, means the corresponding feature is dead. Alert on it — see [Observability](/platform/self-hosting/observability). +Inspect stale schedules and failed Jobs. A stale `LAST SCHEDULE` points to controller, suspension, or deadline settings; a 401 in Job logs points to authentication. `Forbid` can skip a tick while an earlier Job remains active. Alert on successful completion as described in [Observability](/platform/self-hosting/observability). ## Docker Compose -The `cron` service runs the same jobs on the same schedules, so nothing to configure beyond `CRON_SECRET`: +Generate a secret, then save it as `CRON_SECRET` in the `.env` file next to your Compose file. Replace an existing value rather than adding a duplicate. The app and scheduler must receive the same value. ```bash -CRON_SECRET=$(openssl rand -hex 32) +openssl rand -hex 32 +``` + +Recreate the services after updating `.env`: + +```bash +docker compose -f docker-compose.prod.yml up -d ``` Without it the `cron` service logs exactly what to set — including a freshly generated value — and exits, leaving the rest of the stack running. Schedules live in `docker/crontab` and mirror `helm/sim/values.yaml` `cronjobs.jobs` one-for-one. - - Upgrading a deployment created before the scheduler existed? Your `.env` has no `CRON_SECRET`, so the stack comes up as before and `cron` exits with instructions. Add the value and re-run `up -d` to turn background jobs on. - +An older install may lack `CRON_SECRET`; add it to `.env` and run `up -d` to enable the scheduler. The service runs [supercronic](https://github.com/aptible/supercronic) rather than the app image: it logs each job's output to the container log, forwards `SIGTERM` so `docker compose stop` is graceful, and will not start an iteration while the previous one is still running. @@ -128,7 +105,48 @@ level=info msg=starting iteration=0 job.schedule="*/1 * * * *" level=info msg="job succeeded" iteration=0 ``` -To drop a job you do not need, comment out its line in `docker/crontab` and restart the service. +The published cron image contains its crontab. Editing the repository copy and restarting that image does not change its jobs. To customize them, copy `docker/crontab` to an operator-owned file, edit it, and mount it with a Compose override: + +```yaml +# cron-custom.yml +services: + cron: + volumes: + - ./sim-crontab:/etc/sim/crontab:ro +``` + +```bash +docker compose -f docker-compose.prod.yml -f cron-custom.yml up -d cron +``` + +Alternatively, build a custom image from `docker/cron.Dockerfile` with your crontab and configure Compose to use it. + +## Schedule upload-session cleanup + +The cleanup endpoint exists, but neither shipped scheduler calls it. Configure your own authenticated schedule for `/api/cron/cleanup-tasks` to expire upload sessions and reclaim abandoned upload state. It also dispatches task-retention cleanup according to configured policy. + +For Helm, add an operator-owned job to your values file. This example runs hourly; choose a cadence and timeout for your workload: + +```yaml +cronjobs: + jobs: + uploadSessionCleanup: + enabled: true + name: upload-session-cleanup + schedule: "0 * * * *" + path: /api/cron/cleanup-tasks + requestTimeoutSeconds: 300 + activeDeadlineSeconds: 360 + concurrencyPolicy: Forbid +``` + +For Compose, add this line to the mounted or custom-image crontab described above: + +```text +0 * * * * curl -fsS -m 300 -o /dev/null -H "Authorization: Bearer $CRON_SECRET" "$SIM_URL/api/cron/cleanup-tasks" +``` + +Use the internal app address and the same `CRON_SECRET`. Check job logs for a successful response. Provider lifecycle rules remain a second layer for incomplete multipart state; see [Object storage](/platform/self-hosting/object-storage#configure-incomplete-multipart-cleanup). ## Verifying @@ -138,16 +156,57 @@ Create a workflow with a Schedule trigger set to every minute, deploy it, and wa 2. Confirm the app and the scheduler share the same `CRON_SECRET`. A mismatch shows up as `401` in the scheduler log. 3. A `202` means the endpoint accepted the run; it does not confirm a schedule was due, so check the Logs view. +## Shipped job reference + +| Job | Endpoint | Schedule | Drives | +|---|---|---|---| +| Schedule execution | `/api/schedules/execute` | `*/1 * * * *` | **Scheduled workflows** | +| Gmail poll | `/api/webhooks/poll/gmail` | `*/1 * * * *` | Gmail trigger | +| Outlook poll | `/api/webhooks/poll/outlook` | `*/1 * * * *` | Outlook trigger | +| IMAP poll | `/api/webhooks/poll/imap` | `*/1 * * * *` | IMAP trigger | +| RSS poll | `/api/webhooks/poll/rss` | `*/1 * * * *` | RSS trigger | +| Google Sheets poll | `/api/webhooks/poll/google-sheets` | `*/1 * * * *` | Sheets trigger | +| Google Drive poll | `/api/webhooks/poll/google-drive` | `*/1 * * * *` | Drive trigger | +| Google Calendar poll | `/api/webhooks/poll/google-calendar` | `*/1 * * * *` | Calendar trigger | +| HubSpot poll | `/api/webhooks/poll/hubspot` | `*/1 * * * *` | HubSpot trigger | +| Time pause/resume | `/api/resume/poll` | `*/1 * * * *` | Workflows paused on a timer | +| Outbox processing | `/api/webhooks/outbox/process` | `*/1 * * * *` | Transactional-outbox retries for billing, membership, enterprise issuance, and workflow-deployment side effects | +| Workspace file search dispatch | `/api/cron/workspace-file-search-dispatch` | `*/1 * * * *` | Dispatches indexing work for workspace file search | +| Knowledge projection | `/api/cron/knowledge-projection` | `*/1 * * * *` | Brings knowledge base search up to date with document, permission, and chunk changes | +| Table row-change fold | `/api/cron/fold-table-row-changes` | `*/1 * * * *` | Folds the table row-change log into each table's stored row count and version | +| Connector sync | `/api/knowledge/connectors/sync` | `*/5 * * * *` | Knowledge base connector syncs | +| Connector member sync | `/api/knowledge/connectors/member-sync` | `*/5 * * * *` | Per-member content/access sync for indexed connectors; live Search sources are skipped | +| Connector directory sync | `/api/knowledge/connectors/directory-sync` | `*/5 * * * *` | Refreshes stored groups for indexed administrator-mode connectors; live Search sources are skipped | +| Workspace events poll | `/api/workspace-events/poll` | `*/15 * * * *` | Workspace event triggers | +| Table row TTL cleanup | `/api/cron/cleanup-table-row-ttl` | `*/15 * * * *` | Deletes table rows whose TTL column has expired | +| Stale execution cleanup | `/api/cron/cleanup-stale-executions` | `*/30 * * * *` | Fails runs whose worker died without finishing — workflow executions, background jobs, table jobs and table runs — so they stop showing as running | +| OAuth token cleanup | `/api/cron/cleanup-oauth-tokens` | `0 * * * *` | Deletes access and refresh tokens after the retention tail | +| SCIM reconciliation | `/api/cron/scim-reconcile` | `17 * * * *` | Re-applies directory group mappings | +| Data drains | `/api/cron/run-data-drains` | `0 * * * *` | Enterprise data drains | +| Renew subscriptions | `/api/cron/renew-subscriptions` | `0 */12 * * *` | Renews Microsoft Teams chat subscriptions (Graph caps them at ~3 days) | +| Billing cycle close | `/api/cron/billing-cycle-close` | `0 */6 * * *` | Billing only — final overage collection and per-period tracker reset | +| Reconcile billing seats | `/api/cron/reconcile-billing-seats` | `0 * * * *` | Billing only — safe to disable when self-hosted | +| Reconcile inbox entitlement | `/api/cron/reconcile-inbox-entitlement` | `0 3 * * *` | Inbox access reconciliation | +| Cleanup sandbox images | `/api/cron/cleanup-sandbox-images` | `30 4 * * *` | Reclaims sandbox images | +| Idempotency key cleanup | `/api/webhooks/cleanup/idempotency` | `0 5 * * *` | Deletes deduplication records older than seven days | + +Subscription renewal covers Microsoft Teams chat triggers. Their Graph subscriptions last at most three days; rich notifications have a shorter limit. Gmail, Outlook, Drive, Calendar, and Sheets use the per-minute polling jobs instead. See [Microsoft Graph subscription lifetimes](https://learn.microsoft.com/en-us/graph/change-notifications-overview). SCIM reconciliation calls its authenticated endpoint directly each hour; it does not require Trigger.dev. + ## Concurrency -Scheduled execution volume is bounded per app instance by: +On the default database-backed queue, scheduled execution capacity is shared across the deployment: | Variable | Default | Applies to | |---|---|---| -| `SCHEDULE_EXECUTION_CONCURRENCY_LIMIT` | `30` | Scheduled workflows in flight, on every install | +| `SCHEDULE_EXECUTION_CONCURRENCY_LIMIT` | `30` | Scheduled workflows in flight across the database-backed queue; also the schedule task limit on Trigger.dev | `WORKFLOW_EXECUTION_CONCURRENCY_LIMIT`, `WEBHOOK_EXECUTION_CONCURRENCY_LIMIT`, and `RESUME_EXECUTION_CONCURRENCY_LIMIT` are `concurrencyLimit` settings on Trigger.dev task definitions. They have **no effect** unless `TRIGGER_DEV_ENABLED` is set, and neither the Helm chart nor Docker Compose configures Trigger.dev — so on a default self-host they are inert. -Raise the schedule limit only alongside memory headroom: concurrent executions run in the app process, so throughput is bounded by the pod's memory before it is bounded by this number. +Adding replicas does not multiply the database queue's schedule cap. Raise it only after measuring memory and database headroom. The app orchestrates runs; local JavaScript uses Node child workers inside its container. + +## Related docs + +- [Observability](/platform/self-hosting/observability) +- [Upgrades](/platform/self-hosting/upgrades) diff --git a/apps/docs/content/docs/platform/self-hosting/desktop.mdx b/apps/docs/content/docs/platform/self-hosting/desktop.mdx index 43c153a16a3..45344d8c907 100644 --- a/apps/docs/content/docs/platform/self-hosting/desktop.mdx +++ b/apps/docs/content/docs/platform/self-hosting/desktop.mdx @@ -1,170 +1,150 @@ --- -title: Desktop App on Your Deployment -description: Point the macOS desktop app at your own Sim deployment +title: Desktop app on your deployment +description: Connect the macOS desktop app to a Sim deployment you operate --- import { Callout } from 'fumadocs-ui/components/callout' import { Step, Steps } from 'fumadocs-ui/components/steps' -This page is about pointing the app at a deployment you run. For installing and using it, see [Sim Desktop](/desktop). +Install the official Sim desktop app and connect it to your deployment. You do not need a custom build to change servers. The app is currently macOS-only; use the web app on other platforms. See [Sim Desktop](/desktop) for general installation and use. -The Sim desktop app is a native macOS shell around a Sim deployment. It is **not** tied to sim.ai — the build bakes in only a *default* server, and every runtime boundary (navigation, content security policy, cookie storage, the update feed) is derived from the server you point it at. +## Server prerequisites [#requirements-for-the-server-url] -So self-hosting the desktop app takes no build of your own: install the same signed, notarized app everyone else installs, then point it at your deployment. - - - The desktop app is macOS-only today. The web app works in any browser on any platform. - - -## Your deployment already serves the installer - -Every Sim deployment exposes two public endpoints: - -| Endpoint | What it does | -|---|---| -| `/api/desktop/update/download` | Redirects (302) to the newest installer for this deployment's release channel | -| `/api/desktop/update/latest-mac.yml` | The update manifest installed apps poll | - -Both resolve against Sim's public GitHub releases, and the installers themselves are downloaded from GitHub. Nothing is built, signed, or hosted by you: your deployment decides *which* release its clients are offered and serves the manifest, so installed apps poll your server instead of sim.ai — but they cannot be served artifacts of your own from this path, and a self-updating stable build falls back to Sim's own feed if yours stops answering. To ship your own build, see [Building your own shell](#building-your-own-shell). - -Both endpoints cache their GitHub lookups for **5 minutes**, and both respond the same way when they cannot answer: - -| Status | Meaning | -|---|---| -| `302` | Success on `/download` — a redirect to the release asset. The update feed answers `200` with `text/yaml` instead | -| `404` | GitHub answered, but this channel has no release | -| `502` | GitHub could not be read — unreachable, rate-limited, or every candidate release lacked valid desktop artifacts | - -The Sim server needs outbound access to `api.github.com` and `github.com` for these to resolve. Unauthenticated GitHub API requests are capped at 60/hour per IP; set `GITHUB_TOKEN` on the Sim server to raise that to 5000/hour. - -### What an installed app does when the feed fails - -A `404` carries a header the shell reads as *no update available*, so the app reports it is up to date. Anything else — `502`, a timeout, a connection failure — means the feed is unavailable, and only a self-updating build (Developer ID, installed in `/Applications`) has anywhere else to go: on the stable channel it falls back to Sim's packaged GitHub feed, and on `dev` or `staging` it skips the check, since that fallback carries only stable artifacts their bundle identity cannot install. Every other build simply stops being offered updates until the feed answers again. - -Release selection is therefore yours only while the feed answers. With `APPCONFIG_ENVIRONMENT` unset both paths resolve the same release, so the fallback is invisible; it matters when your deployment serves a channel that disagrees with stable. - -### Which channel your deployment serves - -The channel is chosen by `APPCONFIG_ENVIRONMENT`, not by whether you are self-hosting: - -| `APPCONFIG_ENVIRONMENT` | Channel | Release repository | -|---|---|---| -| `dev` | `dev` | `simstudioai/sim-desktop-releases` | -| `staging` | `staging` | `simstudioai/sim-desktop-releases` | -| anything else, including unset | `latest` | `simstudioai/sim` | +- Use the origin your server serves, including scheme, hostname, and port. Paths are ignored. +- HTTPS is required except for `localhost`, `127.0.0.1`, and `::1`, which allow HTTP for local testing. +- Do not include credentials in the URL. +- Use a certificate trusted by macOS. +- Allow your Sim server to reach `api.github.com` and `github.com` for official installer and update lookup. - A self-hosted deployment that sets `APPCONFIG_ENVIRONMENT=dev` or `staging` — a reasonable thing to do for a non-production environment — serves its users **prereleases** from the desktop prerelease repository, silently and with no other symptom. Leave it unset on any deployment whose users install the desktop app. + Use the final served origin, not a redirecting alias. If `sim.example.com` redirects to `www.sim.example.com`, enter the `www` origin. The shell checks origins exactly; an alias can strand sign-in. Certificate errors are rejected without a “continue anyway” option. Install a private CA in the system trust store or use a publicly trusted certificate. ## Install and connect - -### Get the installer link +### Resolve the installer + +From your installation directory: ```bash -npx sim-setup desktop +bunx sim-setup desktop ``` -This reads your deployment URL from your Compose and Helm configuration, resolves the installer, and prints the download link plus the server URL to enter. It then offers to open the download in your browser — pass `--no-open` to skip the prompt, for scripts and CI. +The command reads Compose/Helm configuration, resolves the installer, and prints the download link and server URL. It offers to open the installer in your browser. Use `--no-open` to skip that prompt, or supply the public origin directly: -The two probes are not weighted the same. **The installer probe is fatal**: if `/api/desktop/update/download` does not resolve, the command prints why and exits `1`. A failing update feed is only a warning — the command tells you the app will install but will not auto-update from this deployment, and still exits `0`. Read the output; do not rely on the exit code alone to prove the feed works. +```bash +bunx sim-setup desktop --url https://sim.example.com --no-open +``` -Pass `--url https://sim.example.com` when running the CLI somewhere that reaches Sim at a different address. It also **skips discovery entirely**, which is worth using deliberately: discovery shells out to `docker compose` and `helm`, so it costs seconds that `--url` avoids. +`--url` skips discovery. Without the CLI, open `https:///api/desktop/update/download` in a browser. - - If the machine holds more than one Sim configuration naming different `NEXT_PUBLIC_APP_URL` values, the command does **not** prompt you to pick — it errors, lists what it found, and tells you to re-run with `--url`. There is no interactive picker. + + - In the opposite case, where no configuration sets `NEXT_PUBLIC_APP_URL` at all, it falls back to `http://localhost:3000` without saying so. If the printed deployment URL is `localhost` and you expected your real domain, that fallback is why. - +### Install the app -Without the CLI, open `https://your-sim-url/api/desktop/update/download` in a browser. +Open the `.dmg` and drag Sim to **Applications**. Official installers are signed and notarized by Sim.
- -### Install it +### Connect to your server -Open the `.dmg` and drag Sim to Applications. The build is signed and notarized by Sim, so Gatekeeper accepts it with no override. +Launch Sim, choose **Sim → Server…**, enter your deployment origin, and select **Connect**. The app relaunches against that server and saves the setting across updates. +
- +## What changes when you switch servers -### Point it at your server +Each server has its own cookie and storage partition. Switching clears deployment-scoped state before the new server loads: -Launch Sim, then choose **Sim → Server…** in the menu bar. Enter your deployment URL and press **Connect**. +| State | Result | +| --- | --- | +| Sign-in session | Sign in to the new deployment. | +| Saved route | Open the workspace picker rather than the old deployment's workspace. | +| Folder access | Grant directories again when needed. | +| Built-in browser sessions | Sign in to sites again. | -The app relaunches against your server and stays there — the setting persists across updates, and every later update is fetched from your deployment's feed. +Window size, zoom, theme, notification preferences, tray, and launch-at-login settings remain. If deployment-scoped state cannot be cleared, the switch is refused; retry to complete it. -Changing servers deliberately clears what the previous deployment was trusted with, so the new one cannot inherit it: +## Recover a wrong server URL [#recovering-from-a-wrong-server-url] -- **Your session.** Each server gets its own storage, so you sign in again. -- **The saved route.** The app opens on the workspace picker, not the workspace the old server had open. -- **Folder access.** Directories you let the agent read are forgotten; grant them again when you need them. -- **Built-in browser sessions.** Sites you were signed into in the built-in browser are signed out. +The **Can't connect** page reports a DNS, timeout, or TLS failure. Select **Change server** to open the picker with the current value prefilled. No filesystem change is needed to correct a typo. -The last two are capabilities you granted to a *specific* Sim server, so carrying them across would hand the new deployment access it was never given — the same reasoning that clears them when you sign out. +A private or self-signed certificate must be trusted by macOS; otherwise the app shows **Connection isn't secure**. A correct URL does not bypass certificate validation. -Device settings are kept: window size, zoom, theme, notification preferences, tray, and launch-at-login. +## Installer and update endpoints [#your-deployment-already-serves-the-installer] -If something cannot be cleared, the change is refused and the app stays on your current server rather than switching with the old deployment's access still in place. Retrying finishes the job. +Your deployment exposes two public endpoints: - +| Endpoint | Response | +| --- | --- | +| `/api/desktop/update/download` | `302` to the newest official installer for the deployment channel. | +| `/api/desktop/update/latest-mac.yml` | `200` with a `text/yaml` update manifest. | - +Both resolve official GitHub release assets and cache lookups for five minutes. They return `404` when the channel has no release and `502` when GitHub lookup fails or candidates lack valid desktop artifacts. + +The server serves release selection and the manifest; clients download installers from GitHub. These endpoints cannot distribute your custom artifacts. Set `GITHUB_TOKEN` on the Sim server if its shared egress IP reaches GitHub's unauthenticated 60-requests/hour limit; authenticated user-token requests typically allow 5,000/hour. See [GitHub rate limits](https://docs.github.com/en/rest/using-the-rest-api/rate-limits-for-the-rest-api). + +### Deployment channel [#which-channel-your-deployment-serves] + +`APPCONFIG_ENVIRONMENT` selects the channel: + +| Value | Channel | Repository | +| --- | --- | --- | +| `dev` | `dev` | `simstudioai/sim-desktop-releases` | +| `staging` | `staging` | `simstudioai/sim-desktop-releases` | +| Anything else, including unset | `latest` | `simstudioai/sim` | - Enter the origin your server actually **serves**, not one that redirects to it. If your load balancer redirects `sim.example.com` to `www.sim.example.com`, use the `www` form. The app compares origins exactly, so a redirecting origin leaves every page off-origin and strands sign-in. + A self-hosted deployment with `APPCONFIG_ENVIRONMENT=dev` or `staging` serves prerelease installers. Leave it unset when you intend to offer the stable desktop app. -## Requirements for the server URL +### Unavailable update feed [#what-an-installed-app-does-when-the-feed-fails] -- **HTTPS is required**, except for the loopback hosts `localhost`, `127.0.0.1`, and `::1`, which may use HTTP for local testing. -- No credentials in the URL. -- Paths are ignored — only scheme, host, and port are stored. +A feed `404` with the no-release header means no update is available. For `502`, timeout, or connection failure: -Each server gets its own isolated cookie and storage partition, so you can move between deployments without either one seeing the other's session. +- A stable build eligible for self-update falls back to Sim's packaged GitHub feed. +- A `dev` or `staging` build skips the check because the stable fallback cannot update its bundle identity. +- Other builds receive no update offer until the deployment feed answers again. -## Recovering from a wrong server URL +Self-update requires a Developer ID build installed in **Applications**. Other packaged builds can offer manual downloads when the feed works. Release selection therefore follows your deployment only while its feed answers; an eligible stable app can use the fallback during an outage. -If the app is pointed at a server it cannot reach, it shows its **Can't connect** page, which names the reason — a DNS failure, a timeout, or a TLS problem. That page has a **Change server** button that opens the same picker, pre-filled with the current value, so a typo is always recoverable without touching the filesystem. +## CLI discovery and probe failures - - **Your TLS certificate must be trusted by the operating system.** The app rejects certificate errors outright and offers no "continue anyway" — a self-signed certificate or a private CA that is not in the system trust store shows `Connection isn't secure` and will not load, however correct the URL is. Install your CA in the system keychain, or use a publicly trusted certificate. - +The installer probe is required: failure exits `1`. Update-feed failure is a warning and still exits `0` if the installer resolved, so read both results before relying on updates. -## Building your own shell +If detected configurations name different `NEXT_PUBLIC_APP_URL` origins, the command lists them and requires `--url`; there is no interactive selection. If none names an origin, it defaults to `http://localhost:3000`. `--url` also avoids the Docker/Helm discovery calls. -You almost certainly do not need this. It is worth it only if you need your own bundle identity or your own signing identity — for example, to distribute through MDM under your organization's Developer ID. +## Build a custom shell [#building-your-own-shell] -Packaging needs **macOS with Xcode 26 or newer** — the app icon is an Icon Composer asset, and an older toolchain fails with `Failed to check actool version`. +Use a custom build for a different bundle identity or signing identity, such as distribution through MDM with your organization's Developer ID. Start from a source checkout with dependencies installed. Packaging requires macOS with Xcode 26 or later for the Icon Composer asset. ```bash cd apps/desktop SIM_DESKTOP_DEFAULT_ORIGIN=https://sim.example.com bun run package:mac ``` -This bakes your origin in as the default for fresh installs, so nobody has to set the server by hand (the picker stays available in the menu). The mac target builds a single universal binary, so artifacts land in `apps/desktop/release/` as `Sim--universal.dmg` and `Sim--universal.zip`. Add `-c.appId=com.example.sim` if you want your own bundle identifier rather than Sim's. +The default origin applies to fresh installs; the server picker remains available. The macOS target builds a universal binary. Output files are `apps/desktop/release/Sim--universal.dmg` and `.zip`. Pass `-c.appId=com.example.sim` to choose a bundle identifier. - - The origin you bake in also decides the app's **identity**. A loopback origin, or a `dev.sim.ai` / `staging.sim.ai` hostname, produces a differently named app with its own userData directory, and its own single-instance lock — deliberately, so those installs can sit alongside a production one. Any other origin, including your own domain, is treated as production and shares the plain `Sim` identity. Baking in `http://localhost:3000` to test therefore does not produce a build your users can later repoint; it produces a separate app. - +The baked default determines the app's channel identity, userData directory, and single-instance lock. Loopback, `dev.sim.ai`, and `staging.sim.ai` defaults produce separate Local, Dev, and Staging app identities; other origins use the production Sim identity. A Local build can still be pointed at another HTTPS server, but changing servers does not turn it into a production build or change its update eligibility. -`package:share` overrides both the output directory and the artifact name — builds land in `apps/desktop/release//` as `--.`, not the names above. +`package:share` instead writes `apps/desktop/release//--.` and disables trusted timestamps. Use `package:mac` for notarized distribution. -### Overriding the server at runtime + + Your custom build needs your own signing and notarization. Set `CSC_LINK` and `CSC_KEY_PASSWORD` for Developer ID signing. Set `APPLE_API_KEY` to the absolute path of the App Store Connect `.p8` file, plus `APPLE_API_KEY_ID`, `APPLE_API_ISSUER`, and `APPLE_TEAM_ID`. A leading `~` is not expanded. `package:share` passes `-c.mac.timestamp=none`; Apple notarization requires a secure timestamp, so that output cannot be notarized even with credentials configured. + -`SIM_DESKTOP_ORIGIN` overrides the stored server for a single launch, which is useful for testing a build against another deployment without changing its saved setting. It is validated the same way the picker's input is; an invalid value is logged and ignored rather than applied. +### Runtime override [#overriding-the-server-at-runtime] - - Signing and notarization become your responsibility with this route, and macOS quarantines anything downloaded that is not notarized. +`SIM_DESKTOP_ORIGIN` overrides the saved server for one launch. It uses the same validation as the picker; an invalid value is logged and ignored. The override does not replace the saved server setting. - Supply your own Developer ID via `CSC_LINK` and `CSC_KEY_PASSWORD`. For notarization, save your App Store Connect key as a `.p8` file and point `APPLE_API_KEY` at its **absolute filesystem path** — it is a path, not the key itself, and a leading `~` is not expanded — then set `APPLE_API_KEY_ID`, `APPLE_API_ISSUER`, and `APPLE_TEAM_ID`. +## Related docs - Use `package:mac` for this, **not** `package:share`. The share script is the "send someone a build to try" path: it passes `-c.mac.timestamp=none` to skip the per-file round trip to Apple's timestamp authority. Apple's notary service requires a secure timestamp, so a build made that way cannot be notarized however many credentials you supply. - +- [Verify your install](/platform/self-hosting/verify) +- [Networking](/platform/self-hosting/networking) +- [Sim Desktop](/desktop) diff --git a/apps/docs/content/docs/platform/self-hosting/docker.mdx b/apps/docs/content/docs/platform/self-hosting/docker.mdx index 56cfe3a5027..4241c4acd8c 100644 --- a/apps/docs/content/docs/platform/self-hosting/docker.mdx +++ b/apps/docs/content/docs/platform/self-hosting/docker.mdx @@ -1,88 +1,111 @@ --- title: Docker -description: Deploy Sim with Docker Compose +description: Deploy Sim with Docker Compose and verify its services --- import { Callout } from 'fumadocs-ui/components/callout' -import { FAQ } from '@/components/ui/faq' -## Quick Start +Use the production Compose stack for a single-node installation. It starts the app, realtime, PostgreSQL with pgvector, Redis, migrations, and the scheduler. + +## Prerequisites + +- Docker Engine or Docker Desktop, running. +- Docker Compose 2.24.0 or later. The file uses optional `env_file` entries introduced in that version. +- Bun for `bunx`, and Node.js 20 or later for the published `sim-setup` executable. +- Available host ports 3000 and 3002, with enough resources for your workload. See [resource examples](/platform/self-hosting#requirements). +- A public domain and TLS proxy for remote access. + +## Quick start ```bash -npx sim-setup +bunx sim-setup ``` -Open [http://localhost:3000](http://localhost:3000) +The wizard creates `./sim` with a generated `.env` and production Compose file, then starts published container images. Pass `--dir ` for another directory. Open [http://localhost:3000](http://localhost:3000). -The setup package creates `./sim` with a generated `.env` and the production Compose file, then -starts published container images. Pass `--dir ` to choose another directory. +For a manual installation, obtain the Compose file from a source checkout: -## Production Setup +```bash +git clone https://github.com/simstudioai/sim.git +cd sim +``` -### 1. Configure Environment +Then follow the configuration steps below. -For a new installation, create the configuration below. If you already ran the quick start, edit its generated `.env` and retain the existing secret values; do not overwrite them with new keys. +## Production setup + +### 1. Configure the environment + +For a new installation, create `.env` next to `docker-compose.prod.yml`: ```bash +umask 077 cat > .env << EOF BETTER_AUTH_SECRET=$(openssl rand -hex 32) ENCRYPTION_KEY=$(openssl rand -hex 32) INTERNAL_API_SECRET=$(openssl rand -hex 32) API_ENCRYPTION_KEY=$(openssl rand -hex 32) CRON_SECRET=$(openssl rand -hex 32) - -# Your public origin. BETTER_AUTH_URL is derived from this automatically. NEXT_PUBLIC_APP_URL=https://sim.yourdomain.com - -# Database credentials. DATABASE_URL is composed from these by the compose file. POSTGRES_USER=postgres POSTGRES_PASSWORD=$(openssl rand -hex 24) POSTGRES_DB=simstudio EOF ``` - - Do not set `DATABASE_URL` or `BETTER_AUTH_URL` in `.env` — `docker-compose.prod.yml` composes both on the service definition, and a value set here is ignored. Change `POSTGRES_*` and `NEXT_PUBLIC_APP_URL` instead. +If you already ran the wizard or have an existing installation, edit that `.env` and retain its keys and database credentials. Do not rerun this creation command over it. - Because `DATABASE_URL` is composed from them, keep `POSTGRES_USER`, `POSTGRES_PASSWORD`, and `POSTGRES_DB` URL-safe — letters, digits, and `.` `_` `~` `-`. They are inserted into the connection string as written, so a value containing `@`, `/`, `?`, `#`, `%`, or a space can initialize the database while leaving the app and migrations unable to connect. `openssl rand -hex` output is always safe. - +Compose derives `BETTER_AUTH_URL` from `NEXT_PUBLIC_APP_URL` and `DATABASE_URL` from `POSTGRES_*`. Setting either derived variable in `.env` does not override the service definition. To use an external database, maintain a Compose configuration that supplies the same external DSN to the app, realtime, and migrations and adjusts their bundled-database dependencies. + +Keep `POSTGRES_USER`, `POSTGRES_PASSWORD`, and `POSTGRES_DB` URL-safe: letters, digits, `.`, `_`, `~`, or `-`. Compose inserts them into the DSN without escaping; values containing `@`, `/`, `?`, `#`, `%`, or spaces can initialize PostgreSQL but prevent app connections. Hex output from `openssl` is safe. - Save `ENCRYPTION_KEY` and `API_ENCRYPTION_KEY` somewhere outside this server. `ENCRYPTION_KEY` encrypts workspace and personal environment variables, stored provider API keys, MCP OAuth credentials, and deployment/chat secrets; `API_ENCRYPTION_KEY` encrypts user-generated Sim API keys. Neither can be regenerated — a database restore paired with a different key leaves the data it protected permanently unreadable. + Back up `ENCRYPTION_KEY` and `API_ENCRYPTION_KEY` separately from the server. Restoring the database with different keys leaves encrypted values unreadable. `ENCRYPTION_KEY` protects environment variables, provider keys, MCP OAuth credentials, and deployment/Chat secrets. `API_ENCRYPTION_KEY` protects stored Sim API-key material; when absent, legacy API keys can be stored in plain text. -The compose file refuses to start if `BETTER_AUTH_SECRET`, `ENCRYPTION_KEY`, `INTERNAL_API_SECRET`, or `POSTGRES_PASSWORD` is missing, rather than booting with empty or well-known values. Postgres applies `POSTGRES_PASSWORD` only when it first creates the database volume — see [Postgres on Compose](/platform/self-hosting/security#postgres-on-compose) before changing it on an existing install. `CRON_SECRET` is treated more gently: without it the `cron` service prints what to set and exits, leaving the rest of the stack running — so upgrading from a compose file that predates the scheduler still works. +Compose refuses startup without `BETTER_AUTH_SECRET`, `ENCRYPTION_KEY`, `INTERNAL_API_SECRET`, or `POSTGRES_PASSWORD`. PostgreSQL applies its credentials only when initializing a new volume; changing `.env` does not change an existing database password. See [Postgres on Compose](/platform/self-hosting/security#postgres-on-compose) before rotating it. + +Set `CRON_SECRET` for scheduled work. Without it, the cron service prints instructions and exits; the other services can still run. Images use `latest` unless you set `SIM_VERSION`; the separate scheduler image uses `SIM_CRON_VERSION`. Pin and upgrade deliberately using [Upgrades](/platform/self-hosting/upgrades). -Images track `latest` unless you pin them. For production, see [Upgrades](/platform/self-hosting/upgrades). +### 2. Configure durable uploads -### 2. Start Services + + The production Compose file persists PostgreSQL but does not mount `/app/apps/sim/uploads`. Recreating the app container loses uploads stored there. Configure object storage or a persistent mount before saving files you need to retain. + + +Follow [Object storage](/platform/self-hosting/object-storage) for AWS S3, Azure Blob, Google Cloud Storage, or local-volume configuration. Local disk is not shared across app replicas. + +### 3. Start and verify services ```bash docker compose -f docker-compose.prod.yml up -d +docker compose -f docker-compose.prod.yml ps -a +docker compose -f docker-compose.prod.yml logs migrations +curl -fsS http://localhost:3000/api/health ``` -Six services start: - -| Service | Port | Purpose | -|---|---|---| -| `simstudio` | 3000 | Main application (8 GB memory limit) | -| `realtime` | 3002 | WebSocket server (1 GB memory limit) | -| `db` | internal | PostgreSQL 17 with pgvector — not published to the host | -| `redis` | internal | Pub/sub and shared cache — not published to the host | -| `cron` | — | Runs the [background jobs](/platform/self-hosting/background-jobs) on a schedule | -| `migrations` | — | Applies schema migrations once, then exits | +| Service | Host port | Purpose | +| --- | --- | --- | +| `simstudio` | 3000 | App; 8G memory limit. | +| `realtime` | 3002 | WebSocket service; 1G memory limit. | +| `db` | Not published | PostgreSQL 17 with pgvector. | +| `redis` | Not published | Shared coordination, pub/sub, and caches. | +| `cron` | None | Calls background job endpoints. | +| `migrations` | None | Applies migrations once, then exits. | -Confirm the five long-running services are up and that `migrations` has exited cleanly (it is a one-shot job with no healthcheck): +Expect five services running and `migrations` exited successfully. The migrator has no healthcheck because it is a one-shot job. ```bash -docker compose -f docker-compose.prod.yml ps +docker compose -f docker-compose.prod.yml logs -f cron ``` -### 3. Put it behind TLS +Confirm the scheduler calls succeed, then run [Verify your install](/platform/self-hosting/verify). -Caddy is the least-effort option — it obtains and renews certificates automatically. +### 4. Serve the public origin over TLS -``` +A host-installed Caddy proxy can obtain and renew certificates for your domain. For example: + +```text sim.yourdomain.com { request_body { max_size 250MB @@ -98,115 +121,123 @@ sim.yourdomain.com { } ``` -Three things in that config are Sim-specific and easy to get wrong: `/socket.io` must reach the realtime service on 3002, `flush_interval -1` stops Caddy buffering streamed agent output into one delayed block, and `max_size` has to clear the chat endpoint's 220 MB limit. +Route `/socket.io` to realtime on 3002 and other requests to the app on 3000. The 250 MB decimal Caddy limit clears the configured 220 MiB deployed-chat cap, but the app's current Next.js proxy buffer still limits matching requests to 10 MiB. See [Request size limits](/platform/self-hosting/networking#request-size-limits) before increasing payload sizes. `flush_interval -1` explicitly disables response buffering; Caddy already flushes SSE immediately. It also keeps the upstream request running if the client disconnects. See [Caddy streaming behavior](https://caddyserver.com/docs/caddyfile/directives/reverse_proxy#streaming). -For nginx, Traefik, or a cloud load balancer — and for the GKE websocket timeout — see [Networking](/platform/self-hosting/networking). +This example assumes Caddy runs on the Docker host. A containerized proxy needs reachable Compose service addresses instead of its own `localhost`. For Nginx, Traefik, cloud load balancers, or separate socket hosts, see [Networking](/platform/self-hosting/networking). ## Ollama -`docker-compose.ollama.yml` is a **development** stack, not a drop-in swap for `docker-compose.prod.yml`. It builds `simstudio`, `realtime`, and `migrations` from the source checkout instead of pulling published images, and it ships neither a `redis` service nor a `cron` service. Without an external Redis, pub/sub falls back to a process-local emitter and API-key login through the CLI pairing-code flow fails, since that approval store has no fallback; the idempotency store and execution progress markers do fall back to Postgres. And with no cron service, every [background job](/platform/self-hosting/background-jobs) is missing. For production with local models, keep `docker-compose.prod.yml` and point `OLLAMA_URL` at an Ollama instance, as under [External Ollama](#external-ollama) below. +### External Ollama -Always pass a server profile alongside `setup`. With `--profile setup` on its own no Ollama server starts and `model-setup` waits forever. +For production, keep this Compose stack and point `OLLAMA_URL` at an Ollama server. If it runs on the Docker host, save the address in `.env` so later recreations retain it: ```bash -# With GPU -docker compose -f docker-compose.ollama.yml --profile gpu --profile setup up -d - -# CPU only -docker compose -f docker-compose.ollama.yml --profile cpu --profile setup up -d +OLLAMA_URL=http://host.docker.internal:11434 ``` -The `setup` profile pulls `gemma3:4b` as a starter model. Pull additional models — the service name differs by profile: -```bash -# GPU profile -docker compose -f docker-compose.ollama.yml exec ollama ollama pull llama3.2 +Production Compose maps `host.docker.internal` to the host gateway, including on Linux. You can instead use a reachable host IP. The Ollama server must listen on an interface reachable from the container. -# CPU profile -docker compose -f docker-compose.ollama.yml exec ollama-cpu ollama pull llama3.2 +```bash +docker compose -f docker-compose.prod.yml up -d ``` -### External Ollama + + Container `localhost` is the container itself. The default `http://localhost:11434` does not reach an Ollama server on the host. + + +### Development Ollama stack -If Ollama runs on your host machine (not in Docker): +`docker-compose.ollama.yml` builds the app, realtime, and migrations from source. It does not bundle Redis or cron. Without Redis, pub/sub is process-local and CLI pairing approval has no fallback; idempotency and execution-progress storage can fall back to PostgreSQL. Without a scheduler, background jobs do not run. -Set it in the `.env` next to your Compose file. A one-shot shell prefix satisfies the interpolation for that command only, so the next `up -d` silently reverts to the `http://localhost:11434` default and the container points at itself: +Use a server profile together with `setup`; `setup` alone starts no Ollama server and the model setup waits: ```bash -# .env — macOS/Windows -OLLAMA_URL=http://host.docker.internal:11434 +# NVIDIA GPU +docker compose -f docker-compose.ollama.yml --profile gpu --profile setup up -d -# Linux - use your host IP -# OLLAMA_URL=http://192.168.1.100:11434 +# CPU only +docker compose -f docker-compose.ollama.yml --profile cpu --profile setup up -d ``` +Setup pulls `gemma3:4b`. To pull another model: + ```bash -docker compose -f docker-compose.prod.yml up -d -``` +# GPU profile +docker compose -f docker-compose.ollama.yml exec ollama ollama pull llama3.2 - - Inside Docker, `localhost` refers to the container, not your host. Use `host.docker.internal` or your host's IP. - +# CPU profile +docker compose -f docker-compose.ollama.yml exec ollama-cpu ollama pull llama3.2 +``` ## LM Studio -[LM Studio exposes an OpenAI-compatible API](https://lmstudio.ai/docs/developer/openai-compat). Start its local server, load a model, and enable **Serve on Local Network** so the Docker container can reach it. [Enable API authentication](https://lmstudio.ai/docs/developer/core/authentication), then set the endpoint and token in the `.env` file next to your Compose file: +Start [LM Studio's local server](https://lmstudio.ai/docs/developer/core/server), load a model, enable **Serve on Local Network**, and [configure API authentication](https://lmstudio.ai/docs/developer/core/authentication). Save these values beside your Compose file: ```bash -# macOS/Windows VLLM_BASE_URL=http://host.docker.internal:1234 - -# Linux - use your host IP instead -# VLLM_BASE_URL=http://192.168.1.100:1234 - VLLM_API_KEY=your_lm_studio_api_token ``` -Both the server root shown above and a URL ending in `/v1` are accepted. After recreating the `simstudio` service, its models appear in the model picker with a `vllm/` prefix; Sim removes that prefix before sending the model identifier to LM Studio. +Use a reachable host IP when needed. Sim accepts the server root or a `/v1` URL. Models appear with a `vllm/` prefix, which Sim removes before sending the model ID to LM Studio. + +Recreate the app using the file that started your installation: ```bash -# Pick the file that started your install. COMPOSE_FILE=docker-compose.prod.yml -# COMPOSE_FILE=docker-compose.local.yml -# COMPOSE_FILE=docker-compose.ollama.yml +# For a source-built stack, use docker-compose.local.yml or docker-compose.ollama.yml. docker compose -f "$COMPOSE_FILE" up -d --force-recreate simstudio ``` ## The `sim-setup` CLI -`npx sim-setup` also manages an existing install created from the production or local-development Compose files. It does not detect or manage an Ollama-stack install. Run `doctor`, `config`, and the wizard from the directory holding your `.env` and Compose file; the lifecycle commands find a running stack wherever it was started. The table drops the `npx` prefix for brevity — keep it unless you installed the package globally. +Invoke commands as `bunx sim-setup ` unless the package is installed globally. Run `doctor`, `config`, and the wizard from the configuration directory. Lifecycle commands discover running production/local Compose stacks, source checkouts, and Helm releases; Ollama-stack installs are not managed. + +| Command | Behavior | +| --- | --- | +| `sim-setup` | Wizard. `--quick` uses defaults and asks essential questions; `--mode compose\|dev\|k8s` chooses the target. Dev and Kubernetes modes require a source checkout. | +| `status` | Reports detected installations and health. | +| `logs` | Follows Compose logs or the Kubernetes app deployment. In dev mode, prints container log commands; the app runs in your terminal. | +| `start` / `stop` / `restart` | Starts, stops, or restarts Compose services. In dev mode, manages only PostgreSQL and Redis; start/stop the dev server yourself. For Kubernetes, prints port-forward or scale commands without applying them. | +| `update` | Pulls or rebuilds Compose images and applies them. Refuses dev and Kubernetes installs, which use git and `helm upgrade`. | +| `down` | Confirms before removing managed containers or uninstalling the Helm release. Compose/dev data volumes remain. | +| `reset` | Confirms before archiving env files and removing managed Compose/dev data. On Helm it uninstalls the release; PostgreSQL StatefulSet PVCs remain and must be deleted separately to erase data. | +| `config` | Reports configured capabilities and integrations. | +| `doctor` | Checks env files and reachable services. `--fix` writes supported repairs; `--json` emits structured findings. | +| `add ` | Configures `email`, `storage`, `sandbox`, `jobs`, `cache`, `knowledge`, `knowledge-embeddings`, `chat`, `llm`, or `integration `. Requires one writable configuration; refuses ambiguous destinations and Helm releases. | +| `desktop` | Prints this deployment's installer/server links. `--url ` skips discovery; `--no-open` skips the browser-opening prompt. | + +`--dir ` works with every command and scopes standalone lifecycle commands to that installation. -| Command | What it does | -|---|---| -| `sim-setup` | The setup wizard. `--quick` takes the defaults and asks only the essential questions, `--mode compose\|dev\|k8s` picks the target (`dev` and `k8s` need a source checkout) | -| `sim-setup status` | Show what is installed and healthy | -| `sim-setup logs` | Follow logs. On Kubernetes it follows the app deployment only; on a source checkout it prints where the logs are — the dev server streams in its own terminal — rather than following a stream | -| `sim-setup start` / `stop` / `restart` | Bring the install up, down, or cycle it. On a source checkout this covers only the managed Postgres and Redis containers — the dev server is yours to start and stop. On Kubernetes it acts on nothing: `stop` prints the `kubectl scale` equivalents, and `start` and `restart` print the port-forward commands for reaching the release | -| `sim-setup update` | Pull or rebuild images and apply them. Compose installs only — it refuses on source checkouts and Kubernetes, which update through git and `helm upgrade` | -| `sim-setup down` | After a confirmation prompt, remove containers and keep the data. On a source checkout it removes only the managed Postgres and Redis containers, keeping their volume. On Kubernetes it runs `helm uninstall` on the whole release | -| `sim-setup reset` | After a confirmation prompt, archive the env files and wipe managed data. A Compose install archives the `.env` beside its Compose file; a source checkout, a Kubernetes install, and an invocation with no install detected all archive `apps/sim/.env`, `apps/realtime/.env`, `packages/db/.env`, and the root `.env`. On Kubernetes it runs `helm uninstall`, which leaves the Postgres volumes behind — they come from a StatefulSet's `volumeClaimTemplates`, which Kubernetes never deletes. Delete those PVCs yourself to reset the data | -| `sim-setup config` | Show configured capabilities and integrations | -| `sim-setup doctor` | Check the setup. `--fix` repairs what it can, `--json` prints machine-readable output | -| `sim-setup add ` | Configure one capability: `email`, `storage`, `sandbox`, `jobs`, `cache`, `knowledge`, `knowledge-embeddings`, `chat`, `llm`, or `integration `. Writes to the `.env` beside your Compose file — recreate the containers that read the value to apply it, which for `cache` means `realtime` as well as `simstudio`, since both take `REDIS_URL` — or to `apps/sim/.env` on a source checkout, where `apps/realtime/.env` needs the same value. It refuses when no configuration is writable, when more than one is, and for Helm releases | -| `sim-setup desktop` | Resolve the desktop installer for this deployment. `--url ` skips discovery, and is required when several detected configurations name different `NEXT_PUBLIC_APP_URL` origins. `--no-open` skips the "Download it now?" prompt — the link is printed either way | +For Compose, `reset` archives `.env` beside the Compose file. For dev, Kubernetes, or no detected install, it archives `apps/sim/.env`, `apps/realtime/.env`, `packages/db/.env`, and root `.env`. Preserve any backups before intentionally removing volumes. -`--dir ` is accepted by every command, not just the wizard. On a standalone install it also scopes the lifecycle commands to that directory's install, which is how you disambiguate when more than one exists. +`add` writes beside the Compose file or to `apps/sim/.env` on a source checkout. Recreate containers that read the change: `cache` changes `REDIS_URL` for both app and realtime. For a source checkout, mirror shared values into `apps/realtime/.env`. `restart` alone does not apply changed container environment. Desktop discovery refuses configurations naming different origins; pass `--url` to choose. -## Commands +## Back up and update [#commands] + +For the default database role/name: ```bash -# Did migrations succeed? -docker compose -f docker-compose.prod.yml logs migrations +docker compose -f docker-compose.prod.yml exec -T db pg_dump -U postgres simstudio > backup.sql +``` -# Is the scheduler firing? -docker compose -f docker-compose.prod.yml logs -f cron +Restore only to the intended database: -# Upgrade: bump SIM_VERSION in .env when pinned, then -npx sim-setup update +```bash +docker compose -f docker-compose.prod.yml exec -T db psql -U postgres simstudio < backup.sql +``` + +Use your configured role/database if you changed `POSTGRES_*`. `-T` disables TTY allocation for redirected input/output. Compose stores database data in the `postgres_data` volume; file uploads and encryption keys need separate backups. + +For an image update, change the pinned `SIM_VERSION` in `.env`, then: + +```bash +bunx sim-setup update ``` - backup.sql. The -T matters — without it exec allocates a TTY and corrupts the redirected dump. Restore with: docker compose -f docker-compose.prod.yml exec -T db psql -U postgres simstudio < backup.sql. The database data is persisted in a Docker volume named postgres_data."}, - { question: "Can I customize the PostgreSQL credentials?", answer: "Yes. Set POSTGRES_USER (default: postgres) and POSTGRES_DB (default: simstudio) in .env before the first start. POSTGRES_PASSWORD has no default — the compose file will not start without it. Postgres applies all three only when it creates the database volume, so changing them later does not change the existing database; to rotate the password, see Postgres on Compose in the security guide." }, -]} /> +Read [Upgrades](/platform/self-hosting/upgrades) before updating or restoring an existing installation. + +## Related docs + +- [Environment variables](/platform/self-hosting/environment-variables) +- [Background jobs](/platform/self-hosting/background-jobs) +- [Security](/platform/self-hosting/security) diff --git a/apps/docs/content/docs/platform/self-hosting/email.mdx b/apps/docs/content/docs/platform/self-hosting/email.mdx index 91505212e2a..7b45e080f55 100644 --- a/apps/docs/content/docs/platform/self-hosting/email.mdx +++ b/apps/docs/content/docs/platform/self-hosting/email.mdx @@ -1,105 +1,99 @@ --- title: Email -description: Configure transactional email for invitations, verification, and notifications +description: Configure and verify transactional email delivery --- -import { Tabs, Tab } from 'fumadocs-ui/components/tabs' +import { Tabs, Tab } from '@/components/ui/tabs' import { Callout } from 'fumadocs-ui/components/callout' -Sim sends workspace invitations, email verification, password resets, and notifications. Configure at least one provider. +Configure a mail provider for workspace invitations, email verification, password resets, and notifications. Use a sender address the provider is authorized to send as. - With no provider configured, nothing is sent and nothing errors — the mailer logs a single line with the recipient, subject, and sender, then reports success. On a production deployment that means workspace invitations silently never arrive. The message body is **not** logged, so an email missed this way cannot be recovered from the logs. + Without a mail provider, Sim skips delivery and reports success. At INFO log level it records recipient, subject, and sender, but not the message body. Invitations and password resets will not arrive; the message cannot be recovered from those logs. Email verification is enforced only when a provider is configured. ## Provider selection -There is no provider flag. Every provider whose variables are set becomes active, and the mailer tries them in this fixed order, falling through to the next one only when the previous **fails**: +There is no provider-selection flag. Every configured, usable provider participates in this fallback order: **Resend → AWS SES → SMTP → Azure Communication Services → Gmail** -So the earliest configured provider handles normal traffic, and any others act as automatic failover. Configuring one is the simple case; configuring two gives you a fallback path at the cost of mail occasionally leaving from a different sender. +The first provider handles normal traffic. Later providers are tried only after a failure. Configure a single provider or verify the sender and permissions for every fallback you enable. ## Shared settings -| Variable | Description | -|---|---| -| `FROM_EMAIL_ADDRESS` | Sender address, e.g. `Sim ` | -| `EMAIL_DOMAIN` | Fallback domain when `FROM_EMAIL_ADDRESS` is unset — sends as `noreply@EMAIL_DOMAIN` | -| `EMAIL_VERIFICATION_ENABLED` | Set `true` to require email verification at signup | +| Variable | Behavior | +| --- | --- | +| `FROM_EMAIL_ADDRESS` | Sender, such as `Sim `. | +| `EMAIL_DOMAIN` | When the sender is unset, use `noreply@EMAIL_DOMAIN`. | +| `EMAIL_VERIFICATION_ENABLED` | Set `true` to require signup verification when a mail provider is configured. | -The sender address must be one your provider is authorized to send as. A mismatch is the most common cause of mail that is accepted by the provider and then silently dropped or spam-filtered downstream. - -## Providers +## Configure a provider [#providers] - - -Simplest option if you have no existing mail infrastructure. + ```bash RESEND_API_KEY=re_... FROM_EMAIL_ADDRESS="Sim " ``` -Verify your sending domain in the Resend dashboard and add the DNS records it gives you before sending in production. +Verify your sending domain and add Resend's DNS records before production delivery. See [Resend domain setup](https://resend.com/docs/dashboard/domains/introduction). - - + + ```bash AWS_SES_REGION=us-east-1 FROM_EMAIL_ADDRESS="Sim " ``` -Credentials resolve through the standard AWS provider chain — environment variables, shared config, ECS/EKS task role (IRSA), EC2 instance profile, or SSO. On EKS, attach an IRSA role with `ses:SendEmail` and `ses:SendRawEmail` and set no keys at all. +Credentials use the AWS default provider chain: environment/shared configuration, ECS/EKS roles, EC2 instance profile, or SSO. For EKS, an IRSA role can provide `ses:SendEmail` and `ses:SendRawEmail` without static keys. Verify your sending identity and configure DKIM in the chosen SES region. - New SES accounts are in the **sandbox**, which only permits sending to verified addresses. Invitations to your team will fail until you request production access. Verify the sending domain and configure DKIM as well. + New SES accounts start in a region-specific sandbox and can send only to verified recipients or the mailbox simulator. Request production access before inviting unverified recipients. See [SES sandbox restrictions](https://docs.aws.amazon.com/ses/latest/dg/request-production-access.html). - - + + -Works with any relay — Postfix, SendGrid, Mailgun, Google Workspace SMTP relay, or MailHog for local testing. +Use a reachable relay such as Postfix, SendGrid, Mailgun, Google Workspace SMTP relay, or a local test relay: ```bash SMTP_HOST=smtp.example.com -SMTP_PORT=587 # 465 implicit TLS, 587 STARTTLS, 25 plain -SMTP_USER=apikey # omit for unauthenticated relays -SMTP_PASS=... # omit for unauthenticated relays -# SMTP_SECURE=true # only for implicit TLS. Leave unset on 587 — it is - # automatic on 465, and forcing it on a STARTTLS port fails to connect -# SMTP_EHLO_NAME=mail.yourdomain.com # only if the relay expects an identity other - # than the domain Sim is served from +SMTP_PORT=587 +SMTP_USER=apikey +SMTP_PASS=... FROM_EMAIL_ADDRESS="Sim " ``` -Sim greets the relay with the domain it is served from, derived from `NEXT_PUBLIC_APP_URL`, so `SMTP_EHLO_NAME` is rarely needed. Without that derivation the underlying mail library would fall back to the address literal `[127.0.0.1]` on Kubernetes, where pod hostnames have no dot — a greeting strict relays reject outright. +Set both `SMTP_USER` and `SMTP_PASS` for authenticated relays, or omit both for an unauthenticated relay. Port 465 enables implicit TLS automatically. Leave `SMTP_SECURE` unset for port 587/STARTTLS; forcing implicit TLS there prevents connection. Port 25 uses a non-implicit-TLS connection. -For Google Workspace without a service account: +Sim derives its EHLO hostname from `NEXT_PUBLIC_APP_URL`. If the relay needs another identity, set `SMTP_EHLO_NAME` to a fully qualified hostname it accepts. + +For a Google Workspace IP-authorized relay: ```bash SMTP_HOST=smtp-relay.gmail.com SMTP_PORT=587 ``` -The relay must be configured to accept mail from your deployment's egress IP in the Workspace admin console. It needs no service account and no domain-wide delegation, so prefer it over the Gmail API path unless you cannot allowlist a stable egress IP. +Configure the relay in Workspace administration to accept the deployment's public egress IP and permitted senders. This path does not require a service-account key or domain-wide delegation. If a stable IP is unavailable, consider authenticated SMTP or the Gmail API path. See [Google SMTP relay settings](https://knowledge.workspace.google.com/admin/gmail/advanced/route-outgoing-smtp-relay-messages-through-google). - - + + ```bash AZURE_ACS_CONNECTION_STRING=endpoint=https://...;accesskey=... FROM_EMAIL_ADDRESS="Sim " ``` -Provision an Email Communication Service, connect a verified domain, then link it to the Communication Service resource. The sender address must belong to the linked domain. +Provision an Email Communication Service, verify its sending domain, and link that domain to the Communication Service. Use a sender from the linked domain. See [Azure's email-domain connection guide](https://learn.microsoft.com/en-us/azure/communication-services/quickstarts/email/connect-email-communication-resource). - - + + -GCP has no first-party transactional email service, so the Google-native path is the Gmail API with a Google Workspace sender. +Use a service account to impersonate a Google Workspace sender: ```bash GMAIL_CREDENTIALS_JSON='{"type":"service_account",...}' @@ -107,65 +101,93 @@ GMAIL_SENDER=noreply@yourdomain.com FROM_EMAIL_ADDRESS="Sim " ``` -Setup: - -1. Create a service account and download its JSON key. -2. In the Workspace admin console → **Security → Access and data control → API controls → Domain-wide delegation → Add new**, add the service account's `client_id` with the scope `https://www.googleapis.com/auth/gmail.send`. -3. Set `GMAIL_SENDER` to the Workspace user the service account impersonates. +1. Enable Gmail API in the Google Cloud project. +2. Create a service account, enable domain-wide delegation, and download its JSON key. +3. In Workspace administration, open **Security → Access and data control → API controls → Domain-wide delegation → Add new**. Add the service account's numeric `client_id` with `https://www.googleapis.com/auth/gmail.send`. +4. Set `GMAIL_SENDER` to the Workspace user to impersonate. See [Google service-account credentials](https://developers.google.com/workspace/guides/create-credentials). - `FROM_EMAIL_ADDRESS` must match `GMAIL_SENDER` or one of its registered aliases. Gmail rewrites unrecognized From addresses, so a mismatch produces mail that sends successfully but arrives from the wrong address. + `FROM_EMAIL_ADDRESS` must match `GMAIL_SENDER` or a registered alias. Gmail can rewrite an unrecognized sender even when delivery succeeds. - - Gmail caps sending at roughly 2,000 messages per day per user — ample for invitations and verification on most deployments. If you need more, switch to the Workspace SMTP relay or Resend; both are configuration-only changes. - +Paid Workspace accounts currently allow up to 2,000 messages per user over a rolling 24-hour period, with lower trial and separate recipient limits. Check [Google's sending limits](https://knowledge.workspace.google.com/admin/gmail/gmail-sending-limits-in-google-workspace) before choosing this path for your volume. SMTP relay has separate limits. -Keep the JSON on one line when pasting it into a values file: +For a single-line JSON secret: ```bash jq -c . service-account-key.json ``` - + -## Kubernetes +## Apply configuration + +For Compose, save provider settings in `.env` beside the Compose file and recreate the app: + +```bash +docker compose -f docker-compose.prod.yml up -d --force-recreate simstudio +``` + +For a source checkout, save them in `apps/sim/.env` and restart the app. -Email credentials are secrets. Supply them through your secret store rather than plain values: +### Kubernetes + +Choose one of the chart's [secret strategies](/platform/self-hosting/kubernetes#secret-stores): + +- **Inline mode:** set credentials under `app.env`; Helm writes them to a Secret but also retains them in release values. Do not commit secret values to Git. +- **Existing Secret:** add the provider keys to the pre-created app Secret. Credentials set explicitly under `app.env` in this mode are inlined into pod specs. +- **ESO:** map each credential under `externalSecrets.remoteRefs.app`; the chart-managed inline Secret is disabled. Use `app.envDefaults` for non-secret sender settings. + +For example, merge this into a complete ESO configuration whose store and core secrets are already configured: ```yaml app: - env: + envDefaults: FROM_EMAIL_ADDRESS: "Sim " - RESEND_API_KEY: "re_..." # via External Secrets or an existing Secret +externalSecrets: + remoteRefs: + app: + RESEND_API_KEY: "sim/app/resend-api-key" ``` -In the default and External Secrets modes, `app.env` keys are written into a chart-managed Secret and mounted via `envFrom`, so values do not appear in pod specs. A secret committed to `values.yaml` is still a secret in your git history — pass it through External Secrets or a pre-created Secret instead. +Restart the affected app pods after the credentials have synchronized: + +```bash +kubectl rollout restart deployment/sim-app -n simstudio +``` -## Verifying +## Verify delivery [#verifying] -Invite a user to a workspace from workspace settings and watch the app logs: +Invite a test member from workspace settings, confirm the message arrives, and accept it. If verification is required, also test a new account's verification message and a password reset. + +Set `LOG_LEVEL=INFO` and restart/recreate the app before using logs to diagnose skipped delivery. The production default is `ERROR`; log-level values are uppercase. ```bash kubectl logs -n simstudio -l app.kubernetes.io/component=app --tail=100 | grep -i mail ``` -| What you see | Meaning | -|---|---| -| A single log line with recipient, subject, and sender, and no delivery | No provider is configured — the mailer no-opped | -| A provider API error | Credentials or sender address problem; the error names which | -| Success, but nothing arrives | Delivered to the provider — check the provider's dashboard, then spam filtering, SPF, and DKIM | - -## Troubleshooting +For Compose, use `docker compose -f docker-compose.prod.yml logs simstudio`. -**"Delegation denied" / `unauthorized_client` (Gmail)** — the domain-wide delegation entry is missing or has the wrong client ID or scope. Re-check the admin console entry against the `client_id` in the service-account JSON, and confirm the scope is exactly `https://www.googleapis.com/auth/gmail.send`. +| Signal | Diagnosis | +| --- | --- | +| No-provider log with recipient, subject, and sender | Sim skipped delivery. Configure a usable provider. | +| Provider error | Check the named provider's credentials, sender, permissions, and quotas. Later configured providers may be tried. | +| Provider acceptance but no message | Check delivery status in its dashboard, recipient filtering, SPF, DKIM, and DMARC. Acceptance does not prove inbox delivery. | -**Mail rejected with a From-address error** — the sender is not authorized for the provider's verified domain. Align `FROM_EMAIL_ADDRESS` with the verified domain (and with `GMAIL_SENDER` on the Gmail path). - -**SES rejects recipients** — the account is still in the SES sandbox. Request production access. +## Troubleshooting -**Mail lands in spam** — configure SPF, DKIM, and DMARC for your sending domain. This is on your DNS, not on Sim. +| Failure | Action | +| --- | --- | +| Gmail `unauthorized_client` or delegation denied | Match the JSON `client_id` to the Workspace delegation entry and confirm the exact `gmail.send` scope and impersonated user. | +| Sender rejected or rewritten | Match the verified sender/domain; for Gmail, use the impersonated sender or its registered alias. | +| SES rejects an unverified recipient | Request production access in the configured region. | +| SMTP connection fails | Check host/port, reachability, matching username/password, and implicit TLS versus STARTTLS. | +| SMTP rejects EHLO, such as `421-4.7.0` | Set `SMTP_EHLO_NAME` to a dotted hostname accepted by the relay. Older releases used `[127.0.0.1]` on Kubernetes; upgrade to use the public-domain derivation. | +| Mail is filtered as spam | Verify sending-domain SPF, DKIM, and DMARC, then inspect provider delivery events. | -**SMTP fails at the greeting with `421-4.7.0 Try again later, closing connection. (EHLO)`** — the relay rejected how the client identified itself, not your credentials or IP allowlist. Strict relays, Google Workspace's among them, refuse a greeting that is not a fully-qualified domain name. Sim greets with the domain it is served from, so this should not occur; if it does, set `SMTP_EHLO_NAME` to a dotted hostname the relay accepts. Older releases always greeted as `[127.0.0.1]` on Kubernetes — upgrade rather than working around it. +## Related docs +- [Authentication](/platform/self-hosting/authentication) +- [Environment variables](/platform/self-hosting/environment-variables) +- [Verify your install](/platform/self-hosting/verify) diff --git a/apps/docs/content/docs/platform/self-hosting/environment-variables.mdx b/apps/docs/content/docs/platform/self-hosting/environment-variables.mdx index f31b1d32246..8c1b71b8143 100644 --- a/apps/docs/content/docs/platform/self-hosting/environment-variables.mdx +++ b/apps/docs/content/docs/platform/self-hosting/environment-variables.mdx @@ -1,10 +1,14 @@ --- -title: Environment Variables -description: Configuration reference for Sim +title: Environment variables +description: Deployment configuration, feature prerequisites, and limits --- import { Callout } from 'fumadocs-ui/components/callout' +Configure variables in the env files or secret strategy for your deployment. Restart source processes or recreate containers/pods after changes; a running process does not reread credentials. + +Production Compose derives `DATABASE_URL` and `BETTER_AUTH_URL` on its service definitions, overriding values in `.env`. Use `POSTGRES_*` and `NEXT_PUBLIC_APP_URL` there. Helm constructs the database URL from its database values. See [Docker](/platform/self-hosting/docker) and [Kubernetes secret strategies](/platform/self-hosting/kubernetes#secret-stores). + ## Required | Variable | Description | @@ -16,28 +20,28 @@ import { Callout } from 'fumadocs-ui/components/callout' | `INTERNAL_API_SECRET` | Internal API secret, at least 32 characters: `openssl rand -hex 32` | | `NEXT_PUBLIC_APP_URL` | Public app URL | -`openssl rand -hex 32` prints 64 hex characters. `ENCRYPTION_KEY` and `API_ENCRYPTION_KEY` must be exactly that — a value of any other shape throws the first time Sim encrypts or decrypts, not at startup. The rest are secrets of no fixed shape and only need 32 characters or more. The Sim app never checks — it runs its env schema with validation skipped — but the realtime service validates `BETTER_AUTH_SECRET` and `INTERNAL_API_SECRET` at boot and refuses to start if either is shorter. +`openssl rand -hex 32` prints 64 hex characters. Encryption keys require that format. The app skips its env schema validation; individual consumers can reject invalid values when first used. Realtime validates `BETTER_AUTH_SECRET` and `INTERNAL_API_SECRET` at boot and rejects values shorter than 32 characters. - `ENCRYPTION_KEY` and `API_ENCRYPTION_KEY` cannot be rotated or recovered. Losing either makes the data it protects permanently unreadable — workspace and personal environment variables, stored provider API keys, MCP OAuth credentials, and deployment/chat secrets in the first case, user-generated Sim API keys in the second. Back them up separately from the database. + Retain `ENCRYPTION_KEY` and `API_ENCRYPTION_KEY` across upgrades and restores. There is no supported in-place key rotation procedure; losing a key makes values encrypted with it unreadable — workspace and personal environment variables, stored provider API keys, MCP OAuth credentials, and deployment/chat secrets in the first case, user-generated Sim API keys in the second. Back them up separately from the database. -## Strongly recommended +## Feature prerequisites and coordination [#strongly-recommended] | Variable | Description | |----------|-------------| -| `API_ENCRYPTION_KEY` | Encrypts user-generated Sim API keys at rest, exactly 64 hex characters (32 bytes): `openssl rand -hex 32`. **When unset, API keys are stored in plain text** — the app logs a warning each time it encrypts or decrypts one and keeps working | -| `CRON_SECRET` | Bearer token for the background job endpoints: `openssl rand -hex 32`. **Required whenever background jobs are enabled** — the Helm chart's default, and the chart will not render without it, unless it comes from `app.secrets.existingSecret` or External Secrets. See [Background Jobs](/platform/self-hosting/background-jobs) | -| `REDIS_URL` | Redis connection string. Optional on a single replica; **required** past one app or realtime replica — see [Redis](/platform/self-hosting/redis) | +| `API_ENCRYPTION_KEY` | Encrypts stored Sim API-key material; use exactly 64 hex characters (`openssl rand -hex 32`). When unset, legacy API keys can be stored in plain text; the key getter logs a warning when called | +| `CRON_SECRET` | Bearer token for the background job endpoints: `openssl rand -hex 32`. **Required whenever background jobs are enabled** — the Helm chart's default, and the chart will not render without it, unless it comes from `app.secrets.existingSecret` or External Secrets. See [Background jobs](/platform/self-hosting/background-jobs) | +| `REDIS_URL` | Redis connection string. Required for cross-replica events and features with no fallback, such as CLI pairing approval. Some single-process storage paths can fall back to PostgreSQL or local state; see [Redis](/platform/self-hosting/redis) | | `REDIS_TLS_SERVERNAME` | TLS SNI override. Required when `REDIS_URL` uses `rediss://` with a bare IP, or the app throws the first time it opens a Redis connection | -| `NEXT_PUBLIC_SOCKET_URL` | WebSocket URL — defaults to the page origin; set only if realtime is on a separate host | +| `NEXT_PUBLIC_SOCKET_URL` | Public WebSocket URL. Proxied deployments default to the page origin; a localhost page uses port 3002. Set it for a separate realtime host. | | `TRUSTED_ORIGINS` | Comma-separated additional origins to trust for auth (apex + `www`, alias domains) | | `AUTH_TRUSTED_PROXIES` | Comma-separated reverse-proxy IPs/CIDRs so the client IP cannot be forged through `X-Forwarded-For` | -| `INTERNAL_API_BASE_URL` | Internal URL for server-side self-calls, e.g. `http://sim-app.simstudio.svc.cluster.local:3000`. Optional — falls back to the public base URL. Deliberately ignored inside the Trigger.dev worker runtime, where a cluster-internal address resolves to the worker itself | +| `INTERNAL_API_BASE_URL` | Internal URL for server-side self-calls, e.g. `http://sim-app.simstudio.svc.cluster.local:3000`. Defaults to the public base URL. The Trigger.dev worker ignores it and uses the public app URL. | | `SIM_MCP_URL` | Public URL of the [Sim MCP server](/mcp/overview) when you serve it on its own host, e.g. `https://mcp.example.com/mcp`. Point that host at the app; Sim serves only the MCP endpoint and its OAuth metadata there, and stops serving `/api/mcp` on the app host so clients use one URL. Optional — defaults to `/api/mcp` | | `DATABASE_REPLICA_URL` | Read-replica connection string for log listing, audit logs, and dashboard aggregations. Falls back to the primary when unset | -## AI Providers +## AI providers | Variable | Provider | |----------|----------| @@ -56,19 +60,13 @@ import { Callout } from 'fumadocs-ui/components/callout' | `OLLAMA_URL` | Ollama (default: `http://localhost:11434`) | | `VERTEX_PROJECT` / `VERTEX_LOCATION` | Google Vertex AI — GCP project ID and region (region defaults to `us-central1`) | - - **Knowledge bases need an embedding model, selected with `KB_EMBEDDING_MODEL`.** Hosted: `text-embedding-3-small` (default) and `text-embedding-3-large` on OpenAI or Azure OpenAI, and `gemini-embedding-001` on Gemini. Local: any embedding model on your own Ollama, named `ollama/` (for example `ollama/nomic-embed-text`) with `OLLAMA_URL` set. Ollama serves embeddings only through this variable — embeddings never route through the configured chat model, so vLLM and LM Studio do not substitute. - +Knowledge bases use an embedding model independent of the chat model. See [Knowledge bases](#knowledge-bases) for supported providers, local Ollama, and vector widths. - - For load balancing, add multiple keys with `_1`, `_2`, `_3` suffixes (e.g., `OPENAI_API_KEY_1`, `OPENAI_API_KEY_2`). Works with OpenAI, Anthropic, Gemini, xAI, Kimi, Z.ai, Cohere, and Fireworks. - +For provider-key rotation, configure `_1`, `_2`, and `_3` keys, such as `OPENAI_API_KEY_1` and `OPENAI_API_KEY_2`. OpenAI, Anthropic, Gemini, xAI, Kimi, Z.ai, Cohere, and Fireworks support numbered keys. - - In Docker, use `OLLAMA_URL=http://host.docker.internal:11434` for host-machine Ollama. - +For Ollama on the Docker host, use `OLLAMA_URL=http://host.docker.internal:11434` and ensure its server is reachable from the container. - + **Agent tool-call depth.** An Agent block keeps calling tools until the model answers, with no round-trip limit by default. With billing disabled there is also no execution timeout unless `EXECUTION_TIMEOUT_FREE` (sync) or `EXECUTION_TIMEOUT_ASYNC_FREE` (async) is set, so a looping agent keeps making paid model calls. Set `MAX_TOOL_ITERATIONS` (for example `MAX_TOOL_ITERATIONS=50`) to cap the model round trips per block, or set those timeouts to bound the whole run. @@ -92,7 +90,7 @@ import { Callout } from 'fumadocs-ui/components/callout' |----------|-------------| | `AZURE_OPENAI_API_KEY` | Azure OpenAI API key | | `AZURE_OPENAI_ENDPOINT` | Azure OpenAI endpoint URL | -| `AZURE_OPENAI_API_VERSION` | API version (e.g., `2024-02-15-preview`) | +| `AZURE_OPENAI_API_VERSION` | API version supported by your Azure model/deployment; check the [API lifecycle](https://learn.microsoft.com/en-us/azure/ai-foundry/openai/api-version-lifecycle) | | `KB_OPENAI_MODEL_NAME` | Azure deployment name serving the knowledge base embedding model. Optional — defaults to the model id, which is only correct when the deployment is named after the model | ### Azure Anthropic @@ -121,94 +119,21 @@ import { Callout } from 'fumadocs-ui/components/callout' | `LITELLM_BASE_URL` | LiteLLM proxy base URL | | `LITELLM_API_KEY` | Optional bearer token for LiteLLM | -## Login Providers - -Google, GitHub, and Microsoft sign-in, their callback URLs, and the `DISABLE_*_AUTH` switches are documented in [Authentication](/platform/self-hosting/authentication#social-login). - -## Integration Credentials - - - OAuth integrations require a provider application and its credentials on a self-hosted deployment. API-key integrations use the keys supplied in their blocks. The full table, redirect-URI format, and setup steps are in [Integrations & OAuth](/platform/self-hosting/integrations-oauth). - - -## Access Control - -Who may sign up and sign in — the allowlists, blocklists, `DISABLE_REGISTRATION`, `DISABLE_INVITATIONS`, `DISABLE_PUBLIC_API`, and `DISABLE_AUTH` — is documented in [Authentication](/platform/self-hosting/authentication). - -## Code Execution - -| Variable | Description | -|----------|-------------| -| `SANDBOX_PROVIDER` | Remote sandbox provider: `e2b` (default) or `daytona` | -| `E2B_ENABLED` / `E2B_API_KEY` | Enable E2B remote execution | -| `DAYTONA_API_KEY` | Daytona API key (used when `SANDBOX_PROVIDER=daytona`) | -| `E2B_FUNCTION_TEMPLATE_ID` | Immutable `