Buckets API

Organize documents in buckets and nested folders, upload and download files, run configurable LLM extraction pipelines (with OCR reuse), search by hybrid vector + lexical similarity, and manage zero-trust access, connections, and permission grants.

Base URL/api/v1/buckets

Automation triggers: view every Buckets event, payload field, and predicate.

Buckets

Create and manage top-level buckets. A bucket is a federated-zone root; nested structure lives in folders beneath it. Buckets are no longer self-nestable — use the folder routes to create nested containers.

POST/api/v1/buckets/buckets

Create Bucket

Create a top-level bucket. Buckets are no longer self-nestable; the parent_id field has been removed from the request — to create a nested container, call POST /buckets/{bucket_id}/folders instead. Requires buckets:buckets:create on the org root.

Bearer token required.

Request Body

NameTypeDescription
name*
stringBucket name (1–500 characters)
description
string | nullOptional bucket description (max 5000 characters)
pipeline_config
object | nullSparse canonical v2 config with preprocess, ocr, analysis, and embedding sections. Raster DPI supports 120–300 and defaults to 150. Omitted values use cost-lean defaults; temporary v1 aliases are accepted and rewritten as v2.

Response Fields

NameTypeDescription
id*
string (UUID)Bucket ID
company_id*
string (UUID)Organization ID
name*
stringBucket name
description
string | nullBucket description
parent_id
string | nullAlways null for new buckets; retained for legacy clients
pipeline_config*
object | nullEffective pipeline configuration
system_managed
booleanTrue for subsystem-owned buckets (hidden from user-facing listings)Default: false
capabilities
BucketCapabilitiesPer-principal capability flags (can_create_folder, can_upload_file, manage_pipeline, …)
allowed_grant_permissions
string[] | nullPermissions the caller may grant on this bucket
created_at*
datetimeCreation timestamp (ISO 8601)
updated_at*
datetimeLast update timestamp
curl -X POST https://platform.ergondata.ai/api/v1/buckets/buckets \
  -H "Authorization: Bearer {token}" \
  -H "Content-Type: application/json" \
  -d '{
    "name": "Contracts 2026",
    "description": "Signed vendor agreements",
    "pipeline_config": {
      "version": 2,
      "auto_process": true,
      "ocr": { "mode": "auto", "reuse_on_reprocess": true },
      "analysis": {
        "schemas": [{
          "name": "file_type",
          "prompt": "Classify the contract type",
          "json_schema": { "type": "string" },
          "level": "file"
        }]
      },
      "embedding": { "enabled": true, "source": "extracted_text" }
    }
  }'

Response

201 Created
{
  "id": "f7a8b9c0-1234-5678-9abc-def012345678",
  "company_id": "c0ffee00-cafe-babe-dead-beefcafebabe",
  "name": "Contracts 2026",
  "description": "Signed vendor agreements",
  "parent_id": null,
  "pipeline_config": {
    "version": 2,
    "auto_process": true,
    "ocr": { "mode": "auto", "reuse_on_reprocess": true },
    "analysis": {
      "schemas": [{
        "name": "file_type",
        "prompt": "Classify the contract type",
        "json_schema": { "type": "string" },
        "level": "file",
        "allow_many": false
      }]
    },
    "embedding": { "enabled": true, "source": "extracted_text" }
  },
  "system_managed": false,
  "capabilities": {
    "can_create_folder": true,
    "can_upload_file": true,
    "can_list_files": true,
    "manage_pipeline": true,
    "manage_security": true
  },
  "created_at": "2026-04-12T09:15:22Z",
  "updated_at": "2026-04-12T09:15:22Z"
}
GET/api/v1/buckets/buckets

List Buckets

List the company's root buckets. System-managed buckets (e.g. the per-company Conversations or Memory roots) are excluded by default; pass include_system_managed=true to include them.

Bearer token required.

Query Parameters

NameTypeDescription
include_system_managed
booleanInclude subsystem-owned buckets in the resultDefault: false

Response Fields

NameTypeDescription
[]*
BucketResponse[]Bucket roots (id, company_id, name, description, pipeline_config, system_managed, capabilities, timestamps)
curl https://platform.ergondata.ai/api/v1/buckets/buckets \
  -H "Authorization: Bearer {token}"

Response

200 OK
[
  {
    "id": "f7a8b9c0-1234-5678-9abc-def012345678",
    "company_id": "c0ffee00-cafe-babe-dead-beefcafebabe",
    "name": "Contracts 2026",
    "description": "Signed vendor agreements",
    "parent_id": null,
    "pipeline_config": { "auto_process": true },
    "system_managed": false,
    "capabilities": { "can_upload_file": true, "can_list_files": true },
    "created_at": "2026-04-12T09:15:22Z",
    "updated_at": "2026-04-12T09:15:22Z"
  }
]
GET/api/v1/buckets/buckets/{bucket_id}

Get Bucket

Return bucket details, its stored sparse pipeline override, and the fully resolved canonical-v2 pipeline config. The legacy children array is retained on the wire for compatibility; the folder hierarchy is exposed by the tree and folder endpoints.

Bearer token required.

Path Parameters

NameTypeDescription
bucket_id*
string (UUID)Bucket ID

Response Fields

NameTypeDescription
id*
string (UUID)Bucket ID
name*
stringBucket name
pipeline_config*
object | nullStored sparse bucket pipeline override
resolved_pipeline_config*
PipelineConfigV2Effective canonical-v2 config after the bucket override and platform defaults are applied
children
BucketResponse[]Legacy child-bucket field; empty for new buckets
curl https://platform.ergondata.ai/api/v1/buckets/buckets/{bucket_id} \
  -H "Authorization: Bearer {token}"

Response

200 OK
{
  "id": "f7a8b9c0-1234-5678-9abc-def012345678",
  "company_id": "c0ffee00-cafe-babe-dead-beefcafebabe",
  "name": "Contracts 2026",
  "description": "Signed vendor agreements",
  "parent_id": null,
  "pipeline_config": { "version": 2, "auto_process": true },
  "resolved_pipeline_config": {
    "version": 2,
    "auto_process": true,
    "preprocess": {
      "native_text_min_chars": 100,
      "native_text_min_lines": 3,
      "rotation": "auto",
      "raster_dpi": 150,
      "raster_batch_size": 2
    },
    "ocr": {
      "mode": "auto",
      "forms": false,
      "tables": false,
      "signatures": false,
      "reuse_on_reprocess": true
    },
    "analysis": {
      "describe": { "enabled": false, "prompt": null, "key_facts": true, "detailed": false },
      "schemas": [],
      "grouping": "none",
      "evidence_locations": false,
      "grouping_visual_fallback": true
    },
    "embedding": { "enabled": false, "source": "extracted_text" }
  },
  "system_managed": false,
  "capabilities": { "can_upload_file": true, "manage_pipeline": true },
  "created_at": "2026-04-12T09:15:22Z",
  "updated_at": "2026-04-12T10:02:00Z",
  "children": []
}
PATCH/api/v1/buckets/buckets/{bucket_id}

Update Bucket

Update bucket name, description, and/or pipeline_config. System-managed buckets reject public structural mutation.

Bearer token required.

Path Parameters

NameTypeDescription
bucket_id*
string (UUID)Bucket ID

Request Body

NameTypeDescription
name
string | nullNew bucket name (1–500 characters)
description
string | nullNew description (max 5000 characters)
pipeline_config
object | nullReplace/clear the sparse canonical v2 config. Raster DPI supports 120–300 and defaults to 150. Nested preprocess, ocr, analysis, and embedding fields are persisted sparsely; v1 aliases remain accepted.

Response Fields

NameTypeDescription
id*
string (UUID)Bucket ID
name*
stringBucket name
pipeline_config*
object | nullUpdated pipeline configuration
curl -X PATCH https://platform.ergondata.ai/api/v1/buckets/buckets/{bucket_id} \
  -H "Authorization: Bearer {token}" \
  -H "Content-Type: application/json" \
  -d '{"name": "Contracts — Legal"}'

Response

200 OK
{
  "id": "f7a8b9c0-1234-5678-9abc-def012345678",
  "company_id": "c0ffee00-cafe-babe-dead-beefcafebabe",
  "name": "Contracts — Legal",
  "description": "Signed vendor agreements",
  "parent_id": null,
  "pipeline_config": { "auto_process": true },
  "system_managed": false,
  "created_at": "2026-04-12T09:15:22Z",
  "updated_at": "2026-04-12T11:30:45Z"
}
DELETE/api/v1/buckets/buckets/{bucket_id}

Delete Bucket

Soft-delete a bucket and record an audit event. System-managed buckets reject public deletion.

Bearer token required.

Path Parameters

NameTypeDescription
bucket_id*
string (UUID)Bucket ID
curl -X DELETE https://platform.ergondata.ai/api/v1/buckets/buckets/{bucket_id} \
  -H "Authorization: Bearer {token}" \
  -w "\n%{http_code}\n"

Response

204 No Content
GET/api/v1/buckets/buckets/{bucket_id}/tree

Get Bucket Tree

Return a bucket subtree of nested folders, optionally walked recursively and optionally with inline files. The permission check is performed on the root bucket only; descendants inherit visibility.

Bearer token required.

Path Parameters

NameTypeDescription
bucket_id*
string (UUID)Bucket ID

Query Parameters

NameTypeDescription
recursive
booleanWalk the subtree to max_depth instead of the legacy depth-2 walk. max_depth is only honoured when this is trueDefault: false
max_depth
integer | nullMaximum walk depth when recursive=true (default 8, hard cap 16)
include_files
booleanAttach a files list to every node in the responseDefault: false

Response Fields

NameTypeDescription
id*
string (UUID)Bucket root ID
name*
stringBucket name
folders
FolderTreeNode[]Nested folders (id, name, parent_folder_id, system_managed, folders[], files[])
files
BucketTreeFileEntry[]Root files when include_files=true (id, filename, content_type, size_bytes)
truncated_depth
booleanTrue when the walk hit max_depth
truncated_files
booleanTrue when a node's files were capped
curl "https://platform.ergondata.ai/api/v1/buckets/buckets/{bucket_id}/tree?recursive=true&include_files=true" \
  -H "Authorization: Bearer {token}"

Response

200 OK
{
  "id": "f7a8b9c0-1234-5678-9abc-def012345678",
  "company_id": "c0ffee00-cafe-babe-dead-beefcafebabe",
  "name": "Contracts 2026",
  "pipeline_config": { "auto_process": true },
  "system_managed": false,
  "folders": [
    {
      "id": "a1b2c3d4-e5f6-7890-abcd-ef1234567890",
      "name": "NDAs",
      "parent_folder_id": null,
      "system_managed": false,
      "folders": [],
      "files": [
        {
          "id": "d0c0d0c0-1111-2222-3333-444455556666",
          "bucket_id": "f7a8b9c0-1234-5678-9abc-def012345678",
          "filename": "nda-acme.pdf",
          "content_type": "application/pdf",
          "size_bytes": 32118,
          "updated_at": "2026-04-12T08:01:02Z"
        }
      ]
    }
  ],
  "files": [],
  "truncated_depth": false,
  "truncated_files": false,
  "created_at": "2026-04-12T09:15:22Z",
  "updated_at": "2026-04-12T10:02:00Z"
}
POST/api/v1/buckets/buckets/{bucket_id}/pipeline/schemas/generate

Generate Bucket Pipeline Schema

Infer a JSON Schema dict from a natural-language extraction prompt, ready to paste into the bucket's pipeline_config. Requires buckets:buckets:pipeline:edit on the bucket.

Bearer token required.

Path Parameters

NameTypeDescription
bucket_id*
string (UUID)Bucket ID

Request Body

NameTypeDescription
prompt*
stringNatural-language description of the fields to extract (min 1 char)
name
string | nullOptional schema name included as context for the generator

Response Fields

NameTypeDescription
json_schema*
objectGenerated JSON Schema ready for pipeline_config
rationale*
stringOne-sentence explanation of the schema choices
curl -X POST https://platform.ergondata.ai/api/v1/buckets/buckets/{bucket_id}/pipeline/schemas/generate \
  -H "Authorization: Bearer {token}" \
  -H "Content-Type: application/json" \
  -d '{
    "name": "invoice_fields",
    "prompt": "Extract vendor name, invoice number, date, line items, and total"
  }'

Response

200 OK
{
  "json_schema": {
    "type": "object",
    "properties": {
      "vendor_name": { "type": "string" },
      "invoice_number": { "type": "string" },
      "date": { "type": "string", "format": "date" },
      "line_items": {
        "type": "array",
        "items": {
          "type": "object",
          "properties": {
            "description": { "type": "string" },
            "amount": { "type": "number" }
          }
        }
      },
      "total_amount": { "type": "number" }
    }
  },
  "rationale": "Scalar fields for vendor, invoice number, and date; an array of line items with description and amount; and a separate total field."
}
GET/api/v1/buckets/companies/{company_id}/bucket-prefs

Get Bucket Preferences

Return the caller's per-user buckets-tree and file-browser presentation preferences (ordering, favorite, view settings).

