Skip to main content

The Zapier alternative, written in Python.

Zapier connects two apps in ten minutes. Once an automation grows branches, loops and judgment calls, a Task is a program instead of a step list.

reconcile.py
invoices = qbash.integrations.xero.list_invoices(status="AUTHORISED")["data"]["Invoices"] for invoice in invoices: match = qbash.ai.run_prompt( slug="match-invoices", variables={"invoice": invoice}, ) if match["confidence"] < 0.8: qbash.integrations.slack.create_message(channel="#finance", text=match["note"])

Model and provider agnostic.

  • Anthropic
  • OpenAI
  • Gemini
  • xAI
  • OpenRouter
  • Amazon
  • Perplexity
  • MoonshotAI
  • Meta
  • Qwen

qbash vs Zapier

Zapier has the largest catalogue in the category and the best cold start in it. These rows are about what happens after an automation stops being simple.

FeatureqbashZapier
What you buildA Python programA Zap: a trigger and ordered steps
Billable unitThe run, plus the model calls your code makesThe task, and every step counts
Adding a stepCosts nothingCosts more per run
Branching and loopingLanguage featuresPaths and looping steps, each billed
Large batchesconcurrency and max_per_minute are argumentsAwkward past modest volumes
Long runsUp to 12 hoursShort step timeouts
Change historyA revision on every save, with a line-level diffZap version history
TestsA tests.py rides with the task, in the same revisionNot included
Model outputAn output schema constrains the model to your JSONNot constrained
PromptsOwned by a Task, versioned with it, and called by slugPrompt text sits in the step
Retrying a partial runCheckpoints skip the items that finishedReplay the run
Shared team credentialsYes, brokered server-side, shared with chatYes, spanning Zaps and Chatbots
Run surface for non-developersTyped inputs render a formInterfaces and Forms
Building without codeThe builder drafts the task as code you editCopilot builds a Zap
Integrations45+ integrations, 390+ operations, plus raw HTTPThousands of apps
Time to a first automationMinutes, if you write PythonMinutes, for anyone
What you build
qbashA Python program
ZapierA Zap: a trigger and ordered steps
Billable unit
qbashThe run, plus the model calls your code makes
ZapierThe task, and every step counts
Adding a step
qbashCosts nothing
ZapierCosts more per run
Branching and looping
qbashLanguage features
ZapierPaths and looping steps, each billed
Large batches
qbashconcurrency and max_per_minute are arguments
ZapierAwkward past modest volumes
Long runs
qbashUp to 12 hours
ZapierShort step timeouts
Change history
qbashA revision on every save, with a line-level diff
ZapierZap version history
Tests
qbashA tests.py rides with the task, in the same revision
ZapierNot included
Model output
qbashAn output schema constrains the model to your JSON
ZapierNot constrained
Prompts
qbashOwned by a Task, versioned with it, and called by slug
ZapierPrompt text sits in the step
Retrying a partial run
qbashCheckpoints skip the items that finished
ZapierReplay the run
Shared team credentials
qbashYes, brokered server-side, shared with chat
ZapierYes, spanning Zaps and Chatbots
Run surface for non-developers
qbashTyped inputs render a form
ZapierInterfaces and Forms
Building without code
qbashThe builder drafts the task as code you edit
ZapierCopilot builds a Zap
Integrations
qbash45+ integrations, 390+ operations, plus raw HTTP
ZapierThousands of apps
Time to a first automation
qbashMinutes, if you write Python
ZapierMinutes, for anyone

It’s code.

Loops, branches, and functions, + models where needed. Your code owns the orchestration: what runs, in what order, and when. Reviewable, versioned, and diffable, so a team maintains and improves it like any software.

Logic that outgrew a step list

Paths inside paths are hard to follow and harder to change safely. The same logic in Python is a few conditionals you read in one screen and review as a diff before it ships.

reconcile.py
for invoice in invoices:
    if invoice["total"] > 10_000:
        route = "manual-review"
    elif match["confidence"] > 0.9:
        route = "auto-post"
    else:
        route = "queue"

Predictable token spend

A prompt is only used when you call it, so you decide when to spend tokens. A task is one run whether it executes ten lines or ten thousand, and cached lookups and checkpoints stop a retry paying twice.

reconcile.py
rate = qbash.cache.get_or_set("fx-rate", fetch_rate, ttl="6h")

result = qbash.parallel(
    reconcile, invoices,
    concurrency=8, checkpoint="march-close",
)

A test harness

A tests.py rides with the task, versioned in the same revision as the code. Assert the whole flow end to end, and run it from the editor to catch a break before it ships. Tests run in a sandbox, so an unmocked integration or model call raises instead of reaching a live Slack channel.

tests.py
def test_low_confidence_goes_to_queue():
    out = reconcile(FIXTURE)
    assert out["route"] == "queue"

How Zapier pricing counts tasks.

Zapier bills per successful action, so the bill tracks how many actions a Zap takes multiplied by how often it fires. A six-action Zap firing a thousand times a month is six thousand tasks. Zapier and Make grow with the complexity of an automation. n8n grows with how often it runs.

