Buckets
Lifecycle operations on the Bucket entity. See Core Concepts → Bucket for the type signature.
| RPC | HTTP |
|---|---|
CreateBucket | POST /admin/buckets |
GetBucket | GET /admin/buckets/:name |
ListBuckets | GET /admin/buckets |
UpdateBucket | PATCH /admin/buckets/:name |
DeleteBucket | DELETE /admin/buckets/:name |
gRPC setup —
grpcurl, endpoints, reflection, and field-name casing — is covered once in Conventions → Using gRPC.
CreateBucket
Creates a new bucket scoped to the caller’s org. access_mode defaults to BUCKET_ACCESS_MODE_PRIVATE; storage_quota_bytes: 0 means unlimited.
name is validated before anything is provisioned (services/storage/buckets.rs, validate_bucket_name):
| Rule | Failure |
|---|---|
| 3–63 characters | INVALID_ARGUMENT — “bucket name must be 3-63 characters” |
lowercase letters, digits and - only | INVALID_ARGUMENT — “must contain only lowercase letters, numbers, and hyphens” |
| must start and end with a letter or digit | INVALID_ARGUMENT — “must start and end with a letter or number” |
| unique within the org | ALREADY_EXISTS — “bucket already exists” |
Creating a bucket also auto-creates its SOURCE_PROVIDER_INTERNAL_S3 source, so a plain S3 PUT triggers the same ingest rules an external sync would.
Request
HTTP
curl -sS -X POST "https://api.data.dodil.io/admin/buckets" \
-H "Authorization: Bearer $DODIL_TOKEN" \
-H "Content-Type: application/json" \
-d '{
"name": "kb-prod",
"description": "Production knowledge base",
"storageQuotaBytes": "0",
"accessMode": "BUCKET_ACCESS_MODE_PRIVATE"
}'Response
A Bucket row — see Core Concepts → Bucket.
GetBucket
Request
HTTP
curl -sS "https://api.data.dodil.io/admin/buckets/kb-prod" \
-H "Authorization: Bearer $DODIL_TOKEN"Response
A Bucket row — see Core Concepts → Bucket.
ListBuckets
Optional query params — camelCase on this route: pageSize, pageToken, search (case-insensitive substring match on name and description). ListBucketsQuery in http/api/storage.rs carries #[serde(rename_all = "camelCase")], so a snake_case page_size is silently ignored rather than rejected. The object routes below are snake_case — this route is the exception.
pageSize of 0 or less means the server default of 50; the server clamps to a maximum of 200. pageToken is a stringified row offset, opaque to clients.
Request
HTTP
curl -sS "https://api.data.dodil.io/admin/buckets?pageSize=20&search=prod" \
-H "Authorization: Bearer $DODIL_TOKEN"Response
HTTP
{
"buckets": [
{
"name": "kb-prod",
"description": "Production knowledge base",
"status": "BUCKET_STATUS_ACTIVE",
"accessMode": "BUCKET_ACCESS_MODE_PRIVATE",
"internalSourceId": "",
"storageUsedBytes": "12483920",
"storageQuotaBytes": "0",
"objectCount": "1247",
"sourceCount": "0",
"ruleCount": "0",
"indexCount": "0",
"drn": "drn:dodil:k3:us-east-1:<org_id>:bucket/kb-prod",
"createdAt": "1716843600000",
"updatedAt": "1716843600000"
}
],
"pagination": { "nextPageToken": "", "totalCount": "1" }
}
sourceCountandinternalSourceIdare not populated on this route. Live output returns0and""for buckets that demonstrably have an auto-created internal S3 source;GetBucketfills both in correctly. Don’t build on the list values — this is a source-side gap, not a documented behaviour.
drn is server-built (drn:dodil:k3:{region}:{org_id}:bucket/{name}) — never hand-assemble one. The region segment in a DRN is us-east-1, which is not the data-plane region (uk-lon-1).
UpdateBucket
Patches mutable fields. All body fields are optional — only the ones you send change. *_count and storage_used_bytes are server-maintained and ignored on update.
Request
HTTP
curl -sS -X PATCH "https://api.data.dodil.io/admin/buckets/kb-prod" \
-H "Authorization: Bearer $DODIL_TOKEN" \
-H "Content-Type: application/json" \
-d '{
"description": "Renamed",
"accessMode": "BUCKET_ACCESS_MODE_PUBLIC"
}'Response
A Bucket row — see Core Concepts → Bucket.
DeleteBucket
This is a cascading purge, not a guarded delete.
DeleteBucketdoes not refuse a non-empty bucket. The handler loopsListObjectsV2+DeleteObjectsuntil the backing store is empty, then drops the bucket’s plane database, its engine rows (which clears reservation intent and billing), and its remaining ingest rules. There is noforceflag and no confirmation — the API has no undo. Source:services/storage/buckets.rs.
Request
HTTP
curl -sS -X DELETE "https://api.data.dodil.io/admin/buckets/kb-prod" \
-H "Authorization: Bearer $DODIL_TOKEN"Response
Empty (DeleteBucketResponse {}).
See also
- Core Concepts → Bucket — type signature + enums
- Policy · CORS · Objects
- Conventions — auth, headers, error envelope
grpcurlreference — full flag set + reflection-disabled fallbacks