Skip to main content
Live. This area is documented as current, user-reliable behavior.

Goal

Call Assets directly when an SDK does not cover your runtime, or use this page to understand what an SDK request sends over the wire.

Prerequisites

  • A StackShift API key
  • A UUID asset, bucket, session, or job ID when a route requires one

Workflow

1
Send Authorization: Bearer <api-key> to the control-plane API.
2
Use the /api/v1 base URL for account and asset management requests.
3
Use snake_case JSON names such as cache_control, max_downloads, and checksum_sha256.
4
Read the data field from the success envelope and preserve revision/ETag values for later mutations.
5
Poll the returned job, migration, or text-extraction resource instead of treating 202 Accepted as completion.

Authentication and response envelope

The protected Assets routes are account-scoped. The API key selects the account’s default Assets space; clients do not send a project ID or an internal asset-space ID. Use the narrowest available Assets scope for the operation: assets:read, assets:write, assets:process, assets:generate, assets:publish, or assets:admin.

Core routes

  • POST /api/v1/assets/upload accepts a multipart file plus bucket, key, folder, visibility, cache_control, and JSON metadata.
  • GET /api/v1/assets lists assets. Filters include bucket, prefix, visibility, query, tag, mime_type, type, folder, checksum, status, scan_status, replication_status, moderation_status, and quarantine_status. Sorting accepts created_at, updated_at, size, key, original_name, or mime_type with direction=asc|desc.
  • GET /api/v1/assets/{assetID} returns one asset. PUT /api/v1/assets/{assetID}/replace replaces its bytes while preserving the logical asset ID.
  • PATCH /api/v1/assets/{assetID} updates bucket, key, original name, cache control, or visibility. PUT /api/v1/assets/{assetID}/tags replaces the tag set. PATCH /api/v1/assets/{assetID}/metadata merges supplied JSON keys into metadata.
  • POST /api/v1/assets/{assetID}/signed-url creates a private download URL. The JSON fields are expires_in and optional max_downloads.
  • DELETE /api/v1/assets/{assetID} starts a revision-checked asynchronous delete. POST /api/v1/assets/{assetID}/purge requests cache invalidation for the asset.

Account controls and DAM routes

  • Buckets: GET/POST /api/v1/assets/buckets, then PUT/DELETE /api/v1/assets/buckets/{bucketID} with the bucket revision. Bucket fields include default visibility, cache control, versioning, retention, byte/MIME limits, CORS/allowed origins, home region, replication policy, lifecycle policy, and an optional custom domain.
  • Content policy: GET/PUT /api/v1/assets/policy with allowed_mime_types, max_image_bytes, max_video_bytes, max_other_bytes, and require_scan.
  • Transformations: POST/GET /api/v1/assets/transformations and DELETE /api/v1/assets/transformations/{name}. The POST body accepts legacy fields or a typed v2 definition plus eager policy. POST /assets/{assetID}/transforms materializes a definition/preset; GET /derivatives lists persisted outputs.
  • Lifecycle: POST/GET /api/v1/assets/lifecycle-rules and DELETE /api/v1/assets/lifecycle-rules/{ruleID}. A rule has name, optional prefix, action=delete|expire_versions, age_days, and enabled.
  • Custom domains: POST/GET /api/v1/assets/domains, POST /api/v1/assets/domains/{domainID}/verify, and DELETE /api/v1/assets/domains/{domainID}.
  • Operations: GET /api/v1/assets/analytics, /summary, and /events expose delivery/transform/AI usage, grouped totals, duplicate groups, and the audit stream.
  • Webhooks: POST/GET/DELETE /api/v1/assets/webhooks, GET /api/v1/assets/webhooks/{webhookID}/deliveries, and POST /api/v1/assets/webhook-deliveries/{deliveryID}/retry. The create response includes the signing secret once.
  • DAM organization: GET/POST/PUT/DELETE /api/v1/assets/collections and GET/POST/PUT/DELETE /api/v1/assets/saved-searches; collections store asset IDs and saved searches store a filter object.
  • Bulk: POST /api/v1/assets/bulk accepts revisioned items for delete, visibility, or add_tags and returns a durable job submission.

AI, versions, and branches

  • AI policy/config: GET/PUT /api/v1/assets/ai/config; the update requires If-Match and accepts enabled_actions plus monthly_spend_cap_micros.
  • AI data and actions: GET /api/v1/assets/{assetID}/ai, POST /ai/analyze, POST /moderation, GET/POST /transcript, POST /smart-crop, and POST /background-remove.
  • Net-new generation: POST /api/v1/assets/generations requires assets:generate plus Idempotency-Key, creates private images, and returns a durable job.
  • Version history: GET /api/v1/assets/{assetID}/versions, POST /versions/{versionID}/restore, POST /branches, and POST /branches/{branch}/promote.
  • Delivery helpers: public/current, private/current, version, branch, named-transform, signed-transform, and video paths are served by the CDN rather than the control-plane JSON API.

Connections, storage, migrations, widget capabilities, and OCR

  • Connections: POST/GET /api/v1/assets/connections, GET/PATCH/DELETE /api/v1/assets/connections/{connectionID}, and POST /verify. Secret values are accepted only on create/update and are never returned.
  • S2 and storage: GET/POST /api/v1/assets/s2-buckets, PUT /api/v1/assets/buckets/{bucketID}/storage, and POST /api/v1/assets/buckets/{bucketID}/relocations. Storage updates require the current bucket revision.
  • Migrations: POST/GET /api/v1/assets/migrations, GET /{migrationID}, POST /cancel, POST /items/{itemID}/retry, and raw JSON/CSV GET /report downloads.
  • OCR: POST/GET /api/v1/assets/{assetID}/text-extraction and POST /api/v1/assets/text-extractions/{extractionID}/retry.
  • Widget authorization: POST /api/v1/assets/upload-capabilities returns one short-lived capability token. Capability-only browser traffic uses /assets/widget, outside the authenticated /api/v1 management base.
  • See the platform operations guide for exact request fields, status codes, token scopes, SDK clients, CLI commands, events, and recovery behavior.

