SudoMock
Mockups
DocsPricing
Request a demo
Get Started

Start rendering mockups in minutes

From PSD to product mockup in one API call.

Get Free API Key→Browse Templates
Public status pagePublished API pricingProduct mockup API500 one-time API credits

Site Navigation

SudoMock

Turn reusable PSD templates, artwork, and editable text into production-ready product images through REST API, no-code workflows, native storefront apps, or AI.

SudoMock is a registered DBA
1209 Mountain Rd Pl NE, Ste N
Albuquerque, NM 87110, USA

Product

  • Pricing
  • Dashboard
  • PSD Mockups
  • Changelog
  • Start Free

Developers

  • API Overview
  • MCP Server
  • Quick Start
  • Render API
  • Upload PSD
  • Authentication
  • Error Handling
  • PSD Preparation
  • Integrations

Mockups & Tools

  • All Mockups
  • Apparel Mockups
  • Drinkware Mockups
  • Wall Art Mockups
  • Home & Living
  • By Platform
  • Search Mockups
  • Background Remover
  • Free Tools

Resources

  • All Use Cases
  • T-Shirt Mockup Generator for Print on Demand
  • Tote Bag Mockup Generator for Sustainable Brands
  • Automate Mug at Scale with SudoMock
  • Blog
  • Roadmap
  • All Alternatives
  • vs Placeit
  • vs DynamicMockups
  • vs Adobe Photoshop API
  • vs Static Mockup Generators
  • vs AI Image Editors

Company

  • About
  • Contact
  • Brand Assets
  • System Status (opens in new tab)
  • Feature Requests (opens in new tab)
Blog

Latest Articles

View all →
  • 01Batch Replace Smart Objects in Photoshop: Script or API
  • 02WooCommerce Product Placeholder Image: Change It, Then Replace It
  • 03Amazon Product Image Requirements: The Rules and Where a Mockup Fits
  • 04Print on Demand Ornaments: A Mockup for Every Holiday Design

© 2026 SudoMock. All rights reserved.

PrivacyTermsRefundsCookies[email protected]
  1. Blog
  2. /
  3. Tutorial

Batch Replace Smart Objects in Photoshop: Script or API

A Photoshop script batch replaces smart objects by selecting the smart object layer, running Replace Contents with each design file and saving a copy, with Photoshop open on that machine. By API it is one render request per design and per template, so one design fills a tee, a mug and a framed poster PSD in three requests.

Published Nov 4, 2026·7 min read·Beck

A Photoshop batch replace script with File.openDialog, placedLayerReplaceContents and saveAs beside the render request that does the same job, above one sunset design rendered into a framed poster, a mug and a t-shirt template

Key takeaways

  • Adobe's current scripts are .psjs files on V8; most forum scripts are ES3 .jsx files.
  • A flat PNG inside the smart object can make the script export the first design every time.
  • A render loop has no file dialog and no Photoshop session, so it runs on a server or in n8n.

On this page

  • How a batch replace script fills a smart object
  • ExtendScript or UXP: which script language
  • Five ways a batch replace script fails, and what the threads say
  • The same job without Photoshop: upload once, then one request per design
  • One design into every mockup PSD
  • Running a long list
  • Next step
  • Frequently asked questions
  • Sources

How a batch replace script fills a smart object

Every forum script for this job is built on one Action Manager call, placedLayerReplaceContents, which swaps the contents of the active layer for a file on disk. The rest is a file dialog, a loop and a save per file.

The Adobe community thread Batch replace smart objects (asked on 30 January 2014, 77 replies and 38,134 views when read on 4 November 2026) started with a designer who needed "over 40 book, CD, DVD, and Blu-Ray mockups for each flyer". The accepted answer from Community Expert c.pfaffenbichler replaces the contents with this Action Manager call:

