Develop
Blueprints
A blueprint is a desired project shape that Mobius can apply through the API. It describes resources that should exist in a project.
Blueprints can create or adopt actions, toolkits, skills, agents, loops, and tables. Apply records a binding from each blueprint key to the Mobius resource it creates or adopts, so the same blueprint can be applied again without creating duplicates.
Use blueprints to start a project from a working template, or when an external system needs to provision the same Mobius setup across many projects. Use the normal resource pages or CLI commands when you only need to author one resource.
For one project, you can preview and apply a blueprint from Build > Blueprints in the app. For terminal workflows, use the CLI command reference. This page owns the HTTP contract for services that provision Mobius projects.
What apply does
POST /v1/projects/{project_handle}/blueprints/apply accepts one desired
resource graph and a mode:
| Mode | What happens |
|---|---|
preview | Mobius validates references and returns the changes it would make. No resources are mutated. |
apply | Mobius creates missing resources, updates resources already managed by the blueprint, and adopts uniquely named unmanaged resources when that is safe. |
Always run preview first. It catches missing references and name conflicts
before the request changes the project.
Apply is idempotent, not a transaction across the whole blueprint. Mobius writes each resource together with its binding, but a failure in a later resource tier can leave earlier resources persisted. Re-apply the same blueprint after fixing the input; Mobius uses the bindings to converge instead of duplicating work.
Keys, names, and bindings
Every blueprint resource has a key. The key is local to the blueprint and is
how other resources in the same apply refer to it:
{
"agent": { "key": "triage" }
}The created Mobius resource gets its normal ID, such as agt_... or
loop_.... Mobius stores the mapping in a binding:
{
"resource_type": "agent",
"key": "triage",
"resource_id": "agt_01...",
"protected": false,
"delete_on_destroy": true
}namespace and blueprint_key identify one applied blueprint. Local resource
keys are scoped to that identity, so two named blueprints can both use a key
such as agent without taking over each other's bindings. blueprint_version
is provenance for the template version that last wrote a binding.
The fields remain optional for compatibility, but set blueprint_key on any
blueprint whose protection or deletion lifecycle you want Mobius to manage.
Resource references
Blueprint resources can point at another resource three ways:
| Shape | Resolves to |
|---|---|
{ "id": "agt_01..." } | An existing Mobius resource by ID. |
{ "key": "triage" } | A resource in this apply request, or an existing binding with the same key. |
{ "blueprint_ref": { "namespace": "acme", "key": "triage" } } | A binding created by another namespaced blueprint. |
Use key inside one blueprint. Use blueprint_ref only when one blueprint
extends resources created by another blueprint.
Resource configuration
Blueprint resources support the complete user-authored create/update contract for their underlying resource:
| Resource | Configurable attributes |
|---|---|
| Action | Name, title, description, endpoint kind and URL, input/output schemas, annotations, and tags. Blueprint uses type and endpoint for the endpoint fields. |
| Toolkit | Name, description, canonical action selectors, and tags. action_name remains available as a legacy exact-selector alias. |
| Skill | Name, title, description, instructions, allowed_tools, and tags. |
| Agent | Name, description, color, model, model route, tool presentation, system prompt, timeout, status, compaction policy, thinking effort, tags, toolkit assignments, and skill assignments. |
| Loop | Name, description, agent, status, schema version, event/config contracts, concurrency, triggers, repositories, steps, output, cleanup, limits, defaults, run naming, default config, settings, and tags. |
| Table | Name, description, instructions, and the full table schema. |
Server-owned IDs, organization/project scope, principals, timestamps, audit actors, generated inbox addresses, signing secrets, provenance, and deletion markers are intentionally not configurable.
Example blueprint
This blueprint creates four resources:
- one toolkit,
- one table,
- one agent,
- one draft loop.
Save it as triage-blueprint.json:
{
"namespace": "acme",
"blueprint_key": "github-triage",
"blueprint_version": "2026-07-01",
"mode": "preview",
"resources": {
"toolkits": [
{
"key": "triage_tables",
"name": "Triage tables",
"description": "Read and write the shared triage results table.",
"actions": [
{ "selector_type": "exact", "selector": "mobius.table.get_table" },
{ "selector_type": "exact", "selector": "mobius.table.find_rows" },
{ "selector_type": "exact", "selector": "mobius.table.save_row" }
]
}
],
"tables": [
{
"key": "triage_results",
"name": "triage_results",
"description": "Classifications written by the triage loop.",
"instructions": "Store one row per GitHub issue URL.",
"schema": {
"columns": [
{ "name": "issue_url", "type": "string", "required": true },
{ "name": "label", "type": "string" },
{ "name": "severity", "type": "string" },
{ "name": "summary", "type": "string" }
],
"identity_column": "issue_url"
}
}
],
"agents": [
{
"key": "triage",
"name": "Triage",
"model": "claude-sonnet-4-6",
"model_route": { "mode": "managed" },
"tool_presentation": "meta",
"timeout_seconds": 600,
"thinking_effort": "medium",
"system_prompt": "Classify inbound engineering issues for Acme.",
"toolkits": [{ "key": "triage_tables" }]
}
],
"loops": [
{
"key": "triage_issues",
"name": "triage-issues",
"description": "Classify new GitHub issues and return a label.",
"schema_version": "1",
"agent": {
"key": "triage"
},
"status": "draft",
"run_name": {
"template": "GitHub issue triage"
},
"default_config": {
"write_results": true
},
"settings": {
"owner": "engineering"
},
"tags": {
"workflow": "issue-triage"
},
"triggers": [
{
"key": "manual",
"kind": "manual",
"enabled": true
}
],
"steps": [
{
"id": "classify",
"name": "Classify issue",
"kind": "agent",
"config": {
"instructions": "Classify the issue from the run input. Return JSON with label, severity, and summary."
}
}
],
"output": {
"label": "${{ steps.classify.output.label }}",
"severity": "${{ steps.classify.output.severity }}",
"summary": "${{ steps.classify.output.summary }}"
}
}
]
}
}The loop lands as draft on purpose. Activate it only after a preview or test
run shows the shape you expect.
Apply through the API
Send the request body to POST /v1/projects/{project}/blueprints/apply with a
project-scoped API key.
Use mode: "preview" first, then send the same body with mode: "apply".
Bindings are available at
GET /v1/projects/{project}/blueprints/bindings?namespace=acme.
Protect and delete an applied blueprint
Set protect_resources: true on Apply, or change protection later:
curl --request PUT \
--url "$MOBIUS_API_URL/v1/projects/ridgeline/blueprints/github-triage/protection?namespace=acme" \
--header "Authorization: Bearer $MOBIUS_API_KEY" \
--header "Content-Type: application/json" \
--data '{"protected":true}'Protection blocks ordinary definition changes and deletion for the blueprint's actions, toolkits, skills, agents, loops, and tables. Blueprint Apply can still converge them. Runtime work such as loop runs, sessions, table rows, and agent memory remains available.
Delete the applied blueprint as one unit:
curl --request DELETE \
--url "$MOBIUS_API_URL/v1/projects/ridgeline/blueprints/github-triage?namespace=acme" \
--header "Authorization: Bearer $MOBIUS_API_KEY"Mobius deletes resources it created in reverse dependency order. Resources it
adopted are retained and unbound. Bindings created before lifecycle ownership
tracking are also retained because Mobius cannot safely infer whether it
created or adopted those resources. The response lists deleted and retained
resources.
To deliberately include retained resources in teardown, add
delete_retained=true to the request URL. Inspect the blueprint bindings first:
retained resources may have been adopted and can contain customer-authored
data. The parameter defaults to false, and the Managed resources UI leaves the
equivalent option unchecked.
Deletion commits one resource at a time. If a later resource cannot be removed,
list bindings again with the same namespace and blueprint_key to see what
remains, then retry the same request after resolving the conflict. Remaining
bindings let the retry continue without repeating completed work.
Omitting namespace on deletion targets only an unnamespaced blueprint. It
does not delete every blueprint with the same key across all namespaces.
For exact request and response schemas, see the interactive reference for blueprints.
FAQ
Does removing a resource from the blueprint delete it?
No. Removing one entry from a later Apply does not delete the Mobius resource. Blueprints converge desired resources that are present in the request. Use the applied blueprint's delete operation when the complete managed shape should leave the project.
Can a blueprint update an unmanaged resource?
Only when Mobius can safely adopt a uniquely named resource. After adoption, the binding marks that resource as managed by the blueprint key. If a name matches more than one candidate, or if changing the resource would violate an immutability rule, apply returns a conflict.
Can I apply several blueprints to one project?
Yes. Use namespace and blueprint_key to give each applied blueprint a stable
identity. Their local resource keys may overlap. One underlying Mobius resource
can belong to only one blueprint, so attempting to adopt a resource already
managed by another blueprint returns a conflict.
Why did apply create some resources before failing?
Apply writes each resource and binding tier by tier. A later conflict can leave earlier tiers in place. Fix the request and re-apply; the existing bindings are what make the retry converge.
Next
- Loops explains the loop fields used inside blueprint loop resources.
- Agents explains model, toolkits, skills, and principal access.
- API introduction covers authentication, project scope, errors, and pagination.