# Upload images to Wix with the Media Manager API
> Generate exact sizes with SocialCutter and push them to Wix Media Manager: generate-upload-url, the binary upload, using the file and the real API limits.
- URL: https://socialcutter.theboomer.dev/en/guides/wix/
- Idioma: en
- Familia: cms
- Actualizado: 2026-09-24
- Palabras clave: Wix, Media Manager, generate-upload-url, API key, multipart upload, images, Node
## Why generate the sizes before uploading

Wix renders every image by cropping it to the slot it sits in: the page header, a product card, a gallery thumbnail, the blog post in the feed. If you upload the master, you leave that crop to the editor and the result changes between views.

The right flow is: **one master goes in, SocialCutter returns every size, and Wix receives the file already cropped**. The `cover` crop (the default mode) is **centred**: it scales and trims the excess evenly on both sides. There is no subject detection involved, so leave some air around the subject.

| Where it goes on the site | SocialCutter destination | Size |
|---|---|---|
| Main product image | `instagram` `post` | 1080x1080 (1:1) |
| Portrait image or story | `instagram` `story` | 1080x1920 (9:16) |
| Page or section header | `twitter` `header` | 1500x500 (3:1) |
| Wide banner | `facebook` `post` | 1200x630 (1.91:1) |
| Video thumbnail | `youtube` `thumbnail` | 1280x720 (16:9) |

The real sizes and formats come from `GET /api/v1/platforms`, which is public. The catalogue has no 4:5: square is 1:1 and portrait is 9:16.

## Before you start: API key and permissions

The API key is generated in the Wix dashboard and sent in the `Authorization` header **as-is**, without the word `Bearer`:

```bash
export WIX_AUTH="IST.eyJra..."   # API key from the dashboard
export SC_KEY="sc_your_key"
```

For the Media Manager the key needs the **Manage Media Manager** permission. The flow is documented here:

- Generate the upload URL: https://dev.wix.com/docs/api-reference/assets/media/media-manager/files/generate-file-upload-url
- Upload with that URL: https://dev.wix.com/docs/api-reference/assets/media/media-manager/files/upload-api

> Heads-up: Wix APIs are versioned and parameter names change. Always check the docs of the day before treating a flow as settled.

## 1. Generate the sizes with SocialCutter

```bash
curl -s -X POST "https://api.socialcutter.theboomer.dev/api/v1/images/process" \
  -H "X-API-Key: *** \
  -H "Content-Type: application/json" \
  -H "Idempotency-Key: wix-home-2026-09" \
  -d '{
    "source": { "type": "url", "value": "https://your-cdn.com/master.jpg" },
    "destinations": [
      { "platform": "instagram", "format": "post" },
      { "platform": "twitter", "format": "header" }
    ]
  }' > sc.json

jq -r '.outputs[] | "\(.platform)/\(.format) \(.width)x\(.height) \(.url)"' sc.json
```

Every output carries `url`, `width`, `height` and `size_bytes`. For a local file use `POST /api/v1/images/process/upload` (multipart, `file` field, 5 MB max); for several masters, `POST /api/v1/images/batch`.

## 2. Ask for the upload URL and push the binary

The Media Manager does not take the file against its own endpoint: first you request a signed URL and upload there with `PUT`.

```bash
WIX_BASE="https://www.wixapis.com"

# 2a. Signed URL
UPLOAD_URL=$(curl -s -X POST "$WIX_BASE/site-media/v1/files/generate-upload-url" \
  -H "Authorization: $WIX_AUTH" \
  -H "Content-Type: application/json" \
  -d '{"mimeType":"image/jpeg","fileName":"category.jpg"}' | jq -r '.uploadUrl')

# 2b. Upload the file (binary)
curl -s -X PUT "$UPLOAD_URL?filename=category.jpg" \
  -H "Content-Type: image/jpeg" \
  --data-binary "@category.jpg" | jq '.file | {id, url, displayName}'
```

The response carries `file.id` and `file.url` (a `static.wixstatic.com/media/...` link). That `url` is what you paste into the page element, the product or the post.

If your outputs already live behind a public URL you can skip the upload: `POST /site-media/v1/files/import` with `{"url": ..., "mimeType": ...}` pulls them in directly, and `POST /site-media/v1/bulk/files/import-v2` imports several at once.

