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

Goal

Operate every Assets expansion surface through a supported interface and recover from provider, worker, checksum, credential, or OCR failures without losing access to asset bytes.

Prerequisites

  • A StackShift API token with the narrowest required Assets scope
  • The current JavaScript SDK or StackShift CLI when not calling REST directly
  • Access to Assets Operations in the dashboard for visual connection, migration, relocation, and OCR workflows

Workflow

1
Choose the narrowest token scope from the route matrix before creating automation.
2
Use the nested JavaScript SDK clients for typed calls, the CLI for operator workflows, or the documented REST routes for another runtime.
3
Treat migration, relocation, and OCR state records as authoritative; do not infer completion from request acceptance or worker logs.
4
Use item reports, warning/error codes, events, and provider verification to identify the failing boundary.
5
Restore access to the recorded backend first, then retry the smallest failed unit and confirm CDN origin health.

Authentication, response rules, and scopes

Management routes use https://api.stackshift.cloud/api/v1 and Authorization: Bearer <token>. Normal successful responses use the StackShift success/data envelope. Migration reports are raw application/json or text/csv downloads. Widget data-plane routes use https://api.stackshift.cloud/assets/widget with a one-time capability token and an exact HTTPS Origin; they do not accept a general Assets token.
  • assets:read: list/get connections, S2 buckets, migrations and reports, text results, buckets, assets, usage, and events.
  • assets:write: create browser upload capabilities and change bucket storage configuration. Existing upload and library-write routes also use this scope.
  • assets:process: start/cancel migrations, start relocation, retry migration items, start/retry OCR, and invoke other transform/AI processing routes.
  • assets:generate: create net-new private images through the governed generation job.
  • assets:publish: publish/activate governed workflow versions and decide publication-bearing approvals.
  • assets:admin: create/update/verify/delete provider connections, create an owned S2 bucket, and perform destructive or credential administration.
  • An assets:admin token permits all Assets routes. Read methods are also permitted by assets:write and assets:process; prefer including assets:read explicitly when minting purpose-specific automation tokens.

Connection and storage REST routes

  • POST /assets/connections (assets:admin, 201): create a tenant-scoped external, S2, or Cloudinary connection.
  • GET /assets/connections and GET /assets/connections/{connectionID} (assets:read, 200): return redacted configuration and verification state.
  • PATCH /assets/connections/{connectionID} (assets:admin, 200): change display/configuration fields or replace a secret without returning it.
  • POST /assets/connections/{connectionID}/verify (assets:admin, 200): perform the provider probe and persist the result.
  • DELETE /assets/connections/{connectionID} (assets:admin, 200): revoke/delete only when no protected reference remains.
  • GET /assets/s2-buckets (assets:read, 200) and POST /assets/s2-buckets (assets:admin, 201): list or create user-owned S2 buckets for Assets.
  • PUT /assets/buckets/{bucketID}/storage (assets:write, 200): set storage_mode, backend reference, prefixes, auto_extract_text, and expected revision. Send the revision in If-Match or expected_revision.
  • POST /assets/buckets/{bucketID}/relocations (assets:process, 202): create a relocation inventory with optional dry_run.

Migration, OCR, and capability REST routes

  • POST /assets/migrations (assets:process, 202): start import or relocate with source connection, destination bucket, prefix, conflict policy, and dry-run mode.
  • GET /assets/migrations?limit=N and GET /assets/migrations/{migrationID} (assets:read, 200): read persisted summaries and progress.
  • POST /assets/migrations/{migrationID}/cancel (assets:process, 200): request cooperative cancellation.
  • POST /assets/migrations/{migrationID}/items/{itemID}/retry (assets:process, 202): requeue one terminal failed item.
  • GET /assets/migrations/{migrationID}/report?format=json|csv (assets:read, 200): download the complete JSON report or CSV projection.
  • POST /assets/{assetID}/text-extraction (assets:process, 202): start or link a cached extraction with language and options.
  • GET /assets/{assetID}/text-extraction (assets:read, 200) and POST /assets/text-extractions/{extractionID}/retry (assets:process, 202): read or retry OCR.
  • POST /assets/upload-capabilities (assets:write, 201): create the one-time browser capability. The token is returned only in this response.

