Skip to content

API reference

Buckets

Markdown

S3-compatible object storage: create buckets, presign object URLs, list and delete objects, set CORS, attach to apps.

A bucket holds objects and speaks the S3 protocol. Your app reaches it in two ways: ask this API for a presigned URL per object, or attach the bucket to the app, which gives the app a key scoped to that bucket and the S3_* environment variables to use it directly. See the guide Buckets.

Attaching and detaching a bucket go through the app’s attach and detach routes (see Apps) with a body of {"bucket": "<name>", "as": "<prefix>"}.

Creates a bucket. Names are unique across Rytiv.

Auth: API key with full access (a key with scopes cannot call this route). An agent token of class sandbox or twin may call it; class production is refused (agent-token-production-readonly).

JSON, the shape CreateBucketRequest of the contract.

Field Type Required Description
name string required The bucket’s name. Unique across Rytiv.
curl -X POST "https://api.rytiv.app/v1/buckets" \
-H "Authorization: Bearer $RYTIV_TOKEN" \
-H "Content-Type: application/json" \
-d '{"name":"my-bucket"}'

201 with the bucket:

{
"id": "<id>",
"name": "my-bucket",
"orgId": "<orgId>",
"backendRef": "<backendRef>",
"createdAt": "2026-10-21T09:00:00Z"
}
Field Type Present Description
id string always The bucket’s id.
name string always
orgId string always The organization that owns it.
backendRef string always Where the objects live, in the storage layer’s own words; opaque.
createdAt string (ISO 8601) always When it was created.
Status Code Meaning
400 bad-request The request is malformed or a field is out of range. error names every field; issues lists them.
401 unauthenticated No API key, or one that does not work.
403 token-scope The key’s scopes do not cover this route.

The organization’s buckets.

Auth: API key with full access or the scope read. Every class of agent token may call it.

curl -X GET "https://api.rytiv.app/v1/buckets" \
-H "Authorization: Bearer $RYTIV_TOKEN"

200 with a list of buckets, each:

[
{
"id": "<id>",
"name": "my-bucket",
"orgId": "<orgId>",
"backendRef": "<backendRef>",
"createdAt": "2026-10-21T09:00:00Z"
}
]
Field Type Present Description
id string always The bucket’s id.
name string always
orgId string always The organization that owns it.
backendRef string always Where the objects live, in the storage layer’s own words; opaque.
createdAt string (ISO 8601) always When it was created.
Status Code Meaning
401 unauthenticated No API key, or one that does not work.
403 token-scope The key’s scopes do not cover this route.

Whether a bucket name is still available, and if not, why.

Auth: API key with full access or the scope read. Every class of agent token may call it.

Name Description
name The name to check.
curl -X GET "https://api.rytiv.app/v1/bucket-names/<name>" \
-H "Authorization: Bearer $RYTIV_TOKEN"

200 with the answer:

{
"name": "my-app",
"available": true
}
Field Type Present Description
name string always
available boolean always Whether you can have the name.
reason taken | taken-by-you | reserved | invalid if set If not: taken, taken-by-you, reserved or invalid.
Status Code Meaning
401 unauthenticated No API key, or one that does not work.
403 token-scope The key’s scopes do not cover this route.
404 not-found Not found, or not yours. An object of another organization answers like one that does not exist.

One bucket.

Auth: API key with full access or the scope read. Every class of agent token may call it.

Name Description
name The bucket’s name.
curl -X GET "https://api.rytiv.app/v1/buckets/<name>" \
-H "Authorization: Bearer $RYTIV_TOKEN"

200 with the bucket:

{
"id": "<id>",
"name": "my-bucket",
"orgId": "<orgId>",
"backendRef": "<backendRef>",
"createdAt": "2026-10-21T09:00:00Z"
}
Field Type Present Description
id string always The bucket’s id.
name string always
orgId string always The organization that owns it.
backendRef string always Where the objects live, in the storage layer’s own words; opaque.
createdAt string (ISO 8601) always When it was created.
Status Code Meaning
401 unauthenticated No API key, or one that does not work.
403 token-scope The key’s scopes do not cover this route.
404 not-found Not found, or not yours. An object of another organization answers like one that does not exist.

Deletes a bucket.

Auth: API key with full access (a key with scopes cannot call this route). An agent token of class sandbox or twin may call it; class production is refused (agent-token-production-readonly).

Name Description
name The bucket’s name.
Name Description
force
curl -X DELETE "https://api.rytiv.app/v1/buckets/<name>" \
-H "Authorization: Bearer $RYTIV_TOKEN"

200 with a JSON object carrying destroyed, deletedObjects, detached.

Status Code Meaning
401 unauthenticated No API key, or one that does not work.
403 token-scope The key’s scopes do not cover this route.
404 not-found Not found, or not yours. An object of another organization answers like one that does not exist.

A time-limited URL for one object and one method (get or put).

Auth: API key with full access (a key with scopes cannot call this route). An agent token of class sandbox or twin may call it; class production is refused.

Name Description
name The bucket’s name.

JSON, the shape PresignRequest of the contract.

Field Type Required Description
op get | put optional get for a download URL, put for an upload URL. default "get".
key string required The object’s key. 1 to 1024 characters.
expiresInS integer optional How long the URL stays valid, in seconds. 1 to 604800, default 900.
contentType string optional put only: the Content-Type the upload must send. It is part of the signature. 1 to 255 characters.
curl -X POST "https://api.rytiv.app/v1/buckets/<name>/presign" \
-H "Authorization: Bearer $RYTIV_TOKEN" \
-H "Content-Type: application/json" \
-d '{"key":"uploads/report.pdf"}'