## 3. Node snippet

```js
const WIX = 'https://www.wixapis.com'
const AUTH = process.env.WIX_AUTH // API key, no 'Bearer'
const SC_KEY = process.env.SC_KEY

async function upload(socialCutterUrl, name) {
  // 1. Signed URL
  const r1 = await fetch(`${WIX}/site-media/v1/files/generate-upload-url`, {
    method: 'POST',
    headers: { Authorization: AUTH, 'Content-Type': 'application/json' },
    body: JSON.stringify({ mimeType: 'image/jpeg', fileName: name })
  })
  const { uploadUrl } = await r1.json()

  // 2. Push the binary
  const bin = await fetch(socialCutterUrl)
  const r2 = await fetch(`${uploadUrl}?filename=${encodeURIComponent(name)}`, {
    method: 'PUT',
    headers: { 'Content-Type': 'image/jpeg' },
    body: Buffer.from(await bin.arrayBuffer())
  })
  const { file } = await r2.json()
  return file // { id, url, ... } — may not be ready yet
}

;(async () => {
  const sc = await fetch('https://api.socialcutter.theboomer.dev/api/v1/images/process', {
    method: 'POST',
    headers: { 'X-API-Key': SC_KEY, 'Content-Type': 'application/json' },
    body: JSON.stringify({
      source: { type: 'url', value: 'https://your-cdn.com/master.jpg' },
      destinations: [{ platform: 'instagram', format: 'post' }]
    })
  }).then(r => r.json())

  for (const out of sc.outputs) {
    const f = await upload(out.url, `wix-${out.platform}-${out.format}.jpg`)
    console.log(out.platform, out.format, '→', f.url)
  }
})()
```

## The Wix API's real limits

Worth knowing before you promise an automation:

- **The Media Manager is reachable** with an API key and the right permission, to upload and import files.
- **The file is not ready when the call returns.** A `200` on the upload does not mean you can use it: the docs ask you to wait for the **File Ready** event (or **File Failed**) before managing it.
- **Files over 10 MB** go through the resumable URL (`generate-resumable-upload-url`), not the regular one.
- **Publishing content through the API is not available on every plan or editor.** The Blog API exists, but calling it requires authenticating as a Wix app or user with the matching permissions and, for a third-party app, supplying a `memberId` as the author. On many sites the practical path is to upload the image to the Media Manager and place it by hand in the editor, or to expose a Velo *web method* inside the site itself, which runs with the site's own permissions. Reference: https://dev.wix.com/docs/api-reference/business-solutions/blog/introduction

That is why this guide covers the part that is genuinely programmable —the images— and leaves publishing to whatever route your plan allows.

## Cost

- **1 use per destination** (platform and format) per request; repeated destinations are not charged twice.
- Failed processing is refunded.
- Every plan includes API and MCP: Free 3 uses/day, Basic 10, Pro 30, Agency 100, from 0 / 3 / 9 / 29 EUR per month.

## Typical errors

| Symptom | Cause | Fix |
|---|---|---|
| `401` from the Wix API | Key mistyped or a stray `Bearer` | Send only the key in `Authorization` |
| `403` when generating the URL | Missing the Manage Media Manager permission | Recreate the key with that permission |
| The upload responds but the image is missing | The file is not ready yet | Wait for the File Ready event before using it |
| Wrong `Content-Type` | Uploaded without the header or with a wrong mime | Send `image/jpeg` or `image/png` matching the file |
| The image looks oddly cropped | You uploaded the master and Wix cropped it | Upload the SocialCutter size instead |
| `413` from SocialCutter | The master is over 5 MB | Shrink the image before uploading it |
| `429` from SocialCutter | Wallet quota exhausted | Check your quota in the dashboard or upgrade |

## Next steps

- Terminal: [Process images with the API from the terminal (curl)](/en/guides/curl/)
- Node: [Process images with the API from Node](/en/guides/node/)
- Webflow: [Integrate SocialCutter with the Webflow API](/en/guides/webflow/)
- WordPress: [Integrate SocialCutter with WordPress and WooCommerce](/en/guides/wordpress/)
- Automation: [Automate image resizing for social media](/en/guides/automatizar-imagenes-redes-sociales/)
- Documentation: https://docs.socialcutter.theboomer.dev