{"section":"limits","limits":{"minIntervalSeconds":60,"cron":"5 fields, UTC. Day-of-month and day-of-week follow the standard: when both are restricted, the match is OR.","cronSyntax":{"fields":5,"timezone":"UTC only","operators":["*","a-b","a,b","*/n","a-b/n"],"names":{"dayOfWeek":["SUN","MON","TUE","WED","THU","FRI","SAT"],"month":["JAN","FEB","MAR","APR","MAY","JUN","JUL","AUG","SEP","OCT","NOV","DEC"]},"macros":["@yearly","@annually","@monthly","@weekly","@daily","@midnight","@hourly"],"dayOfWeek":{"numbering":"0-6 with 0 = Sunday; 7 also means Sunday","advice":"Write days as names (MON-FRI). Numbers differ between schedulers: Quartz, AWS EventBridge and Cloudflare number Sunday as 1, we and croniter as 0."},"translated":{"quartz":["?"],"note":"\"?\" as a whole day-of-month or day-of-week field becomes \"*\". A NUMERIC day-of-week next to \"?\" is refused, because \"?\" means the expression was written where Sunday is 1."},"notSupported":{"quartz":["L","W","#"],"fieldCounts":["six fields (seconds)","seven fields (year)"],"macros":["@reboot","@every"],"other":["CRON_TZ= prefixes","time zones of any kind"]}},"maxBodyBytes":65536,"maxHeaderBytes":8192,"maxNameBytes":200,"maxUrlBytes":2048,"maxCronBytes":256,"urlScope":"The path is canonicalised before we match it against your verified destination: \"..\", \".\" and their encoded forms are folded first. An encoded separator is NOT refused on its own: %2F inside a segment is kept and matched as it stands, so a GitLab-style project path keeps working. What we refuse is a path that HIDES A DOT SEGMENT — one where \"..\" or \".\" shows up once you decode it (we try up to twice), drop a \";\" parameter from a segment, or strip control characters. So \"/hook/..%2Fadmin\" and \"/hook/..%5Cadmin\" are refused; \"/api/v4/projects/group%2Fproject/trigger\" is not. The refusal carries reason \"encoded-separator\" — the name is older than the rule; branch on it, not on the word.","maxRequestBytes":131072,"maxLiveTasks":50,"maxDestinations":25,"verifyAttemptsPerDay":{"perDestination":10,"perClient":40,"needsBalance":"Verification does not consume a delivery, but it does need a live balance: it sends a real request to your server. With an empty balance it refuses with \"no_credits\"."},"whenFull":"Hitting a limit returns error \"limit_reached\" with the field `limit` naming it, plus `max`, `used` and one sentence saying how to free space. 409 when YOU free it (delete something), 429 when TIME does. Time comes in two shapes and the FIELD tells them apart, not the status: a DAILY ration carries `retryTomorrow: true` and no seconds; an HOURLY one carries `retryable: true`, `retryAfterSeconds` and a retry-after header — at least 1 second, never more than 3600 (the UTC hour boundary).","freeingTasks":"Limits count what is LIVE. DELETE /api/tasks/{id} frees its slot immediately, and a soft-deleted task does not count against you.","freeingDestinations":"GET /api/destinations lists them; DELETE /api/destinations/{id} removes one that no task points at.","raising":"Most of these limits are service-wide today and are raised by a deploy, not per account. The exception is `buy_hourly`: it is counted per caller — see `buyAttemptsPerCaller` — so waiting the retry-after does help. If you need more, ask before you build around the limit.","settlementAttempts":"60 payment settlements per hour across all buyers, split into two lanes: 48/hour for authorizations whose EIP-712 signature we verify locally (a plain ECDSA signature from the paying address — every standard x402 client) and 12/hour for signatures only the chain can verify (smart wallets, ERC-1271 / ERC-6492). Over a lane /buy answers 429 with a retry-after header and nothing is charged. A header without a well-formed EIP-712 signature (65–4096 bytes) is refused with 402 and a reason; nothing is charged or counted. That lane refusal is one of the OLDER ones: it carries an English-or-not sentence in `error`, not a machine code, so branch on the 429 and on the retry-after header. Only the per-caller limit below answers with `limit_reached`.","buyAttemptsPerCaller":"16 payment attempts per hour per CALLER — one number, both lanes. A caller is your network address (IPv6 counted per /64) TOGETHER WITH your payer address when your signature verifies locally, and the address alone when only the chain can verify it. So two agents behind one shared egress — Cloudflare Workers, Lambda behind NAT, Vercel — each get their own allowance as long as they pay from different addresses. Replaying an already-settled payment does not count; an authorization the facilitator REFUSED does count, because it reached the key — so retrying a refused header burns the allowance and re-signing does not reset it. Over it /buy answers 429 `limit_reached` with `limit: \"buy_hourly\"`, `max`, `used`, `retryAfterSeconds`, `retryable: true` and a retry-after header; nothing is charged, your nonce is not burnt and the service-wide budget is not touched. One narrower case, said out loud: if our edge hands us no readable client address at all, every such request shares ONE allowance — we alarm on it because it means the route is broken, not that you are.","targets":"https only — an http:// URL is refused when you register a destination and when you change a task URL, and a task that still points at one stops at delivery with a notice instead of sending your headers in the clear. Hostnames only: no IP literals, no single-label or internal names (localhost, and anything ending .local, .internal, .localhost, .home, .lan, .intranet, .corp, .test, .example or .invalid), and none of our own hosts. No user:password in the URL. Ports 80/443 only, no redirects followed, and no path that hides a dot segment — see `urlScope`, where a plain %2F inside a segment is explicitly fine.","overlap":"skip (only supported mode)"}}