Plan limits and task allowances change, so these rows describe the billable unit without quoting figures. Check zapier.com for current numbers before deciding.

ZapierMaken8n Cloudqbash
Billable unitTask, per successful actionCredit, per module callWorkflow executionRun, plus model calls
Trigger firingFreeOne credit, whatever it returnsCounts as the executionCounts as the run
Adding a stepMore per runMore per runNothingNothing
Doubling frequencyDoublesDoublesDoublesDoubles the model calls
Iterating 1,000 rowsRoughly 1,000 tasksRoughly 1,000 creditsDepends on loop shapeOne run
Filters and branchingFreeBranch modules still countNothingNothing, it is an if statement
Cost known before deployCalculable, steps times runsCalculable, modules times runsRoughlyYes, calls sit in the code
Billable unit
ZapierTask, per successful action
MakeCredit, per module call
n8n CloudWorkflow execution
qbashRun, plus model calls
Trigger firing
ZapierFree
MakeOne credit, whatever it returns
n8n CloudCounts as the execution
qbashCounts as the run
Adding a step
ZapierMore per run
MakeMore per run
n8n CloudNothing
qbashNothing
Doubling frequency
ZapierDoubles
MakeDoubles
n8n CloudDoubles
qbashDoubles the model calls
Iterating 1,000 rows
ZapierRoughly 1,000 tasks
MakeRoughly 1,000 credits
n8n CloudDepends on loop shape
qbashOne run
Filters and branching
ZapierFree
MakeBranch modules still count
n8n CloudNothing
qbashNothing, it is an if statement
Cost known before deploy
ZapierCalculable, steps times runs
MakeCalculable, modules times runs
n8n CloudRoughly
qbashYes, calls sit in the code
  • Triggers never count, however often the plan polls for them.
  • Filter and Paths steps are free, and a Zap stopped by a filter has run no actions, so it costs nothing.
  • Formatter, Delay, Looping, Digest, Storage, Tables and Forms steps are free.
  • A step that fails or is skipped is not billed, since nothing was sent.
  • Sub-Zaps bill for the call and the return on top of the actions inside them.
  • Replaying a run recounts every step it repeats.
  • A filter placed after an action has already paid for the records it discards. Move it above the action and the cheap step decides first.

Python in Zapier runs inside one Code step.

Code by Zapier runs Python or JavaScript inside one step of a Zap, with a short timeout and a restricted set of packages. The script inside the step is portable. The Zap logic around it is what has to be rebuilt when you move it into a Task.

CapabilityWhat it doesWhere it stops
Python supportRuns Python or JavaScript inside a Zap stepRequests and a small set of built-in modules, with no pip install
BillingAvailable on all paid Zapier plansEach code step execution counts as a task. Loops multiply the count
TimeoutCode runs between Zap stepsShort runtime limit. Rules out batch processing or long API sequences
Code reuseCode lives inside one stepCannot call functions from another step. Logic duplicates across the Zap
TestingTest individual Zap stepsNo assertion framework to run before going live
Python support
What it doesRuns Python or JavaScript inside a Zap step
Where it stopsRequests and a small set of built-in modules, with no pip install
Billing
What it doesAvailable on all paid Zapier plans
Where it stopsEach code step execution counts as a task. Loops multiply the count
Timeout
What it doesCode runs between Zap steps
Where it stopsShort runtime limit. Rules out batch processing or long API sequences
Code reuse
What it doesCode lives inside one step
Where it stopsCannot call functions from another step. Logic duplicates across the Zap
Testing
What it doesTest individual Zap steps
Where it stopsNo assertion framework to run before going live

ChatGPT in Zapier runs through AI by Zapier.

You add an AI by Zapier step, pick a provider and model, and its usage comes out of your task count, so there is no separate OpenAI bill unless you connect your own key. The older ChatGPT (OpenAI) app still exists for teams that bring an OpenAI key.

CapabilityWhat it doesWhere it stops
Adding AI to a ZapAnalyze, summarize, or generate text inside a Zap stepAdvanced or Premium models count as 3 or 5 tasks per run. A trigger plus two actions running 100 times a day is 6,000 tasks a month on a Standard model
Model outputOutput fields you define by name and type, or generate from the promptAnything that branches on the result still needs Paths or extra steps
Model choiceOpenAI, Anthropic, Google Gemini, Azure OpenAI, or Amazon Bedrock, chosen per stepLogic that picks a model per input, or retries on a different one, has to be built out of more steps
Prompt managementWritten in the step configurationA prompt used in several Zaps is copied into each one, so a change means editing every Zap
Running from ChatGPTZapier MCP lets ChatGPT call Zapier actionsPer-task billing applies to every action fired
Adding AI to a Zap
What it doesAnalyze, summarize, or generate text inside a Zap step
Where it stopsAdvanced or Premium models count as 3 or 5 tasks per run. A trigger plus two actions running 100 times a day is 6,000 tasks a month on a Standard model
Model output
What it doesOutput fields you define by name and type, or generate from the prompt
Where it stopsAnything that branches on the result still needs Paths or extra steps
Model choice
What it doesOpenAI, Anthropic, Google Gemini, Azure OpenAI, or Amazon Bedrock, chosen per step
Where it stopsLogic that picks a model per input, or retries on a different one, has to be built out of more steps
Prompt management
What it doesWritten in the step configuration
Where it stopsA prompt used in several Zaps is copied into each one, so a change means editing every Zap
Running from ChatGPT
What it doesZapier MCP lets ChatGPT call Zapier actions
Where it stopsPer-task billing applies to every action fired
  • Each prompt picks its own model from OpenAI, Anthropic, Gemini, Grok and OpenRouter.
  • An output_schema constrains the model to your JSON, so the branch that follows is an if statement in the same script.
  • Connect qbash as an MCP server in ChatGPT, Claude Code or Cursor, and every shared Task becomes a tool the model can call.
  • Behind that call is one run, however many model calls and branches the script makes.
