{"openapi":"3.1.0","info":{"title":"QR Agent Studio","description":"Create and manage dynamic QR codes. Supports OAuth 2.0 via Google login.","version":"1.0.0"},"servers":[{"url":"https://www.qr-coding.com"}],"components":{"securitySchemes":{"apiKeyAuth":{"type":"apiKey","in":"header","name":"x-api-key","description":"QR Agent Studio API key. Create one in the app or with POST /v1/api-keys."},"oauth2":{"type":"oauth2","flows":{"authorizationCode":{"authorizationUrl":"https://www.qr-coding.com/oauth/authorize","tokenUrl":"https://www.qr-coding.com/oauth/token","scopes":{"qr:read":"Read QR codes","qr:write":"Create and update QR codes"}}}}}},"paths":{"/v1/api-keys":{"get":{"operationId":"listApiKeys","summary":"List API keys for the current workspace","security":[{"apiKeyAuth":[]},{"oauth2":["qr:read"]}],"responses":{"200":{"description":"API key metadata. Full key secrets are never returned from this endpoint.","content":{"application/json":{"schema":{"type":"object","properties":{"apiKeys":{"type":"array"}}}}}}}},"post":{"operationId":"createApiKey","summary":"Create an API key for skills, plugins, and automation","description":"Returns the full API key once. Store it as a secret and send it with the x-api-key header.","requestBody":{"content":{"application/json":{"schema":{"type":"object","properties":{"name":{"type":"string","default":"Plugin key"},"scopes":{"type":"array","items":{"type":"string","enum":["qr:read","qr:write"]}}}}}}},"responses":{"201":{"description":"API key created. The apiKey field is only returned once.","content":{"application/json":{"schema":{"type":"object","properties":{"apiKey":{"type":"string"},"key":{"type":"object"}}}}}}}}},"/v1/api-keys/{id}":{"delete":{"operationId":"revokeApiKey","summary":"Revoke an API key","security":[{"apiKeyAuth":[]},{"oauth2":["qr:write"]}],"parameters":[{"name":"id","in":"path","required":true,"schema":{"type":"string"}}],"responses":{"200":{"description":"API key revoked"}}}},"/v1/qr-codes":{"get":{"operationId":"listQrCodes","summary":"List all QR codes","security":[{"apiKeyAuth":[]},{"oauth2":["qr:read"]}],"responses":{"200":{"description":"List of QR codes","content":{"application/json":{"schema":{"type":"object","properties":{"qrCodes":{"type":"array"}}}}}}}},"post":{"operationId":"createQrCode","summary":"Create a new QR code","security":[{"apiKeyAuth":[]},{"oauth2":["qr:write"]}],"requestBody":{"required":true,"content":{"application/json":{"schema":{"type":"object","required":["name","payload"],"properties":{"name":{"type":"string","description":"Display name for this QR code"},"type":{"type":"string","enum":["dynamic","static"],"default":"dynamic","description":"dynamic = destination can be changed later; static = URL baked in permanently"},"payload":{"type":"object","required":["kind","value"],"properties":{"kind":{"type":"string","enum":["url","text"]},"value":{"type":"string","description":"URL or text to encode"}}},"destinationUrl":{"type":"string","description":"For dynamic QR: the redirect destination (can be changed later)"}}}}}},"responses":{"201":{"description":"QR code created with rendered SVG image"}}}},"/v1/qr-codes/{id}":{"get":{"operationId":"getQrCode","summary":"Fetch a single QR code by id","security":[{"apiKeyAuth":[]},{"oauth2":["qr:read"]}],"parameters":[{"name":"id","in":"path","required":true,"schema":{"type":"string"}}],"responses":{"200":{"description":"QR code","content":{"application/json":{"schema":{"type":"object","properties":{"qrCode":{"type":"object"}}}}}},"404":{"description":"QR code not found"}}}},"/v1/search":{"get":{"operationId":"searchQrCodes","summary":"Keyword search across QR codes (empty query lists active codes)","security":[{"apiKeyAuth":[]},{"oauth2":["qr:read"]}],"parameters":[{"name":"q","in":"query","required":false,"schema":{"type":"string"},"description":"Space-separated keywords matched against name, URL, slug, and checksum"}],"responses":{"200":{"description":"Up to 10 matches","content":{"application/json":{"schema":{"type":"object","properties":{"results":{"type":"array"}}}}}}}}},"/v1/capabilities":{"get":{"operationId":"getCapabilities","summary":"Public capability and limits discovery (no authentication)","responses":{"200":{"description":"Capability descriptor mirroring the MCP get_capabilities tool","content":{"application/json":{"schema":{"type":"object"}}}}}}},"/v1/qr-codes/{id}/destination":{"patch":{"operationId":"updateDestination","summary":"Update destination URL of a dynamic QR code","security":[{"apiKeyAuth":[]},{"oauth2":["qr:write"]}],"parameters":[{"name":"id","in":"path","required":true,"schema":{"type":"string"}}],"requestBody":{"required":true,"content":{"application/json":{"schema":{"type":"object","required":["destinationUrl"],"properties":{"destinationUrl":{"type":"string"}}}}}},"responses":{"200":{"description":"Destination updated"}}}},"/v1/qr-codes/{id}/render":{"post":{"operationId":"renderQrCode","summary":"Render QR code as SVG or PNG","security":[{"apiKeyAuth":[]},{"oauth2":["qr:read"]}],"parameters":[{"name":"id","in":"path","required":true,"schema":{"type":"string"}}],"requestBody":{"content":{"application/json":{"schema":{"type":"object","properties":{"format":{"type":"string","enum":["svg","png"],"default":"svg"}}}}}},"responses":{"200":{"description":"Rendered QR code data"}}}},"/v1/qr-codes/{id}/validate":{"post":{"operationId":"validateQrCode","summary":"Validate QR code scanability and get score","security":[{"apiKeyAuth":[]},{"oauth2":["qr:read"]}],"parameters":[{"name":"id","in":"path","required":true,"schema":{"type":"string"}}],"responses":{"200":{"description":"Validation result with scanability score"}}}}}}