<?xml version="1.0" encoding="UTF-8"?>
<rss version="2.0" xmlns:atom="http://www.w3.org/2005/Atom" xmlns:dc="http://purl.org/dc/elements/1.1/">
  <channel>
    <title>DEV Community: Manveer</title>
    <description>The latest articles on DEV Community by Manveer (@manveer-banxal).</description>
    <link>https://dev.to/manveer-banxal</link>
    <image>
      <url>https://media2.dev.to/dynamic/image/width=90,height=90,fit=cover,gravity=auto,format=auto/https:%2F%2Fdev-to-uploads.s3.us-east-2.amazonaws.com%2Fuploads%2Fuser%2Fprofile_image%2F4155662%2F31f5756f-d8b4-4d50-bc45-c774ea5a72b6.png</url>
      <title>DEV Community: Manveer</title>
      <link>https://dev.to/manveer-banxal</link>
    </image>
    <atom:link rel="self" type="application/rss+xml" href="https://dev.to/feed/manveer-banxal"/>
    <language>en</language>
    <item>
      <title>Mobile App, PWA or Just a Website? A 10-Point Scorecard</title>
      <dc:creator>Manveer</dc:creator>
      <pubDate>Fri, 16 Oct 2026 17:50:53 +0000</pubDate>
      <link>https://dev.to/manveer-banxal/mobile-app-pwa-or-just-a-website-a-10-point-scorecard-1i8h</link>
      <guid>https://dev.to/manveer-banxal/mobile-app-pwa-or-just-a-website-a-10-point-scorecard-1i8h</guid>
      <description>&lt;p&gt;A customer tells you, "You should have an app." A developer friend says, "Just make the website installable." An agency sends a proposal for iOS &lt;em&gt;and&lt;/em&gt; Android. All three could be right, and all three could waste a year of your budget.&lt;/p&gt;

&lt;p&gt;Whether you need a mobile app or a website for a small business comes down to how your customers behave, not to what looks impressive. And the choice isn't really two-way. There's a middle option most comparisons skip: a &lt;strong&gt;progressive web app (PWA)&lt;/strong&gt;, a website that can be installed on a phone's home screen, send notifications and work partly offline.&lt;/p&gt;

&lt;p&gt;Below is a 10-question scorecard you can fill in over a coffee. Every platform claim was checked against Apple, Google, web.dev, MDN and WebKit documentation on 16 October 2026.&lt;/p&gt;

&lt;h2&gt;
  
  
  TL;DR
&lt;/h2&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;Many small businesses score into "website" or "PWA".&lt;/strong&gt; A native or cross-platform app pays off when customers use you weekly or more, or when you need hardware and background features the web can't reliably reach.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;iPhone is the deciding constraint for PWAs.&lt;/strong&gt; Web push on iOS works only after the user adds your site to their Home Screen, so if you need time-critical alerts and your customers won't do that, a PWA isn't enough.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;An app adds gatekeepers and ongoing admin.&lt;/strong&gt; Apple charges 99 USD a year, Google Play has a one-time 25 USD fee, both review your releases, and Apple rejects apps that are little more than "a repackaged website".&lt;/li&gt;
&lt;/ul&gt;

&lt;h2&gt;
  
  
  Website, PWA or app: what's actually different
&lt;/h2&gt;

&lt;p&gt;All three can look identical on a phone screen. The differences show up in four places: how people get it, how you reach them, what it can do on the device, and who has to approve your changes.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.us-east-2.amazonaws.com%2Fuploads%2Farticles%2Fz4bn2g08c6zb1kuueshy.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.us-east-2.amazonaws.com%2Fuploads%2Farticles%2Fz4bn2g08c6zb1kuueshy.png" alt="Comparison table of Website, PWA and native/cross-platform app across how users get it, push on iPhone, offline support, device hardware, app store listing, release approval and platform fees, with the push-on-iPhone row highlighted as the usual tie-breaker" width="800" height="553"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;div class="table-wrapper-paragraph"&gt;&lt;table&gt;
&lt;thead&gt;
&lt;tr&gt;
&lt;th&gt;&lt;/th&gt;
&lt;th&gt;Website&lt;/th&gt;
&lt;th&gt;PWA&lt;/th&gt;
&lt;th&gt;Native or cross-platform app&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td&gt;&lt;strong&gt;How users get it&lt;/strong&gt;&lt;/td&gt;
&lt;td&gt;Search, link, QR code&lt;/td&gt;
&lt;td&gt;Same, plus "install" to home screen&lt;/td&gt;
&lt;td&gt;App Store / Google Play download&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;strong&gt;Push on iPhone&lt;/strong&gt;&lt;/td&gt;
&lt;td&gt;No&lt;/td&gt;
&lt;td&gt;Yes, only once added to Home Screen (iOS 16.4+)&lt;/td&gt;
&lt;td&gt;Yes&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;strong&gt;Offline&lt;/strong&gt;&lt;/td&gt;
&lt;td&gt;No&lt;/td&gt;
&lt;td&gt;Partial: cached pages and data&lt;/td&gt;
&lt;td&gt;Full, if you build it&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;strong&gt;Device hardware&lt;/strong&gt;&lt;/td&gt;
&lt;td&gt;Camera, location (with permission)&lt;/td&gt;
&lt;td&gt;Same as website&lt;/td&gt;
&lt;td&gt;Full access, including Bluetooth and background tasks&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;strong&gt;App store listing&lt;/strong&gt;&lt;/td&gt;
&lt;td&gt;No&lt;/td&gt;
&lt;td&gt;No (by default)&lt;/td&gt;
&lt;td&gt;Yes&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;strong&gt;Release approval&lt;/strong&gt;&lt;/td&gt;
&lt;td&gt;None, you publish&lt;/td&gt;
&lt;td&gt;None, you publish&lt;/td&gt;
&lt;td&gt;Store review on every release&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;strong&gt;Platform fees&lt;/strong&gt;&lt;/td&gt;
&lt;td&gt;Hosting only&lt;/td&gt;
&lt;td&gt;Hosting only&lt;/td&gt;
&lt;td&gt;Apple 99 USD/year; Google 25 USD once&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;&lt;/div&gt;