Bearer token required.

Path Parameters

NameTypeDescription
company_id*
string (UUID)Organization ID

Response Fields

NameTypeDescription
bucket_order
string[]Ordered bucket IDs for the sidebar
favorite_bucket_id
string | nullPinned/favorite bucket
item_order
objectMap of container ID → ordered child IDs
view_prefs
BucketViewPrefsFile-browser settings (mode, density, sort, asc)
curl https://platform.ergondata.ai/api/v1/buckets/companies/{company_id}/bucket-prefs \
  -H "Authorization: Bearer {token}"

Response

200 OK
{
  "bucket_order": ["f7a8b9c0-1234-5678-9abc-def012345678"],
  "favorite_bucket_id": "f7a8b9c0-1234-5678-9abc-def012345678",
  "item_order": {},
  "view_prefs": { "mode": "list", "density": "comfortable", "sort": "name", "asc": true }
}
PUT/api/v1/buckets/companies/{company_id}/bucket-prefs

Update Bucket Preferences

Partial update of the caller's bucket presentation preferences. Only provided fields are written.

Bearer token required.

Path Parameters

NameTypeDescription
company_id*
string (UUID)Organization ID

Request Body

NameTypeDescription
bucket_order
string[] | nullOrdered bucket IDs
favorite_bucket_id
string | nullFavorite bucket ID
item_order
object | nullMap of container ID → ordered child IDs
view_prefs
BucketViewPrefs | nullFile-browser settings (mode, density, sort, asc)

Response Fields

NameTypeDescription
view_prefs
BucketViewPrefsUpdated view settings
curl -X PUT https://platform.ergondata.ai/api/v1/buckets/companies/{company_id}/bucket-prefs \
  -H "Authorization: Bearer {token}" \
  -H "Content-Type: application/json" \
  -d '{"favorite_bucket_id": "f7a8b9c0-1234-5678-9abc-def012345678"}'

Response

200 OK
{
  "bucket_order": ["f7a8b9c0-1234-5678-9abc-def012345678"],
  "favorite_bucket_id": "f7a8b9c0-1234-5678-9abc-def012345678",
  "item_order": {},
  "view_prefs": { "mode": "grid", "density": "comfortable", "sort": "name", "asc": true }
}

Folders

Create and manage nested folders inside a bucket or another folder. Folders are the nesting primitive: they carry their own pipeline_config, capabilities, and access grants.

GET/api/v1/buckets/buckets/{bucket_id}/folders

List Root Folders In Bucket

List the folders directly under a bucket root. Pass recursive=true to flatten the entire folder subtree.

Bearer token required.

Path Parameters

NameTypeDescription
bucket_id*
string (UUID)Bucket ID

Query Parameters

NameTypeDescription
recursive
booleanReturn all descendant folders, not just the direct childrenDefault: false

Response Fields

NameTypeDescription
[]*
FolderResponse[]Folders (id, bucket_id, parent_folder_id, name, description, pipeline_config, capabilities, timestamps)
curl https://platform.ergondata.ai/api/v1/buckets/buckets/{bucket_id}/folders \
  -H "Authorization: Bearer {token}"

Response

200 OK
[
  {
    "id": "a1b2c3d4-e5f6-7890-abcd-ef1234567890",
    "company_id": "c0ffee00-cafe-babe-dead-beefcafebabe",
    "bucket_id": "f7a8b9c0-1234-5678-9abc-def012345678",
    "parent_folder_id": null,
    "name": "NDAs",
    "description": null,
    "pipeline_config": null,
    "system_managed": false,
    "capabilities": { "can_upload_file": true, "can_create_folder": true },
    "created_at": "2026-04-12T09:20:00Z",
    "updated_at": "2026-04-12T09:20:00Z"
  }
]
POST/api/v1/buckets/buckets/{bucket_id}/folders

Create Folder In Bucket

Create a folder directly under a bucket root. Requires buckets:buckets:folders:create on the bucket.

Bearer token required.

Path Parameters

NameTypeDescription
bucket_id*
string (UUID)Bucket ID

Request Body

NameTypeDescription
name*
stringFolder name (1–500 characters)
description
string | nullOptional folder description (max 5000 characters)

Response Fields

NameTypeDescription
id*
string (UUID)Folder ID
bucket_id*
string (UUID)Parent bucket
parent_folder_id*
string | nullAlways null for bucket-root folders
name*
stringFolder name
curl -X POST https://platform.ergondata.ai/api/v1/buckets/buckets/{bucket_id}/folders \
  -H "Authorization: Bearer {token}" \
  -H "Content-Type: application/json" \
  -d '{"name": "NDAs"}'

Response

201 Created
{
  "id": "a1b2c3d4-e5f6-7890-abcd-ef1234567890",
  "company_id": "c0ffee00-cafe-babe-dead-beefcafebabe",
  "bucket_id": "f7a8b9c0-1234-5678-9abc-def012345678",
  "parent_folder_id": null,
  "name": "NDAs",
  "description": null,
  "pipeline_config": null,
  "system_managed": false,
  "created_at": "2026-04-12T09:20:00Z",
  "updated_at": "2026-04-12T09:20:00Z"
}
GET/api/v1/buckets/folders/{folder_id}

Get Folder

Retrieve folder metadata, its stored sparse pipeline override, the fully resolved canonical-v2 config, and the caller's capabilities.

Bearer token required.

Path Parameters

NameTypeDescription
folder_id*
string (UUID)Folder ID

Response Fields

NameTypeDescription
id*
string (UUID)Folder ID
bucket_id*
string (UUID)Owning bucket
parent_folder_id*
string | nullParent folder, or null at bucket root
name*
stringFolder name
pipeline_config
object | nullFolder-scoped pipeline configuration overrides
resolved_pipeline_config*
PipelineConfigV2Effective canonical-v2 config after bucket and full folder ancestry are applied
curl https://platform.ergondata.ai/api/v1/buckets/folders/{folder_id} \
  -H "Authorization: Bearer {token}"

Response

200 OK
{
  "id": "a1b2c3d4-e5f6-7890-abcd-ef1234567890",
  "company_id": "c0ffee00-cafe-babe-dead-beefcafebabe",
  "bucket_id": "f7a8b9c0-1234-5678-9abc-def012345678",
  "parent_folder_id": null,
  "name": "NDAs",
  "description": null,
  "pipeline_config": null,
  "resolved_pipeline_config": {
    "version": 2,
    "auto_process": false,
    "preprocess": {
      "native_text_min_chars": 100,
      "native_text_min_lines": 3,
      "rotation": "auto",
      "raster_dpi": 150,
      "raster_batch_size": 2
    },
    "ocr": {
      "mode": "auto",
      "forms": false,
      "tables": false,
      "signatures": false,
      "reuse_on_reprocess": true
    },
    "analysis": {
      "describe": { "enabled": false, "prompt": null, "key_facts": true, "detailed": false },
      "schemas": [],
      "grouping": "none",
      "evidence_locations": false,
      "grouping_visual_fallback": true
    },
    "embedding": { "enabled": false, "source": "extracted_text" }
  },
  "system_managed": false,
  "capabilities": { "can_upload_file": true, "can_create_folder": true, "can_edit": true },
  "created_at": "2026-04-12T09:20:00Z",
  "updated_at": "2026-04-12T09:20:00Z"
}
PATCH/api/v1/buckets/folders/{folder_id}

Rename Folder

Update a folder's name, description, and/or pipeline_config. Requires buckets:folders:metadata:edit on the folder.

Bearer token required.

Path Parameters

NameTypeDescription
folder_id*
string (UUID)Folder ID

Request Body

NameTypeDescription
name
string | nullNew folder name (1–500 characters)
description
string | nullNew description (max 5000 characters)
pipeline_config
object | nullSparse canonical v2 folder override. It deep-merges over the bucket config; null clears the override.

Response Fields

NameTypeDescription
id*
string (UUID)Folder ID
name*
stringUpdated folder name
curl -X PATCH https://platform.ergondata.ai/api/v1/buckets/folders/{folder_id} \
  -H "Authorization: Bearer {token}" \
  -H "Content-Type: application/json" \
  -d '{"name": "Signed NDAs"}'

Response

200 OK
{
  "id": "a1b2c3d4-e5f6-7890-abcd-ef1234567890",
  "company_id": "c0ffee00-cafe-babe-dead-beefcafebabe",
  "bucket_id": "f7a8b9c0-1234-5678-9abc-def012345678",
  "parent_folder_id": null,
  "name": "Signed NDAs",
  "description": null,
  "pipeline_config": null,
  "system_managed": false,
  "created_at": "2026-04-12T09:20:00Z",
  "updated_at": "2026-04-12T12:00:00Z"
}
DELETE/api/v1/buckets/folders/{folder_id}

Delete Folder

Delete a folder and record an audit event. Requires buckets:folders:delete.

Bearer token required.

Path Parameters

NameTypeDescription
folder_id*
string (UUID)Folder ID
curl -X DELETE https://platform.ergondata.ai/api/v1/buckets/folders/{folder_id} \
  -H "Authorization: Bearer {token}"

Response

204 No Content
GET/api/v1/buckets/folders/{folder_id}/folders

List Child Folders

List folders nested directly under another folder.

Bearer token required.

Path Parameters

NameTypeDescription
folder_id*
string (UUID)Parent folder ID

Response Fields

NameTypeDescription
[]*
FolderResponse[]Child folders
curl https://platform.ergondata.ai/api/v1/buckets/folders/{folder_id}/folders \
  -H "Authorization: Bearer {token}"

Response

200 OK
[
  {
    "id": "b2c3d4e5-f6a7-8901-bcde-f23456789012",
    "company_id": "c0ffee00-cafe-babe-dead-beefcafebabe",
    "bucket_id": "f7a8b9c0-1234-5678-9abc-def012345678",
    "parent_folder_id": "a1b2c3d4-e5f6-7890-abcd-ef1234567890",
    "name": "2026",
    "description": null,
    "pipeline_config": null,
    "system_managed": false,
    "created_at": "2026-04-12T09:25:00Z",
    "updated_at": "2026-04-12T09:25:00Z"
  }
]
POST/api/v1/buckets/folders/{folder_id}/folders

Create Child Folder

Create a folder nested under another folder. Requires buckets:folders:folders:create on the parent folder.

Bearer token required.

Path Parameters

NameTypeDescription
folder_id*
string (UUID)Parent folder ID

Request Body

NameTypeDescription
name*
stringFolder name (1–500 characters)
description
string | nullOptional folder description (max 5000 characters)

Response Fields

NameTypeDescription
id*
string (UUID)Folder ID
parent_folder_id*
string (UUID)Parent folder ID
name*
stringFolder name
curl -X POST https://platform.ergondata.ai/api/v1/buckets/folders/{folder_id}/folders \
  -H "Authorization: Bearer {token}" \
  -H "Content-Type: application/json" \
  -d '{"name": "2026"}'

Response

201 Created
{
  "id": "b2c3d4e5-f6a7-8901-bcde-f23456789012",
  "company_id": "c0ffee00-cafe-babe-dead-beefcafebabe",
  "bucket_id": "f7a8b9c0-1234-5678-9abc-def012345678",
  "parent_folder_id": "a1b2c3d4-e5f6-7890-abcd-ef1234567890",
  "name": "2026",
  "description": null,
  "pipeline_config": null,
  "system_managed": false,
  "created_at": "2026-04-12T09:25:00Z",
  "updated_at": "2026-04-12T09:25:00Z"
}
POST/api/v1/buckets/folders/{folder_id}/pipeline/schemas/generate

Generate Folder Pipeline Schema

Infer a JSON Schema dict for a folder-scoped pipeline config from a natural-language prompt. Requires buckets:folders:pipeline:edit on the folder.

Bearer token required.

Path Parameters

NameTypeDescription
folder_id*
string (UUID)Folder ID

Request Body

NameTypeDescription
prompt*
stringNatural-language description of the fields to extract (min 1 char)
name
string | nullOptional schema name included as context

Response Fields

NameTypeDescription
json_schema*
objectGenerated JSON Schema ready for the folder pipeline_config
rationale*
stringOne-sentence explanation of the schema choices
curl -X POST https://platform.ergondata.ai/api/v1/buckets/folders/{folder_id}/pipeline/schemas/generate \
  -H "Authorization: Bearer {token}" \
  -H "Content-Type: application/json" \
  -d '{"prompt": "Extract the counterparty name and effective date"}'

Response

200 OK
{
  "json_schema": {
    "type": "object",
    "properties": {
      "counterparty_name": { "type": "string" },
      "effective_date": { "type": "string", "format": "date" }
    }
  },
  "rationale": "Two scalar fields capture the counterparty and the date the agreement takes effect."
}

Documents

List, fetch, update metadata and associations, copy, move, and delete files. File content and intelligence reads live in the Upload & download and Runs & results sections.

GET/api/v1/buckets/buckets/{bucket_id}/files

List Files In Bucket

Paginated files in a bucket, optionally filtered by filename substring and folder. Use folder_id='root' for files at the bucket root, or omit it to list all visible files in the bucket.

