> Discover all available pages from the documentation index: https://mastra.ai/llms.txt # Dynamic workflows > **Beta:** This feature is in beta. Breaking changes may occur without a major version bump until the API is stable. Dynamic workflows are workflow definitions expressed as data instead of code. A definition is a JSON document that describes the workflow's schemas and step graph. Mastra validates the definition and registers it as a runnable workflow, then persists it in storage so it survives process restarts. Because a definition contains no JavaScript closures, anything that can produce JSON can author a workflow: an HTTP client, an LLM, a visual editor, or your own tooling. Once registered, a dynamic workflow runs through the same execution API as a code-defined workflow. ## When to use dynamic workflows Use dynamic workflows when users, agents, visual editors, or external systems need to create workflows without changing application code or deploying again. Keep defining workflows with [`createWorkflow()`](https://mastra.ai/docs/workflows/overview) when the workflow belongs in your application source or needs custom step functions. Dynamic workflows can invoke agents, tools, and workflows that are already registered on the `Mastra` instance. ## Quickstart The following example registers a tool and invokes it from a dynamic workflow. It then runs the workflow. `LibSQLStore` persists the definition in `mastra.db`, so Mastra can restore it after a restart. ```typescript import { Mastra } from '@mastra/core/mastra' import { createTool } from '@mastra/core/tools' import { LibSQLStore } from '@mastra/libsql' import { z } from 'zod' const greetingTool = createTool({ id: 'create-greeting', description: 'Create a greeting for a name', inputSchema: z.object({ name: z.string(), }), outputSchema: z.object({ message: z.string(), }), execute: async ({ name }) => ({ message: `Hello, ${name}!`, }), }) const mastra = new Mastra({ storage: new LibSQLStore({ id: 'mastra-storage', url: 'file:./mastra.db', }), tools: { 'create-greeting': greetingTool }, }) await mastra.addDynamicWorkflow({ id: 'greeting-workflow', description: 'Create a greeting for the supplied name', inputSchema: { type: 'object', properties: { name: { type: 'string' }, }, required: ['name'], }, outputSchema: { type: 'object', properties: { message: { type: 'string' }, }, required: ['message'], }, graph: [ { type: 'tool', id: 'greet', toolId: 'create-greeting', }, ], }) const workflow = mastra.getWorkflow('greeting-workflow') const run = await workflow.createRun() const result = await run.start({ inputData: { name: 'Ada' }, }) if (result.status === 'success') { console.log(result.result.message) } ``` The workflow prints `Hello, Ada!`. Calling [`addDynamicWorkflow()`](https://mastra.ai/reference/core/addDynamicWorkflow) validates the definition before it changes storage or the live workflow registry. The definition uses JSON Schema because it must survive a JSON round trip. The `graph` describes which registered components to invoke and how data moves between them. See the [dynamic workflow definition reference](https://mastra.ai/reference/workflows/dynamic-workflow-definition) for every field and graph entry. ## Build and update definitions A definition can come from any source that produces JSON. For example, an API route can accept a definition created by a visual editor and register it directly: ```typescript const definition = await request.json() await mastra.addDynamicWorkflow(definition) ``` ### Register dependencies first Register referenced components on the same `Mastra` instance before adding the dynamic workflow. Agent and nested workflow entries use their intrinsic IDs. A tool entry uses its key from the `Mastra` `tools` object, so the quickstart registers the tool under `create-greeting` before referencing that key with `toolId`. Use a `mapping` entry when one step's output doesn't match the next step's input. Mapping entries can read data from the workflow input and previous step results, along with workflow state and request context. The [definition reference](https://mastra.ai/reference/workflows/dynamic-workflow-definition) lists the supported mapping descriptors. ### Replace a workflow Add a new definition with the same `id` to replace the persisted definition and live registration: ```typescript await mastra.addDynamicWorkflow(updatedDefinition) ``` New runs use the updated graph. Runs that already started continue with their original graph. ### Add nested workflows together When a root workflow references helper workflows that aren't registered yet, add the full set with [`addDynamicWorkflows()`](https://mastra.ai/reference/core/addDynamicWorkflows): ```typescript await mastra.addDynamicWorkflows([rootDefinition, helperDefinition]) ``` Mastra validates the bundle as a unit and determines the registration order from the dependencies. If validation fails, none of the definitions are registered. ### Manage definitions over HTTP Applications don't need direct access to the `Mastra` instance to manage dynamic workflows. Use one of these interfaces: - [Client SDK workflows API](https://mastra.ai/reference/client-js/workflows): Call `upsertDynamicWorkflow()` from a JavaScript or TypeScript client. - [Server routes](https://mastra.ai/reference/server/routes): Send definitions to `POST /api/stored/workflows`. On authenticated servers, dynamic-workflow management requires the `stored-workflows:read` and `stored-workflows:write` permissions. Running the registered workflow requires `workflows:execute`. ### Persist definitions Stored definitions use the `workflowDefinitions` storage domain. On startup, Mastra loads active definitions from storage and registers them in dependency order. Without a storage adapter that supports this domain, `addDynamicWorkflow()` still registers the workflow in memory, but the definition is lost when the process restarts. See the [storage reference](https://mastra.ai/reference/storage/overview) for adapter support. ## Related - [Dynamic workflow definition](https://mastra.ai/reference/workflows/dynamic-workflow-definition) - [`Mastra.addDynamicWorkflow()`](https://mastra.ai/reference/core/addDynamicWorkflow) - [`Mastra.addDynamicWorkflows()`](https://mastra.ai/reference/core/addDynamicWorkflows) - [Client SDK workflows API](https://mastra.ai/reference/client-js/workflows) - [Server routes](https://mastra.ai/reference/server/routes)