200 with the presigned URL:

{
"url": "<url>",
"method": "GET",
"key": "uploads/report.pdf",
"expiresAt": "2026-10-21T09:00:00Z",
"requiredHeaders": {
"<key>": "<value>"
}
}
Field Type Present Description
url string always The URL to call with method.
method GET | PUT always With path: GET (default) or POST.
key string always The object’s key.
expiresAt string (ISO 8601) always When the copy is deleted (a moment). Not together with ttlSeconds.
requiredHeaders object of string always Headers the call must send exactly; a missing one breaks the signature.
Status Code Meaning
400 bad-request The request is malformed or a field is out of range. error names every field; issues lists them.
401 unauthenticated No API key, or one that does not work.
403 token-scope The key’s scopes do not cover this route.
404 not-found Not found, or not yours. An object of another organization answers like one that does not exist.

Lists objects, with a cursor for the next page.

Auth: API key with full access or the scope read. An agent token of class production needs prodDataRead for it; sandbox and twin may call it.

Name Description
name The bucket’s name.
Name Description
limit How many objects per page.
prefix Only keys that start with this.
cursor The nextCursor of the previous page.
curl -X GET "https://api.rytiv.app/v1/buckets/<name>/objects" \
-H "Authorization: Bearer $RYTIV_TOKEN"

200 with the page of objects:

{
"bucket": "my-bucket",
"objects": [
{
"key": "uploads/report.pdf",
"sizeBytes": 0,
"lastModified": "<lastModified>"
}
]
}
Field Type Present Description
bucket string always
objects array of object always
nextCursor string if set Hand it back as cursor to get the next page.
Status Code Meaning
401 unauthenticated No API key, or one that does not work.
403 token-scope The key’s scopes do not cover this route.
404 not-found Not found, or not yours. An object of another organization answers like one that does not exist.

Deletes objects by key.

Auth: API key with full access (a key with scopes cannot call this route). An agent token of class sandbox or twin may call it; class production is refused (agent-token-production-readonly).

Name Description
name The bucket’s name.
Name Description
key
curl -X DELETE "https://api.rytiv.app/v1/buckets/<name>/objects" \
-H "Authorization: Bearer $RYTIV_TOKEN"

200 with a JSON object carrying bucket, deleted.

Status Code Meaning
401 unauthenticated No API key, or one that does not work.
403 token-scope The key’s scopes do not cover this route.
404 not-found Not found, or not yours. An object of another organization answers like one that does not exist.

The bucket’s CORS rules.

Auth: API key with full access or the scope read. Every class of agent token may call it.

Name Description
name The bucket’s name.
curl -X GET "https://api.rytiv.app/v1/buckets/<name>/cors" \
-H "Authorization: Bearer $RYTIV_TOKEN"

200 with the rules:

{
"rules": [
{
"allowedMethods": [
"GET"
],
"allowedOrigins": [
"<allowedOrigin>"
]
}
]
}
Field Type Present Description
rules array of object always The whole CORS configuration; a PUT replaces it.
warnings array of string if set
Status Code Meaning
401 unauthenticated No API key, or one that does not work.
403 token-scope The key’s scopes do not cover this route.
404 not-found Not found, or not yours. An object of another organization answers like one that does not exist.

Replaces the bucket’s CORS rules. An empty list removes them.

Auth: API key with full access (a key with scopes cannot call this route). An agent token of class sandbox or twin may call it; class production is refused (agent-token-production-readonly).

Name Description
name The bucket’s name.

JSON, the shape PutBucketCorsRequest of the contract.

Field Type Required Description
rules array of object required The whole CORS configuration; a PUT replaces it. 0 to 100 items.
curl -X PUT "https://api.rytiv.app/v1/buckets/<name>/cors" \
-H "Authorization: Bearer $RYTIV_TOKEN" \
-H "Content-Type: application/json" \
-d '{"rules":[{"allowedMethods":["GET"],"allowedOrigins":["<allowedOrigin>"]}]}'

200 with the rules as stored:

{
"rules": [
{
"allowedMethods": [
"GET"
],
"allowedOrigins": [
"<allowedOrigin>"
]
}
]
}
Field Type Present Description
rules array of object always The whole CORS configuration; a PUT replaces it.
warnings array of string if set
Status Code Meaning
400 bad-request The request is malformed or a field is out of range. error names every field; issues lists them.
401 unauthenticated No API key, or one that does not work.
403 token-scope The key’s scopes do not cover this route.
404 not-found Not found, or not yours. An object of another organization answers like one that does not exist.

Which bucket is attached to which app, and the environment it injected.

Auth: API key with full access or the scope read. Every class of agent token may call it.

curl -X GET "https://api.rytiv.app/v1/bucket-attachments" \
-H "Authorization: Bearer $RYTIV_TOKEN"

200 with a list of attachments, each:

[
{
"appName": "my-app",
"bucketName": "<bucketName>",
"injected": [
"<injected>"
]
}
]
Field Type Present Description
appName string always
bucketName string always
injected array of string always The environment variables the attachment gave the app.
Status Code Meaning
401 unauthenticated No API key, or one that does not work.
403 token-scope The key’s scopes do not cover this route.