Skip to content
Select themeSelect language

Handler: clone the repo, scan it, apply the plan, return the report.

POST
/api/workflows/import/windmill/repo
curl --request POST \
--url https://example.com/api/workflows/import/windmill/repo \
--header 'Content-Type: application/json' \
--cookie supacloud_session=<supacloud_session> \
--data '{ "credential_id": "2489E9AD-2EE2-8E00-8EC9-32D5F69181C0", "db_resource": "example", "git_ref": "example", "git_url": "example", "project_id": "2489E9AD-2EE2-8E00-8EC9-32D5F69181C0" }'
Media typeapplication/json

POST /api/workflows/import/windmill/repo body.

object
credential_id

Optional git_credentials row id (an access_token credential) whose token is the HTTPS PAT used for the clone. DB-backed + workspace-pickable, so it works on the env-only secret backend. Omit for a public repo.

string | null format: uuid
db_resource

Optional postgresql resources row (by NAME or UUID) the repo’s shared db namespace (db/migrations/) binds to (ADR 0057). This is the one deployment-specific fact a generic windmill repo can’t carry — picked in the wizard — so it binds the INFERRED namespace and overrides any repo-authored db/namespace.yaml resource. Omit when the repo has no db/migrations/, or carries a self-contained db/namespace.yaml.

string | null
git_ref

Branch to clone. Defaults to main when omitted.

string | null
git_url
required

HTTPS clone URL of the windmill-workflows repo.

string
project_id
required

The project the imported workflows are created in.

string format: uuid
Examplegenerated
{
"credential_id": "2489E9AD-2EE2-8E00-8EC9-32D5F69181C0",
"db_resource": "example",
"git_ref": "example",
"git_url": "example",
"project_id": "2489E9AD-2EE2-8E00-8EC9-32D5F69181C0"
}

Per-flow import report

Media typeapplication/json

The full result of applying an ImportPlan to a project.

object
blocked
required

Flows the scanner could not convert (surfaced through from the plan).

Array<object>

A flow the scanner could not convert at all (surfaced straight through from ImportPlan::blocked so the operator sees the whole picture in one report).

object
reason
required
string
source_path
required
string
db_namespace
One of:
null
detected_apps
required

Raw-apps detected but not persisted (same-slug clash / persist error).

Array<object>

A raw-app detected but NOT persisted (e.g. a same-slug App already exists, or the persist failed). Carries the operator-facing note + a reason.

object
name
required
string
note
required
string
reason
required
string
source_path
required
string
detected_http_triggers
required

HTTP triggers detected — DETECT-only, the operator re-wires them.

Array<object>

A generic DETECT-and-record item (HTTP trigger / schedule) the operator must re-wire by hand — SupaCloud has no 1:1 import for these.

object
name
required
string
note
required
string
source_path
required
string
detected_schedules
required

Schedules detected — DETECT-only, the operator re-creates them.

Array<object>

A generic DETECT-and-record item (HTTP trigger / schedule) the operator must re-wire by hand — SupaCloud has no 1:1 import for these.

object
name
required
string
note
required
string
source_path
required
string
failed
required

Flows that converted but failed to persist (one bad flow, rest continue).

Array<object>

A flow that converted but failed to persist (a per-flow error — the rest of the plan still imports). Distinct from the scanner’s blocked (failed to convert).

object
reason
required
string
source_path
required
string
imported
required

Flows that persisted as new workflows.

Array<object>

One flow that persisted into the project.

object
fidelity
required

The scanner’s fidelity badge, as a stable lowercase label (clean | needs_rebind | blocked) — keeps the report serializable without making the internal Fidelity enum Serialize.

string
name
required
string
source_path
required
string
warnings
required
Array<string>
workflow_id
required
string format: uuid
imported_apps
required

Raw-apps that persisted as React Apps.

Array<object>

A raw-app that persisted as a SupaCloud App (framework = react).

object
app_id
required
string format: uuid
file_count
required

Number of source files written into the App’s app_files tree.

integer
name
required
string
source_path
required
string
imported_scripts
required

First-class scripts imported as SupaCloud Script rows (never dropped).

Array<object>

A first-class Windmill script imported as a SupaCloud Script row. Carries the LOUD needs_mapping review notes (windmill APIs the source uses that must be adapted before it runs on the substrate) — the importer surfaces the script, it never silently drops it.

object
name
required

The display name the Script row was created with.

string
needs_mapping
required

Windmill-specific APIs to adapt before the script runs (empty ⇒ none flagged).

Array<string>
script_id
required

The created Script row id.

string format: uuid
source_path
required

The windmill script path (f/shared/finance_overview).

string
needs_mapping
required

Custom resource types an operator must wire (not auto-created).

Array<object>

A custom resource type the operator must wire to a SupaCloud resource/credential before its flows can run. We never auto-create credentials, so each resource type is surfaced here, not applied.

object
name
required
string
source_path
required
string
per_app_db
required