Bearer token required.

Path Parameters

NameTypeDescription
bucket_id*
string (UUID)Bucket ID

Query Parameters

NameTypeDescription
limit
integerPage size (1–500)Default: 50
offset
integerOffset for paginationDefault: 0
q
string | nullCase-insensitive filename filter
folder_id
string | nullFilter to a folder. Use the literal 'root' for files at the bucket root; omit to list all visible files

Response Fields

NameTypeDescription
files*
FileResponse[]Files in this page
total*
integerTotal matching files
curl "https://platform.ergondata.ai/api/v1/buckets/buckets/{bucket_id}/files?limit=20&folder_id=root&q=invoice" \
  -H "Authorization: Bearer {token}"

Response

200 OK
{
  "files": [
    {
      "id": "d0c0d0c0-1111-2222-3333-444455556666",
      "bucket_id": "f7a8b9c0-1234-5678-9abc-def012345678",
      "folder_id": null,
      "company_id": "c0ffee00-cafe-babe-dead-beefcafebabe",
      "visibility": "bucket",
      "filename": "invoice-acme-042.pdf",
      "content_type": "application/pdf",
      "status": "completed",
      "description": "Q1 vendor invoice",
      "detailed_description": null,
      "page_count": 3,
      "size_bytes": 524288,
      "upload_batch_id": null,
      "associations": [
        {
          "id": "aa11bb22-cc33-dd44-ee55-ff6677889900",
          "entity_type": "vendor",
          "entity_id": "acme-corp",
          "created_at": "2026-04-12T08:00:00Z"
        }
      ],
      "capabilities": { "can_edit": true, "can_move": true, "can_delete": true },
      "created_at": "2026-04-12T07:55:10Z",
      "updated_at": "2026-04-12T08:01:02Z"
    }
  ],
  "total": 1
}
GET/api/v1/buckets/files

List All Files

List files across every bucket the caller can access; each item includes bucket_name.

Bearer token required.

Query Parameters

NameTypeDescription
limit
integerPage size (1–500)Default: 50
offset
integerOffset for paginationDefault: 0
q
string | nullFilename filter

Response Fields

NameTypeDescription
files*
FileWithBucketResponse[]Files with an extra bucket_name field
total*
integerTotal matching files
curl "https://platform.ergondata.ai/api/v1/buckets/files?limit=10&offset=0" \
  -H "Authorization: Bearer {token}"

Response

200 OK
{
  "files": [
    {
      "id": "d0c0d0c0-1111-2222-3333-444455556666",
      "bucket_id": "f7a8b9c0-1234-5678-9abc-def012345678",
      "bucket_name": "Contracts 2026",
      "folder_id": null,
      "company_id": "c0ffee00-cafe-babe-dead-beefcafebabe",
      "visibility": "bucket",
      "filename": "invoice-acme-042.pdf",
      "content_type": "application/pdf",
      "status": "completed",
      "description": "Q1 vendor invoice",
      "page_count": 3,
      "size_bytes": 524288,
      "associations": [],
      "created_at": "2026-04-12T07:55:10Z",
      "updated_at": "2026-04-12T08:01:02Z"
    }
  ],
  "total": 1
}
GET/api/v1/buckets/files/{file_id}

Get File

Retrieve file metadata, status, associations, and capabilities.

Bearer token required.

Path Parameters

NameTypeDescription
file_id*
string (UUID)File ID

Response Fields

NameTypeDescription
id*
string (UUID)File ID
bucket_id*
string (UUID) | nullOwning bucket
folder_id
string (UUID) | nullOwning folder, or null at bucket root
visibility*
stringVisibility scope (e.g. bucket)
filename*
stringFilename
content_type*
stringMIME type
status*
stringProcessing status (pending, processing, completed, failed, …)
page_count*
integer | nullPage count once known
associations
AssociationResponse[]Entity links (entity_type, entity_id)
curl https://platform.ergondata.ai/api/v1/buckets/files/{file_id} \
  -H "Authorization: Bearer {token}"

Response

200 OK
{
  "id": "d0c0d0c0-1111-2222-3333-444455556666",
  "bucket_id": "f7a8b9c0-1234-5678-9abc-def012345678",
  "folder_id": null,
  "company_id": "c0ffee00-cafe-babe-dead-beefcafebabe",
  "visibility": "bucket",
  "filename": "invoice-acme-042.pdf",
  "content_type": "application/pdf",
  "status": "completed",
  "description": "Q1 vendor invoice",
  "detailed_description": null,
  "page_count": 3,
  "size_bytes": 524288,
  "upload_batch_id": null,
  "process_skip_reason": null,
  "associations": [
    {
      "id": "aa11bb22-cc33-dd44-ee55-ff6677889900",
      "entity_type": "vendor",
      "entity_id": "acme-corp",
      "created_at": "2026-04-12T08:00:00Z"
    }
  ],
  "capabilities": { "can_edit": true, "can_move": true, "can_copy": true, "can_delete": true, "can_process": true },
  "created_at": "2026-04-12T07:55:10Z",
  "updated_at": "2026-04-12T08:01:02Z"
}
PATCH/api/v1/buckets/files/{file_id}

Update File

Update a file's filename and/or description, and add or remove entity associations.

Bearer token required.

Path Parameters

NameTypeDescription
file_id*
string (UUID)File ID

Request Body

NameTypeDescription
filename
string | nullNew filename (1–500 characters)
description
string | nullNew file description
associations
AssociationPatchPayload | nullAdd and/or remove entity links

Response Fields

NameTypeDescription
id*
string (UUID)File ID
filename*
stringUpdated filename
associations
AssociationResponse[]Current associations after the patch
curl -X PATCH https://platform.ergondata.ai/api/v1/buckets/files/{file_id} \
  -H "Authorization: Bearer {token}" \
  -H "Content-Type: application/json" \
  -d '{
    "description": "Q1 vendor invoice (reviewed)",
    "associations": { "add": [{ "entity_type": "case", "entity_id": "42" }] }
  }'

Response

200 OK
{
  "id": "d0c0d0c0-1111-2222-3333-444455556666",
  "bucket_id": "f7a8b9c0-1234-5678-9abc-def012345678",
  "folder_id": null,
  "company_id": "c0ffee00-cafe-babe-dead-beefcafebabe",
  "visibility": "bucket",
  "filename": "invoice-acme-042.pdf",
  "content_type": "application/pdf",
  "status": "completed",
  "description": "Q1 vendor invoice (reviewed)",
  "page_count": 3,
  "associations": [
    {
      "id": "cc00dd11-ee22-ff33-4455-667788990011",
      "entity_type": "case",
      "entity_id": "42",
      "created_at": "2026-04-12T12:30:00Z"
    }
  ],
  "created_at": "2026-04-12T07:55:10Z",
  "updated_at": "2026-04-12T12:30:00Z"
}
DELETE/api/v1/buckets/files/{file_id}

Delete File

Delete a file and its derived results. Requires buckets:files:delete.

Bearer token required.

Path Parameters

NameTypeDescription
file_id*
string (UUID)File ID
curl -X DELETE https://platform.ergondata.ai/api/v1/buckets/files/{file_id} \
  -H "Authorization: Bearer {token}"

Response

204 No Content
POST/api/v1/buckets/files/{file_id}/copy

Copy File

Copy a file into a target bucket and optional folder. Requires buckets:files:copy on the source and buckets:files:create on the target.

Bearer token required.

Path Parameters

NameTypeDescription
file_id*
string (UUID)Source file ID

Request Body

NameTypeDescription
target_bucket_id*
string (UUID)Destination bucket
target_folder_id
string (UUID) | nullDestination folder, or null for the bucket root
rerun_pipeline
booleanRe-run the extraction pipeline on the copyDefault: true

Response Fields

NameTypeDescription
id*
string (UUID)New (copied) file ID
bucket_id*
string (UUID)Destination bucket
curl -X POST https://platform.ergondata.ai/api/v1/buckets/files/{file_id}/copy \
  -H "Authorization: Bearer {token}" \
  -H "Content-Type: application/json" \
  -d '{
    "target_bucket_id": "b1b1b1b1-2222-3333-4444-555566667777",
    "target_folder_id": null,
    "rerun_pipeline": true
  }'

Response

200 OK
{
  "id": "e3e3e3e3-4444-5555-6666-777788889999",
  "bucket_id": "b1b1b1b1-2222-3333-4444-555566667777",
  "folder_id": null,
  "company_id": "c0ffee00-cafe-babe-dead-beefcafebabe",
  "visibility": "bucket",
  "filename": "invoice-acme-042.pdf",
  "content_type": "application/pdf",
  "status": "processing",
  "description": "Q1 vendor invoice",
  "page_count": 3,
  "associations": [],
  "created_at": "2026-04-12T13:00:00Z",
  "updated_at": "2026-04-12T13:00:00Z"
}
POST/api/v1/buckets/files/{file_id}/move

Move File

Move a file to a different bucket or folder. Requires buckets:files:move on the source and buckets:files:create on the target.

Bearer token required.

Path Parameters

NameTypeDescription
file_id*
string (UUID)File ID

Request Body

NameTypeDescription
target_bucket_id*
string (UUID)Destination bucket
target_folder_id
string (UUID) | nullDestination folder, or null for the bucket root

Response Fields

NameTypeDescription
id*
string (UUID)File ID (unchanged)
bucket_id*
string (UUID)New owning bucket
folder_id
string (UUID) | nullNew owning folder
curl -X POST https://platform.ergondata.ai/api/v1/buckets/files/{file_id}/move \
  -H "Authorization: Bearer {token}" \
  -H "Content-Type: application/json" \
  -d '{
    "target_bucket_id": "f7a8b9c0-1234-5678-9abc-def012345678",
    "target_folder_id": "a1b2c3d4-e5f6-7890-abcd-ef1234567890"
  }'

Response

200 OK
{
  "id": "d0c0d0c0-1111-2222-3333-444455556666",
  "bucket_id": "f7a8b9c0-1234-5678-9abc-def012345678",
  "folder_id": "a1b2c3d4-e5f6-7890-abcd-ef1234567890",
  "company_id": "c0ffee00-cafe-babe-dead-beefcafebabe",
  "visibility": "bucket",
  "filename": "invoice-acme-042.pdf",
  "content_type": "application/pdf",
  "status": "completed",
  "description": "Q1 vendor invoice",
  "page_count": 3,
  "associations": [],
  "created_at": "2026-04-12T07:55:10Z",
  "updated_at": "2026-04-12T13:10:00Z"
}
GET/api/v1/buckets/files/{file_id}/transfer-destinations

List Transfer Destinations

List the buckets and folders the caller may move or copy this file into. Drives the destination picker for move/copy flows.

Bearer token required.

Path Parameters

NameTypeDescription
file_id*
string (UUID)File ID

Query Parameters

NameTypeDescription
operation*
stringEither 'move' or 'copy' (matches the regex ^(move|copy)$)

Response Fields

NameTypeDescription
destinations*
FileTransferDestination[]Eligible targets (bucket_id, bucket_name, folder_id, folder_path, resource, label)
curl "https://platform.ergondata.ai/api/v1/buckets/files/{file_id}/transfer-destinations?operation=move" \
  -H "Authorization: Bearer {token}"

Response

200 OK
{
  "destinations": [
    {
      "bucket_id": "b1b1b1b1-2222-3333-4444-555566667777",
      "bucket_name": "Archive",
      "folder_id": "a1b2c3d4-e5f6-7890-abcd-ef1234567890",
      "folder_path": ["NDAs", "2026"],
      "resource": "org/c0ffee00-cafe-babe-dead-beefcafebabe/bucket/b1b1b1b1-2222-3333-4444-555566667777/folder/a1b2c3d4-e5f6-7890-abcd-ef1234567890",
      "label": "Archive / NDAs / 2026"
    }
  ]
}

Upload & download

Presigned uploads, multipart and batch upload, base64 content upload, in-place content replacement, and downloads. Uploads accept only auto_process; use Process Files after upload for nested sparse v2 per-run overrides. The base64 upload is agent-facing; browser transfer flows are not agent tools.

POST/api/v1/buckets/buckets/{bucket_id}/upload-url

Request Upload URL

Return a time-limited presigned PUT URL and object_key for direct storage upload. PUT the bytes to upload_url, then call Confirm Upload.

Bearer token required.

Path Parameters

NameTypeDescription
bucket_id*
string (UUID)Target bucket ID

Request Body

NameTypeDescription
filename*
stringOriginal filename (1–500 chars)
content_type*
stringMIME type (1–200 chars)
size*
integerFile size in bytes (must be > 0, within server max)
folder_id
string (UUID) | nullTarget folder; omit for the bucket root
associations
AssociationInput[] | nullOptional links applied on confirm
auto_process
boolean | nullOverride the bucket/folder pipeline auto-processing setting

Response Fields

