SudoMock
POST

Upload PSD

Upload a Photoshop template and get back its detected Smart Objects, text layers, editable outline groups, and preview.

POST/api/v1/psd/upload

PSD File Requirements

  • File must be accessible via public URL (or signed URL)
  • Maximum file size: 300MB max
  • Maximum dimensions: 10,000 x 10,000 pixels
  • Must contain at least one visible Smart Object or one text layer
  • Supported formats: PSD and PSB (Large Document Format)
  • Download timeout: 300 seconds

Request

Headers

x-api-keystringRequired

Your SudoMock API key starting with sm_

Content-TypestringRequired

Must be application/json

Request Body

psd_file_urlstringRequired

URL to the PSD file. Must be publicly accessible or a signed URL. Cannot be empty (min_length: 1). The file is downloaded server-side with a 300-second timeout.

psd_namestring

Human-readable name for the mockup template (max 255 characters). Auto-generated from the URL filename if not provided.

is_asyncboolean= false

Set to true to process the upload in the background. The endpoint then responds with 202 Accepted and a small body: job_id, kind: upload, status: queued, and status_url (/api/v1/jobs/{job_id}) to poll. Defaults to false (synchronous), which returns the inline mockup.

Upload asynchronously for large PSDs

Add "is_async": true to get an immediate 202 with a job_id and a status_url instead of waiting for parsing to finish. Poll GET /api/v1/jobs/{job_id} and read mockup_uuid on success (or receive an upload.succeeded webhook if one is configured). Send an Idempotency-Key header to make retries safe. See Async Rendering.
Request Body Example
1{
2 "psd_file_url": "https://your-storage.com/mockup-template.psd",
3 "psd_name": "T-Shirt Mockup Front"
4}

Code Examples

Upload PSD
bash
1curl -X POST "https://api.sudomock.com/api/v1/psd/upload" \
2 -H "Content-Type: application/json" \
3 -H "x-api-key: sm_your_api_key" \
4 -d '{
5 "psd_file_url": "https://your-storage.com/mockup.psd",
6 "psd_name": "My Mockup Template"
7 }'

Response

Success Response

200OK
Response 200 OK
1{
2 "success": true,
3 "data": {
4 "uuid": "c315f78f-d2c7-4541-b240-a9372842de94",
5 "name": "T-Shirt Mockup Front",
6 "thumbnail": "https://cdn.sudomock.com/thumbnails/c315f78f_720.webp",
7 "width": 2000,
8 "height": 3000,
9 "smart_objects": [
10 {
11 "uuid": "128394ee-6758-4f2f-aa36-e2b19b152bd9",
12 "name": "Design Area",
13 "layer_name": "Smart Object 1",
14 "size": { "width": 3000, "height": 3413 },
15 "position": { "x": 450, "y": 380, "width": 1200, "height": 1400 },
16 "quad": null,
17 "blend_mode": "normal",
18 "print_area_presets": [
19 {
20 "uuid": "preset-001",
21 "name": "Default",
22 "thumbnails": [],
23 "size": { "width": 3000, "height": 3413 },
24 "position": { "x": 0, "y": 0, "width": 3000, "height": 3413 }
25 }
26 ]
27 }
28 ],
29 "text_layers": [
30 {
31 "uuid": "b7f2c1a0-9e34-4d21-8f0a-1c2b3d4e5f60",
32 "name": "Headline",
33 "text_content": "YOUR BRAND",
34 "font_postscript_name": "Poppins-Bold",
35 "font_size": 96,
36 "color": "#1A1A1A",
37 "font_available": true,
38 "is_editable": true,
39 "has_stroke_effect": true,
40 "stroke_count": 2,
41 "has_color_overlay": false,
42 "enclosing_group_layers": [
43 "9d7e4b18-3a65-4c21-8f90-2b6d7e1a5c43"
44 ]
45 }
46 ],
47 "group_layers": [
48 {
49 "uuid": "9d7e4b18-3a65-4c21-8f90-2b6d7e1a5c43",
50 "name": "Headline Outline",
51 "has_stroke_effect": true,
52 "stroke_count": 1
53 }
54 ],
55 "collections": [],
56 "thumbnails": [
57 { "width": 720, "url": "https://cdn.sudomock.com/thumbnails/c315f78f_720.webp" },
58 { "width": 480, "url": "https://cdn.sudomock.com/thumbnails/c315f78f_480.webp" },
59 { "width": 240, "url": "https://cdn.sudomock.com/thumbnails/c315f78f_240.webp" }
60 ]
61 },
62 "message": ""
63}

Response Fields

successbooleanRequired

Whether the upload was successful. Always true for 200 responses.

