# Rename, reorder or delete vendor files

```http
POST https://secure.yoprint.com/v1/api/store/{team_slug}/vendor/{hash_id}/media/{media_reference}
```

- API version: v1
- Operation ID: `v1_public_vendor_media_sync`
- Section: Purchasing › [Vendor files](https://developer.yoprint.com/reference/vendor-files.md)
- Web page: https://developer.yoprint.com/reference/vendor-files/v1-vendor-media-sync/
- Authentication: `Authorization: Bearer YOUR_API_KEY`

Changes several of the vendor's files in one request and returns all its files. The last path segment must be the word `sync`.

Each item names a file and an `action`: `update` sets its `name` and `position`, `delete` removes it. Items run in order, all or nothing.

## Permission

Any member of the team.

## Path parameters

- `team_slug` (string, required): Your team slug, shown as Team ID next to your API key in Profile. Example `your-team`.
- `hash_id` (string, required): The vendor's id (`id` from List vendors). A hash id from an earlier answer; unique keys and document numbers (such as `PO0042`) don't work here. Example `EDhVUaC6jbLbed`.
- `media_reference` (string, required): Always the word `sync`. The route only matches `sync`: any other value answers 405 (an HTML page unless you send `Accept: application/json`). One of: `"sync"`. Example `sync`.

## Request body

Content type `application/json`, required.

Fields:

- `data` (array of objects, required): At least 1 item.
  - Each item:
    - `action` (string, required): One of: `"update"`, `"delete"`.
    - `id` (string, required): The file id.
    - `name` (string, optional): `update`: the new display name.
    - `position` (integer, optional): `update`: where the file sorts, a whole number from 0. Minimum 0.

### Example request

```bash
curl -X POST 'https://secure.yoprint.com/v1/api/store/your-team/vendor/EDhVUaC6jbLbed/media/sync' \
  -H 'Authorization: Bearer YOUR_API_KEY' \
  -H 'Accept: application/json' \
  -H 'X-Yoprint-Decimal-Format: exact-v1' \
  -H 'Content-Type: application/json' \
  -d '{
    "data": [
      {
        "action": "update",
        "id": "YMlcxHYran1mzL",
        "name": "Price list 2026",
        "position": 0
      },
      {
        "action": "delete",
        "id": "mBwjI68SoEttbX"
      }
    ]
  }'
```

## Response

`200` Successful response.

Fields:

- `data` (array of objects, required): All the vendor's files after the changes.
  - Each item:
    - `collection` (string, required): Customer files: `tax_exemption`, `internal_file` or `external_file`. Vendor files: `default`, `mockup` or `production_file`.
    - `created_at` (string (date-time), required)
    - `file_name` (string, required)
    - `id` (string, required)
    - `mime_type` (string | null, required)
    - `name` (string | null, required): The display name.
    - `size` (integer, required): Bytes.
    - `custom_properties` (object | array, optional)
    - `customer_id` (string, optional): Customer files only.
    - `dimensions` (object | null, optional): Pixel size of an image, read from its header; null for other files and for images uploaded before the size was recorded.
      - `height` (integer, optional)
      - `width` (integer, optional)
    - `is_image` (boolean, optional)
    - `position` (integer | null, optional): Where the file sorts.
    - `preview` (object | null, optional): Preview image links `small`, `medium` and `large` (250, 800 and 1200 px), or null when there is no preview.
    - `preview_state` (string, optional): `ready`: the preview links work. `processing`: an image over 10 MB whose stored preview a worker is still making (seconds); read the file again, or in the web app wait for `media.preview_state_changed` on the team channel. `too_large`: an image over 120 megapixels; it never gets a preview. `failed`: the worker gave up. `none`: not an image. One of: `"ready"`, `"processing"`, `"too_large"`, `"failed"`, `"none"`.
    - `show_in_pdf` (boolean | null, optional)
    - `source_media_id` (string | null, optional)
    - `url` (string | null, optional): Where to download the file.
    - `view_url` (string | null, optional): A signed link to view the file. It expires: read it fresh, and don't store it.
- `status` (integer, required)
- `success` (boolean, required)

Example response:

```json
{
  "data": [
    {
      "collection": "default",
      "created_at": "2026-11-01T09:00:00+00:00",
      "custom_properties": [],
      "file_name": "price-list.pdf",
      "id": "YMlcxHYran1mzL",
      "is_image": false,
      "mime_type": "application/pdf",
      "name": "Price list 2026",
      "position": 0,
      "preview": null,
      "show_in_pdf": null,
      "size": 48211,
      "source_media_id": null,
      "url": "https://example.com/media/YMlcxHYran1mzL/download",
      "view_url": "https://example.com/media/YMlcxHYran1mzL/view"
    }
  ],
  "status": 200,
  "success": true
}
```

## Errors

- `401` The API key is missing or wrong (`unauthenticated`).
- `403` You are not allowed to do this. `api_access_not_in_plan`: your team's plan doesn't include API access (Pro and above, with an active subscription or trial), so every request answers this until the team upgrades. When your role lacks the permission the operation needs, the body is only `{"message": "Insufficient Permission"}`. Other refusals use the error envelope, with `unauthorized` or `user_is_not_authorized`.
- `404` Not found. `page_not_found`: the team slug is unknown, you are not a member of the team, or an id in the path is not one of this team's. `code: null`, with a message that starts "No query results for": there is no record with that id.
  - When: An `id` is not a file of this vendor. Nothing is changed. `error.code` is null and `error.message` names the record type. Fix: List the vendor's files first.
- `405`
  - When: The last path segment is not `sync`. Fix: End the path with `/media/sync`.
- `422` The request was refused and changed nothing. `validation_failed` lists what to fix in `error.fields`; other codes name a business rule, explained in `error.message`. A few checks answer with only `{"message": "..."}`. An operation that calls another service (a payment provider, a carrier, an accounting app) can answer `connect_timeout` ("Please retry again") when that service does not answer in time: the change may or may not have happened there, so read the record back before you retry.
  - When: `data` is empty, or an item has no `id` or an `action` other than `update` and `delete`. `error.code` is `validation_failed`. Fix: Fix each field named in `error.fields`; its keys are field paths such as `contact.0.phone`.

## Related

- [List a vendor's files](https://developer.yoprint.com/reference/vendor-files/v1-vendor-media-index.md): `GET /v1/api/store/{team_slug}/vendor/{hash_id}/media`