NameTypeDescription
upload_url*
stringShort-lived presigned PUT URL — use it exactly as returned; do not parse, cache, or reconstruct it.
object_key*
stringStorage key; pass to Confirm Upload
expires_in*
integerURL lifetime in seconds
curl -X POST https://platform.ergondata.ai/api/v1/buckets/buckets/{bucket_id}/upload-url \
  -H "Authorization: Bearer {token}" \
  -H "Content-Type: application/json" \
  -d '{
    "filename": "scan.pdf",
    "content_type": "application/pdf",
    "size": 524288,
    "associations": [{ "entity_type": "project", "entity_id": "proj-7f3a" }]
  }'

Response

200 OK
{
  "upload_url": "https://storage.example.com/bucket/buckets/f7a8b9c0-1234-5678-9abc-def012345678/files/9c4e5f6a-7777-8888-9999-aaaabbbbcccc/raw/scan.pdf?X-Amz-Algorithm=AWS4-HMAC-SHA256&X-Amz-Expires=300",
  "object_key": "buckets/f7a8b9c0-1234-5678-9abc-def012345678/files/9c4e5f6a-7777-8888-9999-aaaabbbbcccc/raw/scan.pdf",
  "expires_in": 300
}
POST/api/v1/buckets/buckets/{bucket_id}/confirm

Confirm Upload

Create the file record after a successful PUT to the presigned upload URL.

Bearer token required.

Path Parameters

NameTypeDescription
bucket_id*
string (UUID)Bucket ID (must match object_key prefix)

Request Body

NameTypeDescription
object_key*
stringKey returned from Request Upload URL
filename*
stringFilename
content_type*
stringMIME type
size*
integerUploaded size in bytes (> 0)
folder_id
string (UUID) | nullTarget folder; omit for the bucket root
associations
AssociationInput[] | nullEntity links for the new file
auto_process
boolean | nullOverride the bucket/folder pipeline auto-processing setting

Response Fields

NameTypeDescription
id*
string (UUID)New file ID
status*
stringInitial status
curl -X POST https://platform.ergondata.ai/api/v1/buckets/buckets/{bucket_id}/confirm \
  -H "Authorization: Bearer {token}" \
  -H "Content-Type: application/json" \
  -d '{
    "object_key": "buckets/f7a8b9c0-1234-5678-9abc-def012345678/files/9c4e5f6a-7777-8888-9999-aaaabbbbcccc/raw/scan.pdf",
    "filename": "scan.pdf",
    "content_type": "application/pdf",
    "size": 524288
  }'

Response

200 OK
{
  "id": "9c4e5f6a-7777-8888-9999-aaaabbbbcccc",
  "bucket_id": "f7a8b9c0-1234-5678-9abc-def012345678",
  "folder_id": null,
  "company_id": "c0ffee00-cafe-babe-dead-beefcafebabe",
  "visibility": "bucket",
  "filename": "scan.pdf",
  "content_type": "application/pdf",
  "status": "pending",
  "description": null,
  "page_count": null,
  "size_bytes": 524288,
  "associations": [],
  "created_at": "2026-04-12T14:22:18Z",
  "updated_at": "2026-04-12T14:22:18Z"
}
POST/api/v1/buckets/buckets/{bucket_id}/upload

Direct Upload

Multipart upload: a file part plus optional associations_json (JSON array), folder_id, and auto_process form fields.

Bearer token required.

Path Parameters

NameTypeDescription
bucket_id*
string (UUID)Target bucket ID

Request Body

NameTypeDescription
file*
file (multipart)File binary
associations_json
string (JSON) | nullJSON array, e.g. [{"entity_type":"case","entity_id":"42"}]
folder_id
string | nullTarget folder; omit for the bucket root
auto_process
boolean | nullOverride the bucket/folder pipeline auto-processing setting

Response Fields

NameTypeDescription
id*
string (UUID)New file ID
status*
stringInitial status
curl -X POST https://platform.ergondata.ai/api/v1/buckets/buckets/{bucket_id}/upload \
  -H "Authorization: Bearer {token}" \
  -F "file=@./report.pdf;type=application/pdf" \
  -F 'associations_json=[{"entity_type":"case","entity_id":"42"}]'

Response

200 OK
{
  "id": "b0b0b0b0-aaaa-bbbb-cccc-dddddddddddd",
  "bucket_id": "f7a8b9c0-1234-5678-9abc-def012345678",
  "folder_id": null,
  "company_id": "c0ffee00-cafe-babe-dead-beefcafebabe",
  "visibility": "bucket",
  "filename": "report.pdf",
  "content_type": "application/pdf",
  "status": "pending",
  "description": null,
  "page_count": null,
  "size_bytes": 81234,
  "associations": [
    {
      "id": "cc00dd11-ee22-ff33-4455-667788990011",
      "entity_type": "case",
      "entity_id": "42",
      "created_at": "2026-04-12T15:10:00Z"
    }
  ],
  "created_at": "2026-04-12T15:10:00Z",
  "updated_at": "2026-04-12T15:10:00Z"
}
POST/api/v1/buckets/buckets/{bucket_id}/upload-batch

Batch Upload

Upload multiple files in one multipart request. All files share an upload_batch_id and optional associations, but each is handed to its own pipeline run. Storage rejections fail the whole batch; pipeline rejections are returned in skipped without failing siblings.

Bearer token required.

Path Parameters

NameTypeDescription
bucket_id*
string (UUID)Target bucket ID

Request Body

NameTypeDescription
files*
file[] (multipart)One or more file binaries
associations_json
string (JSON) | nullJSON array applied to all files, e.g. [{"entity_type":"case","entity_id":"42"}]
folder_id
string | nullTarget folder; omit for the bucket root
auto_process
boolean | nullOverride the bucket/folder pipeline auto-processing setting

Response Fields

NameTypeDescription
upload_batch_id*
string (UUID)Shared batch identifier for all uploaded files
files*
FileResponse[]Created file records
runs
RunRef[]Processing runs created (one per accepted file)
skipped
SkippedFile[]Files rejected by pipeline validation (file_id, decision, reason)
curl -X POST https://platform.ergondata.ai/api/v1/buckets/buckets/{bucket_id}/upload-batch \
  -H "Authorization: Bearer {token}" \
  -F "files=@./invoice-01.pdf;type=application/pdf" \
  -F "files=@./invoice-02.pdf;type=application/pdf" \
  -F 'associations_json=[{"entity_type":"project","entity_id":"proj-7f3a"}]' \
  -F "auto_process=true"

Response

201 Created
{
  "upload_batch_id": "c1c1c1c1-dddd-eeee-ffff-000011112222",
  "files": [
    {
      "id": "b0b0b0b0-aaaa-bbbb-cccc-dddddddddddd",
      "bucket_id": "f7a8b9c0-1234-5678-9abc-def012345678",
      "folder_id": null,
      "company_id": "c0ffee00-cafe-babe-dead-beefcafebabe",
      "visibility": "bucket",
      "filename": "invoice-01.pdf",
      "content_type": "application/pdf",
      "status": "processing",
      "description": null,
      "page_count": null,
      "size_bytes": 524288,
      "upload_batch_id": "c1c1c1c1-dddd-eeee-ffff-000011112222",
      "associations": [],
      "created_at": "2026-04-12T15:10:00Z",
      "updated_at": "2026-04-12T15:10:00Z"
    }
  ],
  "runs": [
    {
      "run_id": "e10e10e1-aaaa-bbbb-cccc-dddddddddddd",
      "file_id": "b0b0b0b0-aaaa-bbbb-cccc-dddddddddddd",
      "status": "pending"
    }
  ],
  "skipped": []
}
POST/api/v1/buckets/buckets/{bucket_id}/upload-content

Upload Content

Create a file from base64-encoded bytes — convenient for agents and programmatic clients that already hold the content in memory.

Bearer token required.

Path Parameters

NameTypeDescription
bucket_id*
string (UUID)Target bucket ID

Request Body

NameTypeDescription
filename*
stringStored filename (1–500 chars)
content_base64*
stringBase64-encoded file bytes
content_type
stringMIME type (max 200 chars)Default: application/octet-stream
description
string | nullOptional file description
folder_id
string (UUID) | nullTarget folder; omit for the bucket root
associations
AssociationInput[] | nullOptional entity links
auto_process
boolean | nullOverride the bucket/folder pipeline auto-processing setting

Response Fields

NameTypeDescription
id*
string (UUID)New file ID
status*
stringInitial status
curl -X POST https://platform.ergondata.ai/api/v1/buckets/buckets/{bucket_id}/upload-content \
  -H "Authorization: Bearer {token}" \
  -H "Content-Type: application/json" \
  -d '{
    "filename": "notes.txt",
    "content_base64": "SGVsbG8sIEJ1Y2tldHMu",
    "content_type": "text/plain",
    "description": "Pasted notes"
  }'

Response

201 Created
{
  "id": "e2e2e2e2-3333-4444-5555-666677778888",
  "bucket_id": "f7a8b9c0-1234-5678-9abc-def012345678",
  "folder_id": null,
  "company_id": "c0ffee00-cafe-babe-dead-beefcafebabe",
  "visibility": "bucket",
  "filename": "notes.txt",
  "content_type": "text/plain",
  "status": "pending",
  "description": "Pasted notes",
  "page_count": null,
  "size_bytes": 15,
  "associations": [],
  "created_at": "2026-04-12T16:05:33Z",
  "updated_at": "2026-04-12T16:05:33Z"
}
POST/api/v1/buckets/files/{file_id}/replace-content

Replace File Content

Agent-callable JSON/base64 update that atomically replaces an existing file's bytes in place. Filename, associations, bucket, and surrounding metadata are untouched; only content_type/size and updated_at change. Requires buckets:files:edit.

Bearer token required.

Path Parameters

NameTypeDescription
file_id*
string (UUID)File ID

Request Body

NameTypeDescription
content_base64*
stringBase64-encoded replacement bytes (min length 1)
content_type
stringMIME type (max 200 chars)Default: application/octet-stream

Response Fields

NameTypeDescription
id*
string (UUID)File ID (unchanged)
size_bytes
integer | nullNew content size
updated_at*
datetimeBumped on replace
curl -X POST https://platform.ergondata.ai/api/v1/buckets/files/{file_id}/replace-content \
  -H "Authorization: Bearer {token}" \
  -H "Content-Type: application/json" \
  -d '{
    "content_base64": "SGVsbG8sIHJldmlzZWQu",
    "content_type": "text/plain"
  }'

Response

200 OK
{
  "id": "e2e2e2e2-3333-4444-5555-666677778888",
  "bucket_id": "f7a8b9c0-1234-5678-9abc-def012345678",
  "folder_id": null,
  "company_id": "c0ffee00-cafe-babe-dead-beefcafebabe",
  "visibility": "bucket",
  "filename": "notes.txt",
  "content_type": "text/plain",
  "status": "pending",
  "description": "Pasted notes",
  "page_count": null,
  "size_bytes": 15,
  "associations": [],
  "created_at": "2026-04-12T16:05:33Z",
  "updated_at": "2026-04-12T16:40:00Z"
}
GET/api/v1/buckets/files/{file_id}/download-url

Request Download URL

Return a time-limited presigned GET URL for the stored object.

Bearer token required.

Path Parameters

NameTypeDescription
file_id*
string (UUID)File ID

Response Fields

NameTypeDescription
download_url*
stringShort-lived presigned GET URL — use it exactly as returned; do not parse, cache, or reconstruct it.
expires_in*
integerURL lifetime in seconds
curl https://platform.ergondata.ai/api/v1/buckets/files/{file_id}/download-url \
  -H "Authorization: Bearer {token}"

Response

200 OK
{
  "download_url": "https://storage.example.com/bucket/objects/d0c0d0c0-1111-2222-3333-444455556666/raw?X-Amz-Algorithm=AWS4-HMAC-SHA256&X-Amz-Expires=900",
  "expires_in": 900
}
GET/api/v1/buckets/files/{file_id}/file

Download File

Stream the raw file bytes through the API with Content-Type and Content-Disposition set.

Bearer token required.

Path Parameters

NameTypeDescription
file_id*
string (UUID)File ID

Response Fields

NameTypeDescription
(body)*
application/octet-stream | …Raw file content
curl -L -o invoice.pdf \
  https://platform.ergondata.ai/api/v1/buckets/files/{file_id}/file \
  -H "Authorization: Bearer {token}"

Response

200 OK

Hybrid (vector + lexical) search across embedded file content, merged via Reciprocal Rank Fusion and pre-filtered to the buckets the caller can view.

GET/api/v1/buckets/search/files

Search Files

Run a hybrid search across the org's files. Pass q multiple times to search across query variants. Results are pre-filtered to accessible buckets; narrow further with bucket_id or restrict to a single file with file_id.

Bearer token required.

Query Parameters

NameTypeDescription
q*
string[]One or more query strings (repeat ?q=foo&q=bar; cap of 8, each at least 2 characters)
limit
integerMax resultsDefault: 10
min_similarity
number | nullMinimum cosine similarity (0–1) for the vector lane; lexical matches are still included before rank fusionDefault: 0.3
threshold
number | nullDeprecated alias for min_similarity
bucket_id
string (UUID) | nullNarrow the search to a single accessible bucket
file_id
string (UUID) | nullRestrict the search to a single file (composes with bucket_id)
snippet_chars
integer | nullMax length of each result's content_text snippet; set 0 to suppress snippets

