Automation

Loops & dynamic workflows

Stop prompting. Start building loops. A loop is a chain of automated steps that runs on a schedule, webhook, or trigger. You design the routine once - PromptFloe does the work forever.

#The mental model

Most tools require a human in the loop - you prompt, it responds, you review, you prompt again. PromptFloe Loops invert this. Your job is to design the loop. PromptFloe's job is to run it.

✍️
You define the routine
A list of steps, a trigger, and a max iteration count. Takes ~5 minutes in the loop builder.
⚙️
PromptFloe runs it
BullMQ queues each step independently. If a step fails, it retries. Completions chain to the next step automatically.
📬
You get the results
Slack DM, Telegram message, webhook call, or just check the run history in /loops.

#Anatomy of a loop

Every loop has four parts:

name + descriptionHuman-readable identifier. Shows in the loop list and Slack notifications.
triggerWhen to fire. Manual, cron schedule, or inbound webhook.
steps[]An ordered chain. Each step has a type, a config, and a nextStepId. Condition steps have yesStepId + noStepId instead.
maxIterationsHow many times the loop can cycle back to the first step via a condition. Prevents runaway loops.

#Step types

Six step types cover every building block you need. Mix them freely in a single loop.

generate

Build or edit a full-stack app - frontend, backend, tests, all wired up.

Use when: Kick off a fresh app each iteration, or edit an existing one based on upstream LLM output.

Output fields: appId, fileCount, framework
prompt: "Build a dashboard for {{llm.result.summary}}"
llm

Run any text or structured JSON task - summarise, classify, extract, rewrite.

Use when: Pre-process data before a generate step, or post-process results before a notify step.

Output fields: result (string or JSON if schema provided)
prompt: "Summarise these PRs: {{webhook.body.prs}}" + JSON schema → structured output
condition

PromptFloe evaluates a yes/no question and routes to yesStepId or noStepId.

Use when: Branch your loop based on generated content, webhook data, or LLM output.

Output fields: answer (yes|no), reasoning, nextStepId
prompt: "Does the app at {{generate.appId}} pass all smoke tests? Answer yes or no."
notify

Send a message to Slack, Telegram, or any webhook URL.

Use when: Alert your team when an app is generated, a condition is met, or a weekly report is ready.

Output fields: sent: true
message: "Weekly report ready: {{llm.result.text}}\nApp: {{generate.appId}}"
delay

Wait N seconds before the next step.

Use when: Give a deploy time to warm up, or space out API calls.

Output fields: waited (seconds)
seconds: 120
webhook

POST (or GET/PUT/PATCH) to any external HTTP endpoint.

Use when: Trigger a GitHub Action, notify a third-party API, or push data to a database.

Output fields: status, body (parsed response)
url: "https://api.github.com/repos/org/repo/actions/workflows/ci.yml/dispatches"

#Memory & template interpolation

Every time a step completes, its output is added to the loop memory - a running key-value store keyed by step ID. Downstream steps can reference those values with {{stepId.field}}.

Example: 3-step loop memory after each step completes
// After step "summarise" (llm):
memory = {
  __trigger: { firedAt: "2026-06-06T09:00:00Z" },
  summarise: { result: { text: "3 PRs need review: fix-auth, add-dark-mode, perf-opt" } }
}

// After step "build" (generate):
memory = {
  ...above,
  build: { appId: "app_01xyz", fileCount: 34, framework: "next" }
}

// After step "notify" (notify):
memory = {
  ...above,
  notify: { sent: true }
}
FieldTypeDescription
{{stepId.field}}-Access a specific field from a previous step's output. E.g. {{build.appId}}
{{stepId.result.key}}-Access nested JSON from an llm step that used a schema. E.g. {{summarise.result.score}}
{{__trigger}}-The trigger payload - webhook body, cron firedAt timestamp, or manual input.
{{__trigger.body.userId}}-Drill into a webhook payload field. Useful for routing builds per-user.

#Triggers

Manual
Run on demand via the UI (Run now button) or the REST API.
POST /v1/loops/:id/run - optionally pass a JSON body as trigger data.
Cron schedule
Standard cron expression - runs on a recurring schedule in any timezone.
"0 9 * * 1-5" = Mon-Fri at 9am. Timezone defaults to UTC but can be set to any IANA zone.
Inbound webhook
A secret token URL that any external system can POST to.
POST /v1/loops/webhook/:token - no auth header needed. The body becomes {{__trigger}} in memory.

#Condition branching

A condition step gives your loop a decision point. You write a yes/no question; PromptFloe evaluates it in fast mode by default - low cost, near-instant. The loop routes to yesStepId or noStepId based on the result.

Visual: branch on a condition
fetch-data
has-new-data?
yes ↓no ↓
build-report
- end -

You can also use conditions to loop back - set yesStepId to the first step's ID. The loop iterates up to maxIterations times, then stops automatically.

#Real-world examples

Four patterns covering the most common use cases. Each one maps to a loop you can build in under 5 minutes.

