{"openapi":"3.1.0","info":{"title":"Amaia Records Manager API","description":"\n    An API for managing document records: listing, uploading, and deleting files\n    stored in Google Cloud Storage, with per-document access control enforced via\n    asset-level privileges set at upload time.\n    ","contact":{"name":"Kage Technologies","email":"support.dev@kagetechnologies.com"},"license":{"name":"All rights reserved to Kage Technologies"},"version":"0.1.0"},"paths":{"/v1/records":{"get":{"tags":["Document Records"],"summary":"List documents","description":"Returns a page of documents in the organisation that the requesting user\nis authorised to see.  Access control is based on the `allowed_user_oids`\nfield pre-computed and stored in Firestore when the document was uploaded.\n\nPass ``cursor`` (the ``next_cursor`` value from the previous response) to\nfetch the next page.  Omit it to start from the beginning.  ``page_size``\ncontrols the maximum number of records returned per page (minimum 25).\n\nThe organisation is identified by the ``X-ORG-ID`` header injected by\nthe API gateway.  The requesting user is identified by the ``sub`` claim\nof the bearer JWT forwarded as ``X-Forwarded-Authorization``.","operationId":"list_documents_v1_records_get","parameters":[{"name":"cursor","in":"query","required":false,"schema":{"anyOf":[{"type":"string"},{"type":"null"}],"description":"Opaque pagination cursor from the previous response's next_cursor field. Omit for the first page.","title":"Cursor"},"description":"Opaque pagination cursor from the previous response's next_cursor field. Omit for the first page."},{"name":"page_size","in":"query","required":false,"schema":{"type":"integer","maximum":200,"minimum":25,"description":"Number of documents per page (25 to 200).","default":25,"title":"Page Size"},"description":"Number of documents per page (25 to 200)."},{"name":"path","in":"query","required":false,"schema":{"anyOf":[{"type":"string"},{"type":"null"}],"description":"Folder to open (e.g. 'Cases/2024'); pass an empty value for the root. When present, the response lists that folder's direct files and subfolders. When absent, the flat list of all documents is returned.","title":"Path"},"description":"Folder to open (e.g. 'Cases/2024'); pass an empty value for the root. When present, the response lists that folder's direct files and subfolders. When absent, the flat list of all documents is returned."},{"name":"sort","in":"query","required":false,"schema":{"type":"string","pattern":"^(name|date)$","description":"Folder view only: 'name' (default, ascending) or 'date' (last update, newest first).","default":"name","title":"Sort"},"description":"Folder view only: 'name' (default, ascending) or 'date' (last update, newest first)."},{"name":"order","in":"query","required":false,"schema":{"anyOf":[{"type":"string","pattern":"^(asc|desc)$"},{"type":"null"}],"description":"Folder view only: overrides the default direction of `sort`.","title":"Order"},"description":"Folder view only: overrides the default direction of `sort`."},{"name":"x-org-id","in":"header","required":false,"schema":{"anyOf":[{"type":"string"},{"type":"null"}],"description":"Organisation UUID (set by API gateway)","title":"X-Org-Id"},"description":"Organisation UUID (set by API gateway)"},{"name":"authorization","in":"header","required":false,"schema":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Authorization"}},{"name":"x-forwarded-authorization","in":"header","required":false,"schema":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"X-Forwarded-Authorization"}}],"responses":{"200":{"description":"Documents visible to the requesting user","content":{"application/json":{"schema":{"anyOf":[{"$ref":"#/components/schemas/FolderListResponse"},{"$ref":"#/components/schemas/DocumentListResponse"}],"title":"Response List Documents V1 Records Get"}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}}},"/v1/records/detail":{"get":{"tags":["Document Records"],"summary":"Get document details","description":"Returns details of a document in the organisation that the requesting user is\nauthorised to see.  Access control is based on the `allowed_user_oids`\nfield pre-computed and stored in Firestore when the document was uploaded.\n\nThe organisation is identified by the ``X-ORG-ID`` header injected by\nthe API gateway.  The requesting user is identified by the ``sub`` claim\nof the bearer JWT forwarded as ``X-Forwarded-Authorization``.","operationId":"get_document_details_v1_records_detail_get","parameters":[{"name":"filename","in":"query","required":true,"schema":{"type":"string","description":"Original filename, e.g. folder/subfolder/report.pdf","title":"Filename"},"description":"Original filename, e.g. folder/subfolder/report.pdf"},{"name":"x-org-id","in":"header","required":false,"schema":{"anyOf":[{"type":"string"},{"type":"null"}],"description":"Organisation UUID (set by API gateway)","title":"X-Org-Id"},"description":"Organisation UUID (set by API gateway)"},{"name":"authorization","in":"header","required":false,"schema":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Authorization"}},{"name":"x-forwarded-authorization","in":"header","required":false,"schema":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"X-Forwarded-Authorization"}}],"responses":{"200":{"description":"Documents visible to the requesting user","content":{"application/json":{"schema":{"$ref":"#/components/schemas/DocumentDetailsResponse"}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}},"delete":{"tags":["Document Records"],"summary":"Delete a document","description":"Deletes a document and everything derived from it: the record, the stored\nobject, its vectors and any extracted contract. The record disappears at\nonce; the rest is purged synchronously when possible and otherwise by the\njob sweeper (see ``purge`` in the response).\n\nPermission: the document's owner, or a caller whose ``X-User-Role`` is\n``director`` or ``manager`` in this organisation (verified with Ludwig).\nThe caller must be able to see the document in the first place.\n\n`filename` is the original filename returned by ``GET /v1/records``, passed\nas a query parameter. Prefer ``DELETE /v1/records/{id}``.","operationId":"delete_document_v1_records_detail_delete","parameters":[{"name":"filename","in":"query","required":true,"schema":{"type":"string","description":"Original filename, e.g. folder/subfolder/report.pdf","title":"Filename"},"description":"Original filename, e.g. folder/subfolder/report.pdf"},{"name":"x-org-id","in":"header","required":false,"schema":{"anyOf":[{"type":"string"},{"type":"null"}],"description":"Organisation UUID (set by API gateway)","title":"X-Org-Id"},"description":"Organisation UUID (set by API gateway)"},{"name":"x-user-role","in":"header","required":false,"schema":{"anyOf":[{"type":"string"},{"type":"null"}],"description":"Role the caller acts as; a managing role is verified with Ludwig","title":"X-User-Role"},"description":"Role the caller acts as; a managing role is verified with Ludwig"},{"name":"authorization","in":"header","required":false,"schema":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Authorization"}},{"name":"x-forwarded-authorization","in":"header","required":false,"schema":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"X-Forwarded-Authorization"}}],"responses":{"200":{"description":"Confirmation of deletion","content":{"application/json":{"schema":{"$ref":"#/components/schemas/DeleteResponse"}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}}},"/v1/records/{document_id}":{"get":{"tags":["Document Records"],"summary":"Get document details by id","operationId":"get_document_details_by_id_v1_records__document_id__get","parameters":[{"name":"document_id","in":"path","required":true,"schema":{"type":"string","pattern":"^[0-9a-fA-F]{8}-[0-9a-fA-F]{4}-[0-9a-fA-F]{4}-[0-9a-fA-F]{4}-[0-9a-fA-F]{12}$","description":"Stable document id (uuid)","title":"Document Id"},"description":"Stable document id (uuid)"},{"name":"x-org-id","in":"header","required":false,"schema":{"anyOf":[{"type":"string"},{"type":"null"}],"description":"Organisation UUID (set by API gateway)","title":"X-Org-Id"},"description":"Organisation UUID (set by API gateway)"},{"name":"authorization","in":"header","required":false,"schema":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Authorization"}},{"name":"x-forwarded-authorization","in":"header","required":false,"schema":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"X-Forwarded-Authorization"}}],"responses":{"200":{"description":"Details of the document","content":{"application/json":{"schema":{"$ref":"#/components/schemas/DocumentDetailsResponse"}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}},"delete":{"tags":["Document Records"],"summary":"Delete a document by id","description":"Same as ``DELETE /v1/records/detail``, keyed by the stable document id.","operationId":"delete_document_by_id_v1_records__document_id__delete","parameters":[{"name":"document_id","in":"path","required":true,"schema":{"type":"string","pattern":"^[0-9a-fA-F]{8}-[0-9a-fA-F]{4}-[0-9a-fA-F]{4}-[0-9a-fA-F]{4}-[0-9a-fA-F]{12}$","description":"Stable document id (uuid)","title":"Document Id"},"description":"Stable document id (uuid)"},{"name":"x-org-id","in":"header","required":false,"schema":{"anyOf":[{"type":"string"},{"type":"null"}],"description":"Organisation UUID (set by API gateway)","title":"X-Org-Id"},"description":"Organisation UUID (set by API gateway)"},{"name":"x-user-role","in":"header","required":false,"schema":{"anyOf":[{"type":"string"},{"type":"null"}],"description":"Role the caller acts as; a managing role is verified with Ludwig","title":"X-User-Role"},"description":"Role the caller acts as; a managing role is verified with Ludwig"},{"name":"authorization","in":"header","required":false,"schema":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Authorization"}},{"name":"x-forwarded-authorization","in":"header","required":false,"schema":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"X-Forwarded-Authorization"}}],"responses":{"200":{"description":"Confirmation of deletion","content":{"application/json":{"schema":{"$ref":"#/components/schemas/DeleteResponse"}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}}},"/v1/records/upload":{"post":{"tags":["Document Records"],"summary":"Upload documents","description":"Uploads one or more files and sets document-level access privileges.\n\nThe `assetIds` field controls who can see the document after upload:\n- If provided (real asset UUIDs), the document is visible to the uploader\n  **and** every user assigned to any of the listed assets.\n- If omitted, or if only wildcards (`all` / `*`) are provided, the document\n  is visible to all users in the organisation.\n\nThe optional `userIds` field grants additional, explicit access: every\nuser UUID listed there is resolved to an OID and added to\n`allowed_user_oids` alongside the uploader, independent of `assetIds`.\n\nThe organisation is identified by the ``X-ORG-ID`` header injected by\nthe API gateway.  The uploading user is identified by the ``sub`` claim\nof the bearer JWT forwarded as ``X-Forwarded-Authorization``.","operationId":"upload_documents_v1_records_upload_post","parameters":[{"name":"x-org-id","in":"header","required":false,"schema":{"anyOf":[{"type":"string"},{"type":"null"}],"description":"Organisation UUID (set by API gateway)","title":"X-Org-Id"},"description":"Organisation UUID (set by API gateway)"},{"name":"authorization","in":"header","required":false,"schema":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Authorization"}},{"name":"x-forwarded-authorization","in":"header","required":false,"schema":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"X-Forwarded-Authorization"}}],"requestBody":{"required":true,"content":{"application/x-www-form-urlencoded":{"schema":{"$ref":"#/components/schemas/FileUpload"}}}},"responses":{"200":{"description":"Per-file upload results","content":{"application/json":{"schema":{"$ref":"#/components/schemas/FileUploadResponseList"}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}}},"/internal/jobs/run":{"post":{"tags":["Internal"],"summary":"Run pending purge jobs","operationId":"run_jobs_internal_jobs_run_post","parameters":[{"name":"limit","in":"query","required":false,"schema":{"type":"integer","maximum":500,"minimum":1,"default":50,"title":"Limit"}},{"name":"authorization","in":"header","required":false,"schema":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Authorization"}}],"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{"$ref":"#/components/schemas/JobsRunResponse"}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}}}},"components":{"schemas":{"Breadcrumb":{"properties":{"name":{"type":"string","title":"Name","description":"Folder name"},"path":{"type":"string","title":"Path","description":"Full folder path"}},"type":"object","required":["name","path"],"title":"Breadcrumb"},"DeleteResponse":{"properties":{"id":{"type":"string","title":"Id","description":"Stable id of the deleted document","default":""},"filename":{"type":"string","title":"Filename","description":"The filename of the deleted document","default":""},"message":{"type":"string","title":"Message","description":"Result message"},"purge":{"type":"string","title":"Purge","description":"'completed' when the objects, chunks and contracts are gone; 'pending' when the record is deleted but the derived data is still being removed by the job sweeper (a retry is guaranteed).","default":"completed"}},"type":"object","required":["message"],"title":"DeleteResponse"},"DocumentDetailsResponse":{"properties":{"id":{"type":"string","title":"Id","description":"Stable document id","default":""},"fileName":{"type":"string","title":"Filename","description":"Original filename","default":""},"status":{"type":"string","title":"Status","description":"Processing status"},"size":{"type":"integer","title":"Size","description":"File size in bytes","default":0},"createdBy":{"type":"string","title":"Createdby","description":"Display name of the uploader","default":""},"timeCreated":{"type":"string","title":"Timecreated","description":"ISO-8601 creation timestamp","default":""},"updatedBy":{"type":"string","title":"Updatedby","description":"Display name of the last updater","default":""},"timeUpdated":{"type":"string","title":"Timeupdated","description":"ISO-8601 last-update timestamp","default":""},"contentType":{"type":"string","title":"Contenttype","description":"MIME type of the document, e.g. application/pdf, text/markdown, image/png","default":""},"signedUrl":{"type":"string","title":"Signedurl","description":"15-minute signed URL that renders the document inline in the browser — use for preview (status=processed only)","default":""},"downloadUrl":{"type":"string","title":"Downloadurl","description":"15-minute signed URL that downloads the document as an attachment under its original filename (status=processed only)","default":""},"history":{"items":{"$ref":"#/components/schemas/DocumentHistory"},"type":"array","title":"History","description":"Lifecycle history"}},"type":"object","required":["status"],"title":"DocumentDetailsResponse","description":"API response for GET /v1/records/{id} and GET /v1/records/detail.  No internal GCS fields."},"DocumentHistory":{"properties":{"event":{"type":"string","title":"Event","description":"Event type (uploaded, processed, deleted, …)"},"timestamp":{"type":"string","title":"Timestamp","description":"ISO-8601 timestamp of the event"},"uploadedBy":{"type":"string","title":"Uploadedby","description":"User name who triggered the event","default":""},"visibility":{"$ref":"#/components/schemas/Visibility","description":"Visibility details at the time of the event"},"visibilityChanged":{"type":"boolean","title":"Visibilitychanged","description":"Whether visibility changed vs. the previous event"}},"type":"object","required":["event","timestamp","visibility","visibilityChanged"],"title":"DocumentHistory"},"DocumentList":{"properties":{"id":{"type":"string","title":"Id","description":"Stable document id; use it for detail, delete and (later) move/visibility calls","default":""},"filename":{"type":"string","title":"Filename","description":"Original filename"},"sessionId":{"type":"string","title":"Sessionid","description":"Upload session ID","default":""},"status":{"type":"string","title":"Status","description":"Processing status (uploaded, processed, deleted, …)"},"size":{"type":"integer","title":"Size","description":"File size in bytes","default":0},"timeCreated":{"type":"string","title":"Timecreated","description":"ISO-8601 creation timestamp","default":""},"timeUpdated":{"type":"string","title":"Timeupdated","description":"ISO-8601 last-update timestamp","default":""}},"type":"object","required":["filename","status"],"title":"DocumentList"},"DocumentListResponse":{"properties":{"count":{"type":"integer","title":"Count","description":"Number of documents returned in this page"},"documents":{"items":{"$ref":"#/components/schemas/DocumentList"},"type":"array","title":"Documents","description":"List of document records"},"next_cursor":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Next Cursor","description":"Opaque cursor token for the next page; absent when this is the last page"}},"type":"object","required":["count","documents"],"title":"DocumentListResponse"},"FileUpload":{"properties":{"files":{"items":{"type":"string","contentMediaType":"application/octet-stream"},"type":"array","title":"Files","description":"list of files to upload"},"userNature":{"type":"string","title":"Usernature","description":"nature of the user uploading the file, e.g., 'user' or 'system'"},"userName":{"type":"string","title":"Username","description":"display name of the user uploading the file, e.g., 'Charlotte B.'"},"sessionId":{"type":"string","title":"Sessionid","description":"session id of the user uploading the file"},"assetIds":{"anyOf":[{"items":{"type":"string"},"type":"array"},{"type":"null"}],"title":"Assetids","description":"list of asset ids associated with the file"},"userIds":{"anyOf":[{"items":{"type":"string"},"type":"array"},{"type":"null"}],"title":"Userids","description":"list of user ids to explicitly grant document access to, in addition to the uploader"},"replace":{"type":"boolean","title":"Replace","description":"true to overwrite a document that already has this path (explicit re-upload). Without it, a name clash is reported per file as a 'name_exists' conflict.","default":false}},"type":"object","required":["files","userNature","userName","sessionId"],"title":"FileUpload"},"FileUploadResponse":{"properties":{"fileName":{"type":"string","title":"Filename","description":"Name of the uploaded file"},"message":{"type":"string","title":"Message","description":"Result message for this file"},"id":{"type":"string","title":"Id","description":"Stable document id when the file was accepted","default":""},"status":{"type":"string","title":"Status","description":"'uploaded', 'rejected' (invalid file) or 'conflict' (see conflict)","default":""},"conflict":{"anyOf":[{"$ref":"#/components/schemas/UploadConflict"},{"type":"null"}],"description":"Set when status is 'conflict'"}},"type":"object","required":["fileName","message"],"title":"FileUploadResponse"},"FileUploadResponseList":{"properties":{"messages":{"items":{"$ref":"#/components/schemas/FileUploadResponse"},"type":"array","title":"Messages","description":"Per-file upload results"}},"type":"object","required":["messages"],"title":"FileUploadResponseList"},"FolderItem":{"properties":{"name":{"type":"string","title":"Name","description":"Folder name (last path segment)"},"path":{"type":"string","title":"Path","description":"Full folder path, e.g. 'Cases/2024'"},"fileCount":{"type":"integer","title":"Filecount","description":"Files directly inside this folder that the user can see","default":0},"timeUpdated":{"type":"string","title":"Timeupdated","description":"ISO-8601 timestamp of the most recent change inside the folder","default":""}},"type":"object","required":["name","path"],"title":"FolderItem"},"FolderListResponse":{"properties":{"path":{"type":"string","title":"Path","description":"Folder that was listed; empty for the root"},"breadcrumbs":{"items":{"$ref":"#/components/schemas/Breadcrumb"},"type":"array","title":"Breadcrumbs","description":"Path from the root to this folder"},"folders":{"items":{"$ref":"#/components/schemas/FolderItem"},"type":"array","title":"Folders","description":"Immediate subfolders; only on the first page"},"documents":{"items":{"$ref":"#/components/schemas/DocumentList"},"type":"array","title":"Documents","description":"Files directly inside this folder (one page)"},"count":{"type":"integer","title":"Count","description":"Number of documents returned in this page"},"next_cursor":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Next Cursor","description":"Opaque cursor token for the next page; absent when this is the last page"}},"type":"object","required":["path","documents","count"],"title":"FolderListResponse"},"HTTPValidationError":{"properties":{"detail":{"items":{"$ref":"#/components/schemas/ValidationError"},"type":"array","title":"Detail"}},"type":"object","title":"HTTPValidationError"},"JobsRunResponse":{"properties":{"processed":{"type":"integer","title":"Processed","default":0},"succeeded":{"type":"integer","title":"Succeeded","default":0},"failed":{"type":"integer","title":"Failed","default":0}},"type":"object","title":"JobsRunResponse"},"UploadConflict":{"properties":{"reason":{"type":"string","title":"Reason","description":"'name_exists' (same name in that folder; send replace=true to overwrite) or 'duplicate_content' (identical bytes already stored)"},"documentId":{"type":"string","title":"Documentid","description":"The existing document","default":""},"filename":{"type":"string","title":"Filename","description":"Its path, only when the caller may see it","default":""},"owner":{"type":"string","title":"Owner","description":"Display name of its uploader","default":""}},"type":"object","required":["reason"],"title":"UploadConflict"},"ValidationError":{"properties":{"loc":{"items":{"anyOf":[{"type":"string"},{"type":"integer"}]},"type":"array","title":"Location"},"msg":{"type":"string","title":"Message"},"type":{"type":"string","title":"Error Type"},"input":{"title":"Input"},"ctx":{"type":"object","title":"Context"}},"type":"object","required":["loc","msg","type"],"title":"ValidationError"},"Visibility":{"properties":{"scope":{"type":"string","title":"Scope","description":"Scope of visibility (e.g., 'asset', 'organisation')"},"allowedUsers":{"items":{"type":"string"},"type":"array","title":"Allowedusers","description":"List of user names who have access to the document based on the defined scope."}},"type":"object","required":["scope"],"title":"Visibility"}}}}