{"openapi":"3.1.0","info":{"title":"Hitoashi Task API","version":"1"},"servers":[{"url":"https://hitoashi.hageatama.org"}],"components":{"securitySchemes":{"BearerAuth":{"type":"http","scheme":"bearer","bearerFormat":"agent-key"}},"schemas":{"TaskStep":{"type":"object","additionalProperties":false,"required":["id","text","done"],"properties":{"id":{"type":"string","format":"uuid"},"text":{"type":"string","minLength":1,"maxLength":120},"done":{"type":"boolean"}}},"Task":{"type":"object","additionalProperties":false,"description":"An AI completion report is a review signal, not a completed task. Rewards are granted only after a human explicitly sets completed=true.","required":["id","title","step","tag","priority","list","dueDate","steps","createdAt","updatedAt","completedAt","deletedAt","version","startedRewardAt","completedRewardAt","createdByAi"],"properties":{"id":{"type":"string","format":"uuid"},"title":{"type":"string","minLength":1,"maxLength":120},"step":{"type":"string","minLength":1,"maxLength":240,"description":"Short supplemental note shown below the task title: context, details, or the next action."},"tag":{"type":"string","maxLength":40},"priority":{"type":"integer","minimum":0,"maximum":2},"list":{"type":"string","enum":["today","later"],"description":"Legacy grouping for existing clients and backups. Both values appear together in the active UI. New clients should omit this field on writes."},"dueDate":{"type":["string","null"],"format":"date"},"steps":{"type":"array","maxItems":5,"description":"Small actions within this existing task. Preserve existing step IDs and completion flags when subdividing.","items":{"$ref":"#/components/schemas/TaskStep"}},"createdAt":{"type":"integer","minimum":0},"updatedAt":{"type":"integer","minimum":0},"completedAt":{"type":["integer","null"],"minimum":0},"deletedAt":{"type":["integer","null"],"minimum":0},"startedRewardAt":{"type":["integer","null"],"minimum":0,"readOnly":true},"completedRewardAt":{"type":["integer","null"],"minimum":0,"readOnly":true},"completionReport":{"oneOf":[{"type":"null"},{"type":"object","additionalProperties":false,"required":["reason","reportedAt"],"properties":{"reason":{"type":"string","minLength":1,"maxLength":240},"reportedAt":{"type":"integer","minimum":0}}}],"readOnly":true,"description":"AI-origin review only; it does not mean the task is completed."},"createdByAi":{"type":"boolean","readOnly":true,"description":"Whether the task was created through the bearer AI-agent surface."},"version":{"type":"integer","minimum":1}}},"CreateTask":{"type":"object","additionalProperties":false,"required":["requestId","title"],"properties":{"requestId":{"type":"string","format":"uuid"},"title":{"type":"string","minLength":1,"maxLength":120},"step":{"type":"string","minLength":1,"maxLength":240,"description":"Short supplemental note shown below the task title: context, details, or the next action."},"tag":{"type":"string","maxLength":40},"priority":{"type":"integer","minimum":0,"maximum":2},"list":{"type":"string","enum":["today","later"],"description":"Legacy grouping; current UI combines all active tasks. Omit on new writes."},"dueDate":{"type":["string","null"],"format":"date"},"steps":{"type":"array","maxItems":5,"description":"Small actions within this existing task. Preserve existing step IDs and completion flags when subdividing.","items":{"$ref":"#/components/schemas/TaskStep"}}}},"PatchTask":{"type":"object","additionalProperties":false,"required":["expectedVersion"],"properties":{"title":{"type":"string","minLength":1,"maxLength":120},"step":{"type":"string","minLength":1,"maxLength":240,"description":"Short supplemental note shown below the task title: context, details, or the next action."},"tag":{"type":"string","maxLength":40},"priority":{"type":"integer","minimum":0,"maximum":2},"list":{"type":"string","enum":["today","later"],"description":"Legacy grouping; current UI combines all active tasks. Omit on new writes."},"dueDate":{"type":["string","null"],"format":"date"},"steps":{"type":"array","maxItems":5,"description":"Small actions within this existing task. Preserve existing step IDs and completion flags when subdividing.","items":{"$ref":"#/components/schemas/TaskStep"}},"expectedVersion":{"type":"integer","minimum":1},"completed":{"type":"boolean"},"started":{"type":"boolean","const":true},"completionReport":{"oneOf":[{"type":"null"},{"type":"object","additionalProperties":false,"required":["reason"],"properties":{"reason":{"type":"string","minLength":1,"maxLength":240}}}],"description":"Set a non-null AI review reason on an active uncompleted task. Set null to reject it; explicit completed=true or completed=false clears obsolete reports."}}},"ShoppingItem":{"type":"object","additionalProperties":false,"description":"A shopping item is separate from tasks. Shopping changes never affect reward points, levels, activity days, or unlocks.","required":["id","title","urgency","createdAt","updatedAt","completedAt","deletedAt","version"],"properties":{"id":{"type":"string","format":"uuid"},"title":{"type":"string","minLength":1,"maxLength":120},"urgency":{"type":"string","enum":["urgent","normal"]},"createdAt":{"type":"integer","minimum":0},"updatedAt":{"type":"integer","minimum":0},"completedAt":{"type":["integer","null"],"minimum":0},"deletedAt":{"type":["integer","null"],"minimum":0},"version":{"type":"integer","minimum":1}}},"CreateShoppingItem":{"type":"object","additionalProperties":false,"required":["requestId","title"],"properties":{"requestId":{"type":"string","format":"uuid"},"title":{"type":"string","minLength":1,"maxLength":120},"urgency":{"type":"string","enum":["urgent","normal"],"default":"normal"}}},"PatchShoppingItem":{"type":"object","additionalProperties":false,"required":["expectedVersion"],"properties":{"expectedVersion":{"type":"integer","minimum":1},"title":{"type":"string","minLength":1,"maxLength":120},"urgency":{"type":"string","enum":["urgent","normal"]},"completed":{"type":"boolean"}}},"RestoreShoppingItem":{"type":"object","additionalProperties":false,"required":["expectedVersion"],"properties":{"expectedVersion":{"type":"integer","minimum":1}}},"RestoreTask":{"type":"object","additionalProperties":false,"required":["expectedVersion"],"properties":{"expectedVersion":{"type":"integer","minimum":1}}}}},"paths":{"/api/v1/tasks":{"get":{"operationId":"listTasks","summary":"List tasks","description":"Use status=review to list active tasks with an AI completion report; these are not completed. Use status=all to inspect active, completed, and trashed tasks together. Active reports are pinned before other rows. Rewards occur only after a human explicitly sets completed=true. Use limit and offset for pagination; total is the unpaged match count.","x-openai-isConsequential":false,"security":[{"BearerAuth":[]}],"parameters":[{"name":"status","in":"query","description":"review means an AI-origin completion report requiring human review, not a completed task.","schema":{"type":"string","enum":["active","completed","trash","all","review"],"default":"active"}},{"name":"q","in":"query","schema":{"type":"string"}},{"name":"limit","in":"query","schema":{"type":"integer","minimum":1,"maximum":200,"default":200}},{"name":"offset","in":"query","schema":{"type":"integer","minimum":0,"default":0}}],"responses":{"200":{"description":"Tasks","content":{"application/json":{"schema":{"type":"object","required":["tasks","total"],"properties":{"tasks":{"type":"array","items":{"$ref":"#/components/schemas/Task"}},"total":{"type":"integer","minimum":0}}}}}},"401":{"description":"Missing, invalid, expired, or revoked credentials"},"403":{"description":"Insufficient write scope or rejected cookie Origin"},"409":{"description":"Version mismatch, request replay mismatch, or import conflict"},"422":{"description":"Invalid request fields or query parameters"},"404":{"description":"Item is missing or belongs to another account"}}},"post":{"operationId":"createTask","summary":"Create a task","description":"Retrying the same requestId with the same normalized body returns the original task; reusing it with different content returns 409.","x-openai-isConsequential":false,"security":[{"BearerAuth":[]}],"requestBody":{"required":true,"content":{"application/json":{"schema":{"$ref":"#/components/schemas/CreateTask"}}}},"responses":{"201":{"description":"Task","content":{"application/json":{"schema":{"type":"object","required":["task"],"properties":{"task":{"$ref":"#/components/schemas/Task"}}}}}},"401":{"description":"Missing, invalid, expired, or revoked credentials"},"403":{"description":"Insufficient write scope or rejected cookie Origin"},"409":{"description":"Version mismatch, request replay mismatch, or import conflict"},"422":{"description":"Invalid request fields or query parameters"},"404":{"description":"Item is missing or belongs to another account"}}}},"/api/v1/tasks/{id}":{"get":{"operationId":"getTask","summary":"Get a task","x-openai-isConsequential":false,"security":[{"BearerAuth":[]}],"parameters":[{"name":"id","in":"path","required":true,"schema":{"type":"string","format":"uuid"}}],"responses":{"200":{"description":"Task","content":{"application/json":{"schema":{"type":"object","required":["task"],"properties":{"task":{"$ref":"#/components/schemas/Task"}}}}}},"401":{"description":"Missing, invalid, expired, or revoked credentials"},"403":{"description":"Insufficient write scope or rejected cookie Origin"},"409":{"description":"Version mismatch, request replay mismatch, or import conflict"},"422":{"description":"Invalid request fields or query parameters"},"404":{"description":"Item is missing or belongs to another account"}}},"patch":{"operationId":"updateTask","summary":"Update a task","description":"Send expectedVersion and only the fields that changed. completionReport is an AI review signal, not completion; explicit completed=true confirms the task and completed=false also clears obsolete reports. On 409, re-read the task and retry with its current version.","x-openai-isConsequential":false,"security":[{"BearerAuth":[]}],"parameters":[{"name":"id","in":"path","required":true,"schema":{"type":"string","format":"uuid"}}],"requestBody":{"required":true,"content":{"application/json":{"schema":{"$ref":"#/components/schemas/PatchTask"}}}},"responses":{"200":{"description":"Task","content":{"application/json":{"schema":{"type":"object","required":["task"],"properties":{"task":{"$ref":"#/components/schemas/Task"}}}}}},"401":{"description":"Missing, invalid, expired, or revoked credentials"},"403":{"description":"Insufficient write scope or rejected cookie Origin"},"409":{"description":"Version mismatch, request replay mismatch, or import conflict"},"422":{"description":"Invalid request fields or query parameters"},"404":{"description":"Item is missing or belongs to another account"}}},"delete":{"operationId":"trashTask","summary":"Move a task to trash","description":"Soft-delete a task with expectedVersion. Use restore to undo it.","x-openai-isConsequential":true,"security":[{"BearerAuth":[]}],"parameters":[{"name":"id","in":"path","required":true,"schema":{"type":"string","format":"uuid"}},{"name":"expectedVersion","in":"query","required":true,"schema":{"type":"integer","minimum":1}}],"responses":{"200":{"description":"Task","content":{"application/json":{"schema":{"type":"object","required":["task"],"properties":{"task":{"$ref":"#/components/schemas/Task"}}}}}},"401":{"description":"Missing, invalid, expired, or revoked credentials"},"403":{"description":"Insufficient write scope or rejected cookie Origin"},"409":{"description":"Version mismatch, request replay mismatch, or import conflict"},"422":{"description":"Invalid request fields or query parameters"},"404":{"description":"Item is missing or belongs to another account"}}}},"/api/v1/tasks/{id}/restore":{"post":{"operationId":"restoreTask","summary":"Restore a trashed task","description":"Restore a task from trash with expectedVersion.","x-openai-isConsequential":false,"security":[{"BearerAuth":[]}],"parameters":[{"name":"id","in":"path","required":true,"schema":{"type":"string","format":"uuid"}}],"requestBody":{"required":true,"content":{"application/json":{"schema":{"$ref":"#/components/schemas/RestoreTask"}}}},"responses":{"200":{"description":"Task","content":{"application/json":{"schema":{"type":"object","required":["task"],"properties":{"task":{"$ref":"#/components/schemas/Task"}}}}}},"401":{"description":"Missing, invalid, expired, or revoked credentials"},"403":{"description":"Insufficient write scope or rejected cookie Origin"},"409":{"description":"Version mismatch, request replay mismatch, or import conflict"},"422":{"description":"Invalid request fields or query parameters"},"404":{"description":"Item is missing or belongs to another account"}}}},"/api/v1/shopping-items":{"get":{"operationId":"listShoppingItems","summary":"List shopping items","description":"Use status=active, completed, trash, or all. Use limit and offset for pagination; total is the unpaged match count.","x-openai-isConsequential":false,"security":[{"BearerAuth":[]}],"parameters":[{"name":"status","in":"query","schema":{"type":"string","enum":["active","completed","trash","all"],"default":"active"}},{"name":"limit","in":"query","schema":{"type":"integer","minimum":1,"maximum":200,"default":200}},{"name":"offset","in":"query","schema":{"type":"integer","minimum":0,"default":0}}],"responses":{"200":{"description":"Shopping items","content":{"application/json":{"schema":{"type":"object","required":["items","total"],"properties":{"items":{"type":"array","items":{"$ref":"#/components/schemas/ShoppingItem"}},"total":{"type":"integer","minimum":0}}}}}},"401":{"description":"Missing, invalid, expired, or revoked credentials"},"403":{"description":"Insufficient write scope or rejected cookie Origin"},"409":{"description":"Version mismatch, request replay mismatch, or import conflict"},"422":{"description":"Invalid request fields or query parameters"},"404":{"description":"Item is missing or belongs to another account"}}},"post":{"operationId":"createShoppingItem","summary":"Create a shopping item","description":"Retrying the same requestId with the same normalized body returns the original item; reusing it with different content returns 409.","x-openai-isConsequential":false,"security":[{"BearerAuth":[]}],"requestBody":{"required":true,"content":{"application/json":{"schema":{"$ref":"#/components/schemas/CreateShoppingItem"}}}},"responses":{"201":{"description":"Shopping item","content":{"application/json":{"schema":{"type":"object","required":["item"],"properties":{"item":{"$ref":"#/components/schemas/ShoppingItem"}}}}}},"401":{"description":"Missing, invalid, expired, or revoked credentials"},"403":{"description":"Insufficient write scope or rejected cookie Origin"},"409":{"description":"Version mismatch, request replay mismatch, or import conflict"},"422":{"description":"Invalid request fields or query parameters"},"404":{"description":"Item is missing or belongs to another account"}}}},"/api/v1/shopping-items/{id}":{"get":{"operationId":"getShoppingItem","summary":"Get a shopping item","x-openai-isConsequential":false,"security":[{"BearerAuth":[]}],"parameters":[{"name":"id","in":"path","required":true,"schema":{"type":"string","format":"uuid"}}],"responses":{"200":{"description":"Shopping item","content":{"application/json":{"schema":{"type":"object","required":["item"],"properties":{"item":{"$ref":"#/components/schemas/ShoppingItem"}}}}}},"401":{"description":"Missing, invalid, expired, or revoked credentials"},"403":{"description":"Insufficient write scope or rejected cookie Origin"},"409":{"description":"Version mismatch, request replay mismatch, or import conflict"},"422":{"description":"Invalid request fields or query parameters"},"404":{"description":"Item is missing or belongs to another account"}}},"patch":{"operationId":"updateShoppingItem","summary":"Update a shopping item","description":"Send expectedVersion and only the fields that changed. On 409, re-read the item and retry with its current version.","x-openai-isConsequential":false,"security":[{"BearerAuth":[]}],"parameters":[{"name":"id","in":"path","required":true,"schema":{"type":"string","format":"uuid"}}],"requestBody":{"required":true,"content":{"application/json":{"schema":{"$ref":"#/components/schemas/PatchShoppingItem"}}}},"responses":{"200":{"description":"Shopping item","content":{"application/json":{"schema":{"type":"object","required":["item"],"properties":{"item":{"$ref":"#/components/schemas/ShoppingItem"}}}}}},"401":{"description":"Missing, invalid, expired, or revoked credentials"},"403":{"description":"Insufficient write scope or rejected cookie Origin"},"409":{"description":"Version mismatch, request replay mismatch, or import conflict"},"422":{"description":"Invalid request fields or query parameters"},"404":{"description":"Item is missing or belongs to another account"}}},"delete":{"operationId":"trashShoppingItem","summary":"Move a shopping item to trash","description":"Soft-delete a shopping item with expectedVersion. Use restore to undo it.","x-openai-isConsequential":true,"security":[{"BearerAuth":[]}],"parameters":[{"name":"id","in":"path","required":true,"schema":{"type":"string","format":"uuid"}},{"name":"expectedVersion","in":"query","required":true,"schema":{"type":"integer","minimum":1}}],"responses":{"200":{"description":"Shopping item","content":{"application/json":{"schema":{"type":"object","required":["item"],"properties":{"item":{"$ref":"#/components/schemas/ShoppingItem"}}}}}},"401":{"description":"Missing, invalid, expired, or revoked credentials"},"403":{"description":"Insufficient write scope or rejected cookie Origin"},"409":{"description":"Version mismatch, request replay mismatch, or import conflict"},"422":{"description":"Invalid request fields or query parameters"},"404":{"description":"Item is missing or belongs to another account"}}}},"/api/v1/shopping-items/{id}/restore":{"post":{"operationId":"restoreShoppingItem","summary":"Restore a trashed shopping item","description":"Restore a shopping item from trash with expectedVersion.","x-openai-isConsequential":false,"security":[{"BearerAuth":[]}],"parameters":[{"name":"id","in":"path","required":true,"schema":{"type":"string","format":"uuid"}}],"requestBody":{"required":true,"content":{"application/json":{"schema":{"$ref":"#/components/schemas/RestoreShoppingItem"}}}},"responses":{"200":{"description":"Shopping item","content":{"application/json":{"schema":{"type":"object","required":["item"],"properties":{"item":{"$ref":"#/components/schemas/ShoppingItem"}}}}}},"401":{"description":"Missing, invalid, expired, or revoked credentials"},"403":{"description":"Insufficient write scope or rejected cookie Origin"},"409":{"description":"Version mismatch, request replay mismatch, or import conflict"},"422":{"description":"Invalid request fields or query parameters"},"404":{"description":"Item is missing or belongs to another account"}}}}}}