&lt;p&gt;A few rows need context, because they're where most outdated advice goes wrong.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;PWAs on iPhone are better than their reputation.&lt;/strong&gt; Since iOS and iPadOS 16.4, a web app added to the Home Screen can ask for push notifications and set a badge count on its icon (&lt;a href="https://webkit.org/blog/13878/web-push-for-web-apps-on-ios-and-ipados/" rel="noopener noreferrer"&gt;WebKit&lt;/a&gt;). Since iOS 18.4, Declarative Web Push lets those web apps show notifications without a service worker (&lt;a href="https://webkit.org/blog/16574/webkit-features-in-safari-18-4/" rel="noopener noreferrer"&gt;WebKit, Safari 18.4&lt;/a&gt;; &lt;a href="https://webkit.org/blog/16535/meet-declarative-web-push/" rel="noopener noreferrer"&gt;Meet Declarative Web Push&lt;/a&gt;). And in iOS 26, "by default, every website added to the Home Screen opens as a web app", with or without a manifest file (&lt;a href="https://webkit.org/blog/16993/news-from-wwdc25-web-technology-coming-this-fall-in-safari-26-beta/" rel="noopener noreferrer"&gt;WebKit, Safari 26&lt;/a&gt;).&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;The catch is the install step.&lt;/strong&gt; On iPhone, notification permission comes after the user has added your site through the Share menu, and the request has to follow a direct tap, such as a "subscribe" button (&lt;a href="https://webkit.org/blog/13878/web-push-for-web-apps-on-ios-and-ipados/" rel="noopener noreferrer"&gt;WebKit&lt;/a&gt;). There's no automatic install prompt to lean on. Many customers will never find that menu without help.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Android is more forgiving.&lt;/strong&gt; Chrome offers an install prompt when the site is served over HTTPS, has a manifest with a name, 192px and 512px icons, a &lt;code&gt;start_url&lt;/code&gt; and a standalone-style &lt;code&gt;display&lt;/code&gt; mode, and the user has tapped the page and spent at least 30 seconds on it (&lt;a href="https://web.dev/articles/install-criteria" rel="noopener noreferrer"&gt;web.dev&lt;/a&gt;). Here's the minimum manifest:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight json"&gt;&lt;code&gt;&lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="w"&gt;
  &lt;/span&gt;&lt;span class="nl"&gt;"name"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"Riverside Yoga"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
  &lt;/span&gt;&lt;span class="nl"&gt;"short_name"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"Riverside"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
  &lt;/span&gt;&lt;span class="nl"&gt;"start_url"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"/"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
  &lt;/span&gt;&lt;span class="nl"&gt;"display"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"standalone"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
  &lt;/span&gt;&lt;span class="nl"&gt;"icons"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="w"&gt;
    &lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nl"&gt;"src"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"/icon-192.png"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nl"&gt;"sizes"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"192x192"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nl"&gt;"type"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"image/png"&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;},&lt;/span&gt;&lt;span class="w"&gt;
    &lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nl"&gt;"src"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"/icon-512.png"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nl"&gt;"sizes"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"512x512"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nl"&gt;"type"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"image/png"&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;&lt;span class="w"&gt;
  &lt;/span&gt;&lt;span class="p"&gt;]&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;&lt;strong&gt;EU iPhones still get web apps.&lt;/strong&gt; In early 2024 Apple said iOS 17.4 would drop Home Screen web apps in the EU, then reversed: "we will continue to offer the existing Home Screen web apps capability in the EU" (&lt;a href="https://9to5mac.com/2024/03/01/apple-home-screen-web-apps-ios-17-eu/" rel="noopener noreferrer"&gt;Apple's statement, via 9to5Mac&lt;/a&gt;). We found no later Apple notice changing that, and WebKit's iOS 26 web-app changes carry no regional exception.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Hardware is where the web still falls short.&lt;/strong&gt; MDN marks Web Bluetooth as experimental and "not Baseline because it does not work in some of the most widely-used browsers" (&lt;a href="https://developer.mozilla.org/en-US/docs/Web/API/Web_Bluetooth_API" rel="noopener noreferrer"&gt;MDN&lt;/a&gt;). The same applies to Background Sync, the API that lets a web app finish a task once the connection returns (&lt;a href="https://developer.mozilla.org/en-US/docs/Web/API/Background_Synchronization_API" rel="noopener noreferrer"&gt;MDN&lt;/a&gt;). If your idea depends on either, plan for an app.&lt;/p&gt;

&lt;h2&gt;
  
  
  The 10-point scorecard: mobile app or website for a small business?
&lt;/h2&gt;

&lt;p&gt;Score each question 0, 1 or 2. Answer for your &lt;em&gt;typical&lt;/em&gt; customer, not your most enthusiastic one. Higher scores point towards an app.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.us-east-2.amazonaws.com%2Fuploads%2Farticles%2F7kp7ltno6hyu7alc8mlu.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.us-east-2.amazonaws.com%2Fuploads%2Farticles%2F7kp7ltno6hyu7alc8mlu.png" alt="Printable 10-point scorecard with tick boxes for 0, 1 or 2 on each question, a total box out of 20, the three score bands (0–7 Website, 8–13 PWA, 14–20 App) as coloured strips, and an override-checks box for scoring 2 on Q4 or Q5, or 0 on Q8 or Q9" width="800" height="467"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;1. How often does a typical customer use you?&lt;/strong&gt;&lt;br&gt;
0 = a few times a year. 1 = about monthly. 2 = weekly or more.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;2. Do customers need an account?&lt;/strong&gt;&lt;br&gt;
0 = no, they browse, call or enquire. 1 = it's useful (order history, saved details). 2 = it's the core of the relationship (memberships, loyalty, bookings).&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;3. How important are notifications?&lt;/strong&gt;&lt;br&gt;
0 = email or SMS is fine. 1 = push would help, and you can ask customers to add you to their Home Screen. 2 = time-critical alerts are central ("your order is ready", "your driver is outside") and you can't count on iPhone users installing a web app.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;4. Does it need to work offline?&lt;/strong&gt;&lt;br&gt;
0 = no. 1 = showing cached information is enough (a menu, a schedule, last order). 2 = people must complete real work offline and sync later, like a field team logging jobs in a basement.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;5. What device features do you need?&lt;/strong&gt;&lt;br&gt;
0 = none, or photo upload. 1 = camera or location while the screen is open. 2 = Bluetooth, NFC, background location or other deep device access.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;6. Will the app do more than your website already does?&lt;/strong&gt;&lt;br&gt;
0 = it's mostly the same content. 1 = it adds some interactive features. 2 = it's a distinct tool your website can't be. This matters because Apple's guidelines say an app should "elevate it beyond a repackaged website", and that apps shouldn't primarily be "marketing materials, advertisements, web clippings" (&lt;a href="https://developer.apple.com/app-store/review/guidelines/" rel="noopener noreferrer"&gt;App Review Guidelines 4.2&lt;/a&gt;).&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;7. Do your customers expect to find you in an app store?&lt;/strong&gt;&lt;br&gt;
0 = they find you on Google or Maps. 1 = some ask for an app. 2 = an app store listing is standard in your category and customers search there.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;8. Can you fund upkeep after launch?&lt;/strong&gt;&lt;br&gt;
0 = no one is budgeted to maintain it. 1 = a few hours a month. 2 = a planned budget for updates, OS changes and store admin, including Apple's 99 USD per membership year (&lt;a href="https://developer.apple.com/programs/enroll/" rel="noopener noreferrer"&gt;Apple&lt;/a&gt;) and Google's 25 USD one-time registration (&lt;a href="https://support.google.com/googleplay/android-developer/answer/6112435" rel="noopener noreferrer"&gt;Play Console Help&lt;/a&gt;).&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;9. Can you live with release gatekeepers?&lt;/strong&gt;&lt;br&gt;
0 = you need to ship fixes the same day without anyone's approval. 1 = a day or two of delay is fine. 2 = you can plan around store review. Apple says it typically reviews at least 50% of submissions in under 24 hours and 90% in under 48 (&lt;a href="https://developer.apple.com/distribute/app-review/" rel="noopener noreferrer"&gt;Apple&lt;/a&gt;). Google says some reviews take "up to seven days or longer in exceptional cases" (&lt;a href="https://support.google.com/googleplay/android-developer/answer/9859751" rel="noopener noreferrer"&gt;Play Console Help&lt;/a&gt;). New personal Play accounts created after 13 November 2023 also need "a minimum of 12 testers who have been opted in continuously for at least 14 days" before going to production (&lt;a href="https://support.google.com/googleplay/android-developer/answer/14151465" rel="noopener noreferrer"&gt;Play Console Help&lt;/a&gt;).&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;10. Do you have evidence customers will use it?&lt;/strong&gt;&lt;br&gt;
0 = it's a hunch. 1 = people already use your online booking or ordering repeatedly. 2 = you have repeat digital users &lt;em&gt;and&lt;/em&gt; they're asking for an app.&lt;/p&gt;

&lt;h3&gt;
  
  
  What your score means
&lt;/h3&gt;

&lt;div class="table-wrapper-paragraph"&gt;&lt;table&gt;
&lt;thead&gt;
&lt;tr&gt;
&lt;th&gt;Score&lt;/th&gt;
&lt;th&gt;Build&lt;/th&gt;
&lt;th&gt;What that looks like&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td&gt;&lt;strong&gt;0–7&lt;/strong&gt;&lt;/td&gt;
&lt;td&gt;&lt;strong&gt;Website&lt;/strong&gt;&lt;/td&gt;
&lt;td&gt;A fast, mobile-friendly site with clear calls to action, online booking or enquiry forms, and good local SEO. Email and SMS handle reminders.&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;strong&gt;8–13&lt;/strong&gt;&lt;/td&gt;
&lt;td&gt;&lt;strong&gt;PWA&lt;/strong&gt;&lt;/td&gt;
&lt;td&gt;Your website plus an install option, push for customers who add it to their Home Screen, and cached pages for patchy signal. One codebase, no store review.&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;strong&gt;14–20&lt;/strong&gt;&lt;/td&gt;
&lt;td&gt;&lt;strong&gt;App&lt;/strong&gt;&lt;/td&gt;
&lt;td&gt;A cross-platform iOS and Android app (one codebase for both), usually alongside a website that still handles discovery and SEO.&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;&lt;/div&gt;

&lt;p&gt;&lt;strong&gt;Two override checks, because a total can hide a deal-breaker:&lt;/strong&gt;&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;Scored 2 on Q4 or Q5?&lt;/strong&gt; The web can't reliably deliver full offline work or deep hardware access today. Treat an app as the default and check the specific features before ruling it out.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Scored 0 on Q8 or Q9?&lt;/strong&gt; You're not ready to run an app, whatever your total. Start with a PWA and revisit in six months.&lt;/li&gt;
&lt;/ul&gt;

&lt;h2&gt;
  
  
  The decision in one flow
&lt;/h2&gt;

&lt;p&gt;If you'd rather not add up numbers, four yes/no questions in order get you to the same answer: stop at the first "yes" and build that.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.us-east-2.amazonaws.com%2Fuploads%2Farticles%2Fzt4ucoe3vuj4sch1uxdi.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.us-east-2.amazonaws.com%2Fuploads%2Farticles%2Fzt4ucoe3vuj4sch1uxdi.png" alt="Decision flow starting from " width="800" height="467"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;Do you need Bluetooth, NFC, background tasks or full offline work? &lt;strong&gt;App.&lt;/strong&gt;
&lt;/li&gt;
&lt;li&gt;Do customers use you weekly and need time-critical alerts on iPhone? &lt;strong&gt;App.&lt;/strong&gt;
&lt;/li&gt;
&lt;li&gt;Do you have repeat, logged-in customers who'd benefit from install, push or offline caching? &lt;strong&gt;PWA.&lt;/strong&gt;
&lt;/li&gt;
&lt;li&gt;None of the above? &lt;strong&gt;Website.&lt;/strong&gt;
&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;The order matters: hardware and offline limits are technical walls, while usage frequency is a judgment call.&lt;/p&gt;

&lt;h2&gt;
  
  
  A worked example (hypothetical)
&lt;/h2&gt;

&lt;p&gt;&lt;em&gt;Illustrative only. This is not a Banxal client and the numbers are made up for the exercise.&lt;/em&gt;&lt;/p&gt;

&lt;p&gt;"Riverside Yoga" is an independent studio with about 400 members. The owner has been quoted for an iOS and Android app with class booking, a membership card and a waitlist. Here's how they score:&lt;/p&gt;

&lt;div class="table-wrapper-paragraph"&gt;&lt;table&gt;
&lt;thead&gt;
&lt;tr&gt;
&lt;th&gt;Question&lt;/th&gt;
&lt;th&gt;Score&lt;/th&gt;
&lt;th&gt;Reasoning&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td&gt;1. Frequency&lt;/td&gt;
&lt;td&gt;2&lt;/td&gt;
&lt;td&gt;Members come twice a week.&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;2. Accounts&lt;/td&gt;
&lt;td&gt;2&lt;/td&gt;
&lt;td&gt;Bookings and memberships are the business.&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;3. Notifications&lt;/td&gt;
&lt;td&gt;1&lt;/td&gt;
&lt;td&gt;"A spot opened on the waitlist" helps, but email and SMS already work.&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;4. Offline&lt;/td&gt;
&lt;td&gt;0&lt;/td&gt;
&lt;td&gt;Booking needs a connection anyway.&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;5. Device features&lt;/td&gt;
&lt;td&gt;0&lt;/td&gt;
&lt;td&gt;A QR check-in on the front-desk tablet covers it.&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;6. Beyond the website&lt;/td&gt;
&lt;td&gt;1&lt;/td&gt;
&lt;td&gt;Booking and a membership card are interactive, but not unique.&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;7. App store expectation&lt;/td&gt;
&lt;td&gt;0&lt;/td&gt;
&lt;td&gt;New members find the studio on Google Maps.&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;8. Upkeep budget&lt;/td&gt;
&lt;td&gt;1&lt;/td&gt;
&lt;td&gt;The owner can fund a few hours a month.&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;9. Release gatekeepers&lt;/td&gt;
&lt;td&gt;1&lt;/td&gt;
&lt;td&gt;Timetable changes are content, not releases, so a day's review delay is fine.&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;10. Evidence&lt;/td&gt;
&lt;td&gt;1&lt;/td&gt;
&lt;td&gt;Members book online weekly, but nobody has asked for an app.&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;strong&gt;Total&lt;/strong&gt;&lt;/td&gt;
&lt;td&gt;&lt;strong&gt;9&lt;/strong&gt;&lt;/td&gt;
&lt;td&gt;&lt;strong&gt;PWA&lt;/strong&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;&lt;/div&gt;

&lt;p&gt;No override checks fire. The studio's next step is to make its existing booking site installable, add a "Get waitlist alerts" button that walks iPhone users through Add to Home Screen, and cache the timetable so it loads on patchy signal.&lt;/p&gt;

&lt;p&gt;What would change the answer? A feature that needs Bluetooth, such as syncing heart-rate monitors, pushes Q5 to 2 and fires the override. Even then the PWA isn't wasted: its booking logic and backend carry over to an app.&lt;/p&gt;

&lt;h2&gt;
  
  
  Mistakes we see in this decision
&lt;/h2&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;Building an app to get "found".&lt;/strong&gt; If Q7 scored 0, your customers find you through search and maps, so your website's SEO matters more than a store listing.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Wrapping the website in an app shell.&lt;/strong&gt; It's a common shortcut into the stores, and exactly what Apple's minimum-functionality rule (4.2) is written to catch.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Planning for launch, not year two.&lt;/strong&gt; Apps need updates when iOS and Android change, a renewed Apple membership and a store review for every fix. That's why Q8 exists.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Assuming PWAs can't do push on iPhone.&lt;/strong&gt; That stopped being true with iOS 16.4. The real limit is the install step, so design it rather than waiting for a prompt.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Skipping the scope step.&lt;/strong&gt; Whatever you build, write down what's out of scope first. Our &lt;a href="https://banxal.com/blog/mvp-spec-template-non-technical-founders" rel="noopener noreferrer"&gt;MVP spec template&lt;/a&gt; starts there.&lt;/li&gt;
&lt;/ul&gt;

&lt;h2&gt;
  
  
  What it costs, without the made-up ranges
&lt;/h2&gt;

&lt;p&gt;You'll find plenty of "an app costs $X to $Y" tables online. We won't add another, because cost depends on scope and your score doesn't change that. What the score does change is the &lt;em&gt;shape&lt;/em&gt; of the cost:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;Website and PWA:&lt;/strong&gt; one codebase, hosting, no platform fees, no review queue.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;App:&lt;/strong&gt; Apple's 99 USD a year and Google's 25 USD one-off (&lt;a href="https://developer.apple.com/programs/enroll/" rel="noopener noreferrer"&gt;Apple&lt;/a&gt;; &lt;a href="https://support.google.com/googleplay/android-developer/answer/6112435" rel="noopener noreferrer"&gt;Google&lt;/a&gt;), store listings to maintain, and release testing on two platforms. If you sell digital goods inside an iOS app, Apple's Small Business Program rate is 15% for developers under 1 million USD in annual proceeds (&lt;a href="https://developer.apple.com/app-store/small-business-program/" rel="noopener noreferrer"&gt;Apple&lt;/a&gt;). Check the current terms for your region before you build a pricing plan around it.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;If you're tempted to start on a no-code builder, check what you can export first. Our &lt;a href="https://banxal.com/blog/handoff-flutterflow-app-to-developer" rel="noopener noreferrer"&gt;FlutterFlow handoff guide&lt;/a&gt; compares export options across mobile builders. And if your "app" is really about automating bookings or reminders, the problem is sometimes solved behind the scenes, with no new screen for customers at all.&lt;/p&gt;

&lt;h2&gt;
  
  
  FAQ
&lt;/h2&gt;

&lt;p&gt;&lt;strong&gt;Can a PWA be listed in the App Store or Google Play?&lt;/strong&gt;&lt;br&gt;
Not by default. A PWA is installed from the browser. Wrapping one in an app shell for the stores turns it into an app with an app's review process, and Apple may reject it under guideline 4.2 if it adds little beyond your website (&lt;a href="https://developer.apple.com/app-store/review/guidelines/" rel="noopener noreferrer"&gt;Apple&lt;/a&gt;).&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Do PWAs send push notifications on iPhone?&lt;/strong&gt;&lt;br&gt;
Yes, from iOS 16.4, once the user has added the web app to their Home Screen and tapped to allow notifications (&lt;a href="https://webkit.org/blog/13878/web-push-for-web-apps-on-ios-and-ipados/" rel="noopener noreferrer"&gt;WebKit&lt;/a&gt;).&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Do PWAs still work on iPhones in the EU?&lt;/strong&gt;&lt;br&gt;
Yes. Apple reversed its plan to remove Home Screen web apps in the EU in March 2024 (&lt;a href="https://9to5mac.com/2024/03/01/apple-home-screen-web-apps-ios-17-eu/" rel="noopener noreferrer"&gt;9to5Mac&lt;/a&gt;), and we found no later change as of 16 October 2026.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;If I start with a PWA, do I throw it away when I need an app?&lt;/strong&gt;&lt;br&gt;
Usually not. Your backend, database and business logic carry over. The screens get rebuilt for the app.&lt;/p&gt;

&lt;h2&gt;
  
  
  Next step
&lt;/h2&gt;

&lt;p&gt;Score yourself honestly, then look at which questions you scored 2 on, because they tell you which features matter most. Banxal builds &lt;a href="https://banxal.com/services" rel="noopener noreferrer"&gt;websites, web apps and cross-platform mobile apps&lt;/a&gt;. If your score sits on a band boundary, or an override fired and you want a second opinion before committing, &lt;a href="https://banxal.com/contact" rel="noopener noreferrer"&gt;get in touch&lt;/a&gt; and send us your ten answers.&lt;/p&gt;

&lt;p&gt;What did you score, and did it match what you were planning to build? Tell us in the comments.&lt;/p&gt;




&lt;p&gt;&lt;em&gt;Originally published on &lt;a href="https://banxal.com/blog/mobile-app-pwa-or-website-scorecard" rel="noopener noreferrer"&gt;banxal.com&lt;/a&gt;.&lt;/em&gt;&lt;/p&gt;

</description>
      <category>pwa</category>
      <category>mobile</category>
      <category>webdev</category>
      <category>startup</category>
    </item>
    <item>
      <title>Hand Off a FlutterFlow App to a Developer: What to Prepare</title>
      <dc:creator>Manveer</dc:creator>
      <pubDate>Mon, 12 Oct 2026 04:11:49 +0000</pubDate>
      <link>https://dev.to/manveer-banxal/hand-off-a-flutterflow-app-to-a-developer-what-to-prepare-ojo</link>
      <guid>https://dev.to/manveer-banxal/hand-off-a-flutterflow-app-to-a-developer-what-to-prepare-ojo</guid>
      <description>&lt;p&gt;Your FlutterFlow app is on TestFlight, maybe live in the stores, and real people use it. You've found a developer to take it further, and their first message is: "Can you share the code and give me access?"&lt;/p&gt;

&lt;p&gt;On mobile, that one request covers six or seven things: the FlutterFlow project, a GitHub repo, a Firebase or Supabase backend, Apple and Google developer accounts, push-notification keys and every third-party API the app calls. Hand off a FlutterFlow app to a developer without mapping those, and you'll either pay them to dig through your setup or give away something you can't get back.&lt;/p&gt;

&lt;p&gt;This guide covers what you can export, what to share instead of transfer, and what to write down first.&lt;/p&gt;

&lt;h2&gt;
  
  
  TL;DR
&lt;/h2&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;FlutterFlow gives you real code. Most mobile no-code tools don't.&lt;/strong&gt; Code download starts on the Basic plan and GitHub push on Growth. Adalo and Glide have no code export, and Bubble apps only run on Bubble.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Share access, keep ownership.&lt;/strong&gt; Invite the developer to FlutterFlow, Firebase, GitHub, App Store Connect and Play Console under their own login. A FlutterFlow ownership transfer "can not be undone."&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Check secrets and security rules before anyone forks the code.&lt;/strong&gt; Private keys can end up in FlutterFlow's generated cloud function files, and one of its rule options is "Everyone".&lt;/li&gt;
&lt;/ul&gt;

&lt;h2&gt;
  
  
  Why mobile no-code handoffs are trickier than web ones
&lt;/h2&gt;

&lt;p&gt;A web handoff is mostly code, database and domain. Mobile adds three complications.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;The stores are separate accounts.&lt;/strong&gt; Your listing, reviews and release history live in Apple's and Google's consoles, not in FlutterFlow.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Some keys only download once.&lt;/strong&gt; For Apple's push notification key (the &lt;code&gt;.p8&lt;/code&gt; file), "the key is not saved in your developer account and you won't be able to download it again" (&lt;a href="https://developer.apple.com/help/account/keys/revoke-edit-and-download-keys/" rel="noopener noreferrer"&gt;Apple Developer&lt;/a&gt;). If a past freelancer kept the only copy, you'll have to create a new key.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Old versions stay installed.&lt;/strong&gt; Web users get your latest version on their next visit, but mobile users keep whatever build they installed until they update — so a careless database change can break the version people already have, even when the new build works fine.&lt;/p&gt;

&lt;p&gt;Coming from a web builder? Our &lt;a href="https://banxal.com/blog/handoff-lovable-bolt-app-to-developer" rel="noopener noreferrer"&gt;Lovable and Bolt handoff guide&lt;/a&gt; covers that side.&lt;/p&gt;

&lt;h2&gt;
  
  
  Export reality: what you can actually take with you
&lt;/h2&gt;

&lt;p&gt;Before hiring, work out what you're handing over: either code a developer can open, or a project that only exists inside the builder. Here's what each builder's docs said when we checked on 12 October 2026.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.us-east-2.amazonaws.com%2Fuploads%2Farticles%2Fkcfbgsuzrk9kv3n19yo2.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.us-east-2.amazonaws.com%2Fuploads%2Farticles%2Fkcfbgsuzrk9kv3n19yo2.png" alt="Export comparison, checked 12 October 2026. FlutterFlow: full Flutter/Dart code export on paid plans, Push to GitHub on Growth and up, native store builds, data in your own Firebase or Supabase; a developer takes over a Flutter codebase. Adalo: no code export, native builds, CSV per collection. Glide: no code export, PWA only, CSV or source sheet. Bubble: no code export, native builds via React Native, CSV and Bubble API. FlutterFlow listed Basic at $39/month and Growth at $80/month for the first seat." width="800" height="533"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;FlutterFlow.&lt;/strong&gt; Download Code gives you "the entire codebase of the app generated by FlutterFlow" (&lt;a href="https://docs.flutterflow.io/getting-started/ui-builder/tool-bar" rel="noopener noreferrer"&gt;toolbar docs&lt;/a&gt;), and that code runs "as a normal Flutter app without requiring FlutterFlow" (&lt;a href="https://docs.flutterflow.io/resources/projects/" rel="noopener noreferrer"&gt;FlutterFlow projects&lt;/a&gt;). Code Download is on Basic and up, and exporting FlutterFlow to GitHub (Push to GitHub) needs Growth and up (&lt;a href="https://docs.flutterflow.io/accounts-billing/plan-comparison/" rel="noopener noreferrer"&gt;plan comparison&lt;/a&gt;). On 12 October 2026, Basic was listed at $39/month and Growth at $80/month for the first seat (&lt;a href="https://www.flutterflow.io/pricing" rel="noopener noreferrer"&gt;pricing&lt;/a&gt;). Check the page again before you upgrade.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Adalo.&lt;/strong&gt; Adalo staff wrote in August 2025 that "it is not possible to download the source code of the app at the moment" (&lt;a href="https://forum.adalo.com/t/source-code-of-an-application-built-with-adalo/57905" rel="noopener noreferrer"&gt;Adalo forum&lt;/a&gt;) — an Adalo app's no-export lock-in. You can still export data as CSV, one collection at a time; details from the "many" side of a relationship are left out (&lt;a href="https://help.adalo.com/database/download-your-collection-as-a-csv-file" rel="noopener noreferrer"&gt;Adalo help&lt;/a&gt;).&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Glide.&lt;/strong&gt; Glide apps "are Progressive Web Apps (PWAs), and publishing directly to the App Store or Google Play is not supported" (&lt;a href="https://help.glideapps.com/en/articles/10021560-is-glide-able-to-push-to-app-store" rel="noopener noreferrer"&gt;Glide help&lt;/a&gt;). On Glide's community forum, the answer to "can I export my source code?" is "there is no source code for your apps" (&lt;a href="https://community.glideapps.com/t/can-i-download-or-export-my-apps-source-code/140" rel="noopener noreferrer"&gt;Glide community&lt;/a&gt;).&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Bubble.&lt;/strong&gt; Bubble is no longer web-only. It now publishes native apps built on React Native (&lt;a href="https://manual.bubble.io/help-guides/publishing-your-app/native-mobile-app" rel="noopener noreferrer"&gt;Bubble native mobile&lt;/a&gt;). The code still stays with Bubble, though: "there's no way of exporting your application as code," and leaving means you "have to rebuild the application logic" (&lt;a href="https://manual.bubble.io/account-and-marketplace/application-and-data-ownership" rel="noopener noreferrer"&gt;Bubble ownership&lt;/a&gt;).&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;On Adalo, Glide or Bubble, a developer either keeps building inside the tool or rebuilds from scratch. FlutterFlow adds a third option: export the code and carry on from there.&lt;/p&gt;

&lt;h2&gt;
  
  
  The 10-minute export self-check
&lt;/h2&gt;

&lt;p&gt;Do this before your first call with a developer. You don't need to be technical.&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;
&lt;strong&gt;FlutterFlow Developer Menu:&lt;/strong&gt; can you click Download Code? If it's locked, you're on the free plan.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Download the ZIP&lt;/strong&gt; and store it outside FlutterFlow as a dated snapshot.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Settings &amp;gt; Integrations &amp;gt; GitHub:&lt;/strong&gt; is a repo connected, and whose account or organisation owns it?&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Log into Firebase or Supabase yourself.&lt;/strong&gt; If you can't, find out who can.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Log into App Store Connect and Play Console.&lt;/strong&gt; Confirm that you, not a former freelancer, are Apple's Account Holder and Google's account owner.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Find the &lt;code&gt;.p8&lt;/code&gt; push key.&lt;/strong&gt; Do you have it, or know who does?&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;List your custom code:&lt;/strong&gt; every Custom Action, Widget and Function.&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;If steps 4 to 6 end in "I don't know", fix that before hiring. Those accounts are the hardest to recover.&lt;/p&gt;

&lt;h2&gt;
  
  
  How to hand off a FlutterFlow app to a developer: share access, don't transfer ownership
&lt;/h2&gt;

&lt;p&gt;The developer gets their own login with scoped access, and you keep the owner seat. When the work ends, you remove one person and nothing else breaks.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.us-east-2.amazonaws.com%2Fuploads%2Farticles%2Fhouqyjh35fqaat4b5qlq.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.us-east-2.amazonaws.com%2Fuploads%2Farticles%2Fhouqyjh35fqaat4b5qlq.png" alt="Diagram of six accounts — FlutterFlow, Firebase/Supabase, GitHub, App Store Connect, Play Console, push keys and secrets — where the founder keeps the owner seat and the developer connects with a scoped role, plus a warning against transferring ownership" width="800" height="553"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;div class="table-wrapper-paragraph"&gt;&lt;table&gt;
&lt;thead&gt;
&lt;tr&gt;
&lt;th&gt;Account&lt;/th&gt;
&lt;th&gt;Give the developer&lt;/th&gt;
&lt;th&gt;Watch out for&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td&gt;&lt;strong&gt;FlutterFlow&lt;/strong&gt;&lt;/td&gt;
&lt;td&gt;Editor access as a collaborator&lt;/td&gt;
&lt;td&gt;Ownership transfer "can not be undone". To get it back, the new owner has to transfer it to you (&lt;a href="https://docs.flutterflow.io/resources/projects/collaboration/" rel="noopener noreferrer"&gt;collaboration docs&lt;/a&gt;)&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;strong&gt;Firebase&lt;/strong&gt;&lt;/td&gt;
&lt;td&gt;A role under Users and permissions, using "least privilege" (&lt;a href="https://firebase.google.com/docs/projects/iam/overview" rel="noopener noreferrer"&gt;Firebase IAM&lt;/a&gt;)&lt;/td&gt;
&lt;td&gt;FlutterFlow is already an Editor on your project (&lt;a href="https://docs.flutterflow.io/integrations/firebase/connect-to-firebase/" rel="noopener noreferrer"&gt;FlutterFlow + Firebase&lt;/a&gt;). Never share your Google login&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;strong&gt;Supabase&lt;/strong&gt;&lt;/td&gt;
&lt;td&gt;Developer role, which can't change project settings or API keys (&lt;a href="https://supabase.com/docs/guides/platform/access-control" rel="noopener noreferrer"&gt;Supabase access control&lt;/a&gt;)&lt;/td&gt;
&lt;td&gt;Invites expire after 24 hours&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;strong&gt;GitHub&lt;/strong&gt;&lt;/td&gt;
&lt;td&gt;Collaborator on a repo you own&lt;/td&gt;
&lt;td&gt;Check the repo isn't on a past freelancer's account&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;strong&gt;App Store Connect&lt;/strong&gt;&lt;/td&gt;
&lt;td&gt;Developer or App Manager role, limited to this app (&lt;a href="https://developer.apple.com/help/app-store-connect/manage-your-team/add-and-edit-users" rel="noopener noreferrer"&gt;Apple&lt;/a&gt;)&lt;/td&gt;
&lt;td&gt;Individual memberships have a catch (below)&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;strong&gt;Play Console&lt;/strong&gt;&lt;/td&gt;
&lt;td&gt;App-level permissions with an access expiry date (&lt;a href="https://support.google.com/googleplay/android-developer/answer/9844686" rel="noopener noreferrer"&gt;Play Console Help&lt;/a&gt;)&lt;/td&gt;
&lt;td&gt;They must sign in with the exact email you invited&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;strong&gt;Push keys, Stripe, AI APIs&lt;/strong&gt;&lt;/td&gt;
&lt;td&gt;Shared through a password manager vault&lt;/td&gt;
&lt;td&gt;Rotate anything pasted into chat or email&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;&lt;/div&gt;

&lt;p&gt;&lt;strong&gt;Apple individual memberships.&lt;/strong&gt; If you enrolled as an individual, Apple says users you add "only access App Store Connect" and aren't part of your team (&lt;a href="https://developer.apple.com/help/app-store-connect/manage-your-team/add-and-edit-users" rel="noopener noreferrer"&gt;Apple&lt;/a&gt;). Managing keys needs the Account Holder or Admin role (&lt;a href="https://developer.apple.com/help/account/keys/revoke-edit-and-download-keys/" rel="noopener noreferrer"&gt;Apple keys&lt;/a&gt;), so expect to do those steps yourself.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Android's two keys.&lt;/strong&gt; With Play App Signing, Google holds the app signing key and you hold the upload key. If the upload key is lost, you can request a reset (&lt;a href="https://support.google.com/googleplay/android-developer/answer/9842756" rel="noopener noreferrer"&gt;Play App Signing&lt;/a&gt;) — but know where it lives.&lt;/p&gt;

&lt;h2&gt;
  
  
  Document what you built
&lt;/h2&gt;

&lt;p&gt;The developer can read your code, but not the reasoning behind it. This FlutterFlow app takeover checklist covers what to write down before they start.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.us-east-2.amazonaws.com%2Fuploads%2Farticles%2Fbvgnc4oamud00frwpcu6.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.us-east-2.amazonaws.com%2Fuploads%2Farticles%2Fbvgnc4oamud00frwpcu6.png" alt="Pre-handoff checklist in four columns — Accounts, Code, Data and Docs — with a tick box for each item to confirm before a developer starts" width="800" height="387"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;[ ] &lt;strong&gt;Data model:&lt;/strong&gt; each Firestore collection or Supabase table, what it holds, and which hold personal or payment data.&lt;/li&gt;
&lt;li&gt;[ ] &lt;strong&gt;Custom code:&lt;/strong&gt; each Custom Action, Widget and Function, what it does, and any packages added. In the export, these live in &lt;code&gt;lib/custom_code/&lt;/code&gt; (&lt;a href="https://docs.flutterflow.io/generated-code/project-structure/" rel="noopener noreferrer"&gt;project structure&lt;/a&gt;).&lt;/li&gt;
&lt;li&gt;[ ] &lt;strong&gt;Navigation:&lt;/strong&gt; the main screens and the three flows that matter most (signup, core action, payment).&lt;/li&gt;
&lt;li&gt;[ ] &lt;strong&gt;Auth and rules:&lt;/strong&gt; your sign-in methods and the rule setting on every collection.&lt;/li&gt;
&lt;li&gt;[ ] &lt;strong&gt;Environments:&lt;/strong&gt; if you use Development Environments, which one is production and which database each points to (&lt;a href="https://docs.flutterflow.io/testing/dev-environments/" rel="noopener noreferrer"&gt;dev environments&lt;/a&gt;).&lt;/li&gt;
&lt;li&gt;[ ] &lt;strong&gt;Outside FlutterFlow:&lt;/strong&gt; Cloud Functions, webhooks, scheduled jobs and anything else configured by hand.&lt;/li&gt;
&lt;li&gt;[ ] &lt;strong&gt;Live build number and known bugs.&lt;/strong&gt;
&lt;/li&gt;
&lt;/ul&gt;

&lt;h2&gt;
  
  
  FlutterFlow-specific traps
&lt;/h2&gt;

&lt;p&gt;FlutterFlow's visual builder hides a few gotchas that surface only once code is exported or pushed to GitHub. Check each before a developer forks the project.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Secrets in generated cloud functions.&lt;/strong&gt; "Make Private" sends an API call through Firebase Cloud Functions, so your tokens stay out of the app (&lt;a href="https://docs.flutterflow.io/resources/backend-logic/rest-api/" rel="noopener noreferrer"&gt;API calls&lt;/a&gt;). But FlutterFlow warns that a private value used this way "may appear in the cloud function's code." It also says you "must review and manage these cloud function files" before exporting or pushing to GitHub (&lt;a href="https://docs.flutterflow.io/testing/dev-environments/" rel="noopener noreferrer"&gt;dev environments&lt;/a&gt;). Then check your Custom Actions for hardcoded keys; custom Dart code ships inside the app.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Unreviewed Firestore rules.&lt;/strong&gt; Rule options run from "Everyone" (signed in or not) to "No One". FlutterFlow warns that defaults can be too open: a new collection everyone can read when only its creator should (&lt;a href="https://docs.flutterflow.io/integrations/database/cloud-firestore/firestore-rules/" rel="noopener noreferrer"&gt;Firestore rules&lt;/a&gt;). Your screens only show people their own data; the database still answers anyone who asks directly. Our post on &lt;a href="https://banxal.com/blog/backend-validation-ai-finds-loopholes" rel="noopener noreferrer"&gt;backend validation&lt;/a&gt; explains why that gap is now easier for attackers to find.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;The &lt;code&gt;flutterflow&lt;/code&gt; branch gets overwritten.&lt;/strong&gt; FlutterFlow "always pushes changes to a branch named &lt;code&gt;flutterflow&lt;/code&gt;," and direct edits "will be overwritten by the next push" (&lt;a href="https://docs.flutterflow.io/exporting/push-to-github/" rel="noopener noreferrer"&gt;GitHub docs&lt;/a&gt;). The documented pattern: the developer works on their own branch and merges FlutterFlow's updates in through pull requests. Agree on this on day one.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Decide where the visual editor stops.&lt;/strong&gt; Code a developer edits in Git doesn't flow back into FlutterFlow's canvas. The VS Code extension syncs custom code files in both directions, but only on Growth and up (&lt;a href="https://docs.flutterflow.io/concepts/custom-code/vscode-extension/" rel="noopener noreferrer"&gt;VS Code extension&lt;/a&gt;). Decide whether you'll keep building visually or hand the codebase over fully.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Generated code may need restructuring.&lt;/strong&gt; Every page gets its own widget and model file, and utilities sit in &lt;code&gt;lib/flutter_flow/&lt;/code&gt; (&lt;a href="https://docs.flutterflow.io/generated-code/project-structure/" rel="noopener noreferrer"&gt;project structure&lt;/a&gt;). The code works, but a developer may want to reorganise it before adding large features.&lt;/p&gt;

&lt;h2&gt;
  
  
  A worked example (hypothetical)
&lt;/h2&gt;

&lt;p&gt;&lt;em&gt;Illustrative only, not a Banxal client.&lt;/em&gt;&lt;/p&gt;

&lt;p&gt;A founder runs a FlutterFlow booking app on the Basic plan, using Firebase, live in both stores. They've hired a Flutter developer to add payments and a tutor dashboard.&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;
&lt;strong&gt;Self-check.&lt;/strong&gt; Download Code works, but there's no GitHub connection (that needs Growth). The Apple membership is individual, and a freelancer created the &lt;code&gt;.p8&lt;/code&gt; key last year — nobody can find it now.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Code.&lt;/strong&gt; The founder sends the ZIP; the developer sets up the repo in a GitHub organisation the founder owns.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Access.&lt;/strong&gt; The developer gets a scoped Firebase role, an App Manager role in App Store Connect limited to this app, and a 90-day Play Console invite.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Keys.&lt;/strong&gt; The founder revokes the lost key, creates a new one, and stores it in a shared vault.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Rules.&lt;/strong&gt; The developer's first job: lock the bookings collection so tutors only see their own sessions.&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;It takes the founder an afternoon, and the developer starts on features right away.&lt;/p&gt;

&lt;h2&gt;
  
  
  When to rebuild instead
&lt;/h2&gt;

&lt;p&gt;A handoff only makes sense if the foundations are worth keeping. On Adalo or Glide, getting code you own means a rebuild: your data comes with you, but the screens and logic don't. On FlutterFlow, the deciding question is the data model. If your collections still match how the business works, harden what you have; if they don't, every new feature will fight it. Our &lt;a href="https://banxal.com/blog/fix-or-rebuild-vibe-coded-app" rel="noopener noreferrer"&gt;fix-or-rebuild self-test&lt;/a&gt; takes 30 minutes.&lt;/p&gt;

&lt;h2&gt;
  
  
  Choosing who takes over
&lt;/h2&gt;

&lt;p&gt;Look for someone who reads Dart comfortably, has shipped Flutter apps through both stores, and has an opinion on FlutterFlow's generated code. Good candidates ask to be invited, not for your passwords, and bring up the &lt;code&gt;flutterflow&lt;/code&gt; branch before you do. Our guide to &lt;a href="https://banxal.com/blog/vet-developer-fix-vibe-coded-app" rel="noopener noreferrer"&gt;vetting a developer&lt;/a&gt; has interview questions and red-flag answers that carry over to mobile.&lt;/p&gt;

&lt;h2&gt;
  
  
  FAQ
&lt;/h2&gt;

&lt;p&gt;&lt;strong&gt;Can I export a FlutterFlow app and keep editing it in FlutterFlow?&lt;/strong&gt;&lt;br&gt;
Yes. FlutterFlow pushes to its &lt;code&gt;flutterflow&lt;/code&gt; branch, and you merge that into your own branch. Changes the developer makes to generated code don't come back into the editor (&lt;a href="https://docs.flutterflow.io/exporting/push-to-github/" rel="noopener noreferrer"&gt;GitHub docs&lt;/a&gt;).&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Do I need the Growth plan to hand off?&lt;/strong&gt;&lt;br&gt;
No. Code Download is available on Basic, so you can send a ZIP. Push to GitHub and real-time collaboration need Growth or higher (&lt;a href="https://docs.flutterflow.io/accounts-billing/plan-comparison/" rel="noopener noreferrer"&gt;plan comparison&lt;/a&gt;).&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Should I give the developer my Apple or Google login?&lt;/strong&gt;&lt;br&gt;
No. Both stores let you add users with limited roles, and Google lets you set an expiry date. Shared logins mean you can't remove one person later.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;I built on Adalo. Can I get the code?&lt;/strong&gt;&lt;br&gt;
Not today. Adalo staff confirmed in August 2025 that it isn't possible (&lt;a href="https://forum.adalo.com/t/source-code-of-an-application-built-with-adalo/57905" rel="noopener noreferrer"&gt;Adalo forum&lt;/a&gt;). Export your collections as CSV and plan a move to code as a rebuild.&lt;/p&gt;

&lt;h2&gt;
  
  
  Next step
&lt;/h2&gt;

&lt;p&gt;Most of a mobile handoff is admin, but some of it can't be undone. Banxal builds cross-platform iOS and Android apps, and our &lt;a href="https://banxal.com/services" rel="noopener noreferrer"&gt;product maintenance and growth&lt;/a&gt; work covers apps other people started too. Want a second opinion on your export, access and security rules before you commit to a developer? &lt;a href="https://banxal.com/contact" rel="noopener noreferrer"&gt;Get in touch&lt;/a&gt; and tell us what you've built.&lt;/p&gt;

&lt;p&gt;What worries you most about handing over a no-code app: the code, the store accounts or the data? Let us know in the comments.&lt;/p&gt;




&lt;p&gt;&lt;em&gt;Originally published on &lt;a href="https://banxal.com/blog/handoff-flutterflow-app-to-developer" rel="noopener noreferrer"&gt;banxal.com&lt;/a&gt;.&lt;/em&gt;&lt;/p&gt;

</description>
      <category>flutter</category>
      <category>flutterflow</category>
      <category>nocode</category>
      <category>mobile</category>
    </item>
    <item>
      <title>Backend Validation: AI Will Find the Gaps Your UI Hides</title>
      <dc:creator>Manveer</dc:creator>
      <pubDate>Sun, 11 Oct 2026 15:56:01 +0000</pubDate>
      <link>https://dev.to/manveer-banxal/backend-validation-ai-will-find-the-gaps-your-ui-hides-1b2o</link>
      <guid>https://dev.to/manveer-banxal/backend-validation-ai-will-find-the-gaps-your-ui-hides-1b2o</guid>
      <description>&lt;p&gt;Your checkout page has a discount field: type a code, the price drops 10%; type a wrong one, the button greys out. You tested it and it works — what you probably didn't test is the backend validation behind it.&lt;/p&gt;

&lt;p&gt;Now look at what the browser actually sends on "Pay": the cart, the code, and in a surprising number of apps, a &lt;code&gt;total&lt;/code&gt; the page worked out for itself. If the server accepts that number as-is, the only thing stopping a 100% discount is JavaScript running in a browser the customer controls.&lt;/p&gt;

&lt;p&gt;&lt;em&gt;That's a hypothetical, not a client. But OWASP uses the same pattern in its own examples: a booking API that let hosts change a &lt;code&gt;total_stay_price&lt;/code&gt; field they should never have been able to touch (&lt;a href="https://api-security.owasp.org/editions/2023/en/0xa3-broken-object-property-level-authorization/" rel="noopener noreferrer"&gt;OWASP API3&lt;/a&gt;).&lt;/em&gt;&lt;/p&gt;

&lt;p&gt;Gaps like this used to stay hidden because finding them took a patient human with developer tools open — not anymore. &lt;strong&gt;Backend validation&lt;/strong&gt;, enforcing every rule on the server and not just the page, is now the minimum for any live app, because AI has made hunting for these gaps cheap, fast and tireless. This post covers why, the gaps AI finds first, a checklist, and a 15-minute self-check for you and your developer.&lt;/p&gt;

&lt;h2&gt;
  
  
  TL;DR
&lt;/h2&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;Your frontend is a suggestion.&lt;/strong&gt; Anyone can skip a browser-only rule by sending requests directly, and AI tools now do this at machine speed.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;It's not only attackers.&lt;/strong&gt; Browser agents, AI assistants and MCP tools use your app in ways your UI never planned for — treat every request as if it didn't come from your page.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Fix it on the server.&lt;/strong&gt; Validate every input, check ownership on every record, accept only expected fields, recalculate prices and states yourself, rate-limit, and keep error messages boring.&lt;/li&gt;
&lt;/ul&gt;

&lt;h2&gt;
  
  
  Why AI changes the economics of finding loopholes
&lt;/h2&gt;

&lt;p&gt;Probing an app was always possible — what's changed is the cost, and the evidence is piling up:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;Exploiting known weaknesses.&lt;/strong&gt; In a 2024 University of Illinois study, a GPT-4 agent exploited 87% of 15 real-world "one-day" vulnerabilities when given the public description — every other model and the open-source scanners tested managed 0% (&lt;a href="https://arxiv.org/abs/2404.08144" rel="noopener noreferrer"&gt;Fang et al., 2024&lt;/a&gt;). Without the description, success fell to 7%: agents are far better at exploiting &lt;em&gt;known classes&lt;/em&gt; of weakness than at finding new ones.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Finding what fuzzing missed.&lt;/strong&gt; Google's Big Sleep agent found a SQLite bug that "remained undiscovered after 150 CPU-hours of fuzzing" — Google calls it "the first public example of an AI agent finding a previously unknown exploitable memory-safety issue in widely used real-world software" (&lt;a href="https://projectzero.google/2024/10/from-naptime-to-big-sleep.html" rel="noopener noreferrer"&gt;Project Zero&lt;/a&gt;).&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Doing it at scale, cheaply.&lt;/strong&gt; In DARPA's AI Cyber Challenge final, the teams' systems analysed over 54 million lines of code, found 86% of the planted vulnerabilities, turned up 18 real ones nobody had planted, and cost "about $152" per task (&lt;a href="https://www.darpa.mil/news/2025/aixcc-results" rel="noopener noreferrer"&gt;DARPA&lt;/a&gt;).&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Attackers are already using it.&lt;/strong&gt; Anthropic reported a campaign where a threat actor used AI for "80-90% of the campaign", making "thousands of requests, often multiple per second", though the AI "occasionally hallucinated credentials" (&lt;a href="https://www.anthropic.com/news/disrupting-AI-espionage" rel="noopener noreferrer"&gt;Anthropic&lt;/a&gt;) — it isn't magic, but it doesn't get tired.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.us-east-2.amazonaws.com%2Fuploads%2Farticles%2Fglep5vz2hta3ow23qbv2.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.us-east-2.amazonaws.com%2Fuploads%2Farticles%2Fglep5vz2hta3ow23qbv2.png" alt="Stat card: a GPT-4 agent exploited 87% of 15 real one-day vulnerabilities when given the public description, versus 7% without it (Fang et al., 2024); DARPA's AIxCC final found 86% of planted bugs at about $152 per task. Caption: AI is very good at exploiting known classes of weakness — missing server-side checks are one." width="799" height="373"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;What does that mean for a normal web app? The gaps in your app aren't famous CVEs — they're the same documented &lt;strong&gt;API security&lt;/strong&gt; weakness classes OWASP has tracked for years. An AI-assisted tester reads your JavaScript bundle for every route your frontend knows, checks every field in every API response your UI hides, and tries the combinations a human would get bored of: every ID, every optional parameter, every out-of-range value. None of that takes cleverness — just patience, which now costs almost nothing.&lt;/p&gt;

&lt;h2&gt;
  
  
  Even friendly AI uses your backend differently
&lt;/h2&gt;

&lt;p&gt;There's a second shift that gets less attention in most &lt;strong&gt;server-side validation&lt;/strong&gt; advice: AI acting for your &lt;em&gt;real&lt;/em&gt; users.&lt;/p&gt;

&lt;p&gt;Computer-use agents can "take screenshots, control the mouse, and type on the keyboard" (&lt;a href="https://platform.claude.com/docs/en/docs/agents-and-tools/tool-use/computer-use-tool" rel="noopener noreferrer"&gt;Anthropic docs&lt;/a&gt;), and the Model Context Protocol lets assistants like Claude or ChatGPT connect to tools and "perform tasks" (&lt;a href="https://modelcontextprotocol.io/docs/getting-started/intro" rel="noopener noreferrer"&gt;MCP&lt;/a&gt;). An honest customer's assistant might skip a step, retry a payment, enter a value your dropdown would never offer, or call your API through an integration someone else built — no harm meant, but it still breaks the "form only allows 1 to 10" assumption.&lt;/p&gt;

&lt;p&gt;OWASP's own advice for protecting sensitive business flows includes "denying service to unexpected client devices (e.g headless browsers)" (&lt;a href="https://api-security.owasp.org/editions/2023/en/0xa6-unrestricted-access-to-sensitive-business-flows/" rel="noopener noreferrer"&gt;OWASP API6&lt;/a&gt;). That helps, but as agents become an ordinary way to use the web, blocking anything that isn't "a human in Chrome" turns away more real traffic. The defence that lasts is making &lt;strong&gt;every request safe on its own merits&lt;/strong&gt; — valid, authorised and within limits, whoever or whatever sent it. The same goes for your own AI features: OWASP's guidance for LLM apps is blunt — "Implement authorization in downstream systems rather than relying on an LLM to decide if an action is allowed or not" (&lt;a href="https://genai.owasp.org/llmrisk/llm062025-excessive-agency/" rel="noopener noreferrer"&gt;OWASP LLM06&lt;/a&gt;).&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.us-east-2.amazonaws.com%2Fuploads%2Farticles%2Fp0nxkchwh0xocxkianpo.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.us-east-2.amazonaws.com%2Fuploads%2Farticles%2Fp0nxkchwh0xocxkianpo.png" alt="Side-by-side flow diagram comparing frontend-only and backend-enforced requests. Left, " width="800" height="507"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;h2&gt;
  
  
  What AI will poke at first: 8 common gaps
&lt;/h2&gt;

&lt;p&gt;These are classes of weakness, not attack recipes. Each comes with the fix.&lt;/p&gt;

&lt;h3&gt;
  
  
  1. Missing ownership checks (BOLA / IDOR)
&lt;/h3&gt;

&lt;p&gt;Your invoice page loads &lt;code&gt;/api/invoices/1042&lt;/code&gt;. What happens if a logged-in user asks for 1043? OWASP ranks this #1 in its API Top 10, calling it "extremely common in API-based applications" with widespread prevalence (&lt;a href="https://api-security.owasp.org/editions/2023/en/0xa1-broken-object-level-authorization/" rel="noopener noreferrer"&gt;OWASP API1&lt;/a&gt;).&lt;br&gt;
&lt;strong&gt;Fix:&lt;/strong&gt; every function loading a record by a client-supplied ID must check the current user can access &lt;em&gt;that record&lt;/em&gt;.&lt;/p&gt;
&lt;h3&gt;
  
  
  2. Hidden fields the server trusts (mass assignment)
&lt;/h3&gt;

&lt;p&gt;Your profile form sends name and email, but the user record also has &lt;code&gt;role&lt;/code&gt;, &lt;code&gt;plan&lt;/code&gt; or &lt;code&gt;isAdmin&lt;/code&gt;. If the server copies the whole request body into the record, those extra fields go through too — OWASP's cheat sheet uses exactly this &lt;code&gt;isAdmin&lt;/code&gt; example (&lt;a href="https://cheatsheetseries.owasp.org/cheatsheets/Mass_Assignment_Cheat_Sheet.html" rel="noopener noreferrer"&gt;OWASP&lt;/a&gt;).&lt;br&gt;
&lt;strong&gt;Fix:&lt;/strong&gt; allowlist the fields each endpoint accepts — denylisting fails when next month's new column isn't on the list.&lt;/p&gt;
&lt;h3&gt;
  
  
  3. Responses that say too much
&lt;/h3&gt;

&lt;p&gt;The UI shows a user's first name, but the API sends back the whole user object. OWASP's own example: a dating app's report feature that exposed a user's full name and recent location (&lt;a href="https://api-security.owasp.org/editions/2023/en/0xa3-broken-object-property-level-authorization/" rel="noopener noreferrer"&gt;OWASP API3&lt;/a&gt;).&lt;br&gt;
&lt;strong&gt;Fix:&lt;/strong&gt; return only the minimum each screen needs — OWASP advises avoiding generic serialisers such as &lt;code&gt;to_json()&lt;/code&gt;.&lt;/p&gt;
&lt;h3&gt;
  
  
  4. Prices, totals and quantities worked out in the browser
&lt;/h3&gt;

&lt;p&gt;The discount example above. Watch too for negative quantities, zero-priced add-ons and overused discount codes.&lt;br&gt;
&lt;strong&gt;Fix:&lt;/strong&gt; the server calculates every amount itself, and checks discount codes and their usage limits.&lt;/p&gt;
&lt;h3&gt;
  
  
  5. Skipped steps and impossible state changes
&lt;/h3&gt;

&lt;p&gt;An order jumps from &lt;code&gt;pending&lt;/code&gt; straight to &lt;code&gt;shipped&lt;/code&gt;, sign-up step 3 arrives without step 2, or a booking ends before it starts. OWASP calls this semantic validation — checking "whether the value makes sense for the operation", not just its format (&lt;a href="https://cheatsheetseries.owasp.org/cheatsheets/Input_Validation_Cheat_Sheet.html" rel="noopener noreferrer"&gt;OWASP Input Validation&lt;/a&gt;).&lt;br&gt;
&lt;strong&gt;Fix:&lt;/strong&gt; define the allowed transitions on the server, and reject everything else.&lt;/p&gt;
&lt;h3&gt;
  
  
  6. Inputs outside what the form allows
&lt;/h3&gt;

&lt;p&gt;Your form caps a message at 500 characters, but the API accepts 5 MB. A &lt;code&gt;pageSize&lt;/code&gt; of 100,000 returns your whole customer table. OWASP's advice: "define and enforce a maximum size of data on all incoming parameters and payloads" (&lt;a href="https://api-security.owasp.org/editions/2023/en/0xa4-unrestricted-resource-consumption/" rel="noopener noreferrer"&gt;OWASP API4&lt;/a&gt;).&lt;br&gt;
&lt;strong&gt;Fix:&lt;/strong&gt; check type, length, range and format for every field against an allowlist.&lt;/p&gt;
&lt;h3&gt;
  
  
  7. No limits on expensive or sensitive actions
&lt;/h3&gt;

&lt;p&gt;Sign-up, one-time codes, password resets, booking slots, and AI features billed per call. OWASP's examples: buying up all stock to resell, or reserving every available slot (&lt;a href="https://api-security.owasp.org/editions/2023/en/0xa6-unrestricted-access-to-sensitive-business-flows/" rel="noopener noreferrer"&gt;OWASP API6&lt;/a&gt;).&lt;br&gt;
&lt;strong&gt;Fix:&lt;/strong&gt; rate-limit each user and action, and "configure spending limits for all service providers/API integrations" or at least set billing alerts (&lt;a href="https://api-security.owasp.org/editions/2023/en/0xa4-unrestricted-resource-consumption/" rel="noopener noreferrer"&gt;OWASP API4&lt;/a&gt;).&lt;/p&gt;
&lt;h3&gt;
  
  
  8. Forgotten endpoints, weak admin checks and chatty errors
&lt;/h3&gt;

&lt;p&gt;Old &lt;code&gt;/v1&lt;/code&gt; routes, debug endpoints, and admin routes that check login but not role. The OWASP Top 10 lists both broken function-level authorization and improper inventory management, noting that APIs "tend to expose more endpoints than traditional web applications" (&lt;a href="https://api-security.owasp.org/editions/2023/en/0x11-t10" rel="noopener noreferrer"&gt;OWASP API Top 10&lt;/a&gt;). Detailed error messages tell a prober exactly what to try next.&lt;br&gt;
&lt;strong&gt;Fix:&lt;/strong&gt; keep a list of every live endpoint, delete the ones you don't use, check roles on every admin action, and return generic errors while logging the details on the server.&lt;/p&gt;
&lt;h2&gt;
  
  
  The backend validation checklist
&lt;/h2&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.us-east-2.amazonaws.com%2Fuploads%2Farticles%2Fzu765cs8beren69zhfk2.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.us-east-2.amazonaws.com%2Fuploads%2Farticles%2Fzu765cs8beren69zhfk2.png" alt="One-page backend validation checklist with five grouped sections and tick boxes: input, authorization, business rules, limits, and output and errors." width="800" height="467"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Work through these five groups with your developer — each line is a yes/no check, not a project.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Input&lt;/strong&gt;&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;[ ] Every endpoint checks its request against a schema: types, lengths, ranges, formats.&lt;/li&gt;
&lt;li&gt;[ ] Unknown fields are rejected, not silently ignored or saved.&lt;/li&gt;
&lt;li&gt;[ ] Choices (country, plan, status) are checked against an allowlist.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;&lt;strong&gt;Authorization&lt;/strong&gt;&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;[ ] The user's identity comes from the session or token, never from the request body.&lt;/li&gt;
&lt;li&gt;[ ] Every record lookup checks ownership or permission.&lt;/li&gt;
&lt;li&gt;[ ] Admin and staff actions check the role on the server every time.&lt;/li&gt;
&lt;li&gt;[ ] If your frontend talks directly to the database (common in Supabase apps), row-level security is on for every table — Supabase: "A table in an exposed schema without RLS is readable and writable by any role with a grant on it" (&lt;a href="https://supabase.com/docs/guides/database/postgres/row-level-security" rel="noopener noreferrer"&gt;Supabase&lt;/a&gt;).&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;&lt;strong&gt;Business rules&lt;/strong&gt;&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;[ ] Prices, totals, discounts and credits are calculated on the server.&lt;/li&gt;
&lt;li&gt;[ ] State changes follow an allowed list.&lt;/li&gt;
&lt;li&gt;[ ] One-time things (codes, trials, referrals) are enforced as one-time in the database.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;&lt;strong&gt;Limits&lt;/strong&gt;&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;[ ] Rate limits on login, sign-up, codes, resets and anything that costs you money.&lt;/li&gt;
&lt;li&gt;[ ] Maximum page sizes, upload sizes and request sizes.&lt;/li&gt;
&lt;li&gt;[ ] Spending caps or alerts on third-party and AI APIs.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;&lt;strong&gt;Output and errors&lt;/strong&gt;&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;[ ] Responses include only the fields that screen needs.&lt;/li&gt;
&lt;li&gt;[ ] Errors are generic to the user and detailed in your logs.&lt;/li&gt;
&lt;li&gt;[ ] Unused endpoints are removed, not just hidden from the UI.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Here's the shape of it in code. This is a TypeScript example using the Zod validation library; every framework has an equivalent:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight typescript"&gt;&lt;code&gt;&lt;span class="c1"&gt;// Only these fields are accepted. Anything else (role, plan, isAdmin) is rejected.&lt;/span&gt;
&lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;UpdateProfile&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nx"&gt;z&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;object&lt;/span&gt;&lt;span class="p"&gt;({&lt;/span&gt;
  &lt;span class="na"&gt;displayName&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nx"&gt;z&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;string&lt;/span&gt;&lt;span class="p"&gt;().&lt;/span&gt;&lt;span class="nf"&gt;trim&lt;/span&gt;&lt;span class="p"&gt;().&lt;/span&gt;&lt;span class="nf"&gt;min&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="mi"&gt;1&lt;/span&gt;&lt;span class="p"&gt;).&lt;/span&gt;&lt;span class="nf"&gt;max&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="mi"&gt;80&lt;/span&gt;&lt;span class="p"&gt;),&lt;/span&gt;
  &lt;span class="na"&gt;timezone&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nx"&gt;z&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;enum&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;ALLOWED_TIMEZONES&lt;/span&gt;&lt;span class="p"&gt;),&lt;/span&gt;
&lt;span class="p"&gt;}).&lt;/span&gt;&lt;span class="nf"&gt;strict&lt;/span&gt;&lt;span class="p"&gt;();&lt;/span&gt;

