Skip to content

Replace Asset File

Swap the file body of an existing internal asset in place, keeping the same asset ID and links.

Last updated

Use this to ship a new version of a file without re-wiring anything. The asset keeps its ID and stays attached to every digital product and order it was already linked to, so buyers downloading it receive the new file automatically — there is no need to create a fresh asset and re-attach it.

Only internal assets can be replaced. The flow mirrors creating an internal asset: the response includes a single presigned PUT URL — upload the new file body to that URL to finish. Once the replacement is committed, the previous file is removed and any watermarking is re-applied to the new body.

Plan storage quota is enforced on the growth in size (new byte_size minus the current size); the per-file ceiling is 2 GB.

  • id (string, path, required)

    The ID (UUID) of the internal asset to replace.

  • asset (object, required)

    Asset fields:

    • filename (string, required)

      Suggested attachment name on download for the new file.

    • byte_size (integer, required)

      Size of the new file in bytes. Must be positive and at most 2 GB.

    • content_type (string)

      Optional MIME type for the new file. Defaults to the asset’s current content type, or application/octet-stream.

  • asset (object, required)

    The asset, with its ID unchanged.

  • upload (object, required)

    A single-PUT handle (method: "PUT") with the presigned URL and headers required to upload the new file body. See Upload Asset for the field-by-field breakdown.

Example request

Terminal window
curl -X POST 'https://app.filemonk.io/api/v1/external/assets/a1b2c3d4-e5f6-7890-abcd-ef1234567890/replace' \
-H 'X-Auth-Token: fm_api_key_your_key_here' \
-H 'Content-Type: application/json' \
-d '{
"asset": {
"filename": "brushes-pack-v3.zip",
"byte_size": 2097152,
"content_type": "application/zip"
}
}'
const ASSET_ID = 'a1b2c3d4-e5f6-7890-abcd-ef1234567890';
const path = './brushes-pack-v3.zip';
const { size } = await stat(path);
const replace = await fetch(
`https://app.filemonk.io/api/v1/external/assets/${ASSET_ID}/replace`,
{
method: 'POST',
headers: {
'X-Auth-Token': 'fm_api_key_your_key_here',
'Content-Type': 'application/json'
},
body: JSON.stringify({
asset: {
filename: 'brushes-pack-v3.zip',
byte_size: size,
content_type: 'application/zip'
}
})
}
).then(r => r.json());
// Upload the new body to the presigned URL.
await fetch(replace.upload.url, {
method: 'PUT',
headers: replace.upload.headers,
body: await readFile(path)
});
ASSET_ID = 'a1b2c3d4-e5f6-7890-abcd-ef1234567890'
path = './brushes-pack-v3.zip'
replace = requests.post(
f'https://app.filemonk.io/api/v1/external/assets/{ASSET_ID}/replace',
headers={'X-Auth-Token': 'fm_api_key_your_key_here'},
json={
'asset': {
'filename': 'brushes-pack-v3.zip',
'byte_size': os.path.getsize(path),
'content_type': 'application/zip'
}
}
).json()
with open(path, 'rb') as f:
requests.put(
replace['upload']['url'],
headers=replace['upload']['headers'],
data=f
)

Example response

{
"asset": {
"id": "a1b2c3d4-e5f6-7890-abcd-ef1234567890",
"type": "internal",
"name": "Photoshop Brushes Pack",
"filename": "brushes-pack-v3.zip",
"content_type": "application/zip",
"byte_size": 2097152,
"watermark_asset": false,
"autogenerate_licence_key": false,
"created_at": "2026-04-08T10:00:00Z",
"updated_at": "2026-04-09T12:30:00Z"
},
"upload": {
"method": "PUT",
"url": "https://<bucket>.r2.cloudflarestorage.com/external_api/<shop_id>/9c4b.zip?X-Amz-Signature=...",
"headers": {
"Content-Type": "application/zip",
"Content-Disposition": "inline; filename=\"brushes-pack-v3.zip\""
},
"expires_at": "2026-04-09T13:30:00Z"
}
}
{
"error": "Only internal assets can have their file replaced"
}
{
"error": "Asset not found"
}
Was this page helpful?

Still stuck? Ask Quinn or chat with support