messagestring

Optional message about the operation. Empty string on success.

data.uuidstringRequired

Unique identifier for the mockup. Use this to render variations.

data.namestringRequired

Name of the mockup template.

data.thumbnailstring

URL to the main mockup preview image (720px width). Empty string if thumbnail generation failed.

data.widthinteger

Original PSD canvas width in pixels.

data.heightinteger

Original PSD canvas height in pixels.

data.smart_objectsarrayRequired

Visible editable Smart Object layers found in the PSD. This array is empty for a text-only PSD.

data.smart_objects[].uuidstringRequired

Unique identifier for the smart object. Use this when rendering.

data.smart_objects[].namestringRequired

Display name of the smart object.

data.smart_objects[].layer_namestring

Original PSD layer name. May differ from name.

data.smart_objects[].sizeobjectRequired

Embedded (source) dimensions of the smart object content. Contains width and height in pixels. Upload your artwork at this resolution for best quality.

data.smart_objects[].positionobjectRequired

Bounding box of the smart object on the mockup canvas. Contains x, y, width, and height in pixels. Use for client-side preview overlays.

data.smart_objects[].quadarray | null

Four [x, y] coordinate pairs (floats) for the perspective-transformed corners of the smart object. Included on Scale plans; null on lower plans.

data.smart_objects[].blend_modestring

Layer blend mode (e.g. normal, multiply).

data.smart_objects[].print_area_presetsarrayRequired

Print area preset configurations. Always includes a 'Default' preset matching the full smart object area. Each preset has uuid, name, thumbnails, size, and position fields.

data.text_layersarray

Text layers found in the PSD. Each entry includes uuid, name, text_content, font metadata, is_editable, segment metadata, its own has_stroke_effect and stroke_count values, and enclosing_group_layers UUIDs when editable group outlines also affect it. Text-layer stroke_color changes only the layer's own outlines; use render group_layers for an enclosing group.

data.group_layersarray

Editable outline groups found in the PSD. Each entry contains uuid, name, has_stroke_effect, and stroke_count. Presence in this list is the editability signal; use its uuid in render group_layers.

data.collectionsarray

Reserved for future use. Currently always an empty array.

data.thumbnailsarray

Mockup preview thumbnails at multiple sizes. Each entry has width (720, 480, or 240) and url fields.

Understanding Smart Object Data

Each smart object returns detailed metadata for seamless integration. The key distinction is between size and position:

FieldMeaningUsage
size.width/heightOriginal embedded content dimensionsDesign canvas size - upload assets at this resolution
position.x/yTop-left coordinates on mockup canvasClient-side canvas preview overlays
position.width/heightDisplay dimensions after transformsDrawing design on thumbnail images in browser
quadEditable area display coordinates (included on Scale plans; null on lower plans)Keeping your client-side preview aligned with the rendered result
blend_modeLayer blending modeColor overlays, special effects

size vs position

size = Upload your design at this resolution, use these coordinates in render API requests.
position = Use for drawing client-side previews on thumbnail images in browser. Not needed for API calls.

Error Responses

PSD processing errors (400, 500) return a structured body with error_code, message, detail, details, and success fields.

400Bad Request

Returned when the PSD cannot be downloaded, fails to parse, contains neither a visible Smart Object nor a text layer, or uses unsupported features.

json
1// PSD download failed
2{
3 "error_code": "PSD_DOWNLOAD_FAILED",
4 "message": "Failed to download PSD file",
5 "detail": "Failed to download PSD file",
6 "details": {
7 "url": "https://example.com/broken-link.psd",
8 "reason": "HTTP 404",
9 "suggestion": "Check if the URL is accessible and the file exists"
10 },
11 "success": false
12}
13
14// No visible personalizable layers
15{
16 "error_code": "NO_SMART_OBJECTS",
17 "message": "The PSD has no visible personalizable layers.",
18 "detail": "The PSD has no visible personalizable layers.",
19 "details": {
20 "total_layers": 12,
21 "hidden_smart_objects": 0,
22 "suggestion": "Make at least one personalizable layer visible, then upload the PSD again."
23 },
24 "success": false
25}
401Unauthorized

Returned when your API key is missing, malformed, or revoked.

json
1{
2 "detail": "Not authenticated",
3 "success": false
4}
402Payment Required

Returned when you have no remaining credits for PSD uploads.

json
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}
403Forbidden

Returned when you have reached the number of PSD templates your account can keep stored. The ceiling is 5 while the account is in trial and 500 once a card is verified and the balance is funded; subscription plans carry their own. Existing templates keep working, and deleting one frees a slot immediately.

