Assets
Assets SDK quick start
LiveInstall a StackShift SDK and upload files from Node/TypeScript, NestJS, Python, or Go.
Goal
Upload a public asset and get a CDN URL with the official SDK.
Current status
This area is documented as current, user-reliable behavior.
Workflow
- 1Create a StackShift client with apiKey.
- 2Call the Assets upload method with a file, bucket, key, visibility, and metadata.
- 3Store the returned asset ID in your app if you need later replacement or deletion.
- 4Use asset.url for originals, assets.url for transforms, videoUrl helpers for playback outputs, and version helpers for pinned delivery.
TypeScript
Example
tsimport { StackShift } from '@stackshift-cloud/sdk'
const stackshift = new StackShift({
apiKey: process.env.STACKSHIFT_API_KEY!,
})
const asset = await stackshift.assets.upload(file, {
bucket: 'avatars',
key: 'users/user_123.png',
visibility: 'public',
metadata: { userId: 'user_123' },
})
console.log(asset.url)NestJS
Wrap the SDK in a service and accept files through NestJS Multer interceptors. For larger browser uploads, create signed upload URLs instead of buffering through the NestJS process.
Example
tsimport { Injectable } from '@nestjs/common'
import { StackShift } from '@stackshift-cloud/sdk'
@Injectable()
export class AssetsService {
private readonly stackshift = new StackShift({
apiKey: process.env.STACKSHIFT_API_KEY!,
})
upload(file: Express.Multer.File) {
return this.stackshift.assets.upload(
new Blob([file.buffer], { type: file.mimetype }),
{
bucket: 'uploads',
key: file.originalname,
visibility: 'private',
metadata: { originalName: file.originalname },
},
)
}
}Example
tsimport { Controller, Post, UploadedFile, UseInterceptors } from '@nestjs/common'
import { FileInterceptor } from '@nestjs/platform-express'
import { AssetsService } from './assets.service'
@Controller('assets')
export class AssetsController {
constructor(private readonly assets: AssetsService) {}
@Post('upload')
@UseInterceptors(FileInterceptor('file'))
upload(@UploadedFile() file: Express.Multer.File) {
return this.assets.upload(file)
}
}React, Next.js, and TanStack Start
Browser apps should never receive the StackShift API key. Create a signed upload URL on a server route, then upload the browser File directly to StackShift Assets.
Server route
tsimport { StackShift } from '@stackshift-cloud/sdk'
const stackshift = new StackShift({
apiKey: process.env.STACKSHIFT_API_KEY!,
})
export async function createAvatarUpload() {
return stackshift.assets.signedUploadUrl({
bucket: 'avatars',
key: `users/${crypto.randomUUID()}.png`,
visibility: 'public',
expiresIn: '10m',
maxBytes: 5_000_000,
})
}Browser client
tsxasync function uploadAvatar(file: File) {
const upload = await fetch('/api/assets/avatar-upload', {
method: 'POST',
}).then((response) => response.json())
await fetch(upload.url, {
method: upload.method,
body: file,
headers: { 'Content-Type': file.type },
})
}Python
Example
pythonfrom stackshift import StackShift
stackshift = StackShift(api_key="sk_live_...")
asset = stackshift.assets.upload(
"avatar.png",
bucket="avatars",
key="users/user_123.png",
visibility="public",
metadata={"user_id": "user_123"},
)
print(asset["url"])Go
Example
goimport (
"context"
"log"
"os"
stackshift "github.com/stackshiftCloud/assets-go"
)
client, err := stackshift.New(stackshift.Options{
APIKey: os.Getenv("STACKSHIFT_API_KEY"),
})
file, _ := os.Open("avatar.png")
defer file.Close()
asset, err := client.Assets.Upload(ctx, stackshift.AssetUpload{
File: file,
FileName: "avatar.png",
Bucket: "avatars",
Key: "users/user_123.png",
Visibility: "public",
})
log.Println(asset.URL)Expected result
Your app uploads a file to StackShift Assets and receives provider-neutral asset metadata.