&lt;span class="nx"&gt;app&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;patch&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;/api/profile&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;requireUser&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="k"&gt;async &lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;req&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;res&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="o"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
  &lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;parsed&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nx"&gt;UpdateProfile&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;safeParse&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;req&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;body&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
  &lt;span class="k"&gt;if &lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="o"&gt;!&lt;/span&gt;&lt;span class="nx"&gt;parsed&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;success&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="nx"&gt;res&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;status&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="mi"&gt;400&lt;/span&gt;&lt;span class="p"&gt;).&lt;/span&gt;&lt;span class="nf"&gt;json&lt;/span&gt;&lt;span class="p"&gt;({&lt;/span&gt; &lt;span class="na"&gt;error&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;Invalid input&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt; &lt;span class="p"&gt;});&lt;/span&gt;

  &lt;span class="c1"&gt;// Who is being updated comes from the session, never from the request.&lt;/span&gt;
  &lt;span class="k"&gt;await&lt;/span&gt; &lt;span class="nx"&gt;db&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;user&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;update&lt;/span&gt;&lt;span class="p"&gt;({&lt;/span&gt; &lt;span class="na"&gt;where&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="na"&gt;id&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nx"&gt;req&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;user&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;id&lt;/span&gt; &lt;span class="p"&gt;},&lt;/span&gt; &lt;span class="na"&gt;data&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nx"&gt;parsed&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;data&lt;/span&gt; &lt;span class="p"&gt;});&lt;/span&gt;
  &lt;span class="nx"&gt;res&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;status&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="mi"&gt;204&lt;/span&gt;&lt;span class="p"&gt;).&lt;/span&gt;&lt;span class="nf"&gt;end&lt;/span&gt;&lt;span class="p"&gt;();&lt;/span&gt;
&lt;span class="p"&gt;});&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Keep your client-side checks — OWASP's position is that client-side validation "is bypassable; use it for immediate feedback" (&lt;a href="https://cheatsheetseries.owasp.org/cheatsheets/Input_Validation_Cheat_Sheet.html" rel="noopener noreferrer"&gt;OWASP Input Validation&lt;/a&gt;). It's for user experience, not security.&lt;/p&gt;

&lt;h2&gt;
  
  
  A 15-minute self-check for founders
&lt;/h2&gt;

&lt;p&gt;You don't need to be technical for this. Only test your own app, using accounts you own.&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;
&lt;strong&gt;The two-account test.&lt;/strong&gt; Log in as user A, copy the URL of one of A's records (order, invoice or project). In a private window, log in as user B and paste it — you should get "not found" or "forbidden", never A's data.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Look at one response.&lt;/strong&gt; In Chrome, open DevTools → Network, reload your profile page, and read the API response. Is there anything the screen doesn't show — other people's emails, internal flags, password fields?&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Ask your developer five questions:&lt;/strong&gt;

&lt;ul&gt;
&lt;li&gt;"Where is the price calculated — browser or server?"&lt;/li&gt;
&lt;li&gt;"If a request included &lt;code&gt;role: admin&lt;/code&gt;, what would happen?"&lt;/li&gt;
&lt;li&gt;"What stops 10,000 calls to sign-up, password reset or our AI feature?"&lt;/li&gt;
&lt;li&gt;"Do we have a list of every live endpoint, with old ones removed?"&lt;/li&gt;
&lt;li&gt;"If we use Supabase or Firebase, is row-level security on for every table?"&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;Confident, specific answers are a good sign; "the frontend handles that" means you have work to do. Built with Lovable, Bolt or similar? Our &lt;a href="https://banxal.com/blog/fix-or-rebuild-vibe-coded-app" rel="noopener noreferrer"&gt;fix-or-rebuild self-test&lt;/a&gt; sizes the work, and our &lt;a href="https://banxal.com/blog/handoff-lovable-bolt-app-to-developer" rel="noopener noreferrer"&gt;handoff guide&lt;/a&gt; covers rotating secrets before a developer starts. Hiring someone to fix it? &lt;a href="https://banxal.com/blog/vet-developer-fix-vibe-coded-app" rel="noopener noreferrer"&gt;These vetting questions&lt;/a&gt; show who actually understands this — and if you're adding a chatbot, the &lt;a href="https://banxal.com/blog/ai-chatbot-own-data-readiness-checklist" rel="noopener noreferrer"&gt;data-readiness checklist&lt;/a&gt; keeps private data out of its reach.&lt;/p&gt;

&lt;h2&gt;
  
  
  Want a second pair of eyes on your backend?
&lt;/h2&gt;

&lt;p&gt;Banxal's &lt;strong&gt;product maintenance &amp;amp; growth&lt;/strong&gt; work covers ongoing improvements to products we or others built — including apps whose rules live only in the frontend. Planning something new? Our &lt;strong&gt;web applications &amp;amp; SaaS&lt;/strong&gt; builds include auth, payments and admin from day one. &lt;a href="https://banxal.com/contact" rel="noopener noreferrer"&gt;Tell us what your app does and how it's built&lt;/a&gt; and we'll tell you plainly where we'd look first.&lt;/p&gt;

&lt;h2&gt;
  
  
  FAQ
&lt;/h2&gt;

&lt;h3&gt;
  
  
  Is client-side validation useless, then?
&lt;/h3&gt;

&lt;p&gt;No — but client-side validation is not enough on its own. It gives users instant feedback and saves pointless round trips; it just isn't security, since anyone who sends requests directly can skip it. Do both, and treat the server as the one that counts.&lt;/p&gt;

&lt;h3&gt;
  
  
  What's the difference between backend validation and authorization?
&lt;/h3&gt;

&lt;p&gt;Validation asks "is this request well-formed and sensible?" Authorization asks "is &lt;em&gt;this user&lt;/em&gt; allowed to do &lt;em&gt;this&lt;/em&gt; to &lt;em&gt;this record&lt;/em&gt;?" Most serious API problems in the OWASP Top 10 are authorization failures — a request can pass validation and still be dangerous.&lt;/p&gt;

&lt;h3&gt;
  
  
  Do I need a penetration test?
&lt;/h3&gt;

&lt;p&gt;Work through the checklist first — paying a tester to find a missing ownership check you could catch yourself with two accounts in five minutes is expensive. Once the basics are in place, a professional test is worth it, especially if you handle payments, health data or other sensitive personal data.&lt;/p&gt;

&lt;h3&gt;
  
  
  Can I use AI to find these gaps before someone else does?
&lt;/h3&gt;

&lt;p&gt;Yes — that's the other half of the story. DARPA says all seven AIxCC finalist systems "will be made available as open-source software" (&lt;a href="https://www.darpa.mil/news/2025/aixcc-results" rel="noopener noreferrer"&gt;DARPA&lt;/a&gt;), and AI code review can flag missing checks. Treat what it finds as leads to verify, not a clean bill of health.&lt;/p&gt;




&lt;p&gt;Which rule in your app do you suspect lives only in the frontend: a price, a role, a limit? Tell us in the comments.&lt;/p&gt;




&lt;p&gt;&lt;em&gt;Originally published on &lt;a href="https://banxal.com/blog/backend-validation-ai-finds-loopholes" rel="noopener noreferrer"&gt;banxal.com&lt;/a&gt;.&lt;/em&gt;&lt;/p&gt;

</description>
      <category>security</category>
      <category>api</category>
      <category>webdev</category>
      <category>ai</category>
    </item>
    <item>
      <title>Chatbot Trained on Your Own Data? A Readiness Checklist</title>
      <dc:creator>Manveer</dc:creator>
      <pubDate>Fri, 09 Oct 2026 07:05:50 +0000</pubDate>
      <link>https://dev.to/manveer-banxal/chatbot-trained-on-your-own-data-a-readiness-checklist-4mj1</link>
      <guid>https://dev.to/manveer-banxal/chatbot-trained-on-your-own-data-a-readiness-checklist-4mj1</guid>
      <description>&lt;p&gt;A customer asks the chatbot on your website if you're open on the bank holiday Monday. It answers straight away and politely: yes, 9am to 5pm.&lt;/p&gt;

&lt;p&gt;You're closed. The bot found its answer in an old opening-hours PDF that nobody remembered was still in the shared folder.&lt;/p&gt;

&lt;p&gt;The AI did its job. The data was the problem. Most guides to building a &lt;strong&gt;chatbot trained on your own data&lt;/strong&gt; stop at the upload button. This post covers what comes before it: how these chatbots work in plain English, a data-readiness checklist, a hypothetical worked example, and an honest test of whether you need one at all.&lt;/p&gt;

&lt;h2&gt;
  
  
  TL;DR
&lt;/h2&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;It isn't really "trained" on your data.&lt;/strong&gt; Most of these chatbots use RAG (retrieval-augmented generation). When someone asks a question, the system looks up matching passages in your documents and answers from them. The AI model itself never changes.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Your documents decide the quality.&lt;/strong&gt; If a file is outdated, contradicts another file or contains private details, the bot will repeat it to customers, and it will sound sure of itself.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Try the simple option first.&lt;/strong&gt; If customers mostly ask the same short list of questions, an FAQ widget may be enough. If all your material is small, you can often give the AI the whole lot at once and skip RAG.&lt;/li&gt;
&lt;/ul&gt;

&lt;h2&gt;
  
  
  Do you actually need a RAG chatbot — or will an FAQ widget do?
&lt;/h2&gt;

&lt;p&gt;Often you don't — there are three options, each more work to run well than the last.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;1. An FAQ widget or help-centre search.&lt;/strong&gt; You write the answers; the widget shows them. Nothing is generated, so nothing is made up. If most questions are repeats ("Do you deliver to…?", "What's your returns window?"), this is predictable and cheap.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;2. An AI assistant that reads everything, every time.&lt;/strong&gt; If your material is small, skip retrieval and give the AI all of it with each question. Anthropic: "If your knowledge base is smaller than 200,000 tokens (about 500 pages of material), you can just include the entire knowledge base in the prompt" (&lt;a href="https://www.anthropic.com/news/contextual-retrieval" rel="noopener noreferrer"&gt;Anthropic&lt;/a&gt;). The trade-off is that you pay for reading it on every message. Our guide to &lt;a href="https://banxal.com/blog/ai-agent-cost-per-month" rel="noopener noreferrer"&gt;AI agent cost per month&lt;/a&gt; shows how to work that out.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;3. A RAG chatbot.&lt;/strong&gt; Worth it when your material is too big for one prompt, changes often (stock, prices, policies), needs to be shown to some people and hidden from others, or answers must cite their source.&lt;/p&gt;

&lt;p&gt;One more check: if answering means &lt;em&gt;looking something up in a live system&lt;/em&gt; ("Where's my order?", "Is Tuesday at 3pm free?"), you're not dealing with a document problem. You need an integration or an agent. See &lt;a href="https://banxal.com/blog/zapier-n8n-or-ai-agent" rel="noopener noreferrer"&gt;Zapier, n8n or an AI agent&lt;/a&gt;.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.us-east-2.amazonaws.com%2Fuploads%2Farticles%2Fnkg01xd4nk628yzv2v55.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.us-east-2.amazonaws.com%2Fuploads%2Farticles%2Fnkg01xd4nk628yzv2v55.png" alt="Decision gate flowchart " width="800" height="520"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;h2&gt;
  
  
  How a chatbot trained on your own data actually works
&lt;/h2&gt;

&lt;p&gt;A correction first: for most of these tools, "trained on your own data" isn't quite accurate. AWS describes RAG as having a model reference "an authoritative knowledge base outside of its training data sources before generating a response", "all without the need to retrain the model" (&lt;a href="https://aws.amazon.com/what-is/retrieval-augmented-generation/" rel="noopener noreferrer"&gt;AWS&lt;/a&gt;). IBM draws the same line: "RAG lets an LLM query an external data source while fine-tuning trains an LLM on domain-specific data" (&lt;a href="https://www.ibm.com/think/topics/retrieval-augmented-generation" rel="noopener noreferrer"&gt;IBM&lt;/a&gt;).&lt;/p&gt;

&lt;p&gt;Think of a capable new hire with a filing cabinet. They don't memorise it; when a question comes in, they pull the right folder and answer from that page. Updating is cheap (swap the page), and the cabinet is the weak point (a bad page means a bad answer).&lt;/p&gt;

&lt;p&gt;Here's the pipeline behind that picture.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.us-east-2.amazonaws.com%2Fuploads%2Farticles%2F38eah9c2pczc4kx1lk2v.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.us-east-2.amazonaws.com%2Fuploads%2Farticles%2F38eah9c2pczc4kx1lk2v.png" alt="Left-to-right RAG pipeline diagram: your documents, chunks, embeddings, retrieval, grounded answer — with a dashed loop showing embeddings update when documents change" width="799" height="373"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;
&lt;strong&gt;Documents.&lt;/strong&gt; Gather your source material and clean it up. Pinecone's walkthrough describes cleaning the data &lt;em&gt;before&lt;/em&gt; anything else happens (&lt;a href="https://www.pinecone.io/learn/retrieval-augmented-generation/" rel="noopener noreferrer"&gt;Pinecone&lt;/a&gt;).&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Chunks.&lt;/strong&gt; Long documents are split into short passages. OpenAI's hosted version, for example, splits files into 800-token pieces (a token is roughly a word or part of a word) with a 400-token overlap by default (&lt;a href="https://developers.openai.com/api/docs/guides/retrieval" rel="noopener noreferrer"&gt;OpenAI&lt;/a&gt;).&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Embeddings.&lt;/strong&gt; Each chunk is turned into a list of numbers, "a numerical representation of the data's meaning" (&lt;a href="https://www.pinecone.io/learn/retrieval-augmented-generation/" rel="noopener noreferrer"&gt;Pinecone&lt;/a&gt;), and stored in a vector database (&lt;a href="https://aws.amazon.com/what-is/retrieval-augmented-generation/" rel="noopener noreferrer"&gt;AWS&lt;/a&gt;).&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Retrieval.&lt;/strong&gt; The customer's question is turned into numbers the same way and matched against the stored chunks. This is how "Can I bring my dog?" can find a passage titled "Pet policy" even though the words barely overlap. OpenAI notes that semantic search surfaces similar results "even when they match few or no keywords" (&lt;a href="https://developers.openai.com/api/docs/guides/retrieval" rel="noopener noreferrer"&gt;OpenAI&lt;/a&gt;).&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Grounded answer.&lt;/strong&gt; The question and the matching passages go to the AI model, which writes the answer from them. Both AWS and IBM point out that RAG systems can cite their sources, so you and your customers can check them.&lt;/li&gt;
&lt;/ol&gt;

&lt;h3&gt;
  
  
  Two things that trip up real chatbots
&lt;/h3&gt;

&lt;p&gt;&lt;strong&gt;Chunks lose their context.&lt;/strong&gt; Anthropic's example is a passage that reads, on its own, "The company's revenue grew by 3% over the previous quarter." Which company? Which quarter? (&lt;a href="https://www.anthropic.com/news/contextual-retrieval" rel="noopener noreferrer"&gt;Anthropic&lt;/a&gt;). The small-business version: a price-list line saying "£60, includes follow-up" whose heading got split off. Anthropic's fix was to add context to each chunk before storing it and pair meaning-based search with keyword search. In their tests that cut failed retrievals by 49% (67% with an extra re-ranking step). You can do a version of this yourself in how you write your documents.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Exact codes need exact matching.&lt;/strong&gt; Search by meaning can miss precise identifiers. Anthropic's example is "Error code TS-999", which keyword matching finds reliably. If customers ask about SKUs, part numbers or plan names, add keyword search too.&lt;/p&gt;

&lt;h2&gt;
  
  
  The data-readiness checklist
&lt;/h2&gt;

&lt;p&gt;This decides whether your chatbot gives good answers, whichever tool you choose. Go through it before you upload anything.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.us-east-2.amazonaws.com%2Fuploads%2Farticles%2F369dx62mtqxbtjiflwv2.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.us-east-2.amazonaws.com%2Fuploads%2Farticles%2F369dx62mtqxbtjiflwv2.png" alt="One-page AI chatbot data-readiness checklist with five grouped sections and tick boxes: source-of-truth content, freshness and ownership, sensitive data and permissions, FAQ gap-check, and format cleanup" width="800" height="467"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;h3&gt;
  
  
  1. Source-of-truth content
&lt;/h3&gt;

&lt;ul&gt;
&lt;li&gt;[ ] List every place answers live today: website pages, help docs, PDFs, policy documents, saved email replies, and the things only staff know.&lt;/li&gt;
&lt;li&gt;[ ] Choose &lt;strong&gt;one&lt;/strong&gt; current version for each topic: prices, hours, returns, delivery, service descriptions.&lt;/li&gt;
&lt;li&gt;[ ] Exclude old versions, drafts and "v2-final-FINAL" duplicates. If two documents disagree, the bot may quote either one.&lt;/li&gt;
&lt;/ul&gt;

&lt;h3&gt;
  
  
  2. Freshness and ownership
&lt;/h3&gt;

&lt;ul&gt;
&lt;li&gt;[ ] Give every document an owner and a "last reviewed" date.&lt;/li&gt;
&lt;li&gt;[ ] Decide how changes reach the bot. AWS describes keeping RAG data current by updating the documents and their embeddings "through automated real-time processes or periodic batch processing" (&lt;a href="https://aws.amazon.com/what-is/retrieval-augmented-generation/" rel="noopener noreferrer"&gt;AWS&lt;/a&gt;). Either works; having no process doesn't. As IBM puts it, "Knowledge bases must be continually updated" (&lt;a href="https://www.ibm.com/think/topics/retrieval-augmented-generation" rel="noopener noreferrer"&gt;IBM&lt;/a&gt;).&lt;/li&gt;
&lt;li&gt;[ ] Flag anything seasonal or time-limited, such as holiday hours, promotions and price changes. These cause the most embarrassing wrong answers.&lt;/li&gt;
&lt;/ul&gt;

&lt;h3&gt;
  
  
  3. Sensitive data and permissions
&lt;/h3&gt;

&lt;ul&gt;
&lt;li&gt;[ ] Assume that &lt;strong&gt;anything in the knowledge base can be shown to anyone who can talk to the bot&lt;/strong&gt;, unless your setup deliberately filters it.&lt;/li&gt;
&lt;li&gt;[ ] Remove customer records, staff details, internal pricing or margins, contracts, and anything with passwords or account numbers.&lt;/li&gt;
&lt;li&gt;[ ] If you want a staff-only assistant as well as a public one, keep them in separate collections, or use a setup that filters by tags. OpenAI's version, for example, lets you tag files and filter searches "by user, region, date" and similar (&lt;a href="https://developers.openai.com/api/docs/guides/retrieval" rel="noopener noreferrer"&gt;OpenAI&lt;/a&gt;).&lt;/li&gt;
&lt;li&gt;[ ] Protect the vector database as carefully as the original files. IBM warns that if it's breached, "attackers can reverse the vector embedding process and access the original data" (&lt;a href="https://www.ibm.com/think/topics/retrieval-augmented-generation" rel="noopener noreferrer"&gt;IBM&lt;/a&gt;).&lt;/li&gt;
&lt;/ul&gt;

&lt;h3&gt;
  
  
  4. FAQ gap-check
&lt;/h3&gt;

&lt;ul&gt;
&lt;li&gt;[ ] Pull together a few weeks of real customer questions from your inbox, chat logs, contact form and phone notes.&lt;/li&gt;
&lt;li&gt;[ ] For each question, find the document that answers it. Mark the ones with no answer.&lt;/li&gt;
&lt;li&gt;[ ] Write the missing answers. A bot can't retrieve what doesn't exist, and without a source AWS notes models can present "false information when it does not have the answer" (&lt;a href="https://aws.amazon.com/what-is/retrieval-augmented-generation/" rel="noopener noreferrer"&gt;AWS&lt;/a&gt;).&lt;/li&gt;
&lt;li&gt;[ ] Decide what the bot does when it doesn't know: offer a contact form, phone number or hand-off to a person.&lt;/li&gt;
&lt;/ul&gt;

&lt;h3&gt;
  
  
  5. Format cleanup
&lt;/h3&gt;

&lt;ul&gt;
&lt;li&gt;[ ] Use real text. Common formats like PDF, Word, plain text and Markdown are widely supported (&lt;a href="https://developers.openai.com/api/docs/guides/retrieval" rel="noopener noreferrer"&gt;OpenAI&lt;/a&gt;). Quick test: if you can't select the text in a PDF, assume the chatbot can't read it either.&lt;/li&gt;
&lt;li&gt;[ ] Make each section make sense on its own. Name the service, product or location in the passage, not just in a heading three pages up. This is the do-it-yourself version of the context fix above.&lt;/li&gt;
&lt;li&gt;[ ] Turn complicated tables into plain sentences where you can ("Hygiene appointment at the Northside clinic: 30 minutes, £X").&lt;/li&gt;
&lt;li&gt;[ ] Write product codes, plan names and policy names the same way every time.&lt;/li&gt;
&lt;/ul&gt;

&lt;h2&gt;
  
  
  Worked example (hypothetical): a small dental practice
&lt;/h2&gt;

&lt;p&gt;&lt;em&gt;An illustrative scenario, not a client.&lt;/em&gt; Imagine a small dental practice with two clinics. The front desk spends much of the day answering the same calls about prices, opening hours, accepted insurers and how to prepare for a procedure. The owner wants "a chatbot trained on our website and leaflets."&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;The gate.&lt;/strong&gt; Questions repeat, but answers depend on the clinic and the treatment, so a fixed FAQ feels stiff. Booking questions need the live diary, so they route to the existing booking link instead. Everything else (website pages, a price list, a dozen leaflets) is well under 500 pages, so no RAG yet — an assistant with the whole knowledge base in the prompt will do for version one.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;The checklist turns up the real work:&lt;/strong&gt;&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;Source of truth:&lt;/strong&gt; there are two price lists in the shared drive, last year's and this year's. The old one is removed.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Freshness:&lt;/strong&gt; the practice manager becomes the owner of the price list and opening hours, and reviews them each quarter and before every bank holiday.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Sensitive data:&lt;/strong&gt; the staff handbook was in the "upload" folder. It contains staff mobile numbers and internal procedures, so it comes out.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Gap-check:&lt;/strong&gt; going through a few weeks of phone notes shows "Do you take my insurance?" is one of the most common questions, and no document answers it. The team writes a one-page insurer list.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Format:&lt;/strong&gt; the aftercare leaflets turn out to be scanned images. They're retyped as text, and each one names the procedure in its first line.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;None of this needed an engineer, though skipping it would have produced wrong answers. If the practice later adds clinics or a staff-only assistant, the cleaned-up content moves straight into a RAG setup.&lt;/p&gt;

&lt;h2&gt;
  
  
  Platform vs. custom build: what changes once your data is ready
&lt;/h2&gt;

&lt;p&gt;Once your data is ready, picking the tool is the easier decision — the work above carries over whichever you choose.&lt;/p&gt;

&lt;div class="table-wrapper-paragraph"&gt;&lt;table&gt;
&lt;thead&gt;
&lt;tr&gt;
&lt;th&gt;&lt;/th&gt;
&lt;th&gt;No-code chatbot platform&lt;/th&gt;
&lt;th&gt;Hosted retrieval API (e.g. OpenAI file search)&lt;/th&gt;
&lt;th&gt;Custom RAG build&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td&gt;&lt;strong&gt;Setup&lt;/strong&gt;&lt;/td&gt;
&lt;td&gt;Upload files, paste a snippet on your site&lt;/td&gt;
&lt;td&gt;A developer connects files to a model&lt;/td&gt;
&lt;td&gt;Designed around your systems&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;strong&gt;Chunking &amp;amp; search&lt;/strong&gt;&lt;/td&gt;
&lt;td&gt;Fixed by the vendor&lt;/td&gt;
&lt;td&gt;Adjustable. OpenAI allows 100–4,096-token chunks (&lt;a href="https://developers.openai.com/api/docs/guides/retrieval" rel="noopener noreferrer"&gt;OpenAI&lt;/a&gt;)&lt;/td&gt;
&lt;td&gt;Fully controllable, incl. keyword + meaning-based search&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;strong&gt;Permissions&lt;/strong&gt;&lt;/td&gt;
&lt;td&gt;Usually one bot = one set of files&lt;/td&gt;
&lt;td&gt;Tag-based filtering&lt;/td&gt;
&lt;td&gt;Per-user access tied to your logins&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;strong&gt;Live data&lt;/strong&gt;&lt;/td&gt;
&lt;td&gt;Rarely&lt;/td&gt;
&lt;td&gt;With extra development&lt;/td&gt;
&lt;td&gt;Yes, via integrations&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;strong&gt;Best for&lt;/strong&gt;&lt;/td&gt;
&lt;td&gt;Public FAQ-style content&lt;/td&gt;
&lt;td&gt;Small teams with a developer&lt;/td&gt;
&lt;td&gt;Multiple sources, staff + customer bots, citations&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;&lt;/div&gt;

&lt;p&gt;Running costs: storing the documents is usually the small part. OpenAI's vector storage, for instance, is free up to 1 GB and $0.10 per GB per day after that (&lt;a href="https://developers.openai.com/api/docs/guides/retrieval" rel="noopener noreferrer"&gt;OpenAI&lt;/a&gt;). The model's cost per conversation usually matters more, which is what our &lt;a href="https://banxal.com/blog/ai-agent-cost-per-month" rel="noopener noreferrer"&gt;cost-per-month guide&lt;/a&gt; works through.&lt;/p&gt;

&lt;p&gt;A platform is probably enough for public content and simple questions. You've outgrown it when you need per-user answers, live system data, reliable exact-code lookups, or a way to test answer quality before customers see it.&lt;/p&gt;

&lt;h2&gt;
  
  
  Want a second opinion before you build?
&lt;/h2&gt;