The funded ceiling tracks the funding rather than the card. It holds while the balance is positive and for 90 days after the last top-up, then the account is back to 5. Funding also pauses the stored-template cleanup that applies to unfunded accounts, and lapsing past the window restarts it where it left off rather than from the beginning, so an account that was already near removal can lose stale templates soon after it lapses. Keep a balance funded, or keep your own copy of any PSD you need to re-upload.

The suggestion field names the remedy that actually applies to the account, so surface it rather than writing your own:

json
1{
2 "success": false,
3 "error": {
4 "code": "psd_limit_reached",
5 "message": "Your account is in trial, so you can store 5 PSD templates. Existing templates keep working.",
6 "suggestion": "Delete a template, or add a payment method to raise this limit."
7 }
8}

Once the account is funded, or on a subscription, the same status carries the other branch:

json
1{
2 "success": false,
3 "error": {
4 "code": "psd_limit_reached",
5 "message": "You have reached your PSD template limit of 500. Existing templates keep working.",
6 "suggestion": "Delete a template, or move to a plan with a higher limit."
7 }
8}
413Payload Too Large

Returned when the PSD file exceeds the 300MB maximum file size.

json
1{
2 "error_code": "PSD_TOO_LARGE",
3 "message": "PSD file exceeds the maximum allowed size",
4 "detail": "PSD file exceeds the maximum allowed size",
5 "details": {
6 "max_size_mb": 300,
7 "suggestion": "Reduce the file size (flatten non-editable layers) and try again."
8 },
9 "success": false
10}
422Validation Error

Returned when request body validation fails (e.g., missing required field, empty psd_file_url, or psd_name over 255 characters).

json
1{
2 "detail": "Validation error",
3 "errors": [
4 {"field": "body -> psd_file_url", "message": "Missing required field: body -> psd_file_url"}
5 ],
6 "success": false
7}
422Linked Smart Object Content Missing

Returned in the rare case that an externally-linked smart object (placeholder content linked to a file such as @artwork.psb or zREF.psb rather than embedded) has no usable placement geometry. This is a permanent error: retrying the same file will not help. Embed the linked smart object in Photoshop (Layer > Smart Objects > Embed Linked) or supply the design via the render request instead.

json
1{
2 "error_code": "LINKED_SMART_OBJECT_CONTENT_MISSING",
3 "message": "A linked smart object has no usable placement geometry",
4 "detail": "A linked smart object has no usable placement geometry",
5 "details": {
6 "suggestion": "Embed the linked smart object in Photoshop (Layer > Smart Objects > Embed Linked), or supply the design via the render request. Retrying the same file will not help."
7 },
8 "success": false
9}
429Too Many Requests

Returned when you exceed the API rate limit or concurrent upload limit.

json
1{
2 "detail": "Rate limit exceeded. Please slow down and try again.",
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}
500Internal Server Error

Returned when an unexpected error occurs while processing the PSD file. Retry, and contact support if it persists.

json
1{
2 "error_code": "INTERNAL_ERROR",
3 "message": "An unexpected error occurred while processing the PSD file",
4 "detail": "An unexpected error occurred while processing the PSD file",
5 "details": {
6 "suggestion": "Please try again. If the problem persists, contact support."
7 },
8 "success": false
9}

Try It Live

POST/api/v1/psd/upload

Upload a PSD and get back its Smart Objects, text layers, and editable outline groups.

Get your API key from the Dashboard

Best Practices

PSD Preparation Tips

  • Name your smart object layers descriptively (e.g., "Front Design", "Back Logo")
  • Use high-resolution smart objects (3000x3000px or higher)
  • Flatten non-editable layers to reduce file size
  • Keep smart objects in separate layer groups if possible

Common Issues

  • PSD_DOWNLOAD_FAILED: Ensure your URL is publicly accessible or use a signed URL. Downloads time out after 300 seconds.
  • NO_SMART_OBJECTS: The PSD has neither a visible Smart Object nor a text layer. Make a Smart Object visible, add one, or add a text layer before uploading again.
  • UNSUPPORTED_SMART_OBJECT_FORMAT: Smart objects containing AI, PDF, EPS, or SVG files are not supported. Use raster formats (PNG, JPG, TIFF, PSD/PSB).
  • LINKED_SMART_OBJECT_CONTENT_MISSING: Externally-linked smart objects normally render fine as placeholders using their placement geometry. In the rare case a linked smart object has no usable geometry, this permanent error fires. Embed the linked smart object (Layer > Smart Objects > Embed Linked) or supply the design via the render request. Retrying the same file will not help.
Next: Learn how to render mockups with your uploaded templateRender Mockup