Capability-only widget routes

  • POST /assets/widget/sessions: create one chunked session from the capability; request fields are key, file_name, file_size, mime_type, optional checksum_sha256, part_size, and metadata.
  • GET /assets/widget/sessions/current: reconcile the capability-bound session and its received parts.
  • PUT /assets/widget/uploads/{sessionToken}/parts/{partNumber}: stream one part with X-Content-SHA256.
  • POST /assets/widget/sessions/current/complete: verify and commit the asset, then revoke the capability.
  • DELETE /assets/widget/sessions/current: cancel temporary upload state and revoke the capability.
  • POST /assets/widget/remote-url: ingest { url, key } only when the capability explicitly permits remote URLs.
  • CORS allows only the normalized origin carried by the request and the capability. Allowed headers are Authorization, Content-Type, and X-Content-SHA256; the exposed response header is ETag.

JavaScript SDK clients

StackShift.assets keeps the existing upload, delivery, transform, DAM, video, and AI methods and adds typed platform and workflow clients. All names below map directly to documented REST routes.
  • assets.connections: create, list, get, update, verify, and delete.
  • assets.storage: configure, listS2Buckets, createS2Bucket, and relocate.
  • assets.migrations: start, list, get, cancel, retryItem, report, and downloadReport. Use downloadReport for raw JSON/CSV Blob data.
  • assets.text: start, get, and retry.
  • assets.uploadCapabilities: create for trusted backend code only.
  • assets.workflows: catalog, draft CRUD, validation, publish/activate, versions, runs, approvals, restricted HTTP connections, credential rotation, and inbound-hook rotation.
  • assets.materializeTransform, derivatives, generate, and automation cover durable v2 transforms, generated images, and governed MCP discovery.
  • ChunkedUploadController is the framework-neutral upload engine shared by the SDK and widget; it owns per-part SHA-256, bounded concurrency, retries, cancellation, persistence, fingerprint validation, and server-part reconciliation.

CLI command patterns

The command group is stackshift asset; stackshift assets is an alias. Body-taking operations accept --data or --file. Add --output json for automation, --wait to stream supported migration/relocation/OCR progress, and --poll-interval to change the two-second default. Risky cancellation/deletion commands prompt unless --yes is supplied.
  • Connection commands: connection-create, connections, connection-get, connection-update, connection-verify, and connection-delete.
  • Storage commands: s2-buckets, s2-bucket-create, bucket-storage-set, and relocate.
  • Migration commands: migration-start, migrations, migration-get, migration-cancel, migration-item-retry, and migration-report.
  • OCR and widget-backend commands: ocr-start, ocr-get, ocr-retry, and upload-capability-create.
  • Media commands: transform-run, derivatives, generate, and automation.
  • Workflow commands: catalog/list/create/get/draft-update/validate/publish/activate, versions/runs, run detail/cancel/retry, approvals, connections, credential rotation, and inbound-hook rotation.

Durability and concurrency guarantees

  • Production runs a dedicated Assets worker with four durable-job slots. External provider work and OCR are separately bounded to two concurrent operations each by default.
  • Job and migration-item claims use database leases, heartbeats, unique lease tokens, fencing, expired-lease recovery, bounded attempts, and monotonic persisted progress. A stale worker cannot checkpoint or complete work after losing its lease.
  • Worker crashes and restarts recover expired work. Duplicate job delivery and repeated inventory are idempotent; migration source identities and checksum checks prevent duplicate assets.
  • Streaming uses bounded temporary scratch rather than loading entire provider objects into memory. Completion, cancellation, timeout, and recovery clean scratch and abort incomplete multipart uploads.
  • Cancellation races fail closed: a canceled operation cannot later be completed by a stale claimant.