&lt;p&gt;Worked through the checklist and still unsure whether you need an FAQ widget, a simple assistant or a full RAG chatbot? Our &lt;a href="https://banxal.com/services" rel="noopener noreferrer"&gt;AI integration &amp;amp; agents&lt;/a&gt; team builds chatbots and assistants on your own data, and we'll tell you plainly if a simpler option will do. &lt;a href="https://banxal.com/contact" rel="noopener noreferrer"&gt;Tell us what your customers keep asking&lt;/a&gt;.&lt;/p&gt;

&lt;h2&gt;
  
  
  FAQ
&lt;/h2&gt;

&lt;h3&gt;
  
  
  Can I train ChatGPT on my own business data?
&lt;/h3&gt;

&lt;p&gt;You usually don't need to. Most "own data" chatbots use RAG: they look up your documents at question time and leave the model unchanged. Fine-tuning, which does change the model, is "computationally expensive and resource-intensive" (&lt;a href="https://www.ibm.com/think/topics/retrieval-augmented-generation" rel="noopener noreferrer"&gt;IBM&lt;/a&gt;) and rarely a small business's first step.&lt;/p&gt;

&lt;h3&gt;
  
  
  How much data do I need for a chatbot trained on my own data?
&lt;/h3&gt;

&lt;p&gt;Less than you'd think, but it must be current, consistent and cover the questions people actually ask. Under about 500 pages, Anthropic suggests skipping retrieval and putting it all in the prompt (&lt;a href="https://www.anthropic.com/news/contextual-retrieval" rel="noopener noreferrer"&gt;Anthropic&lt;/a&gt;).&lt;/p&gt;

&lt;h3&gt;
  
  
  Is it safe to put customer data into an AI chatbot?
&lt;/h3&gt;

&lt;p&gt;Keep customer and staff data out of a public bot's knowledge base entirely. Anything in it can end up shown to anyone. Give staff assistants a separate, access-controlled collection.&lt;/p&gt;

&lt;h3&gt;
  
  
  How do I stop the chatbot making things up?
&lt;/h3&gt;

&lt;p&gt;Fill the gaps, remove outdated and conflicting documents, have the bot cite sources, and hand over to a person when it can't find an answer. RAG gives the model real material to work from. It can't fix missing or wrong material.&lt;/p&gt;




&lt;p&gt;What's the one question your customers ask that you'd most like a chatbot to answer, and is it actually written down anywhere yet? Tell us in the comments.&lt;/p&gt;




&lt;p&gt;If you've tried a chatbot on your own documents, what tripped it up first: outdated files, missing answers, or something else? Tell us in the comments.&lt;/p&gt;




&lt;p&gt;&lt;em&gt;Originally published on &lt;a href="https://banxal.com/blog/ai-chatbot-own-data-readiness-checklist" rel="noopener noreferrer"&gt;banxal.com&lt;/a&gt;.&lt;/em&gt;&lt;/p&gt;

</description>
      <category>ai</category>
      <category>rag</category>
      <category>chatbot</category>
      <category>beginners</category>
    </item>
    <item>
      <title>Automation Failing Silently in Zapier, n8n or Make?</title>
      <dc:creator>Manveer</dc:creator>
      <pubDate>Thu, 08 Oct 2026 17:41:51 +0000</pubDate>
      <link>https://dev.to/manveer-banxal/automation-failing-silently-in-zapier-n8n-or-make-4c1o</link>
      <guid>https://dev.to/manveer-banxal/automation-failing-silently-in-zapier-n8n-or-make-4c1o</guid>
      <description>&lt;p&gt;It's Monday morning. Your sales lead asks why there have been no new website leads since Thursday. The form has dozens of submissions. The Zap, scenario or workflow that copies them into the CRM is on, and its last run says "success" — but the CRM has nothing new since Thursday.&lt;/p&gt;

&lt;p&gt;Nobody got an email. Nothing turned red. Four days of leads sat in a form inbox nobody reads.&lt;/p&gt;

&lt;p&gt;That's an automation failing silently — in Zapier, n8n or Make alike. Below: why "successful" runs can still be broken, the four failure modes behind it, free alert settings for each platform (checked against the official docs), and a monthly health check that needs no monitoring tool.&lt;/p&gt;

&lt;h2&gt;
  
  
  TL;DR
&lt;/h2&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;Native alerts only catch errors.&lt;/strong&gt; A run that "succeeds" with blank data, or a trigger that stops firing, won't alert you on Zapier, n8n or Make.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Turn on the free alerts today anyway.&lt;/strong&gt; Zapier notification settings, an n8n error workflow and Make's email preferences catch expired logins and API errors. Each takes about five minutes.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Add one "is anything arriving?" check.&lt;/strong&gt; A daily scheduled count of new records, with an alert when it hits zero, catches the failures alerts can't see.&lt;/li&gt;
&lt;/ul&gt;

&lt;h2&gt;
  
  
  Why "it ran successfully" doesn't mean it worked
&lt;/h2&gt;

&lt;p&gt;Automation platforms judge success at the step level: did each API call return without an error? They don't know what &lt;em&gt;should&lt;/em&gt; have happened in your business.&lt;/p&gt;

&lt;p&gt;So "success" can mean any of these:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;A CRM contact was created, but the email field was blank because the form tool renamed &lt;code&gt;email&lt;/code&gt; to &lt;code&gt;email_address&lt;/code&gt;.&lt;/li&gt;
&lt;li&gt;A filter step stopped every run because a dropdown value changed from "Yes" to "yes". The filter did its job, so nothing was flagged.&lt;/li&gt;
&lt;li&gt;The trigger hasn't fired since Thursday. There's no failed run, because there's no run at all.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;The first two look normal in your run history. The third doesn't show up anywhere. Built-in alerts catch loud failures and miss quiet ones.&lt;/p&gt;

&lt;h2&gt;
  
  
  Four ways an automation ends up failing silently in Zapier, n8n or Make
&lt;/h2&gt;

&lt;p&gt;Most silent failures trace back to one of four causes: an expired login, an upstream field change, an empty-data edge case, or a rate limit. Here's what each looks like and whether native alerts catch it.&lt;/p&gt;

&lt;h3&gt;
  
  
  1. Expired or revoked logins (auth tokens)
&lt;/h3&gt;

&lt;p&gt;Every app connection is a stored login, and logins expire. Zapier says connections "expire after a given time, such as after a year" (&lt;a href="https://zapier.com/blog/how-to-troubleshoot-zaps/" rel="noopener noreferrer"&gt;Zapier&lt;/a&gt;). Google's refresh tokens stop working after six months unused, or when a password change touches Gmail-scoped tokens. Self-hosted n8n with a Google Cloud app left in "Testing" status expires tokens in 7 days (&lt;a href="https://developers.google.com/identity/protocols/oauth2" rel="noopener noreferrer"&gt;Google&lt;/a&gt;).&lt;/p&gt;

&lt;p&gt;Common trigger: the person who connected the account leaves, and their login gets disabled.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Is it loud?&lt;/strong&gt; Usually, as an authentication error — but an authentication failure (&lt;code&gt;AccountValidationError&lt;/code&gt;) can't be caught by a Make error handler, and after your set number of consecutive errors Make disables the scenario's scheduling (&lt;a href="https://help.make.com/fix-errors-and-warnings" rel="noopener noreferrer"&gt;Make&lt;/a&gt;), and Zapier can turn off a Zap that "errored too many times" (&lt;a href="https://help.zapier.com/hc/en-us/articles/16815648307853-Error-Task-was-stopped-because-its-Zap-was-turned-off" rel="noopener noreferrer"&gt;Zapier&lt;/a&gt;). If that error email went to an unwatched inbox, you're left with a switched-off automation and no further warning.&lt;/p&gt;

&lt;h3&gt;
  
  
  2. API and field changes
&lt;/h3&gt;

&lt;p&gt;Apps rename fields, change dropdown options and retire endpoints. Sometimes that throws an error; often the field mapping just comes through empty. Zapier's troubleshooting guide flags a related trap: "Dropdown menus understand IDs, not text" (&lt;a href="https://zapier.com/blog/how-to-troubleshoot-zaps/" rel="noopener noreferrer"&gt;Zapier&lt;/a&gt;) — a label change upstream can quietly break a mapping.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Is it loud?&lt;/strong&gt; Only if the receiving app rejects the data. Make calls this a &lt;code&gt;DataError&lt;/code&gt; or &lt;code&gt;BundleValidationError&lt;/code&gt; when it does (&lt;a href="https://help.make.com/fix-errors-and-warnings" rel="noopener noreferrer"&gt;Make&lt;/a&gt;). If the receiving app accepts a blank value, the run succeeds.&lt;/p&gt;

&lt;h3&gt;
  
  
  3. Empty-data edge cases
&lt;/h3&gt;

&lt;p&gt;A search step finds no matching customer and the workflow carries on with nothing. A webhook arrives with an empty body. A spreadsheet trigger watches a tab someone renamed. None of these is technically an error.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Is it loud?&lt;/strong&gt; Almost never. Platform settings alone won't catch it.&lt;/p&gt;

&lt;h3&gt;
  
  
  4. Rate limits and timeouts
&lt;/h3&gt;

&lt;p&gt;Send a burst of records (a bulk import, a busy sale day) and the receiving API starts refusing requests. Make labels these &lt;code&gt;RateLimitError&lt;/code&gt; (HTTP 429) and &lt;code&gt;ModuleTimeoutError&lt;/code&gt; for runs past its 40–60 second limit (&lt;a href="https://help.make.com/fix-errors-and-warnings" rel="noopener noreferrer"&gt;Make&lt;/a&gt;); n8n's "Timeout Workflow" setting cancels a run after a set time (&lt;a href="https://docs.n8n.io/build/manage-workflows/configure-workflow-settings" rel="noopener noreferrer"&gt;n8n&lt;/a&gt;).&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Is it loud?&lt;/strong&gt; Partly. The failed run errors, but the damage is often a &lt;em&gt;half-finished&lt;/em&gt; run: the invoice was created, the welcome email wasn't. Retries can also create duplicates.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.us-east-2.amazonaws.com%2Fuploads%2Farticles%2Fnd1cex7dl395rrd55n8p.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.us-east-2.amazonaws.com%2Fuploads%2Farticles%2Fnd1cex7dl395rrd55n8p.png" alt="Table of the four silent automation failure modes — expired login, API/field change, empty data, rate limit/timeout — showing whether the native alert fires and how to catch each one" width="799" height="373"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;div class="table-wrapper-paragraph"&gt;&lt;table&gt;
&lt;thead&gt;
&lt;tr&gt;
&lt;th&gt;Failure mode&lt;/th&gt;
&lt;th&gt;What you typically see&lt;/th&gt;
&lt;th&gt;Does the native alert fire?&lt;/th&gt;
&lt;th&gt;How you catch it&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td&gt;Expired login&lt;/td&gt;
&lt;td&gt;Auth errors, then the automation switched off&lt;/td&gt;
&lt;td&gt;Usually, if alerts are on and someone reads them&lt;/td&gt;
&lt;td&gt;Native alerts + monthly connection review&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;API / field change&lt;/td&gt;
&lt;td&gt;"Successful" runs with blank or wrong fields&lt;/td&gt;
&lt;td&gt;Sometimes&lt;/td&gt;
&lt;td&gt;Spot-check real output records&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Empty data&lt;/td&gt;
&lt;td&gt;Runs that do nothing, or no runs at all&lt;/td&gt;
&lt;td&gt;Rarely&lt;/td&gt;
&lt;td&gt;Daily "is anything arriving?" count&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Rate limit / timeout&lt;/td&gt;
&lt;td&gt;Some runs fail, some half-finish&lt;/td&gt;
&lt;td&gt;Partly&lt;/td&gt;
&lt;td&gt;Native alerts + check for duplicates&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;&lt;/div&gt;

&lt;h2&gt;
  
  
  The 10-minute self-check
&lt;/h2&gt;

&lt;p&gt;Do this now for the automations that would hurt most if they stopped — usually lead capture, payments or invoicing, and customer onboarding.&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;
&lt;strong&gt;Open the run history&lt;/strong&gt; (Zapier: Zap history; n8n: executions; Make: scenario history). Is the last run as recent as it should be? Leads arriving daily but the last run four days ago means you've found a silent failure.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Open three recent output records&lt;/strong&gt; in the destination app (CRM contact, invoice, row). Is every field you care about filled in?&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Look for runs that aren't plain success or plain error.&lt;/strong&gt; Zapier marks some as "Holding" for "account-related issues, such as high task usage, an account connection issue" (&lt;a href="https://zapier.com/blog/how-to-troubleshoot-zaps/" rel="noopener noreferrer"&gt;Zapier&lt;/a&gt;); Make records warnings and incomplete executions.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Check your connections.&lt;/strong&gt; Note which ones belong to people who've left or are about to.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Find out where alerts go today.&lt;/strong&gt; Whose inbox? Do they still work here? Do they read it?&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Write down an owner&lt;/strong&gt; for each critical automation: one name who gets the alert and fixes it.&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;If step 1 or 2 surprised you, set up the alerts below before doing anything else.&lt;/p&gt;

&lt;h2&gt;
  
  
  Turn on free native alerts today: Zapier, n8n, Make
&lt;/h2&gt;

&lt;p&gt;All three platforms include error alerts at no extra cost. Here's where to find each, per the vendors' own docs.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.us-east-2.amazonaws.com%2Fuploads%2Farticles%2Fh9gs84hc691410po6tao.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.us-east-2.amazonaws.com%2Fuploads%2Farticles%2Fh9gs84hc691410po6tao.png" alt="Side-by-side of the free native alert setup for Zapier, n8n and Make, showing the one setting to change in each platform" width="799" height="373"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;h3&gt;
  
  
  Zapier
&lt;/h3&gt;

&lt;ol&gt;
&lt;li&gt;Go to &lt;strong&gt;Settings → Notifications → My notification settings&lt;/strong&gt;. Under &lt;strong&gt;Default notification&lt;/strong&gt;, click &lt;strong&gt;Edit&lt;/strong&gt; and choose &lt;strong&gt;Immediately&lt;/strong&gt; (one email per error) or &lt;strong&gt;Immediately, then hourly summary&lt;/strong&gt;. Avoid &lt;strong&gt;Never&lt;/strong&gt; (&lt;a href="https://help.zapier.com/hc/en-us/articles/8496289225229-Manage-notifications-when-errors-occur-in-Zap-workflows" rel="noopener noreferrer"&gt;Zapier&lt;/a&gt;).&lt;/li&gt;
&lt;li&gt;For your critical Zaps, add a rule under &lt;strong&gt;Custom notifications → + Add notification&lt;/strong&gt;, pick the Zaps or folders, set the frequency and click &lt;strong&gt;Add to notifications&lt;/strong&gt;. Custom notifications aren't available during a trial.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Know the gap:&lt;/strong&gt; Zapier says errors handled by an error handler don't send notification emails. If you've built error handling into a Zap, make that handler send its own alert.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Optional: route errors to Slack.&lt;/strong&gt; Zapier's &lt;strong&gt;Zapier Manager&lt;/strong&gt; app has a &lt;strong&gt;New Zap Error&lt;/strong&gt; trigger with ready-made templates that post each error to a Slack channel (&lt;a href="https://zapier.com/apps/slack/integrations/zapier-manager/152948/send-slack-channel-messages-for-new-zap-errors" rel="noopener noreferrer"&gt;Zapier&lt;/a&gt;). If you do this, also set "Send me an email when a Zapier Manager Zap fails" to &lt;strong&gt;Always&lt;/strong&gt; under &lt;strong&gt;Notifications → Email subscriptions&lt;/strong&gt; (&lt;a href="https://help.zapier.com/hc/en-us/articles/8496277613325-Manage-your-Zapier-account-email-notification-preferences" rel="noopener noreferrer"&gt;Zapier&lt;/a&gt;) — so you hear about it if the alert Zap itself breaks.&lt;/li&gt;
&lt;/ol&gt;

&lt;h3&gt;
  
  
  n8n
&lt;/h3&gt;

&lt;p&gt;n8n's documented way to hear about failures is an &lt;strong&gt;error workflow&lt;/strong&gt; — a separate workflow that runs when another one fails (&lt;a href="https://docs.n8n.io/flow-logic/error-handling/" rel="noopener noreferrer"&gt;n8n&lt;/a&gt;).&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;Create a new workflow with the &lt;strong&gt;Error Trigger&lt;/strong&gt; node first, then add a Slack, email or Teams node that sends the message. Name and save it (for example "Error Handler").&lt;/li&gt;
&lt;li&gt;In each workflow you want covered, open the &lt;strong&gt;three dots icon&lt;/strong&gt; in the upper-right, select &lt;strong&gt;Settings&lt;/strong&gt;, choose your handler in the &lt;strong&gt;Error Workflow&lt;/strong&gt; dropdown and &lt;strong&gt;Save&lt;/strong&gt; (&lt;a href="https://docs.n8n.io/build/manage-workflows/configure-workflow-settings" rel="noopener noreferrer"&gt;n8n&lt;/a&gt;). This is per workflow, so new workflows aren't covered until you set it.&lt;/li&gt;
&lt;li&gt;In the same settings, make sure &lt;strong&gt;Save failed production executions&lt;/strong&gt; is set to save, so you have something to debug.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Put the useful fields in the alert.&lt;/strong&gt; The Error Trigger receives the workflow name, the error message, the last node that ran and, if executions are saved, a link to it (&lt;a href="https://docs.n8n.io/flow-logic/error-handling/" rel="noopener noreferrer"&gt;n8n&lt;/a&gt;).&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;Bonus: the &lt;strong&gt;Stop And Error&lt;/strong&gt; node lets you "cause executions to fail under certain conditions" (&lt;a href="https://docs.n8n.io/integrations/builtin/core-nodes/n8n-nodes-base.stopanderror/" rel="noopener noreferrer"&gt;n8n&lt;/a&gt;) — use it for empty-data cases, so a search that returns nothing fails on purpose and triggers the error workflow instead of running on.&lt;/p&gt;

&lt;h3&gt;
  
  
  Make
&lt;/h3&gt;

&lt;ol&gt;
&lt;li&gt;Go to &lt;strong&gt;Profile → Email preferences&lt;/strong&gt; → &lt;strong&gt;Organizations&lt;/strong&gt; and check &lt;strong&gt;Errors&lt;/strong&gt;, &lt;strong&gt;Warnings&lt;/strong&gt; and &lt;strong&gt;Deactivation&lt;/strong&gt; for each organization (by default you only get errors and deactivations). Make emails immediately, then a digest after 5 minutes for errors and 15 for warnings (&lt;a href="https://help.make.com/manage-your-email-preferences" rel="noopener noreferrer"&gt;Make&lt;/a&gt;).&lt;/li&gt;
&lt;li&gt;In each important scenario, click the &lt;strong&gt;gear icon&lt;/strong&gt; in the Scenario Builder to open scenario settings (&lt;a href="https://help.make.com/scenario-settings" rel="noopener noreferrer"&gt;Make&lt;/a&gt;):

&lt;ul&gt;
&lt;li&gt;Turn on &lt;strong&gt;Store incomplete executions&lt;/strong&gt;, so failed runs are saved "so the data isn't lost".&lt;/li&gt;
&lt;li&gt;Review how many consecutive errors Make allows before deactivating. Note that "if a scenario starts with an instant trigger, the setting is ignored and the scenario is deactivated immediately once the first error has occurred."&lt;/li&gt;
&lt;li&gt;Think before enabling &lt;strong&gt;Discard data if storage is full&lt;/strong&gt;. It keeps the scenario running, but it throws away the failed data.&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;/ol&gt;

&lt;h2&gt;
  
  
  When native alerts aren't enough
&lt;/h2&gt;

&lt;p&gt;Native alerts only answer one question: "did a step throw an error?" They can't tell you:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;The trigger stopped firing.&lt;/strong&gt; No run, no error, no alert.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;The output is wrong.&lt;/strong&gt; Blank fields and skipped records look like success.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Volume dropped.&lt;/strong&gt; Twelve leads a day falling to two is a business problem, not a technical error.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Nobody is reading the alerts.&lt;/strong&gt; An inbox that gets 40 error digests a week gets ignored.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;The fix needs no new tool: a &lt;strong&gt;heartbeat check&lt;/strong&gt;. Build one small scheduled automation that runs every morning, counts yesterday's new records in the destination (CRM contacts, invoices, rows), and alerts if the count is zero or far below normal — to the same channel as your error alerts, and on a different connection where possible, so one expired login can't silence both.&lt;/p&gt;

&lt;p&gt;Dedicated monitoring tools exist, and some teams need them. You've probably outgrown DIY when:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;You're running enough business-critical automations, or they're spread across enough platforms, that no one person can keep track of them from memory.&lt;/li&gt;
&lt;li&gt;Automations move money, sync two systems both ways, or touch customer data you're accountable for.&lt;/li&gt;
&lt;li&gt;Nobody owns them, or the person who built them has left.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;At that point the fix is usually less "add monitoring" and more "rebuild the fragile parts properly": safe retries, validation before writing, and logs a human can read. Our guide on &lt;a href="https://banxal.com/blog/zapier-n8n-or-ai-agent" rel="noopener noreferrer"&gt;choosing between Zapier, n8n or an AI agent&lt;/a&gt; covers when a workflow has outgrown its platform.&lt;/p&gt;

&lt;h2&gt;
  
  
  A simple monthly automation health-check
&lt;/h2&gt;

&lt;p&gt;Put a 30-minute recurring meeting on the calendar with the automation owner and work through this list.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.us-east-2.amazonaws.com%2Fuploads%2Farticles%2Fhxr0bi9v1mvddzjsxk3c.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.us-east-2.amazonaws.com%2Fuploads%2Farticles%2Fhxr0bi9v1mvddzjsxk3c.png" alt="One-page monthly automation health-check checklist with nine tick boxes grouped under " width="800" height="327"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Is it running?&lt;/strong&gt;&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;[ ] Last run time for each critical automation matches what you'd expect.&lt;/li&gt;
&lt;li&gt;[ ] No automations switched off by the platform (Zapier and Make both do this after errors).&lt;/li&gt;
&lt;li&gt;[ ] Task, credit or execution usage isn't close to your plan limit. Make stops scheduling immediately when you run out of operations (&lt;a href="https://help.make.com/fix-errors-and-warnings" rel="noopener noreferrer"&gt;Make&lt;/a&gt;).&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;&lt;strong&gt;Is it right?&lt;/strong&gt;&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;[ ] Five random output records checked against their source, every field.&lt;/li&gt;
&lt;li&gt;[ ] No duplicates from retried runs.&lt;/li&gt;
&lt;li&gt;[ ] Incomplete executions (Make) or failed executions (n8n) reviewed and cleared.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;&lt;strong&gt;Is someone watching?&lt;/strong&gt;&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;[ ] Error alerts and the heartbeat check still go to a person who works here and reads them.&lt;/li&gt;
&lt;li&gt;[ ] Every connection belongs to a current team member or a shared service account.&lt;/li&gt;
&lt;li&gt;[ ] Each critical automation has a named owner and a one-line note on what it does.&lt;/li&gt;
&lt;/ul&gt;

&lt;h2&gt;
  
  
  Want a second pair of eyes on your automations?
&lt;/h2&gt;

&lt;p&gt;If this check turned up more than you'd like, or there's a Zapier, n8n or Make setup nobody wants to touch, that's what our &lt;a href="https://banxal.com/services" rel="noopener noreferrer"&gt;automation &amp;amp; integrations&lt;/a&gt; team does: audit what you have, add alerts and heartbeat checks, rebuild the fragile parts, and look after it ongoing if you want. &lt;a href="https://banxal.com/contact" rel="noopener noreferrer"&gt;Tell us what you're running&lt;/a&gt; and we'll tell you honestly whether it needs more than the free settings above.&lt;/p&gt;

&lt;h2&gt;
  
  
  FAQ
&lt;/h2&gt;

&lt;h3&gt;
  
  
  Why did my Zapier automation stop working with no notification?
&lt;/h3&gt;

&lt;p&gt;The three usual causes: error notifications are set to &lt;strong&gt;Never&lt;/strong&gt; or go to an unread inbox; Zapier turned the Zap off after repeated errors; or the trigger stopped firing, so there was no error to report. Check Zap history and &lt;strong&gt;Settings → Notifications&lt;/strong&gt; first.&lt;/p&gt;

&lt;h3&gt;
  
  
  How do I get alerted when an n8n workflow fails?
&lt;/h3&gt;

&lt;p&gt;Create an error workflow that starts with the &lt;strong&gt;Error Trigger&lt;/strong&gt; node and sends a Slack message or email. Then select it under &lt;strong&gt;Error Workflow&lt;/strong&gt; in each workflow's settings. It doesn't apply automatically to new workflows (&lt;a href="https://docs.n8n.io/flow-logic/error-handling/" rel="noopener noreferrer"&gt;n8n&lt;/a&gt;).&lt;/p&gt;

&lt;h3&gt;
  
  
  Does Make tell me when a scenario fails?
&lt;/h3&gt;

&lt;p&gt;Yes. By default Make emails you about errors and about scenarios it deactivates. Warnings are off unless you enable them under &lt;strong&gt;Profile → Email preferences&lt;/strong&gt; (&lt;a href="https://help.make.com/manage-your-email-preferences" rel="noopener noreferrer"&gt;Make&lt;/a&gt;). Scenarios with instant triggers are deactivated on the first error, so keep deactivation emails on.&lt;/p&gt;

&lt;h3&gt;
  
  
  How do I monitor business automations without a monitoring tool?
&lt;/h3&gt;

&lt;p&gt;Combine the free native error alerts with a daily heartbeat automation that counts yesterday's new records and alerts on zero, plus the monthly checklist above. For most small teams, that covers loud and quiet failures.&lt;/p&gt;




&lt;p&gt;Has an automation of yours ever failed quietly for days? What gave it away in the end? Tell us in the comments.&lt;/p&gt;




&lt;p&gt;&lt;em&gt;Originally published on &lt;a href="https://banxal.com/blog/automation-silent-failures-zapier-n8n-make" rel="noopener noreferrer"&gt;banxal.com&lt;/a&gt;.&lt;/em&gt;&lt;/p&gt;

</description>
      <category>automation</category>
      <category>nocode</category>
      <category>productivity</category>
      <category>devops</category>
    </item>
    <item>
      <title>How to Vet a Developer to Fix Your Vibe-Coded App</title>
      <dc:creator>Manveer</dc:creator>
      <pubDate>Tue, 06 Oct 2026 15:18:46 +0000</pubDate>
      <link>https://dev.to/manveer-banxal/how-to-vet-a-developer-to-fix-your-vibe-coded-app-1aji</link>
      <guid>https://dev.to/manveer-banxal/how-to-vet-a-developer-to-fix-your-vibe-coded-app-1aji</guid>
      <description>&lt;p&gt;You post a short job description: "Lovable app, Supabase backend, payments are flaky, need someone to fix it." Three replies come in by evening. One says it's a two-day job. One says the whole thing should be rebuilt. One asks you to send your Supabase login so they can "take a quick look".&lt;/p&gt;

&lt;p&gt;Any of the three might be right. You can't tell from the replies, and that's the real problem when you &lt;strong&gt;hire a developer to fix a vibe-coded app&lt;/strong&gt;. The skills that matter here are mostly invisible from a portfolio.&lt;/p&gt;

&lt;p&gt;This guide gives you the questions to ask on the call, what a good answer sounds like, which answers end the conversation, and a scorecard you can fill in as you go.&lt;/p&gt;

&lt;h2&gt;
  
  
  TL;DR
&lt;/h2&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;Vet for diagnosis, not just coding.&lt;/strong&gt; The developer's first job is to find problems the AI builder hid, such as missing database access rules, leaked keys and payments that don't match your app. Ask them how they'd find those.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Access and ownership answers matter as much as technical ones.&lt;/strong&gt; A good hire asks to be &lt;em&gt;invited&lt;/em&gt; to your accounts, not given your passwords, and puts code ownership in writing.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Score every answer Green, Yellow or Red.&lt;/strong&gt; A Red on security, access or ownership ends the conversation, however good the rest of the call was.&lt;/li&gt;
&lt;/ul&gt;

&lt;h2&gt;
  
  
  Why vetting for a vibe-coded app is different
&lt;/h2&gt;

&lt;p&gt;Vetting is different here because the job isn't proving someone can build an app — it's proving they can find what's wrong with one they didn't build, and that looks fine on the surface. A normal hiring process asks "can this person build things?" For a vibe-coded app, the better question is "can this person find what's wrong with something they didn't build, and that nobody fully understands?"&lt;/p&gt;

&lt;p&gt;The problems are predictable. Veracode tested code from over 100 large language models and found that &lt;strong&gt;AI-generated code introduced risky security flaws in 45% of tests&lt;/strong&gt; (&lt;a href="https://www.veracode.com/resources/analyst-reports/2025-genai-code-security-report/" rel="noopener noreferrer"&gt;Veracode&lt;/a&gt;). In the case behind CVE-2025-48757, a researcher scanned 1,645 Lovable-built apps and found &lt;strong&gt;170 (10.3%) with exposed data across 303 endpoints&lt;/strong&gt;, including names, phone numbers, payment details and live API keys (&lt;a href="https://bleek.dev/cve-2025-48757" rel="noopener noreferrer"&gt;bleek.dev&lt;/a&gt;). The cause was missing or misconfigured Supabase Row Level Security (RLS).&lt;/p&gt;

&lt;p&gt;These problems don't show up in the demo. The app looks fine until a stranger reads someone else's records. So the developer you hire has to be good at looking under the surface, and the interview should test exactly that.&lt;/p&gt;

&lt;p&gt;If you haven't yet worked out how bad things are, run our &lt;a href="https://banxal.com/blog/fix-or-rebuild-vibe-coded-app" rel="noopener noreferrer"&gt;30-minute fix-or-rebuild self-test&lt;/a&gt; first. Your scores make every question below sharper, because you'll know which answers matter most for your app.&lt;/p&gt;

&lt;h2&gt;
  
  
  Where founders look for help
&lt;/h2&gt;

&lt;p&gt;There are three common routes. None of them is automatically better. Each one fails in its own way.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.us-east-2.amazonaws.com%2Fuploads%2Farticles%2F6woliuc5ak1xi42bqkk0.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.us-east-2.amazonaws.com%2Fuploads%2Farticles%2F6woliuc5ak1xi42bqkk0.png" alt="Comparison table of where founders find a developer to fix an AI-built app: freelance marketplace, independent freelancer and small agency or studio, scored on how you find them, who does the work, accountability, best for and watch for." width="800" height="497"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;div class="table-wrapper-paragraph"&gt;&lt;table&gt;
&lt;thead&gt;
&lt;tr&gt;
&lt;th&gt;&lt;/th&gt;
&lt;th&gt;Freelance marketplace&lt;/th&gt;
&lt;th&gt;Independent freelancer&lt;/th&gt;
&lt;th&gt;Small agency or studio&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td&gt;&lt;strong&gt;Best for&lt;/strong&gt;&lt;/td&gt;
&lt;td&gt;One clearly scoped fix&lt;/td&gt;
&lt;td&gt;Ongoing work with one trusted person&lt;/td&gt;
&lt;td&gt;Audit, fixes and maintenance across several areas&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;strong&gt;Who does the work&lt;/strong&gt;&lt;/td&gt;
&lt;td&gt;Usually the person on the profile&lt;/td&gt;
&lt;td&gt;The person you talk to&lt;/td&gt;
&lt;td&gt;A team. Ask who exactly&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;strong&gt;Accountability&lt;/strong&gt;&lt;/td&gt;
&lt;td&gt;The platform's dispute process&lt;/td&gt;
&lt;td&gt;Your contract and their reputation&lt;/td&gt;
&lt;td&gt;Your contract, plus more than one person who knows your code&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;strong&gt;Watch for&lt;/strong&gt;&lt;/td&gt;
&lt;td&gt;Quotes given before anyone has seen the code&lt;/td&gt;
&lt;td&gt;One point of failure if they disappear&lt;/td&gt;
&lt;td&gt;A senior person on the sales call and a junior on the code&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;&lt;/div&gt;