JavaScript
// From the accepted answer in the Adobe community thread "Batch replace smart objects"
function replaceContents (newFile, theSO) {
app.activeDocument.activeLayer = theSO;
var idplacedLayerReplaceContents = stringIDToTypeID( "placedLayerReplaceContents" );
var desc3 = new ActionDescriptor();
var idnull = charIDToTypeID( "null" );
desc3.putPath( idnull, new File( newFile ) );
var idPgNm = charIDToTypeID( "PgNm" );
desc3.putInteger( idPgNm, 1 );
executeAction( idplacedLayerReplaceContents, desc3, DialogModes.NO );
return app.activeDocument.activeLayer
};

Each result is saved next to the open PSD, named after the mockup and the design file.

ExtendScript or UXP: which script language

Most Photoshop scripts are JavaScript, in one of two forms. The forum scripts are ExtendScript files (.jsx), and Adobe's current platform runs UXP scripts (.psjs).

Adobe's UXP scripting page (read 4 November 2026) puts the difference this way: "ExtendScript uses a very old version of JavaScript (ES3), while UXP uses the V8 JavaScript engine which supports ES6." Its quickstart runs a .psjs file from "File Menu > Scripts > Browse" or by dropping it onto the Photoshop window, and a UXP script "cannot have a panel UI", only dialogs. Either way the script runs inside Photoshop, on the machine where Photoshop is open.

Five ways a batch replace script fails, and what the threads say

The threads record the same failures again and again, and most have a fix inside Photoshop.

What you seeWhere it is reportedWhat the thread says
The alert "selected layer is not a smart object"The script itself checks theLayer.kind on the active layerSelect the smart object layer in the Layers panel, then run the script
PNG designs do not show in the file dialog2019 thread, JJMack, 22 January 2019: "The image file types can be PSD, Tif and Jpeg."The script's file filter lists *.psd;*.tif;*.jpg: add *.png to it, or convert the designs
The first design is exported for every file2018 thread, about 100 PNGs into one frame mockupJJMack: Save may switch to Save As "because the original was a flat png file". Add an empty layer inside the smart object, save it as a PSD and use Layer > Smart Object > Replace Contents with that PSD before the run
A long run times out and nothing comes outSame thread, for "over 50k of mockups" of one canvas sizeThe asker: "the script seems to time out and nothing occurs at all", later narrowed to "~750 image files" (725 worked). JJMack ran 217 files without a problem and saw RAM use climb "from 4GB to 19GB" over an 876-file run
An error after a Photoshop updateSame thread, 17 August 2020A reader ran JJMack's scripts in Photoshop 2020 only after commenting out an @include line

The same job without Photoshop: upload once, then one request per design

Upload the mockup PSD once and keep the template ID and the smart object ID from the response. Each design is then one render request, and the finished image comes back as a URL, so the loop runs on a server, in a scheduled job or in n8n with no Photoshop session.