Response Fields

NameTypeDescription
query*
stringEcho of the primary query
queries*
string[]All query variants used
results*
SearchResult[]Flat ranked matches
groups
SearchResultGroup[]File-grouped view rolling hits up by result slice (file_id, pages_hit, slices, top scores)
curl "https://platform.ergondata.ai/api/v1/buckets/search/files?q=payment%20terms&limit=5&min_similarity=0.35" \
  -H "Authorization: Bearer {token}"

Response

200 OK
{
  "query": "payment terms",
  "queries": ["payment terms"],
  "results": [
    {
      "file_id": "d0c0d0c0-1111-2222-3333-444455556666",
      "filename": "invoice-acme-042.pdf",
      "bucket_id": "f7a8b9c0-1234-5678-9abc-def012345678",
      "page_number": 1,
      "content_text": "Payment terms: Net 30 from invoice date. Late fees apply after 45 days at 1.5% monthly.",
      "similarity": 0.812,
      "lex_score": 0.41,
      "rrf_score": 0.0312,
      "model": "platform"
    }
  ],
  "groups": [
    {
      "file_id": "d0c0d0c0-1111-2222-3333-444455556666",
      "filename": "invoice-acme-042.pdf",
      "bucket_id": "f7a8b9c0-1234-5678-9abc-def012345678",
      "pages_hit": [1],
      "top_similarity": 0.812,
      "top_rrf_score": 0.0312,
      "slices": []
    }
  ]
}

Runs & results

Trigger configurable LLM extraction runs, inspect run status, and read per-file outputs: extraction results, page outlines, key-value fields, and extracted text.

POST/api/v1/buckets/files/process

Process Files

Run one independent pipeline per accepted file. Canonical v2 sections are deep sparse per-run overrides over the resolved bucket/folder config: omission inherits, while false, null, and empty lists override. OCR/features, analysis/grouping/evidence, and embeddings are independently gated and may add provider cost.

Bearer token required.

Request Body

NameTypeDescription
file_ids*
string[] (UUID)Files to process
version
2 | nullCanonical config version; omit to have the server snapshot version 2
preprocess
PipelinePreprocessOverride | nullSparse native-text thresholds, rotation, raster DPI (120–300; default 150), and bounded raster batch overrides
ocr
PipelineOCROverride | nullmode auto|always|off plus forms/tables/signatures and compatible OCR reuse. Features and evidence may add OCR cost
analysis
PipelineAnalysisOverride | nullSparse describe, schemas, semantic grouping, evidence locations, and bounded visual fallback settings
embedding
PipelineEmbeddingOverride | nullIndependent embedding gate and source: extracted_text, description, or both
reasoning_effort
string | nullOverride the LLM reasoning effort for this run
llm_timeout_seconds
number | nullPer-run LLM timeout in seconds (> 0)

Response Fields

NameTypeDescription
runs
RunRef[]One processing run per accepted file (run_id, file_id, status)
skipped
SkippedFile[]Files refused by pipeline validation (file_id, decision, reason)
upload_batch_id
string | nullBatch identifier when the files were part of one batch
curl -X POST https://platform.ergondata.ai/api/v1/buckets/files/process \
  -H "Authorization: Bearer {token}" \
  -H "Content-Type: application/json" \
  -d '{
    "file_ids": ["d0c0d0c0-1111-2222-3333-444455556666"],
    "version": 2,
    "ocr": { "mode": "auto", "tables": true },
    "analysis": {
      "describe": { "enabled": true, "detailed": true },
      "grouping": "semantic",
      "evidence_locations": true
    },
    "embedding": { "enabled": true, "source": "both" }
  }'

Response

200 OK
{
  "runs": [
    {
      "run_id": "e10e10e1-aaaa-bbbb-cccc-dddddddddddd",
      "file_id": "d0c0d0c0-1111-2222-3333-444455556666",
      "status": "pending"
    }
  ],
  "skipped": [],
  "upload_batch_id": null
}
GET/api/v1/buckets/runs

List Runs

List recent runs for the company, optionally filtered by status. Every run includes its versioned, sanitized structured execution trace.

Bearer token required.

Query Parameters

NameTypeDescription
status
string | nullFilter by run status
limit
integerPage size (1–500)Default: 50
offset
integerOffsetDefault: 0

Response Fields

NameTypeDescription
runs*
RunResponse[]Runs in this response
total*
integerTotal runs matching the filter
curl "https://platform.ergondata.ai/api/v1/buckets/runs?status=completed&limit=20" \
  -H "Authorization: Bearer {token}"

Response

200 OK
{
  "runs": [
    {
      "id": "e10e10e1-aaaa-bbbb-cccc-dddddddddddd",
      "status": "completed",
      "config": {
        "version": 2,
        "ocr": { "reuse_on_reprocess": true },
        "embedding": { "enabled": true, "source": "extracted_text" }
      },
      "triggered_by": "api",
      "error": null,
      "attempt_count": 1,
      "processing_started_at": "2026-04-12T17:40:01Z",
      "run_deadline_at": "2026-04-12T17:55:01Z",
      "lease_expires_at": null,
      "lease_heartbeat_at": null,
      "failure_code": null,
      "failure_class": null,
      "failure_stage": null,
      "failure_details": null,
      "completed_at": "2026-04-12T17:45:12Z",
      "created_at": "2026-04-12T17:40:00Z",
      "execution_trace_version": 2,
      "execution_trace": []
    }
  ],
  "total": 1
}
GET/api/v1/buckets/runs/{run_id}

Get Run

Return run status, config snapshot, attempt and lease/deadline timestamps, stable failure metadata, and the versioned structured execution trace. Trace metadata and errors are bounded and sanitized; lease tokens, provider payloads, prompts, extracted text, raw logs, and stack traces are never returned.

Bearer token required.

Path Parameters

NameTypeDescription
run_id*
string (UUID)Run ID

Response Fields

NameTypeDescription
id*
string (UUID)Run ID
status*
stringRun status
config*
object | nullSparse run config snapshot. New snapshots are canonical v2; historical reads may contain v1 aliases.
triggered_by*
string | nullSource (e.g. api, auto)
error*
string | nullError message if failed
attempt_count*
integerNumber of successfully claimed processing attempts
processing_started_at*
datetime | nullTimestamp of the first processing claim
run_deadline_at*
datetime | nullAbsolute run deadline shared by all retries
lease_expires_at*
datetime | nullCurrent processing lease expiry; null after terminal completion
lease_heartbeat_at*
datetime | nullMost recent successful lease renewal
failure_code*
string | nullStable machine-readable failure code
failure_class*
deterministic | transient | resource | budget | nullOperational failure class
failure_stage*
string | nullPipeline stage associated with the failure
failure_details*
object | nullBounded structured details such as retryability and page numbers
completed_at*
datetime | nullCompletion time if finished
created_at*
datetimeCreation time
execution_trace_version*
integerStructured trace contract version; currently 2
execution_trace*
PipelineTraceEvent[]Append-ordered stage transitions with status, timestamp, duration, attempts, bounded metadata, and sanitized errors
curl https://platform.ergondata.ai/api/v1/buckets/runs/{run_id} \
  -H "Authorization: Bearer {token}"

Response

200 OK
{
  "id": "e10e10e1-aaaa-bbbb-cccc-dddddddddddd",
  "status": "completed",
  "config": {
    "version": 2,
    "ocr": { "mode": "auto", "reuse_on_reprocess": true },
    "analysis": {
      "grouping": "none",
      "schemas": [{
        "name": "file_type",
        "prompt": "Classify this file type",
        "json_schema": { "type": "string" },
        "level": "file",
        "allow_many": false
      }]
    },
    "embedding": { "enabled": true, "source": "extracted_text" }
  },
  "triggered_by": "api",
  "error": null,
  "attempt_count": 1,
  "processing_started_at": "2026-04-12T17:40:01Z",
  "run_deadline_at": "2026-04-12T17:55:01Z",
  "lease_expires_at": null,
  "lease_heartbeat_at": null,
  "failure_code": null,
  "failure_class": null,
  "failure_stage": null,
  "failure_details": null,
  "completed_at": "2026-04-12T17:45:12Z",
  "created_at": "2026-04-12T17:40:00Z",
  "execution_trace_version": 2,
  "execution_trace": [
    {
      "stage": "inspection",
      "status": "completed",
      "timestamp": "2026-04-12T17:40:01Z",
      "duration_ms": 42.7,
      "attempt": 1,
      "metadata": { "page_count": 4 },
      "error": null
    },
    {
      "stage": "persist",
      "status": "completed",
      "timestamp": "2026-04-12T17:45:12Z",
      "duration_ms": 18.3,
      "attempt": 1,
      "metadata": { "output_count": 1 },
      "error": null
    }
  ]
}
GET/api/v1/buckets/files/{file_id}/runs

List File Runs

List processing runs for a specific file. Every run includes the same versioned, sanitized execution trace as Get Run, including active and failed runs that produced no results.

Bearer token required.

Path Parameters

NameTypeDescription
file_id*
string (UUID)File ID

Query Parameters

NameTypeDescription
limit
integerPage size (1–500)Default: 50
offset
integerOffsetDefault: 0

Response Fields

NameTypeDescription
runs*
RunResponse[]Runs for this file
total*
integerTotal runs for this file
curl "https://platform.ergondata.ai/api/v1/buckets/files/{file_id}/runs?limit=10" \
  -H "Authorization: Bearer {token}"

Response

200 OK
{
  "runs": [
    {
      "id": "e10e10e1-aaaa-bbbb-cccc-dddddddddddd",
      "status": "completed",
      "config": {
        "version": 2,
        "analysis": { "grouping": "none" },
        "embedding": { "enabled": true, "source": "extracted_text" }
      },
      "triggered_by": "api",
      "error": null,
      "attempt_count": 1,
      "processing_started_at": "2026-04-12T17:40:01Z",
      "run_deadline_at": "2026-04-12T17:55:01Z",
      "lease_expires_at": null,
      "lease_heartbeat_at": null,
      "failure_code": null,
      "failure_class": null,
      "failure_stage": null,
      "failure_details": null,
      "completed_at": "2026-04-12T17:45:12Z",
      "created_at": "2026-04-12T17:40:00Z",
      "execution_trace_version": 2,
      "execution_trace": []
    }
  ],
  "total": 1
}
GET/api/v1/buckets/files/{file_id}/results

List File Results

Paginated extraction results (slices) for a file, optionally filtered to a single run.

Bearer token required.

Path Parameters

NameTypeDescription
file_id*
string (UUID)File ID

Query Parameters

NameTypeDescription
run_id
string (UUID) | nullFilter to a single pipeline run
limit
integerPage size (1–500)Default: 50
offset
integerOffsetDefault: 0

Response Fields

NameTypeDescription
results*
ResultResponse[]Result records (id, run_id, file_id, filename, schemas, ocr_metadata, split_metadata, page_count)
total*
integerTotal results matching the filter
curl "https://platform.ergondata.ai/api/v1/buckets/files/{file_id}/results?limit=10" \
  -H "Authorization: Bearer {token}"

Response

200 OK
{
  "results": [
    {
      "id": "a3b4c5d6-7890-4123-8abc-def012345678",
      "run_id": "e10e10e1-aaaa-bbbb-cccc-dddddddddddd",
      "file_id": "d0c0d0c0-1111-2222-3333-444455556666",
      "filename": "invoice-acme-042.pdf",
      "output_file_ref": null,
      "schemas": [
        { "name": "vendor_name", "value": "ACME Corp", "level": "file", "confidence": 0.91 }
      ],
      "ocr_metadata": { "extractions": [] },
      "split_metadata": null,
      "page_count": 3,
      "created_at": "2026-04-12T17:45:10Z"
    }
  ],
  "total": 1
}
GET/api/v1/buckets/files/{file_id}/results/{result_id}/download-url

Request Slice Download URL

Agent-callable lookup returning a time-limited presigned GET URL for the assembled split-child PDF of a slice. Returns 404 for flat results that share the parent file — use the file-level download URL instead.

Bearer token required.

Path Parameters

NameTypeDescription
file_id*
string (UUID)File ID
result_id*
string (UUID)Result (slice) ID

Query Parameters

NameTypeDescription
disposition
stringContent-Disposition: inline (default) or attachmentDefault: inline

Response Fields

NameTypeDescription
download_url*
stringPresigned GET URL for the slice file
expires_in*
integerURL lifetime in seconds
curl "https://platform.ergondata.ai/api/v1/buckets/files/{file_id}/results/{result_id}/download-url?disposition=inline" \
  -H "Authorization: Bearer {token}"

Response

200 OK
{
  "download_url": "https://storage.example.com/bucket/runs/e10e10e1-aaaa-bbbb-cccc-dddddddddddd/output/a3b4c5d6-7890-4123-8abc-def012345678.pdf?X-Amz-Algorithm=AWS4-HMAC-SHA256&X-Amz-Expires=900",
  "expires_in": 900
}
GET/api/v1/buckets/files/{file_id}/results/{result_id}/file

