{"openapi":"3.1.0","info":{"title":"Stampify Public Site API","version":"1.0.0","summary":"Read-only discovery API for the Stampify mobile app website.","description":"Official machine-readable interface for https://getstampify.app. Use it to fetch site identity, page catalogs, developer metadata, and sandbox credentials. It does not upload photos or mutate a user’s Stampify collection. Public GET access is the free tier. The self-serve sandbox key is `stampify-public`.","contact":{"name":"OtterSpark Labs","email":"support@otterspark.xyz","url":"https://getstampify.app/contact"},"license":{"name":"Public documentation","url":"https://getstampify.app/developers"}},"servers":[{"url":"https://getstampify.app","description":"Production"}],"tags":[{"name":"Public","description":"Unauthenticated or sandbox-scoped read operations."},{"name":"Auth","description":"Scoped sandbox credentials."}],"paths":{"/openapi.json":{"get":{"operationId":"getOpenApiJson","summary":"Download the OpenAPI document as JSON.","description":"Returns this specification so agents can bind function-calling tools to Stampify endpoints.","tags":["Public"],"security":[{"SandboxApiKey":["read:docs"]},{"OAuth2":["read:docs"]},{}],"responses":{"200":{"description":"Download the OpenAPI document as JSON.","headers":{"RateLimit":{"description":"RFC rate-limit snapshot: limit, remaining, reset.","schema":{"type":"string","examples":["limit=120, remaining=119, reset=60"]}},"RateLimit-Policy":{"description":"Declared policy window.","schema":{"type":"string","examples":["120;w=60"]}},"X-RateLimit-Limit":{"schema":{"type":"string"}},"X-RateLimit-Remaining":{"schema":{"type":"string"}},"X-RateLimit-Reset":{"schema":{"type":"string"}}},"content":{"application/json":{"schema":{"$ref":"#/components/schemas/OpenApiDocument"}}}},"401":{"description":"Structured JSON error with a code, message, and resolution hint.","headers":{"RateLimit":{"description":"RFC rate-limit snapshot: limit, remaining, reset.","schema":{"type":"string","examples":["limit=120, remaining=119, reset=60"]}},"RateLimit-Policy":{"description":"Declared policy window.","schema":{"type":"string","examples":["120;w=60"]}},"X-RateLimit-Limit":{"schema":{"type":"string"}},"X-RateLimit-Remaining":{"schema":{"type":"string"}},"X-RateLimit-Reset":{"schema":{"type":"string"}}},"content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"403":{"description":"Structured JSON error with a code, message, and resolution hint.","headers":{"RateLimit":{"description":"RFC rate-limit snapshot: limit, remaining, reset.","schema":{"type":"string","examples":["limit=120, remaining=119, reset=60"]}},"RateLimit-Policy":{"description":"Declared policy window.","schema":{"type":"string","examples":["120;w=60"]}},"X-RateLimit-Limit":{"schema":{"type":"string"}},"X-RateLimit-Remaining":{"schema":{"type":"string"}},"X-RateLimit-Reset":{"schema":{"type":"string"}}},"content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"404":{"description":"Structured JSON error with a code, message, and resolution hint.","headers":{"RateLimit":{"description":"RFC rate-limit snapshot: limit, remaining, reset.","schema":{"type":"string","examples":["limit=120, remaining=119, reset=60"]}},"RateLimit-Policy":{"description":"Declared policy window.","schema":{"type":"string","examples":["120;w=60"]}},"X-RateLimit-Limit":{"schema":{"type":"string"}},"X-RateLimit-Remaining":{"schema":{"type":"string"}},"X-RateLimit-Reset":{"schema":{"type":"string"}}},"content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"405":{"description":"Structured JSON error with a code, message, and resolution hint.","headers":{"RateLimit":{"description":"RFC rate-limit snapshot: limit, remaining, reset.","schema":{"type":"string","examples":["limit=120, remaining=119, reset=60"]}},"RateLimit-Policy":{"description":"Declared policy window.","schema":{"type":"string","examples":["120;w=60"]}},"X-RateLimit-Limit":{"schema":{"type":"string"}},"X-RateLimit-Remaining":{"schema":{"type":"string"}},"X-RateLimit-Reset":{"schema":{"type":"string"}}},"content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"429":{"description":"Structured JSON error with a code, message, and resolution hint.","headers":{"RateLimit":{"description":"RFC rate-limit snapshot: limit, remaining, reset.","schema":{"type":"string","examples":["limit=120, remaining=119, reset=60"]}},"RateLimit-Policy":{"description":"Declared policy window.","schema":{"type":"string","examples":["120;w=60"]}},"X-RateLimit-Limit":{"schema":{"type":"string"}},"X-RateLimit-Remaining":{"schema":{"type":"string"}},"X-RateLimit-Reset":{"schema":{"type":"string"}},"Retry-After":{"description":"Seconds to wait before retrying.","schema":{"type":"string"}}},"content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}}}}},"/api/openapi.yaml":{"get":{"operationId":"getOpenApiYaml","summary":"Download the OpenAPI document as YAML.","description":"Same contract as /openapi.json, serialized as YAML for clients that expect /api/openapi.yaml.","tags":["Public"],"security":[{"SandboxApiKey":["read:docs"]},{"OAuth2":["read:docs"]},{}],"responses":{"200":{"description":"Download the OpenAPI document as YAML.","headers":{"RateLimit":{"description":"RFC rate-limit snapshot: limit, remaining, reset.","schema":{"type":"string","examples":["limit=120, remaining=119, reset=60"]}},"RateLimit-Policy":{"description":"Declared policy window.","schema":{"type":"string","examples":["120;w=60"]}},"X-RateLimit-Limit":{"schema":{"type":"string"}},"X-RateLimit-Remaining":{"schema":{"type":"string"}},"X-RateLimit-Reset":{"schema":{"type":"string"}}},"content":{"application/json":{"schema":{"type":"object","additionalProperties":true}}}},"401":{"description":"Structured JSON error with a code, message, and resolution hint.","headers":{"RateLimit":{"description":"RFC rate-limit snapshot: limit, remaining, reset.","schema":{"type":"string","examples":["limit=120, remaining=119, reset=60"]}},"RateLimit-Policy":{"description":"Declared policy window.","schema":{"type":"string","examples":["120;w=60"]}},"X-RateLimit-Limit":{"schema":{"type":"string"}},"X-RateLimit-Remaining":{"schema":{"type":"string"}},"X-RateLimit-Reset":{"schema":{"type":"string"}}},"content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"403":{"description":"Structured JSON error with a code, message, and resolution hint.","headers":{"RateLimit":{"description":"RFC rate-limit snapshot: limit, remaining, reset.","schema":{"type":"string","examples":["limit=120, remaining=119, reset=60"]}},"RateLimit-Policy":{"description":"Declared policy window.","schema":{"type":"string","examples":["120;w=60"]}},"X-RateLimit-Limit":{"schema":{"type":"string"}},"X-RateLimit-Remaining":{"schema":{"type":"string"}},"X-RateLimit-Reset":{"schema":{"type":"string"}}},"content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"404":{"description":"Structured JSON error with a code, message, and resolution hint.","headers":{"RateLimit":{"description":"RFC rate-limit snapshot: limit, remaining, reset.","schema":{"type":"string","examples":["limit=120, remaining=119, reset=60"]}},"RateLimit-Policy":{"description":"Declared policy window.","schema":{"type":"string","examples":["120;w=60"]}},"X-RateLimit-Limit":{"schema":{"type":"string"}},"X-RateLimit-Remaining":{"schema":{"type":"string"}},"X-RateLimit-Reset":{"schema":{"type":"string"}}},"content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"405":{"description":"Structured JSON error with a code, message, and resolution hint.","headers":{"RateLimit":{"description":"RFC rate-limit snapshot: limit, remaining, reset.","schema":{"type":"string","examples":["limit=120, remaining=119, reset=60"]}},"RateLimit-Policy":{"description":"Declared policy window.","schema":{"type":"string","examples":["120;w=60"]}},"X-RateLimit-Limit":{"schema":{"type":"string"}},"X-RateLimit-Remaining":{"schema":{"type":"string"}},"X-RateLimit-Reset":{"schema":{"type":"string"}}},"content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"429":{"description":"Structured JSON error with a code, message, and resolution hint.","headers":{"RateLimit":{"description":"RFC rate-limit snapshot: limit, remaining, reset.","schema":{"type":"string","examples":["limit=120, remaining=119, reset=60"]}},"RateLimit-Policy":{"description":"Declared policy window.","schema":{"type":"string","examples":["120;w=60"]}},"X-RateLimit-Limit":{"schema":{"type":"string"}},"X-RateLimit-Remaining":{"schema":{"type":"string"}},"X-RateLimit-Reset":{"schema":{"type":"string"}},"Retry-After":{"description":"Seconds to wait before retrying.","schema":{"type":"string"}}},"content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}}}}},"/api/v1":{"get":{"operationId":"getApiIndex","summary":"List public API entry points.","description":"Returns the sandbox key policy, scopes, and links to OpenAPI, docs, and page catalogs.","tags":["Public"],"security":[{"SandboxApiKey":["read:docs"]},{"OAuth2":["read:docs"]},{}],"responses":{"200":{"description":"List public API entry points.","headers":{"RateLimit":{"description":"RFC rate-limit snapshot: limit, remaining, reset.","schema":{"type":"string","examples":["limit=120, remaining=119, reset=60"]}},"RateLimit-Policy":{"description":"Declared policy window.","schema":{"type":"string","examples":["120;w=60"]}},"X-RateLimit-Limit":{"schema":{"type":"string"}},"X-RateLimit-Remaining":{"schema":{"type":"string"}},"X-RateLimit-Reset":{"schema":{"type":"string"}}},"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ApiIndex"}}}},"401":{"description":"Structured JSON error with a code, message, and resolution hint.","headers":{"RateLimit":{"description":"RFC rate-limit snapshot: limit, remaining, reset.","schema":{"type":"string","examples":["limit=120, remaining=119, reset=60"]}},"RateLimit-Policy":{"description":"Declared policy window.","schema":{"type":"string","examples":["120;w=60"]}},"X-RateLimit-Limit":{"schema":{"type":"string"}},"X-RateLimit-Remaining":{"schema":{"type":"string"}},"X-RateLimit-Reset":{"schema":{"type":"string"}}},"content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"403":{"description":"Structured JSON error with a code, message, and resolution hint.","headers":{"RateLimit":{"description":"RFC rate-limit snapshot: limit, remaining, reset.","schema":{"type":"string","examples":["limit=120, remaining=119, reset=60"]}},"RateLimit-Policy":{"description":"Declared policy window.","schema":{"type":"string","examples":["120;w=60"]}},"X-RateLimit-Limit":{"schema":{"type":"string"}},"X-RateLimit-Remaining":{"schema":{"type":"string"}},"X-RateLimit-Reset":{"schema":{"type":"string"}}},"content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"404":{"description":"Structured JSON error with a code, message, and resolution hint.","headers":{"RateLimit":{"description":"RFC rate-limit snapshot: limit, remaining, reset.","schema":{"type":"string","examples":["limit=120, remaining=119, reset=60"]}},"RateLimit-Policy":{"description":"Declared policy window.","schema":{"type":"string","examples":["120;w=60"]}},"X-RateLimit-Limit":{"schema":{"type":"string"}},"X-RateLimit-Remaining":{"schema":{"type":"string"}},"X-RateLimit-Reset":{"schema":{"type":"string"}}},"content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"405":{"description":"Structured JSON error with a code, message, and resolution hint.","headers":{"RateLimit":{"description":"RFC rate-limit snapshot: limit, remaining, reset.","schema":{"type":"string","examples":["limit=120, remaining=119, reset=60"]}},"RateLimit-Policy":{"description":"Declared policy window.","schema":{"type":"string","examples":["120;w=60"]}},"X-RateLimit-Limit":{"schema":{"type":"string"}},"X-RateLimit-Remaining":{"schema":{"type":"string"}},"X-RateLimit-Reset":{"schema":{"type":"string"}}},"content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"429":{"description":"Structured JSON error with a code, message, and resolution hint.","headers":{"RateLimit":{"description":"RFC rate-limit snapshot: limit, remaining, reset.","schema":{"type":"string","examples":["limit=120, remaining=119, reset=60"]}},"RateLimit-Policy":{"description":"Declared policy window.","schema":{"type":"string","examples":["120;w=60"]}},"X-RateLimit-Limit":{"schema":{"type":"string"}},"X-RateLimit-Remaining":{"schema":{"type":"string"}},"X-RateLimit-Reset":{"schema":{"type":"string"}},"Retry-After":{"description":"Seconds to wait before retrying.","schema":{"type":"string"}}},"content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}}}}},"/api/v1/site":{"get":{"operationId":"getSiteIdentity","summary":"Get Stampify site identity.","description":"Returns canonical URLs, store listings, support contact, and when-to-use guidance for agents.","tags":["Public"],"security":[{"SandboxApiKey":["read:public"]},{"OAuth2":["read:public"]},{}],"responses":{"200":{"description":"Get Stampify site identity.","headers":{"RateLimit":{"description":"RFC rate-limit snapshot: limit, remaining, reset.","schema":{"type":"string","examples":["limit=120, remaining=119, reset=60"]}},"RateLimit-Policy":{"description":"Declared policy window.","schema":{"type":"string","examples":["120;w=60"]}},"X-RateLimit-Limit":{"schema":{"type":"string"}},"X-RateLimit-Remaining":{"schema":{"type":"string"}},"X-RateLimit-Reset":{"schema":{"type":"string"}}},"content":{"application/json":{"schema":{"$ref":"#/components/schemas/SiteIdentity"}}}},"401":{"description":"Structured JSON error with a code, message, and resolution hint.","headers":{"RateLimit":{"description":"RFC rate-limit snapshot: limit, remaining, reset.","schema":{"type":"string","examples":["limit=120, remaining=119, reset=60"]}},"RateLimit-Policy":{"description":"Declared policy window.","schema":{"type":"string","examples":["120;w=60"]}},"X-RateLimit-Limit":{"schema":{"type":"string"}},"X-RateLimit-Remaining":{"schema":{"type":"string"}},"X-RateLimit-Reset":{"schema":{"type":"string"}}},"content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"403":{"description":"Structured JSON error with a code, message, and resolution hint.","headers":{"RateLimit":{"description":"RFC rate-limit snapshot: limit, remaining, reset.","schema":{"type":"string","examples":["limit=120, remaining=119, reset=60"]}},"RateLimit-Policy":{"description":"Declared policy window.","schema":{"type":"string","examples":["120;w=60"]}},"X-RateLimit-Limit":{"schema":{"type":"string"}},"X-RateLimit-Remaining":{"schema":{"type":"string"}},"X-RateLimit-Reset":{"schema":{"type":"string"}}},"content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"404":{"description":"Structured JSON error with a code, message, and resolution hint.","headers":{"RateLimit":{"description":"RFC rate-limit snapshot: limit, remaining, reset.","schema":{"type":"string","examples":["limit=120, remaining=119, reset=60"]}},"RateLimit-Policy":{"description":"Declared policy window.","schema":{"type":"string","examples":["120;w=60"]}},"X-RateLimit-Limit":{"schema":{"type":"string"}},"X-RateLimit-Remaining":{"schema":{"type":"string"}},"X-RateLimit-Reset":{"schema":{"type":"string"}}},"content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"405":{"description":"Structured JSON error with a code, message, and resolution hint.","headers":{"RateLimit":{"description":"RFC rate-limit snapshot: limit, remaining, reset.","schema":{"type":"string","examples":["limit=120, remaining=119, reset=60"]}},"RateLimit-Policy":{"description":"Declared policy window.","schema":{"type":"string","examples":["120;w=60"]}},"X-RateLimit-Limit":{"schema":{"type":"string"}},"X-RateLimit-Remaining":{"schema":{"type":"string"}},"X-RateLimit-Reset":{"schema":{"type":"string"}}},"content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"429":{"description":"Structured JSON error with a code, message, and resolution hint.","headers":{"RateLimit":{"description":"RFC rate-limit snapshot: limit, remaining, reset.","schema":{"type":"string","examples":["limit=120, remaining=119, reset=60"]}},"RateLimit-Policy":{"description":"Declared policy window.","schema":{"type":"string","examples":["120;w=60"]}},"X-RateLimit-Limit":{"schema":{"type":"string"}},"X-RateLimit-Remaining":{"schema":{"type":"string"}},"X-RateLimit-Reset":{"schema":{"type":"string"}},"Retry-After":{"description":"Seconds to wait before retrying.","schema":{"type":"string"}}},"content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}}}}},"/api/v1/pages":{"get":{"operationId":"listPublicPages","summary":"List public pages.","description":"Lists official marketing, trust, and developer pages with stable IDs and URLs.","tags":["Public"],"security":[{"SandboxApiKey":["read:public"]},{"OAuth2":["read:public"]},{}],"responses":{"200":{"description":"List public pages.","headers":{"RateLimit":{"description":"RFC rate-limit snapshot: limit, remaining, reset.","schema":{"type":"string","examples":["limit=120, remaining=119, reset=60"]}},"RateLimit-Policy":{"description":"Declared policy window.","schema":{"type":"string","examples":["120;w=60"]}},"X-RateLimit-Limit":{"schema":{"type":"string"}},"X-RateLimit-Remaining":{"schema":{"type":"string"}},"X-RateLimit-Reset":{"schema":{"type":"string"}}},"content":{"application/json":{"schema":{"$ref":"#/components/schemas/PageList"}}}},"401":{"description":"Structured JSON error with a code, message, and resolution hint.","headers":{"RateLimit":{"description":"RFC rate-limit snapshot: limit, remaining, reset.","schema":{"type":"string","examples":["limit=120, remaining=119, reset=60"]}},"RateLimit-Policy":{"description":"Declared policy window.","schema":{"type":"string","examples":["120;w=60"]}},"X-RateLimit-Limit":{"schema":{"type":"string"}},"X-RateLimit-Remaining":{"schema":{"type":"string"}},"X-RateLimit-Reset":{"schema":{"type":"string"}}},"content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"403":{"description":"Structured JSON error with a code, message, and resolution hint.","headers":{"RateLimit":{"description":"RFC rate-limit snapshot: limit, remaining, reset.","schema":{"type":"string","examples":["limit=120, remaining=119, reset=60"]}},"RateLimit-Policy":{"description":"Declared policy window.","schema":{"type":"string","examples":["120;w=60"]}},"X-RateLimit-Limit":{"schema":{"type":"string"}},"X-RateLimit-Remaining":{"schema":{"type":"string"}},"X-RateLimit-Reset":{"schema":{"type":"string"}}},"content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"404":{"description":"Structured JSON error with a code, message, and resolution hint.","headers":{"RateLimit":{"description":"RFC rate-limit snapshot: limit, remaining, reset.","schema":{"type":"string","examples":["limit=120, remaining=119, reset=60"]}},"RateLimit-Policy":{"description":"Declared policy window.","schema":{"type":"string","examples":["120;w=60"]}},"X-RateLimit-Limit":{"schema":{"type":"string"}},"X-RateLimit-Remaining":{"schema":{"type":"string"}},"X-RateLimit-Reset":{"schema":{"type":"string"}}},"content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"405":{"description":"Structured JSON error with a code, message, and resolution hint.","headers":{"RateLimit":{"description":"RFC rate-limit snapshot: limit, remaining, reset.","schema":{"type":"string","examples":["limit=120, remaining=119, reset=60"]}},"RateLimit-Policy":{"description":"Declared policy window.","schema":{"type":"string","examples":["120;w=60"]}},"X-RateLimit-Limit":{"schema":{"type":"string"}},"X-RateLimit-Remaining":{"schema":{"type":"string"}},"X-RateLimit-Reset":{"schema":{"type":"string"}}},"content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"429":{"description":"Structured JSON error with a code, message, and resolution hint.","headers":{"RateLimit":{"description":"RFC rate-limit snapshot: limit, remaining, reset.","schema":{"type":"string","examples":["limit=120, remaining=119, reset=60"]}},"RateLimit-Policy":{"description":"Declared policy window.","schema":{"type":"string","examples":["120;w=60"]}},"X-RateLimit-Limit":{"schema":{"type":"string"}},"X-RateLimit-Remaining":{"schema":{"type":"string"}},"X-RateLimit-Reset":{"schema":{"type":"string"}},"Retry-After":{"description":"Seconds to wait before retrying.","schema":{"type":"string"}}},"content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}}},"parameters":[{"name":"locale","in":"query","required":false,"description":"Locale code such as en or vi.","schema":{"type":"string","default":"en"}}]}},"/api/v1/pages/{id}":{"get":{"operationId":"getPublicPage","summary":"Get one public page.","description":"Returns a single page record by id (home, about, contact, developers, support, privacy, terms, blog).","tags":["Public"],"security":[{"SandboxApiKey":["read:public"]},{"OAuth2":["read:public"]},{}],"responses":{"200":{"description":"Get one public page.","headers":{"RateLimit":{"description":"RFC rate-limit snapshot: limit, remaining, reset.","schema":{"type":"string","examples":["limit=120, remaining=119, reset=60"]}},"RateLimit-Policy":{"description":"Declared policy window.","schema":{"type":"string","examples":["120;w=60"]}},"X-RateLimit-Limit":{"schema":{"type":"string"}},"X-RateLimit-Remaining":{"schema":{"type":"string"}},"X-RateLimit-Reset":{"schema":{"type":"string"}}},"content":{"application/json":{"schema":{"$ref":"#/components/schemas/Page"}}}},"401":{"description":"Structured JSON error with a code, message, and resolution hint.","headers":{"RateLimit":{"description":"RFC rate-limit snapshot: limit, remaining, reset.","schema":{"type":"string","examples":["limit=120, remaining=119, reset=60"]}},"RateLimit-Policy":{"description":"Declared policy window.","schema":{"type":"string","examples":["120;w=60"]}},"X-RateLimit-Limit":{"schema":{"type":"string"}},"X-RateLimit-Remaining":{"schema":{"type":"string"}},"X-RateLimit-Reset":{"schema":{"type":"string"}}},"content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"403":{"description":"Structured JSON error with a code, message, and resolution hint.","headers":{"RateLimit":{"description":"RFC rate-limit snapshot: limit, remaining, reset.","schema":{"type":"string","examples":["limit=120, remaining=119, reset=60"]}},"RateLimit-Policy":{"description":"Declared policy window.","schema":{"type":"string","examples":["120;w=60"]}},"X-RateLimit-Limit":{"schema":{"type":"string"}},"X-RateLimit-Remaining":{"schema":{"type":"string"}},"X-RateLimit-Reset":{"schema":{"type":"string"}}},"content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"404":{"description":"Structured JSON error with a code, message, and resolution hint.","headers":{"RateLimit":{"description":"RFC rate-limit snapshot: limit, remaining, reset.","schema":{"type":"string","examples":["limit=120, remaining=119, reset=60"]}},"RateLimit-Policy":{"description":"Declared policy window.","schema":{"type":"string","examples":["120;w=60"]}},"X-RateLimit-Limit":{"schema":{"type":"string"}},"X-RateLimit-Remaining":{"schema":{"type":"string"}},"X-RateLimit-Reset":{"schema":{"type":"string"}}},"content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"405":{"description":"Structured JSON error with a code, message, and resolution hint.","headers":{"RateLimit":{"description":"RFC rate-limit snapshot: limit, remaining, reset.","schema":{"type":"string","examples":["limit=120, remaining=119, reset=60"]}},"RateLimit-Policy":{"description":"Declared policy window.","schema":{"type":"string","examples":["120;w=60"]}},"X-RateLimit-Limit":{"schema":{"type":"string"}},"X-RateLimit-Remaining":{"schema":{"type":"string"}},"X-RateLimit-Reset":{"schema":{"type":"string"}}},"content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"429":{"description":"Structured JSON error with a code, message, and resolution hint.","headers":{"RateLimit":{"description":"RFC rate-limit snapshot: limit, remaining, reset.","schema":{"type":"string","examples":["limit=120, remaining=119, reset=60"]}},"RateLimit-Policy":{"description":"Declared policy window.","schema":{"type":"string","examples":["120;w=60"]}},"X-RateLimit-Limit":{"schema":{"type":"string"}},"X-RateLimit-Remaining":{"schema":{"type":"string"}},"X-RateLimit-Reset":{"schema":{"type":"string"}},"Retry-After":{"description":"Seconds to wait before retrying.","schema":{"type":"string"}}},"content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}}},"parameters":[{"name":"id","in":"path","required":true,"description":"Public page identifier.","schema":{"type":"string","enum":["home","about","contact","developers","support","privacy","terms","blog"]}},{"name":"locale","in":"query","required":false,"description":"Locale code such as en or vi.","schema":{"type":"string","default":"en"}}]}},"/api/v1/scopes":{"get":{"operationId":"listApiScopes","summary":"List scoped permissions.","description":"Describes the sandbox scopes an agent can request. Public GET calls already include both scopes.","tags":["Public"],"security":[{"SandboxApiKey":["read:docs"]},{"OAuth2":["read:docs"]},{}],"responses":{"200":{"description":"List scoped permissions.","headers":{"RateLimit":{"description":"RFC rate-limit snapshot: limit, remaining, reset.","schema":{"type":"string","examples":["limit=120, remaining=119, reset=60"]}},"RateLimit-Policy":{"description":"Declared policy window.","schema":{"type":"string","examples":["120;w=60"]}},"X-RateLimit-Limit":{"schema":{"type":"string"}},"X-RateLimit-Remaining":{"schema":{"type":"string"}},"X-RateLimit-Reset":{"schema":{"type":"string"}}},"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ScopeList"}}}},"401":{"description":"Structured JSON error with a code, message, and resolution hint.","headers":{"RateLimit":{"description":"RFC rate-limit snapshot: limit, remaining, reset.","schema":{"type":"string","examples":["limit=120, remaining=119, reset=60"]}},"RateLimit-Policy":{"description":"Declared policy window.","schema":{"type":"string","examples":["120;w=60"]}},"X-RateLimit-Limit":{"schema":{"type":"string"}},"X-RateLimit-Remaining":{"schema":{"type":"string"}},"X-RateLimit-Reset":{"schema":{"type":"string"}}},"content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"403":{"description":"Structured JSON error with a code, message, and resolution hint.","headers":{"RateLimit":{"description":"RFC rate-limit snapshot: limit, remaining, reset.","schema":{"type":"string","examples":["limit=120, remaining=119, reset=60"]}},"RateLimit-Policy":{"description":"Declared policy window.","schema":{"type":"string","examples":["120;w=60"]}},"X-RateLimit-Limit":{"schema":{"type":"string"}},"X-RateLimit-Remaining":{"schema":{"type":"string"}},"X-RateLimit-Reset":{"schema":{"type":"string"}}},"content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"404":{"description":"Structured JSON error with a code, message, and resolution hint.","headers":{"RateLimit":{"description":"RFC rate-limit snapshot: limit, remaining, reset.","schema":{"type":"string","examples":["limit=120, remaining=119, reset=60"]}},"RateLimit-Policy":{"description":"Declared policy window.","schema":{"type":"string","examples":["120;w=60"]}},"X-RateLimit-Limit":{"schema":{"type":"string"}},"X-RateLimit-Remaining":{"schema":{"type":"string"}},"X-RateLimit-Reset":{"schema":{"type":"string"}}},"content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"405":{"description":"Structured JSON error with a code, message, and resolution hint.","headers":{"RateLimit":{"description":"RFC rate-limit snapshot: limit, remaining, reset.","schema":{"type":"string","examples":["limit=120, remaining=119, reset=60"]}},"RateLimit-Policy":{"description":"Declared policy window.","schema":{"type":"string","examples":["120;w=60"]}},"X-RateLimit-Limit":{"schema":{"type":"string"}},"X-RateLimit-Remaining":{"schema":{"type":"string"}},"X-RateLimit-Reset":{"schema":{"type":"string"}}},"content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"429":{"description":"Structured JSON error with a code, message, and resolution hint.","headers":{"RateLimit":{"description":"RFC rate-limit snapshot: limit, remaining, reset.","schema":{"type":"string","examples":["limit=120, remaining=119, reset=60"]}},"RateLimit-Policy":{"description":"Declared policy window.","schema":{"type":"string","examples":["120;w=60"]}},"X-RateLimit-Limit":{"schema":{"type":"string"}},"X-RateLimit-Remaining":{"schema":{"type":"string"}},"X-RateLimit-Reset":{"schema":{"type":"string"}},"Retry-After":{"description":"Seconds to wait before retrying.","schema":{"type":"string"}}},"content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}}}}},"/api/v1/health":{"get":{"operationId":"getApiHealth","summary":"Health check.","description":"Lightweight liveness document for the public API.","tags":["Public"],"security":[{"SandboxApiKey":["read:public"]},{"OAuth2":["read:public"]},{}],"responses":{"200":{"description":"Health check.","headers":{"RateLimit":{"description":"RFC rate-limit snapshot: limit, remaining, reset.","schema":{"type":"string","examples":["limit=120, remaining=119, reset=60"]}},"RateLimit-Policy":{"description":"Declared policy window.","schema":{"type":"string","examples":["120;w=60"]}},"X-RateLimit-Limit":{"schema":{"type":"string"}},"X-RateLimit-Remaining":{"schema":{"type":"string"}},"X-RateLimit-Reset":{"schema":{"type":"string"}}},"content":{"application/json":{"schema":{"$ref":"#/components/schemas/Health"}}}},"401":{"description":"Structured JSON error with a code, message, and resolution hint.","headers":{"RateLimit":{"description":"RFC rate-limit snapshot: limit, remaining, reset.","schema":{"type":"string","examples":["limit=120, remaining=119, reset=60"]}},"RateLimit-Policy":{"description":"Declared policy window.","schema":{"type":"string","examples":["120;w=60"]}},"X-RateLimit-Limit":{"schema":{"type":"string"}},"X-RateLimit-Remaining":{"schema":{"type":"string"}},"X-RateLimit-Reset":{"schema":{"type":"string"}}},"content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"403":{"description":"Structured JSON error with a code, message, and resolution hint.","headers":{"RateLimit":{"description":"RFC rate-limit snapshot: limit, remaining, reset.","schema":{"type":"string","examples":["limit=120, remaining=119, reset=60"]}},"RateLimit-Policy":{"description":"Declared policy window.","schema":{"type":"string","examples":["120;w=60"]}},"X-RateLimit-Limit":{"schema":{"type":"string"}},"X-RateLimit-Remaining":{"schema":{"type":"string"}},"X-RateLimit-Reset":{"schema":{"type":"string"}}},"content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"404":{"description":"Structured JSON error with a code, message, and resolution hint.","headers":{"RateLimit":{"description":"RFC rate-limit snapshot: limit, remaining, reset.","schema":{"type":"string","examples":["limit=120, remaining=119, reset=60"]}},"RateLimit-Policy":{"description":"Declared policy window.","schema":{"type":"string","examples":["120;w=60"]}},"X-RateLimit-Limit":{"schema":{"type":"string"}},"X-RateLimit-Remaining":{"schema":{"type":"string"}},"X-RateLimit-Reset":{"schema":{"type":"string"}}},"content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"405":{"description":"Structured JSON error with a code, message, and resolution hint.","headers":{"RateLimit":{"description":"RFC rate-limit snapshot: limit, remaining, reset.","schema":{"type":"string","examples":["limit=120, remaining=119, reset=60"]}},"RateLimit-Policy":{"description":"Declared policy window.","schema":{"type":"string","examples":["120;w=60"]}},"X-RateLimit-Limit":{"schema":{"type":"string"}},"X-RateLimit-Remaining":{"schema":{"type":"string"}},"X-RateLimit-Reset":{"schema":{"type":"string"}}},"content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"429":{"description":"Structured JSON error with a code, message, and resolution hint.","headers":{"RateLimit":{"description":"RFC rate-limit snapshot: limit, remaining, reset.","schema":{"type":"string","examples":["limit=120, remaining=119, reset=60"]}},"RateLimit-Policy":{"description":"Declared policy window.","schema":{"type":"string","examples":["120;w=60"]}},"X-RateLimit-Limit":{"schema":{"type":"string"}},"X-RateLimit-Remaining":{"schema":{"type":"string"}},"X-RateLimit-Reset":{"schema":{"type":"string"}},"Retry-After":{"description":"Seconds to wait before retrying.","schema":{"type":"string"}}},"content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}}}}},"/api/v1/oauth/token":{"post":{"operationId":"createSandboxToken","summary":"Mint a sandbox access token.","description":"OAuth 2.0 client-credentials endpoint for the public sandbox. Use client_id and client_secret `stampify-public`. No registration or paid plan is required.","tags":["Auth"],"security":[],"requestBody":{"required":true,"content":{"application/x-www-form-urlencoded":{"schema":{"$ref":"#/components/schemas/TokenRequest"}},"application/json":{"schema":{"$ref":"#/components/schemas/TokenRequest"}}}},"responses":{"200":{"description":"Sandbox token.","headers":{"RateLimit":{"description":"RFC rate-limit snapshot: limit, remaining, reset.","schema":{"type":"string","examples":["limit=120, remaining=119, reset=60"]}},"RateLimit-Policy":{"description":"Declared policy window.","schema":{"type":"string","examples":["120;w=60"]}},"X-RateLimit-Limit":{"schema":{"type":"string"}},"X-RateLimit-Remaining":{"schema":{"type":"string"}},"X-RateLimit-Reset":{"schema":{"type":"string"}}},"content":{"application/json":{"schema":{"$ref":"#/components/schemas/TokenResponse"}}}},"400":{"description":"Structured JSON error with a code, message, and resolution hint.","headers":{"RateLimit":{"description":"RFC rate-limit snapshot: limit, remaining, reset.","schema":{"type":"string","examples":["limit=120, remaining=119, reset=60"]}},"RateLimit-Policy":{"description":"Declared policy window.","schema":{"type":"string","examples":["120;w=60"]}},"X-RateLimit-Limit":{"schema":{"type":"string"}},"X-RateLimit-Remaining":{"schema":{"type":"string"}},"X-RateLimit-Reset":{"schema":{"type":"string"}}},"content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"401":{"description":"Structured JSON error with a code, message, and resolution hint.","headers":{"RateLimit":{"description":"RFC rate-limit snapshot: limit, remaining, reset.","schema":{"type":"string","examples":["limit=120, remaining=119, reset=60"]}},"RateLimit-Policy":{"description":"Declared policy window.","schema":{"type":"string","examples":["120;w=60"]}},"X-RateLimit-Limit":{"schema":{"type":"string"}},"X-RateLimit-Remaining":{"schema":{"type":"string"}},"X-RateLimit-Reset":{"schema":{"type":"string"}}},"content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"429":{"description":"Structured JSON error with a code, message, and resolution hint.","headers":{"RateLimit":{"description":"RFC rate-limit snapshot: limit, remaining, reset.","schema":{"type":"string","examples":["limit=120, remaining=119, reset=60"]}},"RateLimit-Policy":{"description":"Declared policy window.","schema":{"type":"string","examples":["120;w=60"]}},"X-RateLimit-Limit":{"schema":{"type":"string"}},"X-RateLimit-Remaining":{"schema":{"type":"string"}},"X-RateLimit-Reset":{"schema":{"type":"string"}}},"content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}}}}}},"components":{"securitySchemes":{"SandboxApiKey":{"type":"apiKey","in":"header","name":"X-API-Key","description":"Optional. Omit for anonymous public reads, or send `stampify-public` for the documented sandbox scopes."},"OAuth2":{"type":"oauth2","description":"Sandbox client-credentials flow. There is no confidential production API.","flows":{"clientCredentials":{"tokenUrl":"https://getstampify.app/api/v1/oauth/token","scopes":{"read:public":"Read public Stampify site content, catalogs, and health.","read:docs":"Read OpenAPI, authentication metadata, and developer documentation."}}}}},"schemas":{"Error":{"type":"object","required":["error"],"properties":{"error":{"type":"object","required":["code","message","hint","status","docs"],"properties":{"code":{"type":"string","examples":["not_found"]},"message":{"type":"string"},"hint":{"type":"string"},"status":{"type":"integer"},"docs":{"type":"string","format":"uri"}}}}},"OpenApiDocument":{"type":"object","additionalProperties":true},"ApiIndex":{"type":"object","required":["name","documentation","openapi","sandbox","scopes"],"properties":{"name":{"type":"string"},"documentation":{"type":"string","format":"uri"},"openapi":{"type":"string","format":"uri"},"sandbox":{"type":"object","additionalProperties":true},"scopes":{"type":"object","additionalProperties":{"type":"string"}}}},"SiteIdentity":{"type":"object","required":["name","url","whenToUse","contact"],"properties":{"name":{"type":"string"},"url":{"type":"string","format":"uri"},"whenToUse":{"type":"string"},"contact":{"type":"string"}}},"Page":{"type":"object","required":["id","title","url","path","markdown"],"properties":{"id":{"type":"string"},"title":{"type":"string"},"url":{"type":"string","format":"uri"},"path":{"type":"string"},"markdown":{"type":"boolean"},"accept":{"type":"string"}}},"PageList":{"type":"object","required":["pages"],"properties":{"pages":{"type":"array","items":{"$ref":"#/components/schemas/Page"}}}},"ScopeList":{"type":"object","required":["scopes","sandboxKey"],"properties":{"sandboxKey":{"type":"string"},"scopes":{"type":"object","additionalProperties":{"type":"string"}}}},"Health":{"type":"object","required":["ok","service"],"properties":{"ok":{"type":"boolean"},"service":{"type":"string"}}},"TokenRequest":{"type":"object","required":["grant_type","client_id","client_secret"],"properties":{"grant_type":{"type":"string","enum":["client_credentials"]},"client_id":{"type":"string","examples":["stampify-public"]},"client_secret":{"type":"string","examples":["stampify-public"]},"scope":{"type":"string","examples":["read:public read:docs"]}}},"TokenResponse":{"type":"object","required":["access_token","token_type","expires_in","scope"],"properties":{"access_token":{"type":"string"},"token_type":{"type":"string"},"expires_in":{"type":"integer"},"scope":{"type":"string"}}}}}}