curl -X POST https://api.sudomock.com/api/v1/psd/upload \
-H "x-api-key: $SUDOMOCK_API_KEY" \
-H "Content-Type: application/json" \
-d '{"psd_file_url": "https://cdn.example.com/canvas-mockup.psd", "psd_name": "Canvas 16x20"}'
const response = await fetch('https://api.sudomock.com/api/v1/psd/upload', {
method: 'POST',
headers: {
'x-api-key': process.env.SUDOMOCK_API_KEY,
'Content-Type': 'application/json',
},
body: JSON.stringify({
"psd_file_url": "https://cdn.example.com/canvas-mockup.psd",
"psd_name": "Canvas 16x20"
}),
});
const data = await response.json();
console.log(data);
import os
import requests
response = requests.post(
"https://api.sudomock.com/api/v1/psd/upload",
headers={
"x-api-key": os.environ["SUDOMOCK_API_KEY"],
"Content-Type": "application/json",
},
json={
"psd_file_url": "https://cdn.example.com/canvas-mockup.psd",
"psd_name": "Canvas 16x20",
},
)
print(response.json())
package main
import (
"bytes"
"fmt"
"io"
"net/http"
"os"
)
func main() {
payload := []byte(`{
"psd_file_url": "https://cdn.example.com/canvas-mockup.psd",
"psd_name": "Canvas 16x20"
}`)
req, err := http.NewRequest("POST", "https://api.sudomock.com/api/v1/psd/upload", bytes.NewBuffer(payload))
if err != nil {
panic(err)
}
req.Header.Set("x-api-key", os.Getenv("SUDOMOCK_API_KEY"))
req.Header.Set("Content-Type", "application/json")
resp, err := http.DefaultClient.Do(req)
if err != nil {
panic(err)
}
defer resp.Body.Close()
body, _ := io.ReadAll(resp.Body)
fmt.Println(string(body))
}
<?php
$payload = <<<'JSON'
{
"psd_file_url": "https://cdn.example.com/canvas-mockup.psd",
"psd_name": "Canvas 16x20"
}
JSON;
$ch = curl_init('https://api.sudomock.com/api/v1/psd/upload');
curl_setopt_array($ch, [
CURLOPT_CUSTOMREQUEST => 'POST',
CURLOPT_RETURNTRANSFER => true,
CURLOPT_HTTPHEADER => [
'x-api-key: ' . getenv('SUDOMOCK_API_KEY'),
'Content-Type: application/json',
],
CURLOPT_POSTFIELDS => $payload,
]);
$response = curl_exec($ch);
curl_close($ch);
echo $response;

Keep data.uuid as the template and the uuid of the smart object that holds the design, listed in data.smart_objects (upload a PSD). The API fetches the file from psd_file_url, so use a link that downloads without a sign-in; the dashboard takes the PSD from your disk. In the dashboard, PSD uploads are capped at 300 MB. API uploads support files up to Adobe's official PSD file size limit.

curl -X POST https://api.sudomock.com/api/v1/renders \
-H "x-api-key: $SUDOMOCK_API_KEY" \
-H "Content-Type: application/json" \
-d '{
"mockup_uuid": "MOCKUP_UUID",
"smart_objects": [
{
"uuid": "SMART_OBJECT_UUID",
"asset": { "url": "https://cdn.example.com/designs/sunset-waves.png", "fit": "fit" }
}
],
"export_options": { "image_format": "jpg", "image_size": 1024, "quality": 90 }
}'
const response = await fetch('https://api.sudomock.com/api/v1/renders', {
method: 'POST',
headers: {
'x-api-key': process.env.SUDOMOCK_API_KEY,
'Content-Type': 'application/json',
},
body: JSON.stringify({
"mockup_uuid": "MOCKUP_UUID",
"smart_objects": [
{
"uuid": "SMART_OBJECT_UUID",
"asset": {
"url": "https://cdn.example.com/designs/sunset-waves.png",
"fit": "fit"
}
}
],
"export_options": {
"image_format": "jpg",
"image_size": 1024,
"quality": 90
}
}),
});
const data = await response.json();
console.log(data);
import os
import requests
response = requests.post(
"https://api.sudomock.com/api/v1/renders",
headers={
"x-api-key": os.environ["SUDOMOCK_API_KEY"],
"Content-Type": "application/json",
},
json={
"mockup_uuid": "MOCKUP_UUID",
"smart_objects": [
{
"uuid": "SMART_OBJECT_UUID",
"asset": {
"url": "https://cdn.example.com/designs/sunset-waves.png",
"fit": "fit",
},
},
],
"export_options": {
"image_format": "jpg",
"image_size": 1024,
"quality": 90,
},
},
)
print(response.json())
package main
import (
"bytes"
"fmt"
"io"
"net/http"
"os"
)
func main() {
payload := []byte(`{
"mockup_uuid": "MOCKUP_UUID",
"smart_objects": [
{
"uuid": "SMART_OBJECT_UUID",
"asset": {
"url": "https://cdn.example.com/designs/sunset-waves.png",
"fit": "fit"
}
}
],
"export_options": {
"image_format": "jpg",
"image_size": 1024,
"quality": 90
}
}`)
req, err := http.NewRequest("POST", "https://api.sudomock.com/api/v1/renders", bytes.NewBuffer(payload))
if err != nil {
panic(err)
}
req.Header.Set("x-api-key", os.Getenv("SUDOMOCK_API_KEY"))
req.Header.Set("Content-Type", "application/json")
resp, err := http.DefaultClient.Do(req)
if err != nil {
panic(err)
}
defer resp.Body.Close()
body, _ := io.ReadAll(resp.Body)
fmt.Println(string(body))
}
<?php
$payload = <<<'JSON'
{
"mockup_uuid": "MOCKUP_UUID",
"smart_objects": [
{
"uuid": "SMART_OBJECT_UUID",
"asset": {
"url": "https://cdn.example.com/designs/sunset-waves.png",
"fit": "fit"
}
}
],
"export_options": {
"image_format": "jpg",
"image_size": 1024,
"quality": 90
}
}
JSON;
$ch = curl_init('https://api.sudomock.com/api/v1/renders');
curl_setopt_array($ch, [
CURLOPT_CUSTOMREQUEST => 'POST',
CURLOPT_RETURNTRANSFER => true,
CURLOPT_HTTPHEADER => [
'x-api-key: ' . getenv('SUDOMOCK_API_KEY'),
'Content-Type: application/json',
],
CURLOPT_POSTFIELDS => $payload,
]);
$response = curl_exec($ch);
curl_close($ch);
echo $response;

