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/loopsCreate 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/:idUpdate steps, trigger, or enabled flag. Cron schedule auto-syncs.
DELETE /v1/loops/:idDelete a loop and all its run history.
POST /v1/loops/:id/runManually fire a run. Optional JSON body becomes {{__trigger}}.
GET /v1/loops/:id/runsList last N runs (default 20).
GET /v1/loops/:id/runs/:runIdRun detail + all step records with duration, output, and errors.
DELETE /v1/loops/:id/runs/:runIdCancel an in-progress run.
POST /v1/loops/webhook/:tokenPublic 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 loop50 steps.
Max iterations per run1000 (default 1). Set higher only for controlled loops with a clear termination condition.
Generate step timeout8 minutes. If the generation hasn't completed, the step fails and the run is marked failed.
Delay step capCapped at 30 minutes (1800s) regardless of what you set.
Webhook step timeout30 seconds per webhook call.
Template refsOnly previous steps' outputs are in memory — you can't reference a step that hasn't run yet.
Speed tier for conditionsAlways fast mode — low cost, near-instant. The condition only answers yes/no.
ConcurrencyUp to 10 steps run concurrently across all your loops (not per loop — sequential within one run).
PromptFloe docs · last updated Jun 2026Report a doc issue