Skip to main content

BusinessCodeCross Team

Rate limits for an AI-built app (2026)

Throttle login and sign-up. Cap write routes and nearby servers. Put a bot check on public doors. Cap reset texts and model spend. Watch refusals after launch.

Business

13 min

Cap
Login doors

Per account and per address

Cost
Reset texts

Twilio bills each segment

Watch
Two clocks

Too-many-requests and spend

After you launch an app built with an artificial intelligence builder, put a ceiling on how often one source can hit login, sign-up, and password reset. Cap the API routes and the small server programs that run near the visitor. Put a bot check on those public doors. Cap reset texts and model spend so a script cannot empty the card. Watch the too-many-requests replies and the shop bills after launch.

CodeCross wrote this guide. We are an Austin, Texas studio at 1606 Headway Cir STE 9212. Our engineers work on US Central hours. Start at Austin app development company. We also build phone apps. Method and numbers live on proof. Short builder pages live on vibe coding.

This page is the abuse card you keep after a stranger can already open the app. The mail-landing card sits on inbox mail from an AI-built app. The watch list sits on watch an AI-built app after launch. This page asks: which doors still have no ceiling, and which bills a script can still run up tonight?

Who this is for

You shipped from Lovable, Bolt, Replit, v0, Cursor, or another AI builder. People who are not you can create an account. The app already sends a confirm mail, a reset mail, or a text. The live host answers. You have not put a ceiling on login, sign-up, reset, or the model route. You want those doors closed before you buy ads.

You are not this page if the app still lives only on a laptop, if only the founder can log in, or if you cannot take the live URL down tonight. Open the inbox-mail page if reset mail still leaves from the builder host. Open the watch page if no company inbox already got a test fail.

What a rate limit means

A rate limit is a ceiling on how many times one source can hit a door in a set window. The source can be an address, an account, a key, or a path. The window is a number of seconds or minutes you choose, or a number the shop already chose. When the ceiling is hit, the door should refuse the next try.

A 429 is the HTTP status that means too many requests. RFC 6585 defines that status. The reply may include a Retry-After line that says how long to wait. OWASP’s bot sheet wants a generic 429 on login. It does not want a precise wait that helps a script schedule the next try, and it does not want a note that names which bucket fired.

An API key is a secret string a shop uses to know who is calling. A leaked model key with no spend cap is a live bill. A public login path with no ceiling is a live guesser. The product path is the proof: a stranger can sign in, and a script cannot empty the card or lock every account.

Six layers that keep an AI-built app from being abused

  1. Watch

    429s, reset volume, text spend, and one named reader.

  2. Model spend

    Hard cap on OpenAI and Claude. An alert is not a cap.

  3. Bot check

    A person check on the public doors, verified on the server.

  4. API and edge routes

    Tighter on write paths than on the home page.

  5. Reset mail and texts

    Per account. Same reply for unknown names. Cap the shop.

  6. Login and sign-up

    Per account and per address. Two buckets, not one pair.

A hidden login button is not a ceiling. Start at the public doors, then walk down. Stop when a layer has no named owner.

Login and sign-up

Login throttling is a ceiling on how often someone can try a password. OWASP’s authentication sheet counts failed tries on the account, not only on the address. An attacker who rotates addresses still hits the same account bucket. The sheet wants a lockout threshold, an observation window, and a lockout duration. It also warns that a lockout can be turned into a denial of service. Keep forgotten-password usable while the password door is closed.

OWASP’s bot sheet is sharper on the buckets. A login door needs two independent ceilings. One is per username. One is per address. Both must be under the line for the try to pass. A single bucket keyed on address plus username lets one address try the threshold against every name. That is the credential-stuffing pattern the sheet is trying to stop. Credential stuffing is the reuse of leaked username and password pairs.

Supabase Auth already puts floors on those doors. Sign-up, recover, resend, magic link, and one-time passwords default to 30 requests per five minutes per address, with a short burst up to 30. A password reset on recover defaults to a 60-second wait for the same user. The token path defaults to 150 requests per five minutes per address. When a bucket empties, Auth returns a 429. You can raise or lower most of those lines in Authentication → Rate Limits. The built-in floors are not a pass if you never opened that page.

Firebase Authentication, last updated 20 October 2026, caps new account creation at 100 accounts per hour per address. Password-reset mail on the no-cost Spark plan is 150 emails a day. Email-link sign-in on Spark is 5 emails a day. Verification texts are 3,000 a day on Firebase Authentication, and 50 a minute per address. Abuse protections may turn on without warning when traffic looks wrong. Those are shop floors. They are not your product policy.

