Render (2D)
Render your artwork onto a 2D mockup. You set the mockup up once in the dashboard (photo, printable surface, print area), then call this endpoint with the mockup UUID in the path and the print area UUIDs in the body to render any design programmatically.
/api/v1/sudoai/2d-mockups/{mockup_uuid}/renderSet up the mockup once, then render any design
mockup_uuid and a returned target ID.How It Works
mockup_uuidplus either a print-area uuid or full-surfacesurface_uuid for each render target.mockup_uuid and target uuid or surface_uuid already filled in. Pick your language and copy it.POST /api/v1/sudoai/2d-mockups/{mockup_uuid}/render with yourartwork_url (and optional placement / adjustments) to render. Swap the artwork on every call to render a new design onto the same saved mockup.Why is there a setup step?
Prefer no backend? Embed Studio
Security
Request
Headers
X-API-KeystringRequiredYour SudoMock API key starting with sm_
Content-TypestringRequiredMust be application/json
Idempotency-KeystringOptional. Use a stable value to retry an asynchronous render without creating and charging for a duplicate job. Max 255 characters.
Request Body
mockup_uuidstringRequiredPath parameter in the URL, not the body: UUID of the 2D mockup you set up in the dashboard. Find it in the editor's Code tab, or in the URL of the mockup in Dashboard > 2D Mockups.
print_areasarrayRequiredOne entry per render target. Each entry supplies exactly one saved print-area uuid or verified full-surface surface_uuid, plus its artwork or color and options.
export_optionsobjectOutput format, size, and quality settings for the rendered file.
is_asyncbooleanOptional, default false. When false, returns the rendered file in the same response. When true, returns a 202 2d_render job.
Render Target Object
Each item in print_areas targets either one bounded print area or one verified full product surface. Send exactly one identifier per item.
uuidstringUUID of a saved bounded print area from data.quads. Required when surface_uuid is omitted.
surface_uuidstringUUID of a verified full product surface from data.surfaces. Required when uuid is omitted.
artwork_urlstringPublicly reachable URL of the artwork/design to place in this print area. Required unless color is provided.
colorstringColor fill in hex format (e.g., '#FF0000'). Use alone for a solid color fill, or together with artwork_url to apply a color overlay.
remove_backgroundboolean= falseRemove the artwork background before placement. Pricing starts at about $0.06 per unique artwork source.
adjustmentsobjectArtwork appearance controls: brightness, contrast, opacity, saturation, vibrance, blur, and blend mode.
placementobjectHow the artwork is positioned and sized within this print area (position, coverage, fit, offset_x, offset_y, width, height, rotation).
Artwork or Color Required
artwork_url orcolor. You can provide both to apply a color overlay on top of your artwork.Bounded and full-surface targets use different IDs
uuid for an entry returned in data.quads. Use surface_uuid for an entry returned in data.surfaces. Never send both on one target.Adjustments
brightnessinteger= 0Brightness adjustment (-150 to 150)
contrastinteger= 0Contrast adjustment (-100 to 100)
opacityinteger= 100Artwork opacity (0=fully transparent, 100=fully opaque)
saturationinteger= 0Saturation adjustment (-100 to 100)
vibranceinteger= 0Vibrance adjustment (-100 to 100)
blurinteger= 0Gaussian blur amount (0 to 100)
blend_modeenum= multiplyHow the artwork sits on the product surface. One of 'multiply', 'normal', 'screen', 'lighten', 'soft_light', 'overlay', or 'darken'. Send 'normal' when a brand color has to match the supplied file. See Blend Modes below.
Placement
Controls how the artwork is positioned and sized within the print area.
positionenum= centerPredefined position within the print area
coverageinteger= 70Percentage of the print area to cover (10 to 100). Ignored when an explicit width and height are provided.
fitenum= containHow to fit the artwork: 'fill' (stretch), 'contain' (fit inside, preserve aspect ratio), 'cover' (fill and crop)
widthintegerArtwork width in print-area pixels (1 to 30000). Send it together with height; the pair overrides coverage and fit. The two axes are independent, so you can stretch artwork on one axis alone.
heightintegerArtwork height in print-area pixels (1 to 30000). Send it together with width. Sending only one of the two is rejected rather than guessed.
rotationnumber= 0Rotation in degrees. Applied to the artwork before placement.
offset_xinteger= 0Horizontal pixel offset from the print area center. Positive moves right, negative moves left.
offset_yinteger= 0Vertical pixel offset from the print area center. Positive moves down, negative moves up.
Available Position Values
The position parameter accepts a 3x3 grid of predefined positions within the print area:
Export Options
image_formatenum= webpOutput format: png, jpg, or webp
image_sizeinteger= 2048Output width in pixels (100-10000). Height scales proportionally. This sets the actual pixel dimensions of the file.
qualityinteger= 90Compression quality for JPG/WebP (1-100). Ignored for PNG.
dpiinteger= nullPrint resolution tag written into the output file metadata (72-2400). Metadata only; it does not change the pixels. image_size controls the actual pixels. For a print file, size your pixels: image_size = print_inches x dpi (e.g. 12 in x 300 = 3600 px). All formats (JPG, PNG, WebP) carry the tag; JPG and PNG are recommended for the widest print-tool compatibility. Opt-in: when omitted, files carry a default 25.4 DPI tag.
1{2 "print_areas": [3 {4 "uuid": "128394ee-6758-4f2f-aa36-e2b19b152bd9",5 "artwork_url": "https://your-domain.com/design.png",6 "adjustments": {7 "brightness": 0,8 "contrast": 0,9 "opacity": 100,10 "saturation": 0,11 "vibrance": 0,12 "blur": 0,13 "blend_mode": "multiply"14 },15 "placement": {16 "position": "center",17 "coverage": 70,18 "fit": "contain"19 }20 }21 ],22 "export_options": {23 "image_format": "webp",24 "image_size": 1920,25 "quality": 9526 }27}
1{2 "print_areas": [3 {4 "surface_uuid": "323e4567-e89b-12d3-a456-426614174002",5 "artwork_url": "https://your-domain.com/design.png",6 "placement": {7 "position": "center",8 "coverage": 70,9 "fit": "contain"10 }11 }12 ],13 "export_options": {14 "image_format": "webp",15 "image_size": 1920,16 "quality": 9517 }18}
Code Examples
The Code tab in the editor generates these snippets for your own mockup, with the real mockup_uuid and render target ID already filled in. The examples below use a bounded print-area uuid; full surfaces use surface_uuid instead.
1curl -X POST "https://api.sudomock.com/api/v1/sudoai/2d-mockups/c315f78f-d2c7-4541-b240-a9372842de94/render" \2 -H "Content-Type: application/json" \3 -H "X-API-Key: sm_your_api_key" \4 -d '{5 "print_areas": [6 {7 "uuid": "128394ee-6758-4f2f-aa36-e2b19b152bd9",8 "artwork_url": "https://your-domain.com/design.png",9 "placement": {10 "position": "center",11 "coverage": 70,12 "fit": "contain"13 }14 }15 ],16 "export_options": {17 "image_format": "webp",18 "image_size": 1920,19 "quality": 9520 }21 }'
Response
Success Response
1{2 "success": true,3 "data": {4 "print_files": [5 {6 "export_path": "https://cdn.sudomock.com/renders/sudoai/abc123.webp",7 "duration_ms": 1840,8 "export_format": "webp"9 }10 ]11 }12}
Response Fields
successbooleanRequiredAlways true for successful responses
dataobjectRequiredResponse data wrapper
data.print_filesarrayRequiredArray of rendered output files, one per rendered print area
data.print_files[].export_pathstringRequiredCDN URL to the rendered mockup image
data.print_files[].duration_msintegerTime in milliseconds the render took to produce this file
data.print_files[].export_formatstringOutput format that was used (png, jpg, or webp)
Asynchronous Response
Set is_async: true for batch or long-running workflows. The API returns a job immediately instead of holding the request open.
1{2 "job_id": "9d4e2b51-2ef0-49ca-92bc-9a4c157a2fe8",3 "kind": "2d_render",4 "status": "queued",5 "status_url": "/api/v1/jobs/9d4e2b51-2ef0-49ca-92bc-9a4c157a2fe8"6}
Poll status_url or subscribe to 2d_render.succeeded and 2d_render.failed. A succeeded job exposes the rendered image in result_url. See Jobs & Polling and the Webhooks reference.
Error Responses
1{2 "detail": "Mockup not found",3 "success": false4}
Returned when mockup_uuid does not match a mockup on your account. Copy the exact value from the editor's Code tab, or from the mockup's URL in Dashboard → 2D Mockups.
1{2 "detail": "Validation error",3 "errors": [4 {"field": "print_areas", "message": "Field required"}5 ],6 "success": false7}
Returned when required fields are missing or invalid. The most common cause is sending the body without print_areas, or a render target without exactly one valid uuid or surface_uuid. Each target also needs at least one of artwork_url or color. The Code tab produces a body that already satisfies these requirements.
1{2 "detail": "Invalid or missing API key",3 "success": false4}
1{2 "error": "credits_exhausted",3 "message": "You have used all 500 trial credits. Add a payment method to keep rendering, or start a plan.",4 "actions": [5 { "label": "Add a payment method", "url": "https://sudomock.com/dashboard/billing?action=topup#payg-section" },6 { "label": "Start a plan", "url": "https://sudomock.com/pricing" }7 ]8}
1{2 "detail": "Rate limit exceeded. Try again in 30 seconds.",3 "error": {4 "type": "rate_limit_exceeded",5 "code": "RATE_LIMIT_EXCEEDED",6 "limit": 1000,7 "remaining": 0,8 "reset_seconds": 30,9 "retry_after": 30,10 "resource": "api"11 }12}
1{2 "detail": "Something went wrong while processing your image. Please try again.",3 "success": false4}
Retired Paths
Earlier 2D render paths were retired
/api/v1/sudoai/2d-mockup/render and its older alias/api/v1/sudoai/render. The mockup UUID moved from the request body into the URL path. Use the canonical endpoint POST /api/v1/sudoai/2d-mockups/{mockup_uuid}/render and send only print_areas and export_options in the body.Try It Live
Replace the placeholder UUIDs below with values from your own mockup. The fastest way to get a working request is the Code tab in the editor. It fills in the correct mockup_uuid and render target uuid or surface_uuid for you.
2D Mockups vs Standard Render API
2D Mockups and the standard Render API serve different use cases. Here is when to use each:
| 2D Mockups Render | Standard Render | |
|---|---|---|
| Template | A product photo prepared as a reusable mockup | A PSD with smart object layers |
| Setup | Automatic preparation, with optional review in the dashboard | Upload a prepared PSD (once) |
| Render input | mockup_uuid + target uuid or surface_uuid | mockup_uuid + smart_objects[].uuid |
| Credits | 5 per render | 1 per render |
| Best for | Quick mockups from a single product photo | Professional templates, high-volume automation |
| Perspective | Automatic surface warp from the product photo | Baked into PSD smart objects |
A single product photo becomes a reusable mockup, then any artwork warps onto the printable surface with realistic perspective. No PSD template required.
Image Fit Modes
The placement.fit parameter controls how your artwork is placed within the print area:
| Mode | Behavior | Use Case |
|---|---|---|
fill | Stretches to fill entire area (may distort) | When aspect ratio matches the print area |
contain | Fits inside, preserves aspect ratio, may leave space | When design must be fully visible (default) |
cover | Fills area, preserves aspect ratio, may crop edges | All-over prints and full-surface designs |
Blend Modes
The adjustments.blend_mode parameter controls how artwork blends with the product surface:
Pick the mode from the garment, not the artwork
multiply for garments and textured surfaces: it lets the material texture show through, so the design looks printed rather than pasted on. On a dark garment a light artwork gets swallowed by multiply, so reach for screen there. Use normal for hard surfaces like mugs or phone cases, where you want the artwork exactly as supplied. The remaining four are for a specific look: overlay for stronger contrast, soft_light for a gentle finish, darken and lighten to keep only the darker or lighter parts of the artwork.When a brand color must not shift
multiply behaves like real ink: on a black tee a white logo comes out grey. That is what makes it look printed, and it is not what you want when a brand color has to match. Send "blend_mode": "normal" and the artwork keeps its exact colors on any product color: white stays white, and a brand blue stays that blue. Blend mode is set per print area, so one area can hold an exact logo while another stays on multiply.Tips for Best Results
mockup_uuid and target uuid work for every bounded-area render. Full-surface targets reuse their surface_uuid. Swap only artwork_url to render a new design onto the same product.coverage: 70 works well for most logos and centered designs. Increase to 80-100 for all-over prints, or decrease to 30-40 for small chest logos.Batch Rendering
Parallel Renders
mockup_uuid and target uuid or surface_uuid, and vary only the artwork_url.1// JavaScript: Render multiple designs on the same mockup2const mockupUuid = "c315f78f-d2c7-4541-b240-a9372842de94";3const printAreaUuid = "128394ee-6758-4f2f-aa36-e2b19b152bd9";4const designs = [5 "https://cdn.example.com/design-1.png",6 "https://cdn.example.com/design-2.png",7 "https://cdn.example.com/design-3.png",8];910const renders = designs.map(url =>11 fetch(`https://api.sudomock.com/api/v1/sudoai/2d-mockups/${mockupUuid}/render`, {12 method: "POST",13 headers: {14 "Content-Type": "application/json",15 "X-API-Key": "sm_your_api_key"16 },17 body: JSON.stringify({18 print_areas: [19 { uuid: printAreaUuid, artwork_url: url }20 ]21 })22 }).then(r => r.json())23);2425const results = await Promise.all(renders);
Need a feature that's not here? Request it or see what's planned.