Documents

Upload, process, and manage knowledge documents

Documents are files uploaded to a project. Once processed, the AI can search through them to answer questions and verify compliance. See Document Processing for a detailed explanation of the upload flow.


POST /api/v2/documents

Reserve a document upload slot. Step 1 of the upload flow. Returns a presigned URL for direct file upload to storage.

Authentication: Bearer token required

Request body:

FieldTypeRequiredDescription
file_namestringYesFile name (no path separators). 1–500 characters
content_typestringYesMIME type (e.g., application/pdf, application/msword)
size_bytesintegerYesFile size in bytes (max 500 MB)
project_iduuidNoProject to associate with. Omit for org-level documents

Example request:

curl -X POST https://api.pyramid-ai.com/api/v2/documents \
-H "Authorization: Bearer pai_live_YOUR_KEY" \
-H "Content-Type: application/json" \
-d '{
"file_name": "Safety-Management-Plan-2026.pdf",
"content_type": "application/pdf",
"size_bytes": 2048576,
"project_id": "7f9c8d2a-1b3e-4c5d-8e9f-0a1b2c3d4e5f"
}'

Example response 201 Created:

{
"success": true,
"data": {
"id": "9d11d31d-17ce-4b9f-8c13-63d7058f5fd3",
"org_id": "iPwoNDP1ribwqCTkvlEyiA6DtGZdYe0k",
"project_id": "7f9c8d2a-1b3e-4c5d-8e9f-0a1b2c3d4e5f",
"file_name": "Safety-Management-Plan-2026.pdf",
"content_type": "application/pdf",
"size_bytes": null,
"status": "awaiting_upload",
"chunk_count": null,
"error_message": null,
"created_at": "2026-05-22T10:00:00Z",
"updated_at": "2026-05-22T10:00:00Z",
"upload": {
"url": "https://storage.supabase.co/...",
"method": "PUT",
"recommended_content_type": "application/pdf",
"expires_at": "2026-05-22T12:00:00Z"
}
},
"request_id": "..."
}

After receiving the response, upload your file directly to upload.url:

curl -X PUT "UPLOAD_URL_FROM_RESPONSE" \
-H "Content-Type: application/pdf" \
--data-binary @Safety-Management-Plan-2026.pdf

The upload URL expires after approximately 2 hours. If it expires before you upload, call this endpoint again to get a fresh URL.


POST /api/v2/documents/process

Trigger processing for uploaded documents. Step 2 of the upload flow. After uploading file bytes to the presigned URL, call this to start text extraction, chunking, and indexing.

Authentication: Bearer token required

Request body:

FieldTypeRequiredDescription
document_idsuuid[]YesArray of document IDs to process (1–100)

Example request:

curl -X POST https://api.pyramid-ai.com/api/v2/documents/process \
-H "Authorization: Bearer pai_live_YOUR_KEY" \
-H "Content-Type: application/json" \
-d '{"document_ids": ["9d11d31d-17ce-4b9f-8c13-63d7058f5fd3"]}'

Example response 200 OK:

{
"success": true,
"data": {
"processed": ["9d11d31d-17ce-4b9f-8c13-63d7058f5fd3"],
"skipped": [],
"failed": []
},
"request_id": "..."
}
FieldTypeDescription
processeduuid[]Documents that started processing successfully
skippedobject[]Documents skipped with a reason (already processed, wrong state, etc.)
failedobject[]Documents that failed with an error and message

Skipped reasons:

ReasonDescription
not_foundDocument ID doesn’t exist or belongs to another org
not_awaiting_uploadDocument already past the upload stage
upload_not_foundFile bytes not found in storage
size_mismatchUploaded file size doesn’t match declared size_bytes
content_type_mismatchUploaded file type doesn’t match declared content_type

GET /api/v2/documents

List documents with optional filters. Supports pagination.

Authentication: Bearer token required

Query parameters:

ParameterTypeDefaultDescription
project_iduuidFilter by project
document_idsstringComma-separated list of document UUIDs
statusstringFilter by status: awaiting_upload, processing, ready, completed, failed
limitinteger50Maximum results per page (max 200)
offsetinteger0Number of results to skip

Example request:

curl "https://api.pyramid-ai.com/api/v2/documents?project_id=7f9c8d2a-1b3e-4c5d-8e9f-0a1b2c3d4e5f&status=completed" \
-H "Authorization: Bearer pai_live_YOUR_KEY"

Example response 200 OK:

{
"success": true,
"data": [
{
"id": "9d11d31d-17ce-4b9f-8c13-63d7058f5fd3",
"org_id": "iPwoNDP1ribwqCTkvlEyiA6DtGZdYe0k",
"project_id": "7f9c8d2a-1b3e-4c5d-8e9f-0a1b2c3d4e5f",
"file_name": "Safety-Management-Plan-2026.pdf",
"content_type": "application/pdf",
"size_bytes": 2048576,
"status": "completed",
"chunk_count": 85,
"error_message": null,
"created_at": "2026-05-22T10:00:00Z",
"updated_at": "2026-05-22T10:05:30Z"
}
],
"request_id": "...",
"pagination": {
"limit": 50,
"offset": 0,
"total": 1
}
}

GET /api/v2/documents/{id}/download

Get a presigned download URL for a document. Returns a short-lived URL (10-minute expiry) for downloading the original source file. Use this to trace AI-generated citations back to the source document — critical for compliance audit trails.

Authentication: Bearer token required

Path parameters:

ParameterTypeDescription
iduuidDocument ID

Example request:

curl https://api.pyramid-ai.com/api/v2/documents/9d11d31d-17ce-4b9f-8c13-63d7058f5fd3/download \
-H "Authorization: Bearer pai_live_YOUR_KEY"

Example response 200 OK:

{
"success": true,
"data": {
"document_id": "9d11d31d-17ce-4b9f-8c13-63d7058f5fd3",
"file_name": "Safety-Management-Plan-2026.pdf",
"content_type": "application/pdf",
"size_bytes": 2048576,
"download_url": "https://storage.supabase.co/object/sign/uploads/orgs/...?token=...",
"expires_at": "2026-05-22T10:10:00Z"
},
"request_id": "..."
}

Response fields:

FieldTypeDescription
document_iduuidThe document this download URL is for
file_namestringOriginal file name
content_typestringMIME type of the file
size_bytesinteger | nullFile size in bytes
download_urlstringPresigned URL — use to download the file directly
expires_atstringWhen the URL expires (ISO 8601). Generate a new one if expired

The download URL expires after approximately 10 minutes. If it expires, call this endpoint again to get a fresh URL.

Error responses:

StatusCodeWhen
404NOT_FOUNDDocument doesn’t exist, belongs to another org, or file is not in storage

GET /api/v2/documents/{id}

Get details for a single document, including its processing status.

Authentication: Bearer token required

Path parameters:

ParameterTypeDescription
iduuidDocument ID

Example request:

curl https://api.pyramid-ai.com/api/v2/documents/9d11d31d-17ce-4b9f-8c13-63d7058f5fd3 \
-H "Authorization: Bearer pai_live_YOUR_KEY"

Example response 200 OK:

{
"success": true,
"data": {
"id": "9d11d31d-17ce-4b9f-8c13-63d7058f5fd3",
"org_id": "iPwoNDP1ribwqCTkvlEyiA6DtGZdYe0k",
"project_id": "7f9c8d2a-1b3e-4c5d-8e9f-0a1b2c3d4e5f",
"file_name": "Safety-Management-Plan-2026.pdf",
"content_type": "application/pdf",
"size_bytes": 2048576,
"status": "completed",
"chunk_count": 85,
"error_message": null,
"created_at": "2026-05-22T10:00:00Z",
"updated_at": "2026-05-22T10:05:30Z"
},
"request_id": "..."
}

DELETE /api/v2/documents

Delete one or more documents by ID. The AI will no longer reference these documents.

Authentication: Bearer token required

Request body:

FieldTypeRequiredDescription
document_idsuuid[]YesArray of document IDs to delete (1–100)

Example request:

curl -X DELETE https://api.pyramid-ai.com/api/v2/documents \
-H "Authorization: Bearer pai_live_YOUR_KEY" \
-H "Content-Type: application/json" \
-d '{"document_ids": ["9d11d31d-17ce-4b9f-8c13-63d7058f5fd3"]}'

Example response 200 OK:

{
"success": true,
"data": {
"deleted": ["9d11d31d-17ce-4b9f-8c13-63d7058f5fd3"]
},
"request_id": "..."
}

Error responses:

StatusCodeWhen
403FORBIDDENOne or more document IDs belong to a different organization

Document fields (all endpoints):

FieldTypeDescription
iduuidUnique document identifier
org_idstringOrganization the document belongs to
project_iduuid | nullProject the document is associated with
file_namestringOriginal file name
content_typestringMIME type (e.g., application/pdf)
size_bytesinteger | nullFile size in bytes
statusstringProcessing status: awaiting_upload, processing, completed, ready, failed
chunk_countinteger | nullNumber of searchable chunks created from this document
error_messagestring | nullError details if status is failed
created_atstringWhen the document was created (ISO 8601)
updated_atstringWhen the document was last modified (ISO 8601)