env.<BINDING> (a CloudStorageBucket) is the in-function handle to a Cloud Storage bucket, declared with a [storage.cloudstorage.<name>] block. It’s a pre-authenticated wrapper over the bucket — the runtime injects the credential, so your code holds no S3 access key or secret key.
This reference tracks
@telnyx/edge-runtime ≥ 0.5.0. Ranged and conditional reads, batch delete, hierarchical listing, SSE-C, and the version / writeHttpMetadata object fields need ≥ 0.4.0; multipart uploads need ≥ 0.5.0.- Missing keys read as
null—getandheadresolve tonullfor a key that doesn’t exist, not an error. - A failed conditional read returns a body-less object — when a
getonlyIfprecondition isn’t met,getresolves to a plainCloudStorageObject(metadata only, nobodyand no readers) so you can reuse your cached copy. Check for a body before reading it. deleteis idempotent — deleting a missing key (single or in a batch) succeeds and resolves tovoid.putreturns partial metadata — the resolved object carrieskey,etag,httpEtag,version, and any metadata you set, but notsizeoruploaded. Useheadto read those after a write.- Custom metadata keys are lower-cased on read —
x-amz-meta-*header names are stored lower-cased, socustomMetadatakeys come back lower-cased (uploadedBy→uploadedby). - SSE-C applies to US and APAC (ap-southeast-1) region buckets —
ssecKeyis honored for buckets in US regions.
get(key, options?)
Read an object and its body. Returns null if the key does not exist.
CloudStorageObjectBody — a CloudStorageObject plus the body stream and one-shot readers arrayBuffer(), text(), json(), and blob().
Ranged reads
Passrange to fetch part of an object instead of the whole thing — byte-range streaming, reading a header, or resuming a download. The resolved object echoes the requested range.
Conditional reads
PassonlyIf to read only when a precondition holds — cache revalidation and “only fetch if changed.” A CloudStorageConditional maps to If-Match / If-None-Match / If-Unmodified-Since / If-Modified-Since; you can also pass a Headers object directly.
Conditional writes are not supported —
onlyIf applies to get/head only.put(key, body, options?)
Write an object. Resolves to a CloudStorageObject describing the write.
key, etag (unquoted MD5 for a single-part write), httpEtag (the quoted, header-ready form), version (when bucket versioning is enabled), and the metadata you set. size and uploaded are not populated on the put result — read them back with head if you need them.
head(key, options?)
Read an object’s metadata without its body. Returns null if the key does not exist. Accepts the same onlyIf preconditions as get.
put, head returns the full CloudStorageObject including size and uploaded.
delete(key | keys)
Remove one object, or many in a single call. Idempotent — deleting a missing key resolves normally.
list(options?)
Enumerate objects (metadata only — list does not return bodies).
truncated is true, pass the returned cursor back in list({ cursor }) to fetch the next page.
By default a list entry carries only key, size, etag, and uploaded. Pass include to also populate httpMetadata and/or customMetadata on each returned object — a heavier listing, so ask for it only when you need it.
Hierarchical (“folder”) listing
Setdelimiter to / to browse one level of a key hierarchy: keys below the current level collapse into delimitedPrefixes, and only keys directly at the level appear in objects.
Multipart upload
Upload a large object in parts from inside a function — for objects past the Edge Compute request/response size cap, or for parallel/resumable uploads. Available on US and APAC (ap-southeast-1) region buckets.createMultipartUpload(key, options?)starts the upload and returns a handle.optionstakes the samehttpMetadata/customMetadata/ssecKeyasput.uploadPart(partNumber, body, options?)uploads one part and returns its{ partNumber, etag }. Parts are numbered from 1; every part except the last must be at least 5 MiB.complete(parts)assembles the object. You may pass the parts in any order — they’re sorted bypartNumber.abort()discards an in-progress upload and its parts.resumeMultipartUpload(key, uploadId, options?)rebuilds a handle for an existinguploadId(no server round-trip) so you can upload more parts orcomplete()/abort()from a later invocation.
Server-side encryption (SSE-C)
PassssecKey on get, put, and multipart calls to encrypt with a customer-provided key. The key is a 256-bit (32-byte) AES key, given as an ArrayBuffer or a 64-character hex string. Supply the same key on read that you used on write; the object exposes ssecKeyMd5 (hex) so you can identify which key encrypted it. SSE-C applies to US and APAC (ap-southeast-1) region buckets.
Object types
head and each list entry populate size and uploaded; put’s result does not. The body readers on CloudStorageObjectBody consume the stream once — call a single one per get, and bodyUsed flips to true once you do. writeHttpMetadata is handy for serving an object straight back out of a function with its stored headers:
Related
- Use a bucket from an Edge Function — declare the binding and get started
- Bindings overview — bindings across Telnyx API, Secrets, KV, and Cloud Storage
- S3-compatible API reference — the same buckets over HTTP