🔍
Daily code-review assistant
cron: 0 8 * * 1-5 (Mon-Fri at 8am)
1
webhookFetch open PRs
GET GitHub API → list of open pull requests
2
llmSummarise PRs
PromptFloe reads each PR title + description → bullet-point review summary
3
notifyPost to Slack
Posts summary to #eng-daily with links to each PR
Your team wakes up every morning to a prioritised review queue - zero manual work.
🔧
Self-healing landing page
cron: 0 */6 * * * (every 6 hours)
1
llmCheck content freshness
PromptFloe reads your latest blog posts + product changelog
2
conditionIs page outdated?
yes → regenerate | no → end
3
generateRebuild landing page
PromptFloe updates the hero copy, features section, and blog cards
4
webhookTrigger Vercel deploy
POST to Vercel deploy hook → new version goes live
5
notifySlack confirmation
"Landing page refreshed ✅ - 3 sections updated"
Your marketing site stays current with zero human intervention.
Webhook-driven app factory
webhook (Zapier, Make, GitHub, anything)
1
llmParse incoming payload
Extract intent, constraints, and target from webhook body
2
generateBuild the app
PromptFloe generates the full app from the extracted spec
3
webhookRegister in your CMS
POST the new appId to your internal registry API
4
notifyNotify requester
Telegram/Slack: "Your app is ready → <preview URL>"
Any external system can trigger an app build. Your team submits a form - the app is live in 2 minutes.
🔁
Iterative app improvement loop
manual (or cron weekly)·maxIterations: 5
1
llmAudit current app
PromptFloe reviews the live app for UX issues, broken flows, stale copy
2
conditionAre improvements needed?
yes → improve | no → end
3
generateApply improvements
Edit the existing app (editAppId from memory)
4
notifyReport changes
"App improved: {{llm.result.issues}} issues fixed"
Set maxIterations to 5. The loop audits and improves your app up to 5 times per run, stopping when PromptFloe determines it's good.

#Creating your first loop

1

Open the loop builder

Go to /loops in the sidebar and click New loop. Or navigate directly to /loops/new.

2

Name it and set a trigger

Give your loop a clear name (e.g. "Daily PR summary") and pick a trigger:

  • Manual - good while you're testing
  • Cron - enter a cron expression like 0 9 * * 1-5
  • Webhook - the server generates a secret token on save
3

Add steps

Click the step type buttons at the bottom of the builder. For each step:

  • Give it a name - this is what shows in run history and template refs
  • Fill in the required fields for its type
  • Reference prior steps with {{stepName.field}} in any text field
4

Set maxIterations

If your loop can cycle back (a condition step routes to the first step), set maxIterations to limit how many cycles per run. For a linear chain with no loop-back, leave it at 1.

5

Save and run

Click Create loop. You'll land on the detail page. Hit Run now to fire your first execution and watch the step records appear in real time.

#Using the API

All loop operations are available as REST endpoints. Authenticate with a JWT session token or a pf_... API key.

FieldTypeDescription
POST /v1/loops-Create a loop. Returns the full loop definition including webhook token if applicable.
GET /v1/loops?workspaceId=-List all loops for a workspace.
PATCH /v1/loops/:id-Update steps, trigger, or enabled flag. Cron schedule auto-syncs.
DELETE /v1/loops/:id-Delete a loop and all its run history.
POST /v1/loops/:id/run-Manually fire a run. Optional JSON body becomes {{__trigger}}.
GET /v1/loops/:id/runs-List last N runs (default 20).
GET /v1/loops/:id/runs/:runId-Run detail + all step records with duration, output, and errors.
DELETE /v1/loops/:id/runs/:runId-Cancel an in-progress run.
POST /v1/loops/webhook/:token-Public webhook trigger - no auth header needed. Body becomes trigger data.
Trigger a loop from CI/CD:
# Trigger a loop from a GitHub Action after a deploy
curl -X POST https://api.promptfloe.com/v1/loops/:id/run \
  -H "Authorization: Bearer pf_..." \
  -H "Content-Type: application/json" \
  -d '{"deployedAt":"2026-06-06T12:00:00Z","env":"production","version":"1.4.2"}'

# Or use the public webhook endpoint (no auth header)
curl -X POST https://api.promptfloe.com/v1/loops/webhook/your-secret-token \
  -d '{"event":"deploy.success","sha":"abc123"}'

#Run history & observability

Every run is tracked end-to-end. In the loop detail page (/loops/:id) you can:

  • See the status of every run (running, completed, failed, cancelled)
  • Expand any run to see each step record - type, duration, output, and error if it failed
  • Cancel a run that's still in progress
  • The page auto-refreshes every 4 seconds when a run is active

#Tips & limits

FieldTypeDescription
Max steps per loop-50 steps.
Max iterations per run-1000 (default 1). Set higher only for controlled loops with a clear termination condition.
Generate step timeout-8 minutes. If the generation hasn't completed, the step fails and the run is marked failed.
Delay step cap-Capped at 30 minutes (1800s) regardless of what you set.
Webhook step timeout-30 seconds per webhook call.
Template refs-Only previous steps' outputs are in memory - you can't reference a step that hasn't run yet.
Speed tier for conditions-Always fast mode - low cost, near-instant. The condition only answers yes/no.
Concurrency-Up to 10 steps run concurrently across all your loops (not per loop - sequential within one run).
PromptFloe docs · last updated Jul 2026Report a doc issue