jsonpad meters two things: how many requests you make in a calendar month, and how many bytes you have stored. Everything else on your plan is a guard rail against a runaway loop rather than something you should need to design around.
If you are writing a client or an agent that talks to jsonpad unattended, this is the page to read: the response headers below are what let it pace itself, and the degradation behaviour is what lets it keep working when it runs out. To check your limits and usage in a single request, call GET /tokens/self.
Every API call authenticated with an API token counts as one request against your monthly allowance, regardless of method or response status.
Four things do not count:
5xx status. If we break, you get the request back.Realtime websocket messages are not metered either. Instead, each plan caps how many concurrent realtime connections a single account may hold open; a connection beyond that cap is refused at connection time, and is told how long to wait before trying again. See connection limits.
Outbound webhook deliveries are not metered either. Each plan caps how many webhooks an account can have (1 on Free, 5 on Indie, 20 on Pro and 50 on Scale).
A flow costs what the same API calls would: calling an endpoint flow, or an event flow running, is one request, and each item the flow reads or writes is one more. Runs you start in the dashboard, and test runs, are free. Each plan caps how many flows an account can have (2 on Free, 10 on Indie, 50 on Pro and 250 on Scale).
Every metered response carries the headers below, alongside the per-minute headers described under rate limits. All of them can be read from JavaScript running in a browser as well as from a server.
x-quota-total25000The request allowance for the current month, excluding any overdraft and any prepaid credits.x-quota-remaining18342How many requests are left before writes start being refused. This includes your plan's overdraft and any prepaid credits you hold, so it can be larger than x-quota-total.x-quota-credits0How many prepaid requests you currently hold. These never expire and are only drawn down once the monthly allowance and overdraft are gone.x-quota-reset2026-10-01T00:00:00.000ZAn ISO 8601 timestamp for when the allowance next resets.x-quota-degradedtrueOnly present on a read served at the free tier's rate limit because your allowance and credits have run out. See below.We email you once, when you cross 80% of your allowance. There is no second email at 90%.
At 100%, in order:
GET, HEAD and OPTIONS requests keep working, but at the free tier's rate limit. Every other method returns QUOTA_EXCEEDED and a retry-after header.In other words, your application degrades to read-only rather than going dark. Whatever you have already stored stays readable.
{name: "QUOTA_EXCEEDED"code: 10013message: "Monthly request quota exceeded. Your allowance resets at 2026-10-01T00:00:00.000Z. Read requests st..."}Buying a prepaid request pack takes effect immediately and does not change your plan.
At 00:00 UTC on the first of each calendar month, not on your billing anniversary. Free accounts have no anniversary, and a fixed reset date means an upgrade never has to prorate your allowance.
Prepaid credits carry over. Unused monthly allowance does not.
Each plan has a total storage allowance covering the JSON data of every item in every one of your lists. Stored bytes are recalculated once a day rather than on every write, so the figure you see on your dashboard can be up to a day behind.
If you are over the allowance, reads keep working and writes return
STORAGE_LIMIT_EXCEEDED until you delete some data or move up a plan. Nothing is ever deleted for you.Separately from the monthly allowance, each plan limits how fast you can make requests: a maximum number of requests per minute, and a minimum gap between consecutive requests. Exceeding either returns
RATE_LIMIT_EXCEEDED and a retry-after header telling you how many seconds to wait. A refused request does not count against your monthly allowance.Every response to a request made with an API token, including a refused one, carries two headers describing the per-minute limit:
x-rate-limit-total60How many requests your plan allows per minute.x-rate-limit-remaining42How many more requests you can make after this one before reaching that limit. The minute is a rolling window over the last 60 seconds.Rate limits exist to stop one account degrading the service for everyone. They are not something you should have to plan around: if you are hitting them during normal operation, add a short delay between requests rather than retrying immediately.
Each plan retains a number of versions per item. Older versions remain in the event log — we never delete event history — but they can no longer be fetched back through the version query parameter, and requesting one returns
ITEM_VERSION_NOT_RETAINED.Write rules have to finish, quickly, on every write, so the language has no loops and no recursion and evaluation has a budget. These limits are the same on every plan, including free:
rule text64 KiBChecked when the rules are saved.statements200allow and require statements in one rule set.expressions5,000Across the whole rule set, counting each call to one of your own functions as the size of its body.nesting depth64Brackets and unary operators, with a separate cap of 500 on the height of an expression — every operator in a chain like a && b && c is one level.function parameters8Per declared function.evaluation budget100,000 unitsPer write. Roughly one unit per expression evaluated, and more for work over large values: comparing, diffing, hashing and string handling all cost by size. Running out refuses the write with WRITE_RULE_DENIED. Ordinary rules use a tiny fraction of it, and the dashboard's playground shows you how much.lookups10 itemsDifferent items one write's rules can read with lookup() and exists(). Reading the same item again doesn't count twice. A lookup past the limit is an error, so the statement making it isn't true. Each item read counts as a request.value depth256How deeply nested a value can be when it's compared, diffed or hashed.rule tests200 / 256 KiBStored per list, as a count and as a size.Refused writes are counted in your list's stats, and the last 50 per list are kept so you can see what was refused and why.
Lists, items per list and indexes per list are uncapped on every plan, including free. In practice what you can store is bounded by the storage allowance rather than by a count.
Every feature is available on every plan too: JSON schema validation, version history, JSON Patch, JSON Pointer, JSON Path, realtime updates and identities. You never need to move up a plan to unlock a capability — only to get more volume.
The current numbers for each plan are on the pricing page.