&lt;p&gt;A practical rule: the less clearly you can describe the problem, the more you need someone who will diagnose before they quote. Marketplaces work well when you can write the fix as one line. If you can't, start with an audit, whichever route you choose.&lt;/p&gt;

&lt;h2&gt;
  
  
  The interview: 8 questions to ask before you hire a developer to fix a vibe-coded app
&lt;/h2&gt;

&lt;p&gt;Ask these on a call, not by email, so you hear how people think rather than what they can look up. You don't need to judge the technical detail yourself. Listen for specifics, for questions asked back, and for whether they're willing to say "I'd need to look first".&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.us-east-2.amazonaws.com%2Fuploads%2Farticles%2Fp3vet2eqc4eog48vfubt.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.us-east-2.amazonaws.com%2Fuploads%2Farticles%2Fp3vet2eqc4eog48vfubt.png" alt="Grid of the 8 interview questions paired with what a good answer sounds like versus the red-flag answer, from " width="800" height="600"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;h3&gt;
  
  
  1. "Will you look at the code before you quote?"
&lt;/h3&gt;

&lt;p&gt;&lt;strong&gt;Good answer:&lt;/strong&gt; "Yes. I'd like read access to the repo and database first, then I'll give you a written list of what I found and what I'd fix first." Some charge for this review, some don't. Either is fine, as long as the review happens before the main quote.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Red flag:&lt;/strong&gt; a firm price, or "you need a rebuild", based on a screen share or your description. Nobody can size a fix to code they haven't read.&lt;/p&gt;

&lt;h3&gt;
  
  
  2. "How would you check that one user can't see another user's data?"
&lt;/h3&gt;

&lt;p&gt;This is the question behind most vibe-coded app incidents. Supabase's docs say a table in an exposed schema without RLS "is readable and writable by any role with a grant on it" (&lt;a href="https://supabase.com/docs/guides/database/postgres/row-level-security" rel="noopener noreferrer"&gt;Supabase RLS&lt;/a&gt;).&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Good answer:&lt;/strong&gt; they'd check that RLS is turned on for every table and read each policy against your business rules. They'd also test it by signing in as two different users and trying to open each other's records. Bonus points if they mention Supabase's Security Advisor, which flags issues such as "RLS disabled in public" (&lt;a href="https://supabase.com/docs/guides/database/database-advisors" rel="noopener noreferrer"&gt;Supabase Advisors&lt;/a&gt;), &lt;em&gt;and&lt;/em&gt; say that it isn't enough on its own.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Red flag:&lt;/strong&gt; "Lovable's security scan is green, so you're fine." In the CVE-2025-48757 write-up, Superblocks notes the scanner "only flagged the presence of RLS, not whether it worked" (&lt;a href="https://www.superblocks.com/blog/lovable-vulnerabilities" rel="noopener noreferrer"&gt;Superblocks&lt;/a&gt;).&lt;/p&gt;

&lt;h3&gt;
  
  
  3. "Where should our secret keys live, and what would you do if one has leaked?"
&lt;/h3&gt;

&lt;p&gt;&lt;strong&gt;Good answer:&lt;/strong&gt; secret keys stay on the server, never in the browser. Lovable's own guidance says secrets in frontend code "should be considered compromised" (&lt;a href="https://docs.lovable.dev/tips-tricks/avoiding-security-pitfalls" rel="noopener noreferrer"&gt;Lovable&lt;/a&gt;). On a leak, a good developer finds and fixes the cause first, then creates a new key, updates everything, and only then deletes the old one. That's the order Supabase recommends (&lt;a href="https://supabase.com/docs/guides/api/api-keys" rel="noopener noreferrer"&gt;Supabase API keys&lt;/a&gt;).&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Red flag:&lt;/strong&gt; "Just send me the service_role key on WhatsApp." Supabase says a secret key "bypasses every Row Level Security policy you have" (same page). Anyone who handles it casually will handle your users' data the same way.&lt;/p&gt;

&lt;h3&gt;
  
  
  4. "How do you make sure payments and the app agree?"
&lt;/h3&gt;

&lt;p&gt;&lt;strong&gt;Good answer:&lt;/strong&gt; the app learns about payments from Stripe webhooks rather than from the browser reaching a "success" page. Each webhook's signature is checked, and repeated events are ignored. Stripe warns that without verification "an attacker could send fake webhook events" to grant access, and that endpoints "might occasionally receive the same event more than once" (&lt;a href="https://docs.stripe.com/webhooks" rel="noopener noreferrer"&gt;Stripe webhooks&lt;/a&gt;).&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Red flag:&lt;/strong&gt; "The success page upgrades the account, that's standard." It isn't standard. It breaks the moment someone closes the tab.&lt;/p&gt;

&lt;h3&gt;
  
  
  5. "Who will actually work on the code, and how do you use AI tools?"
&lt;/h3&gt;

&lt;p&gt;&lt;strong&gt;Good answer:&lt;/strong&gt; a named person, plus a clear way of working. Using AI coding tools is normal. What matters is that a human reviews and tests what the tools produce before it ships.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Red flag:&lt;/strong&gt; "Our team" with no names, or work that gets passed on to people you'll never meet. The opposite is also a warning sign: someone who says AI-built code is worthless and will be thrown away, before they've even read yours.&lt;/p&gt;

&lt;h3&gt;
  
  
  6. "What access do you need from me, and in whose account?"
&lt;/h3&gt;

&lt;p&gt;&lt;strong&gt;Good answer:&lt;/strong&gt; "Invite me as a collaborator to your GitHub repo, your Supabase org and your Stripe account." Invites keep you in control. On a personal GitHub repo, for example, a collaborator can push code but can't delete the repository or transfer ownership (&lt;a href="https://docs.github.com/en/account-and-profile/reference/permission-levels-for-a-personal-account-repository" rel="noopener noreferrer"&gt;GitHub permissions&lt;/a&gt;). Our &lt;a href="https://banxal.com/blog/handoff-lovable-bolt-app-to-developer" rel="noopener noreferrer"&gt;handoff prep guide&lt;/a&gt; lists everything to get ready before the developer starts.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Red flag:&lt;/strong&gt; asking for your passwords, or asking you to move the repo into their account "to make things easier".&lt;/p&gt;

&lt;h3&gt;
  
  
  7. "Who owns the code you write?"
&lt;/h3&gt;

&lt;p&gt;&lt;strong&gt;Good answer:&lt;/strong&gt; "You do. It's in the contract as an assignment of rights." This matters more than most founders realise. Under US law, commissioned work only counts as "work made for hire" if it falls into one of nine listed categories &lt;em&gt;and&lt;/em&gt; both sides sign a written agreement saying so (&lt;a href="https://www.copyright.gov/circs/circ30.pdf" rel="noopener noreferrer"&gt;US Copyright Office, Circular 30&lt;/a&gt;). Software isn't named on that list, so a clear written assignment is the safer route. The rules differ by country. Ask a lawyer about your own contract.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Red flag:&lt;/strong&gt; "We'll sort the paperwork later," or a contract that only grants you a licence to use the code.&lt;/p&gt;

&lt;h3&gt;
  
  
  8. "What does 'done' look like?"
&lt;/h3&gt;

&lt;p&gt;&lt;strong&gt;Good answer:&lt;/strong&gt; a list you could check off. That means written findings, each fix linked to an item on that list, tests or a repeatable check for the risky fixes, and short handover notes so the next person isn't starting from zero. If you have a written spec, share it. A one-page &lt;a href="https://banxal.com/blog/mvp-spec-template-non-technical-founders" rel="noopener noreferrer"&gt;MVP spec&lt;/a&gt; gives a good developer something concrete to scope against.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Red flag:&lt;/strong&gt; "We'll just fix bugs as they come up." That's fine for ongoing maintenance &lt;em&gt;after&lt;/em&gt; the first round of fixes. It doesn't work as the first round.&lt;/p&gt;

&lt;h2&gt;
  
  
  Red flags that end the conversation on their own
&lt;/h2&gt;

&lt;p&gt;Some answers make the rest of the call irrelevant. Stop if the developer:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Asks for your passwords or wants you to send secret keys over chat or email.&lt;/li&gt;
&lt;li&gt;Quotes a rebuild without reading your code or database.&lt;/li&gt;
&lt;li&gt;Wants the repo, database or domain moved into &lt;em&gt;their&lt;/em&gt; account.&lt;/li&gt;
&lt;li&gt;Brushes off exposed data as "fine for an MVP" when you have real users.&lt;/li&gt;
&lt;li&gt;Can't explain in plain English how they'd stop one user seeing another's data.&lt;/li&gt;
&lt;li&gt;Won't put code ownership in writing.&lt;/li&gt;
&lt;/ul&gt;

&lt;h2&gt;
  
  
  Score the call: Green, Yellow, Red
&lt;/h2&gt;

&lt;p&gt;Use this while you're on the call. It uses the same scoring as the Pass/Warn/Fail checks in our &lt;a href="https://banxal.com/blog/fix-or-rebuild-vibe-coded-app" rel="noopener noreferrer"&gt;fix-or-rebuild self-test&lt;/a&gt;: &lt;strong&gt;Green (0)&lt;/strong&gt;, &lt;strong&gt;Yellow (1)&lt;/strong&gt;, &lt;strong&gt;Red (2)&lt;/strong&gt;.&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;Green:&lt;/strong&gt; a specific answer, and they ask you something useful back.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Yellow:&lt;/strong&gt; the right idea, but vague, or "I'd have to check" without saying how they'd check.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Red:&lt;/strong&gt; the red-flag answer, or a confident answer that contradicts the official docs.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.us-east-2.amazonaws.com%2Fuploads%2Farticles%2Fr7828876bxxc09fob8mh.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.us-east-2.amazonaws.com%2Fuploads%2Farticles%2Fr7828876bxxc09fob8mh.png" alt="Developer vetting scorecard: 8 rows (Q1 audit before quote through Q8 definition of done) each with Green/Yellow/Red tick-boxes, Q2, Q3, Q6 and Q7 marked deal-breaker, and a results band of 0–3 strong candidate, 4–7 probe the yellows, 8–16 keep looking." width="800" height="640"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;div class="table-wrapper-paragraph"&gt;&lt;table&gt;
&lt;thead&gt;
&lt;tr&gt;
&lt;th&gt;Score&lt;/th&gt;
&lt;th&gt;Also true&lt;/th&gt;
&lt;th&gt;What to do&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td&gt;0–3&lt;/td&gt;
&lt;td&gt;No Red anywhere&lt;/td&gt;
&lt;td&gt;Strong candidate. Check two references, then agree the audit scope.&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;4–7&lt;/td&gt;
&lt;td&gt;No Red on Q2, Q3, Q6 or Q7&lt;/td&gt;
&lt;td&gt;Ask them to answer the Yellow questions in writing before you sign.&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;8–16&lt;/td&gt;
&lt;td&gt;—&lt;/td&gt;
&lt;td&gt;Keep looking.&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Any&lt;/td&gt;
&lt;td&gt;A Red on Q2, Q3, Q6 or Q7&lt;/td&gt;
&lt;td&gt;Keep looking, whatever the total.&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;&lt;/div&gt;

&lt;p&gt;These thresholds are our rule of thumb, not an industry standard. The rule that matters is the last row. A charming developer who wants your Supabase password is still a bad hire.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;A hypothetical example.&lt;/strong&gt; Back to the three replies from the opening. Developer A (the "two-day job") answers Q1 with a firm price and Q2 with "the scanner's fine". That's two Reds, one of them on a deal-breaker. Developer B (the "rebuild") hasn't read the code either, so Q1 is Red, but they're solid on Q2 to Q4 and they offer an IP assignment. They score 4–7, so ask why they think a rebuild is needed before trusting the verdict. Developer C (the "send me your login") fails Q6 straight away. None of them is an obvious yes. That's a normal result, and it's the reason to talk to a fourth.&lt;/p&gt;

&lt;h2&gt;
  
  
  FAQ
&lt;/h2&gt;

&lt;p&gt;&lt;strong&gt;Should I pay for a code audit before hiring a developer to fix my app?&lt;/strong&gt;&lt;br&gt;
Usually, yes. A short, scoped review turns a guess into a list of findings, and you keep the list even if you hire someone else. Our self-test lets you do the first pass for free.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Can the developer who fixes my app keep using Lovable or Bolt?&lt;/strong&gt;&lt;br&gt;
Yes, if you agree a way of working first. The usual risk is you and the developer changing the same code at the same time, through the builder and through GitHub. Our &lt;a href="https://banxal.com/blog/handoff-lovable-bolt-app-to-developer" rel="noopener noreferrer"&gt;handoff guide&lt;/a&gt; covers how each builder syncs.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Is a freelancer or an agency better for fixing a vibe-coded app?&lt;/strong&gt;&lt;br&gt;
Neither is better by default. It depends on how clearly you can describe the problem. A freelancer suits one well-defined fix. A team suits a broader audit followed by ongoing work. Score both with the same eight questions.&lt;/p&gt;

&lt;h2&gt;
  
  
  Next step
&lt;/h2&gt;

&lt;p&gt;If you'd like a second opinion on your app, or want to see how we'd answer these eight questions, Banxal builds and hardens &lt;a href="https://banxal.com/services" rel="noopener noreferrer"&gt;web apps and SaaS products&lt;/a&gt; and looks after them afterwards. We'll review the code before we suggest anything, and we'll tell you plainly if a rebuild isn't needed. &lt;a href="https://banxal.com/contact" rel="noopener noreferrer"&gt;Tell us about your app&lt;/a&gt;.&lt;/p&gt;

&lt;p&gt;Which of these questions has caught someone out on one of your hiring calls? Or which one do you wish you'd asked? Tell us in the comments.&lt;/p&gt;




&lt;p&gt;&lt;em&gt;Originally published on &lt;a href="https://banxal.com/blog/vet-developer-fix-vibe-coded-app" rel="noopener noreferrer"&gt;banxal.com&lt;/a&gt;.&lt;/em&gt;&lt;/p&gt;

</description>
      <category>startup</category>
      <category>webdev</category>
      <category>security</category>
      <category>beginners</category>
    </item>
    <item>
      <title>MVP Spec Template for Non-Technical Founders: Cut First</title>
      <dc:creator>Manveer</dc:creator>
      <pubDate>Sun, 04 Oct 2026 10:38:49 +0000</pubDate>
      <link>https://dev.to/manveer-banxal/mvp-spec-template-for-non-technical-founders-cut-first-1cjc</link>
      <guid>https://dev.to/manveer-banxal/mvp-spec-template-for-non-technical-founders-cut-first-1cjc</guid>
      <description>&lt;p&gt;Most founders write their first spec the same way: a long list of everything the product will do. A developer reads it, quotes for all of it, and three weeks in someone asks, "Can we also add…?"&lt;/p&gt;

&lt;p&gt;This &lt;strong&gt;MVP spec template for non-technical founders&lt;/strong&gt; reverses the order. You write down what you're &lt;em&gt;not&lt;/em&gt; building before you describe what you are. It takes five minutes, fits on one page, and gives your developer the one thing most specs leave out: a clear edge.&lt;/p&gt;

&lt;h2&gt;
  
  
  TL;DR
&lt;/h2&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;Write the out-of-scope list first.&lt;/strong&gt; For each cut feature, note the manual workaround and the point at which you'll reconsider it. That's what keeps cut features from creeping back in.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Scope in one core workflow and name its screens.&lt;/strong&gt; If a developer can't count the screens, they can't estimate the work.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Send one page, not twenty.&lt;/strong&gt; Include the template below, a few sketches and your constraints. A good developer's first questions will be about the edges, not the features.&lt;/li&gt;
&lt;/ul&gt;

&lt;h2&gt;
  
  
  Why specs get scope creep
&lt;/h2&gt;

&lt;p&gt;Specs get scope creep because the out-of-scope decision gets made too late, after the feature list is already written — and the problem is common well beyond first-time founders. In PMI's 2018 &lt;em&gt;Pulse of the Profession&lt;/em&gt; survey, 52% of projects completed in the previous 12 months had scope creep or uncontrolled changes to scope, up from 43% five years earlier (&lt;a href="https://www.pmi.org/-/media/pmi/documents/public/pdf/learning/thought-leadership/pulse/pulse-of-the-profession-2018.pdf" rel="noopener noreferrer"&gt;PMI, 2018&lt;/a&gt;). The same report names "erroneous requirements gathering" as one of the causes behind uncontrolled scope.&lt;/p&gt;

&lt;p&gt;For an MVP, every added feature delays the day real users tell you whether the idea works. In CB Insights' 2026 analysis of startup shutdowns, poor product-market fit was cited in 43% of cases where a failure reason could be identified (&lt;a href="https://www.cbinsights.com/research/report/startup-failure-reasons-top/" rel="noopener noreferrer"&gt;CB Insights&lt;/a&gt;).&lt;/p&gt;

&lt;p&gt;Most MVP spec templates do have an "out of scope" section. The trouble is that it comes near the end, after the features. By then you've already decided what's in, and the section just collects leftovers.&lt;/p&gt;

&lt;h2&gt;
  
  
  Start with what you're not building
&lt;/h2&gt;

&lt;p&gt;Write your out-of-scope list before you write your feature list — deciding what to cut first is what keeps the cuts from being reversed later. Starting with exclusions isn't a new idea: Basecamp's Shape Up method lists "no-gos" as one of the five parts of every project pitch: "functionality or use cases we intentionally aren't covering" (&lt;a href="https://basecamp.com/shapeup/1.5-chapter-06" rel="noopener noreferrer"&gt;Shape Up, ch. 6&lt;/a&gt;). The MoSCoW prioritisation method has a "Won't Have this time" category for the same reason. Writing those items down helps "avoid them being informally reintroduced at a later date" (&lt;a href="https://www.agilebusiness.org/resource/what-is-moscow-prioritization/" rel="noopener noreferrer"&gt;Agile Business Consortium&lt;/a&gt;).&lt;/p&gt;

&lt;p&gt;"Informally reintroduced" is how MVP scope creep usually happens. Nobody decides to double the scope. Someone says on a call that self-rescheduling would be nice, and since nobody wrote down why it was cut, nobody can say no.&lt;/p&gt;

&lt;p&gt;The fix is to give every cut feature three things:&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;
&lt;strong&gt;The feature&lt;/strong&gt;, named specifically ("customer self-rescheduling", not "account features").&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;The manual workaround&lt;/strong&gt; you'll use instead ("customer texts us; we move it by hand").&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;The revisit trigger&lt;/strong&gt;: the evidence that would put it back on the table ("more than 10 reschedule texts a week").&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;A cut with a workaround and a trigger reads as a decision. A cut without them reads as an oversight, and people will try to fix oversights.&lt;/p&gt;

&lt;h2&gt;
  
  
  The 5-minute out-of-scope exercise
&lt;/h2&gt;

&lt;p&gt;Set a timer and grab paper or a blank doc.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Minutes 0–2: Dump everything.&lt;/strong&gt; List every feature you've imagined, including the ones you assume are obvious: login with Google, an admin dashboard, notifications, a mobile app, reports, payments, reviews, multiple languages. Don't filter yet.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Minutes 2–3: Apply the one-question test.&lt;/strong&gt; For each item, ask: &lt;em&gt;Can my first 10 real customers get the core job done without this?&lt;/em&gt; If yes, move it to the out-of-scope column. Be strict. Most items will move.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Minutes 3–4: Write the workaround.&lt;/strong&gt; For each cut item, write how you'll handle it by hand for now: email, a spreadsheet, a phone call, a Stripe payment link, or you personally. If you can't think of any workaround, that's a signal the item may belong in scope.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Minutes 4–5: Write the trigger.&lt;/strong&gt; For each cut item, write what would make you reconsider it. Make it observable ("three customers ask for it unprompted"), not a feeling ("when we're bigger").&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.us-east-2.amazonaws.com%2Fuploads%2Farticles%2F97nfg6vti1exu1fg2bmt.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.us-east-2.amazonaws.com%2Fuploads%2Farticles%2F97nfg6vti1exu1fg2bmt.png" alt="Out-of-scope worksheet with the one-question test at the top and a three-column table (Feature cut, Manual workaround for now, Revisit when…) showing four example rows: native app, self-rescheduling, online payment and SMS reminders." width="800" height="540"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Two things never go on the cut list: basic security (proper login, protected data, backups) and anything the law requires where you operate. Those aren't features. They're the cost of having real users.&lt;/p&gt;

&lt;h2&gt;
  
  
  Now scope what's in (one core workflow, named screens)
&lt;/h2&gt;

&lt;p&gt;Once your out-of-scope list is set, the in-scope section only needs two things: one core workflow written as numbered steps, and a list of named screens. With the edges set, the in-scope section can stay short.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;One core workflow, written as numbered steps.&lt;/strong&gt; This is the one journey a user takes to get the value you're promising. Write it from the user's point of view, one action per line. If you have two workflows, pick the one that tests your riskiest assumption and move the other to out-of-scope.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;A list of named screens.&lt;/strong&gt; "Booking page", "Confirmation email", "Owner's day view". Developers estimate in screens, data and integrations, so a named list turns "a booking app" into something they can count. If a step in your workflow doesn't map to a screen, an email or a manual action, you've found a gap.&lt;/p&gt;

&lt;p&gt;The Agile Business Consortium recommends keeping "Must Have" work to no more than 60% of total effort, leaving room for surprises (&lt;a href="https://www.agilebusiness.org/resource/what-is-moscow-prioritization/" rel="noopener noreferrer"&gt;Agile Business Consortium&lt;/a&gt;). In practice: if your must-haves feel like the whole budget, keep cutting.&lt;/p&gt;

&lt;h2&gt;
  
  
  The one-page MVP spec template for non-technical founders (copy this)
&lt;/h2&gt;

&lt;p&gt;Call it a spec, an MVP scope document or a requirements template; the job is the same. Fill it in top to bottom. Section 2 comes before section 4 on purpose.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight markdown"&gt;&lt;code&gt;&lt;span class="gh"&gt;# [Product name] — MVP spec (v1, [date])&lt;/span&gt;