The finished file is at data.print_files[0].export_path. Save it under the design's own file name, the naming the forum scripts use. Each step of the script has a field:

Script stepRender request
Open the mockup PSDmockup_uuid, from the upload
Select the smart object layersmart_objects[].uuid
Replace Contents with a fileasset.url, or asset.base64 with content_type for a file on disk
Resize the design to fit the smart objectasset.fit: fit keeps the whole design, crop covers the area, fill stretches
Save a copy as JPG or PSDexport_options: png, jpg or webp, and image_size
Next file in the folderThe next request

The smart object keeps the transforms, warps, blend modes and effects the PSD gives it, as render a PSD without Photoshop lists, and SudoMock renders match Photoshop's own output. There is no file dialog in the loop, and a design in PNG, JPEG, WebP or GIF goes in as it is.

One design into every mockup PSD

To put one design into many templates, loop over the templates instead of the designs. The design URL stays the same, and each request carries another template's mockup_uuid and its smart object uuid.

On 4 November 2026 one design, a 2048 px square sunset with a transparent background, went to three templates with fit set to fit: a t-shirt, a mug and a framed poster. Three requests returned three finished mockups, each with the whole design inside its print area.

One sunset design rendered into a t-shirt, a mug and a framed poster mockup PSD with three render requestsOne design, three templates: the same asset URL with each template's own smart object ID, fit set to fit, rendered on 4 November 2026.

The three print areas have different shapes, and fit keeps a square design whole in each of them, where crop would cut it to the area (fit and blend modes). Without templates of your own, the API-ready crewneck t-shirt templates, mug templates and framed print templates take the same request.

A PSD with several smart objects is one request too: list one entry per smart object uuid, and any you leave out renders as the designer built it (smart objects). A smart object placed inside another is listed inside its parent's entry in the upload response.

Running a long list

A long list runs as many requests at once. The average SudoMock render finishes in under a second; we measure render time in milliseconds.

Requests run in parallel up to your plan's concurrency, and a request past it comes back as 429 with a Retry-After header to wait out (usage limits). For a run you start and leave, send is_async: true and take each result from a webhook.

Next step

Upload one mockup PSD, render three designs into it, then add a second template to the same loop. The render reference lists every field above, and the Python integration carries the same request in a script. Without code, the PSD Mockup: Render operation of the SudoMock n8n node takes the same template, smart object and design URL.

If your designs come with titles or captions in a spreadsheet, Photoshop Variables and Data Sets by API maps each CSV row to one request. For catalog-size runs, the bulk rendering use case shows the same loop across products.

