Promote Workflow configuration between environments
FastHook does not currently provide a Workflow export/import dialog or a one-click cross-team promotion. Promotion is an explicit API procedure: retrieve the reviewed graph, replace environment-owned references, create a new destination Workflow in draft, and validate it before activation.
What the Workflow response contains
GET /v1/workflows/:id returns Workflow metadata, source_id, the current version, and the complete steps and edges graph. Build the create body from only:
{
"name": "[staging] Notify on failed payment",
"description": "Promoted from development release rel_2026_08_27_01",
"source_id": "src_staging",
"status": "draft",
"steps": [],
"edges": []
}Do not send response-only fields such as id, team_id, version, source, counts, timestamps, or capabilities to the create endpoint. A successfully created Workflow starts at version 1.
Always set status: "draft" explicitly. The API defaults a new Workflow to active when status is omitted.
Build a promotion manifest
Keep a reviewed, non-secret manifest beside the release record:
{
"release_id": "rel_2026_08_27_01",
"source": {
"team_id": "tm_development",
"workflow_id": "wfl_development",
"workflow_version": 12
},
"destination": {
"team_id": "tm_staging",
"source_id": "src_staging",
"workflow_name": "[staging] Notify on failed payment"
},
"resource_ids": {
"dst_development_alerts": "dst_staging_alerts",
"flt_development_supported_currency": "flt_staging_supported_currency",
"trn_development_normalize_payment": "trn_staging_normalize_payment"
},
"connected_accounts": {
"Slack Action": "staging workspace",
"Stripe Trigger": "staging account"
}
}The labels under connected_accounts are review evidence, not API replacements. Provider Action configuration must refer to an account available to the destination team. Never put access tokens, refresh tokens, signing secrets, API keys, or webhook credentials in the manifest.
Remap team-scoped references
Replace references according to Step kind:
| Reference | Promotion rule |
| --- | --- |
| Workflow source_id | Replace with a Source owned by the destination team |
| Destination Step resource_id | Replace with a destination-team Destination ID |
| Filter Step resource_id | Replace a reusable Filter ID; the built-in inline_filter identifier can remain unchanged |
| Transformation Step resource_id | Replace a reusable Transformation ID; the built-in json_patch identifier can remain unchanged |
| Action Step | Rebind its provider account/configuration to an account valid in the destination team and review its input mappings |
| Step and Edge IDs | Preserve them inside the promoted graph so Edge and mapping references remain consistent |
FastHook validates the Source and reusable Step resources against the authenticated team. A missing destination resource fails creation instead of silently using a similarly named resource. Inline Actions are also validated against the provider account available to that team.
Do not replace IDs with a blind text substitution across the JSON document. A value may appear in a mapping template, condition, description, or sample where changing it would alter behavior. Traverse the structured fields and review the resulting graph.
Promotion procedure
- Freeze the reviewed source version and record its integer
version. - Retrieve
GET /v1/workflows/:idusing the source team and API key. - Fail the release if the returned version differs from the reviewed version.
- Copy
name,description,steps, andedgesinto a new create body. - replace
source_id, reusable resource IDs, and provider account configuration using the destination manifest; - set a unique destination name and
status: "draft"; - create it with
POST /v1/workflowsusing the destination team and API key; - retrieve the new Workflow and retain its ID, version
1, and graph as promotion evidence; and - test the Draft with destination-environment data before activation.
Example requests:
curl --fail-with-body --silent --show-error \
--header "Authorization: Bearer $SOURCE_FASTHOOK_API_KEY" \
--header "x-team-id: $SOURCE_FASTHOOK_TEAM_ID" \
"$FASTHOOK_API_BASE/v1/workflows/$SOURCE_WORKFLOW_ID"
curl --fail-with-body --silent --show-error \
--request POST \
--header "Authorization: Bearer $DESTINATION_FASTHOOK_API_KEY" \
--header "x-team-id: $DESTINATION_FASTHOOK_TEAM_ID" \
--header "content-type: application/json" \
--data @workflow-promotion.json \
"$FASTHOOK_API_BASE/v1/workflows"Keep both keys in the runner’s secret manager. Do not pass them as command-line arguments or write them into workflow-promotion.json.
Diff the behavior, not only the JSON
Review these separately:
- Trigger provider, event definition, and sample schema;
- Step kinds, order, enabled state, and branch topology;
- Action operation keys, authentication mode, account identity, and mapped required fields;
- Destination URLs, headers, signatures, timeouts, and retry behavior;
- Filter conditions, transformation code or JSON Patch operations, and error routes;
- Delay duration and duplicate-side-effect exposure; and
- source and destination data classifications.
Provider account IDs and environment resource IDs are expected to differ. Treat any unexpected semantic difference as a blocked release.
Validate the destination Draft
Send a unique synthetic event, then record:
- the destination Workflow ID and version;
- the request ID and Workflow run ID;
- each Step status and selected output evidence from Audit;
- the provider tenant or endpoint that received the side effect; and
- the expected business record or reconciliation result.
A successful HTTP request or succeeded Workflow run does not by itself prove the business outcome. Use reconciliation reports or provider-side verification for critical automations.
Update an existing destination Workflow
Retrieve the destination immediately before updating and send its current version with PUT or PATCH /v1/workflows/:id. A successful update increments the version. If another editor saved first, FastHook returns HTTP 409 with code workflow_conflict; reload, compare, and reapply the reviewed change.
Do not omit the concurrency check in an automated release. Although the endpoint accepts an update without version, that can overwrite a newer graph read by another editor.
Historical Workflow versions are immutable evidence, not a one-click restore mechanism. Prepare rollback as a reviewed forward update or as a separate known-good Draft. Continue with the release checklist and Workflow versioning.