From 8ad2d58ea31296ba3305d4ba8fb80ade73fc1fac Mon Sep 17 00:00:00 2001 From: Manas Srivastava Date: Mon, 6 Jul 2026 11:30:00 +0530 Subject: [PATCH 1/2] docs(resources): document resource health-check and live connectivity testing patterns --- llms.txt | 28 ++++++++++++++++++++++++++++ 1 file changed, 28 insertions(+) diff --git a/llms.txt b/llms.txt index bad4a78..5d3283c 100644 --- a/llms.txt +++ b/llms.txt @@ -289,6 +289,34 @@ Full guide: [https://instanode.dev/docs#troubleshooting-deploys](https://instano Every error envelope includes an `agent_action` string when recovery is possible — surface it to the user verbatim. The `retry` field (seconds) signals the server-suggested back-off when present. +## Resource health-checks and live connectivity testing + +After provisioning, an agent should verify a resource is reachable before writing application code that depends on it. Use these patterns: + +### Checking provisioned resource status +- **`GET /api/v1/resources`** — list all resources for the authenticated team. Returns `{ok, resources: [{id, token, kind, name, tier, status, environment, created_at, expires_at}]}`. The `status` field is one of `active`, `expired`, `deleted`, or `error`. Filter by `?kind=postgres` to scope to a service type. +- **`GET /api/v1/resources/:token`** — get a single resource by its provision token. Returns the same shape as a single element from the list, plus `connection_url` (decrypted for the calling team) and `limits` (tier-specific maximums). +- **`status:"active"`** is the only signal that the resource is live and provisioned — `error` means the provisioner returned a failure during initial setup (rare; usually a transient backend issue; re-provision with a new name). + +### Verifying connectivity without credentials in source code +When the agent's goal is to *confirm* a database is reachable before handing off to the user: + +```bash +# Quick Postgres reachability check +PGPASSWORD="" psql "" -c "SELECT 1;" 2>&1 + +# Quick Redis reachability check +redis-cli -u "" PING + +# Quick MongoDB reachability check +mongosh "" --eval "db.runCommand({ping:1})" --quiet +``` + +The agent should only emit `connection_url` to the user after confirming `SELECT 1` returns `1` (or equivalent). A non-`active` status or a failed ping means re-provision — call the same endpoint again with a new `name`; the failed resource token is inert. + +### TTL awareness +Every response includes `expires_at` (ISO 8601, null for permanent). An anonymous resource expires 24h after creation. The agent should surface `expires_at` to the user so they can claim the resource before the window closes. The claim URL is in the original provision response as `upgrade`. + ## How to use this file If you're an LLM helping a user build something, you can: From 01dce73bc9bfcb68d1081a25ef1b682e483336d9 Mon Sep 17 00:00:00 2001 From: Manas Srivastava Date: Tue, 7 Jul 2026 10:15:00 +0530 Subject: [PATCH 2/2] docs(quota): document rate limiting, quota exhaustion responses, and agent recovery patterns --- llms.txt | 38 ++++++++++++++++++++++++++++++++++++++ 1 file changed, 38 insertions(+) diff --git a/llms.txt b/llms.txt index 5d3283c..91786f2 100644 --- a/llms.txt +++ b/llms.txt @@ -317,6 +317,44 @@ The agent should only emit `connection_url` to the user after confirming `SELECT ### TTL awareness Every response includes `expires_at` (ISO 8601, null for permanent). An anonymous resource expires 24h after creation. The agent should surface `expires_at` to the user so they can claim the resource before the window closes. The claim URL is in the original provision response as `upgrade`. +## Rate limiting, quota exhaustion, and recovery patterns + +InstaNode enforces two distinct throttle layers. Agents must handle both without user intervention. + +### Anonymous fingerprint rate limit (pre-auth) +Unauthenticated requests are fingerprinted by IP subnet + ASN. The daily cap is **5 new provisions per fingerprint**. On the 6th attempt within 24 hours, the API returns the *same* token as the most recent same-kind provision for that fingerprint — not a 429 — so the agent receives a valid (if duplicate) resource rather than an error. If distinct resources are needed, the user must claim (authenticate) first. + +### Quota exhaustion (authenticated, over-tier) +When a team's provisioned resource count reaches the tier limit, `POST /db/new` (or any provision endpoint) returns: + +```json +{ + "ok": false, + "error": "quota_exceeded", + "agent_action": "Upgrade to Pro at https://instanode.dev/pricing to provision more databases.", + "upgrade": "https://instanode.dev/pricing" +} +``` + +HTTP status is **402 Payment Required**. The agent should surface `agent_action` verbatim to the user and stop retrying — quota exhaustion is deterministic, not transient. + +### Rate limiting on write endpoints (429) +Heavy-burst provisioning (>20 requests/minute to provisioning endpoints) triggers a 429 with a `Retry-After` header (seconds) and `{"error":"rate_limited","retry":}` in the body. Back off by the `retry` value before retrying. Do not retry immediately — the server-side sliding window is per-IP and does not reset on connection close. + +### Error shapes reference + +| HTTP | `error` field | Transient? | Agent action | +|---|---|---|---| +| 402 | `quota_exceeded` | No | Surface `agent_action` + stop | +| 402 | `tier_required` | No | Surface upgrade link | +| 429 | `rate_limited` | Yes | Wait `retry` seconds | +| 503 | `provisioner_unavailable` | Yes | Retry with 5s back-off, max 3× | +| 409 | `name_taken` | No | Choose a different `name` | +| 400 | `name_required` | No | Add `name` field | +| 400 | `invalid_name` | No | Fix name: `^[A-Za-z0-9][A-Za-z0-9 _-]*$` | + +The `agent_action` string is always present on 402 responses and is human-readable. Print it directly into any user-facing message. + ## How to use this file If you're an LLM helping a user build something, you can: