The API Layer provides the REST and streaming interfaces for all client-server communication in the Sim platform. It implements Next.js API routes with hybrid authentication, workspace-based authorization, comprehensive request validation, and observability. This document covers authentication patterns, authorization mechanisms, request/response handling, and the organization of API endpoints.
For database schema details, see Database Schema. For real-time collaboration via WebSocket, see Real-time Collaboration System. For workflow execution APIs specifically, see Workflow Execution Engine.
The API layer is organized using Next.js file-based routing under apps/sim/app/api/. Routes follow REST conventions with HTTP verbs (GET, POST, PUT, DELETE) mapped to handler functions exported from route.ts files. The API utilizes a withRouteHandler wrapper to provide consistent error handling and logging apps/sim/app/api/workflows/[id]/state/route.ts:36.
Sources: apps/sim/app/api/workflows/route.ts23-140 apps/sim/app/api/workflows/[id]/route.ts:30-169, apps/sim/app/api/workflows/[id]/state/route.ts:36-106, apps/sim/app/api/schedules/route.ts27-199 apps/sim/app/api/workspaces/route.ts31-173
All route handlers export async functions matching HTTP verbs. The system uses a "Normalized Tables" approach where workflow data is split across workflow_blocks, workflow_edges, and workflow_subflows rather than a single JSON blob.
| HTTP Method | Export Name | Key Logic / Function |
|---|---|---|
| GET | export const GET | loadWorkflowFromNormalizedTables apps/sim/app/api/workflows/[id]/state/route.ts:58 |
| PUT | export const PUT | saveWorkflowToNormalizedTables apps/sim/app/api/workflows/[id]/state/route.ts:160 |
| POST | export const POST | parseRequest and contract validation apps/sim/app/api/workflows/[id]/state/route.ts:120 |
| DELETE | export const DELETE | performDeleteWorkflow apps/sim/app/api/workflows/[id]/route.ts:186 |
Sources: apps/sim/app/api/workflows/[id]/state/route.ts:36-178, apps/sim/app/api/workflows/[id]/route.ts:1-200
The API layer supports multiple authentication mechanisms unified through hybrid authentication helpers.
| Mechanism | Use Case | Implementation |
|---|---|---|
| Session | User browser requests | getSession() via Better Auth apps/sim/app/api/workspaces/route.ts32 |
| API Key | External/SDK access | authenticateApiKeyFromHeader apps/sim/app/api/workflows/middleware.ts112 |
| Hybrid | Mixed access | checkHybridAuth apps/sim/app/api/workflows/[id]/route.ts:37 |
| Internal JWT | Service-to-service calls | checkSessionOrInternalAuth apps/sim/app/api/workflows/[id]/state/route.ts:41 |
The checkHybridAuth and checkSessionOrInternalAuth functions determine the identity and permission level of the caller, supporting both standard user sessions and Internal JWTs for system operations.
Sources: apps/sim/app/api/workflows/[id]/route.ts:37-85, apps/sim/app/api/workflows/[id]/state/route.ts:41-53
A critical part of the API layer is the synchronization of workflow state between the client-side Zustand stores and the PostgreSQL database.
When a user edits a workflow on the canvas, the client (via React Query mutations) sends a PUT request to /api/workflows/[id]/state.
putWorkflowNormalizedStateContract using parseRequest apps/sim/app/api/workflows/[id]/state/route.ts:120-122.sanitizeAgentToolsInBlocks apps/sim/app/api/workflows/[id]/state/route.ts:156-158.saveWorkflowToNormalizedTables apps/sim/app/api/workflows/[id]/state/route.ts:160-176.workflow:state_updated event via Socket.io to keep other collaborative clients in sync apps/sim/app/api/workflows/[id]/state/route.ts:182-192.React Query hooks like useWorkflowState and useWorkflows bridge the UI to these endpoints.
Sources: apps/sim/hooks/queries/workflows.ts53-81 apps/sim/app/api/workflows/[id]/state/route.ts:36-91
API routes are strictly gated by workspace membership and role-based permissions.
authorizeWorkflowByWorkspacePermission checks if the user has read or write access for a specific workflow apps/sim/app/api/workflows/[id]/state/route.ts:46-53.verifyWorkspaceMembership ensures the user belongs to the workspace containing the requested resources apps/sim/app/api/workflows/route.ts57assertWorkflowMutable(workflowId) ensures the workflow is not in a locked state (e.g., currently deployed) before allowing updates apps/sim/app/api/workflows/[id]/state/route.ts:148.assertFolderMutable prevents operations in locked folders apps/sim/app/api/workflows/[id]/route.ts:5.Sources: apps/sim/app/api/workflows/[id]/state/route.ts:46-148, apps/sim/app/api/workflows/route.ts57-67 apps/sim/app/api/workflows/[id]/route.ts:170-185
The API layer is protected by centralized validation logic and security configurations.
The validateWorkflowAccess utility is used across various endpoints to perform a standard check of:
Request parsing is strictly typed using Zod contracts. The parseRequest helper ensures that only valid data reaches the business logic apps/sim/app/api/workflows/[id]/state/route.ts:120.
The API layer interacts with the PostgreSQL database via Drizzle ORM, often utilizing transactions to ensure data consistency across normalized tables.
| Table Name | Code Entity | Role |
|---|---|---|
workflow | workflow | Stores metadata, variables, and high-level workflow properties apps/sim/app/api/workflows/[id]/state/route.ts:2 |
workflow_folder | workflowFolder | Manages hierarchical organization of workflows apps/sim/app/api/workflows/route.ts3 |
workflow_schedule | workflowSchedule | Manages scheduled execution jobs and standalone tasks apps/sim/app/api/schedules/route.ts3 |
workspace | workspace | Defines the primary multi-tenant boundary apps/sim/app/api/workspaces/route.ts3 |
Sources: apps/sim/app/api/workflows/[id]/state/route.ts:1-23, apps/sim/app/api/schedules/route.ts1-10 apps/sim/app/api/workspaces/route.ts1-10
Refresh this wiki