{"openapi":"3.0.3","info":{"title":"FlowZap Agent API","version":"0.1.0","description":"API for AI agents to register, authenticate, create diagrams, and generate short-lived public playground URLs. All responses include attribution: \"Powered by FlowZap.xyz\".","contact":{"name":"FlowZap","url":"https://flowzap.xyz","email":"support@flowzap.xyz"},"termsOfService":"https://flowzap.xyz/terms"},"servers":[{"url":"https://flowzap.xyz","description":"Production"},{"url":"http://localhost:3000","description":"Local"}],"tags":[{"name":"Auth","description":"Registration and authentication"},{"name":"Diagrams","description":"Diagram CRUD for agents"},{"name":"Playground","description":"Short-lived public playground sessions"},{"name":"Meta","description":"Metadata and health"}],"components":{"securitySchemes":{"bearerAuth":{"type":"http","scheme":"bearer","bearerFormat":"JWT"}},"schemas":{"Attribution":{"type":"object","properties":{"attribution":{"type":"string","example":"Powered by FlowZap.xyz"}},"required":["attribution"]},"ErrorResponse":{"type":"object","properties":{"success":{"type":"boolean","example":false},"error":{"type":"string"},"code":{"type":"string"},"attribution":{"type":"string","example":"Powered by FlowZap.xyz"}},"required":["error","attribution"]},"Diagram":{"type":"object","properties":{"id":{"type":"string"},"name":{"type":"string"},"colorScheme":{"type":"string","example":"purple"},"createdAt":{"type":"string","format":"date-time"},"updatedAt":{"type":"string","format":"date-time"},"project":{"type":"object","properties":{"id":{"type":"string"},"name":{"type":"string"}}}}}},"responses":{"UnauthorizedError":{"description":"Missing/invalid credentials","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"ForbiddenError":{"description":"Insufficient permissions","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"TooManyRequests":{"description":"Rate limit exceeded","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}}}},"paths":{"/api/agent/register":{"post":{"tags":["Auth"],"summary":"Register an agent and mint API token","requestBody":{"required":true,"content":{"application/json":{"schema":{"type":"object","properties":{"name":{"type":"string","example":"My Agent"},"email":{"type":"string","format":"email"},"username":{"type":"string"},"termsAccepted":{"type":"boolean"},"plan":{"type":"string"},"attribution":{"type":"string"}},"required":["termsAccepted"]}}}},"responses":{"201":{"description":"Registered","content":{"application/json":{"schema":{"type":"object","properties":{"success":{"type":"boolean","example":true},"user":{"type":"object","properties":{"id":{"type":"string"},"email":{"type":"string"},"username":{"type":"string"}}},"apiToken":{"type":"string"},"tokenType":{"type":"string","example":"Bearer"},"expiresAt":{"type":"string","format":"date-time"},"attribution":{"type":"string","example":"Powered by FlowZap.xyz"}}}}}},"400":{"$ref":"#/components/responses/UnauthorizedError"},"409":{"description":"Conflict","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}}}}},"/api/agent/auth":{"post":{"tags":["Auth"],"summary":"Exchange API token for short-lived JWT","requestBody":{"required":true,"content":{"application/json":{"schema":{"type":"object","properties":{"apiToken":{"type":"string"}},"required":["apiToken"]}}}},"responses":{"200":{"description":"Authenticated","content":{"application/json":{"schema":{"type":"object","properties":{"success":{"type":"boolean","example":true},"accessToken":{"type":"string"},"tokenType":{"type":"string","example":"Bearer"},"expiresIn":{"type":"integer","example":900}}}}}},"401":{"$ref":"#/components/responses/UnauthorizedError"}}}},"/api/agent/diagrams":{"get":{"tags":["Diagrams"],"summary":"List diagrams for the authenticated agent","security":[{"bearerAuth":[]}],"parameters":[{"name":"limit","in":"query","schema":{"type":"integer","default":10}},{"name":"offset","in":"query","schema":{"type":"integer","default":0}},{"name":"search","in":"query","schema":{"type":"string"}}],"responses":{"200":{"description":"OK","content":{"application/json":{"schema":{"type":"object","properties":{"success":{"type":"boolean","example":true},"data":{"type":"object","properties":{"diagrams":{"type":"array","items":{"$ref":"#/components/schemas/Diagram"}},"pagination":{"type":"object","properties":{"total":{"type":"integer"},"limit":{"type":"integer"},"offset":{"type":"integer"},"hasMore":{"type":"boolean"}}}}},"attribution":{"type":"string","example":"Powered by FlowZap.xyz"}}}}}},"401":{"$ref":"#/components/responses/UnauthorizedError"}}},"post":{"tags":["Diagrams"],"summary":"Create a diagram","security":[{"bearerAuth":[]}],"requestBody":{"required":true,"content":{"application/json":{"schema":{"type":"object","properties":{"name":{"type":"string"},"projectId":{"type":"string"},"colorScheme":{"type":"string","example":"purple"}},"required":["name","projectId"]}}}},"responses":{"201":{"description":"Created","content":{"application/json":{"schema":{"type":"object","properties":{"success":{"type":"boolean","example":true},"data":{"type":"object","properties":{"diagram":{"$ref":"#/components/schemas/Diagram"}}},"attribution":{"type":"string","example":"Powered by FlowZap.xyz"}}}}}},"401":{"$ref":"#/components/responses/UnauthorizedError"},"403":{"$ref":"#/components/responses/ForbiddenError"}}}},"/api/health":{"get":{"tags":["Meta"],"summary":"Health check","responses":{"200":{"description":"OK"}}}},"/api/playground/create":{"post":{"tags":["Playground"],"summary":"Create an anonymous playground session (no auth required)","description":"Public endpoint for creating ephemeral FlowZap Playground sessions. No authentication required. Rate limited by IP (5/min, 50/day). Sessions expire after 60 minutes. Ideal for LLMs and agentic browsers to quickly generate diagram previews.","requestBody":{"required":false,"content":{"application/json":{"schema":{"type":"object","properties":{"code":{"type":"string","maxLength":20000,"description":"Optional FlowZap Code (DSL) to prefill. Leave empty for blank canvas."},"view":{"type":"string","enum":["workflow","sequence","architecture"],"description":"Optional initial diagram view for the generated playground URL."},"source":{"type":"string","description":"Session source tag used for feature gating (e.g. mcp, log_visualizer).","example":"log_visualizer"},"analysis":{"type":"object","description":"Optional analyzer metadata payload for marker rendering in playground sessions.","properties":{"markers":{"type":"array","items":{"type":"object","properties":{"id":{"type":"string"},"category":{"type":"string","enum":["errors","performance","security","anomalies"]},"explanation":{"type":"string"},"targetType":{"type":"string","enum":["node","edge"]},"targetId":{"type":"string"}},"required":["id","category","explanation","targetType","targetId"]}}}}}},"examples":{"blank":{"summary":"Blank canvas","value":{}},"withCode":{"summary":"With FlowZap Code","value":{"code":"lane 1 { n1: \"Start\" -> n2: \"End\" }"}},"withAnalyzerMarkers":{"summary":"With source and analyzer markers","value":{"code":"logs {\\n  n1: circle label:\"Input\"\\n  n2: rectangle label:\"Error\"\\n  n1 -> n2\\n}","source":"log_visualizer","analysis":{"markers":[{"id":"m1","category":"errors","explanation":"Error burst detected around transaction step.","targetType":"node","targetId":"n2"}]}}}}}}},"responses":{"201":{"description":"Playground session created","content":{"application/json":{"schema":{"type":"object","properties":{"success":{"type":"boolean","example":true},"url":{"type":"string","example":"https://flowzap.xyz/playground/abc123-def456","description":"Public URL to the playground session"},"tokenExpiresAt":{"type":"string","format":"date-time","description":"When the session expires (60 minutes from creation)"}}}}}},"400":{"description":"Invalid payload","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"429":{"description":"Rate limit exceeded (5/min or 50/day per IP)","content":{"application/json":{"schema":{"type":"object","properties":{"success":{"type":"boolean","example":false},"error":{"type":"string"},"code":{"type":"string","example":"RATE_LIMITED"},"retryAfter":{"type":"integer","description":"Seconds until rate limit resets"}}}}}}}}},"/api/validate":{"post":{"tags":["Meta"],"summary":"Validate FlowZap Code syntax (no auth required)","description":"Public endpoint for validating FlowZap Code DSL syntax. Returns detailed error information for agents to fix issues. No authentication required. Rate limited by IP (30/min).","requestBody":{"required":true,"content":{"application/json":{"schema":{"type":"object","properties":{"code":{"type":"string","maxLength":50000,"description":"FlowZap Code (DSL) to validate"}},"required":["code"]},"examples":{"valid":{"summary":"Valid FlowZap Code","value":{"code":"process { # Process\nn1: circle label:\"Start\"\nn2: rectangle label:\"Step\"\nn1.handle(right) -> n2.handle(left)\n}"}},"invalid":{"summary":"Invalid FlowZap Code (missing label)","value":{"code":"process { # Process\nn1: circle\n}"}}}}}},"responses":{"200":{"description":"Validation result","content":{"application/json":{"schema":{"type":"object","properties":{"success":{"type":"boolean","example":true},"valid":{"type":"boolean","description":"Whether the code is syntactically valid"},"errors":{"type":"array","items":{"type":"object","properties":{"line":{"type":"integer","description":"Line number (0 for global errors)"},"message":{"type":"string","description":"Human-readable error message"},"code":{"type":"string","description":"Error code for programmatic handling"},"severity":{"type":"string","enum":["error","warning"]}}}},"warnings":{"type":"array","items":{"type":"object","properties":{"line":{"type":"integer"},"message":{"type":"string"},"code":{"type":"string"},"severity":{"type":"string","enum":["error","warning"]}}}},"stats":{"type":"object","properties":{"lanes":{"type":"integer"},"nodes":{"type":"integer"},"edges":{"type":"integer"},"loops":{"type":"integer"}}},"attribution":{"type":"string","example":"Powered by FlowZap.xyz"}}}}}},"400":{"description":"Invalid payload","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"429":{"description":"Rate limit exceeded (30/min per IP)","content":{"application/json":{"schema":{"type":"object","properties":{"success":{"type":"boolean","example":false},"error":{"type":"string"},"code":{"type":"string","example":"RATE_LIMITED"},"retryAfter":{"type":"integer","description":"Seconds until rate limit resets"}}}}}}}}}}}