The per-App installs of the repo’s shared schema into each imported App’s own app_<id> schema (#626 §14 — the built-in App DB path). Empty unless the import bound the built-in App DB and the repo ships db/migrations/.

Array<object>

The result of installing a repo’s shared schema into ONE imported App’s own per-App app_<id> schema (built-in App DB path).

object
app_id
required

The App the schema was installed into.

string format: uuid
app_name
required

The App’s display name (echoed for the report).

string
applied
required

Migration names newly applied into this App’s schema this run.

Array<string>
failed
required

Per-migration failures (a failure blocks the rest — append-only migrations are ordered, so a mid-set failure would mis-attribute if we continued).

Array<object>

One migration (or resolution step) that failed during a namespace import.

object
name
required
string
reason
required
string
schema
required

The per-App schema the repo migrations were applied to (app_<id>); empty only when the very first migration failed before any apply resolved it.

string
skipped
required

Flows skipped because a same-named workflow already exists in the project.

Array<object>

A flow skipped because a workflow with the same name already exists in the project (idempotent re-import — cheap skip-by-name, no duplicate row).

object
name
required
string
reason
required
string
source_path
required
string
skipped_scripts
required

First-class scripts detected but not imported (idempotent same-slug skip / unsupported-language create error) — surfaced, never silently dropped.

Array<object>

A first-class script detected but NOT imported — an idempotent same-slug skip on re-import, or a create error (e.g. a language not yet supported as a standalone Script). Surfaced so the operator sees it; NEVER silently dropped.

object
name
required
string
reason
required
string
source_path
required
string
Examplegenerated
{
"blocked": [
{
"reason": "example",
"source_path": "example"
}
],
"db_namespace": {
"applied": [
"example"
],
"failed": [
{
"name": "example",
"reason": "example"
}
],
"handle": "example",
"namespace_id": "2489E9AD-2EE2-8E00-8EC9-32D5F69181C0",
"recorded": [
"example"
],
"schema": "example"
},
"detected_apps": [
{
"name": "example",
"note": "example",
"reason": "example",
"source_path": "example"
}
],
"detected_http_triggers": [
{
"name": "example",
"note": "example",
"source_path": "example"
}
],
"detected_schedules": [
{
"name": "example",
"note": "example",
"source_path": "example"
}
],
"failed": [
{
"reason": "example",
"source_path": "example"
}
],
"imported": [
{
"fidelity": "example",
"name": "example",
"source_path": "example",
"warnings": [
"example"
],
"workflow_id": "2489E9AD-2EE2-8E00-8EC9-32D5F69181C0"
}
],
"imported_apps": [
{
"app_id": "2489E9AD-2EE2-8E00-8EC9-32D5F69181C0",
"file_count": 1,
"name": "example",
"source_path": "example"
}
],
"imported_scripts": [
{
"name": "example",
"needs_mapping": [
"example"
],
"script_id": "2489E9AD-2EE2-8E00-8EC9-32D5F69181C0",
"source_path": "example"
}
],
"needs_mapping": [
{
"name": "example",
"source_path": "example"
}
],
"per_app_db": [
{
"app_id": "2489E9AD-2EE2-8E00-8EC9-32D5F69181C0",
"app_name": "example",
"applied": [
"example"
],
"failed": [
{
"name": "example",
"reason": "example"
}
],
"schema": "example"
}
],
"skipped": [
{
"name": "example",
"reason": "example",
"source_path": "example"
}
],
"skipped_scripts": [
{
"name": "example",
"reason": "example",
"source_path": "example"
}
]
}

Structured client error

Media typeapplication/json

The canonical JSON body of every error response — the single source of truth the frontend binds to. Every AppError serializes as this exact shape, and the generated OpenAPI component ApiErrorBody (with its ErrorCode enum) is what the frontend error schema is generated from, so there is no hand-written error schema on either end.

object
code
required

Machine-readable, stable error code.

string
Allowed values: not_found unauthorized forbidden bad_request unprocessable precondition_failed conflict method_not_allowed rate_limited quota_exceeded database_error docker_error vault_error internal_error
details
One of:
null
error
required

Human-readable message (the server’s English text; the client may localize by code).

string
Example
{
"code": "not_found"
}

Authentication required

Media typeapplication/json

The canonical JSON body of every error response — the single source of truth the frontend binds to. Every AppError serializes as this exact shape, and the generated OpenAPI component ApiErrorBody (with its ErrorCode enum) is what the frontend error schema is generated from, so there is no hand-written error schema on either end.

object
code
required

Machine-readable, stable error code.

string
Allowed values: not_found unauthorized forbidden bad_request unprocessable precondition_failed conflict method_not_allowed rate_limited quota_exceeded database_error docker_error vault_error internal_error
details
One of:
null
error
required

Human-readable message (the server’s English text; the client may localize by code).

string
Example
{
"code": "not_found"
}

Permission denied

Media typeapplication/json

The canonical JSON body of every error response — the single source of truth the frontend binds to. Every AppError serializes as this exact shape, and the generated OpenAPI component ApiErrorBody (with its ErrorCode enum) is what the frontend error schema is generated from, so there is no hand-written error schema on either end.

object
code
required

Machine-readable, stable error code.

string
Allowed values: not_found unauthorized forbidden bad_request unprocessable precondition_failed conflict method_not_allowed rate_limited quota_exceeded database_error docker_error vault_error internal_error
details
One of:
null
error
required

Human-readable message (the server’s English text; the client may localize by code).

string
Example
{
"code": "not_found"
}

Structured server error

Media typeapplication/json

The canonical JSON body of every error response — the single source of truth the frontend binds to. Every AppError serializes as this exact shape, and the generated OpenAPI component ApiErrorBody (with its ErrorCode enum) is what the frontend error schema is generated from, so there is no hand-written error schema on either end.

object
code
required

Machine-readable, stable error code.

string
Allowed values: not_found unauthorized forbidden bad_request unprocessable precondition_failed conflict method_not_allowed rate_limited quota_exceeded database_error docker_error vault_error internal_error
details
One of:
null
error
required

Human-readable message (the server’s English text; the client may localize by code).

string
Example
{
"code": "not_found"
}