&lt;span class="gu"&gt;## 1. Who and why (3 lines max)&lt;/span&gt;
&lt;span class="p"&gt;-&lt;/span&gt; User: [one specific type of person or business]
&lt;span class="p"&gt;-&lt;/span&gt; Problem: [what they do today, and why it's painful]
&lt;span class="p"&gt;-&lt;/span&gt; This MVP proves: [the one assumption we're testing]

&lt;span class="gu"&gt;## 2. Not in this version&lt;/span&gt;
| Feature cut | Manual workaround for now | Revisit when… |
|---|---|---|
| | | |

&lt;span class="gu"&gt;## 3. Core workflow (numbered, user's point of view)&lt;/span&gt;
&lt;span class="p"&gt;1.&lt;/span&gt;
&lt;span class="p"&gt;2.&lt;/span&gt;
&lt;span class="p"&gt;3.&lt;/span&gt;

&lt;span class="gu"&gt;## 4. Screens and emails&lt;/span&gt;
&lt;span class="p"&gt;-&lt;/span&gt; [Screen name]: [what the user sees or does here]

&lt;span class="gu"&gt;## 5. Data we store&lt;/span&gt;
&lt;span class="p"&gt;-&lt;/span&gt; [e.g. Customer: name, phone, email]

&lt;span class="gu"&gt;## 6. Integrations (max 1–2)&lt;/span&gt;
&lt;span class="p"&gt;-&lt;/span&gt; [e.g. Stripe for deposits, Google Calendar sync]

&lt;span class="gu"&gt;## 7. Constraints&lt;/span&gt;
&lt;span class="p"&gt;-&lt;/span&gt; Must use / must avoid: [tools, accounts you already have]
&lt;span class="p"&gt;-&lt;/span&gt; Why the date matters: [launch event, funding, season, or "no hard date"]
&lt;span class="p"&gt;-&lt;/span&gt; Rules we must follow: [privacy, industry rules, where users are]

&lt;span class="gu"&gt;## 8. Done means&lt;/span&gt;
&lt;span class="p"&gt;-&lt;/span&gt; [The one measurable thing that tells us v1 worked]

&lt;span class="gu"&gt;## 9. Swap rule&lt;/span&gt;
New ideas during the build go to section 2. To add one, we remove
something of equal or larger size that hasn't been started.
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;The swap rule comes from Jesse Fewell, quoted in the same PMI report: "You can replace any not-started deliverable with anything of equal or lesser cost" (&lt;a href="https://www.pmi.org/-/media/pmi/documents/public/pdf/learning/thought-leadership/pulse/pulse-of-the-profession-2018.pdf" rel="noopener noreferrer"&gt;PMI, 2018&lt;/a&gt;). Writing it into the spec means you agree on the rule before you're attached to any new idea.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.us-east-2.amazonaws.com%2Fuploads%2Farticles%2Fxgb4fyfmoc6zlnkp0hvu.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.us-east-2.amazonaws.com%2Fuploads%2Farticles%2Fxgb4fyfmoc6zlnkp0hvu.png" alt="One-page MVP spec template mockup showing all 9 numbered sections in order, with section 2 " width="800" height="600"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;h2&gt;
  
  
  Worked example: a booking app for a grooming salon
&lt;/h2&gt;

&lt;p&gt;&lt;em&gt;This is a hypothetical example to show the template in use. It isn't a client project.&lt;/em&gt;&lt;/p&gt;

&lt;p&gt;Imagine a two-groomer dog salon where customers book by phone and Instagram DM, and the owner misses calls while grooming.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;1. Who and why&lt;/strong&gt;&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;User: existing salon customers booking a groom&lt;/li&gt;
&lt;li&gt;Problem: booking means calling during working hours or waiting for a DM reply&lt;/li&gt;
&lt;li&gt;This MVP proves: customers will book online if it's quick, which frees up the owner's time&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;&lt;strong&gt;2. Not in this version&lt;/strong&gt;&lt;/p&gt;

&lt;div class="table-wrapper-paragraph"&gt;&lt;table&gt;
&lt;thead&gt;
&lt;tr&gt;
&lt;th&gt;Feature cut&lt;/th&gt;
&lt;th&gt;Manual workaround for now&lt;/th&gt;
&lt;th&gt;Revisit when…&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td&gt;Native iOS/Android app&lt;/td&gt;
&lt;td&gt;Mobile-friendly web page&lt;/td&gt;
&lt;td&gt;Most bookings come from repeat customers on phones and they ask for an app&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Customer self-rescheduling&lt;/td&gt;
&lt;td&gt;Customer replies to the confirmation email; owner moves it&lt;/td&gt;
&lt;td&gt;More than 10 reschedule requests a week&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Online payment&lt;/td&gt;
&lt;td&gt;Pay in salon as today&lt;/td&gt;
&lt;td&gt;No-shows cost more than a deposit system would&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;SMS reminders&lt;/td&gt;
&lt;td&gt;Email reminder only&lt;/td&gt;
&lt;td&gt;No-show rate stays high after email reminders&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Customer accounts and logins&lt;/td&gt;
&lt;td&gt;Book with name, phone, email&lt;/td&gt;
&lt;td&gt;Repeat customers complain about re-entering details&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Reports and analytics&lt;/td&gt;
&lt;td&gt;Owner exports bookings to a spreadsheet monthly&lt;/td&gt;
&lt;td&gt;Owner needs this more than once a month&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Second location&lt;/td&gt;
&lt;td&gt;Not needed&lt;/td&gt;
&lt;td&gt;A second location is signed&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;&lt;/div&gt;

&lt;p&gt;&lt;strong&gt;3. Core workflow&lt;/strong&gt;&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;Customer opens the booking link from Instagram or Google.&lt;/li&gt;
&lt;li&gt;Picks a service (bath, full groom, nail trim) and dog size.&lt;/li&gt;
&lt;li&gt;Sees available slots for the next 14 days and picks one.&lt;/li&gt;
&lt;li&gt;Enters name, phone, email, dog's name and breed.&lt;/li&gt;
&lt;li&gt;Gets a confirmation email, and a reminder 24 hours before.&lt;/li&gt;
&lt;li&gt;Owner sees the booking in a day view and can cancel or block time.&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;&lt;strong&gt;4. Screens and emails:&lt;/strong&gt; service picker, slot picker, details form, confirmation page, confirmation email, reminder email, owner login, owner day view, block-time form. That's nine items a developer can estimate.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;5–8.&lt;/strong&gt; Data: customer, dog, booking, service, groomer. Integrations: an email-sending service. Constraint: the owner already uses Google Workspace. Done means: 30% of bookings made online within the first two months.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.us-east-2.amazonaws.com%2Fuploads%2Farticles%2Fg09rjqr9epxxo5pnwabm.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.us-east-2.amazonaws.com%2Fuploads%2Farticles%2Fg09rjqr9epxxo5pnwabm.png" alt="Two-column comparison for the hypothetical grooming-salon example: " width="800" height="533"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;The out-of-scope table, not the feature list, is what keeps this build small. "No online payment" and "no accounts" remove whole chunks of work, and the workarounds show they were decisions.&lt;/p&gt;

&lt;h2&gt;
  
  
  What to send a developer (and what a good first call sounds like)
&lt;/h2&gt;

&lt;p&gt;Send four things:&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;
&lt;strong&gt;The one-page spec&lt;/strong&gt; above.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Sketches.&lt;/strong&gt; Phone photos of paper drawings are fine. If you've built a clickable prototype in Lovable or Bolt, send that too. Our guide to &lt;a href="https://banxal.com/blog/handoff-lovable-bolt-app-to-developer" rel="noopener noreferrer"&gt;handing off a Lovable or Bolt app to a developer&lt;/a&gt; covers what to prepare.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Two or three reference products.&lt;/strong&gt; "Booking like Calendly, but showing services first."&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Accounts you already have:&lt;/strong&gt; domain, email provider, payment account, brand files.&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;On the first call, listen to the questions. A good developer asks about the edges: "What if two people book the same slot?" "Do groomers have different hours on different days?" They may push back on a cut, suggest cutting more, and say which parts they're unsure about. Be wary of anyone who agrees to everything and quotes without asking a question. That estimate is a guess.&lt;/p&gt;

&lt;p&gt;Already have a half-built product? Read &lt;a href="https://banxal.com/blog/fix-or-rebuild-vibe-coded-app" rel="noopener noreferrer"&gt;fix or rebuild a vibe-coded app&lt;/a&gt; before writing the spec.&lt;/p&gt;

&lt;h2&gt;
  
  
  Want a second pair of eyes on your spec?
&lt;/h2&gt;

&lt;p&gt;Banxal builds &lt;a href="https://banxal.com/services" rel="noopener noreferrer"&gt;web applications and MVPs&lt;/a&gt; for founders. If you've filled in the template, &lt;a href="https://banxal.com/contact" rel="noopener noreferrer"&gt;send it to us&lt;/a&gt;. We'll read it and tell you what's missing, what's unclear, and what we'd move to "not in this version".&lt;/p&gt;

&lt;h2&gt;
  
  
  FAQ
&lt;/h2&gt;

&lt;h3&gt;
  
  
  How long should an MVP spec be?
&lt;/h3&gt;

&lt;p&gt;One page for the parts above, plus sketches. If it runs past two pages, you're probably describing more than one workflow, or writing implementation details your developer should decide. Length doesn't make a spec clear. Clear edges do.&lt;/p&gt;

&lt;h3&gt;
  
  
  What if I don't know what to cut?
&lt;/h3&gt;

&lt;p&gt;Run the one-question test on every feature: can your first 10 customers get the core job done without it? If you still can't decide, ask what the manual workaround would cost you each week. If it's an hour of your time, cut it. If it means losing customers, keep it.&lt;/p&gt;

&lt;h3&gt;
  
  
  Do I need wireframes before talking to a developer?
&lt;/h3&gt;

&lt;p&gt;No. Named screens and rough sketches are enough for a useful first conversation and a sensible estimate. Detailed wireframes help later, but making them before scope is settled often means designing screens you'll cut.&lt;/p&gt;




&lt;p&gt;What's the hardest feature you've had to move to "not in this version"? Tell us in the comments. We'd especially like to hear from anyone whose revisit trigger actually fired.&lt;/p&gt;




&lt;p&gt;&lt;em&gt;Originally published on &lt;a href="https://banxal.com/blog/mvp-spec-template-non-technical-founders" rel="noopener noreferrer"&gt;banxal.com&lt;/a&gt;.&lt;/em&gt;&lt;/p&gt;

</description>
      <category>startup</category>
      <category>productivity</category>
      <category>webdev</category>
      <category>beginners</category>
    </item>
    <item>
      <title>AI Agent Cost per Month: The Token Maths, Worked Out</title>
      <dc:creator>Manveer</dc:creator>
      <pubDate>Sat, 03 Oct 2026 07:53:15 +0000</pubDate>
      <link>https://dev.to/manveer-banxal/ai-agent-cost-per-month-the-token-maths-worked-out-4e35</link>
      <guid>https://dev.to/manveer-banxal/ai-agent-cost-per-month-the-token-maths-worked-out-4e35</guid>
      <description>&lt;p&gt;A four-message support chat with a tool-using AI agent can send the model more than 45,000 input tokens. That's about twelve times Anthropic's own estimate of roughly 3,700 tokens for a support conversation (&lt;a href="https://platform.claude.com/docs/en/about-claude/pricing" rel="noopener noreferrer"&gt;Anthropic pricing&lt;/a&gt;). Nothing is broken: each turn simply resends everything that came before it.&lt;/p&gt;

&lt;p&gt;That's why most guides to &lt;strong&gt;AI agent cost per month&lt;/strong&gt; give you wide ranges instead of a number. This one gives you a formula, worked through a small-business example and priced against six current models using each provider's official pricing page.&lt;/p&gt;

&lt;h2&gt;
  
  
  TL;DR
&lt;/h2&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;Separate build cost from run cost.&lt;/strong&gt; This post covers only run cost: model tokens, tools, storage, monitoring and the people who handle escalations.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Conversation history is the biggest cost.&lt;/strong&gt; In our example, resending earlier turns accounts for 44% of the model bill. Because each turn resends all the earlier ones, history cost grows with the square of the number of turns.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;3,000 support conversations a month cost $17 to $342 in model fees&lt;/strong&gt; across six current models, before caching. Turning on prompt caching cut the Sonnet 5.5 bill by 59%.&lt;/li&gt;
&lt;/ul&gt;

&lt;h2&gt;
  
  
  Why "AI agent cost" articles never add up
&lt;/h2&gt;

&lt;p&gt;Most articles on this topic mix two different bills:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;Build cost:&lt;/strong&gt; design, integration, prompt work, testing. You pay it once, and it's usually much larger.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Run cost:&lt;/strong&gt; what you pay every month after launch. It grows with usage and never goes away.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;One top-ranking article says plainly that "the published per-token price tells you almost nothing about what an agent will actually spend" (&lt;a href="https://www.cloudzero.com/blog/ai-agent-cost/" rel="noopener noreferrer"&gt;CloudZero&lt;/a&gt;). True, but behaviour can be measured — and anything measurable belongs in a formula.&lt;/p&gt;

&lt;p&gt;Not sure you need an agent at all? Read &lt;a href="https://banxal.com/blog/zapier-n8n-or-ai-agent" rel="noopener noreferrer"&gt;Zapier, n8n or an AI agent&lt;/a&gt; — often one AI step inside a normal workflow is enough.&lt;/p&gt;

&lt;h2&gt;
  
  
  The real cost drivers
&lt;/h2&gt;

&lt;p&gt;Four things set your monthly bill:&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;
&lt;strong&gt;Conversations per month.&lt;/strong&gt; This is your volume.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Model calls per conversation.&lt;/strong&gt; A tool-using agent usually makes at least two calls per customer message: one to pick a tool, one to write the answer.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Input tokens per call.&lt;/strong&gt; Every call resends the system prompt, the tool definitions, the conversation so far and any retrieved documents. Tools add hidden tokens too. Anthropic adds a tool-use system prompt (496 tokens on Haiku 4.5, 286 on Sonnet 5.5) on top of your tool schemas (&lt;a href="https://platform.claude.com/docs/en/about-claude/pricing" rel="noopener noreferrer"&gt;Anthropic pricing&lt;/a&gt;).&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Loops and retries.&lt;/strong&gt; These are failed tool calls, re-asked questions and agents that check their own work. Each one is another full-price call.&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;One more catch: &lt;strong&gt;the same text produces different token counts on different models.&lt;/strong&gt; Anthropic says the tokenizer in its newer models "produces approximately 30% more tokens for the same text" (&lt;a href="https://platform.claude.com/docs/en/about-claude/pricing" rel="noopener noreferrer"&gt;Anthropic pricing&lt;/a&gt;). Count tokens on the model you'll actually use.&lt;/p&gt;

&lt;h2&gt;
  
  
  The formula
&lt;/h2&gt;

&lt;p&gt;Monthly run cost is conversations times per-conversation token cost, plus retry overhead, plus fixed costs. Here it is in full:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;Monthly run cost = N × (I × p_in + O × p_out) / 1,000,000 × (1 + r) + fixed costs

N      = conversations per month
I      = input tokens per conversation (summed over every model call)
O      = output tokens per conversation
p_in   = price per million input tokens; p_out = price per million output tokens
r      = retry/loop overhead (0.10 = 10% extra calls)
fixed  = vector DB, monitoring, hosting, search fees, human fallback
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;The hard part is calculating I correctly. Each call's input is &lt;strong&gt;fixed prefix + history so far + new content&lt;/strong&gt;. With T turns, k calls per turn and h tokens added to the history each turn:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;History tokens per conversation = k × h × T(T − 1) / 2
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;The T(T − 1) term is the important part. Going from 4 turns to 8 turns multiplies history tokens by 4.7 (from 6 to 28 in the T(T − 1)/2 term), not by 2.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.us-east-2.amazonaws.com%2Fuploads%2Farticles%2Fxrzq0za53d980fraq2jz.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.us-east-2.amazonaws.com%2Fuploads%2Farticles%2Fxrzq0za53d980fraq2jz.png" alt="Formula for monthly AI agent cost, with input tokens split into fixed prefix, history and new content, and history tokens rising 0, 1,900, 3,800, 5,700 across four turns." width="800" height="520"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Here's the same calculation as a small pricing calculator you can edit:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight python"&gt;&lt;code&gt;&lt;span class="k"&gt;def&lt;/span&gt; &lt;span class="nf"&gt;agent_cost&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;convs&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;turns&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;prefix&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;user&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;tool_call&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;tool_result&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;answer&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
               &lt;span class="n"&gt;price_in&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;price_out&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;overhead&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="mf"&gt;0.10&lt;/span&gt;&lt;span class="p"&gt;):&lt;/span&gt;
    &lt;span class="n"&gt;history&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;tokens_in&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;tokens_out&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="mi"&gt;0&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="mi"&gt;0&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="mi"&gt;0&lt;/span&gt;
    &lt;span class="k"&gt;for&lt;/span&gt; &lt;span class="n"&gt;_&lt;/span&gt; &lt;span class="ow"&gt;in&lt;/span&gt; &lt;span class="nf"&gt;range&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;turns&lt;/span&gt;&lt;span class="p"&gt;):&lt;/span&gt;
        &lt;span class="n"&gt;tokens_in&lt;/span&gt; &lt;span class="o"&gt;+=&lt;/span&gt; &lt;span class="n"&gt;prefix&lt;/span&gt; &lt;span class="o"&gt;+&lt;/span&gt; &lt;span class="n"&gt;history&lt;/span&gt; &lt;span class="o"&gt;+&lt;/span&gt; &lt;span class="n"&gt;user&lt;/span&gt;                            &lt;span class="c1"&gt;# call 1: pick a tool
&lt;/span&gt;        &lt;span class="n"&gt;tokens_in&lt;/span&gt; &lt;span class="o"&gt;+=&lt;/span&gt; &lt;span class="n"&gt;prefix&lt;/span&gt; &lt;span class="o"&gt;+&lt;/span&gt; &lt;span class="n"&gt;history&lt;/span&gt; &lt;span class="o"&gt;+&lt;/span&gt; &lt;span class="n"&gt;user&lt;/span&gt; &lt;span class="o"&gt;+&lt;/span&gt; &lt;span class="n"&gt;tool_call&lt;/span&gt; &lt;span class="o"&gt;+&lt;/span&gt; &lt;span class="n"&gt;tool_result&lt;/span&gt;  &lt;span class="c1"&gt;# call 2: answer
&lt;/span&gt;        &lt;span class="n"&gt;tokens_out&lt;/span&gt; &lt;span class="o"&gt;+=&lt;/span&gt; &lt;span class="n"&gt;tool_call&lt;/span&gt; &lt;span class="o"&gt;+&lt;/span&gt; &lt;span class="n"&gt;answer&lt;/span&gt;
        &lt;span class="n"&gt;history&lt;/span&gt; &lt;span class="o"&gt;+=&lt;/span&gt; &lt;span class="n"&gt;user&lt;/span&gt; &lt;span class="o"&gt;+&lt;/span&gt; &lt;span class="n"&gt;tool_call&lt;/span&gt; &lt;span class="o"&gt;+&lt;/span&gt; &lt;span class="n"&gt;tool_result&lt;/span&gt; &lt;span class="o"&gt;+&lt;/span&gt; &lt;span class="n"&gt;answer&lt;/span&gt;
    &lt;span class="n"&gt;per_conv&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;tokens_in&lt;/span&gt; &lt;span class="o"&gt;*&lt;/span&gt; &lt;span class="n"&gt;price_in&lt;/span&gt; &lt;span class="o"&gt;+&lt;/span&gt; &lt;span class="n"&gt;tokens_out&lt;/span&gt; &lt;span class="o"&gt;*&lt;/span&gt; &lt;span class="n"&gt;price_out&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="o"&gt;/&lt;/span&gt; &lt;span class="mf"&gt;1e6&lt;/span&gt;
    &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="n"&gt;per_conv&lt;/span&gt; &lt;span class="o"&gt;*&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="mi"&gt;1&lt;/span&gt; &lt;span class="o"&gt;+&lt;/span&gt; &lt;span class="n"&gt;overhead&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="o"&gt;*&lt;/span&gt; &lt;span class="n"&gt;convs&lt;/span&gt;

&lt;span class="nf"&gt;print&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nf"&gt;agent_cost&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="mi"&gt;3000&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="mi"&gt;4&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="mi"&gt;2000&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="mi"&gt;100&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="mi"&gt;50&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="mi"&gt;1500&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="mi"&gt;250&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="mf"&gt;1.00&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="mf"&gt;5.00&lt;/span&gt;&lt;span class="p"&gt;))&lt;/span&gt;  &lt;span class="c1"&gt;# ≈ 170.94
&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h2&gt;
  
  
  Worked example: AI agent cost per month for a small-business support bot
&lt;/h2&gt;

&lt;p&gt;This example prices a small-business support bot at $170.94 a month on Claude Haiku 4.5, with every step shown so you can swap in your own numbers.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;The setup (these are assumptions, so swap in your own):&lt;/strong&gt; a support agent that searches a knowledge base and answers customers.&lt;/p&gt;

&lt;div class="table-wrapper-paragraph"&gt;&lt;table&gt;
&lt;thead&gt;
&lt;tr&gt;
&lt;th&gt;Assumption&lt;/th&gt;
&lt;th&gt;Value&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td&gt;Conversations per month (N)&lt;/td&gt;
&lt;td&gt;3,000 (about 100 a day)&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Customer messages per conversation (T)&lt;/td&gt;
&lt;td&gt;4&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Model calls per turn (k)&lt;/td&gt;
&lt;td&gt;2 (choose tool → answer)&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;System prompt + tool definitions&lt;/td&gt;
&lt;td&gt;2,000 tokens&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Customer message / tool call / retrieved docs / answer&lt;/td&gt;
&lt;td&gt;100 / 50 / 1,500 / 250 tokens&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Retry overhead (r)&lt;/td&gt;
&lt;td&gt;10%&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;&lt;/div&gt;

&lt;p&gt;&lt;strong&gt;Step 1: tokens added to history per turn.&lt;/strong&gt; 100 + 50 + 1,500 + 250 = &lt;strong&gt;1,900&lt;/strong&gt;. History at the start of turns 1–4 is 0, 1,900, 3,800 and 5,700 tokens.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Step 2: input per turn.&lt;/strong&gt;&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Call 1 = 2,000 + history + 100 = &lt;strong&gt;2,100 + history&lt;/strong&gt;
&lt;/li&gt;
&lt;li&gt;Call 2 = 2,000 + history + 100 + 50 + 1,500 = &lt;strong&gt;3,650 + history&lt;/strong&gt;
&lt;/li&gt;
&lt;li&gt;Per turn = 5,750 + 2 × history&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;&lt;strong&gt;Step 3: input per conversation.&lt;/strong&gt; 4 × 5,750 = 23,000. History adds 2 × (0 + 1,900 + 3,800 + 5,700) = 22,800. That matches the formula: 2 × 1,900 × 6 = 22,800. &lt;strong&gt;Total I = 45,800 tokens.&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Step 4: output per conversation.&lt;/strong&gt; (50 + 250) × 4 = &lt;strong&gt;O = 1,200 tokens.&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Step 5: monthly tokens, with 10% overhead.&lt;/strong&gt;&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Input: 45,800 × 1.1 × 3,000 = &lt;strong&gt;151.14M&lt;/strong&gt;
&lt;/li&gt;
&lt;li&gt;Output: 1,200 × 1.1 × 3,000 = &lt;strong&gt;3.96M&lt;/strong&gt;
&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;&lt;strong&gt;Step 6: price it.&lt;/strong&gt; On Claude Haiku 4.5 ($1 input / $5 output per million tokens): 151.14 × $1 + 3.96 × $5 = $151.14 + $19.80 = &lt;strong&gt;$170.94 a month&lt;/strong&gt;, or about &lt;strong&gt;$0.057 per conversation&lt;/strong&gt;. The Python above gives the same figure.&lt;/p&gt;

&lt;p&gt;Notice the ratio: the agent reads 38 tokens for every token it writes. &lt;strong&gt;For tool-using agents, the input price matters far more than the output price.&lt;/strong&gt;&lt;/p&gt;

&lt;h2&gt;
  
  
  Provider price comparison
&lt;/h2&gt;

&lt;p&gt;Across six current models, the same worked example costs $17 to $342 a month in model fees alone. &lt;em&gt;Prices as of 3 October 2026, taken from each provider's official pricing page. Re-check them before relying on this; they change often.&lt;/em&gt; Monthly cost uses the worked example (151.14M input, 3.96M output) with no caching and no batching.&lt;/p&gt;

&lt;div class="table-wrapper-paragraph"&gt;&lt;table&gt;
&lt;thead&gt;
&lt;tr&gt;
&lt;th&gt;Model&lt;/th&gt;
&lt;th&gt;Input / Output per 1M tokens&lt;/th&gt;
&lt;th&gt;Cached input per 1M&lt;/th&gt;
&lt;th&gt;Example monthly cost&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td&gt;OpenAI gpt-6-luna&lt;/td&gt;
&lt;td&gt;$0.10 / $0.50&lt;/td&gt;
&lt;td&gt;$0.01&lt;/td&gt;
&lt;td&gt;&lt;strong&gt;$17.09&lt;/strong&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Gemini 3.5 Flash-Lite&lt;/td&gt;
&lt;td&gt;$0.30 / $2.50&lt;/td&gt;
&lt;td&gt;$0.03 + storage&lt;/td&gt;
&lt;td&gt;&lt;strong&gt;$55.24&lt;/strong&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Claude Haiku 4.5&lt;/td&gt;
&lt;td&gt;$1 / $5&lt;/td&gt;
&lt;td&gt;$0.10&lt;/td&gt;
&lt;td&gt;&lt;strong&gt;$170.94&lt;/strong&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Gemini 3.5 Flash&lt;/td&gt;
&lt;td&gt;$1.50 / $9&lt;/td&gt;
&lt;td&gt;$0.15 + storage&lt;/td&gt;
&lt;td&gt;&lt;strong&gt;$262.35&lt;/strong&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Claude Sonnet 5.5&lt;/td&gt;
&lt;td&gt;$2 / $10&lt;/td&gt;
&lt;td&gt;$0.20&lt;/td&gt;
&lt;td&gt;&lt;strong&gt;$341.88&lt;/strong&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;OpenAI gpt-6.1-sol&lt;/td&gt;
&lt;td&gt;$2 / $10&lt;/td&gt;
&lt;td&gt;$0.10&lt;/td&gt;
&lt;td&gt;&lt;strong&gt;$341.88&lt;/strong&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;&lt;/div&gt;

&lt;p&gt;Sources: &lt;a href="https://platform.claude.com/docs/en/about-claude/pricing" rel="noopener noreferrer"&gt;Anthropic&lt;/a&gt;, &lt;a href="https://developers.openai.com/api/docs/pricing" rel="noopener noreferrer"&gt;OpenAI&lt;/a&gt; (short-context rates, up to 272K input tokens), &lt;a href="https://ai.google.dev/gemini-api/docs/pricing" rel="noopener noreferrer"&gt;Google&lt;/a&gt; (Gemini caching also charges $1 per million tokens per hour of storage).&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.us-east-2.amazonaws.com%2Fuploads%2Farticles%2F7plovyoe413u9j68za8q.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.us-east-2.amazonaws.com%2Fuploads%2Farticles%2F7plovyoe413u9j68za8q.png" alt="Horizontal bar chart of monthly cost for the worked example across six models, $17.09 to $341.88, plus Sonnet 5.5 with caching at $140.79." width="800" height="480"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Prompt caching&lt;/strong&gt; is the biggest discount you can control. On Anthropic, a cache read costs 0.1× the base input price and a 5-minute cache write costs 1.25× (on Sonnet 5.5, that's $0.20 and $2.50 per million). With automatic caching, each new request reads everything up to the previous message from cache (&lt;a href="https://platform.claude.com/docs/en/build-with-claude/prompt-caching" rel="noopener noreferrer"&gt;Anthropic prompt caching&lt;/a&gt;). In our example, the eight calls add up to 45,800 input tokens. Of these, 36,450 are cache reads and 9,350 are writes:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Input: 36,450 × $0.20 + 9,350 × $2.50 = $0.0307 per conversation (down from $0.0916)&lt;/li&gt;
&lt;li&gt;Add output ($0.012), the 10% overhead and the 3,000 conversations: &lt;strong&gt;$140.79 a month instead of $341.88, a 59% cut.&lt;/strong&gt;
&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Two catches: the default cache lasts 5 minutes (a 1-hour cache costs 2× to write), so a quiet customer breaks the chain; and Haiku 4.5 only caches prompts of at least 4,096 tokens, so the early calls here wouldn't be cached (&lt;a href="https://platform.claude.com/docs/en/build-with-claude/prompt-caching" rel="noopener noreferrer"&gt;Anthropic prompt caching&lt;/a&gt;).&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Batch APIs&lt;/strong&gt; take 50% off at Anthropic, OpenAI and Google, but only for jobs that can wait, like nightly ticket summaries. They're no use for live chat.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Watch for introductory prices.&lt;/strong&gt; Gemini 3.8 Flash is $0.75 / $3.75 until 31 December 2026, then $1.50 / $7.50 from 1 January 2027 (&lt;a href="https://ai.google.dev/gemini-api/docs/pricing" rel="noopener noreferrer"&gt;Google&lt;/a&gt;). If you budget at the introductory price, your bill will double when it ends.&lt;/p&gt;

&lt;h2&gt;
  
  
  Hidden costs beyond tokens
&lt;/h2&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.us-east-2.amazonaws.com%2Fuploads%2Farticles%2Fl4eop7hlnz3il84y7ae5.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.us-east-2.amazonaws.com%2Fuploads%2Farticles%2Fl4eop7hlnz3il84y7ae5.png" alt="Stacked bar showing where a Claude Haiku 4.5 conversation's $0.0518 goes: 44.0% history, 30.9% fixed prefix, 13.5% current-turn input, 11.6% output." width="799" height="373"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;The model fee is only part of the cost of running an AI chatbot. The rest:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;Vector database.&lt;/strong&gt; Pinecone's free Starter plan covers up to 2 GB of storage, 2M write units and 1M read units a month. Its Standard plan has a $50/month minimum, then $0.33/GB/month for storage and $16–$18 per million read units (&lt;a href="https://www.pinecone.io/pricing/" rel="noopener noreferrer"&gt;Pinecone&lt;/a&gt;). OpenAI's hosted file search charges $0.10/GB per day after the first free GB (&lt;a href="https://developers.openai.com/api/docs/pricing" rel="noopener noreferrer"&gt;OpenAI&lt;/a&gt;).&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Monitoring and logging.&lt;/strong&gt; You need traces to find loops. Langfuse Cloud is free for 50k units a month, and its Core plan is $29/month for 100k units plus $8 per extra 100k. You can also self-host it for free (&lt;a href="https://langfuse.com/pricing" rel="noopener noreferrer"&gt;Langfuse&lt;/a&gt;). Our example makes about 24,000 model calls a month before retries, so check how your tool counts units.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Search and hosted runtimes.&lt;/strong&gt; Web search costs $10 per 1,000 searches on &lt;a href="https://platform.claude.com/docs/en/about-claude/pricing" rel="noopener noreferrer"&gt;Anthropic&lt;/a&gt; and $10 per 1,000 calls on &lt;a href="https://developers.openai.com/api/docs/pricing" rel="noopener noreferrer"&gt;OpenAI&lt;/a&gt;. &lt;a href="https://ai.google.dev/gemini-api/docs/pricing" rel="noopener noreferrer"&gt;Google&lt;/a&gt; includes 5,000 free searches a month across Gemini 3.x, then charges $14 per 1,000. Anthropic's Managed Agents add $0.08 per session-hour of runtime.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Human fallback and app hosting.&lt;/strong&gt; Escalated conversations cost your team's time, far more than the tokens. The server running the agent loop is usually a small cost, but never zero.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;For comparison, Intercom's Fin charges $0.99 per resolved conversation (&lt;a href="https://www.intercom.com/pricing" rel="noopener noreferrer"&gt;Intercom&lt;/a&gt;) — not like-for-like, since that price includes the product itself, but a useful ceiling.&lt;/p&gt;

&lt;h2&gt;
  
  
  When self-hosting an open model beats per-token pricing
&lt;/h2&gt;

&lt;p&gt;Running an open model on a GPU you rent turns a per-token bill into a per-hour one. On Lambda, one NVIDIA A10 (24 GB) is $1.29/hour and one H100 PCIe is $3.29/hour (&lt;a href="https://lambda.ai/pricing" rel="noopener noreferrer"&gt;Lambda&lt;/a&gt;). Running all month (about 730 hours), that's &lt;strong&gt;about $942 and $2,402&lt;/strong&gt;.&lt;/p&gt;

&lt;p&gt;Our whole example costs $17–$342 a month through an API. &lt;strong&gt;At small-business volume, self-hosting costs more, often several times more.&lt;/strong&gt; It starts to make sense when:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;the GPU is busy most of the day, because your volume is high enough to use the capacity you pay for&lt;/li&gt;
&lt;li&gt;your data can't leave your own infrastructure&lt;/li&gt;
&lt;li&gt;you need a fine-tuned or specialised open model&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;To find your break-even point, benchmark how many tokens per second the GPU handles on your workload, then add the engineering time for patching, scaling and uptime.&lt;/p&gt;

&lt;h2&gt;
  
  
  Quick self-check: is your spend normal or bloated?
&lt;/h2&gt;

&lt;p&gt;Pull a week of logs and check these:&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;
&lt;strong&gt;Input-to-output ratio.&lt;/strong&gt; A high ratio is normal for tool-using agents (ours is 38:1). A sudden rise usually means history or retrieval is growing unchecked.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Calls per turn.&lt;/strong&gt; If you designed for 2 and see 5, the agent is looping. Set a hard cap on steps.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Cost by turn count.&lt;/strong&gt; Long conversations cost far more than short ones. Summarise or trim history after a few turns.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Cache hit rate.&lt;/strong&gt; The API's usage fields (for example, &lt;code&gt;cache_read_input_tokens&lt;/code&gt;) show whether caching is working.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Model fit.&lt;/strong&gt; Are you using a top-tier model for questions a small model can answer? Send easy questions to a cheaper model.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Most expensive 5% of conversations.&lt;/strong&gt; Read them. Bugs and abuse usually show up there.&lt;/li&gt;
&lt;/ol&gt;

&lt;h2&gt;
  
  
  Want this run against your own numbers?
&lt;/h2&gt;

&lt;p&gt;If you want this formula applied to your real logs, or an agent built with budget caps and caching from the start, that's part of our &lt;a href="https://banxal.com/services" rel="noopener noreferrer"&gt;AI integration &amp;amp; agents&lt;/a&gt; work. &lt;a href="https://banxal.com/contact" rel="noopener noreferrer"&gt;Send us your volumes&lt;/a&gt; and we'll tell you what it should cost to run — or if an agent isn't worth it at all.&lt;/p&gt;

&lt;h2&gt;
  
  
  FAQ
&lt;/h2&gt;

&lt;h3&gt;
  
  
  How much does an AI agent cost per month for a small business?
&lt;/h3&gt;

&lt;p&gt;In our worked example, 3,000 support conversations cost $17–$342 a month in model fees across six current models, before caching. On top of that come vector storage, monitoring, search and your team's time on escalations.&lt;/p&gt;

&lt;h3&gt;
  
  
  Why is my AI chatbot's running cost higher than the per-token price suggests?
&lt;/h3&gt;

&lt;p&gt;Every call resends the system prompt, tool definitions and the conversation so far. History cost grows with the square of the number of turns, and retries add more full-price calls.&lt;/p&gt;

&lt;h3&gt;
  
  
  Does prompt caching really reduce LLM API costs?
&lt;/h3&gt;

&lt;p&gt;Usually. In our example it cut the Sonnet 5.5 bill by 59%. Check your model's minimum cacheable prompt length and how long the cache lasts.&lt;/p&gt;

&lt;h3&gt;
  
  
  Is self-hosting an open-source model cheaper?
&lt;/h3&gt;

&lt;p&gt;Rarely at small-business volume. One rented A10 GPU running all month costs about $942, which is more than our example's highest API bill.&lt;/p&gt;

&lt;p&gt;What does your agent's input-to-output ratio look like, and which cost driver surprised you most? Tell us in the comments.&lt;/p&gt;




&lt;p&gt;&lt;em&gt;Originally published on &lt;a href="https://banxal.com/blog/ai-agent-cost-per-month" rel="noopener noreferrer"&gt;banxal.com&lt;/a&gt;.&lt;/em&gt;&lt;/p&gt;

</description>
      <category>ai</category>
      <category>llm</category>
      <category>startup</category>
      <category>python</category>
    </item>
    <item>
      <title>AI Agent vs Zapier for Small Business: Pick by Task</title>
      <dc:creator>Manveer</dc:creator>
      <pubDate>Fri, 02 Oct 2026 15:54:56 +0000</pubDate>
      <link>https://dev.to/manveer-banxal/ai-agent-vs-zapier-for-small-business-pick-by-task-21n</link>
      <guid>https://dev.to/manveer-banxal/ai-agent-vs-zapier-for-small-business-pick-by-task-21n</guid>
      <description>&lt;p&gt;Someone on your team just spent Friday afternoon copying form leads into the CRM. Again. Half your feed says "replace your team with AI agents"; the other half says "just use Zapier". Both camps are selling something.&lt;/p&gt;

&lt;p&gt;Here's the honest answer to the AI agent vs Zapier small business question: most of your automations don't need an agent, a few genuinely do, and some shouldn't be automated at all. The task decides, not the tool. Below is a task-by-task table across Zapier or Make, n8n, custom code and AI agents, plus what each costs to run.&lt;/p&gt;

&lt;h2&gt;
  
  
  TL;DR
&lt;/h2&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;Ask one question first: does this task need judgment?&lt;/strong&gt; If every input has one correct, rule-writable output, you want a workflow tool, not an agent.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Zapier or Make covers most small-business glue work.&lt;/strong&gt; n8n earns its complexity with heavy branching, self-hosting or data control. Custom code wins at high volume or when the logic is your product.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Agents cost per run, and that cost varies run to run.&lt;/strong&gt; Use them where the input is messy and the steps can't be predicted, with a human checkpoint in front of anything that touches customers or money.&lt;/li&gt;
&lt;/ul&gt;

&lt;h2&gt;
  
  
  The real question is "does this task need judgment?"
&lt;/h2&gt;

&lt;p&gt;Anthropic, which builds agents for a living, draws a useful line. Workflows are "systems where LLMs and tools are orchestrated through predefined code paths", while agents are "systems where LLMs dynamically direct their own processes and tool usage" (&lt;a href="https://www.anthropic.com/engineering/building-effective-agents" rel="noopener noreferrer"&gt;Anthropic, Building effective agents&lt;/a&gt;). Their advice is to find "the simplest solution possible, and only increase complexity when needed", because agentic systems "often trade latency and cost for better task performance".&lt;/p&gt;

&lt;p&gt;So, in plain terms:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;No judgment needed&lt;/strong&gt; (form submitted, create CRM contact): a rule-based workflow — cheaper, faster, and it fails the same way every time, making it easy to debug.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;A little judgment on a fixed path&lt;/strong&gt; (read this email, label it "billing", "bug" or "sales"): a workflow with one AI step. The path is fixed; only one decision is fuzzy.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Open-ended judgment&lt;/strong&gt; (research this prospect and decide what to look at next): an agent. Anthropic describes this as problems "where it's difficult or impossible to predict the required number of steps, and where you can't hardcode a fixed path."&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;That middle category is where most small-business value sits.&lt;/p&gt;

