Skip to main content

Object storage reads

These three endpoints let an external program browse objects and obtain links or content using the instance's existing S3 compatible connections. Complete connection and authentication first. Every request uses the instance's X-Agent-Service-Token.

Requirements​

  • The current user has installed and enabled Object Storage in My Apps. Disabled, uninstalled, or uncertain availability returns 403 capabilityDisabled.
  • Add a connection in the client under Resources → Object Storage, with the bucket and access credentials. Confirm that the provider account can list and read the target objects.
  • Use an existing connection's id. Requests do not submit an access key or secret key, and connection summaries do not return credentials. An instance token accesses the instance's configured connections; it is not a separate grant for one object or prefix.

The handshake's capabilities.objectStorageCapability indicates support for the user capability switch. It does not mean the current user enabled the feature or that a connection works. Use the actual endpoint response.

PurposeEndpoint
Find connection IDs and configuration summariesGET /api/s3/connections
Browse objects by prefix and pageGET /api/s3/list
Obtain a link or file bytesGET /api/s3/download

Connection summaries​

GET /api/s3/connections​

No query parameters. Returns configured connection summaries. An instance with no connections returns 200 with an empty array.

curl --silent --show-error \
--header "X-Agent-Service-Token: ${AGENT_SERVICE_TOKEN}" \
"${BASE_URL}/api/s3/connections"
{
"success": true,
"connections": [
{
"id": "storage-main",
"label": "Project files",
"bucket": "project-files",
"region": "us-east-1",
"status": "connected",
"is_default": true,
"has_public_url": true
}
]
}

status is the saved connection state, not a fresh probe. has_public_url only means a public address is configured. A summary does not prove that credentials are valid, an object is readable, or a download will use a public URL.

Pass connection_id on subsequent requests. When omitted, selection follows default connection → first connected connection → first connection. If the selected connection lacks configuration or credentials, the request returns 400 NO_CONNECTION without trying other connections. Store and explicitly pass the selected ID so that a default change does not change your read target.

Browse objects​

GET /api/s3/list​

Query parameterRules
connection_idOptional connection ID; selection when omitted follows the order above
prefixOptional object key prefix, such as reports/
delimiterDefaults to /, grouping the next level into common_prefixes; an empty string disables directory grouping
max_keysDefaults to 100; range 1–1000; use a decimal integer
continuation_tokenOptional; pass back the previous page's next_continuation_token unchanged
curl --silent --show-error --get \
--header "X-Agent-Service-Token: ${AGENT_SERVICE_TOKEN}" \
--data-urlencode 'connection_id=storage-main' \
--data-urlencode 'prefix=reports/' \
--data-urlencode 'max_keys=100' \
"${BASE_URL}/api/s3/list"
{
"success": true,
"objects": [
{ "key": "reports/summary.txt", "size": 120, "last_modified": "2026-10-25T00:00:00.000Z" }
],
"common_prefixes": [{ "prefix": "reports/archive/" }],
"key_count": 2,
"is_truncated": true,
"next_continuation_token": "opaque-provider-token",
"bucket": "project-files",
"prefix": "reports/"
}

objects contains object entries and common_prefixes contains grouped prefixes. They are not filesystem paths. key_count preserves the provider's page count and may include common prefixes; it is neither a total nor necessarily objects.length. last_modified preserves the provider's timestamp string and can be empty when unavailable.

When is_truncated is true, keep the connection, prefix, delimiter and page size unchanged, and pass the token back. Do not decode it or calculate a next page from object counts. The final page normally omits next_continuation_token, rather than returning null. prefix is also omitted without a nonempty prefix. If a truncated page has no token, stop and report the inconsistency. Objects may change between pages; there is no fixed snapshot or total count contract.

The server converts max_keys to a number. An omitted value, 0, or a value that cannot be converted uses 100, then the result is clamped to 1–1000. Decimal fractions and malformed input are not uniformly rejected with 400. The example rejects nonintegers before connecting.

Download objects​

GET /api/s3/download​

