Provision a workspace from a template
A workflow template is a ready-made workflow you can materialize into a project instead of drawing the graph yourself. Two shipped templates cover the common intake shapes:
| Slug | What it does | How it fires |
|---|---|---|
mail_intake |
Picks up incoming mail from a mailbox and starts a task per message | IMAP trigger on a mailbox resource |
scan_intake |
Sweeps a document library for new files and starts a task per document | Schedule (daily by default) |
The Management API can create these for you, so connecting a mailbox is a single request rather than a manual assembly in the builder.


Provision a mail-intake workspace
Section titled “Provision a mail-intake workspace”-
Declare the mailbox as a resource.
The resource’s
nameis the identity you refer to later — there is no separate key field, and the reference below matches the name character for character. Pick a name you are happy to type again. The password is write-only: it is never returned by a read of the workspace state.{"resources": [{"name": "workspace-mailbox","kind": "imap","config": {"host": "mail.example.com","port": 993,"username": "intake@example.com"},"secret": "the-mailbox-password"}]} -
Materialize the workflow from the template.
The IMAP trigger binds the mailbox by its id, so write the reference form
${{ resources.<name>.id }}— it is resolved against the resource you declared in step 1, in this same request, so you never paste a UUID.{"workflow_templates": [{"key": "mail-intake","project_key": "my-project","template": "mail_intake","name": "Mailbox Intake","config": {"mailbox_resource_id": "${{ resources.workspace-mailbox.id }}"}}]}Every other blank in the template has a working default, so this one line is enough to get a running mailbox intake:
configkeyDefault What it fills mailbox_resource_id(none) The mailbox to poll. Omit it and the workflow is materialized without a trigger, for you to attach one later. mailbox_folderINBOXThe folder the trigger polls. agent_typeclaudeThe agent that triages and handles each message. mailbox_labelthe connected mailboxHow the prompt refers to this mailbox. intake_purposeA generic sentence What this mailbox is for — the triage step’s yardstick. approval_noteA generic sentence Extra guidance shown to the human approver. handling_instructionsHouse rules about not disclosing credentials How the handler should carry out an approved action. -
Send both blocks in one request.
Terminal window curl -X PUT \-H "Authorization: Bearer $SUPACLOUD_MANAGEMENT_TOKEN" \-H "Content-Type: application/json" \--data @workspace-state.json \https://app.example.com/api/management/v1/workspaces/my-workspace/stateThe blocks apply in a fixed order — resources, then projects, then workflow templates, then triggers and schedules — so everything a later block refers to already exists.
Provision a document-scan workspace
Section titled “Provision a document-scan workspace”The scan template works against a document library instead of a mailbox, and it binds that library by plain name — not by id. Its two program steps reach the library through a binding that is resolved by resource name, so write the name itself, exactly as declared:
{ "resources": [ { "name": "document-library", "kind": "seafile_webdav", "config": { "base_url": "https://seafile.example.com/seafdav", "user": "scanner@example.com", "library_path": "/Documents", "repo_name": "Documents" }, "secret": "the-seafile-password" } ], "workflow_templates": [ { "key": "scan-intake", "project_key": "my-project", "template": "scan_intake", "config": { "library_resource": "document-library", "scan_folder": "/Inbox", "archive_folder": "/Archive" } } ]}config key |
Default | What it fills |
|---|---|---|
library_resource |
scans |
The name of the seafile_webdav resource to sweep. A name no resource has fails the request. |
scan_folder |
/Inbox |
The drop folder that is swept. |
archive_folder |
/Archive |
Where a confirmed batch is moved to. |
file_extensions |
.pdf,.jpg,.jpeg,.png,.tif,.tiff |
Which files count as documents. |
lookback_minutes |
1440 |
How far back a sweep looks for new files. |
review_note |
A generic sentence | Extra guidance shown to the human confirming a batch. |
The library resource carries two location fields, and the scan template needs both kinds of information:
config field |
Required | What reads it |
|---|---|---|
base_url |
yes | The WebDAV/Seafile host. It is also the only host the two program steps may reach. |
user |
yes | The Seafile account the steps authenticate as. |
library_path |
yes | The WebDAV path of the library, required by the seafile_webdav resource kind. |
repo_name |
one of the two | The library’s display name. The steps look the library up by it. |
repo_id |
one of the two | The library’s id, if you already know it. Set it and repo_name is not consulted. |
web_base_url |
no | The Seafile web host, when it differs from base_url. |
Give either repo_name or repo_id. With neither, the resource is still
accepted — the two fields are optional to the resource kind — but the first sweep
fails with Seafile library is not resolvable by name: ''.
Because a document library has no push notification, this template runs on a
schedule rather than a trigger. Add its cadence with a workflow_schedules
entry naming the materialized workflow — Scan intake unless you set a name
override on the template entry:
{ "workflow_schedules": [ { "key": "scan-sweep", "project_key": "my-project", "workflow": "Scan intake", "cadence": "daily", "timezone": "Europe/Berlin", "next_run_at": "2026-09-01T06:00:00Z" } ]}What re-applying does
Section titled “What re-applying does”Applying the same document again is safe and does nothing:
- A template whose workflow already exists reports
changed: false. The apply never overwrites your edits — once the workflow is materialized, the graph belongs to you, so you can freely adjust it in the builder. - Removing an entry from the document does not delete the workflow. Every list in the workspace state is additive; deletion is always an explicit action.
- Renaming the workflow is safe. Reconciliation uses the
keyyou chose, not the display name.
What a config value may contain
Section titled “What a config value may contain”A config value fills one blank in the shipped template — a folder, a label, a
sentence of guidance. The template is read as a document first, and your value
is then placed into the single blank it belongs to, so it stays one piece of text:
it cannot add a step, rename a field, or reach a second blank, whatever it
contains. A config key that names no blank in the template fills nothing.
Two things a value still cannot do, because they are about what reads it
afterwards rather than about the document. Both are checked before anything is
created, and a value that fails one fails the request with 400, naming the key:
- The scan template’s program. Its two steps run a small program against your
library, with the library’s credential in reach, and a few blanks sit inside
that program’s text (
scan_folder,archive_folder,file_extensions,lookback_minutes). A value there may not contain"or\, which would end the quoted text it is placed into. - A second template marker. No value may contain
${{ … }}. Prompts and program text are filled in again while the workflow runs, so a marker smuggled through now would be expanded later against live data. The single exception is the${{ resources.<name>.id }}reference form, which is resolved into a UUID before the value reaches the template at all.
Two more rules round it off: keep each value on one line (a line break is refused rather than reinterpreted — put longer guidance in the builder afterwards), and keep it under 8192 characters.
Neither template is applied automatically
Section titled “Neither template is applied automatically”New projects do not receive these workflows. Both templates are opt-in — through this block or the picker — so adding them changes nothing for projects that already exist.