&lt;h2&gt;
  
  
  The four options in one sentence each
&lt;/h2&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;Zapier / Make:&lt;/strong&gt; hosted, no-code "when this happens, do that" workflows across thousands of apps. Zapier lists 10,000+ (&lt;a href="https://zapier.com/apps" rel="noopener noreferrer"&gt;Zapier apps&lt;/a&gt;).&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;n8n:&lt;/strong&gt; a visual workflow builder you can self-host, with JavaScript and Python code steps and 1,500+ integrations (&lt;a href="https://github.com/n8n-io/n8n" rel="noopener noreferrer"&gt;n8n on GitHub&lt;/a&gt;).&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Custom code:&lt;/strong&gt; a script or service your developer writes, runs on your own infrastructure and keeps in version control.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;AI agent:&lt;/strong&gt; a language model given tools (search, CRM, email) and a goal, deciding its own steps until finished or stopped.&lt;/li&gt;
&lt;/ul&gt;

&lt;h2&gt;
  
  
  AI agent vs Zapier for a small business: the decision table
&lt;/h2&gt;

&lt;p&gt;These are the tasks we see most often in startup and SMB backlogs. "Best fit" means the simplest option that does the job reliably, not the only one that could.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.us-east-2.amazonaws.com%2Fuploads%2Farticles%2F1xzkmyv5hqpcl8nz3pbi.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.us-east-2.amazonaws.com%2Fuploads%2Farticles%2F1xzkmyv5hqpcl8nz3pbi.png" alt="Matrix of 12 SMB tasks against Zapier/Make, n8n, custom code and AI agent, with the best-fit option highlighted per row" width="800" height="533"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;div class="table-wrapper-paragraph"&gt;&lt;table&gt;
&lt;thead&gt;
&lt;tr&gt;
&lt;th&gt;Task&lt;/th&gt;
&lt;th&gt;Best fit&lt;/th&gt;
&lt;th&gt;Why&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td&gt;Website form → CRM contact + Slack alert&lt;/td&gt;
&lt;td&gt;Zapier / Make&lt;/td&gt;
&lt;td&gt;Fixed path, popular apps, five minutes to build.&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Stripe payment → invoice in accounting tool + welcome email&lt;/td&gt;
&lt;td&gt;Zapier / Make&lt;/td&gt;
&lt;td&gt;Clear trigger, clear actions, no judgment.&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Weekly metrics from 3 tools into a Google Sheet&lt;/td&gt;
&lt;td&gt;Zapier / Make (n8n if it grows)&lt;/td&gt;
&lt;td&gt;Scheduled and predictable; move to n8n once it needs loops.&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Lead routing with 10+ rules (region, size, source, owner capacity)&lt;/td&gt;
&lt;td&gt;n8n&lt;/td&gt;
&lt;td&gt;Lots of branching and merging; per-step pricing gets expensive.&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Workflows touching health, finance or client data that must stay on your servers&lt;/td&gt;
&lt;td&gt;n8n (self-hosted)&lt;/td&gt;
&lt;td&gt;You control where the data runs.&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Two-way CRM ↔ ERP sync with deduplication&lt;/td&gt;
&lt;td&gt;Custom code (or n8n with care)&lt;/td&gt;
&lt;td&gt;Conflict handling and retries are real engineering problems.&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Sorting inbound support email into categories&lt;/td&gt;
&lt;td&gt;Workflow + one AI step&lt;/td&gt;
&lt;td&gt;Fixed path; only the labelling is fuzzy.&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Pulling fields from invoices or PDFs with varying layouts&lt;/td&gt;
&lt;td&gt;Workflow + one AI step&lt;/td&gt;
&lt;td&gt;Extraction needs a model; everything around it doesn't.&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Answering customer questions from your docs and policies&lt;/td&gt;
&lt;td&gt;AI assistant on your data (RAG)&lt;/td&gt;
&lt;td&gt;Questions are open-ended; answers must be grounded in your content.&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Researching a prospect across the web and drafting a brief&lt;/td&gt;
&lt;td&gt;AI agent&lt;/td&gt;
&lt;td&gt;You can't predict which pages or how many steps it will need.&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Nightly import of hundreds of thousands of rows&lt;/td&gt;
&lt;td&gt;Custom code&lt;/td&gt;
&lt;td&gt;Per-task or per-credit billing punishes volume; a script doesn't care.&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;A 10-minute task done twice a month&lt;/td&gt;
&lt;td&gt;Skip automation&lt;/td&gt;
&lt;td&gt;Write a checklist; automating costs more than it saves.&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;&lt;/div&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.us-east-2.amazonaws.com%2Fuploads%2Farticles%2Fj1xt409ojbq8ldr7vd7x.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.us-east-2.amazonaws.com%2Fuploads%2Farticles%2Fj1xt409ojbq8ldr7vd7x.png" alt="Decision tree: five yes/no questions routing a task to a checklist, Zapier/Make, n8n, custom code, a workflow with one AI step, or an AI agent" width="800" height="600"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;h2&gt;
  
  
  When Zapier or Make is simply correct
&lt;/h2&gt;

&lt;p&gt;If the task is "when X happens in app A, do Y in app B" and both apps are mainstream, Zapier or Make is the right answer — not a compromise.&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;Speed to working.&lt;/strong&gt; A non-developer can build and own it, so it doesn't wait in an engineering queue.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Built-in reliability.&lt;/strong&gt; You don't run servers. Zapier also only counts a task when an action succeeds: "Failed actions are not counted" (&lt;a href="https://zapier.com/pricing" rel="noopener noreferrer"&gt;Zapier pricing&lt;/a&gt;).&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Low volume is cheap.&lt;/strong&gt; Zapier says triggers and built-in tools like Filter, Formatter and Paths don't count as tasks (&lt;a href="https://zapier.com/pricing" rel="noopener noreferrer"&gt;Zapier pricing&lt;/a&gt;).&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;&lt;strong&gt;This is the wrong choice if&lt;/strong&gt; the workflow has grown past ~10 steps with nested paths, nobody remembers why each step exists, or your task count keeps tipping into the next pricing tier.&lt;/p&gt;

&lt;h2&gt;
  
  
  When n8n earns its complexity
&lt;/h2&gt;

&lt;p&gt;n8n gives you more control in exchange for more responsibility. It earns it in three situations.&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;
&lt;strong&gt;Self-hosting and data control.&lt;/strong&gt; The Community edition is free to self-host. Its licence lets you use it "for your own internal business purposes" (&lt;a href="https://github.com/n8n-io/n8n/blob/master/LICENSE.md" rel="noopener noreferrer"&gt;n8n Sustainable Use License&lt;/a&gt;) — fine for your own automations, but embedding n8n in a product you sell needs its own licence check.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Branching-heavy logic.&lt;/strong&gt; Loops, merges, sub-workflows and code steps in JavaScript or Python (&lt;a href="https://github.com/n8n-io/n8n" rel="noopener noreferrer"&gt;n8n on GitHub&lt;/a&gt;) handle logic that turns a Zapier canvas into spaghetti.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Many steps, many runs.&lt;/strong&gt; n8n bills per execution: "a single run of your entire workflow. It doesn't matter how many steps are in the workflow" (&lt;a href="https://n8n.io/pricing/" rel="noopener noreferrer"&gt;n8n pricing&lt;/a&gt;). A 15-step workflow costs the same as a 2-step one.&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;&lt;strong&gt;The hidden cost:&lt;/strong&gt; self-hosting means you own updates, backups, uptime and security — if nobody will patch the server, use n8n Cloud or stay on Zapier.&lt;/p&gt;

&lt;h2&gt;
  
  
  When you actually need an AI agent
&lt;/h2&gt;

&lt;p&gt;You need an agent when all three of these are true:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;The input is messy:&lt;/strong&gt; free text, varied documents, the open web.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;You can't write the steps down in advance:&lt;/strong&gt; the next action depends on what the last one found.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;A wrong answer is recoverable:&lt;/strong&gt; a human reviews it, or the cost of an error is small.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;If only the first is true, skip the agent — put one AI step inside a normal workflow instead. Both Zapier and n8n support this, and it's easier to test, since the model makes just one decision per run.&lt;/p&gt;

&lt;p&gt;When you do build an agent, take Anthropic's warning seriously: "The autonomous nature of agents means higher costs, and the potential for compounding errors. We recommend extensive testing in sandboxed environments, along with the appropriate guardrails" (&lt;a href="https://www.anthropic.com/engineering/building-effective-agents" rel="noopener noreferrer"&gt;Anthropic&lt;/a&gt;). In practice that means:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;Start read-only.&lt;/strong&gt; Let it search and draft; don't let it send, refund or delete until proven.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Default to approval.&lt;/strong&gt; Anything reaching a customer goes through a human queue first.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Cap the run.&lt;/strong&gt; Set a max step count and token budget so it can't loop all night.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Log every call.&lt;/strong&gt; You need to see why, when it gets something wrong.&lt;/li&gt;
&lt;/ul&gt;

&lt;h2&gt;
  
  
  When to just write custom code (or skip automation)
&lt;/h2&gt;

&lt;p&gt;Custom code is the right call when:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;Volume is high.&lt;/strong&gt; Per-task and per-credit pricing grows with every run; a script on a small server mostly doesn't.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;The logic is your product.&lt;/strong&gt; If customers pay for it, it belongs in your codebase with tests, not a no-code canvas only one person understands.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;You need real sync.&lt;/strong&gt; Two-way sync, idempotent retries and conflict resolution are easier to get right in code.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Sometimes the right automation is none: if a task is rare, changes every time, or lives in a tool with no API, a checklist beats a fragile bot. Quick automations also tend to become unmaintained software; if yours has, our guide on whether to &lt;a href="https://banxal.com/blog/fix-or-rebuild-vibe-coded-app" rel="noopener noreferrer"&gt;fix or rebuild a vibe-coded app&lt;/a&gt; applies here too.&lt;/p&gt;

&lt;h2&gt;
  
  
  Cost reality check: the shape matters more than the sticker price
&lt;/h2&gt;

&lt;p&gt;Every option is cheap to start; what matters is how the bill grows. Prices below are from each vendor's official pricing page on 2 October 2026 — check again before committing, since they change.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.us-east-2.amazonaws.com%2Fuploads%2Farticles%2Fo732e5zqik5fjtrobwr6.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.us-east-2.amazonaws.com%2Fuploads%2Farticles%2Fo732e5zqik5fjtrobwr6.png" alt="Five charts of monthly cost vs runs: Zapier and Make step up with steps/modules × runs, n8n steps up with runs only, custom code is a flat line after an upfront cost, AI agent rises steadily with a variance band" width="799" height="373"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;div class="table-wrapper-paragraph"&gt;&lt;table&gt;
&lt;thead&gt;
&lt;tr&gt;
&lt;th&gt;Option&lt;/th&gt;
&lt;th&gt;You pay per…&lt;/th&gt;
&lt;th&gt;Entry price (official page, 2 Oct 2026)&lt;/th&gt;
&lt;th&gt;How the bill grows&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td&gt;Zapier&lt;/td&gt;
&lt;td&gt;Task (each successful action)&lt;/td&gt;
&lt;td&gt;Free: 100 tasks/mo, two-step Zaps only. Professional: $19.99/mo billed annually ($29.99 monthly) for 750 tasks; $39/mo annually for 1,500&lt;/td&gt;
&lt;td&gt;Steps × runs. With pay-per-task on, overage is 1.25× the base rate on annual plans or 2.5× on monthly (&lt;a href="https://zapier.com/pricing" rel="noopener noreferrer"&gt;Zapier&lt;/a&gt;)&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Make&lt;/td&gt;
&lt;td&gt;Credit (each module action)&lt;/td&gt;
&lt;td&gt;Free: 1,000 credits/mo; Make plan from $9/mo for 5,000 credits (&lt;a href="https://www.make.com/en/pricing" rel="noopener noreferrer"&gt;Make&lt;/a&gt;)&lt;/td&gt;
&lt;td&gt;Modules × runs; routers and error handlers don't count&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;n8n&lt;/td&gt;
&lt;td&gt;Execution (whole workflow run)&lt;/td&gt;
&lt;td&gt;Cloud Starter €20/mo billed annually for 2,500 executions; Pro €50/mo for 10,000; Community edition free to self-host (&lt;a href="https://n8n.io/pricing/" rel="noopener noreferrer"&gt;n8n&lt;/a&gt;)&lt;/td&gt;
&lt;td&gt;Runs only. Self-hosting turns it into server costs plus your team's time&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Custom code&lt;/td&gt;
&lt;td&gt;Developer time up front, then hosting&lt;/td&gt;
&lt;td&gt;Depends on scope&lt;/td&gt;
&lt;td&gt;Large one-off cost, then low and mostly flat&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;AI agent (via API)&lt;/td&gt;
&lt;td&gt;Tokens in and out&lt;/td&gt;
&lt;td&gt;For example, Claude Haiku 4.5 is $1 per million input tokens and $5 per million output; Sonnet 5.5 is $2 / $10 (&lt;a href="https://platform.claude.com/docs/en/about-claude/pricing" rel="noopener noreferrer"&gt;Anthropic pricing&lt;/a&gt;)&lt;/td&gt;
&lt;td&gt;Runs × tokens per run. The same task can use very different amounts of tokens each time&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;&lt;/div&gt;