Clerk rate-limits the frontend by address. Create SignIn and Create SignUp allow 5 requests per 10 seconds. Attempt SignIn and Attempt SignUp verification allow 3 per 10 seconds. A 429 includes Retry-After. Honor it. Clerk’s own floor is not a reason to skip an edge rule on the same path. Two ceilings beat one.

API and edge-function ceilings

An edge function is a small server program that runs near the visitor, not only on one origin box. Builders love them for login helpers, Stripe webhooks, and model calls. A write route with no ceiling is a bill and a lockout in the same afternoon. OWASP’s bot sheet wants a tighter ceiling on login than on the home page, and a per-key quota on a public API.

A web application firewall is a filter that sits in front of the site and can block or slow matching requests. Dashboards often label that filter WAF. Vercel’s WAF rate limiting is available on all plans. Vercel tracks counters per region. Traffic that matches the same key in more than one region can go past the number you set in any single region. Hobby allows 1 rate-limit rule per project, a 10-second to 10-minute window, and 1,000,000 allowed requests. Pro allows 40 rules. The dashboard default is a 60-second window and 100 requests. The default action is a 429. You can Log first, then tighten.

Cloudflare’s rate-limiting rules match an expression, then act when the count hits the line. Free allows 1 rule, counts by address, and uses a 10-second period and a 10-second mitigation. Pro allows 2 rules and periods up to 1 minute. Business allows 5 rules, periods up to 10 minutes, and can count by address when many people share one office line. Cloudflare is plain that counters are not exact. A delay of a few seconds can let extra requests reach the origin before the block starts. Do not treat the number as a precise admit count.

Supabase Edge Functions are not a request-rate table. They are a runtime ceiling. Free workers stay active for 150 seconds. Paid workers stay active for 400 seconds. CPU time per request is 2 seconds. An idle request that sends no reply hits 150 seconds and returns 504. A 504 is the HTTP status that means the door waited too long. A model call that streams past those clocks will fail even if you never set a 429. Put the spend cap on the model shop. Put the request ceiling on the route that calls it.

Bot checks on public doors

A bot is a program that hits your doors without a person in the loop. A CAPTCHA is a check that tries to tell a person from a robot, often with a puzzle grid. OWASP’s bot sheet treats a visible puzzle as a last step, not the first. Puzzle grids are hard for some people, easy for solver farms, and weak as the only lock. Prefer a managed check on login, sign-up, and reset. Keep the rate limit after the check passes.

Cloudflare Turnstile is that managed check. It can sit on any site and does not need the rest of the traffic to pass through Cloudflare. It runs small browser checks first. It can show a box, or none, based on risk. Server-side validation is required. The widget alone does not protect the form. Tokens can be forged. Each token is valid for 300 seconds, which is five minutes. Each token can be checked once. A replay returns timeout-or-duplicate. You must POST the token to https://challenges.cloudflare.com/turnstile/v0/siteverify with your secret. Allow the request only when success is true.

OWASP repeats the same Turnstile rules: validate on the server, require success, and check the hostname and the action you configured. Pair the check with an edge rule on the same path. Cloudflare names login as the example a rate-limiting rule is for. Vercel can Challenge instead of 429. A challenge without a ceiling on the route behind it is still an open door.

Password-reset mail and texts

A password-reset form is a mail cannon if it has no ceiling. OWASP’s forgot-password sheet wants the same reply for a real name and a fake one, in the same amount of time. It wants a per-account ceiling, or a bot check, so a script cannot flood one inbox. It also says not to lock the account because of a forgotten-password flood. That flood would become a lockout of people whose names an attacker already knows.

Supabase sends 2 emails per hour with the built-in provider. That floor is a product brake, not a launch plan. Custom SMTP or a Send Email hook lets you raise it. Text messages default to 30 per hour for the project. Recover defaults to a 60-second wait per user. If the builder pointed reset at the built-in sender and you later attach Twilio, the 2-an-hour brake comes off. Put your own ceiling on before that click.

SMS is a text message sent to a phone. Twilio’s US SMS page, current as of October 2026, bills $0.0083 per outbound segment on long codes, toll-free, and short codes. A segment is up to 160 characters on a standard text. Carrier fees sit on top. AT&T adds $0.0035. T-Mobile adds $0.0045. Verizon adds $0.005. A failed message still costs $0.001. One thousand segments to AT&T is $8.30 plus $3.50 in carrier fees. A reset storm that retries is a bill, not a log line.

Amazon SNS SMS does not publish a single US per-text price on that page. Price varies by country, region, and sometimes by carrier. AWS says to read the daily usage report after you send. A US toll-free carrier fee of $0.0025 per message has sat on that page since 1 August 2021. Do not guess a unit price from chat. Read the report. Cap the sender. Firebase still bills phone sign-in on Blaze and caps verification texts at 3,000 a day on Firebase Authentication. Spark password-reset mail is 150 a day. Those floors hide the bill until you upgrade. The upgrade is when the storm gets expensive.

Cost of 1,000 US SMS segments on Twilio

USD

Plus Verizon carrier fee

$13.30

Official Verizon long-code outbound carrier fee: $0.005 per segment.

$0$4$8$11$15October 2026 list price, USDTwilio base1,000 segments$8.30Plus AT&Tcarrier fee$11.80Plus T-Mobilecarrier fee$12.80Plus Verizoncarrier fee$13.30

October 2026 list price, USD

Sourced from Twilio US SMS pricing, current as of October 2026. Base outbound $0.0083. AT&T long-code outbound carrier $0.0035. T-Mobile $0.0045. Verizon $0.005. Failed-message fee $0.001 is not in the bars.

Base outbound SMS is $0.0083 per segment. Carrier fees sit on top. One thousand segments is the unit so the add-on is visible. This is not a CodeCross study.

Model endpoint spend

A model endpoint is the shop URL that runs a large language model. Builders paste that call into a route the browser can reach. A stranger who finds it spends on your card. OpenAI’s rate-limits guide sets an approved monthly usage limit by tier, separate from the spend limits you configure. Free is $100 a month. Build is $500 after $5 in credit purchases. Launch is $5,000 after $100. Grow is $200,000 after $500. A hard spend limit is the switch that stops traffic. A spend alert only mails you. When the hard cap is hit, requests return a 429 with organization_spend_limit_exceeded or project_spend_limit_exceeded.

OpenAI’s spend-limits page is blunt. Enforcement is not instant. Recorded spend can go slightly past the number you set. An organization cap covers every project. A project cap covers only that project. Raising or removing the cap restores traffic after the change lands. Otherwise the cap resets with the next month. Set an alert under the hard cap so you see the climb before the door slams.

Anthropic’s rate-limits page splits the same idea. Start’s monthly spend cap is $500. Build is $1,000. Scale is $200,000. Custom has no published cap. Hitting the tier cap pauses usage until 00:00 UTC on the first day of the next month, unless you raise the tier sooner. Those replies are HTTP 429 with enforced_spend_limit_reached and no Retry-After. A spend limit you set yourself, below the tier cap, returns HTTP 400 instead. You cannot set a spend cap on the Default workspace. Workspace spend is a lower cap on a named workspace. Put the app key in a named workspace. Cap that workspace. Do not leave the key on Default.

OpenAI also tells you to put a usage limit on each user of your product, daily or monthly, if people can trigger the model. The shop cap stops your card. The per-user cap stops one account from burning the shop cap for everyone else. Route the call through a server or an edge function you control. Never put the model key in the browser bundle.

Looks open vs actually capped

Looks finished

  1. Hidden login button

    The token path still answers if a script asks.

  2. Builder default Auth

    Shop floors exist. You never opened the Rate Limits page.

  3. Turnstile box only

    No Siteverify. A forged token still posts.

  4. OpenAI usage tier

    An alert, or the shop’s own monthly line, is not your hard cap.

If the right column is empty on any row, a script can still guess passwords or empty the card. ↓

Actually capped

  1. Two login buckets

    Per account and per address. Generic 429. Reset still works.

  2. Reset ceiling plus same reply

    Unknown names get the same message. SMS has a project cap.

  3. Siteverify on the server

    Success true. Five-minute, one-use token. Edge rule on the path.

  4. Hard spend on a named project

    OpenAI project cap. Claude workspace cap. Per-user daily line.

A green sign-in on your laptop is not an abuse pass. Real protection is two login buckets, a reset ceiling, a bot check on the server, and a hard spend cap.

What to watch after launch

After launch, four clocks matter. Too-many-requests on login and reset. Reset volume per account. SMS and mail spend. Model spend against the hard cap. OWASP’s bot sheet wants a log on each sensitive door: time, route, status, address, and the decision. A sudden climb in 429s or in sign-up volume is the incident, not a one-star review two days later.

Vercel tells you to watch the custom rule on the Firewall overview after you publish. Start on Log if you are unsure. Then switch to 429 or Challenge. Cloudflare evaluates rules in order. A Block stops later rules. Clerk sends Retry-After on a 429. Honor it in your own retries so a refresh loop does not deepen the hole.

Name who reads those clocks this week. A Saturday reset storm that bills Twilio is an incident. A model 429 with organization_spend_limit_exceeded is an incident. A login 429 that also locks real users is an incident. Stop the public door. Keep the halt click you already named on the watch page. Product traffic and a guessed-password flood must not share one silent inbox.