Workflows, automation, and MCP

  • Workflow catalog and drafts: GET /assets/workflows/catalog, GET/POST /assets/workflows, GET /assets/workflows/{workflowId}, PUT /draft, and POST /validate.
  • Immutable operation: POST /publish, POST /activate, GET /versions, POST /run, and workflow-scoped GET /runs. Global run detail/cancel/retry is under /assets/workflows/runs/{runId}.
  • Governance: GET /assets/workflows/approvals, approve/reject endpoints, restricted HTTP connections and credential rotation, and active-workflow inbound-hook rotation.
  • GET /assets/automation describes governed tools and recent audits. /assets/mcp is the stateless Streamable HTTP MCP transport; each tool enforces its declared scope.
  • The public signed receiver is POST /api/v1/assets/workflow-hooks/{token} with timestamp, delivery ID, and HMAC signature headers.

Upload sessions

  • POST /api/v1/assets/upload-sessions creates either a single PUT session or a chunked session. Set mode=chunked, file_name, file_size, mime_type, optional checksum_sha256, and optional part_size for resumable uploads.
  • POST /api/v1/assets/upload-url is the legacy-compatible alias for creating the same session response. The current SDK uses /upload-sessions; the alias also accepts legacy camelCase field names for older clients.
  • The response contains upload_session_id, session_id for chunked sessions, the signed PUT url, expires_at, max_bytes, and part_size.
  • PUT a single file to the signed URL. For a chunked session, PUT each part to {upload_url}/parts/{part_number} with an X-Content-SHA256 header, then call POST /api/v1/assets/upload-sessions/{sessionID}/complete.
  • GET /api/v1/assets/upload-sessions/{sessionID} returns the session and received parts so a client can resume. DELETE cancels the session and cleans up its temporary parts.
  • Send Idempotency-Key when creating a session. Reusing the key with different canonical request content returns a conflict instead of creating a second session.

Concurrency and idempotency

  • Asset and bucket mutations require If-Match: "<revision>". The current response includes an ETag with the same revision. A stale or missing revision is rejected so an older dashboard cannot overwrite a newer edit.
  • Upload, replace, delete, bulk, and AI job mutations accept Idempotency-Key where the SDK exposes one. A key with different request content returns assets.idempotency_conflict.
  • List cursors are opaque and bound to their sort and direction. Keep using the returned next_cursor; do not manufacture or decode cursors.

Asynchronous jobs and states

  • AI actions, bulk actions, and physical deletion return 202 Accepted with job_id, status, and status_url. Poll GET /api/v1/assets/jobs/{jobID} and cancel with POST /api/v1/assets/jobs/{jobID}/cancel when supported.
  • A newly uploaded asset may be processing before it is ready. quarantined and failed assets have no deliverable public URL. A delete moves through deleting before the physical replicas are removed.
  • AI requests can be rejected when the action is not enabled for the account, the monthly spend cap is exhausted, or the configured model has not passed the evaluation gate.

Delivery URL shapes

  • Current public version: https://cdn.stackshift.cloud/assets/{assetID}/versions/{versionID}/{filename}.
  • Private signed version: https://cdn.stackshift.cloud/private/assets/{assetID}/versions/{versionID}/{filename}?token=....
  • Named transform: https://cdn.stackshift.cloud/t/{preset}/assets/{assetID}.
  • Signed transform: https://cdn.stackshift.cloud/assets/{assetID}/tr/{spec}/{filename}?exp=...&sig=....
  • Video output: .../assets/{assetID}/video/{kind}/{profile} for hls, poster, thumbnail, or mp4; add the private token query parameter for a private output.
  • The SDK URL helpers are preferred because they use the configured CDN base URL and escape IDs, names, specs, and filenames correctly.

Common error codes

  • 401 means the API key or session is missing or invalid. 404 means the asset, bucket, job, or delivery target is not visible in the account.
  • 409 is used for duplicate keys, idempotency conflicts, or an idempotent operation still in progress.
  • 428 means a required If-Match header is missing; 412 means the supplied revision is stale and does not match the current revision.
  • 422 indicates a checksum mismatch. Content-policy and request validation failures use 400; 402 can indicate an asset quota or AI spend cap has been reached.
  • A public delivery 404 is also expected for an asset that is not ready, quarantined, deleted, or missing an available replica. Do not retry it as if it were a transient CDN failure without checking the asset state.

Expected result

You can map any Assets SDK method to its REST route and handle successful, asynchronous, conflicting, and quarantined responses correctly.

StackShift Assets

A grounded guide to Assets storage, uploads, delivery, imports, BYOB and S2, transformations, OCR, media processing, AI jobs, and DAM controls.

Assets SDK quick start

Install the official SDKs, upload a first asset, and handle the readiness state before you publish its URL.

Deterministic image, video, and audio transforms

Define ordered v2 transforms for images, video renditions, audio extraction, and timestamp thumbnails; store eager presets or materialize durable derivatives.

Media Workflows visual builder and API

Author editable templates or blank typed DAGs that coordinate asset gates, native StackShift services, bounded Stackie reasoning, and approved external integrations.