MainSDK
Search⌘K
Integrations

Cloudinary

Cloudinary as a planned MainSDK media driver - image and video transforms, setup, main.yaml, works on files from any files driver, and swapping.

1 interface1 driverWritten guide
Updated 2026-10-28

Cloudinary is a hosted service that stores, transforms and delivers images and video. It is listed as a planned driver behind media, which resizes images and transcodes video with location data stripped. You would pick it for a wide range of on-the-fly image transforms and a delivery network in front of them.

Interfaces it serves

Pick Cloudinary in main.yaml for any of these. Your calls stay the same, and you can swap later.

Before you start

  1. Create a Cloudinary account. Cloudinary identifies your account by a cloud name, with an API key and secret for server calls.
  2. Decide which transforms you need and whether Cloudinary should store originals. With MainSDK, originals stay in getqr.id through files.
  3. Store the API secret in your secrets manager.

Configure

main.yaml
media:
  driver: cloudinary

How the driver takes the cloud name and keys (as secret: references, for example secret:CLOUDINARY_API_SECRET) is not defined yet.

Use it

lib/avatar.ts
import { media } from "mainsdk/media";

export async function avatarSizes(photoId: string) {
  const [small, large] = await Promise.all([
    media.image(photoId, { width: 64 }),
    media.image(photoId, { width: 512 }),
  ]);
  return { small, large };
}

The photo comes from files.upload(), private to its owner and scanned before it is readable. What media.image() returns is not decided yet.

Local development and testing

media ships in phase 2. The testing kit's in-memory fake for media arrives with its spec, so createTestApp() from @mainsdk/testing and chaos.on("media", { outage: true }) cover it from then. Until then, use the getqr driver with a getqr.id sandbox key.

What MainSDK adds on top

  • Location data stripped from images and video, whichever driver runs.
  • Source files stay in files: owner-scoped, scanned and stored by your files driver.
  • The same media.image() and media.video().transcode() calls on every driver.

See Images and video.

Limits and notes

  • Planned driver, not in the spec yet. media has no spec and is phase 2.
  • Works on files from any files driver (ADR-0013). Whether Cloudinary stays as a media driver is not decided, because media has no spec.
  • Cloudinary would receive the images you transform. Check where it processes and stores them against your MainSDK data region (US, EU or India).

Swap to or from it

main.yaml
media:
  driver: cloudinary   # was getqr

Your media calls stay the same. Originals stay in files, so no files move; processed copies held by Cloudinary would be left behind and should be deleted when you switch back.

FAQ

Can I upload straight to Cloudinary from the browser? No. Uploads go through files to the store you chose, with files.upload() or files.uploadUrl(); importing a storage SDK in route code fails mainsdk check with MAIN-FILES-0010.

Should I use Cloudinary today? media is phase 2 and has no spec, so the driver does not exist yet. Use the default getqr driver until it does.

Next

Open questions

Was this page helpful?

↑↓ moveEnter openEsc close

Not decided yet