Query parameterRules
keyRequired full object key; preserve case and /
connection_idOptional connection ID
modeExplicit link or binary is recommended; defaults to link. Only the exact value binary returns bytes; other values use link mode
expires_inSigned link lifetime in seconds; defaults to 3600, range 60–604800; does not set a lifetime on public URLs
curl --silent --show-error --get \
--header "X-Agent-Service-Token: ${AGENT_SERVICE_TOKEN}" \
--data-urlencode 'connection_id=storage-main' \
--data-urlencode 'key=reports/summary.txt' \
--data-urlencode 'mode=link' \
--data-urlencode 'expires_in=3600' \
"${BASE_URL}/api/s3/download"
{
"success": true,
"key": "reports/summary.txt",
"download_url": "https://files.example.com/reports/summary.txt",
"url_type": "public",
"content_type": "text/plain",
"content_length": 120
}
  • url_type: public: a configured public address passed this request's reachability check. The response omits expires_in. The API sets no expiry on this link; availability still depends on the object and public access configuration.
  • url_type: presigned: a time limited signed URL, with expires_in. This is used when a public address is absent or unreachable. Credentials, provider policy or object changes may invalidate it earlier.
  • content_type and content_length can be omitted, for example when provider metadata is absent or length is zero. Numeric conversion for expires_in follows the same pattern as listing: an omitted value, 0, or an unconvertible value uses 3600, then it is clamped to 60–604800.

A download URL can grant read access to its holder. Limit sharing, and do not send the instance's X-Agent-Service-Token to an S3/CDN URL. These URLs are separate from signed attachment media URLs.

Download bytes directly​

With mode=binary, success returns file content instead of a JSON wrapper. Headers include Content-Type (falling back to application/octet-stream), Content-Length, and an attachment Content-Disposition. An object can itself contain JSON, HTML or any other data; its MIME type alone does not identify an API status response. This endpoint provides no Range or resume contract.

The example below requires an explicit local filename and does not derive a destination from a server filename. Handle unsuccessful HTTP responses before writing a target file.

Runnable read example​

Download s3.mjs. Use Node.js 22 or later; no npm packages are required:

export DESIRECORE_URL='https://your-instance.example'
export DESIRECORE_TOKEN='your-existing-owner-token'

node s3.mjs connections
node s3.mjs list --connection-id storage-main --prefix reports/ --all
node s3.mjs download --connection-id storage-main --key reports/summary.txt
node s3.mjs download --connection-id storage-main --key reports/summary.txt \
--mode binary --output ./summary.txt --max-bytes 10485760

The example verifies the instance handshake before reading storage endpoints. Listing reads one page by default. --all reads at most 100 pages, adjustable with --max-pages. Missing or repeated tokens and page limits produce an error; previously emitted pages remain partial results. Use --delimiter '' for an ungrouped list.

Link mode prints the returned URL without visiting it. Binary mode requests only the verified instance, refuses redirects, defaults to a 100 MiB limit, requires an explicit output path and never overwrites existing files. An interrupted download removes the incomplete file created by that request. The example does not retry, upload or delete objects. Protect object keys and signed links in its output as business data.

Common errors​

ResponseAction
401Check the instance address and token
403 capabilityDisabledCheck that Object Storage is installed and enabled in My Apps. The body is {error, code, capability, retryable} without success; retryable is false
400 INVALID_REQUESTDownload requires a nonempty key query parameter
400 NO_CONNECTIONCheck the connection ID, S3 configuration and saved credentials; an existing summary can still produce this error
404 NOT_FOUND (link mode)The instance could not confirm readable object metadata. Check the key, provider read permissions and connection state; this response alone does not prove deletion
500 LIST_FAILED / DOWNLOAD_FAILEDCheck provider permissions, network and instance logs; a missing object in binary mode can also return DOWNLOAD_FAILED
503 service_not_readyWait according to Retry-After before reading again

S3 domain errors use {success:false, error, code}. Capability and authentication errors have different wrappers. Error text can contain connection or provider details. Keep status and code when investigating, and remove tokens and signed links before sharing logs. See errors and troubleshooting and the OpenAPI downloads for more details.