Skip to Content
We are live but in Staging 🎉

Objects

Two surfaces — keep them straight when picking a route:

  • Byte plane — full S3 protocol via the K3 HTTP gateway: PUT / GET / HEAD / DELETE directly 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

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.pdf

Or via aws-cli:

aws s3 cp ./sample.pdf s3://kb-prod/docs/sample.pdf \ --endpoint-url https://k3.dev.dodil.io

GET /:bucket/:key — download

GET /:bucket/:key

curl -sS "https://k3.dev.dodil.io/kb-prod/docs/sample.pdf" \ -H "Authorization: Bearer $DODIL_TOKEN" \ --output sample.pdf

HEAD /:bucket/:key — S3 metadata headers

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).

RPCHTTP
ListObjectsGET /:bucket/objects
GetObjectInfoGET /:bucket/objects/:key/info
DeleteObjectDELETE /:bucket/objects/:key
GetObjectUrlGET /:bucket/objects/:key/url

ListObjects

Optional query params (snake_case): prefix, delimiter (/ for folder-like grouping), max_keys, continuation_token.

Request

curl -sS "https://k3.dev.dodil.io/kb-prod/objects?prefix=docs/&max_keys=100" \ -H "Authorization: Bearer $DODIL_TOKEN"

Response

{ "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

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

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

curl -sS "https://k3.dev.dodil.io/kb-prod/objects/docs%2Fsample.pdf/url?expires_in_seconds=900" \ -H "Authorization: Bearer $DODIL_TOKEN"

Response

{ "url": "https://k3.dev.dodil.io/kb-prod/docs/sample.pdf?X-K3-Signature=...", "expiresAt": "1716847200000" }

See also