You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
docs(openapi): widen API title/description to full bundle + AI-agent/MCP framing
The OpenAPI info block — the first thing an AI coding agent fetches to
decide what the API does — only mentioned "databases, caches, and queues"
and a generic "InstaNode API" title. It omitted pgvector/vector, object
storage, webhooks, and the headline deployment wedge, plus any AI-agent /
MCP / free-tier / single-HTTP-call framing.
Framing-only change (no path/parameter/schema contract edits):
- info.title → "instanode.dev — zero-friction dev infrastructure for AI agents"
- info.description widened to lead with the keywords agents match: Postgres,
pgvector/vector, Redis, MongoDB, NATS queues, S3 storage, webhooks, AND app
deployment — each a single HTTP call, no account/Docker/setup; free anon
tier; also MCP server + SDKs + CLI. Accurate to the live router surface.
- Added a top-level tags[] block describing each service family
(database/vector/cache/nosql/queue/storage/webhook/deploy/auth).
- Regenerated openapi.snapshot.json (description is content, so the
canonical snapshot changed; drift check passes).
No paths, parameters, or schemas added/removed/renamed.
Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
"title": "instanode.dev — zero-friction dev infrastructure for AI agents",
187
187
"version": "1.0.0",
188
-
"description": "Zero-friction developer infrastructure. Provision real databases, caches, and queues with a single HTTP call — no account, no Docker, no setup.\n\n## Idempotency\n\nEvery POST endpoint that creates a resource is idempotent. Two layered protections cover every retry pattern:\n\n1. Explicit Idempotency-Key header (Stripe-shape, 24h TTL). Pass the same opaque key on each retry of a logical operation and the server replays the first response verbatim. Reusing a key with a different body returns 409.\n2. Body-fingerprint fallback (120s TTL). When the header is absent, the server synthesises a key from sha256(scope, route, canonical-body) and dedups identical retries inside a 120s window. Absorbs double-clicks, mobile double-taps, agent retries on transient 5xx, and reverse-proxy retries on network blips. Use the explicit header for true exactly-once across longer windows.\n\nEvery response from a create endpoint carries:\n- X-Idempotency-Source: explicit | fingerprint | miss — which dedup path matched (explicit = caller passed an Idempotency-Key; fingerprint = the body-fingerprint cache replayed; miss = handler ran fresh).\n- X-Idempotent-Replay: true — present only when the response was served from the cache (either path).\n\n## Rate limit (applies to every route)\n\nA global per-IP rate limit (100 req/min) is applied to EVERY documented endpoint by the router middleware. Exceeding it returns 429 with the standard ErrorResponse envelope (error=rate_limited), a Retry-After HTTP header, and retry_after_seconds in the JSON body. The per-route response maps below may omit 429 for brevity; the canonical 429 shape is documented under components.responses.TooManyRequests and applies to every path. T19 P1-1 (BugHunt 2026-05-20).\n\n## Payload size (applies to every route)\n\nFiber's global BodyLimit is set to 50 MiB — only /deploy/new and /stacks/new (multipart tarballs) and /webhooks/github/* (push payloads) approach that cap; JSON endpoints are bounded to sub-KB bodies by the per-handler shape. Oversized requests return 413 payload_too_large with the standard JSON ErrorResponse envelope (NOT the upstream nginx HTML 502 the older shape returned — T19 P1-2). The canonical 413 shape is documented under components.responses.PayloadTooLarge.\n\n## Security headers (applies to every response)\n\nEvery response from EVERY route — including liveness/readiness probes, OpenAPI document fetch, 4xx error envelopes, 5xx error envelopes, and 404/405 Fiber-default responses — carries the following defense-in-depth response headers, set by the SecurityHeaders middleware ahead of RequestID in the router middleware chain (task #311 wave-3 chaos-verify redo):\n\n- Strict-Transport-Security: max-age=63072000; includeSubDomains — production only (omitted on ENVIRONMENT=development so local http://localhost:8080 doesn't poison the host's HSTS cache). 2-year max-age, includeSubDomains for *.api.instanode.dev.\n- X-Content-Type-Options: nosniff — disables MIME sniffing.\n- X-Frame-Options: SAMEORIGIN — clickjacking defense.\n- Referrer-Policy: strict-origin-when-cross-origin — prevents URL-token leakage across origin downgrades.\n- Permissions-Policy: geolocation=(), microphone=(), camera=(), payment=() — denies powerful browser APIs.\n- Cross-Origin-Resource-Policy: same-origin — blocks no-cors cross-origin fetches.\n\nThese headers are not enumerated in each per-route responses block to keep the spec readable; they apply globally. Coverage test: TestSecurityHeaders_AllEndpoints_AllHeaders_Prod (internal/handlers/security_headers_test.go) iterates 5 representative endpoints (healthz, readyz, openapi.json, db/new, claim) and asserts all 6 headers land on every response."
188
+
"description": "Zero-friction developer infrastructure built for AI coding agents (Claude Code, Cursor, MCP tool-use) and humans alike. Provision real Postgres + pgvector + Redis + MongoDB + NATS JetStream queues + S3-compatible object storage + webhook receivers — AND deploy your app on top of them — each with a single HTTP call. No account, no Docker, no setup. A free anonymous tier (24h TTL) lets an agent claim infrastructure the moment it hits a limit, with no signup. Also available as an MCP server, language SDKs, and a CLI for agent tool-use. The unit of value is the whole bundle: everything an agent needs to ship a working app, claimed and provisioned in one flow. Keywords: AI agent infrastructure, MCP, Postgres, pgvector / vector database, Redis cache, MongoDB, NATS queue, S3 object storage, webhooks, app deployment, free tier, single HTTP call, no signup.\n\n## Idempotency\n\nEvery POST endpoint that creates a resource is idempotent. Two layered protections cover every retry pattern:\n\n1. Explicit Idempotency-Key header (Stripe-shape, 24h TTL). Pass the same opaque key on each retry of a logical operation and the server replays the first response verbatim. Reusing a key with a different body returns 409.\n2. Body-fingerprint fallback (120s TTL). When the header is absent, the server synthesises a key from sha256(scope, route, canonical-body) and dedups identical retries inside a 120s window. Absorbs double-clicks, mobile double-taps, agent retries on transient 5xx, and reverse-proxy retries on network blips. Use the explicit header for true exactly-once across longer windows.\n\nEvery response from a create endpoint carries:\n- X-Idempotency-Source: explicit | fingerprint | miss — which dedup path matched (explicit = caller passed an Idempotency-Key; fingerprint = the body-fingerprint cache replayed; miss = handler ran fresh).\n- X-Idempotent-Replay: true — present only when the response was served from the cache (either path).\n\n## Rate limit (applies to every route)\n\nA global per-IP rate limit (100 req/min) is applied to EVERY documented endpoint by the router middleware. Exceeding it returns 429 with the standard ErrorResponse envelope (error=rate_limited), a Retry-After HTTP header, and retry_after_seconds in the JSON body. The per-route response maps below may omit 429 for brevity; the canonical 429 shape is documented under components.responses.TooManyRequests and applies to every path. T19 P1-1 (BugHunt 2026-05-20).\n\n## Payload size (applies to every route)\n\nFiber's global BodyLimit is set to 50 MiB — only /deploy/new and /stacks/new (multipart tarballs) and /webhooks/github/* (push payloads) approach that cap; JSON endpoints are bounded to sub-KB bodies by the per-handler shape. Oversized requests return 413 payload_too_large with the standard JSON ErrorResponse envelope (NOT the upstream nginx HTML 502 the older shape returned — T19 P1-2). The canonical 413 shape is documented under components.responses.PayloadTooLarge.\n\n## Security headers (applies to every response)\n\nEvery response from EVERY route — including liveness/readiness probes, OpenAPI document fetch, 4xx error envelopes, 5xx error envelopes, and 404/405 Fiber-default responses — carries the following defense-in-depth response headers, set by the SecurityHeaders middleware ahead of RequestID in the router middleware chain (task #311 wave-3 chaos-verify redo):\n\n- Strict-Transport-Security: max-age=63072000; includeSubDomains — production only (omitted on ENVIRONMENT=development so local http://localhost:8080 doesn't poison the host's HSTS cache). 2-year max-age, includeSubDomains for *.api.instanode.dev.\n- X-Content-Type-Options: nosniff — disables MIME sniffing.\n- X-Frame-Options: SAMEORIGIN — clickjacking defense.\n- Referrer-Policy: strict-origin-when-cross-origin — prevents URL-token leakage across origin downgrades.\n- Permissions-Policy: geolocation=(), microphone=(), camera=(), payment=() — denies powerful browser APIs.\n- Cross-Origin-Resource-Policy: same-origin — blocks no-cors cross-origin fetches.\n\nThese headers are not enumerated in each per-route responses block to keep the spec readable; they apply globally. Coverage test: TestSecurityHeaders_AllEndpoints_AllHeaders_Prod (internal/handlers/security_headers_test.go) iterates 5 representative endpoints (healthz, readyz, openapi.json, db/new, claim) and asserts all 6 headers land on every response."
189
189
},
190
+
"tags": [
191
+
{ "name": "database", "description": "Real Postgres connection strings via POST /db/new — encrypted at rest, per-token isolation, instant." },
192
+
{ "name": "vector", "description": "pgvector-enabled Postgres via POST /vector/new — embedding stores with HNSW + IVFFlat for AI/RAG workloads." },
193
+
{ "name": "cache", "description": "Real Redis connection strings via POST /cache/new — ACL namespace isolation." },
194
+
{ "name": "nosql", "description": "Real MongoDB connection strings via POST /nosql/new — per-token database scoping." },
195
+
{ "name": "queue", "description": "NATS JetStream URLs via POST /queue/new — per-account subject isolation." },
196
+
{ "name": "storage", "description": "S3-compatible object storage via POST /storage/new plus broker-mode signed URLs via POST /storage/{token}/presign." },
197
+
{ "name": "webhook", "description": "Public webhook receiver URLs via POST /webhook/new — captures any HTTP method payload." },
198
+
{ "name": "deploy", "description": "The deployment wedge: ship an app via POST /deploy/new (single app) or POST /stacks/new (multi-service) — Docker build to public HTTPS URL with TLS, no Dockerfile-on-disk required." },
199
+
{ "name": "auth", "description": "Magic-link, GitHub OAuth, and CLI device-flow login — used to claim a free anonymous resource bundle." }
Copy file name to clipboardExpand all lines: openapi.snapshot.json
+40-2Lines changed: 40 additions & 2 deletions
Original file line number
Diff line number
Diff line change
@@ -2566,8 +2566,8 @@
2566
2566
}
2567
2567
},
2568
2568
"info": {
2569
-
"description": "Zero-friction developer infrastructure. Provision real databases, caches, and queues with a single HTTP call — no account, no Docker, no setup.\n\n## Idempotency\n\nEvery POST endpoint that creates a resource is idempotent. Two layered protections cover every retry pattern:\n\n1. Explicit Idempotency-Key header (Stripe-shape, 24h TTL). Pass the same opaque key on each retry of a logical operation and the server replays the first response verbatim. Reusing a key with a different body returns 409.\n2. Body-fingerprint fallback (120s TTL). When the header is absent, the server synthesises a key from sha256(scope, route, canonical-body) and dedups identical retries inside a 120s window. Absorbs double-clicks, mobile double-taps, agent retries on transient 5xx, and reverse-proxy retries on network blips. Use the explicit header for true exactly-once across longer windows.\n\nEvery response from a create endpoint carries:\n- X-Idempotency-Source: explicit | fingerprint | miss — which dedup path matched (explicit = caller passed an Idempotency-Key; fingerprint = the body-fingerprint cache replayed; miss = handler ran fresh).\n- X-Idempotent-Replay: true — present only when the response was served from the cache (either path).\n\n## Rate limit (applies to every route)\n\nA global per-IP rate limit (100 req/min) is applied to EVERY documented endpoint by the router middleware. Exceeding it returns 429 with the standard ErrorResponse envelope (error=rate_limited), a Retry-After HTTP header, and retry_after_seconds in the JSON body. The per-route response maps below may omit 429 for brevity; the canonical 429 shape is documented under components.responses.TooManyRequests and applies to every path. T19 P1-1 (BugHunt 2026-05-20).\n\n## Payload size (applies to every route)\n\nFiber's global BodyLimit is set to 50 MiB — only /deploy/new and /stacks/new (multipart tarballs) and /webhooks/github/* (push payloads) approach that cap; JSON endpoints are bounded to sub-KB bodies by the per-handler shape. Oversized requests return 413 payload_too_large with the standard JSON ErrorResponse envelope (NOT the upstream nginx HTML 502 the older shape returned — T19 P1-2). The canonical 413 shape is documented under components.responses.PayloadTooLarge.\n\n## Security headers (applies to every response)\n\nEvery response from EVERY route — including liveness/readiness probes, OpenAPI document fetch, 4xx error envelopes, 5xx error envelopes, and 404/405 Fiber-default responses — carries the following defense-in-depth response headers, set by the SecurityHeaders middleware ahead of RequestID in the router middleware chain (task #311 wave-3 chaos-verify redo):\n\n- Strict-Transport-Security: max-age=63072000; includeSubDomains — production only (omitted on ENVIRONMENT=development so local http://localhost:8080 doesn't poison the host's HSTS cache). 2-year max-age, includeSubDomains for *.api.instanode.dev.\n- X-Content-Type-Options: nosniff — disables MIME sniffing.\n- X-Frame-Options: SAMEORIGIN — clickjacking defense.\n- Referrer-Policy: strict-origin-when-cross-origin — prevents URL-token leakage across origin downgrades.\n- Permissions-Policy: geolocation=(), microphone=(), camera=(), payment=() — denies powerful browser APIs.\n- Cross-Origin-Resource-Policy: same-origin — blocks no-cors cross-origin fetches.\n\nThese headers are not enumerated in each per-route responses block to keep the spec readable; they apply globally. Coverage test: TestSecurityHeaders_AllEndpoints_AllHeaders_Prod (internal/handlers/security_headers_test.go) iterates 5 representative endpoints (healthz, readyz, openapi.json, db/new, claim) and asserts all 6 headers land on every response.",
2570
-
"title": "InstaNode API",
2569
+
"description": "Zero-friction developer infrastructure built for AI coding agents (Claude Code, Cursor, MCP tool-use) and humans alike. Provision real Postgres + pgvector + Redis + MongoDB + NATS JetStream queues + S3-compatible object storage + webhook receivers — AND deploy your app on top of them — each with a single HTTP call. No account, no Docker, no setup. A free anonymous tier (24h TTL) lets an agent claim infrastructure the moment it hits a limit, with no signup. Also available as an MCP server, language SDKs, and a CLI for agent tool-use. The unit of value is the whole bundle: everything an agent needs to ship a working app, claimed and provisioned in one flow. Keywords: AI agent infrastructure, MCP, Postgres, pgvector / vector database, Redis cache, MongoDB, NATS queue, S3 object storage, webhooks, app deployment, free tier, single HTTP call, no signup.\n\n## Idempotency\n\nEvery POST endpoint that creates a resource is idempotent. Two layered protections cover every retry pattern:\n\n1. Explicit Idempotency-Key header (Stripe-shape, 24h TTL). Pass the same opaque key on each retry of a logical operation and the server replays the first response verbatim. Reusing a key with a different body returns 409.\n2. Body-fingerprint fallback (120s TTL). When the header is absent, the server synthesises a key from sha256(scope, route, canonical-body) and dedups identical retries inside a 120s window. Absorbs double-clicks, mobile double-taps, agent retries on transient 5xx, and reverse-proxy retries on network blips. Use the explicit header for true exactly-once across longer windows.\n\nEvery response from a create endpoint carries:\n- X-Idempotency-Source: explicit | fingerprint | miss — which dedup path matched (explicit = caller passed an Idempotency-Key; fingerprint = the body-fingerprint cache replayed; miss = handler ran fresh).\n- X-Idempotent-Replay: true — present only when the response was served from the cache (either path).\n\n## Rate limit (applies to every route)\n\nA global per-IP rate limit (100 req/min) is applied to EVERY documented endpoint by the router middleware. Exceeding it returns 429 with the standard ErrorResponse envelope (error=rate_limited), a Retry-After HTTP header, and retry_after_seconds in the JSON body. The per-route response maps below may omit 429 for brevity; the canonical 429 shape is documented under components.responses.TooManyRequests and applies to every path. T19 P1-1 (BugHunt 2026-05-20).\n\n## Payload size (applies to every route)\n\nFiber's global BodyLimit is set to 50 MiB — only /deploy/new and /stacks/new (multipart tarballs) and /webhooks/github/* (push payloads) approach that cap; JSON endpoints are bounded to sub-KB bodies by the per-handler shape. Oversized requests return 413 payload_too_large with the standard JSON ErrorResponse envelope (NOT the upstream nginx HTML 502 the older shape returned — T19 P1-2). The canonical 413 shape is documented under components.responses.PayloadTooLarge.\n\n## Security headers (applies to every response)\n\nEvery response from EVERY route — including liveness/readiness probes, OpenAPI document fetch, 4xx error envelopes, 5xx error envelopes, and 404/405 Fiber-default responses — carries the following defense-in-depth response headers, set by the SecurityHeaders middleware ahead of RequestID in the router middleware chain (task #311 wave-3 chaos-verify redo):\n\n- Strict-Transport-Security: max-age=63072000; includeSubDomains — production only (omitted on ENVIRONMENT=development so local http://localhost:8080 doesn't poison the host's HSTS cache). 2-year max-age, includeSubDomains for *.api.instanode.dev.\n- X-Content-Type-Options: nosniff — disables MIME sniffing.\n- X-Frame-Options: SAMEORIGIN — clickjacking defense.\n- Referrer-Policy: strict-origin-when-cross-origin — prevents URL-token leakage across origin downgrades.\n- Permissions-Policy: geolocation=(), microphone=(), camera=(), payment=() — denies powerful browser APIs.\n- Cross-Origin-Resource-Policy: same-origin — blocks no-cors cross-origin fetches.\n\nThese headers are not enumerated in each per-route responses block to keep the spec readable; they apply globally. Coverage test: TestSecurityHeaders_AllEndpoints_AllHeaders_Prod (internal/handlers/security_headers_test.go) iterates 5 representative endpoints (healthz, readyz, openapi.json, db/new, claim) and asserts all 6 headers land on every response.",
2570
+
"title": "instanode.dev — zero-friction dev infrastructure for AI agents",
2571
2571
"version": "1.0.0"
2572
2572
},
2573
2573
"openapi": "3.1.0",
@@ -10177,5 +10177,43 @@
10177
10177
"description": "Production",
10178
10178
"url": "https://api.instanode.dev"
10179
10179
}
10180
+
],
10181
+
"tags": [
10182
+
{
10183
+
"description": "Real Postgres connection strings via POST /db/new — encrypted at rest, per-token isolation, instant.",
10184
+
"name": "database"
10185
+
},
10186
+
{
10187
+
"description": "pgvector-enabled Postgres via POST /vector/new — embedding stores with HNSW + IVFFlat for AI/RAG workloads.",
10188
+
"name": "vector"
10189
+
},
10190
+
{
10191
+
"description": "Real Redis connection strings via POST /cache/new — ACL namespace isolation.",
10192
+
"name": "cache"
10193
+
},
10194
+
{
10195
+
"description": "Real MongoDB connection strings via POST /nosql/new — per-token database scoping.",
10196
+
"name": "nosql"
10197
+
},
10198
+
{
10199
+
"description": "NATS JetStream URLs via POST /queue/new — per-account subject isolation.",
10200
+
"name": "queue"
10201
+
},
10202
+
{
10203
+
"description": "S3-compatible object storage via POST /storage/new plus broker-mode signed URLs via POST /storage/{token}/presign.",
10204
+
"name": "storage"
10205
+
},
10206
+
{
10207
+
"description": "Public webhook receiver URLs via POST /webhook/new — captures any HTTP method payload.",
10208
+
"name": "webhook"
10209
+
},
10210
+
{
10211
+
"description": "The deployment wedge: ship an app via POST /deploy/new (single app) or POST /stacks/new (multi-service) — Docker build to public HTTPS URL with TLS, no Dockerfile-on-disk required.",
10212
+
"name": "deploy"
10213
+
},
10214
+
{
10215
+
"description": "Magic-link, GitHub OAuth, and CLI device-flow login — used to claim a free anonymous resource bundle.",
0 commit comments