Frequently asked questions

Do I need Photoshop open to batch replace smart objects?

A Photoshop script runs inside Photoshop, so Photoshop stays open on that machine for the whole run. A render request needs no Photoshop session: the PSD is uploaded once and each design is sent by HTTP from any machine, server or workflow tool.

What language are Photoshop scripts written in?

Most Photoshop scripts are JavaScript, and Adobe's scripting guide also lists AppleScript on Mac and VBScript on Windows. Older scripts, including most forum scripts for batch replacing smart objects, are ExtendScript files with the .jsx extension, written for ES3. Adobe's current UXP scripts use the .psjs extension and run modern JavaScript on the V8 engine.

How do I replace several smart objects in one PSD at once?

In a render request, list one entry per smart object, each with its own uuid from the upload response and its own design. Smart objects you leave out render as the designer built them. One request returns the finished mockup with every listed smart object filled.

Why does my batch replace script export the same design every time?

A reply on the Adobe community traces it to a smart object whose contents are a flat PNG, which can turn Save into Save As. The suggested fix is to open the smart object, add an empty layer, save it as a PSD and replace the contents with that PSD once before running the script again.

Is there a file size limit for the mockup PSD?

In the SudoMock dashboard, PSD uploads are capped at 300 MB. API uploads support files up to Adobe's official PSD file size limit.

Sources

  1. Batch replace smart objects (opens in new tab), Adobe Community
  2. Batch replace smart objects v2 (opens in new tab), Adobe Community
  3. Photoshop Script for Multiple Mockups (opens in new tab), Adobe Community
  4. UXP Scripting (opens in new tab), Adobe Developer
  5. Quickstart Guide (opens in new tab), Adobe Developer
  6. Render a PSD without Photoshop (opens in new tab)
  7. Upload a PSD (opens in new tab)
  8. Fit and blend modes (opens in new tab)
  9. Photoshop CC Scripting Guide (opens in new tab), Adobe
B

Beck

CTO

View all posts

On this page

  • How a batch replace script fills a smart object
  • ExtendScript or UXP: which script language
  • Five ways a batch replace script fails, and what the threads say
  • The same job without Photoshop: upload once, then one request per design
  • One design into every mockup PSD
  • Running a long list
  • Next step
  • Frequently asked questions
  • Sources

Related articles

A three-row CSV of export labels and design URLs above the three framed poster mockups SudoMock rendered from it, each labeled with its row's export_label
Tutorial

Photoshop Variables and Data Sets for Mockups, Run by API

Map Photoshop's Text Replacement, Pixel Replacement and Visibility variables to render fields and run every CSV row against your mockup PSD.

Oct 28, 2026 · 8 min read

Flat geometric artwork in a Design_Front smart object canvas, mapped by its transform box onto a navy t-shirt render
Guide

PSD Mockup Template Guide: Best Practices for Automation

Learn how to create API-ready PSD mockup templates. Complete guide covering dimensions, Smart Object setup, layer naming, blend modes, and optimization for automation.

Dec 24, 2025 · 7 min read

A POST /api/v1/renders request linked to its framed citrus poster render, with Photoshop Actions record and replay below
Comparison

PSD Mockup API vs Photoshop Actions: Complete Guide

When to use a mockup API vs Photoshop actions. Pros, cons, and use cases for each approach.

Dec 1, 2025 · 2 min read

Explore by use case

See SudoMock in action for your specific product category

Bulk Mockup Generation API for Enterprise ScaleT-Shirt Mockup Generator API for Print on DemandPrint on Demand Mockup Automation for POD SellersEtsy Mockup Generator API for Handmade Marketplace SellersAutomate Mug Mockups at Scale with SudoMock APIPoster Mockup Generator API for Wall Art Sellers

Your own PSD, rendered via API

Render your own PSD through the API. Start with 500 one-time credits, no card.

Start Free View Docs

Render your own PSD via API with 500 one-time credits.

Start Free · 500 credits, no card