Events, reports, and observable state

  • Audit/event names include asset.connection.created, .updated, .verified, .deleted, asset.bucket.storage_changed, migration .started, .completed, .failed, .canceled, relocation .completed/.failed, and OCR .completed/.failed.
  • Use GET /assets/events and existing Assets webhooks for customer-visible lifecycle evidence. Event payloads carry IDs and states, not stored secrets, signed URLs, or capability tokens.
  • Migration reports remain available after completion, failure, or cancellation and are authoritative for item outcomes. source_identity is the provider-side correlation key.
  • The dashboard Assets Operations area exposes Storage, Connections, Migrations, and OCR panels with verification results, live progress, report download, retry/cancel actions, relocation state, and geometry inspection.

Recovery playbooks

  • Stalled queue or worker crash: confirm worker/database/provider health, allow the lease to expire, restart normally, and verify persisted counters resume. Never edit leases or delete operation rows.
  • Static credential rotation: update the encrypted connection secret, verify the connection, then revoke the old provider key. AWS AssumeRole rotation should retain the connection external ID while the customer role policy/trust is updated.
  • Provider outage: keep connection and migration records. Restore provider access first; managed objects remain independent while objects recorded on the unavailable backend can produce origin failures.
  • checksum_mismatch: leave the source reference unchanged, remove/quarantine the bad destination object, investigate transport/provider integrity, and retry.
  • source_delete_failed: the verified destination is already authoritative. Restore source-provider access and remove only the recorded old object; do not roll back the database storage reference.
  • OCR provider_failed: verify the asset is readable and Poppler, Tesseract, requested language data, and scratch capacity are healthy, then retry the extraction ID.
  • Multipart cleanup alert: restore the exact provider connection, identify incomplete uploads by the known StackShift prefix/session identity, and abort only those uploads. Never bulk-delete a customer bucket.

Security, deletion, and billing invariants

  • Secrets are encrypted with connection-specific authenticated data, redacted from responses, and forbidden from logs, reports, events, and URLs. Browser capabilities are stored hashed and expire within one hour.
  • Generic endpoints require public HTTPS, reject redirects and userinfo, validate DNS before use, and revalidate resolved addresses at connection time to block private/reserved targets and DNS rebinding.
  • A connection or S2 bucket cannot be deleted while referenced by bucket storage, active uploads, migrations, relocations, or available storage objects. Remove references safely; do not bypass the check.
  • Relocation never deletes the source before destination checksum verification and atomic reference commit. A failed relocation remains readable from the original backend.
  • Managed, BYOB, and S2 assets all count toward logical Assets quota, ingress/egress, processing, OCR, and CDN usage. Only StackShift-managed Assets bytes accrue Assets managed physical-storage byte-hours; native S2 is accounted by the Object Store product.

Expected result

Automation and operators use the same persisted state and can recover without editing storage references, exposing credentials, or deleting source data prematurely.

Common failures

  • A token has assets:write but the operation requires assets:process or assets:admin.
  • A client treats 202 Accepted as completed rather than polling the migration or extraction resource.
  • A report download is parsed through the JSON envelope even though JSON/CSV report responses are raw downloadable bodies.
  • An operator retries broadly before restoring provider access, causing repeated bounded failures without changing the underlying condition.

Storage connections, BYOB, and StackShift S2

Configure AWS S3, Cloudflare R2, Wasabi, MinIO, generic S3, or native StackShift S2 without exposing customer storage credentials or changing delivery URLs.

Cloudinary, S3, R2, and S2 migrations

Inventory, dry-run, import, deduplicate, retry, cancel, and report durable migrations from Cloudinary or S3-compatible storage into StackShift Assets.

Embeddable Assets upload widget

Install @stackshift-cloud/assets-widget for React or vanilla JavaScript with constrained backend-issued capabilities, resumable chunks, camera and URL input, cropping, previews, progress, retry, and cancellation.

OCR, document intelligence, and DAM search

Extract embedded PDF text or OCR PDF and image pages asynchronously, inspect normalized word geometry, cache by content identity, and search extracted text in the DAM.