{"openapi":"3.1.0","info":{"title":"Jilian Garette Abangan portfolio API","version":"1.0.0","description":"Read-only portfolio data and a first-person Q&A endpoint. No API key. Use it to vet Jilian for freelance or full-time work.","contact":{"name":"Jilian Garette Abangan","email":"jiliangarette@gmail.com","url":"https://2026.jilian.dev/developers"}},"servers":[{"url":"https://2026.jilian.dev"}],"externalDocs":{"url":"https://2026.jilian.dev/developers"},"components":{"securitySchemes":{"anonymousAgent":{"type":"http","scheme":"bearer","bearerFormat":"JWT","description":"Optional. Mint one at POST /api/agent/identity. Gives your agent its own chat rate limit."}}},"paths":{"/api/profile":{"get":{"operationId":"getProfile","summary":"Profile, availability and contact links","responses":{"200":{"description":"OK","content":{"application/json":{"schema":{"type":"object"}}}}}}},"/api/projects":{"get":{"operationId":"listProjects","summary":"Every project in the portfolio","responses":{"200":{"description":"OK","content":{"application/json":{"schema":{"type":"object","properties":{"projects":{"type":"array","items":{"type":"object","properties":{"slug":{"type":"string"},"title":{"type":"string"},"summary":{"type":"string"},"publishedAt":{"type":"string","format":"date"},"tech":{"type":"array","items":{"type":"string"}},"link":{"type":["string","null"]},"github":{"type":["string","null"]},"url":{"type":"string","format":"uri"}}}}}}}}}}}},"/api/projects/{slug}":{"get":{"operationId":"getProject","summary":"One project with its case study in Markdown","parameters":[{"name":"slug","in":"path","required":true,"schema":{"type":"string"}}],"responses":{"200":{"description":"OK","content":{"application/json":{"schema":{"allOf":[{"type":"object","properties":{"slug":{"type":"string"},"title":{"type":"string"},"summary":{"type":"string"},"publishedAt":{"type":"string","format":"date"},"tech":{"type":"array","items":{"type":"string"}},"link":{"type":["string","null"]},"github":{"type":["string","null"]},"url":{"type":"string","format":"uri"}}},{"type":"object","properties":{"markdown":{"type":"string"}}}]}}}},"404":{"description":"Unknown slug","content":{"application/json":{"schema":{"type":"object"}}}}}}},"/api/chat":{"post":{"operationId":"askJilian","summary":"Ask Jilian a question about his work","security":[{},{"anonymousAgent":[]}],"requestBody":{"required":true,"content":{"application/json":{"schema":{"type":"object","required":["messages"],"properties":{"messages":{"type":"array","maxItems":10,"items":{"type":"object","required":["role","content"],"properties":{"role":{"enum":["user","assistant"]},"content":{"type":"string","maxLength":1000}}}}}}}}},"responses":{"200":{"description":"OK","content":{"application/json":{"schema":{"type":"object","properties":{"reply":{"type":"string"},"cards":{"type":"array","items":{"type":"object"}},"chips":{"type":"array","items":{"type":"string"}},"contact":{"type":["object","null"]}}}}}},"429":{"description":"Rate limited. Retry after 60 seconds.","content":{"application/json":{"schema":{"type":"object"}}}}}}},"/api/agent/identity":{"post":{"operationId":"createAgentIdentity","summary":"Mint an anonymous agent token","requestBody":{"content":{"application/json":{"schema":{"type":"object","properties":{"type":{"enum":["anonymous"]}}}}}},"responses":{"200":{"description":"OK","content":{"application/json":{"schema":{"type":"object","properties":{"access_token":{"type":"string"},"token_type":{"const":"Bearer"},"expires_in":{"type":"integer"},"scope":{"type":"string"},"identity_type":{"const":"anonymous"}}}}}}}}}}}