SudoAI Render
AI-powered mockup rendering from any product photo. No PSD template needed. AI automatically detects the printable surface, applies perspective correction, and composites your artwork.
/api/v1/sudoai/renderNo PSD Required
How It Works
Request
Headers
x-api-keystringRequiredYour SudoMock API key starting with sm_
Content-TypestringRequiredMust be application/json
Request Body
source_urlstringRequiredURL of the source product photo. This is the image AI will analyze to detect the printable surface.
artwork_urlstringURL of the artwork/design to place on the product. Required if color is not provided.
product_typestringOptional product type hint for better detection accuracy. Examples: 't-shirt', 'hoodie', 'canvas', 'mug', 'tote-bag'. When omitted, AI auto-detects the product.
segment_indexintegerPre-selected segment index (0-based). Use when you already know which segment to target from a previous /segment response. Skips AI detection.
print_area_xintegerX coordinate (in pixels) for manual print area selection. Must be provided together with print_area_y.
print_area_yintegerY coordinate (in pixels) for manual print area selection. Must be provided together with print_area_x.
colorstringColor overlay in hex format (e.g., '#FF0000'). Applied to the artwork before compositing. Can be used alone (without artwork_url) for solid color fills.
adjustmentsobjectAdjustment parameters for the artwork (brightness, contrast, blend mode, warp, etc.)
placementobjectArtwork placement configuration within the detected print area (position, coverage, fit, rotation)
export_optionsobjectOutput format, size, and quality settings
Artwork or Color Required
artwork_url or color. You can also provide both to apply a color overlay on top of your artwork.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_modestring= multiplyBlend mode for artwork compositing. Use 'multiply' for realistic fabric texture blending, or 'normal' for no texture effect.
warp_strengthnumber= 0Mesh warp strength for fabric curvature (0 to 2). 0 disables warping. Higher values increase the warp effect following the surface shape.
edge_expandinteger= 0Edge expansion using region growing (0 to 50). Expands artwork to fill edges better. 0 disables.
texture_strengthinteger= 0Texture bake strength (0 to 100). Overlays the source surface texture onto the artwork for a more realistic look. 0 disables.
Placement
Controls how the artwork is positioned and sized within the detected print area.
positionenum= centerPredefined position within the print area
coverageinteger= 60Percentage of the print area to cover (10 to 100). Ignored if size is provided.
fitenum= containHow to fit the artwork: 'fill' (stretch), 'contain' (fit inside, preserve aspect ratio), 'cover' (fill and crop)
rotateinteger= 0Rotation in degrees (-360 to 360). Applied before sizing.
sizeobjectExplicit size override in pixels. Overrides coverage when provided. Both fields are optional; provide one to scale proportionally or both for exact dimensions.
size.widthintegerCustom width in pixels (minimum: 1). Optional.
size.heightintegerCustom height in pixels (minimum: 1). Optional.
offsetobjectPixel offset from the calculated position. Both fields are optional and can be negative.
offset.topintegerTop offset in pixels. Positive moves down, negative moves up. Optional.
offset.leftintegerLeft offset in pixels. Positive moves right, negative moves left. Optional.
Available Position Values
The position parameter accepts a 3x3 grid of predefined positions within the detected print area:
Export Options
image_formatenum= webpOutput format: png, jpg, or webp
image_sizeinteger= 1920Output width in pixels (100-10000). Height scales proportionally.
qualityinteger= 95Compression quality for JPG/WebP (1-100). Ignored for PNG.
1{2 "source_url": "https://example.com/tshirt-photo.jpg",3 "artwork_url": "https://example.com/user-design.png",4 "product_type": "t-shirt",5 "color": "#FF5500",6 "placement": {7 "position": "center",8 "coverage": 60,9 "fit": "contain",10 "rotate": 011 },12 "adjustments": {13 "brightness": 0,14 "contrast": 0,15 "opacity": 100,16 "saturation": 0,17 "vibrance": 0,18 "blur": 0,19 "blend_mode": "multiply",20 "warp_strength": 0,21 "edge_expand": 0,22 "texture_strength": 023 },24 "export_options": {25 "image_format": "webp",26 "image_size": 1920,27 "quality": 9528 }29}
Code Examples
1curl -X POST "https://api.sudomock.com/api/v1/sudoai/render" \2 -H "Content-Type: application/json" \3 -H "x-api-key: sm_your_api_key" \4 -d '{5 "source_url": "https://example.com/tshirt-photo.jpg",6 "artwork_url": "https://example.com/design.png",7 "product_type": "t-shirt",8 "placement": {9 "position": "center",10 "coverage": 60,11 "fit": "contain"12 },13 "export_options": {14 "image_format": "webp",15 "image_size": 1920,16 "quality": 9517 }18 }'
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": 2340,8 "segment_index": 0,9 "confidence": 0.95,10 "export_format": "webp"11 }12 ]13 }14}
Response Fields
successbooleanRequiredAlways true for successful responses
dataobjectRequiredResponse data wrapper
data.print_filesarrayRequiredArray of rendered output files
data.print_files[].export_pathstringRequiredCDN URL to the rendered mockup image
data.print_files[].duration_msintegerTotal render duration in milliseconds (includes AI detection, perspective analysis, and compositing)
data.print_files[].segment_indexintegerIndex of the segment used for rendering (0-based). Useful for subsequent requests with segment_index parameter.
data.print_files[].confidencenumberConfidence score of the selected segment (0.0 to 1.0). Higher values indicate better detection certainty.
data.print_files[].export_formatstringOutput format that was used (png, jpg, or webp)
Error Responses
1{2 "detail": "No printable area detected in source image",3 "success": false4}
This can occur when the AI cannot identify a printable surface in the photo. Try providing the product_type parameter for better detection accuracy.
1{2 "detail": "Validation error",3 "errors": [4 {"field": "body", "message": "Invalid value for field: body"}5 ],6 "success": false7}
Returned when required fields are missing or invalid. For example, you must provide at least one of artwork_url or color, and both print_area_x and print_area_y must be provided together.
1{2 "detail": "Invalid or missing API key",3 "success": false4}
1{2 "error": "credits_exhausted",3 "message": "You've run out of credits for this billing period.",4 "actions": [5 {"label": "Enable Pay-As-You-Go", "url": "https://sudomock.com/dashboard/billing?action=enable-payg"},6 {"label": "Upgrade Plan", "url": "https://sudomock.com/pricing"}7 ],8 "credits_reset_at": "2026-04-01T00:00:00Z"9}
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}
Try It Live
/api/v1/sudoai/renderRender a mockup using AI detection. Provide a product photo and your artwork.
Get your API key from the Dashboard
SudoAI vs Standard Render API
SudoAI and the standard Render API serve different use cases. Here is when to use each:
| SudoAI Render | Standard Render | |
|---|---|---|
| Input | Any product photo URL | Pre-uploaded PSD template |
| Setup | Zero setup | Upload PSD first |
| Credits | 5 per render | 1 per render |
| Speed | ~2-4s (includes AI detection) | <1s avg |
| Best for | User-uploaded photos, dynamic products, rapid prototyping | Professional mockups, consistent templates, high-volume automation |
| Perspective | Auto-computed via AI | Baked into PSD smart objects |
Image Fit Modes
The placement.fit parameter controls how your artwork is placed within the detected 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:
Multiply for Realism
multiply blend mode for garments and textured surfaces. It lets the fabric texture show through, making the design look printed rather than pasted on. Use normal for hard surfaces like mugs or phone cases where texture blending is not desired.Tips for Best Results
product_type (e.g., "t-shirt", "hoodie") improves detection accuracy and speed.segment_index value in subsequent requests for the same source image. This skips AI detection and renders faster.coverage: 60 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
segment_index from the first response. Each subsequent request skips AI detection for faster processing.1// JavaScript: Render multiple designs on the same product2const sourceUrl = "https://example.com/tshirt-photo.jpg";3const designs = [4 "https://cdn.example.com/design-1.png",5 "https://cdn.example.com/design-2.png",6 "https://cdn.example.com/design-3.png",7];89// First render: AI detects the print area10const first = await fetch("https://api.sudomock.com/api/v1/sudoai/render", {11 method: "POST",12 headers: {13 "Content-Type": "application/json",14 "x-api-key": "sm_your_api_key"15 },16 body: JSON.stringify({17 source_url: sourceUrl,18 artwork_url: designs[0],19 product_type: "t-shirt"20 })21}).then(r => r.json());2223const segmentIndex = first.data.print_files[0].segment_index;2425// Subsequent renders: skip detection with segment_index26const batchPromises = designs.slice(1).map(url =>27 fetch("https://api.sudomock.com/api/v1/sudoai/render", {28 method: "POST",29 headers: {30 "Content-Type": "application/json",31 "x-api-key": "sm_your_api_key"32 },33 body: JSON.stringify({34 source_url: sourceUrl,35 artwork_url: url,36 segment_index: segmentIndex37 })38 }).then(r => r.json())39);4041const results = await Promise.all(batchPromises);
Need a feature that's not here? Request it or see what's planned.