Download Slice File

Stream the assembled split-child PDF inline through the API. Returns 404 for flat results — use the file-level file download instead.

Bearer token required.

Path Parameters

NameTypeDescription
file_id*
string (UUID)File ID
result_id*
string (UUID)Result (slice) ID

Response Fields

NameTypeDescription
(body)*
application/pdfRaw slice file content
curl -L -o slice.pdf \
  https://platform.ergondata.ai/api/v1/buckets/files/{file_id}/results/{result_id}/file \
  -H "Authorization: Bearer {token}"

Response

200 OK
GET/api/v1/buckets/results/{result_id}/file

Get Result File

Stream a result's output file by result ID. Supports split-child PDFs and image outputs; Content-Type is inferred from the result filename.

Bearer token required.

Path Parameters

NameTypeDescription
result_id*
string (UUID)Result ID

Response Fields

NameTypeDescription
(body)*
application/pdf | image/*Raw result file content
curl -L -o result.pdf \
  https://platform.ergondata.ai/api/v1/buckets/results/{result_id}/file \
  -H "Authorization: Bearer {token}"

Response

200 OK
GET/api/v1/buckets/files/{file_id}/outline

Get File Outline

High-level map of a file's pipeline output: per-page summaries (text/KV/signature counts), schema values, and a breakdown of contributing result slices. Aggregates every result by default — designed as the first call when investigating a file, returning enough structure to decide where to drill in without transferring extracted text or geometry.

Bearer token required.

Path Parameters

NameTypeDescription
file_id*
string (UUID)File ID

Query Parameters

NameTypeDescription
run_id
string (UUID) | nullNarrow the outline to results from a specific run
result_id
string (UUID) | nullNarrow the outline to a single result slice

Response Fields

NameTypeDescription
file_id*
string (UUID)File ID
filename*
string | nullFilename (null when aggregating slices with different names)
run_id*
string (UUID) | nullRun ID when scoped to a single run
result_id*
string (UUID) | nullResult ID when scoped to a single slice
page_count*
integer | nullTotal pages in the file
schemas*
object | nullAggregated extracted schema fields with values and confidence
pages*
FileOutlinePage[]Per-page summaries (page_number, text_chars, kv_field_count, signature_count, has_extraction)
result_breakdown*
FileOutlineResultSlice[]Contributing slices with per-slice description, slim schemas, and page ranges
parent_description
FileDescriptionPayload | nullWhole-file description from the describe stage (headline, summary, file_type, key_facts)
curl "https://platform.ergondata.ai/api/v1/buckets/files/{file_id}/outline" \
  -H "Authorization: Bearer {token}"

Response

200 OK
{
  "file_id": "d0c0d0c0-1111-2222-3333-444455556666",
  "filename": "invoice-acme-042.pdf",
  "run_id": null,
  "result_id": null,
  "page_count": 3,
  "schemas": [
    { "name": "vendor_name", "value": "ACME Corp", "level": "file", "confidence": 0.91 },
    { "name": "total_amount", "value": "1240.50", "level": "file", "confidence": 0.88 }
  ],
  "pages": [
    { "page_number": 1, "text_chars": 1842, "kv_field_count": 6, "signature_count": 0, "has_extraction": true },
    { "page_number": 2, "text_chars": 2105, "kv_field_count": 12, "signature_count": 0, "has_extraction": true },
    { "page_number": 3, "text_chars": 580, "kv_field_count": 0, "signature_count": 1, "has_extraction": true }
  ],
  "result_breakdown": [
    {
      "result_id": "a3b4c5d6-7890-4123-8abc-def012345678",
      "run_id": "e10e10e1-aaaa-bbbb-cccc-dddddddddddd",
      "filename": "invoice-acme-042.pdf",
      "page_count": 3,
      "page_numbers": [1, 2, 3],
      "extraction_count": 3,
      "description": {
        "headline": "Vendor invoice from ACME Corp",
        "file_type": "invoice",
        "summary": "Three-page invoice covering Q1 services.",
        "key_facts": ["Net 30 payment terms", "Total: $1,240.50"]
      },
      "schemas": [{ "name": "vendor_name", "value": "ACME Corp", "confidence": 0.91 }],
      "kv_field_count": 18,
      "signature_count": 1,
      "created_at": "2026-04-12T17:45:10Z"
    }
  ],
  "parent_description": {
    "headline": "Vendor invoice from ACME Corp",
    "file_type": "invoice",
    "summary": "Three-page invoice covering Q1 services.",
    "key_facts": ["Net 30 payment terms", "Total: $1,240.50"]
  }
}
GET/api/v1/buckets/files/{file_id}/kv

Get File Key-Value Fields

Deduplicated KEY_VALUE_SET fields extracted by the OCR pipeline across all result slices. Requires at least one of key or page. Results are deduplicated by normalized (key, value, page) and sorted by page, then key name.

Bearer token required.

Path Parameters

NameTypeDescription
file_id*
string (UUID)File ID

Query Parameters

NameTypeDescription
key
string | nullCase-insensitive substring on OCR field name (required if page is omitted)
page
integer | nullParent-PDF page number (>= 1; required if key is omitted)
result_id
string (UUID) | nullRestrict to a single result slice
run_id
string (UUID) | nullRestrict to a single pipeline run
min_confidence
numberMinimum confidence threshold (0–1)Default: 0.0
limit
integerMax results (1–200)Default: 50

Response Fields

NameTypeDescription
file_id*
string (UUID)File ID
fields*
FileKvRow[]Deduplicated rows (page_number, key, value, confidence, result_id, duplicate_count)
total_before_dedup*
integerTotal raw matches before deduplication
total_after_dedup*
integerTotal unique matches after deduplication
truncated
booleanWhether results were capped by the limit
curl "https://platform.ergondata.ai/api/v1/buckets/files/{file_id}/kv?key=amount&min_confidence=0.5" \
  -H "Authorization: Bearer {token}"

Response

200 OK
{
  "file_id": "d0c0d0c0-1111-2222-3333-444455556666",
  "fields": [
    {
      "page_number": 1,
      "key": "Total Amount",
      "value": "$1,240.50",
      "confidence": 0.92,
      "result_id": "a3b4c5d6-7890-4123-8abc-def012345678",
      "duplicate_count": 1
    },
    {
      "page_number": 2,
      "key": "Line Amount",
      "value": "$620.25",
      "confidence": 0.88,
      "result_id": "a3b4c5d6-7890-4123-8abc-def012345678",
      "duplicate_count": 2
    }
  ],
  "total_before_dedup": 3,
  "total_after_dedup": 2,
  "truncated": false
}
GET/api/v1/buckets/files/{file_id}/text

Get File Text

Cursor-paginated extracted text across all result slices, ordered by parent-PDF page number. Segments are tagged with result_id and page_number; use the opaque next_cursor token to page through large files.

Bearer token required.

Path Parameters

NameTypeDescription
file_id*
string (UUID)File ID

Query Parameters

NameTypeDescription
page
integer | nullRestrict to a specific parent-PDF page number
result_id
string (UUID) | nullRestrict to a single result slice
run_id
string (UUID) | nullRestrict to a single pipeline run
cursor
string | nullOpaque continuation token from a previous response
max_chars
integerPer-response character cap (1–40000)Default: 10000

Response Fields

NameTypeDescription
file_id*
string (UUID)File ID
segments*
FileTextSegment[]Text segments (result_id, page_number, text, chars)
total_chars_returned*
integerCharacters in this response
next_cursor
string | nullPass as cursor to fetch the next page; null when complete
truncated
booleanWhether more text remains beyond this response
curl "https://platform.ergondata.ai/api/v1/buckets/files/{file_id}/text?max_chars=5000" \
  -H "Authorization: Bearer {token}"

Response

200 OK
{
  "file_id": "d0c0d0c0-1111-2222-3333-444455556666",
  "segments": [
    {
      "result_id": "a3b4c5d6-7890-4123-8abc-def012345678",
      "page_number": 1,
      "text": "ACME Corporation\nInvoice #INV-2026-042\nBill To: Widgets Inc.\nSubtotal: $1,240.50",
      "chars": 78
    }
  ],
  "total_chars_returned": 78,
  "next_cursor": "eyJnIjogNzh9",
  "truncated": true
}

Access & grants

Manage zero-trust access to bucket and folder zones: list eligible principals, available permissions and resource types, create and revoke permission grants, and review or decide inbound connection requests.

GET/api/v1/buckets/buckets/{bucket_id}/access/eligible

List Eligible Principals

Return IAM principals eligible for bucket-level grants (members, API keys, agents, roles).

Bearer token required.

Path Parameters

NameTypeDescription
bucket_id*
string (UUID)Bucket ID

Response Fields

NameTypeDescription
[]*
EligiblePrincipal[]Eligible principals (principal_type, principal_id, label)
curl https://platform.ergondata.ai/api/v1/buckets/buckets/{bucket_id}/access/eligible \
  -H "Authorization: Bearer {token}"

Response

200 OK
[
  {
    "principal_type": "member",
    "principal_id": "u9000000-0000-4000-8000-000000000001",
    "label": "Jane Doe"
  }
]
GET/api/v1/buckets/buckets/{bucket_id}/access/permissions

List Bucket Permissions

Return the permissions that can be granted at bucket level.

Bearer token required.

Path Parameters

NameTypeDescription
bucket_id*
string (UUID)Bucket ID

Response Fields

NameTypeDescription
[]*
PermissionOption[]Permissions (id, name, friendly_name, description, scope_anchor, display_order)
curl https://platform.ergondata.ai/api/v1/buckets/buckets/{bucket_id}/access/permissions \
  -H "Authorization: Bearer {token}"

Response

200 OK
[
  {
    "id": "perm-001",
    "name": "buckets:files:view",
    "friendly_name": "View files",
    "description": "Read files and metadata",
    "scope_anchor": "instance",
    "display_order": 1
  }
]
GET/api/v1/buckets/buckets/{bucket_id}/access/resource-types

List Resource Types

Return the resource-type hierarchy (with edges and associated permissions) for the buckets service. Drives the grant picker.

Bearer token required.

Path Parameters

NameTypeDescription
bucket_id*
string (UUID)Bucket ID

Response Fields

NameTypeDescription
resource_types*
ResourceTypeNode[]Resource-type nodes (id, name, slug, parent_id, children)
resource_type_edges
ResourceTypeEdgeNode[]Directed parent→child edges for multi-parent shapes
permissions*
PermissionOption[]Permissions associated with resource types
curl https://platform.ergondata.ai/api/v1/buckets/buckets/{bucket_id}/access/resource-types \
  -H "Authorization: Bearer {token}"

Response

200 OK
{
  "resource_types": [
    { "id": "rt-001", "name": "Folder", "slug": "folder", "parent_id": "rt-000", "children": [] }
  ],
  "resource_type_edges": [
    { "parent_resource_type_id": "rt-000", "child_resource_type_id": "rt-001" }
  ],
  "permissions": [
    {
      "id": "perm-001",
      "name": "buckets:files:view",
      "friendly_name": "View files",
      "description": "Read files and metadata",
      "scope_anchor": "instance",
      "display_order": 1
    }
  ]
}
GET/api/v1/buckets/buckets/{bucket_id}/access/grants

List Grants

Paginated list of IAM permission grants on the bucket.

Bearer token required.

Path Parameters

NameTypeDescription
bucket_id*
string (UUID)Bucket ID

Query Parameters

NameTypeDescription
page
integerPage number (>= 1)Default: 1
limit
integerPage size (1–500)Default: 100

Response Fields

NameTypeDescription
items*
GrantResponse[]Grants in this page (id, permission_id, name, resource, effect, is_system)
total
integerTotal grants
curl "https://platform.ergondata.ai/api/v1/buckets/buckets/{bucket_id}/access/grants?page=1&limit=50" \
  -H "Authorization: Bearer {token}"

Response

200 OK
{
  "items": [
    {
      "id": "ag-0001-0000-4000-8000-000000000001",
      "permission_id": "perm-001",
      "name": "buckets:files:view",
      "resource": "org/c0ffee00-cafe-babe-dead-beefcafebabe/bucket/f7a8b9c0-1234-5678-9abc-def012345678",
      "effect": "allow",
      "is_system": false,
      "granted_at": "2026-04-12T20:00:00Z"
    }
  ],
  "total": 1,
  "page": 1,
  "limit": 50
}
POST/api/v1/buckets/buckets/{bucket_id}/access/grants

Create Grant

Grant a permission to a principal on this bucket. The resource must stay within the bucket's resource boundary.

Bearer token required.

Path Parameters

NameTypeDescription
bucket_id*
string (UUID)Bucket ID

Request Body

NameTypeDescription
principal_type*
stringOne of member, api_key, agent, or role
principal_id*
string (UUID)Principal ID
permission_id*
string (UUID)Permission ID to grant
resource
string | nullResource path; defaults to the bucket
effect
stringGrant effectDefault: allow

Response Fields

NameTypeDescription
id*
string (UUID)Grant ID
permission_id*
string (UUID)Permission ID
name*
stringPermission name
resource*
stringResource path
effect*
stringGrant effect
is_system*
booleanWhether the grant is system-managed
granted_at*
datetimeGrant creation time
curl -X POST https://platform.ergondata.ai/api/v1/buckets/buckets/{bucket_id}/access/grants \
  -H "Authorization: Bearer {token}" \
  -H "Content-Type: application/json" \
  -d '{
    "principal_type": "member",
    "principal_id": "u9000000-0000-4000-8000-000000000001",
    "permission_id": "perm-001",
    "effect": "allow"
  }'

Response

201 Created
{
  "id": "ag-0002-0000-4000-8000-000000000002",
  "permission_id": "perm-001",
  "name": "buckets:files:view",
  "resource": "org/c0ffee00-cafe-babe-dead-beefcafebabe/bucket/f7a8b9c0-1234-5678-9abc-def012345678",
  "effect": "allow",
  "is_system": false,
  "granted_at": "2026-04-12T20:15:00Z"
}
DELETE/api/v1/buckets/buckets/{bucket_id}/access/grants/{grant_id}

Delete Grant

Revoke a bucket permission grant by ID.

Bearer token required.

Path Parameters

NameTypeDescription
bucket_id*
string (UUID)Bucket ID
grant_id*
string (UUID)Grant ID
curl -X DELETE https://platform.ergondata.ai/api/v1/buckets/buckets/{bucket_id}/access/grants/{grant_id} \
  -H "Authorization: Bearer {token}"

Response

204 No Content
GET/api/v1/buckets/buckets/{bucket_id}/access/connection-requests

List Connection Requests

List zero-trust connection requests targeting this bucket, filtered by status (defaults to pending).

Bearer token required.

Path Parameters

NameTypeDescription
bucket_id*
string (UUID)Bucket ID

Query Parameters

NameTypeDescription
status
stringFilter by request statusDefault: pending

Response Fields

NameTypeDescription
[]*
ConnectionRequestEntry[]Requests (id, principal_id, target_service, target_resource, status, requested_permissions)
curl "https://platform.ergondata.ai/api/v1/buckets/buckets/{bucket_id}/access/connection-requests?status=pending" \
  -H "Authorization: Bearer {token}"

Response

200 OK
[
  {
    "id": "cr-0001-0000-4000-8000-000000000001",
    "principal_id": "agent-7777-0000-4000-8000-000000000001",
    "target_service": "buckets",
    "target_resource": "org/c0ffee00-cafe-babe-dead-beefcafebabe/bucket/f7a8b9c0-1234-5678-9abc-def012345678",
    "status": "pending",
    "requested_permissions": ["buckets:files:view"],
    "message": "Triage agent needs read access",
    "requested_by": "u9000000-0000-4000-8000-000000000001",
    "created_at": "2026-04-12T19:00:00Z"
  }
]
POST/api/v1/buckets/buckets/{bucket_id}/access/connection-requests/{request_id}/approve

Approve Connection Request

Approve a pending connection request, optionally creating a grant with specific permissions and a label.

Bearer token required.

Path Parameters

NameTypeDescription
bucket_id*
string (UUID)Bucket ID
request_id*
string (UUID)Connection request ID

Request Body

NameTypeDescription
grant
booleanCreate the connection/grant on approvalDefault: true
permissions
string[] | nullPermissions to grant (defaults to the requested set)
label
string | nullOptional label for the resulting connection

Response Fields

NameTypeDescription
id*
string (UUID)Connection request ID
status*
stringUpdated status (approved)
connection_id
string (UUID) | nullCreated connection ID when grant=true
curl -X POST https://platform.ergondata.ai/api/v1/buckets/buckets/{bucket_id}/access/connection-requests/{request_id}/approve \
  -H "Authorization: Bearer {token}" \
  -H "Content-Type: application/json" \
  -d '{"grant": true, "permissions": ["buckets:files:view"], "label": "Triage agent"}'

Response

200 OK
{
  "id": "cr-0001-0000-4000-8000-000000000001",
  "principal_id": "agent-7777-0000-4000-8000-000000000001",
  "target_service": "buckets",
  "target_resource": "org/c0ffee00-cafe-babe-dead-beefcafebabe/bucket/f7a8b9c0-1234-5678-9abc-def012345678",
  "status": "approved",
  "connection_id": "conn-0001-0000-4000-8000-000000000001",
  "decided_by": "u9000000-0000-4000-8000-000000000001",
  "decided_at": "2026-04-12T19:10:00Z",
  "created_at": "2026-04-12T19:00:00Z"
}
POST/api/v1/buckets/buckets/{bucket_id}/access/connection-requests/{request_id}/reject

Reject Connection Request

Reject a pending connection request with an optional reason.

Bearer token required.

Path Parameters

NameTypeDescription
bucket_id*
string (UUID)Bucket ID
request_id*
string (UUID)Connection request ID

Request Body

NameTypeDescription
reason
string | nullOptional rejection reason

Response Fields

NameTypeDescription
id*
string (UUID)Connection request ID
status*
stringUpdated status (rejected)
curl -X POST https://platform.ergondata.ai/api/v1/buckets/buckets/{bucket_id}/access/connection-requests/{request_id}/reject \
  -H "Authorization: Bearer {token}" \
  -H "Content-Type: application/json" \
  -d '{"reason": "Out of scope"}'

Response

200 OK
{
  "id": "cr-0001-0000-4000-8000-000000000001",
  "principal_id": "agent-7777-0000-4000-8000-000000000001",
  "target_service": "buckets",
  "target_resource": "org/c0ffee00-cafe-babe-dead-beefcafebabe/bucket/f7a8b9c0-1234-5678-9abc-def012345678",
  "status": "rejected",
  "decided_by": "u9000000-0000-4000-8000-000000000001",
  "decided_at": "2026-04-12T19:12:00Z",
  "created_at": "2026-04-12T19:00:00Z"
}
GET/api/v1/buckets/buckets/{bucket_id}/access/connections

List Inbound Connections

List active inbound connections where another principal connects to this bucket zone.

Bearer token required.

Path Parameters

NameTypeDescription
bucket_id*
string (UUID)Bucket ID

Response Fields

NameTypeDescription
[]*
InboundConnectionEntry[]Connections (id, principal_id, principal_label, target_service, target_resource, label)
curl https://platform.ergondata.ai/api/v1/buckets/buckets/{bucket_id}/access/connections \
  -H "Authorization: Bearer {token}"

Response

200 OK
[
  {
    "id": "conn-0001-0000-4000-8000-000000000001",
    "principal_id": "agent-7777-0000-4000-8000-000000000001",
    "principal_label": "Triage agent",
    "principal_type": "agent",
    "target_service": "buckets",
    "target_resource": "org/c0ffee00-cafe-babe-dead-beefcafebabe/bucket/f7a8b9c0-1234-5678-9abc-def012345678",
    "label": "Triage agent",
    "created_by": "u9000000-0000-4000-8000-000000000001",
    "created_at": "2026-04-12T19:10:00Z"
  }
]
DELETE/api/v1/buckets/buckets/{bucket_id}/access/connections/{connection_id}

Revoke Inbound Connection

Revoke an active inbound connection to this bucket zone.

Bearer token required.

Path Parameters

NameTypeDescription
bucket_id*
string (UUID)Bucket ID
connection_id*
string (UUID)Connection ID
curl -X DELETE https://platform.ergondata.ai/api/v1/buckets/buckets/{bucket_id}/access/connections/{connection_id} \
  -H "Authorization: Bearer {token}"

Response

204 No Content
GET/api/v1/buckets/folders/{folder_id}/access/eligible

List Folder Eligible Principals

Return IAM principals eligible for folder-level grants.

Bearer token required.

Path Parameters

NameTypeDescription
folder_id*
string (UUID)Folder ID

Response Fields

NameTypeDescription
[]*
EligiblePrincipal[]Eligible principals (principal_type, principal_id, label)
curl https://platform.ergondata.ai/api/v1/buckets/folders/{folder_id}/access/eligible \
  -H "Authorization: Bearer {token}"

Response

200 OK
[
  {
    "principal_type": "member",
    "principal_id": "u9000000-0000-4000-8000-000000000001",
    "label": "Jane Doe"
  }
]
GET/api/v1/buckets/folders/{folder_id}/access/resource-types

List Folder Resource Types

Return the resource-type hierarchy and permissions for folder-scoped grants.

Bearer token required.

Path Parameters

NameTypeDescription
folder_id*
string (UUID)Folder ID

Response Fields

NameTypeDescription
resource_types*
ResourceTypeNode[]Resource-type nodes
permissions*
PermissionOption[]Permissions associated with resource types
curl https://platform.ergondata.ai/api/v1/buckets/folders/{folder_id}/access/resource-types \
  -H "Authorization: Bearer {token}"

Response

200 OK
{
  "resource_types": [
    { "id": "rt-001", "name": "Folder", "slug": "folder", "parent_id": "rt-000", "children": [] }
  ],
  "permissions": [
    {
      "id": "perm-001",
      "name": "buckets:files:view",
      "friendly_name": "View files",
      "description": "Read files and metadata",
      "scope_anchor": "instance",
      "display_order": 1
    }
  ]
}
GET/api/v1/buckets/folders/{folder_id}/access/grants

List Folder Grants

Paginated list of IAM permission grants on the folder.

Bearer token required.

Path Parameters

NameTypeDescription
folder_id*
string (UUID)Folder ID

Query Parameters

NameTypeDescription
page
integerPage number (>= 1)Default: 1
limit
integerPage size (1–500)Default: 100

Response Fields

NameTypeDescription
items*
GrantResponse[]Grants in this page
total
integerTotal grants
curl "https://platform.ergondata.ai/api/v1/buckets/folders/{folder_id}/access/grants?page=1&limit=50" \
  -H "Authorization: Bearer {token}"

Response

200 OK
{
  "items": [
    {
      "id": "fg-0001-0000-4000-8000-000000000001",
      "permission_id": "perm-001",
      "name": "buckets:files:view",
      "resource": "org/c0ffee00-cafe-babe-dead-beefcafebabe/bucket/f7a8b9c0-1234-5678-9abc-def012345678/folder/a1b2c3d4-e5f6-7890-abcd-ef1234567890",
      "effect": "allow",
      "is_system": false,
      "granted_at": "2026-04-12T20:00:00Z"
    }
  ],
  "total": 1,
  "page": 1,
  "limit": 50
}
POST/api/v1/buckets/folders/{folder_id}/access/grants

Create Folder Grant

Grant a permission to a principal on this folder. The resource must stay within the folder's resource boundary.

Bearer token required.

Path Parameters

NameTypeDescription
folder_id*
string (UUID)Folder ID

Request Body

NameTypeDescription
principal_type*
stringOne of member, api_key, agent, or role
principal_id*
string (UUID)Principal ID
permission_id*
string (UUID)Permission ID to grant
resource
string | nullResource path; defaults to the folder
effect
stringGrant effectDefault: allow

Response Fields

NameTypeDescription
id*
string (UUID)Grant ID
permission_id*
string (UUID)Permission ID
name*
stringPermission name
resource*
stringResource path
effect*
stringGrant effect
is_system*
booleanSystem-managed flag
granted_at*
datetimeGrant creation time
curl -X POST https://platform.ergondata.ai/api/v1/buckets/folders/{folder_id}/access/grants \
  -H "Authorization: Bearer {token}" \
  -H "Content-Type: application/json" \
  -d '{
    "principal_type": "member",
    "principal_id": "u9000000-0000-4000-8000-000000000001",
    "permission_id": "perm-001",
    "effect": "allow"
  }'

Response

201 Created
{
  "id": "fg-0002-0000-4000-8000-000000000002",
  "permission_id": "perm-001",
  "name": "buckets:files:view",
  "resource": "org/c0ffee00-cafe-babe-dead-beefcafebabe/bucket/f7a8b9c0-1234-5678-9abc-def012345678/folder/a1b2c3d4-e5f6-7890-abcd-ef1234567890",
  "effect": "allow",
  "is_system": false,
  "granted_at": "2026-04-12T20:15:00Z"
}
DELETE/api/v1/buckets/folders/{folder_id}/access/grants/{grant_id}

Delete Folder Grant

Revoke a folder permission grant by ID.

Bearer token required.

Path Parameters

NameTypeDescription
folder_id*
string (UUID)Folder ID
grant_id*
string (UUID)Grant ID
curl -X DELETE https://platform.ergondata.ai/api/v1/buckets/folders/{folder_id}/access/grants/{grant_id} \
  -H "Authorization: Bearer {token}"

Response

204 No Content
GET/api/v1/buckets/folders/{folder_id}/access/connection-requests

List Folder Connection Requests

List zero-trust connection requests targeting this folder, filtered by status (defaults to pending).

Bearer token required.

Path Parameters

NameTypeDescription
folder_id*
string (UUID)Folder ID

Query Parameters

NameTypeDescription
status
stringFilter by request statusDefault: pending

Response Fields

NameTypeDescription
[]*
ConnectionRequestEntry[]Connection requests targeting the folder
curl "https://platform.ergondata.ai/api/v1/buckets/folders/{folder_id}/access/connection-requests?status=pending" \
  -H "Authorization: Bearer {token}"

Response

200 OK
[
  {
    "id": "cr-0002-0000-4000-8000-000000000002",
    "principal_id": "agent-7777-0000-4000-8000-000000000001",
    "target_service": "buckets",
    "target_resource": "org/c0ffee00-cafe-babe-dead-beefcafebabe/bucket/f7a8b9c0-1234-5678-9abc-def012345678/folder/a1b2c3d4-e5f6-7890-abcd-ef1234567890",
    "status": "pending",
    "requested_permissions": ["buckets:files:view"],
    "created_at": "2026-04-12T19:30:00Z"
  }
]
POST/api/v1/buckets/folders/{folder_id}/access/connection-requests/{request_id}/approve

Approve Folder Connection Request

Approve a pending folder connection request, optionally creating a grant with specific permissions and a label.

Bearer token required.

Path Parameters

NameTypeDescription
folder_id*
string (UUID)Folder ID
request_id*
string (UUID)Connection request ID

Request Body

NameTypeDescription
grant
booleanCreate the connection/grant on approvalDefault: true
permissions
string[] | nullPermissions to grant (defaults to the requested set)
label
string | nullOptional label for the resulting connection

Response Fields

NameTypeDescription
id*
string (UUID)Connection request ID
status*
stringUpdated status (approved)
curl -X POST https://platform.ergondata.ai/api/v1/buckets/folders/{folder_id}/access/connection-requests/{request_id}/approve \
  -H "Authorization: Bearer {token}" \
  -H "Content-Type: application/json" \
  -d '{"grant": true, "permissions": ["buckets:files:view"]}'

Response

200 OK
{
  "id": "cr-0002-0000-4000-8000-000000000002",
  "principal_id": "agent-7777-0000-4000-8000-000000000001",
  "target_service": "buckets",
  "target_resource": "org/c0ffee00-cafe-babe-dead-beefcafebabe/bucket/f7a8b9c0-1234-5678-9abc-def012345678/folder/a1b2c3d4-e5f6-7890-abcd-ef1234567890",
  "status": "approved",
  "connection_id": "conn-0002-0000-4000-8000-000000000002",
  "decided_at": "2026-04-12T19:35:00Z",
  "created_at": "2026-04-12T19:30:00Z"
}
POST/api/v1/buckets/folders/{folder_id}/access/connection-requests/{request_id}/reject

Reject Folder Connection Request

Reject a pending folder connection request with an optional reason.

Bearer token required.

Path Parameters

NameTypeDescription
folder_id*
string (UUID)Folder ID
request_id*
string (UUID)Connection request ID

Request Body

NameTypeDescription
reason
string | nullOptional rejection reason

Response Fields

NameTypeDescription
id*
string (UUID)Connection request ID
status*
stringUpdated status (rejected)
curl -X POST https://platform.ergondata.ai/api/v1/buckets/folders/{folder_id}/access/connection-requests/{request_id}/reject \
  -H "Authorization: Bearer {token}" \
  -H "Content-Type: application/json" \
  -d '{"reason": "Out of scope"}'

Response

200 OK
{
  "id": "cr-0002-0000-4000-8000-000000000002",
  "principal_id": "agent-7777-0000-4000-8000-000000000001",
  "target_service": "buckets",
  "target_resource": "org/c0ffee00-cafe-babe-dead-beefcafebabe/bucket/f7a8b9c0-1234-5678-9abc-def012345678/folder/a1b2c3d4-e5f6-7890-abcd-ef1234567890",
  "status": "rejected",
  "decided_at": "2026-04-12T19:36:00Z",
  "created_at": "2026-04-12T19:30:00Z"
}
GET/api/v1/buckets/folders/{folder_id}/access/connections

List Folder Inbound Connections

List active inbound connections to this folder zone.

Bearer token required.

Path Parameters

NameTypeDescription
folder_id*
string (UUID)Folder ID

Response Fields

NameTypeDescription
[]*
InboundConnectionEntry[]Active connections to the folder zone
curl https://platform.ergondata.ai/api/v1/buckets/folders/{folder_id}/access/connections \
  -H "Authorization: Bearer {token}"

Response

200 OK
[
  {
    "id": "conn-0002-0000-4000-8000-000000000002",
    "principal_id": "agent-7777-0000-4000-8000-000000000001",
    "principal_label": "Triage agent",
    "principal_type": "agent",
    "target_service": "buckets",
    "target_resource": "org/c0ffee00-cafe-babe-dead-beefcafebabe/bucket/f7a8b9c0-1234-5678-9abc-def012345678/folder/a1b2c3d4-e5f6-7890-abcd-ef1234567890",
    "created_at": "2026-04-12T19:35:00Z"
  }
]
DELETE/api/v1/buckets/folders/{folder_id}/access/connections/{connection_id}

Revoke Folder Inbound Connection

Revoke an active inbound connection to this folder zone.

Bearer token required.

Path Parameters

NameTypeDescription
folder_id*
string (UUID)Folder ID
connection_id*
string (UUID)Connection ID
curl -X DELETE https://platform.ergondata.ai/api/v1/buckets/folders/{folder_id}/access/connections/{connection_id} \
  -H "Authorization: Bearer {token}"

Response

204 No Content

Activity

Track events across buckets, folders, and files. Query available event types, page through a bucket's event history, or fetch a single event by ID.

GET/api/v1/buckets/event-types

List Event Types

Agent-callable catalog of registered event-type slugs with human-readable names and descriptions. Use it to discover valid filters before querying activity logs.

Bearer token required.

Response Fields

NameTypeDescription
[]*
EventTypeItem[]Event-type records (slug, name, description)
curl https://platform.ergondata.ai/api/v1/buckets/event-types \
  -H "Authorization: Bearer {token}"

Response

200 OK
[
  {
    "slug": "buckets.files.ingested",
    "name": "File Ingested",
    "description": "A new file was uploaded to a bucket or folder"
  },
  {
    "slug": "buckets.files.updated",
    "name": "File Updated",
    "description": "A file's metadata or content was modified"
  },
  {
    "slug": "buckets.bucket.created",
    "name": "Bucket Created",
    "description": "A new bucket was created"
  }
]
GET/api/v1/buckets/buckets/{bucket_id}/activity

List Bucket Activity

Paginated activity log for a bucket, optionally filtered by event type. Actor labels are enriched from IAM.

Bearer token required.

Path Parameters

NameTypeDescription
bucket_id*
string (UUID)Bucket ID

Query Parameters

NameTypeDescription
event_type
string | nullFilter by event-type slug (e.g. buckets.files.ingested)
page
integerPage number (>= 1)Default: 1
limit
integerPage size (1–100)Default: 50

Response Fields

NameTypeDescription
items*
ActivityEventItem[]Activity events in this page
total*
integerTotal matching events
page*
integerCurrent page number
limit*
integerPage size
curl "https://platform.ergondata.ai/api/v1/buckets/buckets/{bucket_id}/activity?event_type=buckets.files.ingested&page=1&limit=20" \
  -H "Authorization: Bearer {token}"

Response

200 OK
{
  "items": [
    {
      "id": "evt-00000001-0000-4000-8000-000000000001",
      "bucket_id": "f7a8b9c0-1234-5678-9abc-def012345678",
      "file_id": "d0c0d0c0-1111-2222-3333-444455556666",
      "event_type": "buckets.files.ingested",
      "actor_type": "member",
      "actor_label": "Jane Doe",
      "correlation_id": null,
      "data": { "filename": "invoice-acme-042.pdf" },
      "created_at": "2026-04-12T07:55:10Z"
    }
  ],
  "total": 1,
  "page": 1,
  "limit": 20
}
GET/api/v1/buckets/activity/{event_id}

Get Activity Event

Retrieve a single activity event by ID. The caller must have activity-view permission on the event's bucket.

Bearer token required.

Path Parameters

NameTypeDescription
event_id*
string (UUID)Activity event ID

Response Fields

NameTypeDescription
id*
string (UUID)Event ID
bucket_id*
string (UUID)Bucket the event belongs to
file_id
string (UUID) | nullFile ID if the event relates to a file
event_type*
stringEvent-type slug
actor_type
string | nullActor type (member, api_key, agent, service)
actor_label
string | nullHuman-readable actor name
correlation_id
string (UUID) | nullOptional correlation ID linking related events
data
object | nullEvent-specific payload
created_at*
datetimeEvent timestamp (ISO 8601)
curl https://platform.ergondata.ai/api/v1/buckets/activity/{event_id} \
  -H "Authorization: Bearer {token}"

Response

200 OK
{
  "id": "evt-00000001-0000-4000-8000-000000000001",
  "bucket_id": "f7a8b9c0-1234-5678-9abc-def012345678",
  "file_id": "d0c0d0c0-1111-2222-3333-444455556666",
  "event_type": "buckets.files.ingested",
  "actor_type": "member",
  "actor_label": "Jane Doe",
  "correlation_id": null,
  "data": { "filename": "invoice-acme-042.pdf" },
  "created_at": "2026-04-12T07:55:10Z"
}

Batch Access Grants

Public JWT-authenticated batch grant routes use BatchCreateGrantsRequest and return ordered BatchCreateGrantsResponse partial-success envelopes. Each operation expands as resources × permission_ids; requests may expand to at most 200 grants. `already_exists` is an idempotent success, so whole-batch or failed-item retries are safe. Post-write ancestor-view or activity/outbox failures appear in side_effect_error_status/side_effect_error_detail without rolling back the IAM grant.

POST/api/v1/buckets/access/buckets/grants/batch

Batch Create Bucket Grants

Create grants across concrete bucket roots with per-item validation and partial success. Agent ToolDef slug: `buckets.access_grants.create_grants_batch`.

Bearer token required. IAM permission `buckets:permissions:buckets:manage` on every concrete bucket root.

Request Body

NameTypeDescription
operations*
BatchGrantOperation[]One or more grouped operations; maximum 200 expanded grants

Response Fields

NameTypeDescription
results*
BatchGrantResult[]Ordered results containing index, client_ref, status, principal_type/id, permission_id, canonical resource, effect, grant, primary error fields, and side-effect error fields
summary*
objectcreated, already_exists, and failed counts
curl -X POST https://platform.ergondata.ai/api/v1/buckets/access/buckets/grants/batch \
  -H "Authorization: Bearer {token}" \
  -H "Content-Type: application/json" \
  -d '{"operations":[{"client_ref":"bucket-access","principal_type":"member","principal_id":"{principal_id}","resources":["org/{company_id}/bucket/{bucket_id}"],"permission_ids":["{permission_id}"],"effect":"allow"}]}'

Response

200 OK
{
  "results": [{
    "index": 0, "client_ref": "bucket-access", "status": "created",
    "principal_type": "member", "principal_id": "{principal_id}",
    "permission_id": "{permission_id}", "resource": "org/{company_id}/bucket/{bucket_id}",
    "effect": "allow", "grant": {}, "error_status": null, "error_detail": null,
    "side_effect_error_status": null, "side_effect_error_detail": null
  }],
  "summary": { "created": 1, "already_exists": 0, "failed": 0 }
}
POST/api/v1/buckets/access/folders/grants/batch

Batch Create Folder Grants

Create grants across concrete canonical folder roots with the same request, partial-success, retry, and side-effect semantics. Agent ToolDef slug: `buckets.folder_access_grants.create_grants_batch`.

Bearer token required. IAM permission `buckets:permissions:folders:manage` on every concrete canonical folder root.

Request Body

NameTypeDescription
operations*
BatchGrantOperation[]BatchCreateGrantsRequest operations (client_ref, principal_type/id, resources, permission_ids, effect); maximum 200 expanded grants

Response Fields

NameTypeDescription
results*
BatchGrantResult[]Ordered created, already_exists, or failed results with primary and side-effect errors
summary*
objectcreated, already_exists, and failed counts
curl -X POST https://platform.ergondata.ai/api/v1/buckets/access/folders/grants/batch \
  -H "Authorization: Bearer {token}" \
  -H "Content-Type: application/json" \
  -d '{"operations":[{"principal_type":"team","principal_id":"{principal_id}","resources":["org/{company_id}/bucket/{bucket_id}/folder/{folder_id}"],"permission_ids":["{permission_id}"]}]}'

Response

200 OK
{
  "results": [{
    "index": 0, "client_ref": null, "status": "already_exists",
    "principal_type": "team", "principal_id": "{principal_id}",
    "permission_id": "{permission_id}", "resource": "org/{company_id}/bucket/{bucket_id}/folder/{folder_id}",
    "effect": "allow", "grant": {}, "error_status": null, "error_detail": null,
    "side_effect_error_status": null, "side_effect_error_detail": null
  }],
  "summary": { "created": 0, "already_exists": 1, "failed": 0 }
}