mirror of
https://github.com/simstudioai/sim.git
synced 2026-09-24 15:45:35 +08:00
* improvement(platform): workspace UI/UX overhaul + integrations catalog Rework the workspace around the AI-workspace model: a Mothership home, a top-level Skills route, connected-credential and integration-detail pages, and a polished sidebar/settings surface. Replace the notifications store with a unified toast system (provider-level dismiss/pause, countdown ring). Integrations & catalog: - Add a BlockMeta layer (tags + catalog templates) scoped to catalog-visible integrations; every catalog integration carries >=7 grounded templates. - Rework the taxonomy: each block declares category tools|blocks|triggers. 3rd-party services are 'tools'; first-party primitives (postgres, mysql, knowledge, file, search, stt/tts, image/video generators, thinking, etc.) are 'blocks'. Versioned blocks follow the upgrade paradigm (old hidden, latest in toolbar/docs). - Generate integrations.json + tool docs canonically from block configs. Architecture & cleanup: - Consolidate block data extraction behind a single latest-version strategy (getCanonicalBlocksByCategory; version-consistent getBlockMeta). - Unify version-suffix handling in @sim/utils/string (stripVersionSuffix / isVersionedType, with tests); registry, generate-docs, tools/utils, and integrations all route through it. - Repair latent broken barrels, remove dead code, fix BlockMeta-related type errors and 5 broken docs links. Behavior-preserving for block execution and the toolbar's tool/block listing. * refactor(platform): remove forms, templates, and creators features Remove three standalone features and their supporting code: - Forms: form-deployment pages, API routes, execution path, and docs. - Templates: the template gallery (landing + workspace) and template APIs. - Creators: creator-profile routes and contracts. Add a super-user permissions module (lib/permissions/super-user) and an organizations API contract; update the audit/db/testing packages, billing, and the session/theme providers accordingly. * test(workflows): update archiveWorkflow update count after forms removal The forms feature was removed, dropping the form-table update from archiveWorkflow. Update the stale assertion from 8 to 7 tx.update calls. * upgrade * improvement(knowledge): polish tag filter dropdowns (#4816) * improvement(logs): object storage backed tracespans (#4787) * improvement(logs): obj storage backed tracespans * fix storage write context * fix tests * address comments * address comments * chore(db): remove migration 0219 to regenerate after staging merge Drops the 0219_robust_shard SQL, its snapshot, and the journal entry so the trace-spans/cost schema migration can be regenerated on top of the latest staging migration chain (avoids a number collision with staging's migrations). Co-authored-by: Cursor <cursoragent@cursor.com> * improvement(billing): accurate per-member usage via shared ledger helper Per-member/per-user usage in the org-member routes now adds the usage_log ledger to the currentPeriodCost baseline (which is no longer incremented), via a shared getOrgMemberLedgerByUser helper to avoid repeating the subscription→period→ledger lookup across the admin and member-facing routes. Co-authored-by: Cursor <cursoragent@cursor.com> * regen migrations * update migration * address comments * more code cleanup * incorrect type cast --------- Co-authored-by: Cursor <cursoragent@cursor.com> * improvement(providers): harden OpenAI-compatible providers + add tests (#4796) * improvement(providers): harden OpenAI-compatible providers + add tests * fix(vllm): let tool-loop errors propagate instead of returning silent partial success * fix(litellm): force tool_choice 'none' on final structured-output call The deferred final call used tool_choice 'auto', so the model could emit another tool_calls round instead of the structured answer, leaving content stale. Use 'none' (matching vLLM/Fireworks) on both the streaming and non-streaming final calls so the model must return the structured response. Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com> * fix(providers/ollama): drop tools from post-tool streaming call Ollama ignores tool_choice (not in its supported fields), so vLLM/Fireworks' tool_choice:'none' guard is a no-op here. Omit tools from the final streaming payload instead so the summarization turn can't emit dropped tool calls. Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com> * fix(litellm): spread payload into deferred final call so reasoning_effort carries over The non-streaming deferred finalPayload hand-picked fields and dropped reasoning_effort (and any future payload field), diverging from the streaming path which spreads ...payload. Spread payload here too for consistency. Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com> * chore(providers/ollama): restore enrichment TSDoc block Keeps parity with sibling Chat Completions providers (cerebras/mistral/xai). Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com> * docs(fireworks): restore TSDoc on utils helpers Restore the TSDoc blocks on supportsNativeStructuredOutputs, createReadableStreamFromOpenAIStream, and checkForForcedToolUsage — TSDoc is the codebase documentation standard and should not have been stripped. Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com> * chore(litellm): remove inline rationale comments (codebase uses TSDoc) Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com> * chore(providers/ollama): drop orphaned enrichment TSDoc The block documented a function that now lives in trace-enrichment.ts, so it documents nothing in this file. Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com> --------- Co-authored-by: Claude Opus 4.8 <noreply@anthropic.com> * chore(copilot): deprecate mcp server (#4797) * chore(copilot): deprecate mcp * update error codes * deprecate copilot api v1 route * feat(integrations): hosted API keys for Findymail, Prospeo, and Wiza (#4777) * feat(integrations): hosted API keys for Findymail, Prospeo, and Wiza Add hosted-key support across all credit-consuming Findymail, Prospeo, and Wiza operations so Sim provides the key when a workspace has not brought its own. Register the three BYOK providers, consolidate Wiza's two-step reveal into a single polling wiza_individual_reveal op, and hide the API key field on hosted Sim for hosted operations. * fix(integrations): harden Wiza reveal polling, soften enrichment getCost guards Address Greptile + Cursor Bugbot review on #4777: return explicit failures from the Wiza individual_reveal poller instead of throwing (thrown errors were swallowed into a false queued success), short-circuit when the initial reveal is already terminal, tolerate transient 5xx/429 during polling, and return 0 (not throw) from Findymail getCost when the contacts/employees array is absent. * chore(integrations): biome formatting after wiza merge resolution * fix(wiza): type isTerminalReveal param structurally for next build typecheck * feat(enrichments): add Findymail, Prospeo, Wiza to work-email waterfall * feat(enrichments): add Wiza + Prospeo phone reveal to phone-number waterfall * feat(enrichments): opportunistic identifiers + LinkedIn URL input across work-email & phone cascades * fix(tables): reduce column header chevron size and fix sidebar shadow bleed (#4800) * feat(slack): add install + privacy section to integration landing page (#4799) * feat(slack): add install + privacy section to integration landing page Adds a hand-authored, slug-keyed landing-content module (separate from the generated integrations.json so it survives regeneration) and renders an install walkthrough + privacy-policy link on integration pages when present. Also refreshes generated docs (data-enrichment entry, icon mappings, tool mdx). * fix(landing): render privacy section independently, align CTA analytics label * docs(landing): clarify the Slack install button is behind sign-in * refactor(landing): bake integration landing content into generated json via docs-gen Moves landing content (install walkthrough + privacy) out of a render-time augment and into the generation pipeline: generate-docs reads the pure-data content map and writes landingContent into integrations.json, so the page reads a single source (integration.landingContent). Canonical types live in integrations/data/types.ts. * improvement(enrichments): align enrichments sidebar with design system (#4801) * improvement(enrichments): align enrichments sidebar with design system * fix(enrichments): consistent close button pattern and fix url link hover * fix(misc): upgrade path change for new better-auth version, billing issue for workflow block agent usage (#4803) * fix(misc): upgrade path change for new better-auth version, double-billing for workflow block agent usage * fail loudly if stripe sub id missing * fix(copilot): seq migration (#4804) * chore(db): drop redundant idx_webhook_on_workflow_id_block_id index (#4809) Removed because (workflow_id, block_id) is a left-prefix of idx_webhook_on_workflow_id_block_id_updated_at_desc, which fully covers it. The dropped index was non-unique and enforced no constraint. * perf(copilot): read chat transcripts from copilot_messages (R+1 cutover) (#4808) * perf(copilot): read chat transcripts from copilot_messages, not JSONB Flip user-facing chat reads from the legacy copilot_chats.messages JSONB array (5.7GB, 99% TOAST) to the normalized copilot_messages table via a new loadCopilotChatMessages helper ordered by seq NULLS LAST, created_at, id — the verified canonical order. Both chat-detail getters (getAccessibleCopilotChat, getAccessibleCopilotChatWithMessages) now drop the messages column from their metadata select (no more whole-array detoast on every load) and assemble the transcript from the table after authorization. This cascades to the copilot + mothership GET endpoints and to resolveOrCreateChat's conversationHistory (the LLM payload). The normalize/effective-transcript pipeline is source-agnostic (copilot_messages.content == a JSONB array element), so transcripts are byte-identical. Dual-write and the JSONB column stay in place as the internal-logic source and fallback; removing JSONB writes is a later step. Prod integrity verified before cutover: 0 messages missing, 0 NULL-seq, 0 dup keys/seq, 0 orphans, order-parity vs JSONB = 0 mismatches. Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com> * test(copilot): cover auth-deny on a found row skips the messages query Address PR review: exercise the `if (!authorized) return null` contract — when the chat row exists but authorization fails, the getter returns null and never issues the copilot_messages read. Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com> --------- Co-authored-by: Claude Opus 4.8 <noreply@anthropic.com> * fix(tables): right-align run/stop in embedded toolbar; workflow cells format like normal cells (#4806) * fix(tables): right-align run/stop in the embedded table toolbar Add a right-aligned `trailing` slot to ResourceOptionsBar and move the embedded mothership table's run/stop control into it, so Filter + Sort stay left-aligned and run/stop sits opposite on the right. No-op for the search-bearing consumers (logs, resource list), which don't pass `trailing`. Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com> * fix(tables): workflow-output cells format values like normal cells Workflow-output columns short-circuited in resolveCellRender and rendered their value as plain text, so a sim-resource URL / external URL / JSON / date produced by a workflow never got the chip, favicon link, or typed formatting a normal cell gets. Factor value formatting into a shared `resolveValueKind` helper used by both the workflow-value branch and the plain-cell branch; the workflow branch keeps the typewriter reveal for plain streaming text via a `typewriter` flag. Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com> * fix(tables): detect resource/URL links on workflow output regardless of column type Workflow output columns default to `json` (columnTypeForLeaf), so routing their values through the type-based formatter (a) gated chip/URL promotion behind `column.type === 'string'` — a URL produced by a json-typed output never became a chip — and (b) JSON.stringify'd plain string values, adding quotes and losing the typewriter reveal. Detect links (sim-resource chip / favicon URL) on the value string directly for workflow outputs, falling back to the plain `value` kind; plain cells keep the type-based formatting. Addresses Greptile P2 on #4806. Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com> --------- Co-authored-by: Claude Opus 4.8 (1M context) <noreply@anthropic.com> * fix(icons): repair broken integration icon rendering (#4810) * fix(icons): repair broken integration icon rendering Two distinct bugs left integration icons broken on the /integrations page (visible at 32-40px, hidden at the toolbar's 16px): 1. Corrupted SVG paths (Notion, Greptile, Granola, Calendly, Grafana, Bedrock): over-minified data dropped elliptical-arc flag digits (e.g. `A1 1 0 5.9 7` instead of `A1 1 0 0 0 5.9 7`); Granola's cubic stream was truncated. Browsers abort path parsing at the first invalid arc flag, so each rendered as a fragment or blank. Replaced with correct path data from canonical sources, preserving each icon's existing fill/gradient and bgColor. 2. Invisible glyph (Bright Data): its icon uses fill='currentColor' but bgColor was '#FFFFFF', and every surface forces text-white on the glyph - white-on-white. Changed bgColor to Bright Data's brand blue (#3d7ffc) so the white glyph reads, matching the white-glyph-on-brand-chip convention. Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com> * fix(icons): restore Calendly dual-tone brand colors Addresses review feedback: the previous fix replaced the broken Calendly icon with a monochrome #006BFF path, dropping the cyan #0ae8f0 accent from the original dual-tone mark. Restored the two-tone logo (blue + cyan) using clean, valid path data, cropped to a tight square viewBox so it fills the chip. Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com> * improvement(icons): enlarge icons, fix Zoom contrast and Quiver chip - Zoom: glyph was blue-on-blue (#0B5CFF on #2D8CFF chip); switched to currentColor so it renders as a white glyph on the blue chip. - Quiver: chip bgColor #000000 -> #FFFFFF to match the icon's near-white box, and enlarged the mark slightly (viewBox crop). - Enlarged (tightened viewBox, verified no clipping): RevenueCat, Prospeo, Granola, Firecrawl, Enrich.so, and the AWS icons (RDS, DynamoDB, SQS, CloudFormation, Athena, CloudWatch, SES, Bedrock, S3). - ZoomInfo left unchanged: it is a full red rounded-square logo that already fills its frame, so a crop would clip it. Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com> * fix(icons): use Bright Data wordmark on white chip; repair Circleback - Bright Data: replaced the flame glyph with the official two-tone 'bright data' wordmark (provided asset), centered in a symmetric viewBox. Reverted the chip bgColor from #3d7ffc to #FFFFFF since the blue wordmark is invisible on a blue chip (the wordmark is designed for a light background). - Circleback: a minifier had rounded the pattern's image scale to scale(0), collapsing the embedded logo to zero size (invisible). Restored the correct scale (1/280 = 0.00357142857) so the C. mark renders. Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com> * fix(docs): sync Quiver block color card to white chip Reflects the Quiver bgColor change (#000000 -> #FFFFFF) in the docs block info card. Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com> * improvement(icons): enlarge AWS/Cloudflare/Dagster icons, fully white Zoom - Enlarged (tighter viewBox, render-verified, no clipping): Cloudflare, Dagster, and the red AWS icons AWS IAM, Identity Center, Secrets Manager, SES, STS. Identity Center was anomalously small (filled ~32% of its frame); the group is now sized consistently (~80% fill). - Zoom: the camera lens triangle was still #0B5CFF (blue-on-blue); switched it to currentColor so the whole camera renders white on the blue chip. Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com> * docs(wiza): consolidate individual reveal into a single operation Merges the separate Start/Get Individual Reveal operations into one Individual Reveal operation in the Wiza docs and integrations data (operationCount 5 -> 4). Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com> * improvement(icons): size remaining AWS icons to match the set (~80% fill) Bring RDS, DynamoDB, SQS, CloudFormation, Athena, CloudWatch and S3 up to the same ~80% fill as the AWS IAM/Identity Center/Secrets Manager/SES/STS group, so all AWS icons are visually consistent. Bedrock left as-is (already ~92% fill). Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com> * fix(icons): use Bright Data flame mark, enlarge ZoomInfo - Bright Data: the full 'bright data' wordmark was illegible at chip size. Replaced with just the flame-'i' brand mark (blue #4280f6 on the white chip), centered. - ZoomInfo: cropped the viewBox toward the white 'Zi' so it's larger; the red rounded-square background still fills the chip. Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com> * improvement(icons): enlarge CrowdStrike icon The falcon mark sat small in its chip because the icon used a wide 768x500 viewBox (letterboxed in the square chip). Switched to a square viewBox centered on the mark so it fills ~80%, consistent with the other icons. Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com> --------- Co-authored-by: Claude Opus 4.8 <noreply@anthropic.com> * fix(tables): serialize schema mutations to prevent parallel column clobber (#4812) * Make workflow description nullable * fix(tables): serialize schema mutations to prevent parallel column clobber * fix(tables): load workflow outside schema lock; use DbOrTx for getTableById * fix(tables): scale idle timeout in updateColumnType to avoid aborting large type changes * fix(tables): skip stale remap types when workflowId changes concurrently * fix(tables): scale idle timeout in updateColumnConstraints for large tables * fix(wait): resume live/draft async waits and preserve cell context on chained waits (#4814) * Make workflow description nullable * fix(wait): resume live/draft async waits and preserve cell context on chained waits * improvement(knowledge): polish tag filter dropdowns * improvement(knowledge): soften filter section labels * improvement(knowledge): soften list filter labels * fix(security): harden SSO domain registration, webhook path isolation, and CSV export (#4813) * fix(security): harden KB file access, SSO domain registration, webhook path isolation, env secrets, and CSV export * fix(sso): scope domain conflict query with indexed lower(domain) filter Address PR review: avoid a full-table scan on every SSO provider registration by filtering candidate rows in SQL with lower(domain) = <normalized>, keeping the in-memory ownership check. Also tighten the normalizeSSODomain TSDoc. Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com> * chore: condense env route security comments Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com> * icons update * chore(security): tighten inline comments in CSV export and KB file authorization Condense verbose comment blocks to concise TSDoc/single-line form; no behavior change. Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com> * fix(security): validate internal serve origin in KB file authorization Replace the bypassable isInternalFileUrl substring check in resolveInternalKbKey with an origin allow-list (base URL, internal API base URL, TRUSTED_ORIGINS). A crafted external host whose path is /api/files/serve/<victim-key> no longer resolves to the victim key. Relative same-origin URLs are unaffected. * style(sso): use idiomatic sql lower() comparison for domain conflict query Match the repo's prevailing `sql`lower(col) = value`` idiom for the case-insensitive SSO domain conflict lookup. Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com> * fix(security): align workspace env admin gate with hasWorkspaceAdminAccess Use the same admin check the secrets UI uses (owner, admin permission, or org-admin) so owners and org-admins are not wrongly denied their own decrypted workspace secrets, while read-only members remain restricted to names only. Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com> * fix(sso): rely on lower(domain) match for conflict detection, drop dead in-memory recheck Address PR review: the SQL `lower(domain) = <normalized>` predicate already excludes rows that the in-memory `normalizeSSODomain(...) === domain` recheck claimed to catch, making that recheck dead/misleading code. Match on the canonical lower-cased domain and filter purely by ownership. Malformed legacy values (wildcards, schemes, ports) never match an email domain at sign-in, so excluding them is not a gap. Test DB mock now applies the lower() predicate so the casing-variant case is genuinely exercised. Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com> * fix(security): scope webhook deploy path conflict to active webhooks findConflictingWebhookPathOwner omitted the isActive filter that the runtime dispatcher (findAllWebhooksForPath) applies, so an inactive but non-archived webhook from another workflow (e.g. after undeploy or failure auto-disable) would permanently block any new deployment on that path even though it never receives deliveries. Align the guard with the runtime isActive + archivedAt filter; the earliest-owner runtime check remains the authoritative cross-tenant protection. Also trims verbose TSDoc on the webhook path-isolation helpers. Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com> * fix(security): exclude archived workflows from webhook deploy path conflict findConflictingWebhookPathOwner now joins workflow and filters isNull(workflow.archivedAt), matching the runtime dispatcher (findAllWebhooksForPath). A webhook on an archived workflow can never receive deliveries at runtime, so it must not block legitimate path reuse with a 409. Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com> * fix(security): anchor KB file ownership to earliest document in any state A KB file's owner is now the earliest document referencing its key regardless of state (active/archived/deleted/excluded); access is granted only when that owning document is still active. Closes the residual where an attacker could plant an active document to claim a file whose original document was archived or deleted. * updated greptile icon * revert(security): drop KB file authorization changes Reverts the knowledge-base file-access work (origin-pinning / owner-pinning / origin allow-list in verifyKBFileAccess) and its test. The other hardening fixes (SSO domain registration, webhook path isolation, workspace env secrets, CSV export) are unchanged. apps/sim/app/api/files/authorization.ts is restored to its origin/staging baseline. * fix(sso): treat caller's own user-scoped provider as owned during conflict check Self-hosters often register SSO user-scoped via the CLI script (no SSO_ORGANIZATION_ID). If they later enable organizations and reconfigure the same domain org-scoped through the UI, the conflict check previously treated their own user-scoped row as another tenant's and returned a misleading 409. Recognize the caller's own user-scoped provider as owned so that migration is allowed, while still blocking another user's or another org's domain. Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com> * revert(security): remove workspace-env admin gate Defer to a credential-based access model (separate change). Restores GET /api/workspaces/[id]/environment to main behavior and removes the test. Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com> * refactor(security): consolidate webhook path-collision check into one helper Extract findConflictingWebhookPathOwner to lib/webhooks/utils.server.ts as the single source of truth for cross-tenant path-collision detection, used by both webhook creation paths (deploy sync and the manual /api/webhooks route). This also repairs two latent issues in the manual route's previous inline check, which queried with limit(1) and only webhook.archivedAt: - limit(1) inspected one arbitrary row, so a same-workflow row could mask a foreign collision (false negative). The shared helper scans all matching rows. - It omitted isActive/workflow.archivedAt, so inactive or archived-workflow webhooks (which never receive deliveries) permanently blocked path reuse. The helper mirrors the runtime dispatcher's filter. Same-workflow webhook reuse for upsert is now a separate, explicit lookup. Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com> --------- Co-authored-by: Claude Opus 4.8 <noreply@anthropic.com> * fix(security): block private/reserved IPs for hosted 1Password Connect SSRF (#4818) * fix(security): block private/reserved IPs for hosted 1Password Connect SSRF * test(security): use real isPrivateOrReservedIP and cover IPv6 edge cases * improvement(integrations): validate and expand devin, cursor, and greptile (#4820) * improvement(integrations): validate and expand devin, cursor, and greptile - devin: fix missing org_id path segment on all session endpoints, add 7 session sub-resource tools (list messages/attachments, get/append/replace tags, archive, terminate), pagination, and is_archived output - cursor: add get_api_key_info, list_models, list_repositories tools - greptile: align block and docs - normalize array outputs to default [] and tighten types * refactor(cursor): simplify list_repositories v2 array normalization Collapse the redundant `?? []` + `Array.isArray` double-guard into a single Array.isArray check, per PR review feedback. Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com> * fix(devin): scope session-tag mapping to tag ops and normalize array tag inputs - Only map sessionTags into the tools tags param for append/replace operations, preventing stale sessionTags state from clobbering create_session tags - Fall back to a wired tags value when sessionTags is empty for tag operations - Normalize tag inputs (string or wired string[]) via normalizeTags so array values from other blocks no longer throw on .split Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com> * fix(cursor): restore base64 file data in legacy download_artifact metadata The legacy CursorBlock exposes only content + metadata (no v2 file output), so metadata.data was the only way legacy-block workflows could access downloaded artifact bytes. Restore the base64 data field and document it in the outputs/type instead of dropping it. Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com> * fix(devin): coerce terminateArchive to archive flag for boolean-wired input * docs(integrations): regenerate tool docs for new devin and cursor operations --------- Co-authored-by: Claude Opus 4.8 <noreply@anthropic.com> * fix(search-replace): don't auto-navigate when content edits invalidate the active match (#4819) * fix(search-replace): don't auto-navigate when content edits invalidate the active match * fix(search-replace): clear afterReplaceIndexRef on apply failure and zero matches * fix(search-replace): remove duplicate setActiveSearchTarget(null) on close * fix(search-replace): move afterReplaceIndexRef write inside handleApply past the guard * fix(search-replace): auto-navigate when hydration resolves with no prior active match * chore(search-replace): remove inline comments * fix(search-replace): revert !activeMatchId guard that caused immediate re-navigation after deselect * improvement(enrichments): limit company-info to fields both providers return (#4817) Hunter's company dataset returns null industry/foundedYear for many large companies (verified against the live API for Microsoft, Amazon, Google), so under the first-non-empty-wins cascade those columns appeared inconsistently across rows. Limit company-info outputs to employee count and description — the fields Hunter and PDL both reliably return — so every row is consistent. employeeCount is a string so Hunter's range bucket and PDL's exact count share the column. * fix(files): don't reject external URLs containing '..' in file parse validation (#4821) * fix(files): don't reject external URLs containing '..' in file parse validation The file block's file_fetch operation rejected any external URL whose path contained '..' (e.g. Slack files-pri slugs with a literal '...') with 'Access denied: path traversal detected'. Traversal checks only apply to local paths — external http(s) URLs are fetched with SSRF protection downstream and are never resolved against the filesystem, so they now short-circuit as valid. Internal /api/files/serve/ URLs keep full traversal protection. * test(files): fix external-URL assertion to handle undefined error * test(files): assert success explicitly in external-URL traversal test * fix(files): keep traversal protection for https URLs matching internal serve paths * feat(google-sheets): add row filtering to read with numeric operators (#4822) * feat(google-sheets): add row filtering to read with numeric operators Adds client-side row filtering to the Google Sheets read (v2) operation. Filter the returned rows by a header column using text operators (contains, not_contains, exact, not_equals, starts_with, ends_with) and numeric/ordering operators (gt, gte, lt, lte). Filtering lives in a pure, unit-tested helper (filterSheetRows) and runs over the fetched read range; an optional `filter` output reports whether the column was found and how many rows matched. Also hardens the surrounding tools: - trim spreadsheetId in write/update/append URL builders (matches read) - URL-encode the v1 read default range - expose valueInputOption for the update operation in the block Backwards compatible: with no filter requested, read output is byte- identical and the `filter` field is omitted. The filterMatchType union is widened additively (4 -> 10 values). * fix(google-sheets): correct filter metadata for missing column and header-only sheets - matchedRows is now 0 (not totalRows) when the filter column is not found, so it no longer contradicts applied=false / columnFound=false - columnFound now reflects an actual header lookup for empty/header-only sheets instead of being hardcoded true - add tests covering header-only and empty sheets with present/absent columns * fix(selectors): fetch all pages for paginated dropdown list routes (#4823) * fix(selectors): fetch all pages for paginated dropdown list routes Dropdown selectors fetched only the first page of paginated provider APIs, silently hiding results past page one. Add bounded server-side draining to the list routes across Microsoft Graph, Google, Notion, Atlassian, Linear, AWS CloudWatch, and offset/token REST APIs, plus a shared client-side drain cap in the selector hook. Response shapes, stored values, and tool execution are unchanged; CloudWatch list tools still honor a caller-supplied limit. Also fixes the Word file picker that was searching for .xlsx files. * fix(selectors): harden JSM and Monday pagination draining - JSM service-desk/request-type drains advance `start` by the actual row count returned (not the fixed page size) and stop on an empty page, so a short non-final page can't skip items. - Monday boards drain now checks `response.ok` per page, surfacing a mid-drain HTTP failure instead of treating it as an empty final page and returning a partial 200. * docs(selectors): clarify JSM drain advances start by actual row count The offset-advancement fix (advance `start` by the rows returned, not the fixed page size) landed in 7b19788a8; update the TSDoc to match so it no longer reads as advancing by `limit`. * fix(selectors): drain fetchPage in direct fetchList callers Making `fetchList` optional left three direct callers (outside the useSelectorOptions hook) calling it unguarded, which broke the build's type check. Route them through a shared `loadAllSelectorOptions` helper that uses `fetchList` when present and otherwise drains `fetchPage`. This also prevents a regression: `confluence.spaces` / `knowledge.documents` now paginate via `fetchPage` only, and these callers (search/replace, value resolution) would otherwise have silently returned no options. * chore(selectors): rename MAX_PAGE_PAGES to MAX_NOTION_PAGES for readability * fix(sso): re-check domain conflict before write and reject IP-address domains (#4825) * improvement(copilot): make copilot_messages the sole transcript store, remove JSONB dual-write (#4826) Stop writing/reading the legacy copilot_chats.messages JSONB column now that reads are cut over to copilot_messages. Make appendCopilotChatMessages the primary write (throws on failure instead of swallowing), repoint peripheral readers (workspace VFS, chat cleanup, data drains, fork, superuser import) to copilot_messages, and persist the assistant turn inside finalizeAssistantTurn's transaction so it commits atomically with the stream-marker clear. The column itself is dropped in a follow-up migration after this bakes. * feat(tables): expand filter operators (not-contains, starts/ends-with, not-in, empty) (#4827) Add does-not-contain ($ncontains), starts-with ($startsWith), ends-with ($endsWith), not-in-array ($nin, previously executed server-side but unexposed in the UI), and is-empty/is-not-empty ($empty) filter operators end-to-end — SQL builder, condition types, query-builder converters/constants, the filter UI, the Table tools/block descriptions, and docs. Also fix correctness bugs in the filter builder surfaced by the wider operator set: - Same-column AND rules (e.g. age > 18 AND age < 65, or name startsWith 'A' AND name endsWith 'Z') silently overwrote each other because the AND group was keyed by column name. They now merge into one operator object, which also makes Filter -> rules -> Filter round-trip losslessly for multi-operator columns. - $nin values were not split into an array like $in, and textual-match values like "123" were numeric-coerced (breaking the ILIKE path). - A non-boolean $empty operand from the raw API silently inverted the check; it now coerces 'true'/'false' strings and otherwise returns a 400. * improvement(copilot): stop persisting tool-call result outputs in transcripts (#4829) Opening a Mothership task could take many seconds because a single persisted assistant message in copilot_messages.content can reach hundreds of MB, almost entirely inside contentBlocks[].toolCall.result.output (e.g. a get_workflow_logs or run_workflow result). The DB query is ~2ms; the cost is detoasting that payload, shipping it to the browser, and parsing it. These outputs are dead weight on the Sim side: they are never rendered (the thread shows only tool name/title/status) and never replayed to the model (the upstream copilot service owns conversation memory). So drop result.output before it is persisted, keeping result.success/error plus the tool metadata. - add stripToolResultOutput() in persisted-message.ts - apply it in messages-store toRow (covers every write path) and in loadCopilotChatMessages (existing rows render fast on read) Co-authored-by: Claude Opus 4.8 <noreply@anthropic.com> * feat(providers): add Together AI, Baseten, and Ollama Cloud model providers (#4830) * feat(providers): add Together AI, Baseten, and Ollama Cloud model providers * fix(providers): guard Ollama streaming fast-path with hasActiveTools Match Together/Baseten/Fireworks: when tools are supplied but all are filtered out (usageControl 'none'), take the single streaming call instead of an extra non-streaming round-trip. Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com> * fix(providers): filter non-chat model types from Together model list * refactor(providers): dedupe Ollama Cloud upstream schema ollamaCloudUpstreamResponseSchema was byte-for-byte identical to ollamaUpstreamResponseSchema (both /api/tags endpoints return the same { models: [{ name }] } shape). Drop the duplicate and reuse the shared schema. Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com> --------- Co-authored-by: Claude Opus 4.8 <noreply@anthropic.com> * fix(knowledge): calendar view sync, deduplicate popover animation classes, type-safe filter cast * cleanup(knowledge): remove TRIGGER_BORDER_CLASS duplication, inline displayLabel, drop enabledFilterParam alias --------- Co-authored-by: Vikhyath Mondreti <vikhyathvikku@gmail.com> Co-authored-by: Cursor <cursoragent@cursor.com> Co-authored-by: Waleed <walif6@gmail.com> Co-authored-by: Claude Opus 4.8 <noreply@anthropic.com> Co-authored-by: Theodore Li <theo@sim.ai> Co-authored-by: andresdjasso <andresdjasso@users.noreply.github.com> * feat(blocks): add BlockMeta to Quiver and Linq; fix invalid block config fields; update skills Block fixes: - Add QuiverBlockMeta (tags + 3 templates: icon generator, diagram creator, vectorizer) - Fix QuiverBlock: remove invalid tags field from BlockConfig, IntegrationType.Design → IntegrationType.AI (Design doesn't exist in the enum) - Fix GreptileBlock: remove invalid tags field from BlockConfig, IntegrationType.DeveloperTools → IntegrationType.DevOps - Fix LinqBlock: remove invalid tags field from BlockConfig (tags belong only in BlockMeta) Skills: - add-block: add dedicated BlockMeta section with structure, rules, and registration pattern; add BlockMeta checklist items - add-integration: add BlockMeta to block structure template, add rules clarifying that tags must NOT appear on BlockConfig and integrationType must be a valid enum value; update registry snippet to include blocksMeta; add checklist items * fix(integrations): fix category dropdown by defining missing LANDING_INTEGRATIONS_DATA_PATH and regenerating integrations.json The staging merge introduced landing-content.ts but forgot to define LANDING_INTEGRATIONS_DATA_PATH in generate-docs.ts, causing the script to crash before writing integrations.json. The stale JSON had integrationTypes (plural array) from an older script version, while the Integration type and workspace UI both read integrationType (singular string) — so ALL_CATEGORY_SECTIONS bucketed to undefined and the category filters never appeared in the dropdown. Fixed by adding the missing path constant and re-running the generator. integrations.json now has 192 entries with the correct integrationType field. * fix(sidebar): restore resize handle on all pages commit3109104582wrapped the resize handle in {(isCollapsed || isOnWorkflowPage) && ...} and added a useEffect that resets sidebar width to SIDEBAR_WIDTH.MIN whenever the user navigates away from a workflow page. Together these made the sidebar non-resizable on Tasks, Tables, Knowledge Base, and every other non-workflow page. Restore the staging behavior: always render the resize handle and remove the effect that forced the width reset on page transitions. * fix(sidebar): match staging onKeyDown and tabIndex on resize handle The resize handle was still conditionalizing onKeyDown and tabIndex on isCollapsed, blocking keyboard accessibility of the separator role when expanded. Staging always attaches both unconditionally. onKeyDown={isCollapsed ? handleEdgeKeyDown : undefined} → onKeyDown={handleEdgeKeyDown} tabIndex={isCollapsed ? 0 : undefined} → tabIndex={0} * feat(integrations): show connected credentials on integration detail page When navigating to /integrations/google-docs (or any integration), a Connected section now appears above the templates listing all workspace credentials tied to that provider. Each row links back to the credential detail page (/integrations/connected/${id}) for management actions. Pairs with the earlier change that routes connected items from the integrations list to the provider detail page instead of directly to the credential detail page. * fix(integrations): rename Add in chat to Add to Sim * fix(skills): rename Add button to Add to Sim * fix(platform): restore M1/M2/M3 regressions and LazyMotion on landing page M1 — Invitation guard: re-introduce usePermissionConfig().isInvitationsDisabled alongside the workspace inviteDisabledReason check. The flag now also respects NEXT_PUBLIC_DISABLE_INVITATIONS and EE permission-group disableInvitations, not just billing policy. M2 — Settings redirects: /settings/integrations and /settings/skills now server-redirect to /integrations and /skills respectively so old bookmarks and emails don't silently land on General. M3 — Starter block search exclusion: restore block.type !== 'starter' guard in the search store so users cannot add a duplicate Starter block via the command palette. LazyMotion: restore LazyMotion + domMax/domAnimation wrappers and m.* components in landing-preview-panel and landing-preview-home. The removal was accidental (the full motion bundle was left after an import cleanup), which caused the entire framer-motion feature set to load eagerly on the landing page. * fix(integrations): revert connected list to credential detail; remove settings redirects * feat(sidebar): restore workspace switcher search with updated styling Shows a search input in the workspace dropdown when the user has more than 3 workspaces (WORKSPACE_SEARCH_THRESHOLD). Keyboard navigation: ArrowDown/Up to move through results, Enter to switch, resets on close. Styled to match the current branch (border-1/surface-5 tokens, sm text, 11px Search icon) rather than the old staging styles. Highlight state is wired through chipVariants active prop so it follows the same active appearance as clicked/hovered items. * fix(sidebar): clean up workspace search — layout, memo, and effect guard * fix(sidebar): align workspace rename input selection style with workflow rename * perf(sidebar): eliminate React re-renders during sidebar drag resize Previously, every mousemove during resize called setSidebarWidth(), which both updated the --sidebar-width CSS variable (sync) and set Zustand state (async). This caused: 1. A 1-frame transition flash on mousedown — isResizing state had to round-trip through React before the is-resizing CSS class was applied, so the width transition fired for the first pixel of movement. 2. A React re-render per pixel dragged — components reading sidebarWidth from the store (avatars, usage-indicator) lagged one frame behind the container, making the + and ... buttons appear to jump ahead. New approach: - handleMouseDown adds is-resizing directly to the sidebar DOM node before any React involvement (synchronous, no frame lag). - mousemove writes only to the CSS custom property (zero React renders). - mouseup persists the final width to Zustand exactly once. - isResizing / setIsResizing state removed from the store and hook — they are no longer needed since the class is managed via direct DOM mutation. * perf(sidebar): add requestAnimationFrame throttle to resize mousemove handler * fix(sidebar): fix drag-right lag caused by WorkspaceChrome overflow-hidden transition The sidebar-container's is-resizing class correctly suppressed its own width transition, but the two wrapper divs in WorkspaceChrome both have transition-[width]/transition-transform with a 175ms ease. The outer wrapper also has overflow-hidden, so while the sidebar content was at the correct width instantly, it was visually clipped by the outer wrapper which was still animating — causing the + and ... buttons to appear to lag behind the resize line on drag-right (not on drag-left, since shrinking doesn't clip content). Fix: add sidebar-shell-outer/sidebar-shell-inner class names to both chrome wrappers, and suppress their transitions via html.sidebar-resizing rule when a drag is active. The html.sidebar-resizing class is toggled directly in the resize hook alongside is-resizing, so it takes effect synchronously on mousedown. * fix(icons): redesign Download icon to match Upload style; fix Upload/Download confusion Download icon was missing the tray/shelf line at the bottom that Upload has, making it look like a plain arrow rather than a matched pair. Updated Download to use the same viewBox, stroke weight, and three-path structure as Upload (tray + stem + arrowhead), just pointing down. Also fix 5 places where Upload (↑) was incorrectly used for download/export actions: - files.tsx: two Download action rows in toolbar and context menu - tables/table.tsx: Export CSV toolbar button - table-context-menu.tsx: Export CSV context menu item - logs.tsx: Export toolbar button - landing-preview-logs.tsx: decorative Export button Import CSV and actual upload actions correctly keep the Upload icon. * fix(icons): replace Upload with Download on all remaining export/download actions - panel.tsx: Export workflow dropdown item - context-menu.tsx: Export in sidebar workflow context menu - chat.tsx: Export chat button - output-panel.tsx: Export console CSV button - terminal.tsx: Export console CSV button - resource-content.tsx: Export table as CSV + Download file buttons * fix(icons): fix remaining Upload→Download on download actions in files and logs - action-bar.tsx: download button in files toolbar - file-row-context-menu.tsx: Download item in file context menu - file-download.tsx: both download buttons in log details file viewer * updated block skills, settings pages, modals, buttons -> chips, blocks missing metadata * updated skill modal * improvement(resource-header): refine breadcrumb truncation ux * improvement(resource): add floating overflow text tooltips * wire up credits counter * improvement(resource-header): mute path dropdown title * refactor(resource-header): share floating-tooltip engine, prune dead overlay tooltips (#4844) Clean up the breadcrumb truncation feature for reuse and correctness: - Extract useFloatingTooltip / useIsOverflowing / FloatingTooltip into a shared floating-tooltip module. BreadcrumbSegment and FloatingOverflowText now consume one implementation instead of duplicating ~150 lines of positioning, velocity, overflow-detection, and portal logic. - Replace the hardcoded terminal-label regex in ResourceHeader with a typed `terminal` flag on BreadcrumbItem (set by the document chunk/loading crumbs), decoupling the generic header from knowledge-base copy. - Clear the path-popover close timeout on unmount and reuse the shared POPOVER_ANIMATION_CLASSES constant. - Drop the redundant manual overflow-state writes (fixes a sticky fade mask). - Revert FloatingOverflowText inside Combobox `overlayContent` back to plain truncating spans across files/logs/tables/scheduled-tasks/document: the combobox overlay is pointer-events-none, so the tooltip handlers never fired there. Co-authored-by: Claude Opus 4.8 <noreply@anthropic.com> * refactor(emcn,resource-header): address PR #4844 review feedback - useIsOverflowing now uses a callback ref so the ResizeObserver follows the element across mount/unmount/reassignment instead of capturing it once at mount. Safe for conditionally rendered consumers of the shared hook. (greptile P2) - Move POPOVER_ANIMATION_CLASSES out of chip-date-picker implementation internals into emcn/components/popover/popover-animation.ts, exported from the @/components/emcn barrel. Consumers now import from the module boundary. (greptile P2) Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com> * upgrade table and styling upgrade * fix schema to include integration * fix(files): align delete icon with tables view (Trash → Trash2) Co-Authored-By: waleed <waleed@simstudio.ai> * fix(mothership): preserve blockType for integration contexts in sent messages Integration mention chips were missing their provider icons in sent messages because blockType was dropped when mapping ChatContext to messageContexts. renderIntegrationTile returns null without blockType, silently hiding the icon. * fix(mothership): allow 'integration' resource type in chat resources API The VALID_RESOURCE_TYPES allowlist was missing 'integration', causing a 400 error when adding integrations to the Mothership resource tab — so they never persisted and disappeared on refresh. * fix(ui): Add "File" title next to file resource header * fix(ui): fix resource header columns being bolded * fix(resource): keep the floating tooltip from jumping on click Gate the focus-driven show behind :focus-visible so a mouse click (which focuses the trigger) no longer re-shows the tooltip anchored to the element's bottom edge. On click the tooltip now hides cleanly instead of jumping down; keyboard focus still shows it. Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com> * perf(sidebar): eliminate unnecessary re-renders in workspace switcher for non-search users - onMouseEnter: only set highlightedIndex when showSearch is true, preventing a state update + re-render on every workspace row hover for users with ≤ 3 workspaces where the search is never shown - onOpenChange: only reset workspaceSearch and highlightedIndex when showSearch is true, since both values are always already at their defaults for non-search users and setting them triggers a pointless re-render during dropdown close - data-workspace-row-idx: only set when showSearch is true since the scroll effect that reads this attribute is already gated on showSearch * feat(search): context-aware cmd-k results on the integrations page When cmd-k is opened on the integrations page, show two new result groups: connected accounts (visible even with empty input) and catalog integrations (appear once the user types). Selecting an OAuth integration deep-links to its detail page with ?connect=oauth so the connect modal auto-opens. Non-OAuth integrations navigate to the plain detail page. Both groups are gated to the integrations page only and respect the hideIntegrationsTab permission. The credentials fetch shares the same React Query cache key as the integrations page itself (no double fetch). * refactor(emcn): make the floating tooltip the one canonical Tooltip Replace the Radix-based emcn Tooltip with the cursor-following floating tooltip so every tooltip in the app uses one consistent style. Built on the shared floating-tooltip engine (relocated into emcn), not a parallel implementation. - Move the floating-tooltip engine into emcn/components/tooltip and export it from the barrel; re-point its consumers (FloatingOverflowText, resource-header) - Extend the FloatingTooltip bubble to render arbitrary children (+ role/id for a11y) so it can back general tooltips, not just overflow text - Rebuild emcn Tooltip (Root/Trigger/Content/Provider/Shortcut/Preview) on useFloatingTooltip — compound API preserved, ~350 call sites unchanged, legacy side/align props accepted and ignored (the tooltip follows the cursor). Removes @radix-ui/react-tooltip usage (package kept for a later cleanup; react-slot retained for asChild) Note: general tooltips now show instantly (no hover delay) and follow the cursor. Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com> * style(emcn): put tooltip text on the design scale (text-caption) Replace the tooltip's ad-hoc `text-xs` + `leading-[18px]` with the semantic `text-caption` (12px) font-size token so the text styling is fully on the design scale and self-documenting, matching how the rest of the system is set up. The color already used the global `--text-body` token. No visual change (still 12px with a ~18px line height). Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com> * feat(sidebar): add empty task state and inline task creation - Show "No tasks yet" in the Tasks section (expanded and collapsed) when the list is empty - Clicking + now creates a task via the API and navigates directly to it, rather than navigating to home - Add isCreatingTaskRef guard to prevent double-click from spawning multiple tasks - Disable + button while creation is pending - Fall back to home navigation on creation error * invite, billing, home * improvement(seats): auto purchase seats on invitations into workspace (#4857) * improvement(seats): auto purchase seats on invitations into workspace * improve sampling for seat drift reconciler * address comments * feat(knowledge): align connector UI with integrations page styling - ConnectorTypeCard now matches integration rows: brand-colored rounded-xl tile, ArrowRight, title/subtitle hierarchy - ConnectorCard icon upgraded from flat surface-4 to branded tile (white icon on brand bg, graceful fallback) - Connector header badges use chipVariants instead of custom Button classes - Add-connector search input aligned to integrations style (h-[30px], rounded-lg, border-1) * fix(icons): trim Folder SVG viewBox to remove right-side whitespace The folder path only extends to x≈14.33 in a 15-unit viewBox, leaving ~0.5 units of empty space on the right. At 12px rendered size this produces ~0.4px extra gap (visible as ~1px on retina displays) compared to solid icons like the workflow color square. Trimming the viewBox to 14.5 units makes the folder fill its chip slot evenly. * fix(user-input): restore draft text synchronously to preserve contexts on nav The SSR-safe approach (empty useState + effect restore) created a timing window where the sync effect in useContextManagement fired with message='' before the value was set, clearing any restored contexts. Folder and workflow contexts (not re-added by applyAutoMentions) were lost on every nav-back. Revert to the staging approach: initialize value synchronously from the draft store so message is already populated when effects run, matching the behavior on staging. * fix(queue): render context chips in queued messages - Remove plainMentions from queued message rows so context chips render with icons, consistent with sent messages - Fix computeMentionRanges to use '/' prefix for skill contexts (content has the slash trigger restored at submit time, not '@') * fix(mothership): remove integrations from add-resource dropdown * fix(mothership): comment out integrations from add-resource dropdown * chore(db): drop form, templates, template_creators, template_stars tables These tables backed the Forms and Templates platform features which were intentionally removed from this branch. Clean up the DB schema to match. * chore(db): add migration metadata for 0224 drop tables * block icons, sidebar, toolbar * chore: remove remaining dead code for template-profile feature - Remove 'template-profile' from SettingsSection union type - Remove 'template-profile' entry from SECTION_TITLES - Remove now-redundant template-profile guard in settings sidebar - Remove commented-out template-profile nav item * fix(multi-select): preserve anchor on range selection for tasks and folders After a shift+click range, the anchor (lastSelectedTaskId / lastSelectedFolderId) was being updated to the end of the range (toId). This caused subsequent shift+clicks to extend from the wrong point instead of the original click. Standard behavior: anchor stays at the initial click (fromId) so repeated shift+clicks always expand/contract relative to where you started. * feat(emcn): add SearchInput component and unify search bars platform-wide - Add SearchInput to emcn: 30px chip-family filled search input matching the integrations page pattern (border-1, surface-5, leading Search icon) - Migrate all 22 search bars across settings, EE pages, and integrations to SearchInput (only layout classes allowed at callsites) - Rename Sim Keys -> Sim API Keys in nav/title; page copy now says API key - Remove components/ui input, label, and verified-badge; migrate consumers to emcn equivalents or raw inputs (table cell editor, wand prompt bar) - Delete dead EE skeleton files (data-drains, data-retention) - General settings: Home Page chip moves to header left as navigation * fix(files,tables): restore new-file editor autofocus and CSV import error toasts Both were dropped on the staging line and regressed vs production (main): - Files: the new-file editor autofocus chain (files.tsx -> file-viewer -> text-editor) was stripped by the react-doctor dead-code pass in #4544, which misread the prop-drilled `autoFocus` (consumed by an imperative `editor.focus()` effect) as unused. Restored the prop through all three layers and the one-shot focus effect so creating a new file focuses the editor immediately. - Tables: CSV import failures were silently logged with no user feedback. Restored the per-file and generic `toast.error` surfacing. * feat(home): score suggested actions by workspace signals - Derive the suggestion pool from the curated block template catalog (1,343 prompts across 172 blocks) instead of 15 hardcoded entries - Fix inverted relevance: prompts for connected providers are now boosted 4x (instantly runnable) instead of excluded; unconnected discounted 0.4x - Weight by featured (3x), popular category (1.5x), and resource gaps (no tables -> boost table starters; has KBs -> dampen KB-creation prompts) - Weighted sampling without replacement, max one suggestion per block - Connect rows weighted by catalog template count; 2 for fresh workspaces, 1 once something is connected - Key the catalog map by both versioned and base block types so gmail_v2 templates resolve (gmail, github, notion, linear were silently dropped) - Replace derive-in-effect state with a useMemo keyed by a shuffle nonce - Add suggested_action_clicked / suggested_actions_shuffled / suggested_actions_toggled PostHog events * billing, teammates * improvement(credentials): credentials invites, secrets tab wiring up (#4874) * improvement(credentials): move away from invite notion * wire up secrets ui/ux * address comments * get consistent styling by removing emcninput + text area * styling consistency * remove fallback * address comment: * refactor(ui): migrate settings & workspace UI to chip design system Migrate modals to ChipModal (showDivider, hint, resizable, size, leading, ChipModalTabs), standardize Chip variants, add ChipCombobox wrapper, and apply chip inputs/dropdowns across settings, knowledge, logs, tables, inbox, EE tabs. Render ChipModalTabs as a ChipSwitch segmented control. Align /settings/secrets detail with /integrations, refresh whitelabeling, and restore file-editor autofocus and CSV import error toasts. * fix(mothership): restore integrations to useAvailableResources for @ mention Integrations were fully removed from useAvailableResources which broke the @ mention menu since user-input shares the same hook. Now integrations are always included in the hook but excluded at the AddResourceDropdown component level, keeping them out of the sidebar + menu while remaining available for @ mention autocomplete. * refactor(settings): chip design-system consistency pass across all tabs Extract a shared chip-field shell (CHIP_FIELD_SHELL/CHIP_FIELD_INPUT) mirroring Input variant='chip' and route secrets, credential detail, and integrations credential detail through it (30px height, font-medium, focus ring). Add a Discard action to the secrets header when dirty. Group BYOK providers into Models/Search & web/Enrichment sections and align its tiles to the integrations tile. Normalize list-row typography to text-[14px]/text-[12px] and icon tiles to rounded-xl + border across api-keys, copilot, custom-tools, mcp, workflow-mcp-servers, credential-sets, and access-control. Tone the secrets Details chip and per-row affordances to ghost. Fix token correctness: raw tailwind colors to design tokens (data-drains), missing chip variant on the Snowflake role input, ColorInput chip-field reuse (whitelabeling), error token and icon sizes (workflow-mcp-servers), border token (mcp), no-results sizing (secrets), row chrome (recently-deleted), hover token and Button to Chip (access-control), and deduped textarea chrome (sso). * feat(settings): unify filter dropdowns on ChipSelect (integrations style) Add a ChipSelect emcn component — a filled chip trigger + chevron opening a DropdownMenu, matching the integrations category filter — supporting single select, multi-select (checkbox rows), grouped options, and optional in-menu search. Migrate every settings/EE filter dropdown off ChipCombobox to it: audit-logs (resource-type multi + time-range), data-retention, data-drains, general, admin (grouped tool picker), inbox status filter, and the workflow MCP-server pickers. The SSO provider-id field stays an editable combobox since it accepts free-text slugs. Also fix audit findings: chip the MCP client-secret input, normalize an MCP error-text size, and drop now-dead destination-icon code in data-drains. * fix(mentions): require explicit @ for integration mentions; decorate sent messages robustly - Bare integration names in prose (Monday, Notion, Clay) are no longer auto-converted to mentions or chipped — mention treatment is strictly opt-in via a token-starting @ (fixes the scunthorpe problem) - @-prefixed mentions still canonicalize casing (@slack -> @Slack) on both the keystroke fast-path and bulk paths (paste, template, draft, STT) - Sent/queued messages now self-sufficiently decorate @IntegrationName tokens via a text scan, covering messages sent before the input pass ran or authored outside the chat input - Integration contexts missing a resolvable blockType (messages persisted before blockType was saved) are backfilled by label lookup so their mention pills render the brand icon again * refactor(settings): section the API keys page like secrets Wrap Workspace, Personal, and the allow-personal-keys toggle in SettingsSection (muted label + divider) instead of bare bold headers, matching the secrets and BYOK pages. * fix(settings): ChipSelect renders above modals + full-width form mode Raise the ChipSelect menu to --z-popover so it layers above modal surfaces (--z-modal) instead of opening behind them. Add a fullWidth prop that stretches the trigger and right-aligns the chevron for form-field use, and apply it to the workflow MCP-server pickers. * fix(emcn): ChipSelect uses the emcn flat chevron, not lucide's square one The lucide ChevronDown is square; rendering it at the chip's 9x7 footprint stretched it. Switch to the custom emcn ChevronDown (built for that wide aspect), matching the integrations filter and ChipDropdown. * fix(emcn): ChipSelect trigger hugs its content (w-fit) In a stacked form layout the trigger was stretched by align-items: stretch, leaving an empty gap to the right of the value. Add w-fit so the chip sizes to its content (a compact pill) everywhere; fullWidth form selects are unaffected. * fix(emcn): ChipSelect uses a square lucide chevron Revert to lucide's ChevronDown sized square (size-[14px]) so it renders crisp, matching the standard select chevron used by Combobox. * renamed tasks to chats * rename and file change * improvement(billing): wire up billing, org, teammates tabs + remove deprecated subscription tab (#4887) * improvement(billing): wire up billing, org, teammates tabs + remove depr subscription tab * pass exec timeout to tool routes * reuse helper * address comments * address disable comment * chore(db): remove migration 0224 to regenerate on top of staging Co-authored-by: Cursor <cursoragent@cursor.com> * fix type errors and regen migration? * chore(db): drop branch migration 0226 ahead of staging merge; will regenerate * chore(db): regenerate migration 0226 after staging merge * externalize before compaction in fallback' * fix save/discard chips to be consistent * fix(ui): remove smodal tabs in favor of chip modal tabs * fix(ui): skip auto-scrolling on mouse highlight of workspace * fix(platform): restore settings redirects, forgot-password Enter submit, and tag tooltip visibility - Re-add SETTINGS_REDIRECTS so /settings/integrations and /settings/skills deep links redirect to their top-level routes instead of rendering an empty settings panel (accidentally removed in86da193cc3one minute aftercca5054cf6added it) - Add opt-in onSubmit to ChipModalField input/email variants and wire it in the forgot-password modal so Enter submits again (lost in the ChipModal conversion) - Knowledge tag tooltip: drop the max-h/overflow-y-auto clamp that the pointer-events-none floating tooltip made unreachable; truncate each tag row instead so all tags stay visible with bounded height * chore(db): remove migration 0226_third_spot before staging merge * chore(db): regenerate migration as 0227 after staging merge * feat(telemetry): add posthog + audit coverage for new platform actions Audit log (compliance/permission-relevant only): - org_seat.provisioned — seat auto-purchased when an invite acceptance grows the org (actor = accepting user, includes seat delta) - org_plan.converted — Pro→Team conversion triggered by invite acceptance - org_seat.drift_reconciled — hourly cron healed a drifted seat count - credential_member.added/removed/role_changed — credential sharing surface was previously fully unaudited - table.created — parity with existing table.updated/deleted - skill updates now record skill.updated instead of mislabeled skill.created PostHog: - seats_provisioned, credential_shared/unshared, environment_updated/deleted (key counts only, never names/values) - table_import_started/completed — background CSV imports previously had zero failure observability - table_exported, file_downloaded, skill_updated - credential_connected now fires for OAuth completions (draft-hooks), credential_deleted for OAuth disconnects; previously only manual credentials were tracked - table_workflow_run gains deployment_mode (live/deployed/mixed) Also: logger.warn on all new credential-admin 403 denials (members + environment routes); invite-created audit enriched with enforcedFixedSeats/plan. Deliberately excluded as noise: per-hour dead-letter audit rows (would re-record the same stuck event every cron run) and a duplicate system-actor org_plan.converted in the Stripe outbox handler. * feat(home): fill textarea on suggested prompt click instead of sending Clicking a prompt action in the Suggested Actions panel now populates the Mothership user-input textarea (via applyAutoMentions) and focuses it with the caret at end, rather than immediately submitting. The user can review, edit, and send manually. * fix(templates): name owning integration in featured block template prompts Four featured prompts omitted their owning integration name, making them unbranded and disconnected from their title. Each prompt now explicitly names GitHub or Google Sheets so mentionifyIntegrations renders the chip and the copy reads as a self-contained agent-building instruction. * fix(templates): rewrite fragment prompts so each names its integration and reads as a complete instruction Featured and non-featured block template prompts that either omitted the owning integration's canonical name or were phrased as marketing fragments rather than natural user instructions have been rewritten. Each updated prompt now starts with an imperative verb ("Build a workflow that…"), names the owning integration explicitly so the @-mention chip renders correctly, and aligns with the entry's title. Files changed: salesforce, hubspot (×2), github, slack, airtable, firecrawl, iam. * fix(templates): name integration in remaining block template prompts - google_docs.ts: replace 'Google Doc' with 'Google Docs document' in 4 prompts; update title 'Meeting notes to Google Doc' to 'Meeting notes to Google Docs' - google_sheets.ts: replace 'Google Sheet' with 'Google Sheets spreadsheet/Google Sheets' in 3 non-featured prompts - slack.ts: replace 'Google Doc' with 'Google Docs document' in 'Daily standup summary' - stripe.ts: replace 'Google Sheet'/'Slacks' with 'Google Sheets'/'Slack' in 'Weekly metrics report' - reddit.ts: add 'Reddit' to 3 prompts that only referenced subreddits - notion.ts: rewrite featured prompt to start with a verb and name Notion - jira.ts: rewrite featured marketing-fragment prompt to start with a verb - linear.ts: rewrite featured marketing-fragment prompt to start with a verb - gmail.ts: rewrite featured marketing-fragment prompt to start with a verb and name Gmail * fix(icons): convert monochrome dark brand icons to currentColor for dark mode LinkupIcon, InfisicalIcon, IntercomIcon, LumaIcon, GranolaIcon, OnePasswordIcon, and RailwayIcon were hardcoded to black/near-black fills/strokes, making them invisible in bare DARK mode. Convert all to currentColor so they follow the theme-aware text color. Add iconColor: '#286efa' to IntercomBlock (Intercom brand blue is a confident mid-tone, safe on both themes). Two-tone icons (StagehandIcon, AgentPhoneIcon, QuiverIcon) are left unchanged because their white details are structural — converting to single-tone would destroy logo legibility. * removed color, user input, sidebar, suggested actions, chips/emcn * removed color migration * improve(blocks): audit block catalog metadata for accuracy and fill gaps - Fix template prompts that claimed capabilities blocks don't have (fabricated triggers, non-existent tools) across ~98 integrations - Normalize integration tags to family conventions and valid union values - Align alsoIntegrations and modules with template prompt content - Add BlockMeta for circleback, imap, and rss trigger integrations - Add templates to clickhouse and greptile metas - Remove duplicate PageSpeed deploy-gate template * chore(telemetry): drop org_seat.drift_reconciled audit System self-heal bookkeeping doesn't belong in the user-facing audit trail — membership and seat-purchase changes are already audited, and the cron's logger output covers ops visibility. * chore(db): consolidate branch migrations into single 0227 * fix(emcn): make ChipModal scroll internally when content exceeds viewport The Modal→ChipModal migration dropped the old ModalBody scroll container: ChipModal renders ModalContent bare (no overflow-hidden) and its wrappers had no min-h-0 chain, so tall modals (e.g. New data drain with an S3 destination) overflowed max-h-[84vh] off-screen with no way to scroll. Complete the flex min-h-0 chain through ChipModal's frame and give ChipModalBody flex-1 min-h-0 overflow-y-auto — header/footer stay pinned, body scrolls only when constrained. Short modals are unaffected (max-h caps, it doesn't stretch), and dropdowns inside the body are Radix-portaled so the new scroll container cannot clip them. Five modals that had locally patched this with max-h-[Nvh] overrides keep working unchanged. * fix(emcn): don't close modal when dismissing a dropdown via outside click Radix dispatches pointer-down-outside to every open dismissable layer at once, so clicking outside an open dropdown/select inside a modal closed both the dropdown and the modal in one jarring step. ModalContent now prevents its own dismissal while a portaled popper layer is open — the first outside click closes just the popper, the next one closes the modal. * docs(skills): de-duplicate and correct agent docs; canonical styling tokens; mirror sim-sandbox rule * docs(skills): broaden boundary-raw-fetch scope note, sync cursor rule mirrors * fix(emcn): harden modal popper guard and exempt caret-anchored dropdowns from body scroll Adversarial review follow-ups to the ChipModal scroll + dismissal fixes: - Popper guard now requires data-state="open" inside the popper wrapper, so a dropdown that is merely animating closed no longer swallows the next outside click on the modal (DropdownMenu has an exit animation that keeps its wrapper mounted briefly) - Port the same guard to SModalContent for consistency - custom-tool-modal: opt its body out of the chrome scroll container (flex-none + overflow-visible); the caret-anchored EnvVar/Tag autocomplete dropdowns are absolute-positioned inside the body and must spill past its bounds rather than clip against a scroll boundary * refactor(billing): drop unnecessary useCallback wrappers from event handlers * fix(data-drains): complete chip migration of destination forms and fill missing placeholders Finishes the in-flight FormField → ChipModalField conversion for all destination form specs and adds the placeholders that several inputs never had (S3 bucket/region/access keys, Azure account key, Datadog API key, webhook signing secret/bearer token) — the cause of the New Data Drain modal showing placeholder-less inputs inconsistently. * fix(emcn): broaden modal popper guard to onInteractOutside Covers the focusOutside dismissal path too: when a popper's focus scope unwinds on close, the transient focus shift could still dismiss the modal (and simultaneous body pointer-events lock teardown could freeze the page). Same data-state="open" scoping as the pointer guard. * fix(emcn): harden modal outside interactions * update audit mock --------- Co-authored-by: andres <k62hc5kjst@privaterelay.appleid.com> Co-authored-by: Vikhyath Mondreti <vikhyathvikku@gmail.com> Co-authored-by: Cursor <cursoragent@cursor.com> Co-authored-by: Waleed <walif6@gmail.com> Co-authored-by: Claude Opus 4.8 <noreply@anthropic.com> Co-authored-by: Theodore Li <theo@sim.ai> Co-authored-by: andresdjasso <andresdjasso@users.noreply.github.com> Co-authored-by: Vikhyath Mondreti <vikhyath@simstudio.ai> Co-authored-by: waleed <waleed@simstudio.ai>
7102 lines
246 KiB
JSON
7102 lines
246 KiB
JSON
{
|
|
"openapi": "3.1.0",
|
|
"info": {
|
|
"title": "Sim API",
|
|
"description": "API for executing workflows, querying logs, and managing resources in Sim.",
|
|
"version": "1.0.0",
|
|
"contact": {
|
|
"name": "Sim Support",
|
|
"email": "help@sim.ai",
|
|
"url": "https://www.sim.ai"
|
|
},
|
|
"license": {
|
|
"name": "Apache 2.0",
|
|
"url": "https://www.apache.org/licenses/LICENSE-2.0.html"
|
|
}
|
|
},
|
|
"servers": [
|
|
{
|
|
"url": "https://www.sim.ai",
|
|
"description": "Production"
|
|
}
|
|
],
|
|
"tags": [
|
|
{
|
|
"name": "Workflows",
|
|
"description": "Execute workflows and manage workflow resources"
|
|
},
|
|
{
|
|
"name": "Human in the Loop",
|
|
"description": "Manage paused workflow executions and resume them with input"
|
|
},
|
|
{
|
|
"name": "Logs",
|
|
"description": "Query execution logs and retrieve details"
|
|
},
|
|
{
|
|
"name": "Usage",
|
|
"description": "Check rate limits and billing usage"
|
|
},
|
|
{
|
|
"name": "Audit Logs",
|
|
"description": "View audit trail of workspace activity"
|
|
},
|
|
{
|
|
"name": "Tables",
|
|
"description": "Manage tables and rows for structured data storage"
|
|
},
|
|
{
|
|
"name": "Files",
|
|
"description": "Upload, download, and manage workspace files"
|
|
},
|
|
{
|
|
"name": "Knowledge Bases",
|
|
"description": "Manage knowledge bases, documents, and vector search"
|
|
}
|
|
],
|
|
"security": [
|
|
{
|
|
"apiKey": []
|
|
}
|
|
],
|
|
"paths": {
|
|
"/api/workflows/{id}/execute": {
|
|
"post": {
|
|
"operationId": "executeWorkflow",
|
|
"summary": "Execute Workflow",
|
|
"description": "Execute a deployed workflow. Supports synchronous, asynchronous, and streaming modes. For async execution, the response includes a statusUrl you can poll for results.",
|
|
"tags": ["Workflows"],
|
|
"x-codeSamples": [
|
|
{
|
|
"id": "curl",
|
|
"label": "cURL",
|
|
"lang": "bash",
|
|
"source": "curl -X POST \\\n \"https://www.sim.ai/api/workflows/{id}/execute\" \\\n -H \"X-API-Key: YOUR_API_KEY\" \\\n -H \"Content-Type: application/json\" \\\n -d '{\n \"input\": {\n \"key\": \"value\"\n }\n }'"
|
|
}
|
|
],
|
|
"parameters": [
|
|
{
|
|
"name": "id",
|
|
"in": "path",
|
|
"required": true,
|
|
"description": "The unique identifier of the deployed workflow to execute.",
|
|
"schema": {
|
|
"type": "string",
|
|
"example": "wf_1a2b3c4d5e"
|
|
}
|
|
}
|
|
],
|
|
"requestBody": {
|
|
"description": "Execution configuration including input values and execution mode options.",
|
|
"content": {
|
|
"application/json": {
|
|
"schema": {
|
|
"type": "object",
|
|
"properties": {
|
|
"input": {
|
|
"type": "object",
|
|
"description": "Key-value pairs matching the workflow's defined input fields. Use the Get Workflow endpoint to discover available input fields.",
|
|
"additionalProperties": true
|
|
},
|
|
"triggerType": {
|
|
"type": "string",
|
|
"description": "How this execution was triggered. Defaults to api when called via the REST API. Recorded in execution logs for filtering."
|
|
},
|
|
"stream": {
|
|
"type": "boolean",
|
|
"description": "When true, returns results as Server-Sent Events (SSE) for real-time block-by-block output streaming."
|
|
},
|
|
"selectedOutputs": {
|
|
"type": "array",
|
|
"items": {
|
|
"type": "string"
|
|
},
|
|
"description": "List of specific block IDs whose outputs to include in the response. When omitted, all block outputs are returned."
|
|
}
|
|
}
|
|
},
|
|
"example": {
|
|
"input": {
|
|
"query": "What is the weather in Tokyo?"
|
|
}
|
|
}
|
|
}
|
|
}
|
|
},
|
|
"responses": {
|
|
"200": {
|
|
"description": "Synchronous execution completed successfully.",
|
|
"content": {
|
|
"application/json": {
|
|
"schema": {
|
|
"$ref": "#/components/schemas/ExecutionResult"
|
|
},
|
|
"example": {
|
|
"success": true,
|
|
"executionId": "exec_abc123",
|
|
"output": {
|
|
"content": "The weather in Tokyo is sunny, 22\u00b0C."
|
|
},
|
|
"error": null,
|
|
"metadata": {
|
|
"startTime": "2026-01-15T10:30:00Z",
|
|
"endTime": "2026-01-15T10:30:01Z",
|
|
"duration": 1250
|
|
}
|
|
}
|
|
}
|
|
}
|
|
},
|
|
"202": {
|
|
"description": "Asynchronous execution has been queued. Poll the statusUrl for results.",
|
|
"content": {
|
|
"application/json": {
|
|
"schema": {
|
|
"$ref": "#/components/schemas/AsyncExecutionResult"
|
|
}
|
|
}
|
|
}
|
|
},
|
|
"401": {
|
|
"$ref": "#/components/responses/Unauthorized"
|
|
},
|
|
"404": {
|
|
"$ref": "#/components/responses/NotFound"
|
|
},
|
|
"429": {
|
|
"$ref": "#/components/responses/RateLimited"
|
|
}
|
|
}
|
|
}
|
|
},
|
|
"/api/workflows/{id}/executions/{executionId}": {
|
|
"get": {
|
|
"operationId": "getWorkflowExecution",
|
|
"summary": "Get Execution Status",
|
|
"description": "Get the current status of a workflow execution. Returns the run's lifecycle state (`running`, `paused`, `completed`, `failed`, etc.), timing, error, and optionally per-block outputs. Designed for polling \u2014 works for any execution, including ones that pause and resume.",
|
|
"tags": ["Workflows"],
|
|
"x-codeSamples": [
|
|
{
|
|
"id": "curl",
|
|
"label": "cURL",
|
|
"lang": "bash",
|
|
"source": "curl \\\n \"https://www.sim.ai/api/workflows/{id}/executions/{executionId}\" \\\n -H \"X-API-Key: YOUR_API_KEY\""
|
|
},
|
|
{
|
|
"id": "curl-with-outputs",
|
|
"label": "cURL (with block outputs)",
|
|
"lang": "bash",
|
|
"source": "curl \\\n \"https://www.sim.ai/api/workflows/{id}/executions/{executionId}?selectedOutputs=blockId,blockId.field&includeOutput=true\" \\\n -H \"X-API-Key: YOUR_API_KEY\""
|
|
}
|
|
],
|
|
"parameters": [
|
|
{
|
|
"name": "id",
|
|
"in": "path",
|
|
"required": true,
|
|
"description": "The unique identifier of the workflow.",
|
|
"schema": {
|
|
"type": "string",
|
|
"example": "wf_1a2b3c4d5e"
|
|
}
|
|
},
|
|
{
|
|
"name": "executionId",
|
|
"in": "path",
|
|
"required": true,
|
|
"description": "The unique identifier of the execution.",
|
|
"schema": {
|
|
"type": "string",
|
|
"example": "exec_9f8e7d6c5b"
|
|
}
|
|
},
|
|
{
|
|
"name": "includeOutput",
|
|
"in": "query",
|
|
"required": false,
|
|
"description": "When `true` and the execution has `status: completed`, include the workflow's final output in the response.",
|
|
"schema": {
|
|
"type": "string",
|
|
"enum": ["true", "false"]
|
|
}
|
|
},
|
|
{
|
|
"name": "selectedOutputs",
|
|
"in": "query",
|
|
"required": false,
|
|
"description": "Comma-separated block-output selectors. A bare `blockId` returns that block's full output; a dot-path like `blockId.field` or `blockId.nested.path` returns just that value. Results are returned in the `blockOutputs` map keyed by the selector string.",
|
|
"schema": {
|
|
"type": "string",
|
|
"example": "c1b90bce-8a82-42a5-b6a5-5762846c2eaf,c1b90bce-8a82-42a5-b6a5-5762846c2eaf.waitDuration"
|
|
}
|
|
}
|
|
],
|
|
"responses": {
|
|
"200": {
|
|
"description": "Execution status returned.",
|
|
"content": {
|
|
"application/json": {
|
|
"schema": {
|
|
"$ref": "#/components/schemas/WorkflowExecutionStatus"
|
|
},
|
|
"examples": {
|
|
"completed": {
|
|
"summary": "Completed run",
|
|
"value": {
|
|
"executionId": "9254f1c9-5a11-4a12-91e3-8065293f3609",
|
|
"workflowId": "81f661e1-d704-4861-b5c1-5bb3cf57e6a7",
|
|
"status": "completed",
|
|
"trigger": "api",
|
|
"level": "info",
|
|
"startedAt": "2026-05-15T19:43:12.189Z",
|
|
"endedAt": "2026-05-15T19:45:45.224Z",
|
|
"totalDurationMs": 153035,
|
|
"paused": null,
|
|
"cost": {
|
|
"total": 0.005
|
|
},
|
|
"error": null,
|
|
"finalOutput": null,
|
|
"blockOutputs": null
|
|
}
|
|
},
|
|
"paused": {
|
|
"summary": "Currently paused run",
|
|
"value": {
|
|
"executionId": "772749f6-ee81-414c-a2c3-671549dd62b8",
|
|
"workflowId": "81f661e1-d704-4861-b5c1-5bb3cf57e6a7",
|
|
"status": "paused",
|
|
"trigger": "manual",
|
|
"level": "info",
|
|
"startedAt": "2026-05-15T22:25:57.178Z",
|
|
"endedAt": "2026-05-15T22:25:57.215Z",
|
|
"totalDurationMs": 1,
|
|
"paused": {
|
|
"pausedAt": "2026-05-15T22:25:57.216Z",
|
|
"resumeAt": "2026-05-16T18:25:57.200Z",
|
|
"pauseKind": "time",
|
|
"blockedOnBlockId": "c1b90bce-8a82-42a5-b6a5-5762846c2eaf",
|
|
"pausedExecutionId": "438bf05b-bd3c-4011-b78e-b19c112eeb66",
|
|
"pausePointCount": 1,
|
|
"resumedCount": 0
|
|
},
|
|
"cost": {
|
|
"total": 0.005
|
|
},
|
|
"error": null,
|
|
"finalOutput": null,
|
|
"blockOutputs": null
|
|
}
|
|
},
|
|
"failed": {
|
|
"summary": "Failed run",
|
|
"value": {
|
|
"executionId": "3ccfdeed-a63c-4e86-98e2-8bec723bca52",
|
|
"workflowId": "81f661e1-d704-4861-b5c1-5bb3cf57e6a7",
|
|
"status": "failed",
|
|
"trigger": "api",
|
|
"level": "error",
|
|
"startedAt": "2026-05-15T22:24:50.991Z",
|
|
"endedAt": "2026-05-15T22:24:50.999Z",
|
|
"totalDurationMs": 2,
|
|
"paused": null,
|
|
"cost": {
|
|
"total": 0.005
|
|
},
|
|
"error": "Wait 1: Wait time exceeds maximum of 5 minutes; enable async mode to wait up to 30 days",
|
|
"finalOutput": null,
|
|
"blockOutputs": null
|
|
}
|
|
}
|
|
}
|
|
}
|
|
}
|
|
},
|
|
"401": {
|
|
"$ref": "#/components/responses/Unauthorized"
|
|
},
|
|
"404": {
|
|
"$ref": "#/components/responses/NotFound"
|
|
}
|
|
}
|
|
}
|
|
},
|
|
"/api/workflows/{id}/executions/{executionId}/cancel": {
|
|
"post": {
|
|
"operationId": "cancelExecution",
|
|
"summary": "Cancel Execution",
|
|
"description": "Cancel a running workflow execution. Only effective for executions that are still in progress.",
|
|
"tags": ["Workflows"],
|
|
"x-codeSamples": [
|
|
{
|
|
"id": "curl",
|
|
"label": "cURL",
|
|
"lang": "bash",
|
|
"source": "curl -X POST \\\n \"https://www.sim.ai/api/workflows/{id}/executions/{executionId}/cancel\" \\\n -H \"X-API-Key: YOUR_API_KEY\""
|
|
}
|
|
],
|
|
"parameters": [
|
|
{
|
|
"name": "id",
|
|
"in": "path",
|
|
"required": true,
|
|
"description": "The unique identifier of the workflow.",
|
|
"schema": {
|
|
"type": "string",
|
|
"example": "wf_1a2b3c4d5e"
|
|
}
|
|
},
|
|
{
|
|
"name": "executionId",
|
|
"in": "path",
|
|
"required": true,
|
|
"description": "The unique identifier of the execution to cancel.",
|
|
"schema": {
|
|
"type": "string",
|
|
"example": "exec_9f8e7d6c5b"
|
|
}
|
|
}
|
|
],
|
|
"responses": {
|
|
"200": {
|
|
"description": "Execution was successfully cancelled.",
|
|
"content": {
|
|
"application/json": {
|
|
"schema": {
|
|
"type": "object",
|
|
"properties": {
|
|
"success": {
|
|
"type": "boolean",
|
|
"description": "Whether the cancellation was successful."
|
|
},
|
|
"executionId": {
|
|
"type": "string",
|
|
"description": "The ID of the cancelled execution."
|
|
}
|
|
}
|
|
},
|
|
"example": {
|
|
"success": true,
|
|
"executionId": "exec_abc123"
|
|
}
|
|
}
|
|
}
|
|
},
|
|
"401": {
|
|
"$ref": "#/components/responses/Unauthorized"
|
|
},
|
|
"404": {
|
|
"$ref": "#/components/responses/NotFound"
|
|
}
|
|
}
|
|
}
|
|
},
|
|
"/api/workflows/{id}/paused": {
|
|
"get": {
|
|
"operationId": "listPausedExecutions",
|
|
"summary": "List Paused Executions",
|
|
"description": "List all paused executions for a workflow. Workflows pause at Human in the Loop blocks and wait for input before continuing. Use this endpoint to discover which executions need attention.",
|
|
"tags": ["Human in the Loop"],
|
|
"x-codeSamples": [
|
|
{
|
|
"id": "curl",
|
|
"label": "cURL",
|
|
"lang": "bash",
|
|
"source": "curl -X GET \\\n \"https://www.sim.ai/api/workflows/{id}/paused?status=paused\" \\\n -H \"X-API-Key: YOUR_API_KEY\""
|
|
}
|
|
],
|
|
"parameters": [
|
|
{
|
|
"name": "id",
|
|
"in": "path",
|
|
"required": true,
|
|
"description": "The unique identifier of the workflow.",
|
|
"schema": {
|
|
"type": "string",
|
|
"example": "wf_1a2b3c4d5e"
|
|
}
|
|
},
|
|
{
|
|
"name": "status",
|
|
"in": "query",
|
|
"required": false,
|
|
"description": "Filter paused executions by status.",
|
|
"schema": {
|
|
"type": "string",
|
|
"example": "paused"
|
|
}
|
|
}
|
|
],
|
|
"responses": {
|
|
"200": {
|
|
"description": "List of paused executions.",
|
|
"content": {
|
|
"application/json": {
|
|
"schema": {
|
|
"type": "object",
|
|
"properties": {
|
|
"pausedExecutions": {
|
|
"type": "array",
|
|
"items": {
|
|
"$ref": "#/components/schemas/PausedExecutionSummary"
|
|
}
|
|
}
|
|
}
|
|
},
|
|
"example": {
|
|
"pausedExecutions": [
|
|
{
|
|
"id": "pe_abc123",
|
|
"workflowId": "wf_1a2b3c4d5e",
|
|
"executionId": "exec_9f8e7d6c5b",
|
|
"status": "paused",
|
|
"totalPauseCount": 1,
|
|
"resumedCount": 0,
|
|
"pausedAt": "2026-01-15T10:30:00Z",
|
|
"updatedAt": "2026-01-15T10:30:00Z",
|
|
"expiresAt": null,
|
|
"metadata": null,
|
|
"triggerIds": [],
|
|
"pausePoints": [
|
|
{
|
|
"contextId": "ctx_xyz789",
|
|
"blockId": "block_hitl_1",
|
|
"registeredAt": "2026-01-15T10:30:00Z",
|
|
"resumeStatus": "paused",
|
|
"snapshotReady": true,
|
|
"resumeLinks": {
|
|
"apiUrl": "https://www.sim.ai/api/resume/wf_1a2b3c4d5e/exec_9f8e7d6c5b/ctx_xyz789",
|
|
"uiUrl": "https://www.sim.ai/resume/wf_1a2b3c4d5e/exec_9f8e7d6c5b",
|
|
"contextId": "ctx_xyz789",
|
|
"executionId": "exec_9f8e7d6c5b",
|
|
"workflowId": "wf_1a2b3c4d5e"
|
|
},
|
|
"response": {
|
|
"displayData": {
|
|
"title": "Approval Required",
|
|
"message": "Please review this request"
|
|
},
|
|
"formFields": []
|
|
}
|
|
}
|
|
]
|
|
}
|
|
]
|
|
}
|
|
}
|
|
}
|
|
},
|
|
"400": {
|
|
"$ref": "#/components/responses/BadRequest"
|
|
},
|
|
"401": {
|
|
"$ref": "#/components/responses/Unauthorized"
|
|
},
|
|
"403": {
|
|
"$ref": "#/components/responses/Forbidden"
|
|
},
|
|
"404": {
|
|
"$ref": "#/components/responses/NotFound"
|
|
}
|
|
}
|
|
}
|
|
},
|
|
"/api/workflows/{id}/paused/{executionId}": {
|
|
"get": {
|
|
"operationId": "getPausedExecution",
|
|
"summary": "Get Paused Execution",
|
|
"description": "Get detailed information about a specific paused execution, including its pause points, execution snapshot, and resume queue. Use this to inspect the state before resuming.",
|
|
"tags": ["Human in the Loop"],
|
|
"x-codeSamples": [
|
|
{
|
|
"id": "curl",
|
|
"label": "cURL",
|
|
"lang": "bash",
|
|
"source": "curl -X GET \\\n \"https://www.sim.ai/api/workflows/{id}/paused/{executionId}\" \\\n -H \"X-API-Key: YOUR_API_KEY\""
|
|
}
|
|
],
|
|
"parameters": [
|
|
{
|
|
"name": "id",
|
|
"in": "path",
|
|
"required": true,
|
|
"description": "The unique identifier of the workflow.",
|
|
"schema": {
|
|
"type": "string",
|
|
"example": "wf_1a2b3c4d5e"
|
|
}
|
|
},
|
|
{
|
|
"name": "executionId",
|
|
"in": "path",
|
|
"required": true,
|
|
"description": "The execution ID of the paused execution.",
|
|
"schema": {
|
|
"type": "string",
|
|
"example": "exec_9f8e7d6c5b"
|
|
}
|
|
}
|
|
],
|
|
"responses": {
|
|
"200": {
|
|
"description": "Paused execution details.",
|
|
"content": {
|
|
"application/json": {
|
|
"schema": {
|
|
"$ref": "#/components/schemas/PausedExecutionDetail"
|
|
}
|
|
}
|
|
}
|
|
},
|
|
"401": {
|
|
"$ref": "#/components/responses/Unauthorized"
|
|
},
|
|
"403": {
|
|
"$ref": "#/components/responses/Forbidden"
|
|
},
|
|
"404": {
|
|
"$ref": "#/components/responses/NotFound"
|
|
}
|
|
}
|
|
}
|
|
},
|
|
"/api/resume/{workflowId}/{executionId}": {
|
|
"get": {
|
|
"operationId": "getPausedExecutionByResumePath",
|
|
"summary": "Get Paused Execution (Resume Path)",
|
|
"description": "Get detailed information about a specific paused execution using the resume URL path. Returns the same data as the workflow paused execution detail endpoint.",
|
|
"tags": ["Human in the Loop"],
|
|
"x-codeSamples": [
|
|
{
|
|
"id": "curl",
|
|
"label": "cURL",
|
|
"lang": "bash",
|
|
"source": "curl -X GET \\\n \"https://www.sim.ai/api/resume/{workflowId}/{executionId}\" \\\n -H \"X-API-Key: YOUR_API_KEY\""
|
|
}
|
|
],
|
|
"parameters": [
|
|
{
|
|
"name": "workflowId",
|
|
"in": "path",
|
|
"required": true,
|
|
"description": "The unique identifier of the workflow.",
|
|
"schema": {
|
|
"type": "string",
|
|
"example": "wf_1a2b3c4d5e"
|
|
}
|
|
},
|
|
{
|
|
"name": "executionId",
|
|
"in": "path",
|
|
"required": true,
|
|
"description": "The execution ID of the paused execution.",
|
|
"schema": {
|
|
"type": "string",
|
|
"example": "exec_9f8e7d6c5b"
|
|
}
|
|
}
|
|
],
|
|
"responses": {
|
|
"200": {
|
|
"description": "Paused execution details.",
|
|
"content": {
|
|
"application/json": {
|
|
"schema": {
|
|
"$ref": "#/components/schemas/PausedExecutionDetail"
|
|
}
|
|
}
|
|
}
|
|
},
|
|
"401": {
|
|
"$ref": "#/components/responses/Unauthorized"
|
|
},
|
|
"403": {
|
|
"$ref": "#/components/responses/Forbidden"
|
|
},
|
|
"404": {
|
|
"$ref": "#/components/responses/NotFound"
|
|
},
|
|
"500": {
|
|
"description": "Internal server error.",
|
|
"content": {
|
|
"application/json": {
|
|
"schema": {
|
|
"type": "object",
|
|
"properties": {
|
|
"error": {
|
|
"type": "string",
|
|
"description": "Human-readable error message."
|
|
}
|
|
}
|
|
}
|
|
}
|
|
}
|
|
}
|
|
}
|
|
}
|
|
},
|
|
"/api/resume/{workflowId}/{executionId}/{contextId}": {
|
|
"get": {
|
|
"operationId": "getPauseContext",
|
|
"summary": "Get Pause Context",
|
|
"description": "Get detailed information about a specific pause context within a paused execution. Returns the pause point details, resume queue state, and any active resume entry.",
|
|
"tags": ["Human in the Loop"],
|
|
"x-codeSamples": [
|
|
{
|
|
"id": "curl",
|
|
"label": "cURL",
|
|
"lang": "bash",
|
|
"source": "curl -X GET \\\n \"https://www.sim.ai/api/resume/{workflowId}/{executionId}/{contextId}\" \\\n -H \"X-API-Key: YOUR_API_KEY\""
|
|
}
|
|
],
|
|
"parameters": [
|
|
{
|
|
"name": "workflowId",
|
|
"in": "path",
|
|
"required": true,
|
|
"description": "The unique identifier of the workflow.",
|
|
"schema": {
|
|
"type": "string",
|
|
"example": "wf_1a2b3c4d5e"
|
|
}
|
|
},
|
|
{
|
|
"name": "executionId",
|
|
"in": "path",
|
|
"required": true,
|
|
"description": "The execution ID of the paused execution.",
|
|
"schema": {
|
|
"type": "string",
|
|
"example": "exec_9f8e7d6c5b"
|
|
}
|
|
},
|
|
{
|
|
"name": "contextId",
|
|
"in": "path",
|
|
"required": true,
|
|
"description": "The pause context ID to retrieve details for.",
|
|
"schema": {
|
|
"type": "string",
|
|
"example": "ctx_xyz789"
|
|
}
|
|
}
|
|
],
|
|
"responses": {
|
|
"200": {
|
|
"description": "Pause context details.",
|
|
"content": {
|
|
"application/json": {
|
|
"schema": {
|
|
"$ref": "#/components/schemas/PauseContextDetail"
|
|
}
|
|
}
|
|
}
|
|
},
|
|
"401": {
|
|
"$ref": "#/components/responses/Unauthorized"
|
|
},
|
|
"403": {
|
|
"$ref": "#/components/responses/Forbidden"
|
|
},
|
|
"404": {
|
|
"$ref": "#/components/responses/NotFound"
|
|
}
|
|
}
|
|
},
|
|
"post": {
|
|
"operationId": "resumeExecution",
|
|
"summary": "Resume Execution",
|
|
"description": "Resume a paused workflow execution by providing input for a specific pause context. The execution continues from where it paused, using the provided input. Supports synchronous, asynchronous, and streaming modes (determined by the original execution's configuration).",
|
|
"tags": ["Human in the Loop"],
|
|
"x-codeSamples": [
|
|
{
|
|
"id": "curl",
|
|
"label": "cURL",
|
|
"lang": "bash",
|
|
"source": "curl -X POST \\\n \"https://www.sim.ai/api/resume/{workflowId}/{executionId}/{contextId}\" \\\n -H \"X-API-Key: YOUR_API_KEY\" \\\n -H \"Content-Type: application/json\" \\\n -d '{\n \"input\": {\n \"approved\": true,\n \"comment\": \"Looks good to me\"\n }\n }'"
|
|
}
|
|
],
|
|
"parameters": [
|
|
{
|
|
"name": "workflowId",
|
|
"in": "path",
|
|
"required": true,
|
|
"description": "The unique identifier of the workflow.",
|
|
"schema": {
|
|
"type": "string",
|
|
"example": "wf_1a2b3c4d5e"
|
|
}
|
|
},
|
|
{
|
|
"name": "executionId",
|
|
"in": "path",
|
|
"required": true,
|
|
"description": "The execution ID of the paused execution.",
|
|
"schema": {
|
|
"type": "string",
|
|
"example": "exec_9f8e7d6c5b"
|
|
}
|
|
},
|
|
{
|
|
"name": "contextId",
|
|
"in": "path",
|
|
"required": true,
|
|
"description": "The pause context ID to resume. Found in the pause point's contextId field or resumeLinks.",
|
|
"schema": {
|
|
"type": "string",
|
|
"example": "ctx_xyz789"
|
|
}
|
|
}
|
|
],
|
|
"requestBody": {
|
|
"description": "Input data for the resumed execution. The structure depends on the workflow's Human in the Loop block configuration.",
|
|
"content": {
|
|
"application/json": {
|
|
"schema": {
|
|
"type": "object",
|
|
"properties": {
|
|
"input": {
|
|
"type": "object",
|
|
"description": "Key-value pairs to pass as input to the resumed execution. If omitted, the entire request body is used as input.",
|
|
"additionalProperties": true
|
|
}
|
|
}
|
|
},
|
|
"example": {
|
|
"input": {
|
|
"approved": true,
|
|
"comment": "Looks good to me"
|
|
}
|
|
}
|
|
}
|
|
}
|
|
},
|
|
"responses": {
|
|
"200": {
|
|
"description": "Resume execution completed synchronously, or resume was queued behind another in-progress resume.",
|
|
"content": {
|
|
"application/json": {
|
|
"schema": {
|
|
"oneOf": [
|
|
{
|
|
"$ref": "#/components/schemas/ResumeResult"
|
|
},
|
|
{
|
|
"type": "object",
|
|
"description": "Resume has been queued behind another in-progress resume.",
|
|
"properties": {
|
|
"status": {
|
|
"type": "string",
|
|
"enum": ["queued"],
|
|
"description": "Indicates the resume is queued."
|
|
},
|
|
"executionId": {
|
|
"type": "string",
|
|
"description": "The execution ID assigned to this resume."
|
|
},
|
|
"queuePosition": {
|
|
"type": "integer",
|
|
"description": "Position in the resume queue."
|
|
},
|
|
"message": {
|
|
"type": "string",
|
|
"description": "Human-readable status message."
|
|
}
|
|
}
|
|
},
|
|
{
|
|
"type": "object",
|
|
"description": "Resume execution started (non-API-key callers). The execution runs asynchronously.",
|
|
"properties": {
|
|
"status": {
|
|
"type": "string",
|
|
"enum": ["started"],
|
|
"description": "Indicates the resume execution has started."
|
|
},
|
|
"executionId": {
|
|
"type": "string",
|
|
"description": "The execution ID for the resumed workflow."
|
|
},
|
|
"message": {
|
|
"type": "string",
|
|
"description": "Human-readable status message."
|
|
}
|
|
}
|
|
}
|
|
]
|
|
},
|
|
"examples": {
|
|
"sync": {
|
|
"summary": "Synchronous completion",
|
|
"value": {
|
|
"success": true,
|
|
"status": "completed",
|
|
"executionId": "exec_new123",
|
|
"output": {
|
|
"result": "Approved and processed"
|
|
},
|
|
"error": null,
|
|
"metadata": {
|
|
"duration": 850,
|
|
"startTime": "2026-01-15T10:35:00Z",
|
|
"endTime": "2026-01-15T10:35:01Z"
|
|
}
|
|
}
|
|
},
|
|
"queued": {
|
|
"summary": "Queued behind another resume",
|
|
"value": {
|
|
"status": "queued",
|
|
"executionId": "exec_new123",
|
|
"queuePosition": 2,
|
|
"message": "Resume queued. It will run after current resumes finish."
|
|
}
|
|
},
|
|
"started": {
|
|
"summary": "Execution started (fire and forget)",
|
|
"value": {
|
|
"status": "started",
|
|
"executionId": "exec_new123",
|
|
"message": "Resume execution started."
|
|
}
|
|
}
|
|
}
|
|
}
|
|
}
|
|
},
|
|
"202": {
|
|
"description": "Resume execution has been queued for asynchronous processing. Poll the statusUrl for results.",
|
|
"content": {
|
|
"application/json": {
|
|
"schema": {
|
|
"$ref": "#/components/schemas/AsyncExecutionResult"
|
|
},
|
|
"example": {
|
|
"success": true,
|
|
"async": true,
|
|
"jobId": "job_4a3b2c1d0e",
|
|
"executionId": "exec_new123",
|
|
"message": "Resume execution queued",
|
|
"statusUrl": "https://www.sim.ai/api/jobs/job_4a3b2c1d0e"
|
|
}
|
|
}
|
|
}
|
|
},
|
|
"400": {
|
|
"$ref": "#/components/responses/BadRequest"
|
|
},
|
|
"401": {
|
|
"$ref": "#/components/responses/Unauthorized"
|
|
},
|
|
"403": {
|
|
"$ref": "#/components/responses/Forbidden"
|
|
},
|
|
"404": {
|
|
"$ref": "#/components/responses/NotFound"
|
|
},
|
|
"503": {
|
|
"description": "Failed to queue the resume execution. Retry the request.",
|
|
"content": {
|
|
"application/json": {
|
|
"schema": {
|
|
"type": "object",
|
|
"properties": {
|
|
"error": {
|
|
"type": "string",
|
|
"description": "Error message."
|
|
}
|
|
}
|
|
}
|
|
}
|
|
}
|
|
},
|
|
"500": {
|
|
"description": "Internal server error.",
|
|
"content": {
|
|
"application/json": {
|
|
"schema": {
|
|
"type": "object",
|
|
"properties": {
|
|
"error": {
|
|
"type": "string",
|
|
"description": "Human-readable error message."
|
|
}
|
|
}
|
|
}
|
|
}
|
|
}
|
|
}
|
|
}
|
|
}
|
|
},
|
|
"/api/v1/workflows": {
|
|
"get": {
|
|
"operationId": "listWorkflows",
|
|
"summary": "List Workflows",
|
|
"description": "Retrieve all workflows in a workspace with cursor-based pagination.",
|
|
"tags": ["Workflows"],
|
|
"x-codeSamples": [
|
|
{
|
|
"id": "curl",
|
|
"label": "cURL",
|
|
"lang": "bash",
|
|
"source": "curl -X GET \\\n \"https://www.sim.ai/api/v1/workflows?workspaceId=YOUR_WORKSPACE_ID\" \\\n -H \"X-API-Key: YOUR_API_KEY\""
|
|
}
|
|
],
|
|
"parameters": [
|
|
{
|
|
"$ref": "#/components/parameters/WorkspaceId"
|
|
},
|
|
{
|
|
"name": "folderId",
|
|
"in": "query",
|
|
"description": "Filter results to only include workflows within this folder.",
|
|
"schema": {
|
|
"type": "string"
|
|
}
|
|
},
|
|
{
|
|
"name": "deployedOnly",
|
|
"in": "query",
|
|
"description": "When true, only return workflows that have been deployed. Useful for listing workflows available for API execution.",
|
|
"schema": {
|
|
"type": "boolean"
|
|
}
|
|
},
|
|
{
|
|
"name": "limit",
|
|
"in": "query",
|
|
"description": "Maximum number of workflows to return per page. Must be between 1 and 100.",
|
|
"schema": {
|
|
"type": "integer",
|
|
"minimum": 1,
|
|
"maximum": 100
|
|
}
|
|
},
|
|
{
|
|
"name": "cursor",
|
|
"in": "query",
|
|
"description": "Pagination cursor returned from a previous request's nextCursor field. Omit for the first page.",
|
|
"schema": {
|
|
"type": "string"
|
|
}
|
|
}
|
|
],
|
|
"responses": {
|
|
"200": {
|
|
"description": "A paginated list of workflows.",
|
|
"content": {
|
|
"application/json": {
|
|
"schema": {
|
|
"type": "object",
|
|
"properties": {
|
|
"data": {
|
|
"type": "array",
|
|
"description": "Array of workflow summary objects for the current page.",
|
|
"items": {
|
|
"$ref": "#/components/schemas/WorkflowSummary"
|
|
}
|
|
},
|
|
"nextCursor": {
|
|
"type": "string",
|
|
"nullable": true,
|
|
"description": "Cursor for fetching the next page of results. null when there are no more results."
|
|
},
|
|
"limits": {
|
|
"$ref": "#/components/schemas/Limits",
|
|
"description": "Rate limit and usage information for the current API key."
|
|
}
|
|
}
|
|
},
|
|
"example": {
|
|
"data": [
|
|
{
|
|
"id": "wf_abc123",
|
|
"name": "Weather Bot",
|
|
"isDeployed": true,
|
|
"createdAt": "2026-01-15T10:30:00Z",
|
|
"updatedAt": "2026-01-15T10:30:00Z"
|
|
}
|
|
],
|
|
"nextCursor": null
|
|
}
|
|
}
|
|
}
|
|
},
|
|
"400": {
|
|
"$ref": "#/components/responses/BadRequest"
|
|
},
|
|
"401": {
|
|
"$ref": "#/components/responses/Unauthorized"
|
|
},
|
|
"429": {
|
|
"$ref": "#/components/responses/RateLimited"
|
|
}
|
|
}
|
|
}
|
|
},
|
|
"/api/v1/workflows/{id}": {
|
|
"get": {
|
|
"operationId": "getWorkflow",
|
|
"summary": "Get Workflow",
|
|
"description": "Retrieve details for a single workflow, including its input fields and deployment status.",
|
|
"tags": ["Workflows"],
|
|
"x-codeSamples": [
|
|
{
|
|
"id": "curl",
|
|
"label": "cURL",
|
|
"lang": "bash",
|
|
"source": "curl -X GET \\\n \"https://www.sim.ai/api/v1/workflows/{id}\" \\\n -H \"X-API-Key: YOUR_API_KEY\""
|
|
}
|
|
],
|
|
"parameters": [
|
|
{
|
|
"name": "id",
|
|
"in": "path",
|
|
"required": true,
|
|
"description": "The unique workflow identifier.",
|
|
"schema": {
|
|
"type": "string",
|
|
"example": "wf_1a2b3c4d5e"
|
|
}
|
|
}
|
|
],
|
|
"responses": {
|
|
"200": {
|
|
"description": "Workflow details including input field definitions.",
|
|
"content": {
|
|
"application/json": {
|
|
"schema": {
|
|
"type": "object",
|
|
"properties": {
|
|
"data": {
|
|
"description": "The full workflow detail object.",
|
|
"$ref": "#/components/schemas/WorkflowDetail"
|
|
},
|
|
"limits": {
|
|
"$ref": "#/components/schemas/Limits",
|
|
"description": "Rate limit and usage information for the current API key."
|
|
}
|
|
}
|
|
},
|
|
"example": {
|
|
"data": {
|
|
"id": "wf_abc123",
|
|
"name": "Weather Bot",
|
|
"description": "A workflow that fetches weather data",
|
|
"isDeployed": true,
|
|
"createdAt": "2026-01-15T10:30:00Z",
|
|
"updatedAt": "2026-01-15T10:30:00Z"
|
|
}
|
|
}
|
|
}
|
|
}
|
|
},
|
|
"401": {
|
|
"$ref": "#/components/responses/Unauthorized"
|
|
},
|
|
"404": {
|
|
"$ref": "#/components/responses/NotFound"
|
|
},
|
|
"429": {
|
|
"$ref": "#/components/responses/RateLimited"
|
|
}
|
|
}
|
|
}
|
|
},
|
|
"/api/jobs/{jobId}": {
|
|
"get": {
|
|
"operationId": "getJobStatus",
|
|
"summary": "Get Job Status",
|
|
"description": "Poll the status of an asynchronous workflow execution. Use the jobId returned from the Execute Workflow endpoint when the execution is queued asynchronously.",
|
|
"tags": ["Workflows"],
|
|
"x-codeSamples": [
|
|
{
|
|
"id": "curl",
|
|
"label": "cURL",
|
|
"lang": "bash",
|
|
"source": "curl -X GET \\\n \"https://www.sim.ai/api/jobs/{jobId}\" \\\n -H \"X-API-Key: YOUR_API_KEY\""
|
|
}
|
|
],
|
|
"parameters": [
|
|
{
|
|
"name": "jobId",
|
|
"in": "path",
|
|
"required": true,
|
|
"description": "The job identifier returned in the async execution response.",
|
|
"schema": {
|
|
"type": "string",
|
|
"example": "job_4a3b2c1d0e"
|
|
}
|
|
}
|
|
],
|
|
"responses": {
|
|
"200": {
|
|
"description": "Current status of the job. When completed, includes the execution output.",
|
|
"content": {
|
|
"application/json": {
|
|
"schema": {
|
|
"$ref": "#/components/schemas/JobStatus"
|
|
},
|
|
"example": {
|
|
"success": true,
|
|
"taskId": "job_abc123",
|
|
"status": "completed",
|
|
"output": {
|
|
"content": "Done"
|
|
},
|
|
"metadata": {
|
|
"startTime": "2026-01-15T10:30:00Z"
|
|
}
|
|
}
|
|
}
|
|
}
|
|
},
|
|
"401": {
|
|
"$ref": "#/components/responses/Unauthorized"
|
|
},
|
|
"403": {
|
|
"$ref": "#/components/responses/Forbidden"
|
|
},
|
|
"404": {
|
|
"$ref": "#/components/responses/NotFound"
|
|
}
|
|
}
|
|
}
|
|
},
|
|
"/api/v1/logs": {
|
|
"get": {
|
|
"operationId": "queryLogs",
|
|
"summary": "Query Logs",
|
|
"description": "List workflow execution logs with advanced filtering and cursor-based pagination. Supports filtering by workflow, trigger type, date range, duration, cost, and more.",
|
|
"tags": ["Logs"],
|
|
"x-codeSamples": [
|
|
{
|
|
"id": "curl",
|
|
"label": "cURL",
|
|
"lang": "bash",
|
|
"source": "curl -X GET \\\n \"https://www.sim.ai/api/v1/logs?workspaceId=YOUR_WORKSPACE_ID\" \\\n -H \"X-API-Key: YOUR_API_KEY\""
|
|
}
|
|
],
|
|
"parameters": [
|
|
{
|
|
"$ref": "#/components/parameters/WorkspaceId"
|
|
},
|
|
{
|
|
"name": "workflowIds",
|
|
"in": "query",
|
|
"description": "Comma-separated list of workflow IDs to filter by. Only logs from these workflows will be returned.",
|
|
"schema": {
|
|
"type": "string"
|
|
}
|
|
},
|
|
{
|
|
"name": "folderIds",
|
|
"in": "query",
|
|
"description": "Comma-separated list of folder IDs. Returns logs for all workflows within these folders.",
|
|
"schema": {
|
|
"type": "string"
|
|
}
|
|
},
|
|
{
|
|
"name": "triggers",
|
|
"in": "query",
|
|
"description": "Comma-separated trigger types to filter by: api, webhook, schedule, manual, chat.",
|
|
"schema": {
|
|
"type": "string"
|
|
}
|
|
},
|
|
{
|
|
"name": "level",
|
|
"in": "query",
|
|
"description": "Filter logs by severity level. info for successful executions, error for failed ones.",
|
|
"schema": {
|
|
"type": "string"
|
|
}
|
|
},
|
|
{
|
|
"name": "startDate",
|
|
"in": "query",
|
|
"description": "Only return logs after this ISO 8601 timestamp (inclusive).",
|
|
"schema": {
|
|
"type": "string",
|
|
"format": "date-time"
|
|
}
|
|
},
|
|
{
|
|
"name": "endDate",
|
|
"in": "query",
|
|
"description": "Only return logs before this ISO 8601 timestamp (inclusive).",
|
|
"schema": {
|
|
"type": "string",
|
|
"format": "date-time"
|
|
}
|
|
},
|
|
{
|
|
"name": "executionId",
|
|
"in": "query",
|
|
"description": "Filter by an exact execution ID. Useful for looking up a specific run.",
|
|
"schema": {
|
|
"type": "string"
|
|
}
|
|
},
|
|
{
|
|
"name": "minDurationMs",
|
|
"in": "query",
|
|
"description": "Only return logs where execution took at least this many milliseconds.",
|
|
"schema": {
|
|
"type": "integer"
|
|
}
|
|
},
|
|
{
|
|
"name": "maxDurationMs",
|
|
"in": "query",
|
|
"description": "Only return logs where execution took at most this many milliseconds.",
|
|
"schema": {
|
|
"type": "integer"
|
|
}
|
|
},
|
|
{
|
|
"name": "minCost",
|
|
"in": "query",
|
|
"description": "Only return logs where execution cost at least this amount in USD.",
|
|
"schema": {
|
|
"type": "number"
|
|
}
|
|
},
|
|
{
|
|
"name": "maxCost",
|
|
"in": "query",
|
|
"description": "Only return logs where execution cost at most this amount in USD.",
|
|
"schema": {
|
|
"type": "number"
|
|
}
|
|
},
|
|
{
|
|
"name": "model",
|
|
"in": "query",
|
|
"description": "Filter by the AI model used during execution (e.g., gpt-4o, claude-sonnet-4-20250514).",
|
|
"schema": {
|
|
"type": "string"
|
|
}
|
|
},
|
|
{
|
|
"name": "details",
|
|
"in": "query",
|
|
"description": "Response detail level. basic returns summary fields only. full includes execution data, trace spans, and outputs.",
|
|
"schema": {
|
|
"type": "string"
|
|
}
|
|
},
|
|
{
|
|
"name": "includeTraceSpans",
|
|
"in": "query",
|
|
"description": "When true, includes block-level execution trace spans with timing and input/output data.",
|
|
"schema": {
|
|
"type": "boolean"
|
|
}
|
|
},
|
|
{
|
|
"name": "includeFinalOutput",
|
|
"in": "query",
|
|
"description": "When true, includes the workflow's final output in each log entry.",
|
|
"schema": {
|
|
"type": "boolean"
|
|
}
|
|
},
|
|
{
|
|
"name": "limit",
|
|
"in": "query",
|
|
"description": "Maximum number of log entries to return per page.",
|
|
"schema": {
|
|
"type": "integer"
|
|
}
|
|
},
|
|
{
|
|
"name": "cursor",
|
|
"in": "query",
|
|
"description": "Pagination cursor returned from a previous request's nextCursor field.",
|
|
"schema": {
|
|
"type": "string"
|
|
}
|
|
},
|
|
{
|
|
"name": "order",
|
|
"in": "query",
|
|
"description": "Sort order by execution start time. desc returns newest first.",
|
|
"schema": {
|
|
"type": "string"
|
|
}
|
|
}
|
|
],
|
|
"responses": {
|
|
"200": {
|
|
"description": "A paginated list of execution logs matching the filter criteria.",
|
|
"content": {
|
|
"application/json": {
|
|
"schema": {
|
|
"type": "object",
|
|
"properties": {
|
|
"data": {
|
|
"type": "array",
|
|
"description": "Array of log entries for the current page.",
|
|
"items": {
|
|
"$ref": "#/components/schemas/LogEntry"
|
|
}
|
|
},
|
|
"nextCursor": {
|
|
"type": "string",
|
|
"nullable": true,
|
|
"description": "Cursor for fetching the next page. null when there are no more results."
|
|
},
|
|
"limits": {
|
|
"$ref": "#/components/schemas/Limits"
|
|
}
|
|
}
|
|
},
|
|
"example": {
|
|
"data": [
|
|
{
|
|
"id": "log_abc123",
|
|
"workflowId": "wf_abc123",
|
|
"level": "info",
|
|
"trigger": "api",
|
|
"createdAt": "2026-01-15T10:30:00Z"
|
|
}
|
|
],
|
|
"nextCursor": null
|
|
}
|
|
}
|
|
}
|
|
},
|
|
"400": {
|
|
"$ref": "#/components/responses/BadRequest"
|
|
},
|
|
"401": {
|
|
"$ref": "#/components/responses/Unauthorized"
|
|
},
|
|
"429": {
|
|
"$ref": "#/components/responses/RateLimited"
|
|
}
|
|
}
|
|
}
|
|
},
|
|
"/api/v1/logs/{id}": {
|
|
"get": {
|
|
"operationId": "getLogDetails",
|
|
"summary": "Get Log Details",
|
|
"description": "Retrieve detailed information about a specific log entry, including workflow metadata, execution data, and cost breakdown.",
|
|
"tags": ["Logs"],
|
|
"x-codeSamples": [
|
|
{
|
|
"id": "curl",
|
|
"label": "cURL",
|
|
"lang": "bash",
|
|
"source": "curl -X GET \\\n \"https://www.sim.ai/api/v1/logs/{id}\" \\\n -H \"X-API-Key: YOUR_API_KEY\""
|
|
}
|
|
],
|
|
"parameters": [
|
|
{
|
|
"name": "id",
|
|
"in": "path",
|
|
"required": true,
|
|
"description": "The unique identifier of the log entry.",
|
|
"schema": {
|
|
"type": "string",
|
|
"example": "log_7x8y9z0a1b"
|
|
}
|
|
}
|
|
],
|
|
"responses": {
|
|
"200": {
|
|
"description": "Detailed log entry with full execution data and cost breakdown.",
|
|
"content": {
|
|
"application/json": {
|
|
"schema": {
|
|
"type": "object",
|
|
"properties": {
|
|
"data": {
|
|
"description": "The full log detail object.",
|
|
"$ref": "#/components/schemas/LogDetail"
|
|
},
|
|
"limits": {
|
|
"$ref": "#/components/schemas/Limits"
|
|
}
|
|
}
|
|
},
|
|
"example": {
|
|
"data": {
|
|
"id": "log_abc123",
|
|
"workflowId": "wf_abc123",
|
|
"executionId": "exec_abc123",
|
|
"level": "info",
|
|
"trigger": "api",
|
|
"totalDurationMs": 1250,
|
|
"startedAt": "2026-01-15T10:30:00Z",
|
|
"endedAt": "2026-01-15T10:30:01Z",
|
|
"createdAt": "2026-01-15T10:30:00Z"
|
|
}
|
|
}
|
|
}
|
|
}
|
|
},
|
|
"401": {
|
|
"$ref": "#/components/responses/Unauthorized"
|
|
},
|
|
"404": {
|
|
"$ref": "#/components/responses/NotFound"
|
|
},
|
|
"429": {
|
|
"$ref": "#/components/responses/RateLimited"
|
|
}
|
|
}
|
|
}
|
|
},
|
|
"/api/v1/logs/executions/{executionId}": {
|
|
"get": {
|
|
"operationId": "getExecutionDetails",
|
|
"summary": "Get Execution Details",
|
|
"description": "Retrieve the full execution state snapshot, including the workflow state at time of execution and detailed metadata.",
|
|
"tags": ["Logs"],
|
|
"x-codeSamples": [
|
|
{
|
|
"id": "curl",
|
|
"label": "cURL",
|
|
"lang": "bash",
|
|
"source": "curl -X GET \\\n \"https://www.sim.ai/api/v1/logs/executions/{executionId}\" \\\n -H \"X-API-Key: YOUR_API_KEY\""
|
|
}
|
|
],
|
|
"parameters": [
|
|
{
|
|
"name": "executionId",
|
|
"in": "path",
|
|
"required": true,
|
|
"description": "The unique execution identifier.",
|
|
"schema": {
|
|
"type": "string",
|
|
"example": "exec_9f8e7d6c5b"
|
|
}
|
|
}
|
|
],
|
|
"responses": {
|
|
"200": {
|
|
"description": "Full execution state snapshot with workflow state and metadata.",
|
|
"content": {
|
|
"application/json": {
|
|
"schema": {
|
|
"type": "object",
|
|
"properties": {
|
|
"executionId": {
|
|
"type": "string",
|
|
"description": "The unique identifier for this execution."
|
|
},
|
|
"workflowId": {
|
|
"type": "string",
|
|
"description": "The workflow that was executed."
|
|
},
|
|
"workflowState": {
|
|
"type": "object",
|
|
"description": "Snapshot of the workflow configuration at the time of execution.",
|
|
"properties": {
|
|
"blocks": {
|
|
"type": "object",
|
|
"description": "Map of block IDs to their configuration and state during execution."
|
|
},
|
|
"edges": {
|
|
"type": "array",
|
|
"description": "List of connections between blocks defining the execution flow.",
|
|
"items": {
|
|
"type": "object"
|
|
}
|
|
},
|
|
"loops": {
|
|
"type": "object",
|
|
"description": "Loop configurations defining iterative execution patterns."
|
|
},
|
|
"parallels": {
|
|
"type": "object",
|
|
"description": "Parallel execution group configurations."
|
|
}
|
|
}
|
|
},
|
|
"executionMetadata": {
|
|
"type": "object",
|
|
"description": "Metadata about the execution including timing and cost information.",
|
|
"properties": {
|
|
"trigger": {
|
|
"type": "string",
|
|
"description": "How the execution was triggered (e.g., api, manual, schedule)."
|
|
},
|
|
"startedAt": {
|
|
"type": "string",
|
|
"format": "date-time",
|
|
"description": "ISO 8601 timestamp when execution started."
|
|
},
|
|
"endedAt": {
|
|
"type": "string",
|
|
"format": "date-time",
|
|
"description": "ISO 8601 timestamp when execution completed."
|
|
},
|
|
"totalDurationMs": {
|
|
"type": "integer",
|
|
"description": "Total execution duration in milliseconds."
|
|
},
|
|
"cost": {
|
|
"type": "object",
|
|
"description": "Cost breakdown for this execution including per-model details."
|
|
}
|
|
}
|
|
},
|
|
"limits": {
|
|
"$ref": "#/components/schemas/Limits"
|
|
}
|
|
}
|
|
},
|
|
"example": {
|
|
"executionId": "exec_abc123",
|
|
"workflowId": "wf_abc123",
|
|
"workflowState": {},
|
|
"executionMetadata": {}
|
|
}
|
|
}
|
|
}
|
|
},
|
|
"401": {
|
|
"$ref": "#/components/responses/Unauthorized"
|
|
},
|
|
"404": {
|
|
"$ref": "#/components/responses/NotFound"
|
|
},
|
|
"429": {
|
|
"$ref": "#/components/responses/RateLimited"
|
|
}
|
|
}
|
|
}
|
|
},
|
|
"/api/v1/audit-logs": {
|
|
"get": {
|
|
"operationId": "listAuditLogs",
|
|
"summary": "List Audit Logs",
|
|
"description": "Retrieve audit logs for your organization with cursor-based pagination. Requires an Enterprise subscription and organization admin or owner role.",
|
|
"tags": ["Audit Logs"],
|
|
"x-codeSamples": [
|
|
{
|
|
"id": "curl",
|
|
"label": "cURL",
|
|
"lang": "bash",
|
|
"source": "curl -X GET \\\n \"https://www.sim.ai/api/v1/audit-logs?workspaceId=YOUR_WORKSPACE_ID\" \\\n -H \"X-API-Key: YOUR_API_KEY\""
|
|
}
|
|
],
|
|
"parameters": [
|
|
{
|
|
"name": "action",
|
|
"in": "query",
|
|
"description": "Filter by action type (e.g., workflow.created, workflow.deployed, member.invited).",
|
|
"schema": {
|
|
"type": "string"
|
|
}
|
|
},
|
|
{
|
|
"name": "resourceType",
|
|
"in": "query",
|
|
"description": "Filter by resource type (e.g., workflow, workspace, member).",
|
|
"schema": {
|
|
"type": "string"
|
|
}
|
|
},
|
|
{
|
|
"name": "resourceId",
|
|
"in": "query",
|
|
"description": "Filter by a specific resource ID.",
|
|
"schema": {
|
|
"type": "string"
|
|
}
|
|
},
|
|
{
|
|
"$ref": "#/components/parameters/WorkspaceId"
|
|
},
|
|
{
|
|
"name": "actorId",
|
|
"in": "query",
|
|
"description": "Filter by the user who performed the action. Must be a member of your organization.",
|
|
"schema": {
|
|
"type": "string"
|
|
}
|
|
},
|
|
{
|
|
"name": "startDate",
|
|
"in": "query",
|
|
"description": "Only return logs after this ISO 8601 timestamp (inclusive).",
|
|
"schema": {
|
|
"type": "string",
|
|
"format": "date-time"
|
|
}
|
|
},
|
|
{
|
|
"name": "endDate",
|
|
"in": "query",
|
|
"description": "Only return logs before this ISO 8601 timestamp (inclusive).",
|
|
"schema": {
|
|
"type": "string",
|
|
"format": "date-time"
|
|
}
|
|
},
|
|
{
|
|
"name": "includeDeparted",
|
|
"in": "query",
|
|
"description": "When true, includes audit logs from users who have left the organization.",
|
|
"schema": {
|
|
"type": "boolean"
|
|
}
|
|
},
|
|
{
|
|
"name": "limit",
|
|
"in": "query",
|
|
"description": "Maximum number of audit log entries to return per page. Must be between 1 and 100.",
|
|
"schema": {
|
|
"type": "integer",
|
|
"minimum": 1,
|
|
"maximum": 100
|
|
}
|
|
},
|
|
{
|
|
"name": "cursor",
|
|
"in": "query",
|
|
"description": "Pagination cursor returned from a previous request's nextCursor field.",
|
|
"schema": {
|
|
"type": "string"
|
|
}
|
|
}
|
|
],
|
|
"responses": {
|
|
"200": {
|
|
"description": "A paginated list of audit log entries.",
|
|
"content": {
|
|
"application/json": {
|
|
"schema": {
|
|
"type": "object",
|
|
"properties": {
|
|
"data": {
|
|
"type": "array",
|
|
"description": "Array of audit log entries for the current page.",
|
|
"items": {
|
|
"$ref": "#/components/schemas/AuditLogEntry"
|
|
}
|
|
},
|
|
"nextCursor": {
|
|
"type": "string",
|
|
"nullable": true,
|
|
"description": "Cursor for fetching the next page. null when there are no more results."
|
|
},
|
|
"limits": {
|
|
"$ref": "#/components/schemas/Limits"
|
|
}
|
|
}
|
|
},
|
|
"example": {
|
|
"data": [
|
|
{
|
|
"id": "audit_abc123",
|
|
"action": "workflow.execute",
|
|
"actorId": "user_abc123",
|
|
"actorName": "Jane Doe",
|
|
"actorEmail": "jane@example.com",
|
|
"resourceType": "workflow",
|
|
"createdAt": "2026-01-15T10:30:00Z"
|
|
}
|
|
],
|
|
"nextCursor": null
|
|
}
|
|
}
|
|
}
|
|
},
|
|
"400": {
|
|
"$ref": "#/components/responses/BadRequest"
|
|
},
|
|
"401": {
|
|
"$ref": "#/components/responses/Unauthorized"
|
|
},
|
|
"403": {
|
|
"$ref": "#/components/responses/Forbidden"
|
|
},
|
|
"429": {
|
|
"$ref": "#/components/responses/RateLimited"
|
|
}
|
|
}
|
|
}
|
|
},
|
|
"/api/v1/audit-logs/{id}": {
|
|
"get": {
|
|
"operationId": "getAuditLogDetails",
|
|
"summary": "Get Audit Log Details",
|
|
"description": "Retrieve a single audit log entry by ID. Requires an Enterprise subscription and organization admin or owner role.",
|
|
"tags": ["Audit Logs"],
|
|
"x-codeSamples": [
|
|
{
|
|
"id": "curl",
|
|
"label": "cURL",
|
|
"lang": "bash",
|
|
"source": "curl -X GET \\\n \"https://www.sim.ai/api/v1/audit-logs/{id}\" \\\n -H \"X-API-Key: YOUR_API_KEY\""
|
|
}
|
|
],
|
|
"parameters": [
|
|
{
|
|
"name": "id",
|
|
"in": "path",
|
|
"required": true,
|
|
"description": "The unique audit log entry identifier.",
|
|
"schema": {
|
|
"type": "string",
|
|
"example": "audit_2c3d4e5f6g"
|
|
}
|
|
}
|
|
],
|
|
"responses": {
|
|
"200": {
|
|
"description": "The audit log entry.",
|
|
"content": {
|
|
"application/json": {
|
|
"schema": {
|
|
"type": "object",
|
|
"properties": {
|
|
"data": {
|
|
"description": "The audit log entry.",
|
|
"$ref": "#/components/schemas/AuditLogEntry"
|
|
},
|
|
"limits": {
|
|
"$ref": "#/components/schemas/Limits"
|
|
}
|
|
}
|
|
},
|
|
"example": {
|
|
"data": {
|
|
"id": "audit_abc123",
|
|
"action": "workflow.execute",
|
|
"actorId": "user_abc123",
|
|
"actorName": "Jane Doe",
|
|
"actorEmail": "jane@example.com",
|
|
"resourceType": "workflow",
|
|
"resourceId": "wf_abc123",
|
|
"metadata": {},
|
|
"createdAt": "2026-01-15T10:30:00Z"
|
|
}
|
|
}
|
|
}
|
|
}
|
|
},
|
|
"401": {
|
|
"$ref": "#/components/responses/Unauthorized"
|
|
},
|
|
"403": {
|
|
"$ref": "#/components/responses/Forbidden"
|
|
},
|
|
"404": {
|
|
"$ref": "#/components/responses/NotFound"
|
|
},
|
|
"429": {
|
|
"$ref": "#/components/responses/RateLimited"
|
|
}
|
|
}
|
|
}
|
|
},
|
|
"/api/users/me/usage-limits": {
|
|
"get": {
|
|
"operationId": "getUsageLimits",
|
|
"summary": "Get Usage Limits",
|
|
"description": "Retrieve your current rate limits, usage spending, and storage consumption for the billing period.",
|
|
"tags": ["Usage"],
|
|
"x-codeSamples": [
|
|
{
|
|
"id": "curl",
|
|
"label": "cURL",
|
|
"lang": "bash",
|
|
"source": "curl -X GET \\\n \"https://www.sim.ai/api/users/me/usage-limits\" \\\n -H \"X-API-Key: YOUR_API_KEY\""
|
|
}
|
|
],
|
|
"responses": {
|
|
"200": {
|
|
"description": "Current rate limits, usage, and storage information.",
|
|
"content": {
|
|
"application/json": {
|
|
"schema": {
|
|
"$ref": "#/components/schemas/UsageLimits"
|
|
},
|
|
"example": {
|
|
"success": true,
|
|
"rateLimit": {
|
|
"sync": {
|
|
"limit": 100,
|
|
"remaining": 95,
|
|
"reset": "2026-01-15T11:00:00Z"
|
|
},
|
|
"async": {
|
|
"limit": 50,
|
|
"remaining": 48,
|
|
"reset": "2026-01-15T11:00:00Z"
|
|
}
|
|
},
|
|
"usage": {
|
|
"currentPeriodCost": 12.5,
|
|
"limit": 100.0,
|
|
"plan": "pro"
|
|
},
|
|
"storage": {
|
|
"usedBytes": 5242880,
|
|
"limitBytes": 1073741824,
|
|
"percentUsed": 0.49
|
|
}
|
|
}
|
|
}
|
|
}
|
|
},
|
|
"401": {
|
|
"$ref": "#/components/responses/Unauthorized"
|
|
}
|
|
},
|
|
"parameters": []
|
|
}
|
|
},
|
|
"/api/v1/tables": {
|
|
"get": {
|
|
"operationId": "listTables",
|
|
"summary": "List Tables",
|
|
"description": "List all tables in a workspace. Returns table metadata including name, schema, and row counts.",
|
|
"tags": ["Tables"],
|
|
"x-codeSamples": [
|
|
{
|
|
"id": "curl",
|
|
"label": "cURL",
|
|
"lang": "bash",
|
|
"source": "curl -X GET \\\n \"https://www.sim.ai/api/v1/tables?workspaceId=YOUR_WORKSPACE_ID\" \\\n -H \"X-API-Key: YOUR_API_KEY\""
|
|
}
|
|
],
|
|
"parameters": [
|
|
{
|
|
"$ref": "#/components/parameters/WorkspaceId"
|
|
}
|
|
],
|
|
"responses": {
|
|
"200": {
|
|
"description": "List of tables in the workspace.",
|
|
"content": {
|
|
"application/json": {
|
|
"schema": {
|
|
"type": "object",
|
|
"properties": {
|
|
"success": {
|
|
"type": "boolean",
|
|
"description": "Indicates whether the request was successful."
|
|
},
|
|
"data": {
|
|
"type": "object",
|
|
"properties": {
|
|
"tables": {
|
|
"type": "array",
|
|
"items": {
|
|
"$ref": "#/components/schemas/Table"
|
|
},
|
|
"description": "Array of tables in the workspace."
|
|
},
|
|
"totalCount": {
|
|
"type": "integer",
|
|
"description": "Total number of tables."
|
|
}
|
|
},
|
|
"description": "Response payload."
|
|
}
|
|
}
|
|
},
|
|
"example": {
|
|
"success": true,
|
|
"data": {
|
|
"tables": [
|
|
{
|
|
"id": "tbl_abc123",
|
|
"name": "contacts",
|
|
"description": "Customer contacts",
|
|
"schema": {
|
|
"columns": [
|
|
{
|
|
"name": "email",
|
|
"type": "string",
|
|
"required": true,
|
|
"unique": true
|
|
}
|
|
]
|
|
},
|
|
"rowCount": 150,
|
|
"maxRows": 10000,
|
|
"createdAt": "2026-01-15T10:30:00Z",
|
|
"updatedAt": "2026-01-15T10:30:00Z"
|
|
}
|
|
],
|
|
"totalCount": 1
|
|
}
|
|
}
|
|
}
|
|
}
|
|
},
|
|
"400": {
|
|
"$ref": "#/components/responses/BadRequest"
|
|
},
|
|
"401": {
|
|
"$ref": "#/components/responses/Unauthorized"
|
|
},
|
|
"403": {
|
|
"$ref": "#/components/responses/Forbidden"
|
|
},
|
|
"429": {
|
|
"$ref": "#/components/responses/RateLimited"
|
|
}
|
|
}
|
|
},
|
|
"post": {
|
|
"operationId": "createTable",
|
|
"summary": "Create Table",
|
|
"description": "Create a new table in a workspace. Define the table schema with typed columns, optional constraints (required, unique), and a name.",
|
|
"tags": ["Tables"],
|
|
"x-codeSamples": [
|
|
{
|
|
"id": "curl",
|
|
"label": "cURL",
|
|
"lang": "bash",
|
|
"source": "curl -X POST \\\n \"https://www.sim.ai/api/v1/tables\" \\\n -H \"X-API-Key: YOUR_API_KEY\" \\\n -H \"Content-Type: application/json\" \\\n -d '{\n \"workspaceId\": \"YOUR_WORKSPACE_ID\",\n \"name\": \"contacts\",\n \"description\": \"Customer contacts\",\n \"schema\": {\n \"columns\": [\n { \"name\": \"email\", \"type\": \"string\", \"required\": true, \"unique\": true },\n { \"name\": \"name\", \"type\": \"string\", \"required\": true },\n { \"name\": \"age\", \"type\": \"number\" }\n ]\n }\n }'"
|
|
}
|
|
],
|
|
"requestBody": {
|
|
"required": true,
|
|
"content": {
|
|
"application/json": {
|
|
"schema": {
|
|
"type": "object",
|
|
"required": ["workspaceId", "name", "schema"],
|
|
"properties": {
|
|
"workspaceId": {
|
|
"type": "string",
|
|
"description": "The workspace to create the table in."
|
|
},
|
|
"name": {
|
|
"type": "string",
|
|
"description": "Table name. Must start with a letter or underscore, alphanumeric and underscores only.",
|
|
"pattern": "^[a-zA-Z_][a-zA-Z0-9_]*$"
|
|
},
|
|
"description": {
|
|
"type": "string",
|
|
"description": "Optional description of the table."
|
|
},
|
|
"schema": {
|
|
"type": "object",
|
|
"required": ["columns"],
|
|
"properties": {
|
|
"columns": {
|
|
"type": "array",
|
|
"items": {
|
|
"$ref": "#/components/schemas/ColumnDefinition"
|
|
},
|
|
"minItems": 1,
|
|
"description": "Column definitions for the table."
|
|
}
|
|
},
|
|
"description": "Table schema definition containing column definitions."
|
|
}
|
|
}
|
|
},
|
|
"example": {
|
|
"workspaceId": "wsp_abc123",
|
|
"name": "contacts",
|
|
"description": "Customer contacts",
|
|
"schema": {
|
|
"columns": [
|
|
{
|
|
"name": "email",
|
|
"type": "string",
|
|
"required": true,
|
|
"unique": true
|
|
},
|
|
{
|
|
"name": "name",
|
|
"type": "string",
|
|
"required": true
|
|
},
|
|
{
|
|
"name": "age",
|
|
"type": "number"
|
|
}
|
|
]
|
|
}
|
|
}
|
|
}
|
|
}
|
|
},
|
|
"responses": {
|
|
"200": {
|
|
"description": "Table created successfully.",
|
|
"content": {
|
|
"application/json": {
|
|
"schema": {
|
|
"type": "object",
|
|
"properties": {
|
|
"success": {
|
|
"type": "boolean",
|
|
"description": "Indicates whether the request was successful."
|
|
},
|
|
"data": {
|
|
"type": "object",
|
|
"properties": {
|
|
"table": {
|
|
"$ref": "#/components/schemas/Table",
|
|
"description": "The newly created table."
|
|
},
|
|
"message": {
|
|
"type": "string",
|
|
"description": "Confirmation message."
|
|
}
|
|
},
|
|
"description": "Response payload."
|
|
}
|
|
}
|
|
},
|
|
"example": {
|
|
"success": true,
|
|
"data": {
|
|
"table": {
|
|
"id": "tbl_abc123",
|
|
"name": "contacts",
|
|
"description": "Customer contacts",
|
|
"schema": {
|
|
"columns": [
|
|
{
|
|
"name": "email",
|
|
"type": "string",
|
|
"required": true,
|
|
"unique": true
|
|
}
|
|
]
|
|
},
|
|
"rowCount": 0,
|
|
"maxRows": 10000,
|
|
"createdAt": "2026-01-15T10:30:00Z",
|
|
"updatedAt": "2026-01-15T10:30:00Z"
|
|
},
|
|
"message": "Table created successfully"
|
|
}
|
|
}
|
|
}
|
|
}
|
|
},
|
|
"400": {
|
|
"$ref": "#/components/responses/BadRequest"
|
|
},
|
|
"401": {
|
|
"$ref": "#/components/responses/Unauthorized"
|
|
},
|
|
"403": {
|
|
"$ref": "#/components/responses/Forbidden"
|
|
},
|
|
"429": {
|
|
"$ref": "#/components/responses/RateLimited"
|
|
}
|
|
},
|
|
"parameters": []
|
|
}
|
|
},
|
|
"/api/v1/tables/{tableId}": {
|
|
"get": {
|
|
"operationId": "getTable",
|
|
"summary": "Get Table",
|
|
"description": "Retrieve a table's metadata, schema, and row count.",
|
|
"tags": ["Tables"],
|
|
"x-codeSamples": [
|
|
{
|
|
"id": "curl",
|
|
"label": "cURL",
|
|
"lang": "bash",
|
|
"source": "curl -X GET \\\n \"https://www.sim.ai/api/v1/tables/{tableId}?workspaceId=YOUR_WORKSPACE_ID\" \\\n -H \"X-API-Key: YOUR_API_KEY\""
|
|
}
|
|
],
|
|
"parameters": [
|
|
{
|
|
"$ref": "#/components/parameters/TableId"
|
|
},
|
|
{
|
|
"$ref": "#/components/parameters/WorkspaceId"
|
|
}
|
|
],
|
|
"responses": {
|
|
"200": {
|
|
"description": "Table details.",
|
|
"content": {
|
|
"application/json": {
|
|
"schema": {
|
|
"type": "object",
|
|
"properties": {
|
|
"success": {
|
|
"type": "boolean",
|
|
"description": "Indicates whether the request was successful."
|
|
},
|
|
"data": {
|
|
"type": "object",
|
|
"properties": {
|
|
"table": {
|
|
"$ref": "#/components/schemas/Table",
|
|
"description": "The requested table with its metadata and schema."
|
|
}
|
|
},
|
|
"description": "Response payload."
|
|
}
|
|
}
|
|
},
|
|
"example": {
|
|
"success": true,
|
|
"data": {
|
|
"table": {
|
|
"id": "tbl_abc123",
|
|
"name": "contacts",
|
|
"description": "Customer contacts",
|
|
"schema": {
|
|
"columns": [
|
|
{
|
|
"name": "email",
|
|
"type": "string",
|
|
"required": true,
|
|
"unique": true
|
|
}
|
|
]
|
|
},
|
|
"rowCount": 150,
|
|
"maxRows": 10000,
|
|
"createdAt": "2026-01-15T10:30:00Z",
|
|
"updatedAt": "2026-01-15T10:30:00Z"
|
|
}
|
|
}
|
|
}
|
|
}
|
|
}
|
|
},
|
|
"400": {
|
|
"$ref": "#/components/responses/BadRequest"
|
|
},
|
|
"401": {
|
|
"$ref": "#/components/responses/Unauthorized"
|
|
},
|
|
"403": {
|
|
"$ref": "#/components/responses/Forbidden"
|
|
},
|
|
"404": {
|
|
"$ref": "#/components/responses/NotFound"
|
|
},
|
|
"429": {
|
|
"$ref": "#/components/responses/RateLimited"
|
|
}
|
|
}
|
|
},
|
|
"delete": {
|
|
"operationId": "deleteTable",
|
|
"summary": "Delete Table",
|
|
"description": "Delete a table and all its rows. This action is irreversible.",
|
|
"tags": ["Tables"],
|
|
"x-codeSamples": [
|
|
{
|
|
"id": "curl",
|
|
"label": "cURL",
|
|
"lang": "bash",
|
|
"source": "curl -X DELETE \\\n \"https://www.sim.ai/api/v1/tables/{tableId}?workspaceId=YOUR_WORKSPACE_ID\" \\\n -H \"X-API-Key: YOUR_API_KEY\""
|
|
}
|
|
],
|
|
"parameters": [
|
|
{
|
|
"$ref": "#/components/parameters/TableId"
|
|
},
|
|
{
|
|
"$ref": "#/components/parameters/WorkspaceId"
|
|
}
|
|
],
|
|
"responses": {
|
|
"200": {
|
|
"description": "Table deleted successfully.",
|
|
"content": {
|
|
"application/json": {
|
|
"schema": {
|
|
"type": "object",
|
|
"properties": {
|
|
"success": {
|
|
"type": "boolean",
|
|
"description": "Indicates whether the request was successful."
|
|
},
|
|
"data": {
|
|
"type": "object",
|
|
"properties": {
|
|
"message": {
|
|
"type": "string",
|
|
"description": "Confirmation message."
|
|
}
|
|
},
|
|
"description": "Response payload."
|
|
}
|
|
}
|
|
},
|
|
"example": {
|
|
"success": true,
|
|
"data": {
|
|
"message": "Table deleted successfully"
|
|
}
|
|
}
|
|
}
|
|
}
|
|
},
|
|
"400": {
|
|
"$ref": "#/components/responses/BadRequest"
|
|
},
|
|
"401": {
|
|
"$ref": "#/components/responses/Unauthorized"
|
|
},
|
|
"403": {
|
|
"$ref": "#/components/responses/Forbidden"
|
|
},
|
|
"404": {
|
|
"$ref": "#/components/responses/NotFound"
|
|
},
|
|
"429": {
|
|
"$ref": "#/components/responses/RateLimited"
|
|
}
|
|
}
|
|
}
|
|
},
|
|
"/api/v1/tables/{tableId}/columns": {
|
|
"post": {
|
|
"operationId": "addColumn",
|
|
"summary": "Add Column",
|
|
"description": "Add a new column to the table schema. Optionally specify a position to insert the column at a specific index.",
|
|
"tags": ["Tables"],
|
|
"x-codeSamples": [
|
|
{
|
|
"lang": "curl",
|
|
"source": "curl -X POST \\\n \"https://www.sim.ai/api/v1/tables/{tableId}/columns\" \\\n -H \"X-API-Key: YOUR_API_KEY\" \\\n -H \"Content-Type: application/json\" \\\n -d '{\n \"workspaceId\": \"YOUR_WORKSPACE_ID\",\n \"column\": {\n \"name\": \"email\",\n \"type\": \"string\",\n \"required\": true,\n \"unique\": true\n }\n }'"
|
|
}
|
|
],
|
|
"parameters": [
|
|
{
|
|
"$ref": "#/components/parameters/TableId"
|
|
}
|
|
],
|
|
"requestBody": {
|
|
"required": true,
|
|
"content": {
|
|
"application/json": {
|
|
"schema": {
|
|
"type": "object",
|
|
"required": ["workspaceId", "column"],
|
|
"properties": {
|
|
"workspaceId": {
|
|
"type": "string",
|
|
"description": "The workspace ID"
|
|
},
|
|
"column": {
|
|
"type": "object",
|
|
"required": ["name", "type"],
|
|
"properties": {
|
|
"name": {
|
|
"type": "string",
|
|
"description": "Column name (alphanumeric and underscores, must start with letter or underscore)"
|
|
},
|
|
"type": {
|
|
"type": "string",
|
|
"enum": ["string", "number", "boolean", "date", "json"],
|
|
"description": "Column data type"
|
|
},
|
|
"required": {
|
|
"type": "boolean",
|
|
"description": "Whether the column requires a value"
|
|
},
|
|
"unique": {
|
|
"type": "boolean",
|
|
"description": "Whether column values must be unique"
|
|
},
|
|
"position": {
|
|
"type": "integer",
|
|
"minimum": 0,
|
|
"description": "Position index to insert the column at (0-based). Appends if omitted."
|
|
}
|
|
}
|
|
}
|
|
}
|
|
},
|
|
"example": {
|
|
"workspaceId": "wsp_abc123",
|
|
"column": {
|
|
"name": "phone",
|
|
"type": "string",
|
|
"required": false,
|
|
"unique": false
|
|
}
|
|
}
|
|
}
|
|
}
|
|
},
|
|
"responses": {
|
|
"200": {
|
|
"description": "Column added successfully",
|
|
"content": {
|
|
"application/json": {
|
|
"schema": {
|
|
"type": "object",
|
|
"properties": {
|
|
"success": {
|
|
"type": "boolean"
|
|
},
|
|
"data": {
|
|
"type": "object",
|
|
"properties": {
|
|
"columns": {
|
|
"type": "array",
|
|
"items": {
|
|
"$ref": "#/components/schemas/ColumnDefinition"
|
|
}
|
|
}
|
|
}
|
|
}
|
|
}
|
|
},
|
|
"example": {
|
|
"success": true,
|
|
"data": {
|
|
"columns": [
|
|
{
|
|
"name": "email",
|
|
"type": "string",
|
|
"required": true,
|
|
"unique": true
|
|
},
|
|
{
|
|
"name": "phone",
|
|
"type": "string",
|
|
"required": false,
|
|
"unique": false
|
|
}
|
|
]
|
|
}
|
|
}
|
|
}
|
|
}
|
|
},
|
|
"400": {
|
|
"$ref": "#/components/responses/BadRequest"
|
|
},
|
|
"401": {
|
|
"$ref": "#/components/responses/Unauthorized"
|
|
},
|
|
"404": {
|
|
"$ref": "#/components/responses/NotFound"
|
|
},
|
|
"429": {
|
|
"$ref": "#/components/responses/RateLimited"
|
|
}
|
|
}
|
|
},
|
|
"patch": {
|
|
"operationId": "updateColumn",
|
|
"summary": "Update Column",
|
|
"description": "Update a column's name, type, or constraints. Multiple updates can be applied in a single request. When renaming, subsequent updates (type, constraints) use the new name.",
|
|
"tags": ["Tables"],
|
|
"x-codeSamples": [
|
|
{
|
|
"lang": "curl",
|
|
"source": "curl -X PATCH \\\n \"https://www.sim.ai/api/v1/tables/{tableId}/columns\" \\\n -H \"X-API-Key: YOUR_API_KEY\" \\\n -H \"Content-Type: application/json\" \\\n -d '{\n \"workspaceId\": \"YOUR_WORKSPACE_ID\",\n \"columnName\": \"old_name\",\n \"updates\": {\n \"name\": \"new_name\",\n \"type\": \"number\"\n }\n }'"
|
|
}
|
|
],
|
|
"parameters": [
|
|
{
|
|
"$ref": "#/components/parameters/TableId"
|
|
}
|
|
],
|
|
"requestBody": {
|
|
"required": true,
|
|
"content": {
|
|
"application/json": {
|
|
"schema": {
|
|
"type": "object",
|
|
"required": ["workspaceId", "columnName", "updates"],
|
|
"properties": {
|
|
"workspaceId": {
|
|
"type": "string",
|
|
"description": "The workspace ID"
|
|
},
|
|
"columnName": {
|
|
"type": "string",
|
|
"description": "Current name of the column to update"
|
|
},
|
|
"updates": {
|
|
"type": "object",
|
|
"properties": {
|
|
"name": {
|
|
"type": "string",
|
|
"description": "New column name"
|
|
},
|
|
"type": {
|
|
"type": "string",
|
|
"enum": ["string", "number", "boolean", "date", "json"],
|
|
"description": "New column data type"
|
|
},
|
|
"required": {
|
|
"type": "boolean",
|
|
"description": "Whether the column requires a value"
|
|
},
|
|
"unique": {
|
|
"type": "boolean",
|
|
"description": "Whether column values must be unique"
|
|
}
|
|
}
|
|
}
|
|
}
|
|
},
|
|
"example": {
|
|
"workspaceId": "wsp_abc123",
|
|
"columnName": "phone",
|
|
"updates": {
|
|
"name": "phone_number",
|
|
"type": "string",
|
|
"required": true
|
|
}
|
|
}
|
|
}
|
|
}
|
|
},
|
|
"responses": {
|
|
"200": {
|
|
"description": "Column updated successfully",
|
|
"content": {
|
|
"application/json": {
|
|
"schema": {
|
|
"type": "object",
|
|
"properties": {
|
|
"success": {
|
|
"type": "boolean"
|
|
},
|
|
"data": {
|
|
"type": "object",
|
|
"properties": {
|
|
"columns": {
|
|
"type": "array",
|
|
"items": {
|
|
"$ref": "#/components/schemas/ColumnDefinition"
|
|
}
|
|
}
|
|
}
|
|
}
|
|
}
|
|
},
|
|
"example": {
|
|
"success": true,
|
|
"data": {
|
|
"columns": [
|
|
{
|
|
"name": "email",
|
|
"type": "string",
|
|
"required": true,
|
|
"unique": true
|
|
},
|
|
{
|
|
"name": "phone_number",
|
|
"type": "string",
|
|
"required": true,
|
|
"unique": false
|
|
}
|
|
]
|
|
}
|
|
}
|
|
}
|
|
}
|
|
},
|
|
"400": {
|
|
"$ref": "#/components/responses/BadRequest"
|
|
},
|
|
"401": {
|
|
"$ref": "#/components/responses/Unauthorized"
|
|
},
|
|
"404": {
|
|
"$ref": "#/components/responses/NotFound"
|
|
},
|
|
"429": {
|
|
"$ref": "#/components/responses/RateLimited"
|
|
}
|
|
}
|
|
},
|
|
"delete": {
|
|
"operationId": "deleteColumn",
|
|
"summary": "Delete Column",
|
|
"description": "Delete a column from the table schema. This removes the column definition and strips the corresponding key from all existing row data. Cannot delete the last remaining column.",
|
|
"tags": ["Tables"],
|
|
"x-codeSamples": [
|
|
{
|
|
"lang": "curl",
|
|
"source": "curl -X DELETE \\\n \"https://www.sim.ai/api/v1/tables/{tableId}/columns\" \\\n -H \"X-API-Key: YOUR_API_KEY\" \\\n -H \"Content-Type: application/json\" \\\n -d '{\n \"workspaceId\": \"YOUR_WORKSPACE_ID\",\n \"columnName\": \"old_column\"\n }'"
|
|
}
|
|
],
|
|
"parameters": [
|
|
{
|
|
"$ref": "#/components/parameters/TableId"
|
|
}
|
|
],
|
|
"requestBody": {
|
|
"required": true,
|
|
"content": {
|
|
"application/json": {
|
|
"schema": {
|
|
"type": "object",
|
|
"required": ["workspaceId", "columnName"],
|
|
"properties": {
|
|
"workspaceId": {
|
|
"type": "string",
|
|
"description": "The workspace ID"
|
|
},
|
|
"columnName": {
|
|
"type": "string",
|
|
"description": "Name of the column to delete"
|
|
}
|
|
}
|
|
},
|
|
"example": {
|
|
"workspaceId": "wsp_abc123",
|
|
"columnName": "phone_number"
|
|
}
|
|
}
|
|
}
|
|
},
|
|
"responses": {
|
|
"200": {
|
|
"description": "Column deleted successfully",
|
|
"content": {
|
|
"application/json": {
|
|
"schema": {
|
|
"type": "object",
|
|
"properties": {
|
|
"success": {
|
|
"type": "boolean"
|
|
},
|
|
"data": {
|
|
"type": "object",
|
|
"properties": {
|
|
"columns": {
|
|
"type": "array",
|
|
"items": {
|
|
"$ref": "#/components/schemas/ColumnDefinition"
|
|
}
|
|
}
|
|
}
|
|
}
|
|
}
|
|
},
|
|
"example": {
|
|
"success": true,
|
|
"data": {
|
|
"columns": [
|
|
{
|
|
"name": "email",
|
|
"type": "string",
|
|
"required": true,
|
|
"unique": true
|
|
}
|
|
]
|
|
}
|
|
}
|
|
}
|
|
}
|
|
},
|
|
"400": {
|
|
"$ref": "#/components/responses/BadRequest"
|
|
},
|
|
"401": {
|
|
"$ref": "#/components/responses/Unauthorized"
|
|
},
|
|
"404": {
|
|
"$ref": "#/components/responses/NotFound"
|
|
},
|
|
"429": {
|
|
"$ref": "#/components/responses/RateLimited"
|
|
}
|
|
}
|
|
}
|
|
},
|
|
"/api/v1/tables/{tableId}/rows": {
|
|
"get": {
|
|
"operationId": "listRows",
|
|
"summary": "List Rows",
|
|
"description": "Query rows from a table with optional filtering, sorting, and pagination. Filters and sorts are passed as JSON-encoded query parameters.",
|
|
"tags": ["Tables"],
|
|
"x-codeSamples": [
|
|
{
|
|
"id": "curl",
|
|
"label": "cURL",
|
|
"lang": "bash",
|
|
"source": "curl -X GET \\\n \"https://www.sim.ai/api/v1/tables/{tableId}/rows?workspaceId=YOUR_WORKSPACE_ID&limit=50&offset=0\" \\\n -H \"X-API-Key: YOUR_API_KEY\""
|
|
}
|
|
],
|
|
"parameters": [
|
|
{
|
|
"$ref": "#/components/parameters/TableId"
|
|
},
|
|
{
|
|
"$ref": "#/components/parameters/WorkspaceId"
|
|
},
|
|
{
|
|
"name": "filter",
|
|
"in": "query",
|
|
"required": false,
|
|
"description": "JSON-encoded filter object. Example: {\"status\": \"active\"} or {\"age\": {\"$gt\": 18}}.",
|
|
"schema": {
|
|
"type": "string"
|
|
}
|
|
},
|
|
{
|
|
"name": "sort",
|
|
"in": "query",
|
|
"required": false,
|
|
"description": "JSON-encoded sort object. Example: {\"created_at\": \"desc\"}.",
|
|
"schema": {
|
|
"type": "string"
|
|
}
|
|
},
|
|
{
|
|
"name": "limit",
|
|
"in": "query",
|
|
"required": false,
|
|
"description": "Maximum rows to return (1-1000, default 100).",
|
|
"schema": {
|
|
"type": "integer",
|
|
"default": 100,
|
|
"minimum": 1,
|
|
"maximum": 1000
|
|
}
|
|
},
|
|
{
|
|
"name": "offset",
|
|
"in": "query",
|
|
"required": false,
|
|
"description": "Number of rows to skip for pagination (default 0).",
|
|
"schema": {
|
|
"type": "integer",
|
|
"default": 0,
|
|
"minimum": 0
|
|
}
|
|
}
|
|
],
|
|
"responses": {
|
|
"200": {
|
|
"description": "Rows matching the query.",
|
|
"content": {
|
|
"application/json": {
|
|
"schema": {
|
|
"type": "object",
|
|
"properties": {
|
|
"success": {
|
|
"type": "boolean",
|
|
"description": "Indicates whether the request was successful."
|
|
},
|
|
"data": {
|
|
"type": "object",
|
|
"properties": {
|
|
"rows": {
|
|
"type": "array",
|
|
"items": {
|
|
"$ref": "#/components/schemas/TableRow"
|
|
},
|
|
"description": "Array of rows matching the query."
|
|
},
|
|
"rowCount": {
|
|
"type": "integer",
|
|
"description": "Number of rows returned in this response."
|
|
},
|
|
"totalCount": {
|
|
"type": "integer",
|
|
"description": "Total rows matching the filter."
|
|
},
|
|
"limit": {
|
|
"type": "integer",
|
|
"description": "The limit that was applied to the query."
|
|
},
|
|
"offset": {
|
|
"type": "integer",
|
|
"description": "The offset that was applied to the query."
|
|
}
|
|
},
|
|
"description": "Response payload."
|
|
}
|
|
}
|
|
},
|
|
"example": {
|
|
"success": true,
|
|
"data": {
|
|
"rows": [
|
|
{
|
|
"id": "row_abc123",
|
|
"data": {
|
|
"email": "jane@example.com",
|
|
"name": "Jane Doe"
|
|
},
|
|
"position": 0,
|
|
"createdAt": "2026-01-15T10:30:00Z",
|
|
"updatedAt": "2026-01-15T10:30:00Z"
|
|
}
|
|
],
|
|
"rowCount": 1,
|
|
"totalCount": 1,
|
|
"limit": 100,
|
|
"offset": 0
|
|
}
|
|
}
|
|
}
|
|
}
|
|
},
|
|
"400": {
|
|
"$ref": "#/components/responses/BadRequest"
|
|
},
|
|
"401": {
|
|
"$ref": "#/components/responses/Unauthorized"
|
|
},
|
|
"403": {
|
|
"$ref": "#/components/responses/Forbidden"
|
|
},
|
|
"404": {
|
|
"$ref": "#/components/responses/NotFound"
|
|
},
|
|
"429": {
|
|
"$ref": "#/components/responses/RateLimited"
|
|
}
|
|
}
|
|
},
|
|
"post": {
|
|
"operationId": "insertRows",
|
|
"summary": "Insert Rows",
|
|
"description": "Insert one or more rows into a table. For a single row, pass a `data` object. For batch insert, pass a `rows` array (up to 1000 rows).",
|
|
"tags": ["Tables"],
|
|
"x-codeSamples": [
|
|
{
|
|
"id": "curl",
|
|
"label": "cURL",
|
|
"lang": "bash",
|
|
"source": "curl -X POST \\\n \"https://www.sim.ai/api/v1/tables/{tableId}/rows\" \\\n -H \"X-API-Key: YOUR_API_KEY\" \\\n -H \"Content-Type: application/json\" \\\n -d '{\n \"workspaceId\": \"YOUR_WORKSPACE_ID\",\n \"data\": {\n \"email\": \"user@example.com\",\n \"name\": \"Jane Doe\"\n }\n }'"
|
|
}
|
|
],
|
|
"parameters": [
|
|
{
|
|
"$ref": "#/components/parameters/TableId"
|
|
}
|
|
],
|
|
"requestBody": {
|
|
"required": true,
|
|
"content": {
|
|
"application/json": {
|
|
"schema": {
|
|
"oneOf": [
|
|
{
|
|
"type": "object",
|
|
"required": ["workspaceId", "data"],
|
|
"description": "Single row insert.",
|
|
"properties": {
|
|
"workspaceId": {
|
|
"type": "string",
|
|
"description": "The workspace that owns the table."
|
|
},
|
|
"data": {
|
|
"type": "object",
|
|
"additionalProperties": true,
|
|
"description": "Key-value pairs matching the table schema."
|
|
},
|
|
"position": {
|
|
"type": "integer",
|
|
"minimum": 0,
|
|
"description": "Position index for the row. If omitted, the row is appended at the end of the table."
|
|
}
|
|
}
|
|
},
|
|
{
|
|
"type": "object",
|
|
"required": ["workspaceId", "rows"],
|
|
"description": "Batch insert (up to 1000 rows).",
|
|
"properties": {
|
|
"workspaceId": {
|
|
"type": "string",
|
|
"description": "The workspace that owns the table."
|
|
},
|
|
"rows": {
|
|
"type": "array",
|
|
"items": {
|
|
"type": "object",
|
|
"additionalProperties": true
|
|
},
|
|
"minItems": 1,
|
|
"maxItems": 1000,
|
|
"description": "Array of row objects to insert. Each object contains key-value pairs matching the table schema."
|
|
},
|
|
"positions": {
|
|
"type": "array",
|
|
"items": {
|
|
"type": "integer",
|
|
"minimum": 0
|
|
},
|
|
"uniqueItems": true,
|
|
"maxItems": 1000,
|
|
"description": "Array of position indices for each row. Must be the same length as the rows array and must not contain duplicates. If omitted, rows are appended in order."
|
|
}
|
|
}
|
|
}
|
|
]
|
|
},
|
|
"example": {
|
|
"workspaceId": "wsp_abc123",
|
|
"data": {
|
|
"email": "jane@example.com",
|
|
"name": "Jane Doe",
|
|
"age": 30
|
|
}
|
|
}
|
|
}
|
|
}
|
|
},
|
|
"responses": {
|
|
"200": {
|
|
"description": "Row(s) inserted successfully.",
|
|
"content": {
|
|
"application/json": {
|
|
"schema": {
|
|
"type": "object",
|
|
"properties": {
|
|
"success": {
|
|
"type": "boolean",
|
|
"description": "Indicates whether the request was successful."
|
|
},
|
|
"data": {
|
|
"type": "object",
|
|
"properties": {
|
|
"row": {
|
|
"$ref": "#/components/schemas/TableRow",
|
|
"description": "The inserted row (present for single-row inserts)."
|
|
},
|
|
"rows": {
|
|
"type": "array",
|
|
"items": {
|
|
"$ref": "#/components/schemas/TableRow"
|
|
},
|
|
"description": "Array of inserted rows (present for batch inserts)."
|
|
},
|
|
"insertedCount": {
|
|
"type": "integer",
|
|
"description": "Number of rows successfully inserted."
|
|
},
|
|
"message": {
|
|
"type": "string",
|
|
"description": "Confirmation message."
|
|
}
|
|
},
|
|
"description": "Response payload."
|
|
}
|
|
}
|
|
},
|
|
"example": {
|
|
"success": true,
|
|
"data": {
|
|
"row": {
|
|
"id": "row_abc123",
|
|
"data": {
|
|
"email": "jane@example.com",
|
|
"name": "Jane Doe",
|
|
"age": 30
|
|
},
|
|
"position": 0,
|
|
"createdAt": "2026-01-15T10:30:00Z",
|
|
"updatedAt": "2026-01-15T10:30:00Z"
|
|
},
|
|
"message": "Row inserted successfully"
|
|
}
|
|
}
|
|
}
|
|
}
|
|
},
|
|
"400": {
|
|
"$ref": "#/components/responses/BadRequest"
|
|
},
|
|
"401": {
|
|
"$ref": "#/components/responses/Unauthorized"
|
|
},
|
|
"403": {
|
|
"$ref": "#/components/responses/Forbidden"
|
|
},
|
|
"404": {
|
|
"$ref": "#/components/responses/NotFound"
|
|
},
|
|
"429": {
|
|
"$ref": "#/components/responses/RateLimited"
|
|
}
|
|
}
|
|
},
|
|
"put": {
|
|
"operationId": "updateRows",
|
|
"summary": "Update Rows",
|
|
"description": "Bulk update rows matching a filter. All matching rows will have the specified fields updated. Validates against schema and unique constraints.",
|
|
"tags": ["Tables"],
|
|
"x-codeSamples": [
|
|
{
|
|
"id": "curl",
|
|
"label": "cURL",
|
|
"lang": "bash",
|
|
"source": "curl -X PUT \\\n \"https://www.sim.ai/api/v1/tables/{tableId}/rows\" \\\n -H \"X-API-Key: YOUR_API_KEY\" \\\n -H \"Content-Type: application/json\" \\\n -d '{\n \"workspaceId\": \"YOUR_WORKSPACE_ID\",\n \"filter\": { \"status\": \"pending\" },\n \"data\": { \"status\": \"active\" }\n }'"
|
|
}
|
|
],
|
|
"parameters": [
|
|
{
|
|
"$ref": "#/components/parameters/TableId"
|
|
}
|
|
],
|
|
"requestBody": {
|
|
"required": true,
|
|
"content": {
|
|
"application/json": {
|
|
"schema": {
|
|
"type": "object",
|
|
"required": ["workspaceId", "filter", "data"],
|
|
"properties": {
|
|
"workspaceId": {
|
|
"type": "string",
|
|
"description": "The workspace that owns the table."
|
|
},
|
|
"filter": {
|
|
"type": "object",
|
|
"additionalProperties": true,
|
|
"description": "Filter criteria to match rows."
|
|
},
|
|
"data": {
|
|
"type": "object",
|
|
"additionalProperties": true,
|
|
"description": "Fields to update on matching rows."
|
|
},
|
|
"limit": {
|
|
"type": "integer",
|
|
"minimum": 1,
|
|
"maximum": 1000,
|
|
"description": "Maximum number of rows to update."
|
|
}
|
|
}
|
|
},
|
|
"example": {
|
|
"workspaceId": "wsp_abc123",
|
|
"filter": {
|
|
"status": "pending"
|
|
},
|
|
"data": {
|
|
"status": "active"
|
|
}
|
|
}
|
|
}
|
|
}
|
|
},
|
|
"responses": {
|
|
"200": {
|
|
"$ref": "#/components/responses/RowsUpdated"
|
|
},
|
|
"400": {
|
|
"$ref": "#/components/responses/BadRequest"
|
|
},
|
|
"401": {
|
|
"$ref": "#/components/responses/Unauthorized"
|
|
},
|
|
"403": {
|
|
"$ref": "#/components/responses/Forbidden"
|
|
},
|
|
"404": {
|
|
"$ref": "#/components/responses/NotFound"
|
|
},
|
|
"429": {
|
|
"$ref": "#/components/responses/RateLimited"
|
|
}
|
|
}
|
|
},
|
|
"delete": {
|
|
"operationId": "deleteRows",
|
|
"summary": "Delete Rows",
|
|
"description": "Delete rows by filter criteria or by an explicit list of row IDs. Pass either a `filter` object or a `rowIds` array.",
|
|
"tags": ["Tables"],
|
|
"x-codeSamples": [
|
|
{
|
|
"id": "curl",
|
|
"label": "cURL",
|
|
"lang": "bash",
|
|
"source": "curl -X DELETE \\\n \"https://www.sim.ai/api/v1/tables/{tableId}/rows\" \\\n -H \"X-API-Key: YOUR_API_KEY\" \\\n -H \"Content-Type: application/json\" \\\n -d '{\n \"workspaceId\": \"YOUR_WORKSPACE_ID\",\n \"rowIds\": [\"row_abc123\", \"row_def456\"]\n }'"
|
|
}
|
|
],
|
|
"parameters": [
|
|
{
|
|
"$ref": "#/components/parameters/TableId"
|
|
}
|
|
],
|
|
"requestBody": {
|
|
"required": true,
|
|
"content": {
|
|
"application/json": {
|
|
"schema": {
|
|
"oneOf": [
|
|
{
|
|
"type": "object",
|
|
"required": ["workspaceId", "filter"],
|
|
"description": "Delete by filter.",
|
|
"properties": {
|
|
"workspaceId": {
|
|
"type": "string",
|
|
"description": "The workspace that owns the table."
|
|
},
|
|
"filter": {
|
|
"type": "object",
|
|
"additionalProperties": true,
|
|
"description": "Filter criteria to match rows for deletion."
|
|
},
|
|
"limit": {
|
|
"type": "integer",
|
|
"minimum": 1,
|
|
"maximum": 1000,
|
|
"description": "Maximum number of rows to delete. Defaults to all matching rows, capped at 1000."
|
|
}
|
|
}
|
|
},
|
|
{
|
|
"type": "object",
|
|
"required": ["workspaceId", "rowIds"],
|
|
"description": "Delete by IDs.",
|
|
"properties": {
|
|
"workspaceId": {
|
|
"type": "string",
|
|
"description": "The workspace that owns the table."
|
|
},
|
|
"rowIds": {
|
|
"type": "array",
|
|
"items": {
|
|
"type": "string"
|
|
},
|
|
"maxItems": 1000,
|
|
"description": "Explicit list of row IDs to delete (max 1000)."
|
|
}
|
|
}
|
|
}
|
|
]
|
|
},
|
|
"example": {
|
|
"workspaceId": "wsp_abc123",
|
|
"rowIds": ["row_abc123", "row_def456"]
|
|
}
|
|
}
|
|
}
|
|
},
|
|
"responses": {
|
|
"200": {
|
|
"description": "Rows deleted.",
|
|
"content": {
|
|
"application/json": {
|
|
"schema": {
|
|
"type": "object",
|
|
"properties": {
|
|
"success": {
|
|
"type": "boolean",
|
|
"description": "Indicates whether the request was successful."
|
|
},
|
|
"data": {
|
|
"type": "object",
|
|
"properties": {
|
|
"message": {
|
|
"type": "string",
|
|
"description": "Confirmation message describing how many rows were deleted."
|
|
},
|
|
"deletedCount": {
|
|
"type": "integer",
|
|
"description": "Number of rows that were deleted."
|
|
},
|
|
"deletedRowIds": {
|
|
"type": "array",
|
|
"items": {
|
|
"type": "string"
|
|
},
|
|
"description": "Array of IDs for each row that was deleted."
|
|
},
|
|
"requestedCount": {
|
|
"type": "integer",
|
|
"description": "Number of row IDs requested for deletion (only present when deleting by IDs)."
|
|
},
|
|
"missingRowIds": {
|
|
"type": "array",
|
|
"items": {
|
|
"type": "string"
|
|
},
|
|
"description": "Row IDs that were requested but not found (only present when deleting by IDs)."
|
|
}
|
|
},
|
|
"description": "Response payload."
|
|
}
|
|
}
|
|
},
|
|
"example": {
|
|
"success": true,
|
|
"data": {
|
|
"message": "Rows deleted successfully",
|
|
"deletedCount": 2,
|
|
"deletedRowIds": ["row_abc123", "row_def456"]
|
|
}
|
|
}
|
|
}
|
|
}
|
|
},
|
|
"400": {
|
|
"$ref": "#/components/responses/BadRequest"
|
|
},
|
|
"401": {
|
|
"$ref": "#/components/responses/Unauthorized"
|
|
},
|
|
"403": {
|
|
"$ref": "#/components/responses/Forbidden"
|
|
},
|
|
"404": {
|
|
"$ref": "#/components/responses/NotFound"
|
|
},
|
|
"429": {
|
|
"$ref": "#/components/responses/RateLimited"
|
|
}
|
|
}
|
|
},
|
|
"patch": {
|
|
"operationId": "batchUpdateRows",
|
|
"summary": "Batch Update Rows",
|
|
"description": "Update multiple specific rows by their IDs in a single request. Each entry in the `updates` array specifies a row ID and the fields to update. Validates against the table schema and unique constraints. Up to 1000 rows can be updated per request.",
|
|
"tags": ["Tables"],
|
|
"x-codeSamples": [
|
|
{
|
|
"id": "curl",
|
|
"label": "cURL",
|
|
"lang": "bash",
|
|
"source": "curl -X PATCH \\\n \"https://www.sim.ai/api/v1/tables/{tableId}/rows\" \\\n -H \"X-API-Key: YOUR_API_KEY\" \\\n -H \"Content-Type: application/json\" \\\n -d '{\n \"workspaceId\": \"YOUR_WORKSPACE_ID\",\n \"updates\": [\n { \"rowId\": \"row_abc123\", \"data\": { \"status\": \"active\" } },\n { \"rowId\": \"row_def456\", \"data\": { \"status\": \"archived\" } }\n ]\n }'"
|
|
}
|
|
],
|
|
"parameters": [
|
|
{
|
|
"$ref": "#/components/parameters/TableId"
|
|
}
|
|
],
|
|
"requestBody": {
|
|
"required": true,
|
|
"content": {
|
|
"application/json": {
|
|
"schema": {
|
|
"type": "object",
|
|
"required": ["workspaceId", "updates"],
|
|
"properties": {
|
|
"workspaceId": {
|
|
"type": "string",
|
|
"description": "The workspace that owns the table."
|
|
},
|
|
"updates": {
|
|
"type": "array",
|
|
"items": {
|
|
"type": "object",
|
|
"required": ["rowId", "data"],
|
|
"properties": {
|
|
"rowId": {
|
|
"type": "string",
|
|
"description": "The ID of the row to update."
|
|
},
|
|
"data": {
|
|
"type": "object",
|
|
"additionalProperties": true,
|
|
"description": "Key-value pairs of fields to update on this row."
|
|
}
|
|
}
|
|
},
|
|
"minItems": 1,
|
|
"maxItems": 1000,
|
|
"description": "Array of update objects. Each object specifies a row ID and the fields to update. Duplicate row IDs are not allowed."
|
|
}
|
|
}
|
|
},
|
|
"example": {
|
|
"workspaceId": "wsp_abc123",
|
|
"updates": [
|
|
{
|
|
"rowId": "row_abc123",
|
|
"data": {
|
|
"status": "active"
|
|
}
|
|
},
|
|
{
|
|
"rowId": "row_def456",
|
|
"data": {
|
|
"status": "archived"
|
|
}
|
|
}
|
|
]
|
|
}
|
|
}
|
|
}
|
|
},
|
|
"responses": {
|
|
"200": {
|
|
"$ref": "#/components/responses/RowsUpdated"
|
|
},
|
|
"400": {
|
|
"$ref": "#/components/responses/BadRequest"
|
|
},
|
|
"401": {
|
|
"$ref": "#/components/responses/Unauthorized"
|
|
},
|
|
"403": {
|
|
"$ref": "#/components/responses/Forbidden"
|
|
},
|
|
"404": {
|
|
"$ref": "#/components/responses/NotFound"
|
|
},
|
|
"429": {
|
|
"$ref": "#/components/responses/RateLimited"
|
|
}
|
|
}
|
|
}
|
|
},
|
|
"/api/v1/tables/{tableId}/rows/{rowId}": {
|
|
"get": {
|
|
"operationId": "getRow",
|
|
"summary": "Get Row",
|
|
"description": "Retrieve a single row by its ID.",
|
|
"tags": ["Tables"],
|
|
"x-codeSamples": [
|
|
{
|
|
"id": "curl",
|
|
"label": "cURL",
|
|
"lang": "bash",
|
|
"source": "curl -X GET \\\n \"https://www.sim.ai/api/v1/tables/{tableId}/rows/{rowId}?workspaceId=YOUR_WORKSPACE_ID\" \\\n -H \"X-API-Key: YOUR_API_KEY\""
|
|
}
|
|
],
|
|
"parameters": [
|
|
{
|
|
"$ref": "#/components/parameters/TableId"
|
|
},
|
|
{
|
|
"$ref": "#/components/parameters/RowId"
|
|
},
|
|
{
|
|
"$ref": "#/components/parameters/WorkspaceId"
|
|
}
|
|
],
|
|
"responses": {
|
|
"200": {
|
|
"description": "Row data.",
|
|
"content": {
|
|
"application/json": {
|
|
"schema": {
|
|
"type": "object",
|
|
"properties": {
|
|
"success": {
|
|
"type": "boolean",
|
|
"description": "Indicates whether the request was successful."
|
|
},
|
|
"data": {
|
|
"type": "object",
|
|
"properties": {
|
|
"row": {
|
|
"$ref": "#/components/schemas/TableRow",
|
|
"description": "The requested row."
|
|
}
|
|
},
|
|
"description": "Response payload."
|
|
}
|
|
}
|
|
},
|
|
"example": {
|
|
"success": true,
|
|
"data": {
|
|
"row": {
|
|
"id": "row_abc123",
|
|
"data": {
|
|
"email": "jane@example.com",
|
|
"name": "Jane Doe"
|
|
},
|
|
"position": 0,
|
|
"createdAt": "2026-01-15T10:30:00Z",
|
|
"updatedAt": "2026-01-15T10:30:00Z"
|
|
}
|
|
}
|
|
}
|
|
}
|
|
}
|
|
},
|
|
"400": {
|
|
"$ref": "#/components/responses/BadRequest"
|
|
},
|
|
"401": {
|
|
"$ref": "#/components/responses/Unauthorized"
|
|
},
|
|
"403": {
|
|
"$ref": "#/components/responses/Forbidden"
|
|
},
|
|
"404": {
|
|
"$ref": "#/components/responses/NotFound"
|
|
},
|
|
"429": {
|
|
"$ref": "#/components/responses/RateLimited"
|
|
}
|
|
}
|
|
},
|
|
"patch": {
|
|
"operationId": "updateRow",
|
|
"summary": "Update Row",
|
|
"description": "Partially update a single row. Only the provided fields are updated; existing fields are preserved. Data is validated against the table schema.",
|
|
"tags": ["Tables"],
|
|
"x-codeSamples": [
|
|
{
|
|
"id": "curl",
|
|
"label": "cURL",
|
|
"lang": "bash",
|
|
"source": "curl -X PATCH \\\n \"https://www.sim.ai/api/v1/tables/{tableId}/rows/{rowId}\" \\\n -H \"X-API-Key: YOUR_API_KEY\" \\\n -H \"Content-Type: application/json\" \\\n -d '{\n \"workspaceId\": \"YOUR_WORKSPACE_ID\",\n \"data\": { \"name\": \"Updated Name\" }\n }'"
|
|
}
|
|
],
|
|
"parameters": [
|
|
{
|
|
"$ref": "#/components/parameters/TableId"
|
|
},
|
|
{
|
|
"$ref": "#/components/parameters/RowId"
|
|
}
|
|
],
|
|
"requestBody": {
|
|
"required": true,
|
|
"content": {
|
|
"application/json": {
|
|
"schema": {
|
|
"type": "object",
|
|
"required": ["workspaceId", "data"],
|
|
"properties": {
|
|
"workspaceId": {
|
|
"type": "string",
|
|
"description": "The workspace that owns the table."
|
|
},
|
|
"data": {
|
|
"type": "object",
|
|
"additionalProperties": true,
|
|
"description": "Fields to update. Only specified fields are changed."
|
|
}
|
|
}
|
|
},
|
|
"example": {
|
|
"workspaceId": "wsp_abc123",
|
|
"data": {
|
|
"name": "Updated Name"
|
|
}
|
|
}
|
|
}
|
|
}
|
|
},
|
|
"responses": {
|
|
"200": {
|
|
"description": "Row updated.",
|
|
"content": {
|
|
"application/json": {
|
|
"schema": {
|
|
"type": "object",
|
|
"properties": {
|
|
"success": {
|
|
"type": "boolean",
|
|
"description": "Indicates whether the request was successful."
|
|
},
|
|
"data": {
|
|
"type": "object",
|
|
"properties": {
|
|
"row": {
|
|
"$ref": "#/components/schemas/TableRow",
|
|
"description": "The updated row with all current field values."
|
|
},
|
|
"message": {
|
|
"type": "string",
|
|
"description": "Confirmation message."
|
|
}
|
|
},
|
|
"description": "Response payload."
|
|
}
|
|
}
|
|
},
|
|
"example": {
|
|
"success": true,
|
|
"data": {
|
|
"row": {
|
|
"id": "row_abc123",
|
|
"data": {
|
|
"email": "jane@example.com",
|
|
"name": "Updated Name"
|
|
},
|
|
"position": 0,
|
|
"createdAt": "2026-01-15T10:30:00Z",
|
|
"updatedAt": "2026-01-16T08:00:00Z"
|
|
},
|
|
"message": "Row updated successfully"
|
|
}
|
|
}
|
|
}
|
|
}
|
|
},
|
|
"400": {
|
|
"$ref": "#/components/responses/BadRequest"
|
|
},
|
|
"401": {
|
|
"$ref": "#/components/responses/Unauthorized"
|
|
},
|
|
"403": {
|
|
"$ref": "#/components/responses/Forbidden"
|
|
},
|
|
"404": {
|
|
"$ref": "#/components/responses/NotFound"
|
|
},
|
|
"429": {
|
|
"$ref": "#/components/responses/RateLimited"
|
|
}
|
|
}
|
|
},
|
|
"delete": {
|
|
"operationId": "deleteRow",
|
|
"summary": "Delete Row",
|
|
"description": "Delete a single row by its ID.",
|
|
"tags": ["Tables"],
|
|
"x-codeSamples": [
|
|
{
|
|
"id": "curl",
|
|
"label": "cURL",
|
|
"lang": "bash",
|
|
"source": "curl -X DELETE \\\n \"https://www.sim.ai/api/v1/tables/{tableId}/rows/{rowId}\" \\\n -H \"X-API-Key: YOUR_API_KEY\" \\\n -H \"Content-Type: application/json\" \\\n -d '{\n \"workspaceId\": \"YOUR_WORKSPACE_ID\"\n }'"
|
|
}
|
|
],
|
|
"parameters": [
|
|
{
|
|
"$ref": "#/components/parameters/TableId"
|
|
},
|
|
{
|
|
"$ref": "#/components/parameters/RowId"
|
|
}
|
|
],
|
|
"responses": {
|
|
"200": {
|
|
"description": "Row deleted.",
|
|
"content": {
|
|
"application/json": {
|
|
"schema": {
|
|
"type": "object",
|
|
"properties": {
|
|
"success": {
|
|
"type": "boolean",
|
|
"description": "Indicates whether the request was successful."
|
|
},
|
|
"data": {
|
|
"type": "object",
|
|
"properties": {
|
|
"message": {
|
|
"type": "string",
|
|
"description": "Confirmation message."
|
|
},
|
|
"deletedCount": {
|
|
"type": "integer",
|
|
"description": "Number of rows deleted (always 1 for single-row deletion)."
|
|
}
|
|
},
|
|
"description": "Response payload."
|
|
}
|
|
}
|
|
},
|
|
"example": {
|
|
"success": true,
|
|
"data": {
|
|
"message": "Row deleted successfully",
|
|
"deletedCount": 1
|
|
}
|
|
}
|
|
}
|
|
}
|
|
},
|
|
"400": {
|
|
"$ref": "#/components/responses/BadRequest"
|
|
},
|
|
"401": {
|
|
"$ref": "#/components/responses/Unauthorized"
|
|
},
|
|
"403": {
|
|
"$ref": "#/components/responses/Forbidden"
|
|
},
|
|
"404": {
|
|
"$ref": "#/components/responses/NotFound"
|
|
},
|
|
"429": {
|
|
"$ref": "#/components/responses/RateLimited"
|
|
}
|
|
},
|
|
"requestBody": {
|
|
"required": true,
|
|
"content": {
|
|
"application/json": {
|
|
"schema": {
|
|
"type": "object",
|
|
"required": ["workspaceId"],
|
|
"properties": {
|
|
"workspaceId": {
|
|
"type": "string",
|
|
"description": "The workspace that owns the table."
|
|
}
|
|
}
|
|
},
|
|
"example": {
|
|
"workspaceId": "wsp_abc123"
|
|
}
|
|
}
|
|
}
|
|
}
|
|
}
|
|
},
|
|
"/api/v1/tables/{tableId}/rows/upsert": {
|
|
"post": {
|
|
"operationId": "upsertRow",
|
|
"summary": "Upsert Row",
|
|
"description": "Insert a new row or update an existing one based on a unique column value. The table must have at least one column with a unique constraint. If a row with a matching unique value exists, it is updated; otherwise, a new row is inserted. When multiple unique columns exist, specify `conflictTarget` to indicate which column to match on.",
|
|
"tags": ["Tables"],
|
|
"x-codeSamples": [
|
|
{
|
|
"id": "curl",
|
|
"label": "cURL",
|
|
"lang": "bash",
|
|
"source": "curl -X POST \\\n \"https://www.sim.ai/api/v1/tables/{tableId}/rows/upsert\" \\\n -H \"X-API-Key: YOUR_API_KEY\" \\\n -H \"Content-Type: application/json\" \\\n -d '{\n \"workspaceId\": \"YOUR_WORKSPACE_ID\",\n \"data\": { \"email\": \"user@example.com\", \"name\": \"John\" }\n }'"
|
|
}
|
|
],
|
|
"parameters": [
|
|
{
|
|
"$ref": "#/components/parameters/TableId"
|
|
}
|
|
],
|
|
"requestBody": {
|
|
"required": true,
|
|
"content": {
|
|
"application/json": {
|
|
"schema": {
|
|
"type": "object",
|
|
"required": ["workspaceId", "data"],
|
|
"properties": {
|
|
"workspaceId": {
|
|
"type": "string",
|
|
"description": "The workspace ID."
|
|
},
|
|
"data": {
|
|
"type": "object",
|
|
"additionalProperties": true,
|
|
"description": "Row data. Must include a value for the conflict target column."
|
|
},
|
|
"conflictTarget": {
|
|
"type": "string",
|
|
"description": "Name of the unique column to match on. Required when the table has multiple unique columns. If the table has exactly one unique column, this can be omitted."
|
|
}
|
|
}
|
|
},
|
|
"example": {
|
|
"workspaceId": "wsp_abc123",
|
|
"data": {
|
|
"email": "user@example.com",
|
|
"name": "John Doe"
|
|
}
|
|
}
|
|
}
|
|
}
|
|
},
|
|
"responses": {
|
|
"200": {
|
|
"description": "Row upserted successfully.",
|
|
"content": {
|
|
"application/json": {
|
|
"schema": {
|
|
"type": "object",
|
|
"properties": {
|
|
"success": {
|
|
"type": "boolean",
|
|
"description": "Indicates whether the request was successful."
|
|
},
|
|
"data": {
|
|
"type": "object",
|
|
"properties": {
|
|
"row": {
|
|
"$ref": "#/components/schemas/TableRow",
|
|
"description": "The inserted or updated row."
|
|
},
|
|
"operation": {
|
|
"type": "string",
|
|
"enum": ["insert", "update"],
|
|
"description": "Whether the row was inserted or updated."
|
|
},
|
|
"message": {
|
|
"type": "string",
|
|
"description": "Confirmation message."
|
|
}
|
|
},
|
|
"description": "Response payload."
|
|
}
|
|
}
|
|
},
|
|
"example": {
|
|
"success": true,
|
|
"data": {
|
|
"row": {
|
|
"id": "row_abc123",
|
|
"data": {
|
|
"email": "user@example.com",
|
|
"name": "John Doe"
|
|
},
|
|
"createdAt": "2026-01-15T10:30:00Z",
|
|
"updatedAt": "2026-01-15T10:30:00Z"
|
|
},
|
|
"operation": "insert",
|
|
"message": "Row inserted successfully"
|
|
}
|
|
}
|
|
}
|
|
}
|
|
},
|
|
"400": {
|
|
"$ref": "#/components/responses/BadRequest"
|
|
},
|
|
"401": {
|
|
"$ref": "#/components/responses/Unauthorized"
|
|
},
|
|
"403": {
|
|
"$ref": "#/components/responses/Forbidden"
|
|
},
|
|
"404": {
|
|
"$ref": "#/components/responses/NotFound"
|
|
},
|
|
"429": {
|
|
"$ref": "#/components/responses/RateLimited"
|
|
}
|
|
}
|
|
}
|
|
},
|
|
"/api/v1/files": {
|
|
"get": {
|
|
"operationId": "listFiles",
|
|
"summary": "List Files",
|
|
"description": "List all files in a workspace.",
|
|
"tags": ["Files"],
|
|
"x-codeSamples": [
|
|
{
|
|
"id": "curl",
|
|
"label": "cURL",
|
|
"lang": "bash",
|
|
"source": "curl -X GET \\\n \"https://www.sim.ai/api/v1/files?workspaceId=YOUR_WORKSPACE_ID\" \\\n -H \"X-API-Key: YOUR_API_KEY\""
|
|
}
|
|
],
|
|
"parameters": [
|
|
{
|
|
"$ref": "#/components/parameters/WorkspaceId"
|
|
}
|
|
],
|
|
"responses": {
|
|
"200": {
|
|
"description": "List of workspace files.",
|
|
"content": {
|
|
"application/json": {
|
|
"schema": {
|
|
"type": "object",
|
|
"properties": {
|
|
"success": {
|
|
"type": "boolean",
|
|
"description": "Whether the request completed successfully."
|
|
},
|
|
"data": {
|
|
"type": "object",
|
|
"properties": {
|
|
"files": {
|
|
"type": "array",
|
|
"items": {
|
|
"$ref": "#/components/schemas/FileMetadata"
|
|
},
|
|
"description": "Array of file metadata objects in the workspace."
|
|
},
|
|
"totalCount": {
|
|
"type": "integer",
|
|
"description": "Total number of files."
|
|
}
|
|
},
|
|
"description": "Response payload containing the files list and count."
|
|
}
|
|
}
|
|
},
|
|
"example": {
|
|
"success": true,
|
|
"data": {
|
|
"files": [
|
|
{
|
|
"id": "file_abc123",
|
|
"name": "data.csv",
|
|
"size": 1024,
|
|
"type": "text/csv",
|
|
"key": "files/wsp_abc123/data.csv",
|
|
"uploadedBy": "user_abc123",
|
|
"uploadedAt": "2026-01-15T10:30:00Z"
|
|
}
|
|
],
|
|
"totalCount": 1
|
|
}
|
|
}
|
|
}
|
|
}
|
|
},
|
|
"400": {
|
|
"$ref": "#/components/responses/BadRequest"
|
|
},
|
|
"401": {
|
|
"$ref": "#/components/responses/Unauthorized"
|
|
},
|
|
"403": {
|
|
"$ref": "#/components/responses/Forbidden"
|
|
},
|
|
"429": {
|
|
"$ref": "#/components/responses/RateLimited"
|
|
}
|
|
}
|
|
},
|
|
"post": {
|
|
"operationId": "uploadFile",
|
|
"summary": "Upload File",
|
|
"description": "Upload a file to a workspace. Send the file as multipart/form-data with a `file` field and a `workspaceId` field. Maximum file size is 100MB. Duplicate filenames within a workspace are not allowed.",
|
|
"tags": ["Files"],
|
|
"x-codeSamples": [
|
|
{
|
|
"id": "curl",
|
|
"label": "cURL",
|
|
"lang": "bash",
|
|
"source": "curl -X POST \\\n \"https://www.sim.ai/api/v1/files\" \\\n -H \"X-API-Key: YOUR_API_KEY\" \\\n -F \"workspaceId=YOUR_WORKSPACE_ID\" \\\n -F \"file=@/path/to/file.csv\""
|
|
}
|
|
],
|
|
"requestBody": {
|
|
"required": true,
|
|
"content": {
|
|
"multipart/form-data": {
|
|
"schema": {
|
|
"type": "object",
|
|
"required": ["file", "workspaceId"],
|
|
"properties": {
|
|
"file": {
|
|
"type": "string",
|
|
"format": "binary",
|
|
"description": "The file to upload (max 100MB)."
|
|
},
|
|
"workspaceId": {
|
|
"type": "string",
|
|
"description": "The workspace to upload the file to."
|
|
}
|
|
}
|
|
}
|
|
}
|
|
}
|
|
},
|
|
"responses": {
|
|
"200": {
|
|
"description": "File uploaded successfully.",
|
|
"content": {
|
|
"application/json": {
|
|
"schema": {
|
|
"type": "object",
|
|
"properties": {
|
|
"success": {
|
|
"type": "boolean",
|
|
"description": "Whether the upload completed successfully."
|
|
},
|
|
"data": {
|
|
"type": "object",
|
|
"properties": {
|
|
"file": {
|
|
"$ref": "#/components/schemas/FileMetadata",
|
|
"description": "Metadata of the newly uploaded file."
|
|
},
|
|
"message": {
|
|
"type": "string",
|
|
"description": "Human-readable confirmation message."
|
|
}
|
|
},
|
|
"description": "Response payload containing the uploaded file metadata."
|
|
}
|
|
}
|
|
},
|
|
"example": {
|
|
"success": true,
|
|
"data": {
|
|
"file": {
|
|
"id": "file_abc123",
|
|
"name": "data.csv",
|
|
"size": 1024,
|
|
"type": "text/csv",
|
|
"key": "files/wsp_abc123/data.csv",
|
|
"uploadedBy": "user_abc123",
|
|
"uploadedAt": "2026-01-15T10:30:00Z"
|
|
},
|
|
"message": "File uploaded successfully"
|
|
}
|
|
}
|
|
}
|
|
}
|
|
},
|
|
"400": {
|
|
"$ref": "#/components/responses/BadRequest"
|
|
},
|
|
"401": {
|
|
"$ref": "#/components/responses/Unauthorized"
|
|
},
|
|
"403": {
|
|
"$ref": "#/components/responses/Forbidden"
|
|
},
|
|
"409": {
|
|
"description": "A file with the same name already exists in this workspace.",
|
|
"content": {
|
|
"application/json": {
|
|
"schema": {
|
|
"type": "object",
|
|
"properties": {
|
|
"error": {
|
|
"type": "string",
|
|
"description": "Error message indicating a file with the same name already exists in this workspace."
|
|
}
|
|
}
|
|
}
|
|
}
|
|
}
|
|
},
|
|
"429": {
|
|
"$ref": "#/components/responses/RateLimited"
|
|
}
|
|
},
|
|
"parameters": []
|
|
}
|
|
},
|
|
"/api/v1/files/{fileId}": {
|
|
"get": {
|
|
"operationId": "downloadFile",
|
|
"summary": "Download File",
|
|
"description": "Download a file's content. Returns the raw file bytes with appropriate Content-Type, Content-Disposition, and Content-Length headers. File metadata is included in custom response headers: X-File-Id, X-File-Name, X-Uploaded-At.",
|
|
"tags": ["Files"],
|
|
"x-codeSamples": [
|
|
{
|
|
"id": "curl",
|
|
"label": "cURL",
|
|
"lang": "bash",
|
|
"source": "curl -X GET \\\n \"https://www.sim.ai/api/v1/files/{fileId}?workspaceId=YOUR_WORKSPACE_ID\" \\\n -H \"X-API-Key: YOUR_API_KEY\" \\\n -o downloaded-file.csv"
|
|
}
|
|
],
|
|
"parameters": [
|
|
{
|
|
"name": "fileId",
|
|
"in": "path",
|
|
"required": true,
|
|
"description": "The unique identifier of the file.",
|
|
"schema": {
|
|
"type": "string",
|
|
"example": "wf_1709571234_abc1234"
|
|
}
|
|
},
|
|
{
|
|
"$ref": "#/components/parameters/WorkspaceId"
|
|
}
|
|
],
|
|
"responses": {
|
|
"200": {
|
|
"description": "File content as binary data.",
|
|
"headers": {
|
|
"Content-Type": {
|
|
"description": "MIME type of the file.",
|
|
"schema": {
|
|
"type": "string",
|
|
"example": "text/csv"
|
|
}
|
|
},
|
|
"Content-Disposition": {
|
|
"description": "Attachment with filename.",
|
|
"schema": {
|
|
"type": "string",
|
|
"example": "attachment; filename=\"data.csv\""
|
|
}
|
|
},
|
|
"Content-Length": {
|
|
"description": "File size in bytes.",
|
|
"schema": {
|
|
"type": "string",
|
|
"example": "1024"
|
|
}
|
|
},
|
|
"X-File-Id": {
|
|
"description": "Unique file identifier.",
|
|
"schema": {
|
|
"type": "string"
|
|
}
|
|
},
|
|
"X-File-Name": {
|
|
"description": "Original filename.",
|
|
"schema": {
|
|
"type": "string"
|
|
}
|
|
},
|
|
"X-Uploaded-At": {
|
|
"description": "ISO 8601 upload timestamp.",
|
|
"schema": {
|
|
"type": "string",
|
|
"format": "date-time"
|
|
}
|
|
}
|
|
},
|
|
"content": {
|
|
"application/octet-stream": {
|
|
"schema": {
|
|
"type": "string",
|
|
"format": "binary"
|
|
}
|
|
}
|
|
}
|
|
},
|
|
"400": {
|
|
"$ref": "#/components/responses/BadRequest"
|
|
},
|
|
"401": {
|
|
"$ref": "#/components/responses/Unauthorized"
|
|
},
|
|
"403": {
|
|
"$ref": "#/components/responses/Forbidden"
|
|
},
|
|
"404": {
|
|
"$ref": "#/components/responses/NotFound"
|
|
},
|
|
"429": {
|
|
"$ref": "#/components/responses/RateLimited"
|
|
}
|
|
}
|
|
},
|
|
"delete": {
|
|
"operationId": "deleteFile",
|
|
"summary": "Delete File",
|
|
"description": "Delete a file from a workspace. This removes both the file content and its metadata. This action is irreversible.",
|
|
"tags": ["Files"],
|
|
"x-codeSamples": [
|
|
{
|
|
"id": "curl",
|
|
"label": "cURL",
|
|
"lang": "bash",
|
|
"source": "curl -X DELETE \\\n \"https://www.sim.ai/api/v1/files/{fileId}?workspaceId=YOUR_WORKSPACE_ID\" \\\n -H \"X-API-Key: YOUR_API_KEY\""
|
|
}
|
|
],
|
|
"parameters": [
|
|
{
|
|
"name": "fileId",
|
|
"in": "path",
|
|
"required": true,
|
|
"description": "The unique identifier of the file to delete.",
|
|
"schema": {
|
|
"type": "string",
|
|
"example": "wf_1709571234_abc1234"
|
|
}
|
|
},
|
|
{
|
|
"$ref": "#/components/parameters/WorkspaceId"
|
|
}
|
|
],
|
|
"responses": {
|
|
"200": {
|
|
"description": "File deleted successfully.",
|
|
"content": {
|
|
"application/json": {
|
|
"schema": {
|
|
"type": "object",
|
|
"properties": {
|
|
"success": {
|
|
"type": "boolean",
|
|
"description": "Whether the deletion completed successfully."
|
|
},
|
|
"data": {
|
|
"type": "object",
|
|
"properties": {
|
|
"message": {
|
|
"type": "string",
|
|
"description": "Human-readable confirmation message."
|
|
}
|
|
},
|
|
"description": "Response payload containing the deletion confirmation."
|
|
}
|
|
}
|
|
},
|
|
"example": {
|
|
"success": true,
|
|
"data": {
|
|
"message": "File deleted successfully"
|
|
}
|
|
}
|
|
}
|
|
}
|
|
},
|
|
"400": {
|
|
"$ref": "#/components/responses/BadRequest"
|
|
},
|
|
"401": {
|
|
"$ref": "#/components/responses/Unauthorized"
|
|
},
|
|
"403": {
|
|
"$ref": "#/components/responses/Forbidden"
|
|
},
|
|
"404": {
|
|
"$ref": "#/components/responses/NotFound"
|
|
},
|
|
"429": {
|
|
"$ref": "#/components/responses/RateLimited"
|
|
}
|
|
}
|
|
}
|
|
},
|
|
"/api/v1/knowledge": {
|
|
"get": {
|
|
"operationId": "listKnowledgeBases",
|
|
"summary": "List Knowledge Bases",
|
|
"description": "List all knowledge bases in a workspace.",
|
|
"tags": ["Knowledge Bases"],
|
|
"x-codeSamples": [
|
|
{
|
|
"id": "curl",
|
|
"label": "cURL",
|
|
"lang": "bash",
|
|
"source": "curl -X GET \\\n \"https://www.sim.ai/api/v1/knowledge?workspaceId=YOUR_WORKSPACE_ID\" \\\n -H \"X-API-Key: YOUR_API_KEY\""
|
|
}
|
|
],
|
|
"parameters": [
|
|
{
|
|
"$ref": "#/components/parameters/WorkspaceId"
|
|
}
|
|
],
|
|
"responses": {
|
|
"200": {
|
|
"description": "List of knowledge bases in the workspace.",
|
|
"content": {
|
|
"application/json": {
|
|
"schema": {
|
|
"type": "object",
|
|
"properties": {
|
|
"success": {
|
|
"type": "boolean",
|
|
"description": "Whether the request was successful."
|
|
},
|
|
"data": {
|
|
"type": "object",
|
|
"properties": {
|
|
"knowledgeBases": {
|
|
"type": "array",
|
|
"items": {
|
|
"$ref": "#/components/schemas/KnowledgeBase"
|
|
},
|
|
"description": "Array of knowledge base objects in the workspace."
|
|
},
|
|
"totalCount": {
|
|
"type": "integer",
|
|
"description": "Total number of knowledge bases."
|
|
}
|
|
},
|
|
"description": "Response payload containing the list of knowledge bases."
|
|
}
|
|
}
|
|
},
|
|
"example": {
|
|
"success": true,
|
|
"data": {
|
|
"knowledgeBases": [
|
|
{
|
|
"id": "kb_abc123",
|
|
"name": "Product Docs",
|
|
"description": "Product documentation and FAQs",
|
|
"docCount": 5,
|
|
"tokenCount": 25000,
|
|
"embeddingModel": "text-embedding-3-small",
|
|
"createdAt": "2026-01-15T10:30:00Z",
|
|
"updatedAt": "2026-01-15T10:30:00Z"
|
|
}
|
|
],
|
|
"totalCount": 1
|
|
}
|
|
}
|
|
}
|
|
}
|
|
},
|
|
"400": {
|
|
"$ref": "#/components/responses/BadRequest"
|
|
},
|
|
"401": {
|
|
"$ref": "#/components/responses/Unauthorized"
|
|
},
|
|
"403": {
|
|
"$ref": "#/components/responses/Forbidden"
|
|
},
|
|
"429": {
|
|
"$ref": "#/components/responses/RateLimited"
|
|
}
|
|
}
|
|
},
|
|
"post": {
|
|
"operationId": "createKnowledgeBase",
|
|
"summary": "Create Knowledge Base",
|
|
"description": "Create a new knowledge base in a workspace. Optionally configure chunking parameters for document processing.",
|
|
"tags": ["Knowledge Bases"],
|
|
"x-codeSamples": [
|
|
{
|
|
"id": "curl",
|
|
"label": "cURL",
|
|
"lang": "bash",
|
|
"source": "curl -X POST \\\n \"https://www.sim.ai/api/v1/knowledge\" \\\n -H \"X-API-Key: YOUR_API_KEY\" \\\n -H \"Content-Type: application/json\" \\\n -d '{\n \"workspaceId\": \"YOUR_WORKSPACE_ID\",\n \"name\": \"Product Documentation\",\n \"description\": \"Internal product docs for search\",\n \"chunkingConfig\": {\n \"maxSize\": 1024,\n \"minSize\": 100,\n \"overlap\": 200\n }\n }'"
|
|
}
|
|
],
|
|
"requestBody": {
|
|
"required": true,
|
|
"content": {
|
|
"application/json": {
|
|
"schema": {
|
|
"type": "object",
|
|
"required": ["workspaceId", "name"],
|
|
"properties": {
|
|
"workspaceId": {
|
|
"type": "string",
|
|
"description": "The workspace to create the knowledge base in."
|
|
},
|
|
"name": {
|
|
"type": "string",
|
|
"description": "Knowledge base name (1-255 characters).",
|
|
"maxLength": 255
|
|
},
|
|
"description": {
|
|
"type": "string",
|
|
"description": "Optional description (max 1000 characters).",
|
|
"maxLength": 1000
|
|
},
|
|
"chunkingConfig": {
|
|
"$ref": "#/components/schemas/ChunkingConfig",
|
|
"description": "Optional chunking configuration for document processing. Defaults to maxSize=1024, minSize=100, overlap=200 if omitted."
|
|
}
|
|
}
|
|
},
|
|
"example": {
|
|
"workspaceId": "wsp_abc123",
|
|
"name": "Product Docs",
|
|
"description": "Product documentation and FAQs"
|
|
}
|
|
}
|
|
}
|
|
},
|
|
"responses": {
|
|
"200": {
|
|
"description": "Knowledge base created successfully.",
|
|
"content": {
|
|
"application/json": {
|
|
"schema": {
|
|
"type": "object",
|
|
"properties": {
|
|
"success": {
|
|
"type": "boolean",
|
|
"description": "Whether the request was successful."
|
|
},
|
|
"data": {
|
|
"type": "object",
|
|
"properties": {
|
|
"knowledgeBase": {
|
|
"$ref": "#/components/schemas/KnowledgeBase",
|
|
"description": "The newly created knowledge base object."
|
|
},
|
|
"message": {
|
|
"type": "string",
|
|
"description": "Human-readable confirmation message."
|
|
}
|
|
},
|
|
"description": "Response payload containing the created knowledge base."
|
|
}
|
|
}
|
|
},
|
|
"example": {
|
|
"success": true,
|
|
"data": {
|
|
"knowledgeBase": {
|
|
"id": "kb_abc123",
|
|
"name": "Product Docs",
|
|
"description": "Product documentation and FAQs",
|
|
"docCount": 0,
|
|
"tokenCount": 0,
|
|
"embeddingModel": "text-embedding-3-small",
|
|
"createdAt": "2026-01-15T10:30:00Z",
|
|
"updatedAt": "2026-01-15T10:30:00Z"
|
|
},
|
|
"message": "Knowledge base created successfully"
|
|
}
|
|
}
|
|
}
|
|
}
|
|
},
|
|
"400": {
|
|
"$ref": "#/components/responses/BadRequest"
|
|
},
|
|
"401": {
|
|
"$ref": "#/components/responses/Unauthorized"
|
|
},
|
|
"403": {
|
|
"$ref": "#/components/responses/Forbidden"
|
|
},
|
|
"429": {
|
|
"$ref": "#/components/responses/RateLimited"
|
|
}
|
|
},
|
|
"parameters": []
|
|
}
|
|
},
|
|
"/api/v1/knowledge/{id}": {
|
|
"get": {
|
|
"operationId": "getKnowledgeBase",
|
|
"summary": "Get Knowledge Base",
|
|
"description": "Get details of a specific knowledge base.",
|
|
"tags": ["Knowledge Bases"],
|
|
"x-codeSamples": [
|
|
{
|
|
"id": "curl",
|
|
"label": "cURL",
|
|
"lang": "bash",
|
|
"source": "curl -X GET \\\n \"https://www.sim.ai/api/v1/knowledge/KB_ID?workspaceId=YOUR_WORKSPACE_ID\" \\\n -H \"X-API-Key: YOUR_API_KEY\""
|
|
}
|
|
],
|
|
"parameters": [
|
|
{
|
|
"name": "id",
|
|
"in": "path",
|
|
"required": true,
|
|
"description": "Knowledge base ID.",
|
|
"schema": {
|
|
"type": "string"
|
|
}
|
|
},
|
|
{
|
|
"$ref": "#/components/parameters/WorkspaceId"
|
|
}
|
|
],
|
|
"responses": {
|
|
"200": {
|
|
"description": "Knowledge base details.",
|
|
"content": {
|
|
"application/json": {
|
|
"schema": {
|
|
"type": "object",
|
|
"properties": {
|
|
"success": {
|
|
"type": "boolean",
|
|
"description": "Whether the request was successful."
|
|
},
|
|
"data": {
|
|
"type": "object",
|
|
"properties": {
|
|
"knowledgeBase": {
|
|
"$ref": "#/components/schemas/KnowledgeBase",
|
|
"description": "The knowledge base object."
|
|
}
|
|
},
|
|
"description": "Response payload containing the knowledge base details."
|
|
}
|
|
}
|
|
},
|
|
"example": {
|
|
"success": true,
|
|
"data": {
|
|
"knowledgeBase": {
|
|
"id": "kb_abc123",
|
|
"name": "Product Docs",
|
|
"description": "Product documentation and FAQs",
|
|
"docCount": 5,
|
|
"tokenCount": 25000,
|
|
"embeddingModel": "text-embedding-3-small",
|
|
"createdAt": "2026-01-15T10:30:00Z",
|
|
"updatedAt": "2026-01-15T10:30:00Z"
|
|
}
|
|
}
|
|
}
|
|
}
|
|
}
|
|
},
|
|
"400": {
|
|
"$ref": "#/components/responses/BadRequest"
|
|
},
|
|
"401": {
|
|
"$ref": "#/components/responses/Unauthorized"
|
|
},
|
|
"403": {
|
|
"$ref": "#/components/responses/Forbidden"
|
|
},
|
|
"404": {
|
|
"$ref": "#/components/responses/NotFound"
|
|
},
|
|
"429": {
|
|
"$ref": "#/components/responses/RateLimited"
|
|
}
|
|
}
|
|
},
|
|
"put": {
|
|
"operationId": "updateKnowledgeBase",
|
|
"summary": "Update Knowledge Base",
|
|
"description": "Update a knowledge base's name, description, or chunking configuration. At least one field must be provided.",
|
|
"tags": ["Knowledge Bases"],
|
|
"x-codeSamples": [
|
|
{
|
|
"id": "curl",
|
|
"label": "cURL",
|
|
"lang": "bash",
|
|
"source": "curl -X PUT \\\n \"https://www.sim.ai/api/v1/knowledge/KB_ID\" \\\n -H \"X-API-Key: YOUR_API_KEY\" \\\n -H \"Content-Type: application/json\" \\\n -d '{\n \"workspaceId\": \"YOUR_WORKSPACE_ID\",\n \"name\": \"Updated Name\"\n }'"
|
|
}
|
|
],
|
|
"parameters": [
|
|
{
|
|
"name": "id",
|
|
"in": "path",
|
|
"required": true,
|
|
"description": "Knowledge base ID.",
|
|
"schema": {
|
|
"type": "string"
|
|
}
|
|
}
|
|
],
|
|
"requestBody": {
|
|
"required": true,
|
|
"content": {
|
|
"application/json": {
|
|
"schema": {
|
|
"type": "object",
|
|
"required": ["workspaceId"],
|
|
"properties": {
|
|
"workspaceId": {
|
|
"type": "string",
|
|
"description": "The workspace the knowledge base belongs to."
|
|
},
|
|
"name": {
|
|
"type": "string",
|
|
"description": "New name (1-255 characters).",
|
|
"maxLength": 255
|
|
},
|
|
"description": {
|
|
"type": "string",
|
|
"description": "New description (max 1000 characters).",
|
|
"maxLength": 1000
|
|
},
|
|
"chunkingConfig": {
|
|
"$ref": "#/components/schemas/ChunkingConfig",
|
|
"description": "Updated chunking configuration. All three fields (maxSize, minSize, overlap) must be provided if included."
|
|
}
|
|
}
|
|
},
|
|
"example": {
|
|
"workspaceId": "wsp_abc123",
|
|
"name": "Updated Product Docs",
|
|
"description": "Updated product documentation"
|
|
}
|
|
}
|
|
}
|
|
},
|
|
"responses": {
|
|
"200": {
|
|
"description": "Knowledge base updated successfully.",
|
|
"content": {
|
|
"application/json": {
|
|
"schema": {
|
|
"type": "object",
|
|
"properties": {
|
|
"success": {
|
|
"type": "boolean",
|
|
"description": "Whether the request was successful."
|
|
},
|
|
"data": {
|
|
"type": "object",
|
|
"properties": {
|
|
"knowledgeBase": {
|
|
"$ref": "#/components/schemas/KnowledgeBase",
|
|
"description": "The updated knowledge base object."
|
|
},
|
|
"message": {
|
|
"type": "string",
|
|
"description": "Human-readable confirmation message."
|
|
}
|
|
},
|
|
"description": "Response payload containing the updated knowledge base."
|
|
}
|
|
}
|
|
},
|
|
"example": {
|
|
"success": true,
|
|
"data": {
|
|
"knowledgeBase": {
|
|
"id": "kb_abc123",
|
|
"name": "Updated Product Docs",
|
|
"description": "Updated product documentation",
|
|
"docCount": 5,
|
|
"tokenCount": 25000,
|
|
"embeddingModel": "text-embedding-3-small",
|
|
"createdAt": "2026-01-15T10:30:00Z",
|
|
"updatedAt": "2026-01-16T08:00:00Z"
|
|
},
|
|
"message": "Knowledge base updated successfully"
|
|
}
|
|
}
|
|
}
|
|
}
|
|
},
|
|
"400": {
|
|
"$ref": "#/components/responses/BadRequest"
|
|
},
|
|
"401": {
|
|
"$ref": "#/components/responses/Unauthorized"
|
|
},
|
|
"403": {
|
|
"$ref": "#/components/responses/Forbidden"
|
|
},
|
|
"404": {
|
|
"$ref": "#/components/responses/NotFound"
|
|
},
|
|
"429": {
|
|
"$ref": "#/components/responses/RateLimited"
|
|
}
|
|
}
|
|
},
|
|
"delete": {
|
|
"operationId": "deleteKnowledgeBase",
|
|
"summary": "Delete Knowledge Base",
|
|
"description": "Soft-delete a knowledge base and all its documents.",
|
|
"tags": ["Knowledge Bases"],
|
|
"x-codeSamples": [
|
|
{
|
|
"id": "curl",
|
|
"label": "cURL",
|
|
"lang": "bash",
|
|
"source": "curl -X DELETE \\\n \"https://www.sim.ai/api/v1/knowledge/KB_ID?workspaceId=YOUR_WORKSPACE_ID\" \\\n -H \"X-API-Key: YOUR_API_KEY\""
|
|
}
|
|
],
|
|
"parameters": [
|
|
{
|
|
"name": "id",
|
|
"in": "path",
|
|
"required": true,
|
|
"description": "Knowledge base ID.",
|
|
"schema": {
|
|
"type": "string"
|
|
}
|
|
},
|
|
{
|
|
"$ref": "#/components/parameters/WorkspaceId"
|
|
}
|
|
],
|
|
"responses": {
|
|
"200": {
|
|
"description": "Knowledge base deleted successfully.",
|
|
"content": {
|
|
"application/json": {
|
|
"schema": {
|
|
"type": "object",
|
|
"properties": {
|
|
"success": {
|
|
"type": "boolean",
|
|
"description": "Whether the request was successful."
|
|
},
|
|
"data": {
|
|
"type": "object",
|
|
"properties": {
|
|
"message": {
|
|
"type": "string",
|
|
"description": "Human-readable confirmation message."
|
|
}
|
|
},
|
|
"description": "Response payload."
|
|
}
|
|
}
|
|
},
|
|
"example": {
|
|
"success": true,
|
|
"data": {
|
|
"message": "Knowledge base deleted successfully"
|
|
}
|
|
}
|
|
}
|
|
}
|
|
},
|
|
"401": {
|
|
"$ref": "#/components/responses/Unauthorized"
|
|
},
|
|
"403": {
|
|
"$ref": "#/components/responses/Forbidden"
|
|
},
|
|
"404": {
|
|
"$ref": "#/components/responses/NotFound"
|
|
},
|
|
"429": {
|
|
"$ref": "#/components/responses/RateLimited"
|
|
}
|
|
}
|
|
}
|
|
},
|
|
"/api/v1/knowledge/{id}/documents": {
|
|
"get": {
|
|
"operationId": "listDocuments",
|
|
"summary": "List Documents",
|
|
"description": "List documents in a knowledge base with pagination, filtering, and sorting.",
|
|
"tags": ["Knowledge Bases"],
|
|
"x-codeSamples": [
|
|
{
|
|
"id": "curl",
|
|
"label": "cURL",
|
|
"lang": "bash",
|
|
"source": "curl -X GET \\\n \"https://www.sim.ai/api/v1/knowledge/KB_ID/documents?workspaceId=YOUR_WORKSPACE_ID&limit=50&offset=0\" \\\n -H \"X-API-Key: YOUR_API_KEY\""
|
|
}
|
|
],
|
|
"parameters": [
|
|
{
|
|
"name": "id",
|
|
"in": "path",
|
|
"required": true,
|
|
"description": "Knowledge base ID.",
|
|
"schema": {
|
|
"type": "string"
|
|
}
|
|
},
|
|
{
|
|
"$ref": "#/components/parameters/WorkspaceId"
|
|
},
|
|
{
|
|
"name": "limit",
|
|
"in": "query",
|
|
"description": "Maximum number of documents to return (1-100, default 50).",
|
|
"schema": {
|
|
"type": "integer",
|
|
"minimum": 1,
|
|
"maximum": 100,
|
|
"default": 50
|
|
}
|
|
},
|
|
{
|
|
"name": "offset",
|
|
"in": "query",
|
|
"description": "Number of documents to skip (default 0).",
|
|
"schema": {
|
|
"type": "integer",
|
|
"minimum": 0,
|
|
"default": 0
|
|
}
|
|
},
|
|
{
|
|
"name": "search",
|
|
"in": "query",
|
|
"description": "Search documents by filename.",
|
|
"schema": {
|
|
"type": "string"
|
|
}
|
|
},
|
|
{
|
|
"name": "enabledFilter",
|
|
"in": "query",
|
|
"description": "Filter by enabled status.",
|
|
"schema": {
|
|
"type": "string",
|
|
"enum": ["all", "enabled", "disabled"],
|
|
"default": "all"
|
|
}
|
|
},
|
|
{
|
|
"name": "sortBy",
|
|
"in": "query",
|
|
"description": "Field to sort by.",
|
|
"schema": {
|
|
"type": "string",
|
|
"enum": [
|
|
"filename",
|
|
"fileSize",
|
|
"tokenCount",
|
|
"chunkCount",
|
|
"uploadedAt",
|
|
"processingStatus",
|
|
"enabled"
|
|
],
|
|
"default": "uploadedAt"
|
|
}
|
|
},
|
|
{
|
|
"name": "sortOrder",
|
|
"in": "query",
|
|
"description": "Sort direction.",
|
|
"schema": {
|
|
"type": "string",
|
|
"enum": ["asc", "desc"],
|
|
"default": "desc"
|
|
}
|
|
}
|
|
],
|
|
"responses": {
|
|
"200": {
|
|
"description": "List of documents.",
|
|
"content": {
|
|
"application/json": {
|
|
"schema": {
|
|
"type": "object",
|
|
"properties": {
|
|
"success": {
|
|
"type": "boolean",
|
|
"description": "Whether the request was successful."
|
|
},
|
|
"data": {
|
|
"type": "object",
|
|
"properties": {
|
|
"documents": {
|
|
"type": "array",
|
|
"items": {
|
|
"$ref": "#/components/schemas/KnowledgeDocument"
|
|
},
|
|
"description": "Array of document objects in the knowledge base."
|
|
},
|
|
"pagination": {
|
|
"type": "object",
|
|
"properties": {
|
|
"total": {
|
|
"type": "integer",
|
|
"description": "Total number of documents matching the query."
|
|
},
|
|
"limit": {
|
|
"type": "integer",
|
|
"description": "Maximum number of documents returned per page."
|
|
},
|
|
"offset": {
|
|
"type": "integer",
|
|
"description": "Number of documents skipped from the beginning."
|
|
},
|
|
"hasMore": {
|
|
"type": "boolean",
|
|
"description": "Whether there are more documents beyond the current page."
|
|
}
|
|
},
|
|
"description": "Pagination metadata for the document list."
|
|
}
|
|
},
|
|
"description": "Response payload containing the documents and pagination info."
|
|
}
|
|
}
|
|
},
|
|
"example": {
|
|
"success": true,
|
|
"data": {
|
|
"documents": [
|
|
{
|
|
"id": "doc_abc123",
|
|
"knowledgeBaseId": "kb_abc123",
|
|
"filename": "Getting Started.pdf",
|
|
"fileSize": 204800,
|
|
"mimeType": "application/pdf",
|
|
"processingStatus": "completed",
|
|
"chunkCount": 12,
|
|
"tokenCount": 3500,
|
|
"enabled": true,
|
|
"createdAt": "2026-01-15T10:30:00Z"
|
|
}
|
|
],
|
|
"pagination": {
|
|
"total": 1,
|
|
"limit": 50,
|
|
"offset": 0,
|
|
"hasMore": false
|
|
}
|
|
}
|
|
}
|
|
}
|
|
}
|
|
},
|
|
"400": {
|
|
"$ref": "#/components/responses/BadRequest"
|
|
},
|
|
"401": {
|
|
"$ref": "#/components/responses/Unauthorized"
|
|
},
|
|
"403": {
|
|
"$ref": "#/components/responses/Forbidden"
|
|
},
|
|
"404": {
|
|
"$ref": "#/components/responses/NotFound"
|
|
},
|
|
"429": {
|
|
"$ref": "#/components/responses/RateLimited"
|
|
}
|
|
}
|
|
},
|
|
"post": {
|
|
"operationId": "uploadDocument",
|
|
"summary": "Upload Document",
|
|
"description": "Upload a document to a knowledge base. The document will be processed asynchronously (chunked and embedded). Maximum file size is 100MB.",
|
|
"tags": ["Knowledge Bases"],
|
|
"x-codeSamples": [
|
|
{
|
|
"id": "curl",
|
|
"label": "cURL",
|
|
"lang": "bash",
|
|
"source": "curl -X POST \\\n \"https://www.sim.ai/api/v1/knowledge/KB_ID/documents\" \\\n -H \"X-API-Key: YOUR_API_KEY\" \\\n -F \"workspaceId=YOUR_WORKSPACE_ID\" \\\n -F \"file=@/path/to/document.pdf\""
|
|
}
|
|
],
|
|
"parameters": [
|
|
{
|
|
"name": "id",
|
|
"in": "path",
|
|
"required": true,
|
|
"description": "Knowledge base ID.",
|
|
"schema": {
|
|
"type": "string"
|
|
}
|
|
}
|
|
],
|
|
"requestBody": {
|
|
"required": true,
|
|
"content": {
|
|
"multipart/form-data": {
|
|
"schema": {
|
|
"type": "object",
|
|
"required": ["file", "workspaceId"],
|
|
"properties": {
|
|
"file": {
|
|
"type": "string",
|
|
"format": "binary",
|
|
"description": "The document file to upload (max 100MB)."
|
|
},
|
|
"workspaceId": {
|
|
"type": "string",
|
|
"description": "The workspace the knowledge base belongs to."
|
|
}
|
|
}
|
|
}
|
|
}
|
|
}
|
|
},
|
|
"responses": {
|
|
"200": {
|
|
"description": "Document uploaded successfully. Processing will begin shortly.",
|
|
"content": {
|
|
"application/json": {
|
|
"schema": {
|
|
"type": "object",
|
|
"properties": {
|
|
"success": {
|
|
"type": "boolean",
|
|
"description": "Whether the request was successful."
|
|
},
|
|
"data": {
|
|
"type": "object",
|
|
"properties": {
|
|
"document": {
|
|
"$ref": "#/components/schemas/KnowledgeDocument",
|
|
"description": "The newly created document object with initial processing status of 'pending'."
|
|
},
|
|
"message": {
|
|
"type": "string",
|
|
"description": "Human-readable confirmation message."
|
|
}
|
|
},
|
|
"description": "Response payload containing the uploaded document."
|
|
}
|
|
}
|
|
},
|
|
"example": {
|
|
"success": true,
|
|
"data": {
|
|
"document": {
|
|
"id": "doc_abc123",
|
|
"knowledgeBaseId": "kb_abc123",
|
|
"filename": "Getting Started.pdf",
|
|
"fileSize": 204800,
|
|
"mimeType": "application/pdf",
|
|
"processingStatus": "pending",
|
|
"chunkCount": 0,
|
|
"tokenCount": 0,
|
|
"enabled": true,
|
|
"createdAt": "2026-01-15T10:30:00Z"
|
|
},
|
|
"message": "Document uploaded successfully. Processing will begin shortly."
|
|
}
|
|
}
|
|
}
|
|
}
|
|
},
|
|
"400": {
|
|
"$ref": "#/components/responses/BadRequest"
|
|
},
|
|
"401": {
|
|
"$ref": "#/components/responses/Unauthorized"
|
|
},
|
|
"403": {
|
|
"$ref": "#/components/responses/Forbidden"
|
|
},
|
|
"404": {
|
|
"$ref": "#/components/responses/NotFound"
|
|
},
|
|
"409": {
|
|
"description": "A file with the same name already exists.",
|
|
"content": {
|
|
"application/json": {
|
|
"schema": {
|
|
"type": "object",
|
|
"properties": {
|
|
"error": {
|
|
"type": "string",
|
|
"description": "Error message indicating a file with the same name already exists."
|
|
}
|
|
}
|
|
}
|
|
}
|
|
}
|
|
},
|
|
"413": {
|
|
"description": "Storage limit exceeded for the workspace.",
|
|
"content": {
|
|
"application/json": {
|
|
"schema": {
|
|
"type": "object",
|
|
"properties": {
|
|
"error": {
|
|
"type": "string",
|
|
"description": "Error message indicating the workspace storage limit has been exceeded."
|
|
}
|
|
}
|
|
}
|
|
}
|
|
}
|
|
},
|
|
"415": {
|
|
"description": "Unsupported file type. See error message for supported types.",
|
|
"content": {
|
|
"application/json": {
|
|
"schema": {
|
|
"type": "object",
|
|
"properties": {
|
|
"error": {
|
|
"type": "string",
|
|
"description": "Error message indicating the file type is not supported."
|
|
}
|
|
}
|
|
}
|
|
}
|
|
}
|
|
},
|
|
"429": {
|
|
"$ref": "#/components/responses/RateLimited"
|
|
}
|
|
}
|
|
}
|
|
},
|
|
"/api/v1/knowledge/{id}/documents/{documentId}": {
|
|
"get": {
|
|
"operationId": "getDocument",
|
|
"summary": "Get Document",
|
|
"description": "Get details of a specific document in a knowledge base.",
|
|
"tags": ["Knowledge Bases"],
|
|
"x-codeSamples": [
|
|
{
|
|
"id": "curl",
|
|
"label": "cURL",
|
|
"lang": "bash",
|
|
"source": "curl -X GET \\\n \"https://www.sim.ai/api/v1/knowledge/KB_ID/documents/DOC_ID?workspaceId=YOUR_WORKSPACE_ID\" \\\n -H \"X-API-Key: YOUR_API_KEY\""
|
|
}
|
|
],
|
|
"parameters": [
|
|
{
|
|
"name": "id",
|
|
"in": "path",
|
|
"required": true,
|
|
"description": "Knowledge base ID.",
|
|
"schema": {
|
|
"type": "string"
|
|
}
|
|
},
|
|
{
|
|
"name": "documentId",
|
|
"in": "path",
|
|
"required": true,
|
|
"description": "Document ID.",
|
|
"schema": {
|
|
"type": "string"
|
|
}
|
|
},
|
|
{
|
|
"$ref": "#/components/parameters/WorkspaceId"
|
|
}
|
|
],
|
|
"responses": {
|
|
"200": {
|
|
"description": "Document details.",
|
|
"content": {
|
|
"application/json": {
|
|
"schema": {
|
|
"type": "object",
|
|
"properties": {
|
|
"success": {
|
|
"type": "boolean",
|
|
"description": "Whether the request was successful."
|
|
},
|
|
"data": {
|
|
"type": "object",
|
|
"properties": {
|
|
"document": {
|
|
"$ref": "#/components/schemas/KnowledgeDocumentDetail",
|
|
"description": "Detailed document object including processing and connector information."
|
|
}
|
|
},
|
|
"description": "Response payload containing the document details."
|
|
}
|
|
}
|
|
},
|
|
"example": {
|
|
"success": true,
|
|
"data": {
|
|
"document": {
|
|
"id": "doc_abc123",
|
|
"knowledgeBaseId": "kb_abc123",
|
|
"filename": "Getting Started.pdf",
|
|
"fileSize": 204800,
|
|
"mimeType": "application/pdf",
|
|
"processingStatus": "completed",
|
|
"chunkCount": 12,
|
|
"tokenCount": 3500,
|
|
"characterCount": 18000,
|
|
"enabled": true,
|
|
"createdAt": "2026-01-15T10:30:00Z"
|
|
}
|
|
}
|
|
}
|
|
}
|
|
}
|
|
},
|
|
"401": {
|
|
"$ref": "#/components/responses/Unauthorized"
|
|
},
|
|
"403": {
|
|
"$ref": "#/components/responses/Forbidden"
|
|
},
|
|
"404": {
|
|
"$ref": "#/components/responses/NotFound"
|
|
},
|
|
"429": {
|
|
"$ref": "#/components/responses/RateLimited"
|
|
}
|
|
}
|
|
},
|
|
"delete": {
|
|
"operationId": "deleteDocument",
|
|
"summary": "Delete Document",
|
|
"description": "Soft-delete a document from a knowledge base. For connector-sourced documents, this also prevents re-import on future syncs.",
|
|
"tags": ["Knowledge Bases"],
|
|
"x-codeSamples": [
|
|
{
|
|
"id": "curl",
|
|
"label": "cURL",
|
|
"lang": "bash",
|
|
"source": "curl -X DELETE \\\n \"https://www.sim.ai/api/v1/knowledge/KB_ID/documents/DOC_ID?workspaceId=YOUR_WORKSPACE_ID\" \\\n -H \"X-API-Key: YOUR_API_KEY\""
|
|
}
|
|
],
|
|
"parameters": [
|
|
{
|
|
"name": "id",
|
|
"in": "path",
|
|
"required": true,
|
|
"description": "Knowledge base ID.",
|
|
"schema": {
|
|
"type": "string"
|
|
}
|
|
},
|
|
{
|
|
"name": "documentId",
|
|
"in": "path",
|
|
"required": true,
|
|
"description": "Document ID.",
|
|
"schema": {
|
|
"type": "string"
|
|
}
|
|
},
|
|
{
|
|
"$ref": "#/components/parameters/WorkspaceId"
|
|
}
|
|
],
|
|
"responses": {
|
|
"200": {
|
|
"description": "Document deleted successfully.",
|
|
"content": {
|
|
"application/json": {
|
|
"schema": {
|
|
"type": "object",
|
|
"properties": {
|
|
"success": {
|
|
"type": "boolean",
|
|
"description": "Whether the request was successful."
|
|
},
|
|
"data": {
|
|
"type": "object",
|
|
"properties": {
|
|
"message": {
|
|
"type": "string",
|
|
"description": "Human-readable confirmation message."
|
|
}
|
|
},
|
|
"description": "Response payload."
|
|
}
|
|
}
|
|
},
|
|
"example": {
|
|
"success": true,
|
|
"data": {
|
|
"message": "Document deleted successfully"
|
|
}
|
|
}
|
|
}
|
|
}
|
|
},
|
|
"401": {
|
|
"$ref": "#/components/responses/Unauthorized"
|
|
},
|
|
"403": {
|
|
"$ref": "#/components/responses/Forbidden"
|
|
},
|
|
"404": {
|
|
"$ref": "#/components/responses/NotFound"
|
|
},
|
|
"429": {
|
|
"$ref": "#/components/responses/RateLimited"
|
|
}
|
|
}
|
|
}
|
|
},
|
|
"/api/v1/knowledge/search": {
|
|
"post": {
|
|
"operationId": "searchKnowledgeBase",
|
|
"summary": "Search Knowledge Base",
|
|
"description": "Perform vector similarity search across one or more knowledge bases. Supports semantic search via query text, tag-based filtering, or a combination of both.",
|
|
"tags": ["Knowledge Bases"],
|
|
"x-codeSamples": [
|
|
{
|
|
"id": "curl",
|
|
"label": "cURL",
|
|
"lang": "bash",
|
|
"source": "curl -X POST \\\n \"https://www.sim.ai/api/v1/knowledge/search\" \\\n -H \"X-API-Key: YOUR_API_KEY\" \\\n -H \"Content-Type: application/json\" \\\n -d '{\n \"workspaceId\": \"YOUR_WORKSPACE_ID\",\n \"knowledgeBaseIds\": [\"KB_ID\"],\n \"query\": \"How do I reset my password?\",\n \"topK\": 5\n }'"
|
|
}
|
|
],
|
|
"requestBody": {
|
|
"required": true,
|
|
"content": {
|
|
"application/json": {
|
|
"schema": {
|
|
"type": "object",
|
|
"required": ["workspaceId", "knowledgeBaseIds"],
|
|
"properties": {
|
|
"workspaceId": {
|
|
"type": "string",
|
|
"description": "The workspace containing the knowledge bases."
|
|
},
|
|
"knowledgeBaseIds": {
|
|
"oneOf": [
|
|
{
|
|
"type": "string",
|
|
"description": "A single knowledge base ID."
|
|
},
|
|
{
|
|
"type": "array",
|
|
"items": {
|
|
"type": "string"
|
|
},
|
|
"description": "An array of knowledge base IDs to search across."
|
|
}
|
|
],
|
|
"description": "Array of knowledge base IDs to search across."
|
|
},
|
|
"query": {
|
|
"type": "string",
|
|
"description": "Search query text for semantic similarity search. Either query or tagFilters must be provided."
|
|
},
|
|
"topK": {
|
|
"type": "integer",
|
|
"minimum": 1,
|
|
"maximum": 100,
|
|
"default": 10,
|
|
"description": "Maximum number of results to return."
|
|
},
|
|
"tagFilters": {
|
|
"type": "array",
|
|
"description": "Tag-based filters. Either query or tagFilters must be provided.",
|
|
"items": {
|
|
"$ref": "#/components/schemas/TagFilter"
|
|
}
|
|
}
|
|
}
|
|
},
|
|
"example": {
|
|
"workspaceId": "wsp_abc123",
|
|
"knowledgeBaseIds": ["kb_abc123"],
|
|
"query": "How do I reset my password?",
|
|
"topK": 5
|
|
}
|
|
}
|
|
}
|
|
},
|
|
"responses": {
|
|
"200": {
|
|
"description": "Search results.",
|
|
"content": {
|
|
"application/json": {
|
|
"schema": {
|
|
"type": "object",
|
|
"properties": {
|
|
"success": {
|
|
"type": "boolean",
|
|
"description": "Whether the request was successful."
|
|
},
|
|
"data": {
|
|
"type": "object",
|
|
"properties": {
|
|
"results": {
|
|
"type": "array",
|
|
"items": {
|
|
"$ref": "#/components/schemas/SearchResult"
|
|
},
|
|
"description": "Array of search result objects ranked by similarity."
|
|
},
|
|
"query": {
|
|
"type": "string",
|
|
"description": "The search query used."
|
|
},
|
|
"knowledgeBaseIds": {
|
|
"type": "array",
|
|
"items": {
|
|
"type": "string"
|
|
},
|
|
"description": "Knowledge base IDs that were searched."
|
|
},
|
|
"topK": {
|
|
"type": "integer",
|
|
"description": "Maximum results requested."
|
|
},
|
|
"totalResults": {
|
|
"type": "integer",
|
|
"description": "Number of results returned."
|
|
}
|
|
},
|
|
"description": "Response payload containing the search results and metadata."
|
|
}
|
|
}
|
|
},
|
|
"example": {
|
|
"success": true,
|
|
"data": {
|
|
"results": [
|
|
{
|
|
"documentId": "doc_abc123",
|
|
"documentName": "Getting Started.pdf",
|
|
"sourceUrl": "https://example.atlassian.net/wiki/spaces/DOCS/pages/12345",
|
|
"content": "To reset your password, go to Settings > Security.",
|
|
"chunkIndex": 3,
|
|
"similarity": 0.95,
|
|
"metadata": {}
|
|
}
|
|
],
|
|
"query": "How do I reset my password?",
|
|
"knowledgeBaseIds": ["kb_abc123"],
|
|
"topK": 5,
|
|
"totalResults": 1
|
|
}
|
|
}
|
|
}
|
|
}
|
|
},
|
|
"400": {
|
|
"$ref": "#/components/responses/BadRequest"
|
|
},
|
|
"401": {
|
|
"$ref": "#/components/responses/Unauthorized"
|
|
},
|
|
"403": {
|
|
"$ref": "#/components/responses/Forbidden"
|
|
},
|
|
"404": {
|
|
"$ref": "#/components/responses/NotFound"
|
|
},
|
|
"429": {
|
|
"$ref": "#/components/responses/RateLimited"
|
|
}
|
|
},
|
|
"parameters": []
|
|
}
|
|
}
|
|
},
|
|
"components": {
|
|
"securitySchemes": {
|
|
"apiKey": {
|
|
"type": "apiKey",
|
|
"in": "header",
|
|
"name": "X-API-Key",
|
|
"description": "Your Sim API key (personal or workspace). Generate one from the Sim dashboard under Settings > API Keys."
|
|
}
|
|
},
|
|
"parameters": {
|
|
"TableId": {
|
|
"name": "tableId",
|
|
"in": "path",
|
|
"required": true,
|
|
"schema": {
|
|
"type": "string",
|
|
"example": "tbl_abc123"
|
|
},
|
|
"description": "The unique identifier of the table."
|
|
},
|
|
"RowId": {
|
|
"name": "rowId",
|
|
"in": "path",
|
|
"required": true,
|
|
"schema": {
|
|
"type": "string",
|
|
"example": "row_xyz789"
|
|
},
|
|
"description": "The unique identifier of the row."
|
|
},
|
|
"WorkspaceId": {
|
|
"name": "workspaceId",
|
|
"in": "query",
|
|
"required": true,
|
|
"schema": {
|
|
"type": "string"
|
|
},
|
|
"description": "The unique identifier of the workspace."
|
|
}
|
|
},
|
|
"schemas": {
|
|
"ColumnDefinition": {
|
|
"type": "object",
|
|
"description": "Definition of a table column including its type and constraints.",
|
|
"required": ["name", "type"],
|
|
"properties": {
|
|
"name": {
|
|
"type": "string",
|
|
"description": "Column name. Must start with a letter or underscore.",
|
|
"example": "email",
|
|
"pattern": "^[a-zA-Z_][a-zA-Z0-9_]*$"
|
|
},
|
|
"type": {
|
|
"type": "string",
|
|
"enum": ["string", "number", "boolean", "date", "json"],
|
|
"description": "Data type of the column."
|
|
},
|
|
"required": {
|
|
"type": "boolean",
|
|
"description": "Whether the column requires a value on insert.",
|
|
"default": false
|
|
},
|
|
"unique": {
|
|
"type": "boolean",
|
|
"description": "Whether values in this column must be unique across all rows.",
|
|
"default": false
|
|
}
|
|
}
|
|
},
|
|
"Table": {
|
|
"type": "object",
|
|
"description": "A user-defined table with a typed schema.",
|
|
"properties": {
|
|
"id": {
|
|
"type": "string",
|
|
"description": "Unique table identifier.",
|
|
"example": "tbl_abc123"
|
|
},
|
|
"name": {
|
|
"type": "string",
|
|
"description": "Table name.",
|
|
"example": "contacts"
|
|
},
|
|
"description": {
|
|
"type": "string",
|
|
"description": "Optional description of the table.",
|
|
"example": "Customer contact records"
|
|
},
|
|
"schema": {
|
|
"type": "object",
|
|
"description": "Table schema definition.",
|
|
"properties": {
|
|
"columns": {
|
|
"type": "array",
|
|
"items": {
|
|
"$ref": "#/components/schemas/ColumnDefinition"
|
|
},
|
|
"description": "Array of column definitions for the table."
|
|
}
|
|
}
|
|
},
|
|
"rowCount": {
|
|
"type": "integer",
|
|
"description": "Current number of rows in the table."
|
|
},
|
|
"maxRows": {
|
|
"type": "integer",
|
|
"description": "Maximum rows allowed by the current billing plan."
|
|
},
|
|
"createdAt": {
|
|
"type": "string",
|
|
"format": "date-time",
|
|
"description": "ISO 8601 timestamp when the table was created."
|
|
},
|
|
"updatedAt": {
|
|
"type": "string",
|
|
"format": "date-time",
|
|
"description": "ISO 8601 timestamp when the table was last modified."
|
|
}
|
|
}
|
|
},
|
|
"TableRow": {
|
|
"type": "object",
|
|
"description": "A single row in a table.",
|
|
"properties": {
|
|
"id": {
|
|
"type": "string",
|
|
"description": "Unique row identifier.",
|
|
"example": "row_xyz789"
|
|
},
|
|
"data": {
|
|
"type": "object",
|
|
"additionalProperties": true,
|
|
"description": "Row data as key-value pairs matching the table schema."
|
|
},
|
|
"position": {
|
|
"type": "integer",
|
|
"description": "Row's position/order in the table."
|
|
},
|
|
"createdAt": {
|
|
"type": "string",
|
|
"format": "date-time",
|
|
"description": "ISO 8601 timestamp when the row was created."
|
|
},
|
|
"updatedAt": {
|
|
"type": "string",
|
|
"format": "date-time",
|
|
"description": "ISO 8601 timestamp when the row was last modified."
|
|
}
|
|
}
|
|
},
|
|
"WorkflowSummary": {
|
|
"type": "object",
|
|
"description": "Summary representation of a workflow returned in list operations.",
|
|
"properties": {
|
|
"id": {
|
|
"type": "string",
|
|
"description": "Unique workflow identifier.",
|
|
"example": "wf_1a2b3c4d5e"
|
|
},
|
|
"name": {
|
|
"type": "string",
|
|
"description": "Human-readable workflow name.",
|
|
"example": "Customer Support Agent"
|
|
},
|
|
"description": {
|
|
"type": "string",
|
|
"nullable": true,
|
|
"description": "Optional description of what the workflow does.",
|
|
"example": "Routes incoming support tickets and drafts responses"
|
|
},
|
|
"folderId": {
|
|
"type": "string",
|
|
"nullable": true,
|
|
"description": "The folder this workflow belongs to. null if at the workspace root.",
|
|
"example": "folder_abc123"
|
|
},
|
|
"workspaceId": {
|
|
"type": "string",
|
|
"description": "The workspace this workflow belongs to.",
|
|
"example": "ws_xyz789"
|
|
},
|
|
"isDeployed": {
|
|
"type": "boolean",
|
|
"description": "Whether the workflow is currently deployed and available for API execution.",
|
|
"example": true
|
|
},
|
|
"deployedAt": {
|
|
"type": "string",
|
|
"format": "date-time",
|
|
"nullable": true,
|
|
"description": "ISO 8601 timestamp of the most recent deployment. null if never deployed.",
|
|
"example": "2025-06-15T10:30:00Z"
|
|
},
|
|
"runCount": {
|
|
"type": "integer",
|
|
"description": "Total number of times this workflow has been executed.",
|
|
"example": 142
|
|
},
|
|
"lastRunAt": {
|
|
"type": "string",
|
|
"format": "date-time",
|
|
"nullable": true,
|
|
"description": "ISO 8601 timestamp of the most recent execution. null if never run.",
|
|
"example": "2025-06-20T14:15:22Z"
|
|
},
|
|
"createdAt": {
|
|
"type": "string",
|
|
"format": "date-time",
|
|
"description": "ISO 8601 timestamp when the workflow was created.",
|
|
"example": "2025-01-10T09:00:00Z"
|
|
},
|
|
"updatedAt": {
|
|
"type": "string",
|
|
"format": "date-time",
|
|
"description": "ISO 8601 timestamp when the workflow was last modified.",
|
|
"example": "2025-06-18T16:45:00Z"
|
|
}
|
|
}
|
|
},
|
|
"WorkflowDetail": {
|
|
"type": "object",
|
|
"description": "Full workflow representation including input field definitions and configuration.",
|
|
"properties": {
|
|
"id": {
|
|
"type": "string",
|
|
"description": "Unique workflow identifier.",
|
|
"example": "wf_1a2b3c4d5e"
|
|
},
|
|
"name": {
|
|
"type": "string",
|
|
"description": "Human-readable workflow name.",
|
|
"example": "Customer Support Agent"
|
|
},
|
|
"description": {
|
|
"type": "string",
|
|
"nullable": true,
|
|
"description": "Optional description of what the workflow does.",
|
|
"example": "Routes incoming support tickets and drafts responses"
|
|
},
|
|
"folderId": {
|
|
"type": "string",
|
|
"nullable": true,
|
|
"description": "The folder this workflow belongs to. null if at the workspace root.",
|
|
"example": "folder_abc123"
|
|
},
|
|
"workspaceId": {
|
|
"type": "string",
|
|
"description": "The workspace this workflow belongs to.",
|
|
"example": "ws_xyz789"
|
|
},
|
|
"isDeployed": {
|
|
"type": "boolean",
|
|
"description": "Whether the workflow is currently deployed and available for API execution.",
|
|
"example": true
|
|
},
|
|
"deployedAt": {
|
|
"type": "string",
|
|
"format": "date-time",
|
|
"nullable": true,
|
|
"description": "ISO 8601 timestamp of the most recent deployment. null if never deployed.",
|
|
"example": "2025-06-15T10:30:00Z"
|
|
},
|
|
"runCount": {
|
|
"type": "integer",
|
|
"description": "Total number of times this workflow has been executed.",
|
|
"example": 142
|
|
},
|
|
"lastRunAt": {
|
|
"type": "string",
|
|
"format": "date-time",
|
|
"nullable": true,
|
|
"description": "ISO 8601 timestamp of the most recent execution. null if never run.",
|
|
"example": "2025-06-20T14:15:22Z"
|
|
},
|
|
"variables": {
|
|
"type": "object",
|
|
"description": "Workflow-level variables and their current values.",
|
|
"example": {}
|
|
},
|
|
"inputs": {
|
|
"type": "object",
|
|
"description": "The workflow's input field definitions. Use these to construct the input object when executing the workflow.",
|
|
"properties": {
|
|
"fields": {
|
|
"type": "object",
|
|
"description": "Map of field names to their type definitions and configuration.",
|
|
"additionalProperties": true,
|
|
"example": {}
|
|
}
|
|
}
|
|
},
|
|
"createdAt": {
|
|
"type": "string",
|
|
"format": "date-time",
|
|
"description": "ISO 8601 timestamp when the workflow was created.",
|
|
"example": "2025-01-10T09:00:00Z"
|
|
},
|
|
"updatedAt": {
|
|
"type": "string",
|
|
"format": "date-time",
|
|
"description": "ISO 8601 timestamp when the workflow was last modified.",
|
|
"example": "2025-06-18T16:45:00Z"
|
|
}
|
|
}
|
|
},
|
|
"ExecutionResult": {
|
|
"type": "object",
|
|
"description": "Result of a synchronous workflow execution.",
|
|
"properties": {
|
|
"success": {
|
|
"type": "boolean",
|
|
"description": "Whether the workflow executed successfully without errors.",
|
|
"example": true
|
|
},
|
|
"executionId": {
|
|
"type": "string",
|
|
"description": "Unique identifier for this execution. Use this to query logs or cancel the execution.",
|
|
"example": "exec_9f8e7d6c5b"
|
|
},
|
|
"output": {
|
|
"type": "object",
|
|
"description": "Workflow output keyed by block name and output field. Structure depends on the workflow's block configuration.",
|
|
"additionalProperties": true,
|
|
"example": {
|
|
"result": "Hello, world!"
|
|
}
|
|
},
|
|
"error": {
|
|
"type": "string",
|
|
"nullable": true,
|
|
"description": "Error message if the execution failed. null on success.",
|
|
"example": null
|
|
},
|
|
"metadata": {
|
|
"type": "object",
|
|
"description": "Execution timing metadata.",
|
|
"properties": {
|
|
"duration": {
|
|
"type": "integer",
|
|
"description": "Total execution duration in milliseconds.",
|
|
"example": 1250
|
|
},
|
|
"startTime": {
|
|
"type": "string",
|
|
"format": "date-time",
|
|
"description": "ISO 8601 timestamp when execution started.",
|
|
"example": "2025-06-20T14:15:22Z"
|
|
},
|
|
"endTime": {
|
|
"type": "string",
|
|
"format": "date-time",
|
|
"description": "ISO 8601 timestamp when execution completed.",
|
|
"example": "2025-06-20T14:15:23Z"
|
|
}
|
|
}
|
|
}
|
|
}
|
|
},
|
|
"AsyncExecutionResult": {
|
|
"type": "object",
|
|
"description": "Response returned when a workflow execution is queued for asynchronous processing.",
|
|
"properties": {
|
|
"success": {
|
|
"type": "boolean",
|
|
"description": "Whether the execution was successfully queued.",
|
|
"example": true
|
|
},
|
|
"async": {
|
|
"type": "boolean",
|
|
"description": "Always true for async executions. Use this to distinguish from synchronous responses.",
|
|
"example": true
|
|
},
|
|
"jobId": {
|
|
"type": "string",
|
|
"description": "Internal job queue identifier for tracking the execution.",
|
|
"example": "job_4a3b2c1d0e"
|
|
},
|
|
"executionId": {
|
|
"type": "string",
|
|
"description": "Unique execution identifier. Use this to query execution status or cancel.",
|
|
"example": "exec_9f8e7d6c5b"
|
|
},
|
|
"message": {
|
|
"type": "string",
|
|
"description": "Human-readable status message (e.g., \"Execution queued\").",
|
|
"example": "Execution queued"
|
|
},
|
|
"statusUrl": {
|
|
"type": "string",
|
|
"format": "uri",
|
|
"description": "URL to poll for execution status and results. Returns the full execution result once complete.",
|
|
"example": "https://www.sim.ai/api/jobs/job_4a3b2c1d0e"
|
|
}
|
|
}
|
|
},
|
|
"LogEntry": {
|
|
"type": "object",
|
|
"description": "Summary of a single workflow execution log entry.",
|
|
"properties": {
|
|
"id": {
|
|
"type": "string",
|
|
"description": "Unique log entry identifier.",
|
|
"example": "log_7x8y9z0a1b"
|
|
},
|
|
"workflowId": {
|
|
"type": "string",
|
|
"description": "The workflow that was executed.",
|
|
"example": "wf_1a2b3c4d5e"
|
|
},
|
|
"executionId": {
|
|
"type": "string",
|
|
"description": "Unique execution identifier for this run.",
|
|
"example": "exec_9f8e7d6c5b"
|
|
},
|
|
"level": {
|
|
"type": "string",
|
|
"description": "Log severity. info for successful executions, error for failures.",
|
|
"example": "info"
|
|
},
|
|
"trigger": {
|
|
"type": "string",
|
|
"description": "How the execution was triggered (e.g., api, manual, webhook, schedule, chat).",
|
|
"example": "api"
|
|
},
|
|
"startedAt": {
|
|
"type": "string",
|
|
"format": "date-time",
|
|
"description": "ISO 8601 timestamp when execution started.",
|
|
"example": "2025-06-20T14:15:22Z"
|
|
},
|
|
"endedAt": {
|
|
"type": "string",
|
|
"format": "date-time",
|
|
"description": "ISO 8601 timestamp when execution completed.",
|
|
"example": "2025-06-20T14:15:23Z"
|
|
},
|
|
"totalDurationMs": {
|
|
"type": "integer",
|
|
"description": "Total execution duration in milliseconds.",
|
|
"example": 1250
|
|
},
|
|
"cost": {
|
|
"type": "object",
|
|
"description": "Cost summary for this execution.",
|
|
"properties": {
|
|
"total": {
|
|
"type": "number",
|
|
"description": "Total cost of this execution in USD.",
|
|
"example": 0.0032
|
|
}
|
|
}
|
|
},
|
|
"files": {
|
|
"type": "object",
|
|
"nullable": true,
|
|
"description": "File outputs produced during execution. null if no files were generated.",
|
|
"example": null
|
|
}
|
|
}
|
|
},
|
|
"LogDetail": {
|
|
"type": "object",
|
|
"description": "Detailed log entry with full execution data, workflow metadata, and cost breakdown.",
|
|
"properties": {
|
|
"id": {
|
|
"type": "string",
|
|
"description": "Unique log entry identifier.",
|
|
"example": "log_7x8y9z0a1b"
|
|
},
|
|
"workflowId": {
|
|
"type": "string",
|
|
"description": "The workflow that was executed.",
|
|
"example": "wf_1a2b3c4d5e"
|
|
},
|
|
"executionId": {
|
|
"type": "string",
|
|
"description": "Unique execution identifier for this run.",
|
|
"example": "exec_9f8e7d6c5b"
|
|
},
|
|
"level": {
|
|
"type": "string",
|
|
"description": "Log severity. info for successful executions, error for failures.",
|
|
"example": "info"
|
|
},
|
|
"trigger": {
|
|
"type": "string",
|
|
"description": "How the execution was triggered (e.g., api, manual, webhook, schedule, chat).",
|
|
"example": "api"
|
|
},
|
|
"startedAt": {
|
|
"type": "string",
|
|
"format": "date-time",
|
|
"description": "ISO 8601 timestamp when execution started.",
|
|
"example": "2025-06-20T14:15:22Z"
|
|
},
|
|
"endedAt": {
|
|
"type": "string",
|
|
"format": "date-time",
|
|
"description": "ISO 8601 timestamp when execution completed.",
|
|
"example": "2025-06-20T14:15:23Z"
|
|
},
|
|
"totalDurationMs": {
|
|
"type": "integer",
|
|
"description": "Total execution duration in milliseconds.",
|
|
"example": 1250
|
|
},
|
|
"workflow": {
|
|
"type": "object",
|
|
"description": "Summary metadata about the workflow at the time of execution.",
|
|
"properties": {
|
|
"id": {
|
|
"type": "string",
|
|
"description": "Unique workflow identifier.",
|
|
"example": "wf_1a2b3c4d5e"
|
|
},
|
|
"name": {
|
|
"type": "string",
|
|
"description": "Workflow name at the time of execution.",
|
|
"example": "Customer Support Agent"
|
|
},
|
|
"description": {
|
|
"type": "string",
|
|
"nullable": true,
|
|
"description": "Workflow description at the time of execution.",
|
|
"example": "Routes incoming support tickets and drafts responses"
|
|
}
|
|
}
|
|
},
|
|
"executionData": {
|
|
"type": "object",
|
|
"description": "Detailed execution data including block-level traces and final output.",
|
|
"properties": {
|
|
"traceSpans": {
|
|
"type": "array",
|
|
"description": "Block-level execution traces with timing, inputs, and outputs for each block that ran.",
|
|
"items": {
|
|
"type": "object"
|
|
}
|
|
},
|
|
"finalOutput": {
|
|
"type": "object",
|
|
"description": "The workflow's final output after all blocks completed."
|
|
}
|
|
}
|
|
},
|
|
"cost": {
|
|
"type": "object",
|
|
"description": "Detailed cost breakdown for this execution.",
|
|
"properties": {
|
|
"total": {
|
|
"type": "number",
|
|
"description": "Total cost of this execution in USD.",
|
|
"example": 0.0032
|
|
},
|
|
"tokens": {
|
|
"type": "object",
|
|
"description": "Aggregate token usage across all AI model calls in this execution.",
|
|
"properties": {
|
|
"prompt": {
|
|
"type": "integer",
|
|
"description": "Total prompt (input) tokens consumed.",
|
|
"example": 450
|
|
},
|
|
"completion": {
|
|
"type": "integer",
|
|
"description": "Total completion (output) tokens generated.",
|
|
"example": 120
|
|
},
|
|
"total": {
|
|
"type": "integer",
|
|
"description": "Total tokens (prompt + completion).",
|
|
"example": 570
|
|
}
|
|
}
|
|
},
|
|
"models": {
|
|
"type": "object",
|
|
"description": "Per-model cost and token breakdown. Keys are model identifiers (e.g., gpt-4o, claude-sonnet-4-20250514).",
|
|
"additionalProperties": {
|
|
"type": "object",
|
|
"description": "Cost and token details for a specific model.",
|
|
"properties": {
|
|
"input": {
|
|
"type": "number",
|
|
"description": "Cost of prompt tokens for this model in USD."
|
|
},
|
|
"output": {
|
|
"type": "number",
|
|
"description": "Cost of completion tokens for this model in USD."
|
|
},
|
|
"total": {
|
|
"type": "number",
|
|
"description": "Total cost for this model in USD."
|
|
},
|
|
"tokens": {
|
|
"type": "object",
|
|
"description": "Token usage for this specific model.",
|
|
"properties": {
|
|
"prompt": {
|
|
"type": "integer",
|
|
"description": "Prompt tokens consumed by this model."
|
|
},
|
|
"completion": {
|
|
"type": "integer",
|
|
"description": "Completion tokens generated by this model."
|
|
},
|
|
"total": {
|
|
"type": "integer",
|
|
"description": "Total tokens for this model."
|
|
}
|
|
}
|
|
}
|
|
}
|
|
}
|
|
}
|
|
}
|
|
}
|
|
}
|
|
},
|
|
"Limits": {
|
|
"type": "object",
|
|
"description": "Rate limit and usage information included in every API response.",
|
|
"properties": {
|
|
"workflowExecutionRateLimit": {
|
|
"type": "object",
|
|
"description": "Current rate limit status for workflow executions.",
|
|
"properties": {
|
|
"sync": {
|
|
"description": "Rate limit bucket for synchronous executions.",
|
|
"$ref": "#/components/schemas/RateLimitBucket"
|
|
},
|
|
"async": {
|
|
"description": "Rate limit bucket for asynchronous executions.",
|
|
"$ref": "#/components/schemas/RateLimitBucket"
|
|
}
|
|
}
|
|
},
|
|
"usage": {
|
|
"type": "object",
|
|
"description": "Current billing period usage and plan limits.",
|
|
"properties": {
|
|
"currentPeriodCost": {
|
|
"type": "number",
|
|
"description": "Total spend in the current billing period in USD.",
|
|
"example": 1.25
|
|
},
|
|
"limit": {
|
|
"type": "number",
|
|
"description": "Maximum allowed spend for the current billing period in USD.",
|
|
"example": 50.0
|
|
},
|
|
"plan": {
|
|
"type": "string",
|
|
"description": "Your current subscription plan (e.g., free, pro, team).",
|
|
"example": "pro"
|
|
},
|
|
"isExceeded": {
|
|
"type": "boolean",
|
|
"description": "Whether the usage limit has been exceeded. Executions may be blocked when true.",
|
|
"example": false
|
|
}
|
|
}
|
|
}
|
|
}
|
|
},
|
|
"RateLimitBucket": {
|
|
"type": "object",
|
|
"description": "Rate limit status for a specific execution type.",
|
|
"properties": {
|
|
"requestsPerMinute": {
|
|
"type": "integer",
|
|
"description": "Maximum number of requests allowed per minute.",
|
|
"example": 60
|
|
},
|
|
"maxBurst": {
|
|
"type": "integer",
|
|
"description": "Maximum number of concurrent requests allowed in a burst.",
|
|
"example": 10
|
|
},
|
|
"remaining": {
|
|
"type": "integer",
|
|
"description": "Number of requests remaining in the current rate limit window.",
|
|
"example": 59
|
|
},
|
|
"resetAt": {
|
|
"type": "string",
|
|
"format": "date-time",
|
|
"description": "ISO 8601 timestamp when the rate limit window resets.",
|
|
"example": "2025-06-20T14:16:00Z"
|
|
}
|
|
}
|
|
},
|
|
"JobStatus": {
|
|
"type": "object",
|
|
"description": "Status of an asynchronous job.",
|
|
"properties": {
|
|
"success": {
|
|
"type": "boolean",
|
|
"description": "Whether the request was successful.",
|
|
"example": true
|
|
},
|
|
"taskId": {
|
|
"type": "string",
|
|
"description": "The unique identifier of the job.",
|
|
"example": "job_4a3b2c1d0e"
|
|
},
|
|
"status": {
|
|
"type": "string",
|
|
"enum": ["queued", "processing", "completed", "failed"],
|
|
"description": "Current status of the job.",
|
|
"example": "completed"
|
|
},
|
|
"metadata": {
|
|
"type": "object",
|
|
"description": "Timing metadata for the job.",
|
|
"properties": {
|
|
"startedAt": {
|
|
"type": "string",
|
|
"format": "date-time",
|
|
"description": "ISO 8601 timestamp when the job started processing.",
|
|
"example": "2025-06-20T14:15:22Z"
|
|
},
|
|
"completedAt": {
|
|
"type": "string",
|
|
"format": "date-time",
|
|
"description": "ISO 8601 timestamp when the job completed. Present only when status is completed or failed.",
|
|
"example": "2025-06-20T14:15:23Z"
|
|
},
|
|
"duration": {
|
|
"type": "integer",
|
|
"description": "Duration of the job in milliseconds. Present only when status is completed or failed.",
|
|
"example": 1250
|
|
}
|
|
}
|
|
},
|
|
"output": {
|
|
"description": "The workflow execution output. Present only when status is completed.",
|
|
"type": "object",
|
|
"example": {
|
|
"result": "Hello, world!"
|
|
}
|
|
},
|
|
"error": {
|
|
"description": "Error details. Present only when status is failed.",
|
|
"type": "string",
|
|
"example": null
|
|
},
|
|
"estimatedDuration": {
|
|
"type": "integer",
|
|
"description": "Estimated duration in milliseconds. Present only when status is queued or processing.",
|
|
"example": 2000
|
|
}
|
|
}
|
|
},
|
|
"WorkflowExecutionStatus": {
|
|
"type": "object",
|
|
"description": "Current status of a workflow execution.",
|
|
"properties": {
|
|
"executionId": {
|
|
"type": "string",
|
|
"description": "The unique identifier of the execution.",
|
|
"example": "9254f1c9-5a11-4a12-91e3-8065293f3609"
|
|
},
|
|
"workflowId": {
|
|
"type": "string",
|
|
"description": "The unique identifier of the workflow.",
|
|
"example": "81f661e1-d704-4861-b5c1-5bb3cf57e6a7"
|
|
},
|
|
"status": {
|
|
"type": "string",
|
|
"enum": ["pending", "running", "paused", "completed", "failed", "cancelled"],
|
|
"description": "Current normalized lifecycle status. `paused` is set when a row exists in pausedExecutions with status `paused` or `partially_resumed`; otherwise the workflowExecutionLogs row's status field is used.",
|
|
"example": "completed"
|
|
},
|
|
"trigger": {
|
|
"type": "string",
|
|
"enum": ["api", "manual", "schedule", "webhook", "chat"],
|
|
"description": "What triggered the execution.",
|
|
"example": "api"
|
|
},
|
|
"level": {
|
|
"type": "string",
|
|
"enum": ["info", "warning", "error"],
|
|
"description": "Log level of the execution.",
|
|
"example": "info"
|
|
},
|
|
"startedAt": {
|
|
"type": "string",
|
|
"format": "date-time",
|
|
"description": "ISO 8601 timestamp when execution started.",
|
|
"example": "2026-05-15T19:43:12.189Z"
|
|
},
|
|
"endedAt": {
|
|
"type": "string",
|
|
"format": "date-time",
|
|
"nullable": true,
|
|
"description": "ISO 8601 timestamp when execution ended. Null while the run is in flight.",
|
|
"example": "2026-05-15T19:45:45.224Z"
|
|
},
|
|
"totalDurationMs": {
|
|
"type": "integer",
|
|
"nullable": true,
|
|
"description": "Total duration of the execution in milliseconds. Null while the run is in flight.",
|
|
"example": 153035
|
|
},
|
|
"paused": {
|
|
"type": "object",
|
|
"nullable": true,
|
|
"description": "Pause-state details. Present only when status is `paused`.",
|
|
"properties": {
|
|
"pausedAt": {
|
|
"type": "string",
|
|
"format": "date-time",
|
|
"description": "ISO 8601 timestamp when the workflow was paused.",
|
|
"example": "2026-05-15T22:25:57.216Z"
|
|
},
|
|
"resumeAt": {
|
|
"type": "string",
|
|
"format": "date-time",
|
|
"nullable": true,
|
|
"description": "Earliest scheduled resume time across active pause points. Null for human-only pauses.",
|
|
"example": "2026-05-16T18:25:57.200Z"
|
|
},
|
|
"pauseKind": {
|
|
"type": "string",
|
|
"enum": ["time", "human"],
|
|
"nullable": true,
|
|
"description": "What kind of pause the workflow is waiting on.",
|
|
"example": "time"
|
|
},
|
|
"blockedOnBlockId": {
|
|
"type": "string",
|
|
"nullable": true,
|
|
"description": "The block currently blocking resume.",
|
|
"example": "c1b90bce-8a82-42a5-b6a5-5762846c2eaf"
|
|
},
|
|
"pausedExecutionId": {
|
|
"type": "string",
|
|
"description": "ID of the paused-execution row, useful for cross-referencing with the human-in-the-loop endpoints.",
|
|
"example": "438bf05b-bd3c-4011-b78e-b19c112eeb66"
|
|
},
|
|
"pausePointCount": {
|
|
"type": "integer",
|
|
"description": "Total number of pause points recorded for this execution.",
|
|
"example": 1
|
|
},
|
|
"resumedCount": {
|
|
"type": "integer",
|
|
"description": "Number of pause points already resumed.",
|
|
"example": 0
|
|
}
|
|
}
|
|
},
|
|
"cost": {
|
|
"type": "object",
|
|
"nullable": true,
|
|
"description": "Cost summary. Detailed token / model breakdown lives on the /v1/logs detail endpoint.",
|
|
"properties": {
|
|
"total": {
|
|
"type": "number",
|
|
"description": "Total cost in USD.",
|
|
"example": 0.005
|
|
}
|
|
}
|
|
},
|
|
"error": {
|
|
"type": "string",
|
|
"nullable": true,
|
|
"description": "Error message. Present only when status is `failed`.",
|
|
"example": null
|
|
},
|
|
"finalOutput": {
|
|
"type": "object",
|
|
"nullable": true,
|
|
"description": "The workflow's final output. Returned only when ?includeOutput=true AND status is `completed`.",
|
|
"example": null
|
|
},
|
|
"blockOutputs": {
|
|
"type": "object",
|
|
"nullable": true,
|
|
"description": "Per-block outputs keyed by the selector string. Returned only when `?selectedOutputs` is set.",
|
|
"additionalProperties": true,
|
|
"example": {
|
|
"c1b90bce-8a82-42a5-b6a5-5762846c2eaf.waitDuration": 60000,
|
|
"c1b90bce-8a82-42a5-b6a5-5762846c2eaf.status": "completed"
|
|
}
|
|
}
|
|
}
|
|
},
|
|
"AuditLogEntry": {
|
|
"type": "object",
|
|
"description": "An enterprise audit log entry recording an action taken in the workspace.",
|
|
"properties": {
|
|
"id": {
|
|
"type": "string",
|
|
"description": "Unique identifier for the audit log entry.",
|
|
"example": "audit_2c3d4e5f6g"
|
|
},
|
|
"workspaceId": {
|
|
"type": "string",
|
|
"nullable": true,
|
|
"description": "The workspace where the action occurred.",
|
|
"example": "ws_xyz789"
|
|
},
|
|
"actorId": {
|
|
"type": "string",
|
|
"nullable": true,
|
|
"description": "The user ID of the person who performed the action.",
|
|
"example": "user_abc123"
|
|
},
|
|
"actorName": {
|
|
"type": "string",
|
|
"nullable": true,
|
|
"description": "Display name of the person who performed the action.",
|
|
"example": "Jane Smith"
|
|
},
|
|
"actorEmail": {
|
|
"type": "string",
|
|
"nullable": true,
|
|
"description": "Email address of the person who performed the action.",
|
|
"example": "jane@example.com"
|
|
},
|
|
"action": {
|
|
"type": "string",
|
|
"description": "The action that was performed (e.g., workflow.created, member.invited).",
|
|
"example": "workflow.deployed"
|
|
},
|
|
"resourceType": {
|
|
"type": "string",
|
|
"description": "The type of resource affected (e.g., workflow, workspace, member).",
|
|
"example": "workflow"
|
|
},
|
|
"resourceId": {
|
|
"type": "string",
|
|
"nullable": true,
|
|
"description": "The unique identifier of the affected resource.",
|
|
"example": "wf_1a2b3c4d5e"
|
|
},
|
|
"resourceName": {
|
|
"type": "string",
|
|
"nullable": true,
|
|
"description": "Display name of the affected resource.",
|
|
"example": "Customer Support Agent"
|
|
},
|
|
"description": {
|
|
"type": "string",
|
|
"nullable": true,
|
|
"description": "Human-readable description of the action.",
|
|
"example": "Deployed workflow Customer Support Agent"
|
|
},
|
|
"metadata": {
|
|
"type": "object",
|
|
"nullable": true,
|
|
"description": "Additional context about the action.",
|
|
"example": null
|
|
},
|
|
"createdAt": {
|
|
"type": "string",
|
|
"format": "date-time",
|
|
"description": "ISO 8601 timestamp when the action occurred.",
|
|
"example": "2025-06-20T14:15:22Z"
|
|
}
|
|
}
|
|
},
|
|
"UsageLimits": {
|
|
"type": "object",
|
|
"description": "Current rate limits, usage, and storage information for the authenticated user.",
|
|
"properties": {
|
|
"success": {
|
|
"type": "boolean",
|
|
"description": "Whether the request was successful."
|
|
},
|
|
"rateLimit": {
|
|
"type": "object",
|
|
"description": "Rate limit status for workflow executions.",
|
|
"properties": {
|
|
"sync": {
|
|
"description": "Rate limit bucket for synchronous executions.",
|
|
"allOf": [
|
|
{
|
|
"$ref": "#/components/schemas/RateLimitBucket"
|
|
},
|
|
{
|
|
"type": "object",
|
|
"properties": {
|
|
"isLimited": {
|
|
"type": "boolean",
|
|
"description": "Whether the rate limit has been reached."
|
|
}
|
|
}
|
|
}
|
|
]
|
|
},
|
|
"async": {
|
|
"description": "Rate limit bucket for asynchronous executions.",
|
|
"allOf": [
|
|
{
|
|
"$ref": "#/components/schemas/RateLimitBucket"
|
|
},
|
|
{
|
|
"type": "object",
|
|
"properties": {
|
|
"isLimited": {
|
|
"type": "boolean",
|
|
"description": "Whether the rate limit has been reached."
|
|
}
|
|
}
|
|
}
|
|
]
|
|
},
|
|
"authType": {
|
|
"type": "string",
|
|
"description": "The authentication type used (api or manual)."
|
|
}
|
|
}
|
|
},
|
|
"usage": {
|
|
"type": "object",
|
|
"description": "Current billing period usage.",
|
|
"properties": {
|
|
"currentPeriodCost": {
|
|
"type": "number",
|
|
"description": "Total spend in the current billing period in USD."
|
|
},
|
|
"limit": {
|
|
"type": "number",
|
|
"description": "Maximum allowed spend for the current billing period in USD."
|
|
},
|
|
"plan": {
|
|
"type": "string",
|
|
"description": "Your current subscription plan (e.g., free, pro, team)."
|
|
}
|
|
}
|
|
},
|
|
"storage": {
|
|
"type": "object",
|
|
"description": "File storage usage.",
|
|
"properties": {
|
|
"usedBytes": {
|
|
"type": "integer",
|
|
"description": "Total storage used in bytes."
|
|
},
|
|
"limitBytes": {
|
|
"type": "integer",
|
|
"description": "Maximum storage allowed in bytes."
|
|
},
|
|
"percentUsed": {
|
|
"type": "number",
|
|
"description": "Percentage of storage used (0-100)."
|
|
}
|
|
}
|
|
}
|
|
}
|
|
},
|
|
"FileMetadata": {
|
|
"type": "object",
|
|
"properties": {
|
|
"id": {
|
|
"type": "string",
|
|
"description": "Unique file identifier.",
|
|
"example": "wf_1709571234_abc1234"
|
|
},
|
|
"name": {
|
|
"type": "string",
|
|
"description": "Original filename.",
|
|
"example": "data.csv"
|
|
},
|
|
"size": {
|
|
"type": "integer",
|
|
"description": "File size in bytes.",
|
|
"example": 1024
|
|
},
|
|
"type": {
|
|
"type": "string",
|
|
"description": "MIME type of the file.",
|
|
"example": "text/csv"
|
|
},
|
|
"key": {
|
|
"type": "string",
|
|
"description": "Storage key for the file.",
|
|
"example": "workspace/abc-123/1709571234-xyz-data.csv"
|
|
},
|
|
"uploadedBy": {
|
|
"type": "string",
|
|
"description": "User ID of the uploader."
|
|
},
|
|
"uploadedAt": {
|
|
"type": "string",
|
|
"format": "date-time",
|
|
"description": "ISO 8601 timestamp of when the file was uploaded."
|
|
}
|
|
}
|
|
},
|
|
"KnowledgeBase": {
|
|
"type": "object",
|
|
"description": "A knowledge base for storing and searching document embeddings.",
|
|
"properties": {
|
|
"id": {
|
|
"type": "string",
|
|
"description": "Unique knowledge base identifier."
|
|
},
|
|
"name": {
|
|
"type": "string",
|
|
"description": "Knowledge base name."
|
|
},
|
|
"description": {
|
|
"type": "string",
|
|
"nullable": true,
|
|
"description": "Optional description."
|
|
},
|
|
"tokenCount": {
|
|
"type": "integer",
|
|
"description": "Total token count across all documents."
|
|
},
|
|
"embeddingModel": {
|
|
"type": "string",
|
|
"description": "Embedding model used (e.g. text-embedding-3-small)."
|
|
},
|
|
"embeddingDimension": {
|
|
"type": "integer",
|
|
"description": "Embedding vector dimension."
|
|
},
|
|
"chunkingConfig": {
|
|
"$ref": "#/components/schemas/ChunkingConfig"
|
|
},
|
|
"docCount": {
|
|
"type": "integer",
|
|
"description": "Number of documents in the knowledge base."
|
|
},
|
|
"connectorTypes": {
|
|
"type": "array",
|
|
"items": {
|
|
"type": "string"
|
|
},
|
|
"description": "Types of connectors attached to this knowledge base."
|
|
},
|
|
"createdAt": {
|
|
"type": "string",
|
|
"format": "date-time",
|
|
"description": "ISO 8601 timestamp when the knowledge base was created."
|
|
},
|
|
"updatedAt": {
|
|
"type": "string",
|
|
"format": "date-time",
|
|
"description": "ISO 8601 timestamp when the knowledge base was last modified."
|
|
}
|
|
}
|
|
},
|
|
"ChunkingConfig": {
|
|
"type": "object",
|
|
"description": "Configuration for how documents are split into chunks for embedding.",
|
|
"properties": {
|
|
"maxSize": {
|
|
"type": "integer",
|
|
"minimum": 100,
|
|
"maximum": 4000,
|
|
"default": 1024,
|
|
"description": "Maximum chunk size in tokens."
|
|
},
|
|
"minSize": {
|
|
"type": "integer",
|
|
"minimum": 1,
|
|
"maximum": 2000,
|
|
"default": 100,
|
|
"description": "Minimum chunk size in characters."
|
|
},
|
|
"overlap": {
|
|
"type": "integer",
|
|
"minimum": 0,
|
|
"maximum": 500,
|
|
"default": 200,
|
|
"description": "Overlap between chunks in tokens."
|
|
}
|
|
}
|
|
},
|
|
"KnowledgeDocument": {
|
|
"type": "object",
|
|
"description": "A document in a knowledge base.",
|
|
"properties": {
|
|
"id": {
|
|
"type": "string",
|
|
"description": "Unique document identifier."
|
|
},
|
|
"knowledgeBaseId": {
|
|
"type": "string",
|
|
"description": "Knowledge base this document belongs to."
|
|
},
|
|
"filename": {
|
|
"type": "string",
|
|
"description": "Original filename."
|
|
},
|
|
"fileSize": {
|
|
"type": "integer",
|
|
"description": "File size in bytes."
|
|
},
|
|
"mimeType": {
|
|
"type": "string",
|
|
"description": "MIME type of the file."
|
|
},
|
|
"processingStatus": {
|
|
"type": "string",
|
|
"enum": ["pending", "processing", "completed", "failed"],
|
|
"description": "Current processing status."
|
|
},
|
|
"chunkCount": {
|
|
"type": "integer",
|
|
"description": "Number of chunks created from this document."
|
|
},
|
|
"tokenCount": {
|
|
"type": "integer",
|
|
"description": "Total token count."
|
|
},
|
|
"characterCount": {
|
|
"type": "integer",
|
|
"description": "Total character count."
|
|
},
|
|
"enabled": {
|
|
"type": "boolean",
|
|
"description": "Whether the document is enabled for search."
|
|
},
|
|
"createdAt": {
|
|
"type": "string",
|
|
"format": "date-time",
|
|
"description": "ISO 8601 timestamp when the document was uploaded."
|
|
}
|
|
}
|
|
},
|
|
"KnowledgeDocumentDetail": {
|
|
"type": "object",
|
|
"description": "Detailed document information including processing and connector details.",
|
|
"properties": {
|
|
"id": {
|
|
"type": "string",
|
|
"description": "Unique document identifier."
|
|
},
|
|
"knowledgeBaseId": {
|
|
"type": "string",
|
|
"description": "Knowledge base this document belongs to."
|
|
},
|
|
"filename": {
|
|
"type": "string",
|
|
"description": "Original filename."
|
|
},
|
|
"fileSize": {
|
|
"type": "integer",
|
|
"description": "File size in bytes."
|
|
},
|
|
"mimeType": {
|
|
"type": "string",
|
|
"description": "MIME type of the file."
|
|
},
|
|
"processingStatus": {
|
|
"type": "string",
|
|
"enum": ["pending", "processing", "completed", "failed"],
|
|
"description": "Current processing status."
|
|
},
|
|
"processingError": {
|
|
"type": "string",
|
|
"nullable": true,
|
|
"description": "Error message if processing failed."
|
|
},
|
|
"processingStartedAt": {
|
|
"type": "string",
|
|
"format": "date-time",
|
|
"nullable": true,
|
|
"description": "When processing started."
|
|
},
|
|
"processingCompletedAt": {
|
|
"type": "string",
|
|
"format": "date-time",
|
|
"nullable": true,
|
|
"description": "When processing completed."
|
|
},
|
|
"chunkCount": {
|
|
"type": "integer",
|
|
"description": "Number of chunks created."
|
|
},
|
|
"tokenCount": {
|
|
"type": "integer",
|
|
"description": "Total token count."
|
|
},
|
|
"characterCount": {
|
|
"type": "integer",
|
|
"description": "Total character count."
|
|
},
|
|
"enabled": {
|
|
"type": "boolean",
|
|
"description": "Whether the document is enabled for search."
|
|
},
|
|
"connectorId": {
|
|
"type": "string",
|
|
"nullable": true,
|
|
"description": "Connector ID if sourced from an external connector."
|
|
},
|
|
"connectorType": {
|
|
"type": "string",
|
|
"nullable": true,
|
|
"description": "Connector type (e.g. google-drive, notion)."
|
|
},
|
|
"sourceUrl": {
|
|
"type": "string",
|
|
"nullable": true,
|
|
"description": "Original source URL for connector-sourced documents."
|
|
},
|
|
"createdAt": {
|
|
"type": "string",
|
|
"format": "date-time",
|
|
"description": "ISO 8601 timestamp when the document was uploaded."
|
|
}
|
|
}
|
|
},
|
|
"SearchResult": {
|
|
"type": "object",
|
|
"description": "A single search result from knowledge base vector search.",
|
|
"properties": {
|
|
"documentId": {
|
|
"type": "string",
|
|
"description": "ID of the source document."
|
|
},
|
|
"documentName": {
|
|
"type": "string",
|
|
"description": "Filename of the source document."
|
|
},
|
|
"sourceUrl": {
|
|
"type": "string",
|
|
"nullable": true,
|
|
"description": "URL to the original source document for connector-synced documents (e.g., a Confluence page, Google Doc, or Notion page). Null for documents without an external source."
|
|
},
|
|
"content": {
|
|
"type": "string",
|
|
"description": "The matched chunk content."
|
|
},
|
|
"chunkIndex": {
|
|
"type": "integer",
|
|
"description": "Index of the chunk within the document."
|
|
},
|
|
"metadata": {
|
|
"type": "object",
|
|
"description": "Tag metadata associated with the chunk (display names mapped to values)."
|
|
},
|
|
"similarity": {
|
|
"type": "number",
|
|
"minimum": 0,
|
|
"maximum": 1,
|
|
"description": "Similarity score (0-1, where 1 is most similar)."
|
|
}
|
|
}
|
|
},
|
|
"TagFilter": {
|
|
"type": "object",
|
|
"description": "A tag-based filter for knowledge base search.",
|
|
"required": ["tagName", "value"],
|
|
"properties": {
|
|
"tagName": {
|
|
"type": "string",
|
|
"description": "Display name of the tag to filter by."
|
|
},
|
|
"fieldType": {
|
|
"type": "string",
|
|
"enum": ["text", "number", "date", "boolean"],
|
|
"default": "text",
|
|
"description": "Data type of the tag field."
|
|
},
|
|
"operator": {
|
|
"type": "string",
|
|
"default": "eq",
|
|
"description": "Comparison operator (e.g. eq, neq, gt, lt, gte, lte, contains, between)."
|
|
},
|
|
"value": {
|
|
"oneOf": [
|
|
{
|
|
"type": "string"
|
|
},
|
|
{
|
|
"type": "number"
|
|
},
|
|
{
|
|
"type": "boolean"
|
|
}
|
|
],
|
|
"description": "Value to filter by."
|
|
},
|
|
"valueTo": {
|
|
"oneOf": [
|
|
{
|
|
"type": "string"
|
|
},
|
|
{
|
|
"type": "number"
|
|
}
|
|
],
|
|
"description": "Upper bound value for 'between' operator."
|
|
}
|
|
}
|
|
},
|
|
"PausedExecutionSummary": {
|
|
"type": "object",
|
|
"description": "Summary of a paused workflow execution.",
|
|
"properties": {
|
|
"id": {
|
|
"type": "string",
|
|
"description": "Unique identifier for the paused execution record."
|
|
},
|
|
"workflowId": {
|
|
"type": "string",
|
|
"description": "The workflow this execution belongs to."
|
|
},
|
|
"executionId": {
|
|
"type": "string",
|
|
"description": "The execution that was paused."
|
|
},
|
|
"status": {
|
|
"type": "string",
|
|
"description": "Current status of the paused execution.",
|
|
"example": "paused"
|
|
},
|
|
"totalPauseCount": {
|
|
"type": "integer",
|
|
"description": "Total number of pause points in this execution."
|
|
},
|
|
"resumedCount": {
|
|
"type": "integer",
|
|
"description": "Number of pause points that have been resumed."
|
|
},
|
|
"pausedAt": {
|
|
"type": "string",
|
|
"format": "date-time",
|
|
"nullable": true,
|
|
"description": "When the execution was paused."
|
|
},
|
|
"updatedAt": {
|
|
"type": "string",
|
|
"format": "date-time",
|
|
"nullable": true,
|
|
"description": "When the paused execution record was last updated."
|
|
},
|
|
"expiresAt": {
|
|
"type": "string",
|
|
"format": "date-time",
|
|
"nullable": true,
|
|
"description": "When the paused execution will expire and be cleaned up."
|
|
},
|
|
"metadata": {
|
|
"type": "object",
|
|
"nullable": true,
|
|
"description": "Additional metadata associated with the paused execution.",
|
|
"additionalProperties": true
|
|
},
|
|
"triggerIds": {
|
|
"type": "array",
|
|
"items": {
|
|
"type": "string"
|
|
},
|
|
"description": "IDs of triggers that initiated the original execution."
|
|
},
|
|
"pausePoints": {
|
|
"type": "array",
|
|
"items": {
|
|
"$ref": "#/components/schemas/PausePoint"
|
|
},
|
|
"description": "List of pause points in the execution."
|
|
}
|
|
}
|
|
},
|
|
"PausePoint": {
|
|
"type": "object",
|
|
"description": "A point in the workflow where execution has been paused awaiting human input.",
|
|
"properties": {
|
|
"contextId": {
|
|
"type": "string",
|
|
"description": "Unique identifier for this pause context. Used when resuming execution."
|
|
},
|
|
"blockId": {
|
|
"type": "string",
|
|
"description": "The block ID where execution paused."
|
|
},
|
|
"response": {
|
|
"description": "Data returned by the block before pausing, including display data and form fields."
|
|
},
|
|
"registeredAt": {
|
|
"type": "string",
|
|
"format": "date-time",
|
|
"description": "When this pause point was registered."
|
|
},
|
|
"resumeStatus": {
|
|
"type": "string",
|
|
"enum": ["paused", "resumed", "failed", "queued", "resuming"],
|
|
"description": "Current status of this pause point."
|
|
},
|
|
"snapshotReady": {
|
|
"type": "boolean",
|
|
"description": "Whether the execution snapshot is ready for resumption."
|
|
},
|
|
"resumeLinks": {
|
|
"type": "object",
|
|
"description": "Links for resuming this pause point.",
|
|
"properties": {
|
|
"apiUrl": {
|
|
"type": "string",
|
|
"format": "uri",
|
|
"description": "API endpoint URL to POST resume input to."
|
|
},
|
|
"uiUrl": {
|
|
"type": "string",
|
|
"format": "uri",
|
|
"description": "UI URL for a human to review and approve."
|
|
},
|
|
"contextId": {
|
|
"type": "string",
|
|
"description": "The context ID for this pause point."
|
|
},
|
|
"executionId": {
|
|
"type": "string",
|
|
"description": "The execution ID."
|
|
},
|
|
"workflowId": {
|
|
"type": "string",
|
|
"description": "The workflow ID."
|
|
}
|
|
}
|
|
},
|
|
"queuePosition": {
|
|
"type": "integer",
|
|
"nullable": true,
|
|
"description": "Position in the resume queue, if queued."
|
|
},
|
|
"latestResumeEntry": {
|
|
"$ref": "#/components/schemas/ResumeQueueEntry",
|
|
"nullable": true,
|
|
"description": "The most recent resume queue entry for this pause point."
|
|
},
|
|
"parallelScope": {
|
|
"type": "object",
|
|
"description": "Scope information when the pause occurs inside a parallel branch.",
|
|
"properties": {
|
|
"parallelId": {
|
|
"type": "string",
|
|
"description": "Identifier of the parallel execution group."
|
|
},
|
|
"branchIndex": {
|
|
"type": "integer",
|
|
"description": "Index of the branch within the parallel group."
|
|
},
|
|
"branchTotal": {
|
|
"type": "integer",
|
|
"description": "Total number of branches in the parallel group."
|
|
}
|
|
}
|
|
},
|
|
"loopScope": {
|
|
"type": "object",
|
|
"description": "Scope information when the pause occurs inside a loop.",
|
|
"properties": {
|
|
"loopId": {
|
|
"type": "string",
|
|
"description": "Identifier of the loop."
|
|
},
|
|
"iteration": {
|
|
"type": "integer",
|
|
"description": "Current loop iteration number."
|
|
}
|
|
}
|
|
}
|
|
}
|
|
},
|
|
"ResumeQueueEntry": {
|
|
"type": "object",
|
|
"description": "An entry in the resume execution queue.",
|
|
"properties": {
|
|
"id": {
|
|
"type": "string",
|
|
"description": "Unique identifier for this queue entry."
|
|
},
|
|
"pausedExecutionId": {
|
|
"type": "string",
|
|
"description": "The paused execution this entry belongs to."
|
|
},
|
|
"parentExecutionId": {
|
|
"type": "string",
|
|
"description": "The original execution that was paused."
|
|
},
|
|
"newExecutionId": {
|
|
"type": "string",
|
|
"description": "The new execution ID created for the resume."
|
|
},
|
|
"contextId": {
|
|
"type": "string",
|
|
"description": "The pause context ID being resumed."
|
|
},
|
|
"resumeInput": {
|
|
"description": "The input provided when resuming."
|
|
},
|
|
"status": {
|
|
"type": "string",
|
|
"description": "Status of this queue entry (e.g., pending, claimed, completed, failed)."
|
|
},
|
|
"queuedAt": {
|
|
"type": "string",
|
|
"format": "date-time",
|
|
"nullable": true,
|
|
"description": "When the entry was added to the queue."
|
|
},
|
|
"claimedAt": {
|
|
"type": "string",
|
|
"format": "date-time",
|
|
"nullable": true,
|
|
"description": "When execution started processing this entry."
|
|
},
|
|
"completedAt": {
|
|
"type": "string",
|
|
"format": "date-time",
|
|
"nullable": true,
|
|
"description": "When execution completed."
|
|
},
|
|
"failureReason": {
|
|
"type": "string",
|
|
"nullable": true,
|
|
"description": "Reason for failure, if the resume failed."
|
|
}
|
|
}
|
|
},
|
|
"PausedExecutionDetail": {
|
|
"type": "object",
|
|
"description": "Detailed information about a paused execution, including the execution snapshot and resume queue.",
|
|
"allOf": [
|
|
{
|
|
"$ref": "#/components/schemas/PausedExecutionSummary"
|
|
},
|
|
{
|
|
"type": "object",
|
|
"properties": {
|
|
"executionSnapshot": {
|
|
"type": "object",
|
|
"description": "Serialized execution state for resumption.",
|
|
"properties": {
|
|
"snapshot": {
|
|
"type": "string",
|
|
"description": "Serialized execution snapshot data."
|
|
},
|
|
"triggerIds": {
|
|
"type": "array",
|
|
"items": {
|
|
"type": "string"
|
|
},
|
|
"description": "Trigger IDs from the snapshot."
|
|
}
|
|
}
|
|
},
|
|
"queue": {
|
|
"type": "array",
|
|
"items": {
|
|
"$ref": "#/components/schemas/ResumeQueueEntry"
|
|
},
|
|
"description": "Resume queue entries for this execution."
|
|
}
|
|
}
|
|
}
|
|
]
|
|
},
|
|
"PauseContextDetail": {
|
|
"type": "object",
|
|
"description": "Detailed information about a specific pause context within a paused execution.",
|
|
"properties": {
|
|
"execution": {
|
|
"$ref": "#/components/schemas/PausedExecutionSummary",
|
|
"description": "Summary of the parent paused execution."
|
|
},
|
|
"pausePoint": {
|
|
"$ref": "#/components/schemas/PausePoint",
|
|
"description": "The specific pause point for this context."
|
|
},
|
|
"queue": {
|
|
"type": "array",
|
|
"items": {
|
|
"$ref": "#/components/schemas/ResumeQueueEntry"
|
|
},
|
|
"description": "Resume queue entries for this context."
|
|
},
|
|
"activeResumeEntry": {
|
|
"$ref": "#/components/schemas/ResumeQueueEntry",
|
|
"nullable": true,
|
|
"description": "The currently active resume entry, if any."
|
|
}
|
|
}
|
|
},
|
|
"ResumeResult": {
|
|
"type": "object",
|
|
"description": "Result of a synchronous resume execution.",
|
|
"properties": {
|
|
"success": {
|
|
"type": "boolean",
|
|
"description": "Whether the resume execution completed successfully."
|
|
},
|
|
"status": {
|
|
"type": "string",
|
|
"description": "Execution status.",
|
|
"enum": ["completed", "failed", "paused", "cancelled"],
|
|
"example": "completed"
|
|
},
|
|
"executionId": {
|
|
"type": "string",
|
|
"description": "The new execution ID for the resumed workflow."
|
|
},
|
|
"output": {
|
|
"type": "object",
|
|
"description": "Workflow output from the resumed execution.",
|
|
"additionalProperties": true
|
|
},
|
|
"error": {
|
|
"type": "string",
|
|
"nullable": true,
|
|
"description": "Error message if the execution failed."
|
|
},
|
|
"metadata": {
|
|
"type": "object",
|
|
"description": "Execution timing metadata.",
|
|
"properties": {
|
|
"duration": {
|
|
"type": "integer",
|
|
"description": "Total execution duration in milliseconds."
|
|
},
|
|
"startTime": {
|
|
"type": "string",
|
|
"format": "date-time",
|
|
"description": "When the resume execution started."
|
|
},
|
|
"endTime": {
|
|
"type": "string",
|
|
"format": "date-time",
|
|
"description": "When the resume execution completed."
|
|
}
|
|
}
|
|
}
|
|
}
|
|
}
|
|
},
|
|
"responses": {
|
|
"BadRequest": {
|
|
"description": "Invalid request parameters. Check the details array for specific validation errors.",
|
|
"content": {
|
|
"application/json": {
|
|
"schema": {
|
|
"type": "object",
|
|
"properties": {
|
|
"error": {
|
|
"type": "string",
|
|
"description": "Human-readable error message describing the validation failure."
|
|
},
|
|
"details": {
|
|
"type": "array",
|
|
"description": "List of specific validation errors with field-level details.",
|
|
"items": {
|
|
"type": "object"
|
|
}
|
|
}
|
|
}
|
|
}
|
|
}
|
|
}
|
|
},
|
|
"Unauthorized": {
|
|
"description": "Invalid or missing API key. Ensure the X-API-Key header is set with a valid key.",
|
|
"content": {
|
|
"application/json": {
|
|
"schema": {
|
|
"type": "object",
|
|
"properties": {
|
|
"error": {
|
|
"type": "string",
|
|
"description": "Human-readable error message."
|
|
}
|
|
}
|
|
}
|
|
}
|
|
}
|
|
},
|
|
"Forbidden": {
|
|
"description": "Access denied. You do not have permission to access this resource. For audit log endpoints, this requires an Enterprise subscription and organization admin/owner role.",
|
|
"content": {
|
|
"application/json": {
|
|
"schema": {
|
|
"type": "object",
|
|
"properties": {
|
|
"error": {
|
|
"type": "string",
|
|
"description": "Human-readable error message."
|
|
}
|
|
}
|
|
}
|
|
}
|
|
}
|
|
},
|
|
"NotFound": {
|
|
"description": "The requested resource was not found. Verify the ID is correct and belongs to your workspace.",
|
|
"content": {
|
|
"application/json": {
|
|
"schema": {
|
|
"type": "object",
|
|
"properties": {
|
|
"error": {
|
|
"type": "string",
|
|
"description": "Human-readable error message."
|
|
}
|
|
}
|
|
}
|
|
}
|
|
}
|
|
},
|
|
"RateLimited": {
|
|
"description": "Rate limit exceeded. Wait for the duration specified in the Retry-After header before retrying.",
|
|
"headers": {
|
|
"Retry-After": {
|
|
"description": "Number of seconds to wait before retrying the request.",
|
|
"schema": {
|
|
"type": "integer"
|
|
}
|
|
}
|
|
},
|
|
"content": {
|
|
"application/json": {
|
|
"schema": {
|
|
"type": "object",
|
|
"properties": {
|
|
"error": {
|
|
"type": "string",
|
|
"description": "Human-readable error message with rate limit details."
|
|
}
|
|
}
|
|
}
|
|
}
|
|
}
|
|
},
|
|
"RowsUpdated": {
|
|
"description": "Rows updated.",
|
|
"content": {
|
|
"application/json": {
|
|
"schema": {
|
|
"type": "object",
|
|
"properties": {
|
|
"success": {
|
|
"type": "boolean",
|
|
"description": "Indicates whether the request was successful."
|
|
},
|
|
"data": {
|
|
"type": "object",
|
|
"properties": {
|
|
"message": {
|
|
"type": "string",
|
|
"description": "Confirmation message describing how many rows were updated."
|
|
},
|
|
"updatedCount": {
|
|
"type": "integer",
|
|
"description": "Number of rows that were updated."
|
|
},
|
|
"updatedRowIds": {
|
|
"type": "array",
|
|
"items": {
|
|
"type": "string"
|
|
},
|
|
"description": "Array of IDs for each row that was updated."
|
|
}
|
|
},
|
|
"description": "Response payload."
|
|
}
|
|
}
|
|
},
|
|
"example": {
|
|
"success": true,
|
|
"data": {
|
|
"message": "Rows updated successfully",
|
|
"updatedCount": 2,
|
|
"updatedRowIds": ["row_abc123", "row_def456"]
|
|
}
|
|
}
|
|
}
|
|
}
|
|
}
|
|
}
|
|
}
|
|
}
|