support.py
stubs = qbash.integrations.gmail.search_messages(
    query="is:unread label:support", max_results=50,
)["messages"]

for stub in stubs:
    email = qbash.integrations.gmail.get_email(email_id=stub["id"])["email"]
    triage = qbash.ai.run_prompt(
        slug="triage-support",
        variables={"subject": email["subject"], "body": email["body"]},
    )
    if triage["needs_response"]:
        draft = qbash.ai.run_prompt(
            slug="draft-response",
            variables={"email": email, "category": triage["category"]},
        )
        qbash.integrations.slack.create_message(
            channel="#support-drafts",
            text=f"Re: {email['subject']}\n\n{draft['response']}",
        )

Moving a Zap across.

Most teams should not move everything. Zapier is good at the simple connections, so move the automations that got expensive or fragile and leave the rest.

  1. Pick the Zap with the most steps or the highest monthly task count.
  2. Describe it to the builder and it drafts the task as code your developer edits. Python from a Code step carries over as it is.
  3. Connect the accounts once at the org level, rather than per step.
  4. Run both in parallel, then move the trigger over.

Where Zapier fits better.

Zapier earned its position, and there are cases where nothing here improves on it.

  • You need an app from the long tail of thousands, with no usable public API.
  • Nobody on the team writes code.
  • The automation is genuinely two steps and will stay that way.
  • Non-technical colleagues need to build their own automations, not run yours.

Questions

Is qbash cheaper than Zapier?

It depends on shape, not volume alone. Zapier bills per task, so a ten-step run costs ten times a one-step run. A task is a single run however many lines it executes, which is why the gap widens as automations get more complex rather than just more frequent.

Can qbash replace Zapier completely?

For most teams it should not. Zapier is very good at simple two-app connections and its catalogue is far larger. The automations worth moving are the ones that grew branches, process batches, or call models.

What is the best Zapier alternative for developers?

It depends what you want to own. For a canvas you can self-host, n8n or Activepieces. For durable execution as a library inside your own application, Temporal, Inngest or Trigger.dev. qbash fits when you want the automation to be code but do not want to run the infrastructure under it.

Do non-technical teammates lose access if we move off Zapier?

No. A task declares typed inputs and those render as a form, so a colleague runs it with their own parameters and never sees the code. Results can land in Slack or as a chat they ask follow-up questions in.

What counts as a task in Zapier?

A task is a successful action step, meaning something the Zap sent to another app. Triggers and utility steps such as Filter, Formatter and Delay are free, and so is a step that fails or is skipped. Check zapier.com for current allowances, since plans change.

Why is my Zapier task count higher than expected?

Usually a Zap takes more actions per run, or fires more often, than you remember. Loops turn one run into hundreds of actions, and replays and Sub-Zaps add counts of their own. Counting actions per run and multiplying by trigger volume normally explains the gap.

Is Make cheaper than Zapier?

Often, on the per-unit price, because Make charges a credit per module call and prices those credits lower. Both bill per thing your automation does, so both grow with complexity. Make also charges a credit for the trigger where Zapier does not, and modules inside each active branch count, so a scenario with routers and iterators can consume faster than its step count suggests.

Can Zapier's Code step run any Python package?

No. Only requests and the bundled modules are available, so logic that needs pandas or another package has to be rewritten or moved to an external service.

How much does Zapier with ChatGPT cost at scale?

An AI by Zapier step on a Standard model counts as 1 task per run, and Advanced or Premium models count as 3 or 5. A Zap with a trigger and two actions running 100 times a day uses 6,000 tasks a month on a Standard model, or 12,000 if the AI step uses an Advanced model.

Can I trigger a Zap from ChatGPT?

Yes, via Zapier MCP. ChatGPT can call Zapier actions in natural language. qbash offers the same through its own MCP server, which exposes Tasks, memory folders and selected connector tools to the client.

Is there a free plan?

Yes. The Free plan includes scheduled runs, 3 Tasks and 100 executions a month, with no credit card. Paid plans start at $37 a month.

Competitor details reviewed . Vendors change plans and features without notice, so check theirs before deciding.

Ship your first task.

Open the editor, write a script against your connected accounts, and put it on a trigger. Or describe it, and the builder drafts the task as code you edit.