Objects
Two surfaces — keep them straight when picking a route:
- Byte plane — full S3 protocol via the K3 HTTP gateway:
PUT/GET/HEAD/DELETEdirectly on/:bucket/:key. There is no gRPC equivalent — object bytes don’t flow through the gRPC StorageService. - Admin / metadata — gRPC + HTTP: listing, inspecting
ObjectInfo, deleting via the admin path, and issuing presigned URLs.
See Core Concepts → Object for ObjectInfo (the metadata view).
gRPC setup —
grpcurl, endpoints, reflection, and field-name casing — is covered once in Conventions → Using gRPC.
Byte plane (S3 protocol)
The K3 HTTP gateway accepts standard S3 requests against /:bucket/:key and re-signs upstream. Any S3 SDK works — aws-cli, MinIO client, AWS SDKs — point them at the gateway.
PUT /:bucket/:key — upload
HTTP
PUT /:bucket/:key — request body: raw object bytes (not pbjson).
curl -sS -X PUT "https://k3.dev.dodil.io/kb-prod/docs/sample.pdf" \
-H "Authorization: Bearer $DODIL_TOKEN" \
-H "Content-Type: application/pdf" \
--data-binary @./sample.pdfOr via aws-cli:
aws s3 cp ./sample.pdf s3://kb-prod/docs/sample.pdf \
--endpoint-url https://k3.dev.dodil.ioGET /:bucket/:key — download
HTTP
GET /:bucket/:key
curl -sS "https://k3.dev.dodil.io/kb-prod/docs/sample.pdf" \
-H "Authorization: Bearer $DODIL_TOKEN" \
--output sample.pdfHEAD /:bucket/:key — S3 metadata headers
HTTP
HEAD /:bucket/:key
curl -sS -I "https://k3.dev.dodil.io/kb-prod/docs/sample.pdf" \
-H "Authorization: Bearer $DODIL_TOKEN"Admin / metadata (gRPC + HTTP)
The admin routes sit under /:bucket/objects/... (note the /objects/ segment — this is what distinguishes them from the byte-plane routes above).
| RPC | HTTP |
|---|---|
ListObjects | GET /:bucket/objects |
GetObjectInfo | GET /:bucket/objects/:key/info |
DeleteObject | DELETE /:bucket/objects/:key |
GetObjectUrl | GET /:bucket/objects/:key/url |
ListObjects
Optional query params (snake_case): prefix, delimiter (/ for folder-like grouping), max_keys, continuation_token.
Request
HTTP
curl -sS "https://k3.dev.dodil.io/kb-prod/objects?prefix=docs/&max_keys=100" \
-H "Authorization: Bearer $DODIL_TOKEN"Response
HTTP
{
"objects": [
{
"bucket": "kb-prod",
"key": "docs/sample.pdf",
"size": "182394",
"etag": "\"d41d8cd98f00b204e9800998ecf8427e\"",
"lastModified": "1716843600000",
"contentType": "application/pdf"
}
],
"commonPrefixes": ["docs/contracts/"],
"isTruncated": false,
"nextContinuationToken": "",
"keyCount": 1
}GetObjectInfo
URL-encode / in the object key as %2F. Returns the metadata view with the per-pipeline index status — richer than HEAD.
Request
HTTP
curl -sS "https://k3.dev.dodil.io/kb-prod/objects/docs%2Fsample.pdf/info" \
-H "Authorization: Bearer $DODIL_TOKEN"Response
An ObjectInfo — see Core Concepts → Object.
DeleteObject
This is the admin delete (gRPC-equivalent). The byte-plane S3 delete is DELETE /:bucket/:key (no /objects/ segment) and runs through the S3 proxy.
Request
HTTP
curl -sS -X DELETE "https://k3.dev.dodil.io/kb-prod/objects/docs%2Fsample.pdf" \
-H "Authorization: Bearer $DODIL_TOKEN"Response
Empty (DeleteObjectResponse {}).
GetObjectUrl
Issues a K3-token-signed presigned URL. The expires_in_seconds query param defaults to 3600 (1h) and is capped at 86400 (24h).
Request
HTTP
curl -sS "https://k3.dev.dodil.io/kb-prod/objects/docs%2Fsample.pdf/url?expires_in_seconds=900" \
-H "Authorization: Bearer $DODIL_TOKEN"Response
HTTP
{
"url": "https://k3.dev.dodil.io/kb-prod/docs/sample.pdf?X-K3-Signature=...",
"expiresAt": "1716847200000"
}See also
- Core Concepts → Object —
ObjectInfotype - Core Concepts → PresignedURL —
GetObjectUrlreturn shape - Buckets · Policy · CORS
- Conventions — auth, headers, error envelope
grpcurlreference — full flag set + reflection-disabled fallbacks