&lt;p&gt;&lt;strong&gt;A quick worked example:&lt;/strong&gt; a workflow with a trigger and four actions, run 300 times a month, costs roughly 1,200 Zapier tasks (over the 750 tier, onto the $39/mo annual 1,500 tier), 300 n8n Cloud executions (well inside Starter's 2,500), or 1,500 Make credits (inside the 5,000-credit tier). None is expensive at this size, but add steps or runs: Zapier's bill grows on both, n8n's on one.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;For agents, Anthropic publishes its own estimate:&lt;/strong&gt; about 3,700 tokens per support conversation on Haiku 4.5 comes to "~$37.00 per 10,000 tickets" (&lt;a href="https://platform.claude.com/docs/en/about-claude/pricing" rel="noopener noreferrer"&gt;Anthropic pricing&lt;/a&gt;). Cheap, but that's roughly one conversation's worth of tokens. An agent that searches, reads pages and retries can use many times that, and the amount varies per run — budget with a per-run cap, not an average.&lt;/p&gt;

&lt;h2&gt;
  
  
  A 5-minute self-test
&lt;/h2&gt;

&lt;p&gt;Pick one task from your backlog and answer these five questions.&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;
&lt;strong&gt;How often does it happen?&lt;/strong&gt; Less than weekly and under 15 minutes? Write a checklist and stop here.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Could you write every rule on one page?&lt;/strong&gt; Yes → Zapier, Make or n8n. No → keep going.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Is only one step fuzzy (classify, extract, summarise)?&lt;/strong&gt; Yes → a workflow with one AI step.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Does the path change based on what it finds?&lt;/strong&gt; Yes → an agent, with read-only tools and human approval to start.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Is it high-volume, a two-way sync, or part of your product?&lt;/strong&gt; Yes → custom code, whatever you answered above.&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;One more check: must the data stay on your servers? If so, use self-hosted n8n or custom code, regardless of your other answers.&lt;/p&gt;

&lt;h2&gt;
  
  
  Not sure which bucket your process fits?
&lt;/h2&gt;

&lt;p&gt;If a task still doesn't fit a bucket, or your Zapier account has become something nobody wants to touch, that's what our &lt;a href="https://banxal.com/services" rel="noopener noreferrer"&gt;automation &amp;amp; integrations&lt;/a&gt; work covers — including AI agents with review steps built in, where judgment is genuinely needed. &lt;a href="https://banxal.com/contact" rel="noopener noreferrer"&gt;Send us the process&lt;/a&gt; and we'll tell you which option fits, even if it's "keep using Zapier".&lt;/p&gt;

&lt;h2&gt;
  
  
  FAQ
&lt;/h2&gt;

&lt;h3&gt;
  
  
  Is an AI agent better than Zapier for a small business?
&lt;/h3&gt;

&lt;p&gt;For most tasks, no — Zapier is cheaper, faster and more predictable for fixed "when X, do Y" workflows. An agent wins only when the input is messy and the steps can't be decided in advance, like prospect research or open-ended Q&amp;amp;A.&lt;/p&gt;

&lt;h3&gt;
  
  
  Is n8n cheaper than Zapier?
&lt;/h3&gt;

&lt;p&gt;It depends how the workflow's built. n8n charges per execution regardless of step count, while Zapier charges per successful action (&lt;a href="https://n8n.io/pricing/" rel="noopener noreferrer"&gt;n8n pricing&lt;/a&gt;, &lt;a href="https://zapier.com/pricing" rel="noopener noreferrer"&gt;Zapier pricing&lt;/a&gt;). Long, many-step workflows usually cost less on n8n; simple two-step ones cost about the same, and Zapier takes less setup.&lt;/p&gt;

&lt;h3&gt;
  
  
  Can I add AI to Zapier or n8n without building an agent?
&lt;/h3&gt;

&lt;p&gt;Yes, and it's often the best option: put a single AI step (classify, extract, summarise) inside a normal workflow. The path stays fixed and testable, and you pay for one model call per run.&lt;/p&gt;

&lt;h3&gt;
  
  
  What's the biggest mistake with AI agents?
&lt;/h3&gt;

&lt;p&gt;Giving them write access too early. Start with read-only tools and human approval, cap steps and tokens per run, and log every action before you let an agent send anything on its own.&lt;/p&gt;




&lt;p&gt;&lt;em&gt;Originally published on &lt;a href="https://banxal.com/blog/zapier-n8n-or-ai-agent" rel="noopener noreferrer"&gt;banxal.com&lt;/a&gt;.&lt;/em&gt;&lt;/p&gt;

</description>
      <category>automation</category>
      <category>ai</category>
      <category>nocode</category>
      <category>productivity</category>
    </item>
    <item>
      <title>Hand Off a Lovable or Bolt App to a Developer: Prep Guide</title>
      <dc:creator>Manveer</dc:creator>
      <pubDate>Thu, 01 Oct 2026 21:14:32 +0000</pubDate>
      <link>https://dev.to/manveer-banxal/hand-off-a-lovable-or-bolt-app-to-a-developer-prep-guide-2b9a</link>
      <guid>https://dev.to/manveer-banxal/hand-off-a-lovable-or-bolt-app-to-a-developer-prep-guide-2b9a</guid>
      <description>&lt;p&gt;You built the app in Lovable or Bolt. Now you've found a developer or agency to take it further, and their first message is: "Can you send me access?"&lt;/p&gt;

&lt;p&gt;Before you reply, work out what "access" means. A Lovable or Bolt app lives in several places: the builder, a GitHub repo, a database, a secrets store, a domain, plus payment and email accounts. Hand off a Lovable app to a developer without mapping those, and either they spend their first paid days finding your setup, or you hand over keys you can't take back.&lt;/p&gt;

&lt;p&gt;This guide covers the founder's side: what to export, lock down and write down before a developer opens the repo.&lt;/p&gt;

&lt;h2&gt;
  
  
  TL;DR
&lt;/h2&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;Give access, keep ownership.&lt;/strong&gt; Invite the developer into your GitHub, database and hosting accounts. Don't transfer the accounts themselves unless you're selling the app.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Find your backend first.&lt;/strong&gt; Lovable Cloud, your own Supabase project and Bolt Database each hand off differently. Neither builder offers a one-click way to move off its built-in database.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Secrets don't travel with the code.&lt;/strong&gt; Lovable secrets are write-only and never sync to GitHub. Make a list of every key, share the keys safely and rotate any that have been pasted into chats.&lt;/li&gt;
&lt;/ul&gt;

&lt;h2&gt;
  
  
  Why handoff prep matters
&lt;/h2&gt;

&lt;p&gt;Developers bill for discovery: an hour spent asking "which Supabase project is production?" costs the same as an hour building features.&lt;/p&gt;

&lt;p&gt;There's a security reason too: Lovable's own guidance says "secrets stored in frontend code are visible to users and should be considered compromised" (&lt;a href="https://docs.lovable.dev/tips-tricks/avoiding-security-pitfalls" rel="noopener noreferrer"&gt;Lovable security best practices&lt;/a&gt;) — a key pasted into a prompt, Slack thread or freelancer email counts the same way.&lt;/p&gt;

&lt;h2&gt;
  
  
  What moves automatically vs what you must export
&lt;/h2&gt;

&lt;p&gt;The biggest variable is where your data lives — find out first.&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;Lovable Cloud.&lt;/strong&gt; This is Lovable's built-in backend, "built on Supabase's open-source foundation" (&lt;a href="https://docs.lovable.dev/integrations/cloud" rel="noopener noreferrer"&gt;Lovable Cloud docs&lt;/a&gt;). You manage it inside Lovable. We found no documented way to give an outside developer direct access to the dashboard underneath it.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Your own Supabase project connected to Lovable.&lt;/strong&gt; Lovable says this route gives you "your own Supabase account and billing, full access to the Supabase dashboard" (&lt;a href="https://docs.lovable.dev/integrations/supabase" rel="noopener noreferrer"&gt;Lovable Supabase docs&lt;/a&gt;).&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Bolt Database.&lt;/strong&gt; Bolt "will typically automatically create one as soon as your project needs it" (&lt;a href="https://support.bolt.new/concepts/intro-databases" rel="noopener noreferrer"&gt;Bolt databases intro&lt;/a&gt;). On Pro or Teams plans you can claim it into your own Supabase organisation (&lt;a href="https://support.bolt.new/integrations/supabase" rel="noopener noreferrer"&gt;Bolt Supabase docs&lt;/a&gt;).&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.us-east-2.amazonaws.com%2Fuploads%2Farticles%2Fyy788u36w9xjhtk56mpr.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.us-east-2.amazonaws.com%2Fuploads%2Farticles%2Fyy788u36w9xjhtk56mpr.png" alt="Table comparing what moves automatically vs. what you must export for Lovable Cloud, Lovable with your own Supabase, and Bolt Database" width="800" height="407"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;div class="table-wrapper-paragraph"&gt;&lt;table&gt;
&lt;thead&gt;
&lt;tr&gt;
&lt;th&gt;Item&lt;/th&gt;
&lt;th&gt;Lovable + Lovable Cloud&lt;/th&gt;
&lt;th&gt;Lovable + your own Supabase&lt;/th&gt;
&lt;th&gt;Bolt + Bolt Database&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td&gt;&lt;strong&gt;Code&lt;/strong&gt;&lt;/td&gt;
&lt;td&gt;Two-way GitHub sync, one branch at a time&lt;/td&gt;
&lt;td&gt;Same&lt;/td&gt;
&lt;td&gt;GitHub sync with auto-commits, or ZIP download&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;strong&gt;Database&lt;/strong&gt;&lt;/td&gt;
&lt;td&gt;Export data and storage; no one-click move to your own Supabase&lt;/td&gt;
&lt;td&gt;Already yours; invite the developer to your Supabase org&lt;/td&gt;
&lt;td&gt;Claim into Supabase (Pro/Teams) for direct access&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;strong&gt;Secrets&lt;/strong&gt;&lt;/td&gt;
&lt;td&gt;Write-only, not synced to GitHub&lt;/td&gt;
&lt;td&gt;Lovable secrets plus any Supabase-side keys&lt;/td&gt;
&lt;td&gt;In Bolt's Secrets panel; unclear if included in exports&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;strong&gt;Custom domain&lt;/strong&gt;&lt;/td&gt;
&lt;td&gt;Via Lovable: belongs to the workspace. External: A + TXT at your registrar&lt;/td&gt;
&lt;td&gt;Same&lt;/td&gt;
&lt;td&gt;Check where you bought it&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;strong&gt;Stripe, email, analytics&lt;/strong&gt;&lt;/td&gt;
&lt;td&gt;Never moves; lives in your own accounts&lt;/td&gt;
&lt;td&gt;Same&lt;/td&gt;
&lt;td&gt;Same&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;&lt;/div&gt;

&lt;p&gt;Lovable states "there is no one-click migration from the built-in backend (Cloud) to Supabase or the other way" (&lt;a href="https://docs.lovable.dev/integrations/supabase" rel="noopener noreferrer"&gt;Lovable Supabase docs&lt;/a&gt;), and Cloud's region can't be changed once enabled (&lt;a href="https://docs.lovable.dev/integrations/cloud" rel="noopener noreferrer"&gt;Lovable Cloud docs&lt;/a&gt;). Treat a move to your own Supabase as a scoped migration, not a settings change.&lt;/p&gt;

&lt;h2&gt;
  
  
  The pre-handoff checklist: access, code, data, docs
&lt;/h2&gt;

&lt;p&gt;Work through this in one sitting; most of it takes a couple of hours and needs no technical skill.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.us-east-2.amazonaws.com%2Fuploads%2Farticles%2Fe3thlmi1d05jt96yavw4.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.us-east-2.amazonaws.com%2Fuploads%2Farticles%2Fe3thlmi1d05jt96yavw4.png" alt="Pre-handoff checklist in four columns: Access, Code, Data, and Docs" width="799" height="373"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;h3&gt;
  
  
  Access
&lt;/h3&gt;

&lt;ul&gt;
&lt;li&gt;[ ] Write down every account the app touches: builder, GitHub, database, hosting, domain registrar, DNS, Stripe, email provider, analytics and any AI API. Note the login email and who pays for each one.&lt;/li&gt;
&lt;li&gt;[ ] Turn on two-factor authentication for every account you own.&lt;/li&gt;
&lt;li&gt;[ ] Invite the developer as a &lt;strong&gt;member or collaborator&lt;/strong&gt;, not an owner. Supabase project transfers require you to be the source org's owner and can lower people's roles (&lt;a href="https://supabase.com/docs/guides/platform/project-transfer" rel="noopener noreferrer"&gt;Supabase project transfer&lt;/a&gt;). Keep the project in your org and add the developer to it.&lt;/li&gt;
&lt;li&gt;[ ] Choose a safe channel for sharing keys, such as a password manager's shared vault. Don't use email, and don't use a chat app that keeps history forever.&lt;/li&gt;
&lt;/ul&gt;

&lt;h3&gt;
  
  
  Code
&lt;/h3&gt;

&lt;ul&gt;
&lt;li&gt;[ ] Connect GitHub if you haven't, and make sure the repo is in an account or organisation &lt;strong&gt;you&lt;/strong&gt; control.&lt;/li&gt;
&lt;li&gt;[ ] Confirm which branch the builder syncs to. Lovable "only edits and syncs one branch at a time" (&lt;a href="https://docs.lovable.dev/integrations/github" rel="noopener noreferrer"&gt;Lovable GitHub docs&lt;/a&gt;).&lt;/li&gt;
&lt;li&gt;[ ] Download a ZIP snapshot of the code today and keep it outside the builder.&lt;/li&gt;
&lt;/ul&gt;

&lt;h3&gt;
  
  
  Data
&lt;/h3&gt;

&lt;ul&gt;
&lt;li&gt;[ ] Take a backup before anyone touches anything. On a Supabase project you control, the CLI can dump roles, schema and data as separate files:
&lt;/li&gt;
&lt;/ul&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;supabase db dump &lt;span class="nt"&gt;--db-url&lt;/span&gt; &lt;span class="s2"&gt;"&lt;/span&gt;&lt;span class="nv"&gt;$DB_URL&lt;/span&gt;&lt;span class="s2"&gt;"&lt;/span&gt; &lt;span class="nt"&gt;-f&lt;/span&gt; roles.sql &lt;span class="nt"&gt;--role-only&lt;/span&gt;
supabase db dump &lt;span class="nt"&gt;--db-url&lt;/span&gt; &lt;span class="s2"&gt;"&lt;/span&gt;&lt;span class="nv"&gt;$DB_URL&lt;/span&gt;&lt;span class="s2"&gt;"&lt;/span&gt; &lt;span class="nt"&gt;-f&lt;/span&gt; schema.sql
supabase db dump &lt;span class="nt"&gt;--db-url&lt;/span&gt; &lt;span class="s2"&gt;"&lt;/span&gt;&lt;span class="nv"&gt;$DB_URL&lt;/span&gt;&lt;span class="s2"&gt;"&lt;/span&gt; &lt;span class="nt"&gt;-f&lt;/span&gt; data.sql &lt;span class="nt"&gt;--use-copy&lt;/span&gt; &lt;span class="nt"&gt;--data-only&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;(&lt;a href="https://supabase.com/docs/guides/platform/migrating-within-supabase/backup-restore" rel="noopener noreferrer"&gt;Supabase backup and restore&lt;/a&gt;. The full data command in the docs also excludes two storage tables. Copy it from there.) On Lovable Cloud, use the export option the Cloud docs describe for the database and storage files.&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;[ ] List which tables hold personal or payment data.&lt;/li&gt;
&lt;/ul&gt;

&lt;h3&gt;
  
  
  Docs
&lt;/h3&gt;

&lt;ul&gt;
&lt;li&gt;[ ] Write a one-page "how it works": who the users are, the three most important flows (signup, the core action, payment), and what's broken.&lt;/li&gt;
&lt;li&gt;[ ] List every integration and which secret it uses, without writing the secret values in the doc.&lt;/li&gt;
&lt;li&gt;[ ] Note anything you set up outside the builder, such as Stripe webhooks, DNS records or cron jobs.&lt;/li&gt;
&lt;/ul&gt;

&lt;h2&gt;
  
  
  How to hand off a Lovable app to a developer: Lovable-specific steps
&lt;/h2&gt;

&lt;p&gt;&lt;strong&gt;Decide between collaborator access and moving the project.&lt;/strong&gt; You can share the project, move it to another workspace, or transfer ownership; the new owner needs the owner, admin or editor role (&lt;a href="https://docs.lovable.dev/features/projects/settings" rel="noopener noreferrer"&gt;Lovable project settings&lt;/a&gt;). For a normal engagement, share access and keep ownership.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Be careful moving workspaces once GitHub is connected.&lt;/strong&gt; Moving the project to another workspace breaks the GitHub connection, and reconnecting creates a &lt;em&gt;new&lt;/em&gt; repository; disconnecting works the same way (&lt;a href="https://docs.lovable.dev/integrations/github" rel="noopener noreferrer"&gt;Lovable GitHub docs&lt;/a&gt;). Moving the repo itself is safer: sync continues "when your Lovable workspace also has a GitHub connection for the new owner," and GitHub keeps issues and collaborators and redirects the old URL (&lt;a href="https://docs.github.com/en/repositories/creating-and-managing-repositories/transferring-a-repository" rel="noopener noreferrer"&gt;GitHub: transferring a repository&lt;/a&gt;).&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Agree who edits where.&lt;/strong&gt; Pushes to the active branch flow back into Lovable, so don't prompt on that same branch while the developer is working.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Rebuild your secrets inventory by hand.&lt;/strong&gt; Lovable secrets "are write-only: after you save a secret, its value can never be viewed again in Lovable, only replaced or deleted," and they don't sync to GitHub (&lt;a href="https://docs.lovable.dev/features/secrets" rel="noopener noreferrer"&gt;Lovable Secrets docs&lt;/a&gt;). If the original key isn't saved anywhere, generate a new one from the provider. The &lt;code&gt;.env&lt;/code&gt; file is different: Lovable commits it so build-time &lt;code&gt;VITE_*&lt;/code&gt; values are available, so it must hold only public values.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Check your domain.&lt;/strong&gt; Domains bought through Lovable "belong to your workspace, not to a single project," and transferring one out is irreversible from Lovable's side (&lt;a href="https://docs.lovable.dev/features/custom-domain" rel="noopener noreferrer"&gt;Lovable custom domain docs&lt;/a&gt;). An outside domain just needs an A record and a &lt;code&gt;_lovable&lt;/code&gt; TXT record at your registrar — make sure you, not a past freelancer, can log in there.&lt;/p&gt;

&lt;h2&gt;
  
  
  Bolt app developer handover: Bolt-specific steps
&lt;/h2&gt;

&lt;p&gt;&lt;strong&gt;Export to GitHub.&lt;/strong&gt; Bolt's GitHub integration creates a commit "every time you make a change that doesn't break the project," and "checks GitHub every 30 seconds for any updates made outside Bolt" (&lt;a href="https://support.bolt.new/integrations/git" rel="noopener noreferrer"&gt;Bolt GitHub docs&lt;/a&gt;). Only the project owner can manage it, and disconnecting is permanent — "you can't manually reconnect it" — so don't disconnect to "clean things up" before a handoff.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Keep a ZIP as well.&lt;/strong&gt; Use Export &amp;gt; Download from the project title menu (&lt;a href="https://support.bolt.new/building/using-bolt/projects-files" rel="noopener noreferrer"&gt;Bolt projects docs&lt;/a&gt;) for a dated snapshot you control.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Don't transfer to a user unless you mean it.&lt;/strong&gt; Bolt lets you transfer a project to another user, but "after the recipient accepts the transfer, you won't be able to access the project or make any further edits" (same page) — that fits a sale, not hiring a contractor.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Handle the database before you change anything.&lt;/strong&gt; To get the developer into a real Supabase dashboard, &lt;em&gt;claim&lt;/em&gt; the Bolt database into your Supabase organisation (requires a Pro or Teams plan and Supabase org owner). Don't connect a new Supabase project instead: Bolt warns that doing so "will replace the connection, which may cause data loss" (&lt;a href="https://support.bolt.new/integrations/supabase" rel="noopener noreferrer"&gt;Bolt Supabase docs&lt;/a&gt;).&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Treat secrets as unknown until checked.&lt;/strong&gt; Bolt's Secrets panel keeps values out of users' browsers (&lt;a href="https://support.bolt.new/cloud/database/secrets" rel="noopener noreferrer"&gt;Bolt secrets docs&lt;/a&gt;), but Bolt's docs don't say whether secrets or &lt;code&gt;.env&lt;/code&gt; files end up in GitHub syncs or ZIP downloads. Open both and check — rotate any private key you find.&lt;/p&gt;

&lt;h2&gt;
  
  
  What a developer checks in the first hour
&lt;/h2&gt;

&lt;p&gt;A good developer runs roughly these checks first — here's what each finding means.&lt;/p&gt;

&lt;div class="table-wrapper-paragraph"&gt;&lt;table&gt;
&lt;thead&gt;
&lt;tr&gt;
&lt;th&gt;First-hour check&lt;/th&gt;
&lt;th&gt;Good sign&lt;/th&gt;
&lt;th&gt;Bad sign and what it means&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td&gt;Clone and run the repo locally?&lt;/td&gt;
&lt;td&gt;Runs from the README&lt;/td&gt;
&lt;td&gt;Fails: expect setup cost before feature work&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Secret keys in the browser bundle&lt;/td&gt;
&lt;td&gt;Only publishable keys&lt;/td&gt;
&lt;td&gt;A Supabase secret or &lt;code&gt;service_role&lt;/code&gt; key: rotate it today — secret keys "bypass Row Level Security" (&lt;a href="https://supabase.com/docs/guides/api/api-keys" rel="noopener noreferrer"&gt;Supabase API keys&lt;/a&gt;)&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Row Level Security on user tables&lt;/td&gt;
&lt;td&gt;On, with policies per table&lt;/td&gt;
&lt;td&gt;Off: any logged-in user may read others' data&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Which environment is production?&lt;/td&gt;
&lt;td&gt;One clear prod project&lt;/td&gt;
&lt;td&gt;Several near-identical projects to untangle&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Payment webhooks&lt;/td&gt;
&lt;td&gt;Signed, handled server-side&lt;/td&gt;
&lt;td&gt;Missing: payments can succeed without the app knowing&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;&lt;/div&gt;

&lt;p&gt;If they find a leaked key, follow Supabase's order: "Fix the root cause of the leak before you rotate anything," then create the new key, update everywhere, and retire the old one (&lt;a href="https://supabase.com/docs/guides/api/api-keys" rel="noopener noreferrer"&gt;Supabase API keys&lt;/a&gt;) — rotating first just leaks the new key too.&lt;/p&gt;

&lt;h2&gt;
  
  
  Handoff or rebuild?
&lt;/h2&gt;

&lt;p&gt;Most apps that reach a handoff need fixing, not replacing. The deciding question is the data model, not the code: if your database still describes how your business works, a developer can harden what you have; if it doesn't, every fix fights the structure underneath. Run that test — &lt;a href="https://banxal.com/blog/fix-or-rebuild-vibe-coded-app" rel="noopener noreferrer"&gt;Fix or Rebuild Your Vibe-Coded App? A 30-Minute Self-Test&lt;/a&gt; — before the handoff.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.us-east-2.amazonaws.com%2Fuploads%2Farticles%2Foogvx12d2izwd0gy061z.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.us-east-2.amazonaws.com%2Fuploads%2Farticles%2Foogvx12d2izwd0gy061z.png" alt="Decision flowchart for choosing handoff, rebuild, or security fixes based on repo control, data model fit, and exposed secrets" width="799" height="433"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;h2&gt;
  
  
  FAQ
&lt;/h2&gt;

&lt;p&gt;&lt;strong&gt;Can I export a Lovable app to GitHub and keep building in Lovable?&lt;/strong&gt;&lt;br&gt;
Yes. The sync is two-way on one active branch. Lovable can export to a new repo but can't import an existing one (&lt;a href="https://docs.lovable.dev/integrations/github" rel="noopener noreferrer"&gt;Lovable GitHub docs&lt;/a&gt;).&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Should I give my developer my Lovable or Bolt login?&lt;/strong&gt;&lt;br&gt;
No. Invite them under their own accounts to the project, GitHub and Supabase — shared logins make it impossible to later remove just one person's access.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Do I need to move off Lovable Cloud before a handoff?&lt;/strong&gt;&lt;br&gt;
Not necessarily — only if the developer needs direct database access. It's a manual job, though: export the data, connect a Supabase project and rebuild the schema (&lt;a href="https://docs.lovable.dev/integrations/cloud" rel="noopener noreferrer"&gt;Lovable Cloud docs&lt;/a&gt;).&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;When should I rotate secrets?&lt;/strong&gt;&lt;br&gt;
Rotate any key pasted into a chat, email or prompt before the handoff, and rotate every key the developer had when the engagement ends.&lt;/p&gt;

&lt;h2&gt;
  
  
  Next step
&lt;/h2&gt;

&lt;p&gt;Want a second opinion before committing budget? Banxal's &lt;a href="https://banxal.com/services" rel="noopener noreferrer"&gt;development services&lt;/a&gt; include a handoff review: we go through your repo, backend and secrets and tell you plainly whether it needs fixing, hardening or a partial rebuild. &lt;a href="https://banxal.com/contact" rel="noopener noreferrer"&gt;Get in touch&lt;/a&gt; and tell us what you've built.&lt;/p&gt;




&lt;p&gt;&lt;em&gt;Originally published on &lt;a href="https://banxal.com/blog/handoff-lovable-bolt-app-to-developer" rel="noopener noreferrer"&gt;banxal.com&lt;/a&gt;.&lt;/em&gt;&lt;/p&gt;

</description>
      <category>webdev</category>
      <category>supabase</category>
      <category>github</category>
      <category>ai</category>
    </item>
    <item>
      <title>Fix or Rebuild Your Vibe-Coded App? A 30-Minute Self-Test</title>
      <dc:creator>Manveer</dc:creator>
      <pubDate>Thu, 01 Oct 2026 19:57:39 +0000</pubDate>
      <link>https://dev.to/manveer-banxal/fix-or-rebuild-your-vibe-coded-app-a-30-minute-self-test-5ei1</link>
      <guid>https://dev.to/manveer-banxal/fix-or-rebuild-your-vibe-coded-app-a-30-minute-self-test-5ei1</guid>
      <description>&lt;p&gt;Your Lovable, Bolt or Cursor prototype has real users. It also breaks every week, and you're about to pay someone to sort it out. Before you do, you need to know whether to fix or rebuild your vibe-coded app, because the answer decides whether you're buying a few days of work or a few months.&lt;/p&gt;

&lt;p&gt;Most guides end with "book an audit". This one gives you the audit's first pass free: eight checks, about 30 minutes, no developer needed, ending in a verdict.&lt;/p&gt;

&lt;h2&gt;
  
  
  TL;DR
&lt;/h2&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;Most vibe-coded apps need fixing, not rebuilding.&lt;/strong&gt; The usual problems are exposed secrets, missing database access rules and fragile payment handling. Each of those can be fixed on its own.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Your data model decides whether you rebuild.&lt;/strong&gt; If your database can't describe how your business works today, patching the screens won't help.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Run the 8 checks below on your own app.&lt;/strong&gt; Score them, read off your verdict, and give the results to whoever you hire so you aren't paying them to discover what you already know.&lt;/li&gt;
&lt;/ul&gt;

&lt;h2&gt;
  
  
  Why vibe-coded apps work in the demo and break with users
&lt;/h2&gt;

&lt;p&gt;AI builders are good at getting a screen to show the right thing. Production needs more than that. Strangers have to be kept out of each other's data. Payments have to keep working when someone closes the tab mid-checkout. A table with 50,000 rows has to load as fast as it did with five.&lt;/p&gt;

&lt;p&gt;Security research shows how big the gap is. Veracode tested code from over 100 large language models and found that &lt;strong&gt;AI-generated code introduced risky security flaws in 45% of tests&lt;/strong&gt; (&lt;a href="https://www.veracode.com/resources/analyst-reports/2025-genai-code-security-report/" rel="noopener noreferrer"&gt;Veracode GenAI Code Security Report&lt;/a&gt;). The best-known example is CVE-2025-48757. A researcher scanned 1,645 Lovable-built apps and found &lt;strong&gt;170 (10.3%) with exposed databases&lt;/strong&gt; across 303 vulnerable endpoints. The leaked data included emails, phone numbers, payment status and API keys (&lt;a href="https://bleek.dev/cve-2025-48757" rel="noopener noreferrer"&gt;bleek.dev&lt;/a&gt;, &lt;a href="https://www.superblocks.com/blog/lovable-vulnerabilities" rel="noopener noreferrer"&gt;Superblocks&lt;/a&gt;). The cause was missing or weak Row Level Security, which is check 2 below.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.us-east-2.amazonaws.com%2Fuploads%2Farticles%2Fplly3yt79pnhzw9vhmg8.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.us-east-2.amazonaws.com%2Fuploads%2Farticles%2Fplly3yt79pnhzw9vhmg8.png" alt="Three stats on AI-built app security: 170 of 1,645 scanned Lovable apps (10.3%) had exposed databases across 303 vulnerable endpoints under CVE-2025-48757, and Veracode found AI-generated code introduced a risky security flaw in 45% of tests across 100+ LLMs." width="800" height="320"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;None of this means your app is doomed. The demo proved demand. The invisible parts just haven't been built yet, and the checks below tell you how many of them are missing.&lt;/p&gt;

&lt;h2&gt;
  
  
  The 30-minute self-test: 8 checks
&lt;/h2&gt;

&lt;p&gt;Run these &lt;strong&gt;only on an app you own or are authorised to test.&lt;/strong&gt; Most checks just need your browser and your admin dashboards. Score each one &lt;strong&gt;Pass (0)&lt;/strong&gt;, &lt;strong&gt;Warn (1)&lt;/strong&gt; or &lt;strong&gt;Fail (2)&lt;/strong&gt;.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.us-east-2.amazonaws.com%2Fuploads%2Farticles%2Ffe8naqptj48pb59y3rjn.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.us-east-2.amazonaws.com%2Fuploads%2Farticles%2Ffe8naqptj48pb59y3rjn.png" alt="Checklist of the 8 self-test checks with time needed and what a Fail means: secret keys in the browser bundle (4 min), Row Level Security (5 min), auth and session handling (4 min), payment webhooks (5 min), data model sanity (5 min), error monitoring (2 min), page load with realistic data (3 min), and code in version control you own (2 min)." width="800" height="467"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;h3&gt;
  
  
  1. Secret keys in the browser bundle (4 min)
&lt;/h3&gt;

&lt;p&gt;Anything your app sends to the browser can be read by anyone who visits it.&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;Open your live app in Chrome. Press F12 to open DevTools, then go to the &lt;strong&gt;Sources&lt;/strong&gt; tab.&lt;/li&gt;
&lt;li&gt;Press Ctrl+Shift+F (Cmd+Option+F on Mac) to search across all files.&lt;/li&gt;
&lt;li&gt;Search for &lt;code&gt;sk_live&lt;/code&gt;, &lt;code&gt;sk_test&lt;/code&gt;, &lt;code&gt;rk_live&lt;/code&gt;, &lt;code&gt;sb_secret_&lt;/code&gt;, &lt;code&gt;service_role&lt;/code&gt; and &lt;code&gt;secret&lt;/code&gt;.&lt;/li&gt;
&lt;li&gt;Open your Supabase project's API keys page. Copy the first 20 or so characters of the &lt;strong&gt;secret / service_role&lt;/strong&gt; key and search for those too. Legacy Supabase keys are encoded, so the word "service_role" may not appear in plain text.&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;&lt;strong&gt;Pass:&lt;/strong&gt; you only find publishable keys (&lt;code&gt;pk_live_&lt;/code&gt;, &lt;code&gt;sb_publishable_&lt;/code&gt;, the anon key). Stripe and Supabase both say these are safe to expose (&lt;a href="https://docs.stripe.com/keys" rel="noopener noreferrer"&gt;Stripe&lt;/a&gt;, &lt;a href="https://supabase.com/docs/guides/api/api-keys" rel="noopener noreferrer"&gt;Supabase&lt;/a&gt;).&lt;br&gt;
&lt;strong&gt;Fail:&lt;/strong&gt; any secret, restricted or service key shows up. Rotate it today, before anything else.&lt;/p&gt;

&lt;h3&gt;
  
  
  2. Row Level Security (5 min)
&lt;/h3&gt;

&lt;p&gt;Supabase's own docs are blunt: a table without RLS "is readable and writable by any role with a grant on it" (&lt;a href="https://supabase.com/docs/guides/database/postgres/row-level-security" rel="noopener noreferrer"&gt;Supabase RLS&lt;/a&gt;).&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;In the Supabase dashboard, open &lt;strong&gt;Advisors → Security Advisor&lt;/strong&gt;. Look for errors like &lt;em&gt;RLS Disabled in Public&lt;/em&gt; or &lt;em&gt;Sensitive Columns Exposed&lt;/em&gt; (&lt;a href="https://supabase.com/docs/guides/database/database-advisors" rel="noopener noreferrer"&gt;Supabase Advisors&lt;/a&gt;).&lt;/li&gt;
&lt;li&gt;Run the two-account test. Sign up as User A and create a record (an invoice, a project, a message) and copy its URL. Then sign in as User B in a private window and open that URL.&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;&lt;strong&gt;Pass:&lt;/strong&gt; the advisor is clean and User B sees nothing.&lt;br&gt;
&lt;strong&gt;Warn:&lt;/strong&gt; the advisor shows warnings, but the two-account test holds.&lt;br&gt;
&lt;strong&gt;Fail:&lt;/strong&gt; any RLS error, or User B can see A's data. One catch: Lovable's built-in scanner only checks &lt;em&gt;whether&lt;/em&gt; a policy exists, not whether it actually blocks access (&lt;a href="https://www.superblocks.com/blog/lovable-vulnerabilities" rel="noopener noreferrer"&gt;Superblocks&lt;/a&gt;). The two-account test is what proves it works.&lt;/p&gt;

&lt;h3&gt;
  
  
  3. Auth and session handling (4 min)
&lt;/h3&gt;

&lt;ul&gt;
&lt;li&gt;Log out, press Back, then reload a private page. Do you still see data?&lt;/li&gt;
&lt;li&gt;Signed in as a normal user, type &lt;code&gt;/admin&lt;/code&gt; (or whatever your admin route is) straight into the address bar.&lt;/li&gt;
&lt;li&gt;Run a password reset from start to finish. Does the email arrive, and does the link expire after you've used it?&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;&lt;strong&gt;Pass:&lt;/strong&gt; all three behave. &lt;strong&gt;Warn:&lt;/strong&gt; the reset flow is flaky. &lt;strong&gt;Fail:&lt;/strong&gt; a normal user can reach admin pages, or a logged-out session still shows data.&lt;/p&gt;

&lt;h3&gt;
  
  
  4. Payment webhooks (5 min)
&lt;/h3&gt;

&lt;p&gt;A webhook is the message Stripe sends to your app's server when a payment succeeds or a subscription changes. Many prototypes skip it and unlock paid features when the browser lands on the "success" page, which breaks the moment someone closes the tab.&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;In Stripe, open &lt;strong&gt;Workbench → Webhooks&lt;/strong&gt;. Is an endpoint registered at all? Open &lt;strong&gt;Event deliveries&lt;/strong&gt; and look for anything marked &lt;em&gt;Failed&lt;/em&gt; or &lt;em&gt;Pending&lt;/em&gt; (&lt;a href="https://docs.stripe.com/webhooks" rel="noopener noreferrer"&gt;Stripe webhooks&lt;/a&gt;).&lt;/li&gt;
&lt;li&gt;In a sandbox, start a checkout, pay with a test card and close the tab before the redirect finishes. Does the account still upgrade?&lt;/li&gt;
&lt;li&gt;Cancel that test subscription from the Stripe dashboard. Does the app take away access?&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;&lt;strong&gt;Pass:&lt;/strong&gt; an endpoint exists, deliveries succeed and both tests behave. &lt;strong&gt;Fail:&lt;/strong&gt; there's no endpoint, deliveries are failing, or access doesn't follow what Stripe says.&lt;/p&gt;

&lt;h3&gt;
  
  
  5. Data model sanity (5 min)
&lt;/h3&gt;

&lt;p&gt;This is the check that decides fix versus rebuild. Open Supabase's &lt;strong&gt;Table Editor&lt;/strong&gt; and look for:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Tables named after screens (&lt;code&gt;dashboard_data&lt;/code&gt;, &lt;code&gt;page_two&lt;/code&gt;) instead of things in your business (&lt;code&gt;customers&lt;/code&gt;, &lt;code&gt;orders&lt;/code&gt;).&lt;/li&gt;
&lt;li&gt;The same fact stored in several places, like a customer's email in four tables.&lt;/li&gt;
&lt;li&gt;Lists crammed into one text or JSON column.&lt;/li&gt;
&lt;li&gt;User-owned tables with no column saying who owns each row.&lt;/li&gt;
&lt;li&gt;Something your business does now that the schema can't represent, such as teams, multiple locations or more than one price per product.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;&lt;strong&gt;Pass:&lt;/strong&gt; none of these. &lt;strong&gt;Warn:&lt;/strong&gt; one or two, and they're contained. &lt;strong&gt;Fail:&lt;/strong&gt; the last bullet is true, or most of the others are.&lt;/p&gt;

&lt;h3&gt;
  
  
  6. Error monitoring (2 min)
&lt;/h3&gt;

&lt;p&gt;Who finds out first when something breaks, you or your users? In DevTools, search the &lt;strong&gt;Network&lt;/strong&gt; tab for &lt;code&gt;sentry&lt;/code&gt;, &lt;code&gt;logrocket&lt;/code&gt; or &lt;code&gt;bugsnag&lt;/code&gt;, then check whether you've ever actually received an alert.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Pass:&lt;/strong&gt; errors reach you automatically. &lt;strong&gt;Fail:&lt;/strong&gt; your users are your monitoring.&lt;/p&gt;

&lt;h3&gt;
  
  
  7. Page load with realistic data (3 min)
&lt;/h3&gt;

&lt;p&gt;Fill a test account with the amount of data your heaviest customer has. In DevTools, set &lt;strong&gt;Network&lt;/strong&gt; throttling to &lt;em&gt;Slow 4G&lt;/em&gt; and load your busiest page.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Pass:&lt;/strong&gt; the main content appears within about 2.5 seconds. Google's web.dev counts Largest Contentful Paint at 2.5s or less as "good" and over 4s as "poor" (&lt;a href="https://web.dev/articles/lcp" rel="noopener noreferrer"&gt;web.dev&lt;/a&gt;). &lt;strong&gt;Warn:&lt;/strong&gt; 2.5 to 4 seconds. &lt;strong&gt;Fail:&lt;/strong&gt; over 4 seconds, or the Network tab shows the page downloading an entire table at once.&lt;/p&gt;

&lt;h3&gt;
  
  
  8. Code in version control you own (2 min)
&lt;/h3&gt;

&lt;p&gt;Is your code in a GitHub repository under &lt;em&gt;your&lt;/em&gt; account or organisation? Lovable can create a private repo on your GitHub with two-way sync (&lt;a href="https://docs.lovable.dev/integrations/github" rel="noopener noreferrer"&gt;Lovable docs&lt;/a&gt;). Bolt and Cursor projects should be in a repo too.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Pass:&lt;/strong&gt; you own the repo and can see a history of changes. &lt;strong&gt;Warn:&lt;/strong&gt; a repo exists but sits in a freelancer's account. &lt;strong&gt;Fail:&lt;/strong&gt; the code only lives inside the builder or on one person's laptop.&lt;/p&gt;

&lt;h2&gt;
  
  
  Scoring: ship, fix, refactor or rebuild
&lt;/h2&gt;

&lt;p&gt;Add up your points (maximum 16). These thresholds are our rule of thumb from how these problems usually group together. They aren't an industry standard.&lt;/p&gt;

&lt;div class="table-wrapper-paragraph"&gt;&lt;table&gt;
&lt;thead&gt;
&lt;tr&gt;
&lt;th&gt;Score&lt;/th&gt;
&lt;th&gt;Also true&lt;/th&gt;
&lt;th&gt;Verdict&lt;/th&gt;
&lt;th&gt;What it means&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td&gt;0–2&lt;/td&gt;
&lt;td&gt;No Fail on checks 1–4&lt;/td&gt;
&lt;td&gt;&lt;strong&gt;Ship&lt;/strong&gt;&lt;/td&gt;
&lt;td&gt;Keep building. Add monitoring if you don't have it.&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;3–7&lt;/td&gt;
&lt;td&gt;—&lt;/td&gt;
&lt;td&gt;&lt;strong&gt;Fix&lt;/strong&gt;&lt;/td&gt;
&lt;td&gt;Targeted repairs. Security fails (checks 1–2) go first, this week.&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;8–16&lt;/td&gt;
&lt;td&gt;Check 5 is Pass or Warn&lt;/td&gt;
&lt;td&gt;&lt;strong&gt;Refactor&lt;/strong&gt;&lt;/td&gt;
&lt;td&gt;Keep the product and the data, but restructure the code in stages.&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;8–16&lt;/td&gt;
&lt;td&gt;Check 5 is Fail&lt;/td&gt;
&lt;td&gt;&lt;strong&gt;Rebuild&lt;/strong&gt;&lt;/td&gt;
&lt;td&gt;The foundation can't hold your business. Plan a staged rebuild.&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;&lt;/div&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.us-east-2.amazonaws.com%2Fuploads%2Farticles%2Fwd934a69tgi0xo1al3ed.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.us-east-2.amazonaws.com%2Fuploads%2Farticles%2Fwd934a69tgi0xo1al3ed.png" alt="Scoring table: 0–2 points with no Fail on checks 1–4 is Ship; 3–7 points is Fix; 8–16 points with check 5 Pass or Warn is Refactor; 8–16 points with check 5 Fail is Rebuild." width="800" height="387"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;A low score with a Fail on check 1 or 2 still means &lt;strong&gt;act today&lt;/strong&gt;. Rotate the key or turn on RLS, then carry on.&lt;/p&gt;

&lt;h2&gt;
  
  
  When rebuild is actually right (and when it's a sales pitch)
&lt;/h2&gt;

&lt;p&gt;Most of the top guides agree, and so do we: the data model is the real test. Axonbuild argues that rebuilding is only justified when your data model "cannot express what the business now does" (&lt;a href="https://axonbuild.com/blog/cleanup-or-rebuild" rel="noopener noreferrer"&gt;Axonbuild&lt;/a&gt;). Appmatic puts it as refactor if the data model is sound, rebuild if the architecture can't support the roadmap (&lt;a href="https://appmatictech.com/insights/vibe-coded-app-messy-code-what-next/" rel="noopener noreferrer"&gt;Appmatic&lt;/a&gt;).&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Rebuild is right when:&lt;/strong&gt;&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Check 5 fails and your next three features all need the schema changed.&lt;/li&gt;
&lt;li&gt;Every small change breaks something unrelated, and that's been true for months.&lt;/li&gt;
&lt;li&gt;You can't get the code out of the platform at all.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;&lt;strong&gt;It's probably a sales pitch when:&lt;/strong&gt;&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Someone quotes a rebuild without reading your code or schema.&lt;/li&gt;
&lt;li&gt;The reasons are about taste ("the code is messy", "we'd use a different framework"). Messy code that works is a refactor job.&lt;/li&gt;
&lt;li&gt;Exposed keys or missing RLS are given as the reason. Those are fixes, usually small ones.&lt;/li&gt;
&lt;/ul&gt;

&lt;h2&gt;
  
  
  What to hand a developer
&lt;/h2&gt;

&lt;p&gt;To hand off a Lovable app to a developer (or a Bolt or Cursor one) without paying for discovery twice, send:&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;Your self-test scores, with screenshots of anything that failed.&lt;/li&gt;
&lt;li&gt;Admin or collaborator access to the GitHub repo, Supabase, Stripe, hosting and your domain registrar. Use invites, never shared passwords.&lt;/li&gt;
&lt;li&gt;A list of what's breaking, from user reports, with dates.&lt;/li&gt;
&lt;li&gt;The next three features you need, so they can judge whether the data model will cope.&lt;/li&gt;
&lt;li&gt;Your user and data numbers: active users, the biggest account, the largest tables.&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;If you'd rather not assemble this yourself, Banxal's &lt;a href="https://banxal.com/services" rel="noopener noreferrer"&gt;maintenance and growth work&lt;/a&gt; starts with the same handover review before anything else is touched.&lt;/p&gt;

&lt;h2&gt;
  
  
  Fix or rebuild a vibe-coded app: what each option involves
&lt;/h2&gt;

&lt;p&gt;Fixing, refactoring and rebuilding a vibe-coded app differ in what changes, what you keep, and what it costs. Cost ranges below are other agencies' published figures, not ours, and your app may differ.&lt;/p&gt;

&lt;div class="table-wrapper-paragraph"&gt;&lt;table&gt;
&lt;thead&gt;
&lt;tr&gt;
&lt;th&gt;&lt;/th&gt;
&lt;th&gt;Fix&lt;/th&gt;
&lt;th&gt;Refactor&lt;/th&gt;
&lt;th&gt;Rebuild&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td&gt;What changes&lt;/td&gt;
&lt;td&gt;Specific broken items&lt;/td&gt;
&lt;td&gt;Code structure, tests, deployment&lt;/td&gt;
&lt;td&gt;Code and usually the data model&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;What you keep&lt;/td&gt;
&lt;td&gt;Everything&lt;/td&gt;
&lt;td&gt;Product, data, most UI&lt;/td&gt;
&lt;td&gt;Product knowledge, users, migrated data&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Risk&lt;/td&gt;
&lt;td&gt;Low&lt;/td&gt;
&lt;td&gt;Medium&lt;/td&gt;
&lt;td&gt;High: data migration and two systems running side by side&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Published ranges&lt;/td&gt;
&lt;td&gt;Axonbuild: 6–12 hour repairs at $240–$960 each&lt;/td&gt;
&lt;td&gt;Appmatic: 4–10 weeks, $15,000–$40,000&lt;/td&gt;
&lt;td&gt;Appmatic: 8+ weeks, $40,000+&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;&lt;/div&gt;

&lt;p&gt;Axonbuild's advice on the cost to fix a vibe-coded app is simple arithmetic: count your blocking problems, multiply by the cost per repair, and compare that with a rebuild quote (&lt;a href="https://axonbuild.com/blog/cleanup-or-rebuild" rel="noopener noreferrer"&gt;Axonbuild&lt;/a&gt;). Appmatic lists a separate code audit at 1–2 weeks from $2,500 (&lt;a href="https://appmatictech.com/insights/vibe-coded-app-messy-code-what-next/" rel="noopener noreferrer"&gt;Appmatic&lt;/a&gt;).&lt;/p&gt;

&lt;h2&gt;
  
  
  FAQ
&lt;/h2&gt;

&lt;p&gt;&lt;strong&gt;Is my Lovable app production ready if the Security Advisor is clean?&lt;/strong&gt;&lt;br&gt;
Not on that alone. The advisor finds missing RLS, but it can't tell you whether your policies match your business rules. Run the two-account test, and check payments and auth as well.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Can I run an AI-built app security check myself?&lt;/strong&gt;&lt;br&gt;
You can do the first pass. Checks 1–4 above catch the issues behind the best-known incidents. A developer still needs to review webhook signature checks and server-side logic, because that can't be seen from the browser.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;How long does it take to fix a vibe-coded app?&lt;/strong&gt;&lt;br&gt;
Isolated issues such as a leaked key or a missing policy often take hours. The published ranges above put a fuller hardening at weeks. Your score is a better guide than any average.&lt;/p&gt;

&lt;h2&gt;
  
  
  Next step
&lt;/h2&gt;

&lt;p&gt;If your score says fix or refactor, the next step is a code review and handover conversation. Bring your self-test results. &lt;a href="https://banxal.com/about" rel="noopener noreferrer"&gt;Banxal&lt;/a&gt; builds and hardens web apps and SaaS products, and can look after them afterwards through ongoing maintenance. We'll tell you plainly if a rebuild isn't needed. &lt;a href="https://banxal.com/contact" rel="noopener noreferrer"&gt;Talk to us about your app&lt;/a&gt;.&lt;/p&gt;




&lt;p&gt;&lt;em&gt;Originally published on &lt;a href="https://banxal.com/blog/fix-or-rebuild-vibe-coded-app" rel="noopener noreferrer"&gt;banxal.com&lt;/a&gt;.&lt;/em&gt;&lt;/p&gt;

</description>
      <category>webdev</category>
      <category>security</category>
      <category>supabase</category>
      <category>ai</category>
    </item>
  </channel>
</rss>