Cap → check → prove → watch

  1. 01

    Cap

    Login, sign-up, reset, write routes, SMS, and model spend.

  2. 02

    Check

    Turnstile Siteverify or a WAF rule on the same public doors.

  3. 03

    Prove

    A stranger signs in. A script hits 429. Reset mail does not flood.

  4. 04 · loops

    Watch

    429s, reset volume, SMS spend, model spend. One named reader.

One loop is enough before the first paid week. Ads that skip the reset and model caps train a bot on an open bill.

What to do this week

Keep the week small. You need ceilings on the public doors, a bot check the server actually verifies, and a hard spend cap on every model key.

  1. Open the Auth rate page. Supabase Authentication → Rate Limits. Confirm recover, signup, and token. On Firebase, read the Auth limits table and the Spark mail floors. On Clerk, read the frontend 10-second lines.
  2. Add two login buckets. Per account and per address. Generic 429. Keep reset usable if a lockout fires.
  3. Cap reset and SMS. Same reply for unknown names. Put a project ceiling on Twilio or SNS before you leave the built-in sender.
  4. Put a bot check on login, sign-up, and reset. Turnstile with Siteverify, or a Vercel or Cloudflare rule on those paths. Log first if you need a day of traffic.
  5. Cap the write routes. Vercel WAF or Cloudflare on /api and the edge functions that mutate. Tighter than the home page.
  6. Hard-cap model spend. OpenAI project hard limit. Claude named workspace, not Default. A per-user daily line in your own code.
  7. Name who reads 429s and shop bills this week. Send a test 429. Confirm the mail arrived.

If a door is still red — no recover ceiling, no Siteverify, no model cap — stop buying ads that land on those paths. A reset storm on day one is a launch, not a later harden.

This week, in order

  1. 01 →

    Read the shop floors

    Supabase, Firebase, or Clerk. Write the numbers you actually run.

  2. 02 →

    Two buckets plus reset

    Account and address. Same reset reply. SMS project cap.

  3. 03 →

    Bot check on the server

    Siteverify or a WAF rule. Prove a forged token fails.

  4. 04

    Hard-cap spend and watch

    Model project cap. 429 mail. One named reader.

Do not skip to ads while reset and the model route still have no ceiling. The public doors come first.

Next steps

Put ceilings on login, sign-up, and reset. Cap the write routes. Verify the bot check on the server. Hard-cap SMS and model spend. Watch 429s and the shop bills. Customers should not be the first people who notice that a script emptied the card.

CodeCross is a product studio. The week after an AI-built launch is a live host, a ceiling on every public door, and a spend cap that already stopped a test. If a reset path is still uncapped and you want a second pair of eyes, book a conversation.

FAQ

Does hiding the login button stop a stranger from hitting the token path?

No. OWASP treats the login path as its own door. Supabase rate-limits /auth/v1/token whether a button exists or not. A hidden screen is not a ceiling. Cap the path. Prove a script gets a 429.

Is Supabase’s built-in mail sender enough for a public reset form?

As a brake, yes. Supabase sends 2 emails per hour with the built-in provider. That is not a launch mail shop. Custom SMTP or a Send Email hook lets you raise the line. Put your own per-account ceiling on before you raise it. OWASP still wants the same reply for unknown names.

Can a Cloudflare Free zone write a one-minute login rule?

No. Cloudflare’s rate-limiting rules give Free one rule, a 10-second counting period, and a 10-second mitigation. A one-minute period starts on Pro. Put Turnstile on the form either way. The widget does not need the rest of the site to sit on Cloudflare.

If OpenAI already sets a monthly usage limit, do I still need a hard spend cap?

Yes if you want the door to close at your number. OpenAI assigns an approved monthly usage limit by tier. That line is separate from the spend limits you configure. A spend alert only mails you. A hard spend limit returns a 429. Set the hard cap on the project that holds the live key.

Should I lock the account after a flood of reset mails?

No. OWASP’s forgot-password sheet says a forgotten-password attack should not lock the account. That lock becomes a denial of service against names an attacker already knows. Cap the reset door. Keep the same reply for unknown names. Let a real user still recover.

Is a 429 on the homepage the same as a 429 on login?

No. OWASP wants a tighter ceiling on login than on the home page. Vercel and Cloudflare both match on path. A home-page rule that also wraps /login is either too loose for passwords or too tight for readers. Two rules. Two numbers.

Book a call

Thirty minutes with a senior teammate — honest next steps.

Want a second pair of eyes on your app?

Tell us what you built and where it's stuck. We'll tell you what it takes to make it ready for real users.

Prefer writing? Send project details on the contact page.