## TL;DR
A cloudinary upload preset is a named bundle of upload settings (folder, allowed formats, transformations, size caps) stored in your Cloudinary account. To upload from a browser or mobile app with no backend, create an upload preset, set its signing mode to Unsigned, then POST multipart form data to the upload endpoint with two fields: upload_preset (the preset name) and file (the file bytes). Expect an HTTP 200 with a JSON asset record containing secure_url. The preset name is public by design, so a locked-down preset is your enforcement boundary.

## Use this when
- You need browser or mobile uploads to Cloudinary and have no server to sign requests
- You are setting up an unsigned upload preset for user-generated content
- An upload fails with an error about the preset, signing mode, or unsigned uploads being disabled

## Not for this skill when
- The upload preset exists and is unsigned but uploads still fail: see the troubleshooting skill in Related skills
- The content is sensitive or per-user: use signed uploads with a server-generated signature instead, so your API secret never reaches the client
- You need to delete or manage assets after upload: that requires authenticated API requests, not unsigned ones

## Steps

1. Create the upload preset. In the Cloudinary Console go to Settings, then Upload, then Upload presets, and click Add upload preset. Give it a name and set Signing mode to Unsigned.

Expected: the preset appears in the Upload presets list with signing mode Unsigned.

2. Lock the preset down before you ship it. Set a fixed folder, an allowed-formats list, and file size caps in the preset. Anyone who reads your client code can see the preset name, so everything you do not restrict in the preset is open to the public internet.

Expected: the preset has a folder, a format allowlist, and a maximum file size; nothing uploads outside those bounds.

3. Upload from the client. POST multipart form data to https://api.cloudinary.com/v1_1/[your cloud name]/image/upload with the fields upload_preset and file. Swap image for video or raw in the URL for those resource types.

```text
const formData = new FormData();
formData.append("upload_preset", "my_unsigned_preset");
formData.append("file", file);
const res = await fetch(
  "https://api.cloudinary.com/v1_1/[your cloud name]/image/upload",
  { method: "POST", body: formData }
);
```

Expected: an HTTP 200 response with a JSON asset record containing secure_url and public_id.

4. Verify and troubleshoot failures. If the upload errors, check in this order: the preset name is spelled exactly as in the Console, the preset signing mode really is Unsigned, and unsigned uploads are enabled for the account (Settings, Upload). A signed-mode preset or a typo produces a preset error on every request.

Expected: after the fix, the same request returns 200 with secure_url.

## Variant phrasings

### cloudinary unsigned upload preset
The same setup named by its signing mode: an unsigned upload preset is what makes backend-free uploads possible, because the preset carries the upload parameters so no signature round trip is needed.

### create upload preset cloudinary
The Console task behind the query: Settings, Upload, Upload presets, Add upload preset (step 1). The two settings that matter most are signing mode Unsigned and the restriction fields in step 2.

### cloudinary upload preset not working
Usually one of the three causes in step 4: misspelled preset name, preset still set to Signed, or unsigned uploads disabled at the account level.

## Root cause
Cloudinary will not accept an unsigned client upload without a preset, because the preset is where the account declares which parameters an unauthenticated request may use. Only a restricted set of parameters can be sent from the client in an unsigned request; everything else must live in the preset. Unsigned requests also cannot overwrite existing assets (overwrite is treated as false). If a preset name is exposed and abused, rotate the preset name and update the client config, or disable the preset.

## Edge cases
- Widget and SDK uploads (Upload Widget, React, Vue) take the same preset name and cloud name; the preset rules above apply unchanged.
- Eager transformations on unsigned uploads must be defined in the preset, not sent with the request.
- Multiple presets per app are fine and often better: one locked-down preset per surface (avatars, attachments) beats one permissive preset.

## Tool compatibility
Cloudinary image, video, and raw uploads via the upload API endpoint; Console steps as of 2026. Works with fetch, the Upload Widget, and the JavaScript SDKs, all of which send upload_preset the same way.

## Related skills
- cloudinary unsigned upload not working: https://vectle.com/skills/skl_aP1EKAxvRDm8HFGa207z7Q
- Cloudinary unsigned presets are public upload endpoints; harden them: https://vectle.com/skills/skl_Ut4v1pv8brkmprplEOY6JA

## Provenance
Built from Cloudinary's client-side uploading documentation, linked in the evidence.
