{ "openapi": "3.1.0", "info": { "title": "glyph", "version": "0.1.0", "description": "Type a prompt, get SVG logos and icons drawn by Claude; preview in your theme, copy or download." }, "paths": { "/api/drawings": { "get": { "summary": "Your drawings, newest first (an admin sees everyone's).", "operationId": "getApiDrawings", "parameters": [ { "name": "limit", "in": "query", "schema": { "type": "integer", "minimum": 1, "maximum": 200, "default": 50 } } ], "responses": { "200": { "description": "Your drawings, newest first (an admin sees everyone's).", "content": { "application/json": { "schema": { "type": "array", "items": { "$ref": "#/components/schemas/Drawing" } } } } }, "default": { "description": "{ error, message }: why not", "content": { "application/json": { "schema": { "$ref": "#/components/schemas/Error" } } } } }, "x-contract": { "resource": "drawing", "verb": "list", "least": "author" } }, "post": { "summary": "Ask Claude for a drawing. Answers at once with status `drawing`; read it again (or listen on /events for `drawing.changed`) until it is `done` or `failed`. One at a time per person.", "operationId": "postApiDrawings", "requestBody": { "required": true, "content": { "application/json": { "schema": { "type": "object", "properties": { "prompt": { "type": "string", "minLength": 1, "maxLength": 400 }, "kind": { "enum": [ "mark", "icon", "badge", "spot" ], "default": "mark" } }, "required": [ "prompt" ] } } } }, "responses": { "202": { "description": "Ask Claude for a drawing. Answers at once with status `drawing`; read it again (or listen on /events for `drawing.changed`) until it is `done` or `failed`. One at a time per person.", "content": { "application/json": { "schema": { "$ref": "#/components/schemas/Drawing" } } } }, "default": { "description": "{ error, message }: why not", "content": { "application/json": { "schema": { "$ref": "#/components/schemas/Error" } } } } }, "x-contract": { "resource": "drawing", "verb": "create", "least": "user" } } }, "/api/drawings/{id}": { "get": { "summary": "One drawing.", "operationId": "getApiDrawingsId", "parameters": [ { "name": "id", "in": "path", "required": true, "schema": { "type": "integer" } } ], "responses": { "200": { "description": "One drawing.", "content": { "application/json": { "schema": { "$ref": "#/components/schemas/Drawing" } } } }, "default": { "description": "{ error, message }: why not", "content": { "application/json": { "schema": { "$ref": "#/components/schemas/Error" } } } } }, "x-contract": { "resource": "drawing", "verb": "read", "least": "author" } }, "delete": { "summary": "Remove a drawing.", "operationId": "deleteApiDrawingsId", "parameters": [ { "name": "id", "in": "path", "required": true, "schema": { "type": "integer" } } ], "responses": { "200": { "description": "Remove a drawing.", "content": { "application/json": { "schema": { "type": "object", "properties": { "id": { "type": "integer" } }, "required": [ "id" ] } } } }, "default": { "description": "{ error, message }: why not", "content": { "application/json": { "schema": { "$ref": "#/components/schemas/Error" } } } } }, "x-contract": { "resource": "drawing", "verb": "delete", "least": "author" } } }, "/api/audit": { "get": { "summary": "The audit trail, newest first; `before` pages back by id.", "operationId": "getApiAudit", "parameters": [ { "name": "limit", "in": "query", "schema": { "type": "integer", "minimum": 1, "maximum": 500, "default": 100 } }, { "name": "before", "in": "query", "schema": { "type": "integer" } } ], "responses": { "200": { "description": "The audit trail, newest first; `before` pages back by id.", "content": { "application/json": { "schema": { "type": "array", "items": { "$ref": "#/components/schemas/AuditRow" } } } } }, "default": { "description": "{ error, message }: why not", "content": { "application/json": { "schema": { "$ref": "#/components/schemas/Error" } } } } }, "x-contract": { "resource": "audit", "verb": "list", "least": "admin" } } }, "/api/audit/{id}": { "get": { "summary": "One row of the audit trail.", "operationId": "getApiAuditId", "parameters": [ { "name": "id", "in": "path", "required": true, "schema": { "type": "integer" } } ], "responses": { "200": { "description": "One row of the audit trail.", "content": { "application/json": { "schema": { "$ref": "#/components/schemas/AuditRow" } } } }, "default": { "description": "{ error, message }: why not", "content": { "application/json": { "schema": { "$ref": "#/components/schemas/Error" } } } } }, "x-contract": { "resource": "audit", "verb": "read", "least": "admin" } } }, "/mcp": { "post": { "summary": "One JSON-RPC 2.0 message to the MCP server; its tools are the actions.", "operationId": "postMcp", "requestBody": { "required": true, "content": { "application/json": { "schema": { "type": "object", "properties": { "jsonrpc": { "const": "2.0" }, "id": {}, "method": { "type": "string" }, "params": { "type": "object" } }, "required": [ "jsonrpc", "method" ] } } } }, "responses": { "200": { "description": "One JSON-RPC 2.0 message to the MCP server; its tools are the actions.", "content": { "application/json": { "schema": { "type": "object" } } } }, "default": { "description": "{ error, message }: why not", "content": { "application/json": { "schema": { "$ref": "#/components/schemas/Error" } } } } } } }, "/healthz": { "get": { "summary": "Whether the app is up: its version, commit, environment and seconds since it started.", "operationId": "getHealthz", "responses": { "200": { "description": "Whether the app is up: its version, commit, environment and seconds since it started.", "content": { "application/json": { "schema": { "type": "object", "properties": { "ok": { "type": "boolean" }, "version": { "type": "string" }, "commit": { "type": "string" }, "env": { "type": "string" }, "uptime": { "type": "integer" } }, "required": [ "ok", "version", "uptime" ] } } } }, "default": { "description": "{ error, message }: why not", "content": { "application/json": { "schema": { "$ref": "#/components/schemas/Error" } } } } } } } }, "components": { "schemas": { "Drawing": { "type": "object", "properties": { "id": { "type": "integer" }, "prompt": { "type": "string", "minLength": 1, "maxLength": 400 }, "kind": { "enum": [ "mark", "icon", "badge", "spot" ] }, "status": { "enum": [ "drawing", "done", "failed" ] }, "svgs": { "type": "array", "items": { "type": "string" }, "description": "The drawings, as SVG, in the placeholder ink and glow colours." }, "error": { "type": [ "string", "null" ] }, "author_id": { "type": "string" }, "author_name": { "type": "string" }, "created_at": { "type": "string", "format": "date-time" }, "updated_at": { "type": "string", "format": "date-time" } }, "required": [ "id", "prompt", "kind", "status", "svgs", "author_id", "author_name", "created_at", "updated_at" ] }, "AuditRow": { "type": "object", "properties": { "id": { "type": "integer" }, "at": { "type": "string", "format": "date-time" }, "who_id": { "type": [ "string", "null" ] }, "who_name": { "type": [ "string", "null" ] }, "role": { "enum": [ "anon", "user", "admin" ] }, "resource": { "type": "string" }, "verb": { "type": "string" }, "target": { "type": [ "string", "null" ] }, "allowed": { "enum": [ 0, 1 ] }, "outcome": { "type": "string" } }, "required": [ "id", "at", "role", "resource", "verb", "allowed", "outcome" ] }, "Error": { "type": "object", "properties": { "error": { "type": "string" }, "message": { "type": "string" } }, "required": [ "error" ] } } } }