{
  "openapi": "3.1.0",
  "info": {
    "title": "SudoMock API",
    "description": "Product mockup API. Render PSD templates, turn product photos into reusable mockups, create still images and videos, personalize text with fonts, and manage asynchronous jobs and signed webhooks.\n\nEvery endpoint answers failures with the same envelope, so the status codes, the error_code values and the retry rule are documented once at https://sudomock.com/docs/errors rather than repeated per operation.",
    "version": "1.0.0"
  },
  "paths": {
    "/api/v1/psd/upload": {
      "post": {
        "tags": [
          "PSD mockups"
        ],
        "summary": "Create a mockup from a PSD",
        "description": "Ingests a PSD file from URL, extracts layers and smart objects, generates thumbnails.",
        "operationId": "upload_psd_api_v1_psd_upload_post",
        "requestBody": {
          "required": true,
          "content": {
            "application/json": {
              "schema": {
                "$ref": "#/components/schemas/UploadRequest"
              }
            }
          }
        },
        "responses": {
          "200": {
            "description": "Successful Response",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/UploadResponse"
                }
              }
            }
          },
          "202": {
            "description": "Upload queued (is_async=true). Poll status_url for the result.",
            "content": {
              "application/json": {
                "example": {
                  "job_id": "5f1c0b2a-7d43-4e9a-8c16-0b5d3f7a2e94",
                  "kind": "upload",
                  "status": "queued",
                  "status_url": "/api/v1/jobs/5f1c0b2a-7d43-4e9a-8c16-0b5d3f7a2e94"
                },
                "schema": {
                  "$ref": "#/components/schemas/JobAcceptedResponse"
                }
              }
            }
          }
        },
        "x-mint": {
          "metadata": {
            "sidebarTitle": "Upload PSD file"
          }
        },
        "security": [
          {
            "ApiKeyAuth": []
          }
        ],
        "x-codeSamples": [
          {
            "lang": "Node.js",
            "source": "const response = await fetch(\"https://api.sudomock.com/api/v1/psd/upload\", {\n  method: \"POST\",\n  headers: {\n    \"x-api-key\": \"sm_your_api_key\",\n    \"Content-Type\": \"application/json\",\n  },\n  body: JSON.stringify({\n    \"psd_file_url\": \"https://example.com/heavyweight-tee.psd\",\n    \"psd_name\": \"Heavyweight tee front\"\n  }),\n});\n\nconst data = await response.json();\nconsole.log(data);"
          },
          {
            "lang": "PHP",
            "source": "<?php\n\n$payload = <<<'JSON'\n{\n  \"psd_file_url\": \"https://example.com/heavyweight-tee.psd\",\n  \"psd_name\": \"Heavyweight tee front\"\n}\nJSON;\n\n$ch = curl_init(\"https://api.sudomock.com/api/v1/psd/upload\");\ncurl_setopt($ch, CURLOPT_CUSTOMREQUEST, \"POST\");\ncurl_setopt($ch, CURLOPT_RETURNTRANSFER, true);\ncurl_setopt($ch, CURLOPT_HTTPHEADER, [\n    \"x-api-key: sm_your_api_key\",\n    \"Content-Type: application/json\",\n]);\ncurl_setopt($ch, CURLOPT_POSTFIELDS, $payload);\n\n$response = curl_exec($ch);\ncurl_close($ch);\n\necho $response;"
          },
          {
            "lang": "Python",
            "source": "import requests\n\npayload = {\n    \"psd_file_url\": \"https://example.com/heavyweight-tee.psd\",\n    \"psd_name\": \"Heavyweight tee front\"\n}\n\nresponse = requests.post(\n    \"https://api.sudomock.com/api/v1/psd/upload\",\n    headers={\"x-api-key\": \"sm_your_api_key\"},\n    json=payload,\n)\n\nresponse.raise_for_status()\nprint(response.json())"
          },
          {
            "lang": "Ruby",
            "source": "require \"net/http\"\nrequire \"uri\"\n\nuri = URI(\"https://api.sudomock.com/api/v1/psd/upload\")\nrequest = Net::HTTP::Post.new(uri)\nrequest[\"x-api-key\"] = \"sm_your_api_key\"\nrequest[\"Content-Type\"] = \"application/json\"\n\nrequest.body = <<~JSON\n  {\n    \"psd_file_url\": \"https://example.com/heavyweight-tee.psd\",\n    \"psd_name\": \"Heavyweight tee front\"\n  }\nJSON\n\nresponse = Net::HTTP.start(uri.host, uri.port, use_ssl: true) do |http|\n  http.request(request)\nend\n\nputs response.body"
          },
          {
            "lang": "Go",
            "source": "package main\n\nimport (\n\t\"bytes\"\n\t\"fmt\"\n\t\"io\"\n\t\"net/http\"\n)\n\nfunc main() {\n\tpayload := []byte(`{\n  \"psd_file_url\": \"https://example.com/heavyweight-tee.psd\",\n  \"psd_name\": \"Heavyweight tee front\"\n}`)\n\n\treq, err := http.NewRequest(\"POST\", \"https://api.sudomock.com/api/v1/psd/upload\", bytes.NewBuffer(payload))\n\tif err != nil {\n\t\tpanic(err)\n\t}\n\treq.Header.Set(\"x-api-key\", \"sm_your_api_key\")\n\treq.Header.Set(\"Content-Type\", \"application/json\")\n\n\tres, err := http.DefaultClient.Do(req)\n\tif err != nil {\n\t\tpanic(err)\n\t}\n\tdefer res.Body.Close()\n\n\tbody, _ := io.ReadAll(res.Body)\n\tfmt.Println(string(body))\n}"
          },
          {
            "lang": "Java",
            "source": "import java.net.URI;\nimport java.net.http.HttpClient;\nimport java.net.http.HttpRequest;\nimport java.net.http.HttpResponse;\n\nString payload = \"\"\"\n{\n  \"psd_file_url\": \"https://example.com/heavyweight-tee.psd\",\n  \"psd_name\": \"Heavyweight tee front\"\n}\n\"\"\";\n\nHttpRequest request = HttpRequest.newBuilder()\n    .uri(URI.create(\"https://api.sudomock.com/api/v1/psd/upload\"))\n    .header(\"x-api-key\", \"sm_your_api_key\")\n    .header(\"Content-Type\", \"application/json\")\n    .POST(HttpRequest.BodyPublishers.ofString(payload))\n    .build();\n\nHttpResponse<String> response = HttpClient.newHttpClient()\n    .send(request, HttpResponse.BodyHandlers.ofString());\n\nSystem.out.println(response.body());"
          },
          {
            "lang": ".NET",
            "source": "using System.Net.Http;\nusing System.Text;\n\nvar payload = \"\"\"\n{\n  \"psd_file_url\": \"https://example.com/heavyweight-tee.psd\",\n  \"psd_name\": \"Heavyweight tee front\"\n}\n\"\"\";\n\nvar request = new HttpRequestMessage(HttpMethod.Post, \"https://api.sudomock.com/api/v1/psd/upload\");\nrequest.Headers.Add(\"x-api-key\", \"sm_your_api_key\");\nrequest.Content = new StringContent(payload, Encoding.UTF8, \"application/json\");\n\nvar client = new HttpClient();\nvar response = await client.SendAsync(request);\n\nConsole.WriteLine(await response.Content.ReadAsStringAsync());"
          },
          {
            "lang": "cURL",
            "source": "curl -X POST \"https://api.sudomock.com/api/v1/psd/upload\" \\\n  -H \"x-api-key: sm_your_api_key\" \\\n  -H \"Content-Type: application/json\" \\\n  -d '{\n    \"psd_file_url\": \"https://example.com/heavyweight-tee.psd\",\n    \"psd_name\": \"Heavyweight tee front\"\n  }'"
          }
        ]
      }
    },
    "/api/v1/renders": {
      "post": {
        "tags": [
          "PSD mockups"
        ],
        "summary": "Render a PSD mockup",
        "description": "Renders a mockup by compositing layers with user-provided images.",
        "operationId": "render_mockup_api_v1_renders_post",
        "requestBody": {
          "required": true,
          "content": {
            "application/json": {
              "schema": {
                "$ref": "#/components/schemas/RenderRequest"
              }
            }
          }
        },
        "responses": {
          "200": {
            "description": "Successful Response",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/RenderResponse"
                }
              }
            }
          },
          "202": {
            "description": "Render queued (is_async=true). Poll status_url for the result.",
            "content": {
              "application/json": {
                "example": {
                  "job_id": "5f1c0b2a-7d43-4e9a-8c16-0b5d3f7a2e94",
                  "kind": "render",
                  "status": "queued",
                  "status_url": "/api/v1/jobs/5f1c0b2a-7d43-4e9a-8c16-0b5d3f7a2e94"
                },
                "schema": {
                  "$ref": "#/components/schemas/JobAcceptedResponse"
                }
              }
            }
          }
        },
        "x-mint": {
          "metadata": {
            "sidebarTitle": "Render PSD mockup"
          }
        },
        "security": [
          {
            "ApiKeyAuth": []
          }
        ],
        "x-codeSamples": [
          {
            "lang": "Node.js",
            "source": "const response = await fetch(\"https://api.sudomock.com/api/v1/renders\", {\n  method: \"POST\",\n  headers: {\n    \"x-api-key\": \"sm_your_api_key\",\n    \"Content-Type\": \"application/json\",\n  },\n  body: JSON.stringify({\n    \"export_options\": {\n      \"image_format\": \"webp\",\n      \"image_size\": 1920,\n      \"quality\": 95\n    },\n    \"mockup_uuid\": \"123e4567-e89b-12d3-a456-426614174000\",\n    \"smart_objects\": [\n      {\n        \"asset\": {\n          \"fit\": \"fill\",\n          \"position\": {\n            \"left\": 100,\n            \"top\": 100\n          },\n          \"rotate\": 0,\n          \"size\": {\n            \"height\": 600,\n            \"width\": 800\n          },\n          \"url\": \"https://example.com/user-design.png\"\n        },\n        \"color\": {\n          \"blending_mode\": \"multiply\",\n          \"hex\": \"#FFFFFF\"\n        },\n        \"uuid\": \"223e4567-e89b-12d3-a456-426614174001\"\n      }\n    ]\n  }),\n});\n\nconst data = await response.json();\nconsole.log(data);"
          },
          {
            "lang": "PHP",
            "source": "<?php\n\n$payload = <<<'JSON'\n{\n  \"export_options\": {\n    \"image_format\": \"webp\",\n    \"image_size\": 1920,\n    \"quality\": 95\n  },\n  \"mockup_uuid\": \"123e4567-e89b-12d3-a456-426614174000\",\n  \"smart_objects\": [\n    {\n      \"asset\": {\n        \"fit\": \"fill\",\n        \"position\": {\n          \"left\": 100,\n          \"top\": 100\n        },\n        \"rotate\": 0,\n        \"size\": {\n          \"height\": 600,\n          \"width\": 800\n        },\n        \"url\": \"https://example.com/user-design.png\"\n      },\n      \"color\": {\n        \"blending_mode\": \"multiply\",\n        \"hex\": \"#FFFFFF\"\n      },\n      \"uuid\": \"223e4567-e89b-12d3-a456-426614174001\"\n    }\n  ]\n}\nJSON;\n\n$ch = curl_init(\"https://api.sudomock.com/api/v1/renders\");\ncurl_setopt($ch, CURLOPT_CUSTOMREQUEST, \"POST\");\ncurl_setopt($ch, CURLOPT_RETURNTRANSFER, true);\ncurl_setopt($ch, CURLOPT_HTTPHEADER, [\n    \"x-api-key: sm_your_api_key\",\n    \"Content-Type: application/json\",\n]);\ncurl_setopt($ch, CURLOPT_POSTFIELDS, $payload);\n\n$response = curl_exec($ch);\ncurl_close($ch);\n\necho $response;"
          },
          {
            "lang": "Python",
            "source": "import requests\n\npayload = {\n    \"export_options\": {\n        \"image_format\": \"webp\",\n        \"image_size\": 1920,\n        \"quality\": 95\n    },\n    \"mockup_uuid\": \"123e4567-e89b-12d3-a456-426614174000\",\n    \"smart_objects\": [\n        {\n            \"asset\": {\n                \"fit\": \"fill\",\n                \"position\": {\n                    \"left\": 100,\n                    \"top\": 100\n                },\n                \"rotate\": 0,\n                \"size\": {\n                    \"height\": 600,\n                    \"width\": 800\n                },\n                \"url\": \"https://example.com/user-design.png\"\n            },\n            \"color\": {\n                \"blending_mode\": \"multiply\",\n                \"hex\": \"#FFFFFF\"\n            },\n            \"uuid\": \"223e4567-e89b-12d3-a456-426614174001\"\n        }\n    ]\n}\n\nresponse = requests.post(\n    \"https://api.sudomock.com/api/v1/renders\",\n    headers={\"x-api-key\": \"sm_your_api_key\"},\n    json=payload,\n)\n\nresponse.raise_for_status()\nprint(response.json())"
          },
          {
            "lang": "Ruby",
            "source": "require \"net/http\"\nrequire \"uri\"\n\nuri = URI(\"https://api.sudomock.com/api/v1/renders\")\nrequest = Net::HTTP::Post.new(uri)\nrequest[\"x-api-key\"] = \"sm_your_api_key\"\nrequest[\"Content-Type\"] = \"application/json\"\n\nrequest.body = <<~JSON\n  {\n    \"export_options\": {\n      \"image_format\": \"webp\",\n      \"image_size\": 1920,\n      \"quality\": 95\n    },\n    \"mockup_uuid\": \"123e4567-e89b-12d3-a456-426614174000\",\n    \"smart_objects\": [\n      {\n        \"asset\": {\n          \"fit\": \"fill\",\n          \"position\": {\n            \"left\": 100,\n            \"top\": 100\n          },\n          \"rotate\": 0,\n          \"size\": {\n            \"height\": 600,\n            \"width\": 800\n          },\n          \"url\": \"https://example.com/user-design.png\"\n        },\n        \"color\": {\n          \"blending_mode\": \"multiply\",\n          \"hex\": \"#FFFFFF\"\n        },\n        \"uuid\": \"223e4567-e89b-12d3-a456-426614174001\"\n      }\n    ]\n  }\nJSON\n\nresponse = Net::HTTP.start(uri.host, uri.port, use_ssl: true) do |http|\n  http.request(request)\nend\n\nputs response.body"
          },
          {
            "lang": "Go",
            "source": "package main\n\nimport (\n\t\"bytes\"\n\t\"fmt\"\n\t\"io\"\n\t\"net/http\"\n)\n\nfunc main() {\n\tpayload := []byte(`{\n  \"export_options\": {\n    \"image_format\": \"webp\",\n    \"image_size\": 1920,\n    \"quality\": 95\n  },\n  \"mockup_uuid\": \"123e4567-e89b-12d3-a456-426614174000\",\n  \"smart_objects\": [\n    {\n      \"asset\": {\n        \"fit\": \"fill\",\n        \"position\": {\n          \"left\": 100,\n          \"top\": 100\n        },\n        \"rotate\": 0,\n        \"size\": {\n          \"height\": 600,\n          \"width\": 800\n        },\n        \"url\": \"https://example.com/user-design.png\"\n      },\n      \"color\": {\n        \"blending_mode\": \"multiply\",\n        \"hex\": \"#FFFFFF\"\n      },\n      \"uuid\": \"223e4567-e89b-12d3-a456-426614174001\"\n    }\n  ]\n}`)\n\n\treq, err := http.NewRequest(\"POST\", \"https://api.sudomock.com/api/v1/renders\", bytes.NewBuffer(payload))\n\tif err != nil {\n\t\tpanic(err)\n\t}\n\treq.Header.Set(\"x-api-key\", \"sm_your_api_key\")\n\treq.Header.Set(\"Content-Type\", \"application/json\")\n\n\tres, err := http.DefaultClient.Do(req)\n\tif err != nil {\n\t\tpanic(err)\n\t}\n\tdefer res.Body.Close()\n\n\tbody, _ := io.ReadAll(res.Body)\n\tfmt.Println(string(body))\n}"
          },
          {
            "lang": "Java",
            "source": "import java.net.URI;\nimport java.net.http.HttpClient;\nimport java.net.http.HttpRequest;\nimport java.net.http.HttpResponse;\n\nString payload = \"\"\"\n{\n  \"export_options\": {\n    \"image_format\": \"webp\",\n    \"image_size\": 1920,\n    \"quality\": 95\n  },\n  \"mockup_uuid\": \"123e4567-e89b-12d3-a456-426614174000\",\n  \"smart_objects\": [\n    {\n      \"asset\": {\n        \"fit\": \"fill\",\n        \"position\": {\n          \"left\": 100,\n          \"top\": 100\n        },\n        \"rotate\": 0,\n        \"size\": {\n          \"height\": 600,\n          \"width\": 800\n        },\n        \"url\": \"https://example.com/user-design.png\"\n      },\n      \"color\": {\n        \"blending_mode\": \"multiply\",\n        \"hex\": \"#FFFFFF\"\n      },\n      \"uuid\": \"223e4567-e89b-12d3-a456-426614174001\"\n    }\n  ]\n}\n\"\"\";\n\nHttpRequest request = HttpRequest.newBuilder()\n    .uri(URI.create(\"https://api.sudomock.com/api/v1/renders\"))\n    .header(\"x-api-key\", \"sm_your_api_key\")\n    .header(\"Content-Type\", \"application/json\")\n    .POST(HttpRequest.BodyPublishers.ofString(payload))\n    .build();\n\nHttpResponse<String> response = HttpClient.newHttpClient()\n    .send(request, HttpResponse.BodyHandlers.ofString());\n\nSystem.out.println(response.body());"
          },
          {
            "lang": ".NET",
            "source": "using System.Net.Http;\nusing System.Text;\n\nvar payload = \"\"\"\n{\n  \"export_options\": {\n    \"image_format\": \"webp\",\n    \"image_size\": 1920,\n    \"quality\": 95\n  },\n  \"mockup_uuid\": \"123e4567-e89b-12d3-a456-426614174000\",\n  \"smart_objects\": [\n    {\n      \"asset\": {\n        \"fit\": \"fill\",\n        \"position\": {\n          \"left\": 100,\n          \"top\": 100\n        },\n        \"rotate\": 0,\n        \"size\": {\n          \"height\": 600,\n          \"width\": 800\n        },\n        \"url\": \"https://example.com/user-design.png\"\n      },\n      \"color\": {\n        \"blending_mode\": \"multiply\",\n        \"hex\": \"#FFFFFF\"\n      },\n      \"uuid\": \"223e4567-e89b-12d3-a456-426614174001\"\n    }\n  ]\n}\n\"\"\";\n\nvar request = new HttpRequestMessage(HttpMethod.Post, \"https://api.sudomock.com/api/v1/renders\");\nrequest.Headers.Add(\"x-api-key\", \"sm_your_api_key\");\nrequest.Content = new StringContent(payload, Encoding.UTF8, \"application/json\");\n\nvar client = new HttpClient();\nvar response = await client.SendAsync(request);\n\nConsole.WriteLine(await response.Content.ReadAsStringAsync());"
          },
          {
            "lang": "cURL",
            "source": "curl -X POST \"https://api.sudomock.com/api/v1/renders\" \\\n  -H \"x-api-key: sm_your_api_key\" \\\n  -H \"Content-Type: application/json\" \\\n  -d '{\n    \"export_options\": {\n      \"image_format\": \"webp\",\n      \"image_size\": 1920,\n      \"quality\": 95\n    },\n    \"mockup_uuid\": \"123e4567-e89b-12d3-a456-426614174000\",\n    \"smart_objects\": [\n      {\n        \"asset\": {\n          \"fit\": \"fill\",\n          \"position\": {\n            \"left\": 100,\n            \"top\": 100\n          },\n          \"rotate\": 0,\n          \"size\": {\n            \"height\": 600,\n            \"width\": 800\n          },\n          \"url\": \"https://example.com/user-design.png\"\n        },\n        \"color\": {\n          \"blending_mode\": \"multiply\",\n          \"hex\": \"#FFFFFF\"\n        },\n        \"uuid\": \"223e4567-e89b-12d3-a456-426614174001\"\n      }\n    ]\n  }'"
          }
        ]
      }
    },
    "/api/v1/remove-background": {
      "post": {
        "tags": [
          "Background removal"
        ],
        "summary": "Remove the background from an image",
        "description": "Isolates the subject of an image onto a transparent background and returns a clean PNG cutout URL, ready to use as render artwork. Costs 25 credits per image; credits are refunded automatically if processing fails.",
        "operationId": "remove_background_api_v1_remove_background_post",
        "requestBody": {
          "required": true,
          "content": {
            "application/json": {
              "schema": {
                "$ref": "#/components/schemas/BackgroundRemovalRequest"
              }
            }
          }
        },
        "responses": {
          "200": {
            "description": "Successful Response",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/BackgroundRemovalResponse"
                }
              }
            }
          }
        },
        "x-mint": {
          "metadata": {
            "sidebarTitle": "Remove background"
          }
        },
        "security": [
          {
            "ApiKeyAuth": []
          }
        ],
        "x-codeSamples": [
          {
            "lang": "Node.js",
            "source": "const response = await fetch(\"https://api.sudomock.com/api/v1/remove-background\", {\n  method: \"POST\",\n  headers: {\n    \"x-api-key\": \"sm_your_api_key\",\n    \"Content-Type\": \"application/json\",\n  },\n  body: JSON.stringify({\n    \"url\": \"https://example.com/product-photo.jpg\"\n  }),\n});\n\nconst data = await response.json();\nconsole.log(data);"
          },
          {
            "lang": "PHP",
            "source": "<?php\n\n$payload = <<<'JSON'\n{\n  \"url\": \"https://example.com/product-photo.jpg\"\n}\nJSON;\n\n$ch = curl_init(\"https://api.sudomock.com/api/v1/remove-background\");\ncurl_setopt($ch, CURLOPT_CUSTOMREQUEST, \"POST\");\ncurl_setopt($ch, CURLOPT_RETURNTRANSFER, true);\ncurl_setopt($ch, CURLOPT_HTTPHEADER, [\n    \"x-api-key: sm_your_api_key\",\n    \"Content-Type: application/json\",\n]);\ncurl_setopt($ch, CURLOPT_POSTFIELDS, $payload);\n\n$response = curl_exec($ch);\ncurl_close($ch);\n\necho $response;"
          },
          {
            "lang": "Python",
            "source": "import requests\n\npayload = {\n    \"url\": \"https://example.com/product-photo.jpg\"\n}\n\nresponse = requests.post(\n    \"https://api.sudomock.com/api/v1/remove-background\",\n    headers={\"x-api-key\": \"sm_your_api_key\"},\n    json=payload,\n)\n\nresponse.raise_for_status()\nprint(response.json())"
          },
          {
            "lang": "Ruby",
            "source": "require \"net/http\"\nrequire \"uri\"\n\nuri = URI(\"https://api.sudomock.com/api/v1/remove-background\")\nrequest = Net::HTTP::Post.new(uri)\nrequest[\"x-api-key\"] = \"sm_your_api_key\"\nrequest[\"Content-Type\"] = \"application/json\"\n\nrequest.body = <<~JSON\n  {\n    \"url\": \"https://example.com/product-photo.jpg\"\n  }\nJSON\n\nresponse = Net::HTTP.start(uri.host, uri.port, use_ssl: true) do |http|\n  http.request(request)\nend\n\nputs response.body"
          },
          {
            "lang": "Go",
            "source": "package main\n\nimport (\n\t\"bytes\"\n\t\"fmt\"\n\t\"io\"\n\t\"net/http\"\n)\n\nfunc main() {\n\tpayload := []byte(`{\n  \"url\": \"https://example.com/product-photo.jpg\"\n}`)\n\n\treq, err := http.NewRequest(\"POST\", \"https://api.sudomock.com/api/v1/remove-background\", bytes.NewBuffer(payload))\n\tif err != nil {\n\t\tpanic(err)\n\t}\n\treq.Header.Set(\"x-api-key\", \"sm_your_api_key\")\n\treq.Header.Set(\"Content-Type\", \"application/json\")\n\n\tres, err := http.DefaultClient.Do(req)\n\tif err != nil {\n\t\tpanic(err)\n\t}\n\tdefer res.Body.Close()\n\n\tbody, _ := io.ReadAll(res.Body)\n\tfmt.Println(string(body))\n}"
          },
          {
            "lang": "Java",
            "source": "import java.net.URI;\nimport java.net.http.HttpClient;\nimport java.net.http.HttpRequest;\nimport java.net.http.HttpResponse;\n\nString payload = \"\"\"\n{\n  \"url\": \"https://example.com/product-photo.jpg\"\n}\n\"\"\";\n\nHttpRequest request = HttpRequest.newBuilder()\n    .uri(URI.create(\"https://api.sudomock.com/api/v1/remove-background\"))\n    .header(\"x-api-key\", \"sm_your_api_key\")\n    .header(\"Content-Type\", \"application/json\")\n    .POST(HttpRequest.BodyPublishers.ofString(payload))\n    .build();\n\nHttpResponse<String> response = HttpClient.newHttpClient()\n    .send(request, HttpResponse.BodyHandlers.ofString());\n\nSystem.out.println(response.body());"
          },
          {
            "lang": ".NET",
            "source": "using System.Net.Http;\nusing System.Text;\n\nvar payload = \"\"\"\n{\n  \"url\": \"https://example.com/product-photo.jpg\"\n}\n\"\"\";\n\nvar request = new HttpRequestMessage(HttpMethod.Post, \"https://api.sudomock.com/api/v1/remove-background\");\nrequest.Headers.Add(\"x-api-key\", \"sm_your_api_key\");\nrequest.Content = new StringContent(payload, Encoding.UTF8, \"application/json\");\n\nvar client = new HttpClient();\nvar response = await client.SendAsync(request);\n\nConsole.WriteLine(await response.Content.ReadAsStringAsync());"
          },
          {
            "lang": "cURL",
            "source": "curl -X POST \"https://api.sudomock.com/api/v1/remove-background\" \\\n  -H \"x-api-key: sm_your_api_key\" \\\n  -H \"Content-Type: application/json\" \\\n  -d '{\n    \"url\": \"https://example.com/product-photo.jpg\"\n  }'"
          }
        ]
      }
    },
    "/api/v1/renders/video": {
      "post": {
        "tags": [
          "Video mockups"
        ],
        "summary": "Render a video mockup",
        "description": "Animates a mockup: produces a still render from the given smart objects, then animates it. Returns 202 with a job_id to poll (GET /api/v1/jobs/{job_id}).",
        "operationId": "render_video_api_v1_renders_video_post",
        "requestBody": {
          "required": true,
          "content": {
            "application/json": {
              "schema": {
                "$ref": "#/components/schemas/VideoRenderRequest"
              }
            }
          }
        },
        "responses": {
          "202": {
            "description": "Successful Response",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/VideoRenderAcceptedResponse"
                }
              }
            }
          }
        },
        "x-mint": {
          "metadata": {
            "sidebarTitle": "Render video mockup"
          }
        },
        "security": [
          {
            "ApiKeyAuth": []
          }
        ],
        "x-codeSamples": [
          {
            "lang": "Node.js",
            "source": "const response = await fetch(\"https://api.sudomock.com/api/v1/renders/video\", {\n  method: \"POST\",\n  headers: {\n    \"x-api-key\": \"sm_your_api_key\",\n    \"Content-Type\": \"application/json\",\n  },\n  body: JSON.stringify({\n    \"mockup_uuid\": \"123e4567-e89b-12d3-a456-426614174000\",\n    \"smart_objects\": [\n      {\n        \"asset\": {\n          \"fit\": \"fill\",\n          \"url\": \"https://example.com/user-design.png\"\n        },\n        \"uuid\": \"223e4567-e89b-12d3-a456-426614174001\"\n      }\n    ],\n    \"video\": {\n      \"audio\": false,\n      \"duration_seconds\": 4,\n      \"motion\": \"ambient\",\n      \"advanced_model\": null\n    }\n  }),\n});\n\nconst data = await response.json();\nconsole.log(data);"
          },
          {
            "lang": "PHP",
            "source": "<?php\n\n$payload = <<<'JSON'\n{\n  \"mockup_uuid\": \"123e4567-e89b-12d3-a456-426614174000\",\n  \"smart_objects\": [\n    {\n      \"asset\": {\n        \"fit\": \"fill\",\n        \"url\": \"https://example.com/user-design.png\"\n      },\n      \"uuid\": \"223e4567-e89b-12d3-a456-426614174001\"\n    }\n  ],\n  \"video\": {\n    \"audio\": false,\n    \"duration_seconds\": 4,\n    \"motion\": \"ambient\",\n    \"advanced_model\": null\n  }\n}\nJSON;\n\n$ch = curl_init(\"https://api.sudomock.com/api/v1/renders/video\");\ncurl_setopt($ch, CURLOPT_CUSTOMREQUEST, \"POST\");\ncurl_setopt($ch, CURLOPT_RETURNTRANSFER, true);\ncurl_setopt($ch, CURLOPT_HTTPHEADER, [\n    \"x-api-key: sm_your_api_key\",\n    \"Content-Type: application/json\",\n]);\ncurl_setopt($ch, CURLOPT_POSTFIELDS, $payload);\n\n$response = curl_exec($ch);\ncurl_close($ch);\n\necho $response;"
          },
          {
            "lang": "Python",
            "source": "import requests\n\npayload = {\n    \"mockup_uuid\": \"123e4567-e89b-12d3-a456-426614174000\",\n    \"smart_objects\": [\n        {\n            \"asset\": {\n                \"fit\": \"fill\",\n                \"url\": \"https://example.com/user-design.png\"\n            },\n            \"uuid\": \"223e4567-e89b-12d3-a456-426614174001\"\n        }\n    ],\n    \"video\": {\n        \"audio\": false,\n        \"duration_seconds\": 4,\n        \"motion\": \"ambient\",\n        \"advanced_model\": null\n    }\n}\n\nresponse = requests.post(\n    \"https://api.sudomock.com/api/v1/renders/video\",\n    headers={\"x-api-key\": \"sm_your_api_key\"},\n    json=payload,\n)\n\nresponse.raise_for_status()\nprint(response.json())"
          },
          {
            "lang": "Ruby",
            "source": "require \"net/http\"\nrequire \"uri\"\n\nuri = URI(\"https://api.sudomock.com/api/v1/renders/video\")\nrequest = Net::HTTP::Post.new(uri)\nrequest[\"x-api-key\"] = \"sm_your_api_key\"\nrequest[\"Content-Type\"] = \"application/json\"\n\nrequest.body = <<~JSON\n  {\n    \"mockup_uuid\": \"123e4567-e89b-12d3-a456-426614174000\",\n    \"smart_objects\": [\n      {\n        \"asset\": {\n          \"fit\": \"fill\",\n          \"url\": \"https://example.com/user-design.png\"\n        },\n        \"uuid\": \"223e4567-e89b-12d3-a456-426614174001\"\n      }\n    ],\n    \"video\": {\n      \"audio\": false,\n      \"duration_seconds\": 4,\n      \"motion\": \"ambient\",\n      \"advanced_model\": null\n    }\n  }\nJSON\n\nresponse = Net::HTTP.start(uri.host, uri.port, use_ssl: true) do |http|\n  http.request(request)\nend\n\nputs response.body"
          },
          {
            "lang": "Go",
            "source": "package main\n\nimport (\n\t\"bytes\"\n\t\"fmt\"\n\t\"io\"\n\t\"net/http\"\n)\n\nfunc main() {\n\tpayload := []byte(`{\n  \"mockup_uuid\": \"123e4567-e89b-12d3-a456-426614174000\",\n  \"smart_objects\": [\n    {\n      \"asset\": {\n        \"fit\": \"fill\",\n        \"url\": \"https://example.com/user-design.png\"\n      },\n      \"uuid\": \"223e4567-e89b-12d3-a456-426614174001\"\n    }\n  ],\n  \"video\": {\n    \"audio\": false,\n    \"duration_seconds\": 4,\n    \"motion\": \"ambient\",\n    \"advanced_model\": null\n  }\n}`)\n\n\treq, err := http.NewRequest(\"POST\", \"https://api.sudomock.com/api/v1/renders/video\", bytes.NewBuffer(payload))\n\tif err != nil {\n\t\tpanic(err)\n\t}\n\treq.Header.Set(\"x-api-key\", \"sm_your_api_key\")\n\treq.Header.Set(\"Content-Type\", \"application/json\")\n\n\tres, err := http.DefaultClient.Do(req)\n\tif err != nil {\n\t\tpanic(err)\n\t}\n\tdefer res.Body.Close()\n\n\tbody, _ := io.ReadAll(res.Body)\n\tfmt.Println(string(body))\n}"
          },
          {
            "lang": "Java",
            "source": "import java.net.URI;\nimport java.net.http.HttpClient;\nimport java.net.http.HttpRequest;\nimport java.net.http.HttpResponse;\n\nString payload = \"\"\"\n{\n  \"mockup_uuid\": \"123e4567-e89b-12d3-a456-426614174000\",\n  \"smart_objects\": [\n    {\n      \"asset\": {\n        \"fit\": \"fill\",\n        \"url\": \"https://example.com/user-design.png\"\n      },\n      \"uuid\": \"223e4567-e89b-12d3-a456-426614174001\"\n    }\n  ],\n  \"video\": {\n    \"audio\": false,\n    \"duration_seconds\": 4,\n    \"motion\": \"ambient\",\n    \"advanced_model\": null\n  }\n}\n\"\"\";\n\nHttpRequest request = HttpRequest.newBuilder()\n    .uri(URI.create(\"https://api.sudomock.com/api/v1/renders/video\"))\n    .header(\"x-api-key\", \"sm_your_api_key\")\n    .header(\"Content-Type\", \"application/json\")\n    .POST(HttpRequest.BodyPublishers.ofString(payload))\n    .build();\n\nHttpResponse<String> response = HttpClient.newHttpClient()\n    .send(request, HttpResponse.BodyHandlers.ofString());\n\nSystem.out.println(response.body());"
          },
          {
            "lang": ".NET",
            "source": "using System.Net.Http;\nusing System.Text;\n\nvar payload = \"\"\"\n{\n  \"mockup_uuid\": \"123e4567-e89b-12d3-a456-426614174000\",\n  \"smart_objects\": [\n    {\n      \"asset\": {\n        \"fit\": \"fill\",\n        \"url\": \"https://example.com/user-design.png\"\n      },\n      \"uuid\": \"223e4567-e89b-12d3-a456-426614174001\"\n    }\n  ],\n  \"video\": {\n    \"audio\": false,\n    \"duration_seconds\": 4,\n    \"motion\": \"ambient\",\n    \"advanced_model\": null\n  }\n}\n\"\"\";\n\nvar request = new HttpRequestMessage(HttpMethod.Post, \"https://api.sudomock.com/api/v1/renders/video\");\nrequest.Headers.Add(\"x-api-key\", \"sm_your_api_key\");\nrequest.Content = new StringContent(payload, Encoding.UTF8, \"application/json\");\n\nvar client = new HttpClient();\nvar response = await client.SendAsync(request);\n\nConsole.WriteLine(await response.Content.ReadAsStringAsync());"
          },
          {
            "lang": "cURL",
            "source": "curl -X POST \"https://api.sudomock.com/api/v1/renders/video\" \\\n  -H \"x-api-key: sm_your_api_key\" \\\n  -H \"Content-Type: application/json\" \\\n  -d '{\n    \"mockup_uuid\": \"123e4567-e89b-12d3-a456-426614174000\",\n    \"smart_objects\": [\n      {\n        \"asset\": {\n          \"fit\": \"fill\",\n          \"url\": \"https://example.com/user-design.png\"\n        },\n        \"uuid\": \"223e4567-e89b-12d3-a456-426614174001\"\n      }\n    ],\n    \"video\": {\n      \"audio\": false,\n      \"duration_seconds\": 4,\n      \"motion\": \"ambient\",\n      \"advanced_model\": null\n    }\n  }'"
          }
        ]
      }
    },
    "/api/v1/jobs": {
      "get": {
        "tags": [
          "Jobs"
        ],
        "summary": "Retrieve a list of jobs",
        "description": "List the caller's async jobs (render, video, upload, or photo mockup creation), newest first and paginated by cursor. Optionally filter by kind and/or mockup_uuid (e.g. one mockup's videos). Each item has the SAME shape as GET /api/v1/jobs/{job_id} plus list display fields (duration_seconds/audio/mockup_name/poster_url).",
        "operationId": "list_jobs_api_v1_jobs_get",
        "parameters": [
          {
            "name": "kind",
            "in": "query",
            "required": false,
            "schema": {
              "type": "string",
              "description": "Filter by job kind: video | render | upload | 2d_create | 2d_render | photo_mockup_create | photo_mockup_render. A photo-mockup kind selects both spellings of that job, and the listed jobs are spelled the way you asked. Omit for all kinds, each spelled as it was submitted."
            },
            "description": "Filter by job kind: video | render | upload | 2d_create | 2d_render | photo_mockup_create | photo_mockup_render. A photo-mockup kind selects both spellings of that job, and the listed jobs are spelled the way you asked. Omit for all kinds, each spelled as it was submitted."
          },
          {
            "name": "mockup_uuid",
            "in": "query",
            "required": false,
            "schema": {
              "type": "string",
              "description": "Filter by source mockup UUID (e.g. a mockup's videos). Omit for all mockups. Raw-image videos (no source mockup) are never returned by this filter."
            },
            "description": "Filter by source mockup UUID (e.g. a mockup's videos). Omit for all mockups. Raw-image videos (no source mockup) are never returned by this filter."
          },
          {
            "name": "limit",
            "in": "query",
            "required": false,
            "schema": {
              "type": "integer",
              "maximum": 50,
              "minimum": 1,
              "description": "Max jobs per page (1-50).",
              "default": 20
            },
            "description": "Max jobs per page (1-50)."
          },
          {
            "name": "cursor",
            "in": "query",
            "required": false,
            "schema": {
              "type": "string",
              "description": "Opaque cursor from a prior page's next_cursor."
            },
            "description": "Opaque cursor from a prior page's next_cursor."
          }
        ],
        "responses": {
          "200": {
            "description": "Successful Response",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/JobListResponse"
                }
              }
            }
          }
        },
        "security": [
          {
            "ApiKeyAuth": []
          }
        ],
        "x-codeSamples": [
          {
            "lang": "Node.js",
            "source": "const response = await fetch(\"https://api.sudomock.com/api/v1/jobs\", {\n  method: \"GET\",\n  headers: { \"x-api-key\": \"sm_your_api_key\" },\n});\n\nconst data = await response.json();\nconsole.log(data);"
          },
          {
            "lang": "PHP",
            "source": "<?php\n\n$ch = curl_init(\"https://api.sudomock.com/api/v1/jobs\");\ncurl_setopt($ch, CURLOPT_CUSTOMREQUEST, \"GET\");\ncurl_setopt($ch, CURLOPT_RETURNTRANSFER, true);\ncurl_setopt($ch, CURLOPT_HTTPHEADER, [\n    \"x-api-key: sm_your_api_key\",\n]);\n\n$response = curl_exec($ch);\ncurl_close($ch);\n\necho $response;"
          },
          {
            "lang": "Python",
            "source": "import requests\n\nresponse = requests.get(\n    \"https://api.sudomock.com/api/v1/jobs\",\n    headers={\"x-api-key\": \"sm_your_api_key\"},\n)\n\nresponse.raise_for_status()\nprint(response.json())"
          },
          {
            "lang": "Ruby",
            "source": "require \"net/http\"\nrequire \"uri\"\n\nuri = URI(\"https://api.sudomock.com/api/v1/jobs\")\nrequest = Net::HTTP::Get.new(uri)\nrequest[\"x-api-key\"] = \"sm_your_api_key\"\n\nresponse = Net::HTTP.start(uri.host, uri.port, use_ssl: true) do |http|\n  http.request(request)\nend\n\nputs response.body"
          },
          {
            "lang": "Go",
            "source": "package main\n\nimport (\n\t\"fmt\"\n\t\"io\"\n\t\"net/http\"\n)\n\nfunc main() {\n\treq, err := http.NewRequest(\"GET\", \"https://api.sudomock.com/api/v1/jobs\", nil)\n\tif err != nil {\n\t\tpanic(err)\n\t}\n\treq.Header.Set(\"x-api-key\", \"sm_your_api_key\")\n\n\tres, err := http.DefaultClient.Do(req)\n\tif err != nil {\n\t\tpanic(err)\n\t}\n\tdefer res.Body.Close()\n\n\tbody, _ := io.ReadAll(res.Body)\n\tfmt.Println(string(body))\n}"
          },
          {
            "lang": "Java",
            "source": "import java.net.URI;\nimport java.net.http.HttpClient;\nimport java.net.http.HttpRequest;\nimport java.net.http.HttpResponse;\n\nHttpRequest request = HttpRequest.newBuilder()\n    .uri(URI.create(\"https://api.sudomock.com/api/v1/jobs\"))\n    .header(\"x-api-key\", \"sm_your_api_key\")\n    .GET()\n    .build();\n\nHttpResponse<String> response = HttpClient.newHttpClient()\n    .send(request, HttpResponse.BodyHandlers.ofString());\n\nSystem.out.println(response.body());"
          },
          {
            "lang": ".NET",
            "source": "using System.Net.Http;\nusing System.Text;\n\nvar request = new HttpRequestMessage(HttpMethod.Get, \"https://api.sudomock.com/api/v1/jobs\");\nrequest.Headers.Add(\"x-api-key\", \"sm_your_api_key\");\n\nvar client = new HttpClient();\nvar response = await client.SendAsync(request);\n\nConsole.WriteLine(await response.Content.ReadAsStringAsync());"
          },
          {
            "lang": "cURL",
            "source": "curl -X GET \"https://api.sudomock.com/api/v1/jobs\" \\\n  -H \"x-api-key: sm_your_api_key\""
          }
        ]
      }
    },
    "/api/v1/jobs/{job_id}": {
      "get": {
        "tags": [
          "Jobs"
        ],
        "summary": "Retrieve a single job",
        "description": "Poll an async render, video, upload, or photo mockup creation job. Returns its current status and result when available.",
        "operationId": "get_job_api_v1_jobs__job_id__get",
        "parameters": [
          {
            "name": "job_id",
            "in": "path",
            "required": true,
            "schema": {
              "type": "string",
              "description": "Id returned when this job was accepted."
            },
            "description": "Id returned when this job was accepted."
          }
        ],
        "responses": {
          "200": {
            "description": "Successful Response",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/JobStatusResponse"
                }
              }
            }
          }
        },
        "security": [
          {
            "ApiKeyAuth": []
          }
        ],
        "x-codeSamples": [
          {
            "lang": "Node.js",
            "source": "const response = await fetch(\"https://api.sudomock.com/api/v1/jobs/3fa85f64-5717-4562-b3fc-2c963f66afa6\", {\n  method: \"GET\",\n  headers: { \"x-api-key\": \"sm_your_api_key\" },\n});\n\nconst data = await response.json();\nconsole.log(data);"
          },
          {
            "lang": "PHP",
            "source": "<?php\n\n$ch = curl_init(\"https://api.sudomock.com/api/v1/jobs/3fa85f64-5717-4562-b3fc-2c963f66afa6\");\ncurl_setopt($ch, CURLOPT_CUSTOMREQUEST, \"GET\");\ncurl_setopt($ch, CURLOPT_RETURNTRANSFER, true);\ncurl_setopt($ch, CURLOPT_HTTPHEADER, [\n    \"x-api-key: sm_your_api_key\",\n]);\n\n$response = curl_exec($ch);\ncurl_close($ch);\n\necho $response;"
          },
          {
            "lang": "Python",
            "source": "import requests\n\nresponse = requests.get(\n    \"https://api.sudomock.com/api/v1/jobs/3fa85f64-5717-4562-b3fc-2c963f66afa6\",\n    headers={\"x-api-key\": \"sm_your_api_key\"},\n)\n\nresponse.raise_for_status()\nprint(response.json())"
          },
          {
            "lang": "Ruby",
            "source": "require \"net/http\"\nrequire \"uri\"\n\nuri = URI(\"https://api.sudomock.com/api/v1/jobs/3fa85f64-5717-4562-b3fc-2c963f66afa6\")\nrequest = Net::HTTP::Get.new(uri)\nrequest[\"x-api-key\"] = \"sm_your_api_key\"\n\nresponse = Net::HTTP.start(uri.host, uri.port, use_ssl: true) do |http|\n  http.request(request)\nend\n\nputs response.body"
          },
          {
            "lang": "Go",
            "source": "package main\n\nimport (\n\t\"fmt\"\n\t\"io\"\n\t\"net/http\"\n)\n\nfunc main() {\n\treq, err := http.NewRequest(\"GET\", \"https://api.sudomock.com/api/v1/jobs/3fa85f64-5717-4562-b3fc-2c963f66afa6\", nil)\n\tif err != nil {\n\t\tpanic(err)\n\t}\n\treq.Header.Set(\"x-api-key\", \"sm_your_api_key\")\n\n\tres, err := http.DefaultClient.Do(req)\n\tif err != nil {\n\t\tpanic(err)\n\t}\n\tdefer res.Body.Close()\n\n\tbody, _ := io.ReadAll(res.Body)\n\tfmt.Println(string(body))\n}"
          },
          {
            "lang": "Java",
            "source": "import java.net.URI;\nimport java.net.http.HttpClient;\nimport java.net.http.HttpRequest;\nimport java.net.http.HttpResponse;\n\nHttpRequest request = HttpRequest.newBuilder()\n    .uri(URI.create(\"https://api.sudomock.com/api/v1/jobs/3fa85f64-5717-4562-b3fc-2c963f66afa6\"))\n    .header(\"x-api-key\", \"sm_your_api_key\")\n    .GET()\n    .build();\n\nHttpResponse<String> response = HttpClient.newHttpClient()\n    .send(request, HttpResponse.BodyHandlers.ofString());\n\nSystem.out.println(response.body());"
          },
          {
            "lang": ".NET",
            "source": "using System.Net.Http;\nusing System.Text;\n\nvar request = new HttpRequestMessage(HttpMethod.Get, \"https://api.sudomock.com/api/v1/jobs/3fa85f64-5717-4562-b3fc-2c963f66afa6\");\nrequest.Headers.Add(\"x-api-key\", \"sm_your_api_key\");\n\nvar client = new HttpClient();\nvar response = await client.SendAsync(request);\n\nConsole.WriteLine(await response.Content.ReadAsStringAsync());"
          },
          {
            "lang": "cURL",
            "source": "curl -X GET \"https://api.sudomock.com/api/v1/jobs/3fa85f64-5717-4562-b3fc-2c963f66afa6\" \\\n  -H \"x-api-key: sm_your_api_key\""
          }
        ]
      }
    },
    "/api/v1/packages/plans": {
      "get": {
        "tags": [
          "Account"
        ],
        "summary": "Retrieve a list of plans",
        "description": "Returns all available subscription plans with pricing and API limits",
        "operationId": "get_plans_api_v1_packages_plans_get",
        "responses": {
          "200": {
            "description": "Successful Response",
            "content": {
              "application/json": {
                "schema": {
                  "additionalProperties": true,
                  "type": "object",
                  "title": "Response Get Plans Api V1 Packages Plans Get"
                },
                "example": {
                  "plans": [
                    {
                      "id": "fa2f67af-e024-4412-8b29-a2cca7dfd4ca",
                      "name": "Starter 5K",
                      "slug": "starter-5k",
                      "tier": "starter",
                      "description": "Starter plan with 5,000 credits/month",
                      "price_monthly": 25.0,
                      "price_yearly": 250.0,
                      "credits_per_month": 5000,
                      "max_concurrent_requests": 3,
                      "max_concurrent_uploads": 2,
                      "psd_limit": 150,
                      "prices": {
                        "usd": {
                          "monthly": 25.0,
                          "yearly": 250.0
                        },
                        "eur": {
                          "monthly": 22.0,
                          "yearly": 220.0
                        },
                        "gbp": {
                          "monthly": 19.0,
                          "yearly": 190.0
                        }
                      }
                    }
                  ],
                  "addons": {
                    "custom_domain": {
                      "prices": {
                        "usd": {
                          "monthly": 50.0
                        },
                        "eur": {
                          "monthly": 45.0
                        },
                        "gbp": {
                          "monthly": 39.0
                        }
                      }
                    }
                  }
                }
              }
            }
          }
        },
        "x-mint": {
          "metadata": {
            "sidebarTitle": "List subscription plans"
          }
        },
        "x-codeSamples": [
          {
            "lang": "Node.js",
            "source": "const response = await fetch(\"https://api.sudomock.com/api/v1/packages/plans\", {\n  method: \"GET\",\n});\n\nconst data = await response.json();\nconsole.log(data);"
          },
          {
            "lang": "PHP",
            "source": "<?php\n\n$ch = curl_init(\"https://api.sudomock.com/api/v1/packages/plans\");\ncurl_setopt($ch, CURLOPT_CUSTOMREQUEST, \"GET\");\ncurl_setopt($ch, CURLOPT_RETURNTRANSFER, true);\n\n$response = curl_exec($ch);\ncurl_close($ch);\n\necho $response;"
          },
          {
            "lang": "Python",
            "source": "import requests\n\nresponse = requests.get(\n    \"https://api.sudomock.com/api/v1/packages/plans\",\n)\n\nresponse.raise_for_status()\nprint(response.json())"
          },
          {
            "lang": "Ruby",
            "source": "require \"net/http\"\nrequire \"uri\"\n\nuri = URI(\"https://api.sudomock.com/api/v1/packages/plans\")\nrequest = Net::HTTP::Get.new(uri)\n\nresponse = Net::HTTP.start(uri.host, uri.port, use_ssl: true) do |http|\n  http.request(request)\nend\n\nputs response.body"
          },
          {
            "lang": "Go",
            "source": "package main\n\nimport (\n\t\"fmt\"\n\t\"io\"\n\t\"net/http\"\n)\n\nfunc main() {\n\treq, err := http.NewRequest(\"GET\", \"https://api.sudomock.com/api/v1/packages/plans\", nil)\n\tif err != nil {\n\t\tpanic(err)\n\t}\n\n\tres, err := http.DefaultClient.Do(req)\n\tif err != nil {\n\t\tpanic(err)\n\t}\n\tdefer res.Body.Close()\n\n\tbody, _ := io.ReadAll(res.Body)\n\tfmt.Println(string(body))\n}"
          },
          {
            "lang": "Java",
            "source": "import java.net.URI;\nimport java.net.http.HttpClient;\nimport java.net.http.HttpRequest;\nimport java.net.http.HttpResponse;\n\nHttpRequest request = HttpRequest.newBuilder()\n    .uri(URI.create(\"https://api.sudomock.com/api/v1/packages/plans\"))\n    .GET()\n    .build();\n\nHttpResponse<String> response = HttpClient.newHttpClient()\n    .send(request, HttpResponse.BodyHandlers.ofString());\n\nSystem.out.println(response.body());"
          },
          {
            "lang": ".NET",
            "source": "using System.Net.Http;\nusing System.Text;\n\nvar request = new HttpRequestMessage(HttpMethod.Get, \"https://api.sudomock.com/api/v1/packages/plans\");\n\nvar client = new HttpClient();\nvar response = await client.SendAsync(request);\n\nConsole.WriteLine(await response.Content.ReadAsStringAsync());"
          },
          {
            "lang": "cURL",
            "source": "curl -X GET \"https://api.sudomock.com/api/v1/packages/plans\""
          }
        ]
      }
    },
    "/api/v1/webhook-endpoints": {
      "post": {
        "tags": [
          "Webhook endpoints"
        ],
        "summary": "Create a new webhook endpoint",
        "description": "Create an endpoint. The signing secret is returned in FULL here, once.",
        "operationId": "create_webhook_endpoint_api_v1_webhook_endpoints_post",
        "requestBody": {
          "required": true,
          "content": {
            "application/json": {
              "schema": {
                "$ref": "#/components/schemas/WebhookEndpointCreateRequest"
              }
            }
          }
        },
        "responses": {
          "201": {
            "description": "Successful Response",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/WebhookEndpointSecretResponse"
                }
              }
            }
          }
        },
        "x-mint": {
          "metadata": {
            "sidebarTitle": "Create webhook"
          }
        },
        "security": [
          {
            "ApiKeyAuth": []
          }
        ],
        "x-codeSamples": [
          {
            "lang": "Node.js",
            "source": "const response = await fetch(\"https://api.sudomock.com/api/v1/webhook-endpoints\", {\n  method: \"POST\",\n  headers: {\n    \"x-api-key\": \"sm_your_api_key\",\n    \"Content-Type\": \"application/json\",\n  },\n  body: JSON.stringify({\n    \"description\": \"Production render notifications\",\n    \"event_types\": [\n      \"render.succeeded\",\n      \"render.failed\"\n    ],\n    \"url\": \"https://your-app.example.com/hooks/sudomock\"\n  }),\n});\n\nconst data = await response.json();\nconsole.log(data);"
          },
          {
            "lang": "PHP",
            "source": "<?php\n\n$payload = <<<'JSON'\n{\n  \"description\": \"Production render notifications\",\n  \"event_types\": [\n    \"render.succeeded\",\n    \"render.failed\"\n  ],\n  \"url\": \"https://your-app.example.com/hooks/sudomock\"\n}\nJSON;\n\n$ch = curl_init(\"https://api.sudomock.com/api/v1/webhook-endpoints\");\ncurl_setopt($ch, CURLOPT_CUSTOMREQUEST, \"POST\");\ncurl_setopt($ch, CURLOPT_RETURNTRANSFER, true);\ncurl_setopt($ch, CURLOPT_HTTPHEADER, [\n    \"x-api-key: sm_your_api_key\",\n    \"Content-Type: application/json\",\n]);\ncurl_setopt($ch, CURLOPT_POSTFIELDS, $payload);\n\n$response = curl_exec($ch);\ncurl_close($ch);\n\necho $response;"
          },
          {
            "lang": "Python",
            "source": "import requests\n\npayload = {\n    \"description\": \"Production render notifications\",\n    \"event_types\": [\n        \"render.succeeded\",\n        \"render.failed\"\n    ],\n    \"url\": \"https://your-app.example.com/hooks/sudomock\"\n}\n\nresponse = requests.post(\n    \"https://api.sudomock.com/api/v1/webhook-endpoints\",\n    headers={\"x-api-key\": \"sm_your_api_key\"},\n    json=payload,\n)\n\nresponse.raise_for_status()\nprint(response.json())"
          },
          {
            "lang": "Ruby",
            "source": "require \"net/http\"\nrequire \"uri\"\n\nuri = URI(\"https://api.sudomock.com/api/v1/webhook-endpoints\")\nrequest = Net::HTTP::Post.new(uri)\nrequest[\"x-api-key\"] = \"sm_your_api_key\"\nrequest[\"Content-Type\"] = \"application/json\"\n\nrequest.body = <<~JSON\n  {\n    \"description\": \"Production render notifications\",\n    \"event_types\": [\n      \"render.succeeded\",\n      \"render.failed\"\n    ],\n    \"url\": \"https://your-app.example.com/hooks/sudomock\"\n  }\nJSON\n\nresponse = Net::HTTP.start(uri.host, uri.port, use_ssl: true) do |http|\n  http.request(request)\nend\n\nputs response.body"
          },
          {
            "lang": "Go",
            "source": "package main\n\nimport (\n\t\"bytes\"\n\t\"fmt\"\n\t\"io\"\n\t\"net/http\"\n)\n\nfunc main() {\n\tpayload := []byte(`{\n  \"description\": \"Production render notifications\",\n  \"event_types\": [\n    \"render.succeeded\",\n    \"render.failed\"\n  ],\n  \"url\": \"https://your-app.example.com/hooks/sudomock\"\n}`)\n\n\treq, err := http.NewRequest(\"POST\", \"https://api.sudomock.com/api/v1/webhook-endpoints\", bytes.NewBuffer(payload))\n\tif err != nil {\n\t\tpanic(err)\n\t}\n\treq.Header.Set(\"x-api-key\", \"sm_your_api_key\")\n\treq.Header.Set(\"Content-Type\", \"application/json\")\n\n\tres, err := http.DefaultClient.Do(req)\n\tif err != nil {\n\t\tpanic(err)\n\t}\n\tdefer res.Body.Close()\n\n\tbody, _ := io.ReadAll(res.Body)\n\tfmt.Println(string(body))\n}"
          },
          {
            "lang": "Java",
            "source": "import java.net.URI;\nimport java.net.http.HttpClient;\nimport java.net.http.HttpRequest;\nimport java.net.http.HttpResponse;\n\nString payload = \"\"\"\n{\n  \"description\": \"Production render notifications\",\n  \"event_types\": [\n    \"render.succeeded\",\n    \"render.failed\"\n  ],\n  \"url\": \"https://your-app.example.com/hooks/sudomock\"\n}\n\"\"\";\n\nHttpRequest request = HttpRequest.newBuilder()\n    .uri(URI.create(\"https://api.sudomock.com/api/v1/webhook-endpoints\"))\n    .header(\"x-api-key\", \"sm_your_api_key\")\n    .header(\"Content-Type\", \"application/json\")\n    .POST(HttpRequest.BodyPublishers.ofString(payload))\n    .build();\n\nHttpResponse<String> response = HttpClient.newHttpClient()\n    .send(request, HttpResponse.BodyHandlers.ofString());\n\nSystem.out.println(response.body());"
          },
          {
            "lang": ".NET",
            "source": "using System.Net.Http;\nusing System.Text;\n\nvar payload = \"\"\"\n{\n  \"description\": \"Production render notifications\",\n  \"event_types\": [\n    \"render.succeeded\",\n    \"render.failed\"\n  ],\n  \"url\": \"https://your-app.example.com/hooks/sudomock\"\n}\n\"\"\";\n\nvar request = new HttpRequestMessage(HttpMethod.Post, \"https://api.sudomock.com/api/v1/webhook-endpoints\");\nrequest.Headers.Add(\"x-api-key\", \"sm_your_api_key\");\nrequest.Content = new StringContent(payload, Encoding.UTF8, \"application/json\");\n\nvar client = new HttpClient();\nvar response = await client.SendAsync(request);\n\nConsole.WriteLine(await response.Content.ReadAsStringAsync());"
          },
          {
            "lang": "cURL",
            "source": "curl -X POST \"https://api.sudomock.com/api/v1/webhook-endpoints\" \\\n  -H \"x-api-key: sm_your_api_key\" \\\n  -H \"Content-Type: application/json\" \\\n  -d '{\n    \"description\": \"Production render notifications\",\n    \"event_types\": [\n      \"render.succeeded\",\n      \"render.failed\"\n    ],\n    \"url\": \"https://your-app.example.com/hooks/sudomock\"\n  }'"
          }
        ]
      },
      "get": {
        "tags": [
          "Webhook endpoints"
        ],
        "summary": "Retrieve a list of webhook endpoints",
        "description": "List every webhook endpoint on the account, with its URL, event types, and enabled state.",
        "operationId": "list_webhook_endpoints_api_v1_webhook_endpoints_get",
        "responses": {
          "200": {
            "description": "Successful Response",
            "content": {
              "application/json": {
                "schema": {
                  "type": "array",
                  "items": {
                    "$ref": "#/components/schemas/WebhookEndpointResponse"
                  },
                  "title": "Response List Webhook Endpoints Api V1 Webhook Endpoints Get"
                }
              }
            }
          }
        },
        "x-mint": {
          "metadata": {
            "sidebarTitle": "List webhooks"
          }
        },
        "security": [
          {
            "ApiKeyAuth": []
          }
        ],
        "x-codeSamples": [
          {
            "lang": "Node.js",
            "source": "const response = await fetch(\"https://api.sudomock.com/api/v1/webhook-endpoints\", {\n  method: \"GET\",\n  headers: { \"x-api-key\": \"sm_your_api_key\" },\n});\n\nconst data = await response.json();\nconsole.log(data);"
          },
          {
            "lang": "PHP",
            "source": "<?php\n\n$ch = curl_init(\"https://api.sudomock.com/api/v1/webhook-endpoints\");\ncurl_setopt($ch, CURLOPT_CUSTOMREQUEST, \"GET\");\ncurl_setopt($ch, CURLOPT_RETURNTRANSFER, true);\ncurl_setopt($ch, CURLOPT_HTTPHEADER, [\n    \"x-api-key: sm_your_api_key\",\n]);\n\n$response = curl_exec($ch);\ncurl_close($ch);\n\necho $response;"
          },
          {
            "lang": "Python",
            "source": "import requests\n\nresponse = requests.get(\n    \"https://api.sudomock.com/api/v1/webhook-endpoints\",\n    headers={\"x-api-key\": \"sm_your_api_key\"},\n)\n\nresponse.raise_for_status()\nprint(response.json())"
          },
          {
            "lang": "Ruby",
            "source": "require \"net/http\"\nrequire \"uri\"\n\nuri = URI(\"https://api.sudomock.com/api/v1/webhook-endpoints\")\nrequest = Net::HTTP::Get.new(uri)\nrequest[\"x-api-key\"] = \"sm_your_api_key\"\n\nresponse = Net::HTTP.start(uri.host, uri.port, use_ssl: true) do |http|\n  http.request(request)\nend\n\nputs response.body"
          },
          {
            "lang": "Go",
            "source": "package main\n\nimport (\n\t\"fmt\"\n\t\"io\"\n\t\"net/http\"\n)\n\nfunc main() {\n\treq, err := http.NewRequest(\"GET\", \"https://api.sudomock.com/api/v1/webhook-endpoints\", nil)\n\tif err != nil {\n\t\tpanic(err)\n\t}\n\treq.Header.Set(\"x-api-key\", \"sm_your_api_key\")\n\n\tres, err := http.DefaultClient.Do(req)\n\tif err != nil {\n\t\tpanic(err)\n\t}\n\tdefer res.Body.Close()\n\n\tbody, _ := io.ReadAll(res.Body)\n\tfmt.Println(string(body))\n}"
          },
          {
            "lang": "Java",
            "source": "import java.net.URI;\nimport java.net.http.HttpClient;\nimport java.net.http.HttpRequest;\nimport java.net.http.HttpResponse;\n\nHttpRequest request = HttpRequest.newBuilder()\n    .uri(URI.create(\"https://api.sudomock.com/api/v1/webhook-endpoints\"))\n    .header(\"x-api-key\", \"sm_your_api_key\")\n    .GET()\n    .build();\n\nHttpResponse<String> response = HttpClient.newHttpClient()\n    .send(request, HttpResponse.BodyHandlers.ofString());\n\nSystem.out.println(response.body());"
          },
          {
            "lang": ".NET",
            "source": "using System.Net.Http;\nusing System.Text;\n\nvar request = new HttpRequestMessage(HttpMethod.Get, \"https://api.sudomock.com/api/v1/webhook-endpoints\");\nrequest.Headers.Add(\"x-api-key\", \"sm_your_api_key\");\n\nvar client = new HttpClient();\nvar response = await client.SendAsync(request);\n\nConsole.WriteLine(await response.Content.ReadAsStringAsync());"
          },
          {
            "lang": "cURL",
            "source": "curl -X GET \"https://api.sudomock.com/api/v1/webhook-endpoints\" \\\n  -H \"x-api-key: sm_your_api_key\""
          }
        ]
      }
    },
    "/api/v1/webhook-endpoints/events": {
      "get": {
        "tags": [
          "Webhook deliveries"
        ],
        "summary": "Retrieve a list of events",
        "description": "Reverse-chron delivery log spanning every endpoint the caller owns. The response groups rows by (job_id, event_type) into events.",
        "operationId": "list_events_api_v1_webhook_endpoints_events_get",
        "parameters": [
          {
            "name": "status",
            "in": "query",
            "required": false,
            "schema": {
              "type": "string",
              "description": "Keep only deliveries in this state, where failed also returns the ones marked dead."
            },
            "description": "Keep only deliveries in this state, where failed also returns the ones marked dead."
          },
          {
            "name": "event_type",
            "in": "query",
            "required": false,
            "schema": {
              "type": "string",
              "description": "Filter by event type. Either spelling of a photo-mockup event matches deliveries logged under the other."
            },
            "description": "Filter by event type. Either spelling of a photo-mockup event matches deliveries logged under the other."
          },
          {
            "name": "cursor",
            "in": "query",
            "required": false,
            "schema": {
              "type": "string",
              "description": "Token from the previous page's X-Webhook-Next-Cursor response header; omit it to start from the newest delivery."
            },
            "description": "Token from the previous page's X-Webhook-Next-Cursor response header; omit it to start from the newest delivery."
          },
          {
            "name": "limit",
            "in": "query",
            "required": false,
            "schema": {
              "type": "integer",
              "maximum": 200,
              "minimum": 1,
              "description": "How many deliveries one page returns, with the rest reachable through the next page's cursor.",
              "default": 100
            },
            "description": "How many deliveries one page returns, with the rest reachable through the next page's cursor."
          }
        ],
        "responses": {
          "200": {
            "description": "Successful Response",
            "content": {
              "application/json": {
                "schema": {
                  "type": "array",
                  "items": {
                    "$ref": "#/components/schemas/WebhookDeliveryResponse"
                  },
                  "title": "Response List Events Api V1 Webhook Endpoints Events Get"
                }
              }
            },
            "headers": {
              "X-Webhook-Next-Cursor": {
                "description": "Opaque cursor for the next page; absent on the last page.",
                "schema": {
                  "type": "string"
                }
              }
            }
          }
        },
        "x-mint": {
          "metadata": {
            "sidebarTitle": "List all deliveries"
          }
        },
        "security": [
          {
            "ApiKeyAuth": []
          }
        ],
        "x-codeSamples": [
          {
            "lang": "Node.js",
            "source": "const response = await fetch(\"https://api.sudomock.com/api/v1/webhook-endpoints/events\", {\n  method: \"GET\",\n  headers: { \"x-api-key\": \"sm_your_api_key\" },\n});\n\nconst data = await response.json();\nconsole.log(data);"
          },
          {
            "lang": "PHP",
            "source": "<?php\n\n$ch = curl_init(\"https://api.sudomock.com/api/v1/webhook-endpoints/events\");\ncurl_setopt($ch, CURLOPT_CUSTOMREQUEST, \"GET\");\ncurl_setopt($ch, CURLOPT_RETURNTRANSFER, true);\ncurl_setopt($ch, CURLOPT_HTTPHEADER, [\n    \"x-api-key: sm_your_api_key\",\n]);\n\n$response = curl_exec($ch);\ncurl_close($ch);\n\necho $response;"
          },
          {
            "lang": "Python",
            "source": "import requests\n\nresponse = requests.get(\n    \"https://api.sudomock.com/api/v1/webhook-endpoints/events\",\n    headers={\"x-api-key\": \"sm_your_api_key\"},\n)\n\nresponse.raise_for_status()\nprint(response.json())"
          },
          {
            "lang": "Ruby",
            "source": "require \"net/http\"\nrequire \"uri\"\n\nuri = URI(\"https://api.sudomock.com/api/v1/webhook-endpoints/events\")\nrequest = Net::HTTP::Get.new(uri)\nrequest[\"x-api-key\"] = \"sm_your_api_key\"\n\nresponse = Net::HTTP.start(uri.host, uri.port, use_ssl: true) do |http|\n  http.request(request)\nend\n\nputs response.body"
          },
          {
            "lang": "Go",
            "source": "package main\n\nimport (\n\t\"fmt\"\n\t\"io\"\n\t\"net/http\"\n)\n\nfunc main() {\n\treq, err := http.NewRequest(\"GET\", \"https://api.sudomock.com/api/v1/webhook-endpoints/events\", nil)\n\tif err != nil {\n\t\tpanic(err)\n\t}\n\treq.Header.Set(\"x-api-key\", \"sm_your_api_key\")\n\n\tres, err := http.DefaultClient.Do(req)\n\tif err != nil {\n\t\tpanic(err)\n\t}\n\tdefer res.Body.Close()\n\n\tbody, _ := io.ReadAll(res.Body)\n\tfmt.Println(string(body))\n}"
          },
          {
            "lang": "Java",
            "source": "import java.net.URI;\nimport java.net.http.HttpClient;\nimport java.net.http.HttpRequest;\nimport java.net.http.HttpResponse;\n\nHttpRequest request = HttpRequest.newBuilder()\n    .uri(URI.create(\"https://api.sudomock.com/api/v1/webhook-endpoints/events\"))\n    .header(\"x-api-key\", \"sm_your_api_key\")\n    .GET()\n    .build();\n\nHttpResponse<String> response = HttpClient.newHttpClient()\n    .send(request, HttpResponse.BodyHandlers.ofString());\n\nSystem.out.println(response.body());"
          },
          {
            "lang": ".NET",
            "source": "using System.Net.Http;\nusing System.Text;\n\nvar request = new HttpRequestMessage(HttpMethod.Get, \"https://api.sudomock.com/api/v1/webhook-endpoints/events\");\nrequest.Headers.Add(\"x-api-key\", \"sm_your_api_key\");\n\nvar client = new HttpClient();\nvar response = await client.SendAsync(request);\n\nConsole.WriteLine(await response.Content.ReadAsStringAsync());"
          },
          {
            "lang": "cURL",
            "source": "curl -X GET \"https://api.sudomock.com/api/v1/webhook-endpoints/events\" \\\n  -H \"x-api-key: sm_your_api_key\""
          }
        ]
      }
    },
    "/api/v1/webhook-endpoints/overview": {
      "get": {
        "tags": [
          "Webhook deliveries"
        ],
        "summary": "Retrieve the delivery overview",
        "description": "Window-scoped delivery rollup spanning every endpoint the caller owns: global total/failed COUNTs, a per-day sparkline, and a per-endpoint breakdown (total/failed/last_activity). The path is 'overview', not an endpoint id.",
        "operationId": "webhook_overview_api_v1_webhook_endpoints_overview_get",
        "parameters": [
          {
            "name": "period_days",
            "in": "query",
            "required": false,
            "schema": {
              "type": "integer",
              "maximum": 90,
              "minimum": 1,
              "description": "How many days back the rollup reaches, covering the totals, the daily counts, and the per endpoint breakdown.",
              "default": 7
            },
            "description": "How many days back the rollup reaches, covering the totals, the daily counts, and the per endpoint breakdown."
          },
          {
            "name": "tz_offset_minutes",
            "in": "query",
            "required": false,
            "schema": {
              "type": "integer",
              "description": "Minutes to shift the daily buckets from UTC, so counts line up with your local day.",
              "default": 0
            },
            "description": "Minutes to shift the daily buckets from UTC, so counts line up with your local day."
          }
        ],
        "responses": {
          "200": {
            "description": "Successful Response",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/WebhookOverviewResponse"
                }
              }
            }
          }
        },
        "x-mint": {
          "metadata": {
            "sidebarTitle": "Get delivery overview"
          }
        },
        "security": [
          {
            "ApiKeyAuth": []
          }
        ],
        "x-codeSamples": [
          {
            "lang": "Node.js",
            "source": "const response = await fetch(\"https://api.sudomock.com/api/v1/webhook-endpoints/overview\", {\n  method: \"GET\",\n  headers: { \"x-api-key\": \"sm_your_api_key\" },\n});\n\nconst data = await response.json();\nconsole.log(data);"
          },
          {
            "lang": "PHP",
            "source": "<?php\n\n$ch = curl_init(\"https://api.sudomock.com/api/v1/webhook-endpoints/overview\");\ncurl_setopt($ch, CURLOPT_CUSTOMREQUEST, \"GET\");\ncurl_setopt($ch, CURLOPT_RETURNTRANSFER, true);\ncurl_setopt($ch, CURLOPT_HTTPHEADER, [\n    \"x-api-key: sm_your_api_key\",\n]);\n\n$response = curl_exec($ch);\ncurl_close($ch);\n\necho $response;"
          },
          {
            "lang": "Python",
            "source": "import requests\n\nresponse = requests.get(\n    \"https://api.sudomock.com/api/v1/webhook-endpoints/overview\",\n    headers={\"x-api-key\": \"sm_your_api_key\"},\n)\n\nresponse.raise_for_status()\nprint(response.json())"
          },
          {
            "lang": "Ruby",
            "source": "require \"net/http\"\nrequire \"uri\"\n\nuri = URI(\"https://api.sudomock.com/api/v1/webhook-endpoints/overview\")\nrequest = Net::HTTP::Get.new(uri)\nrequest[\"x-api-key\"] = \"sm_your_api_key\"\n\nresponse = Net::HTTP.start(uri.host, uri.port, use_ssl: true) do |http|\n  http.request(request)\nend\n\nputs response.body"
          },
          {
            "lang": "Go",
            "source": "package main\n\nimport (\n\t\"fmt\"\n\t\"io\"\n\t\"net/http\"\n)\n\nfunc main() {\n\treq, err := http.NewRequest(\"GET\", \"https://api.sudomock.com/api/v1/webhook-endpoints/overview\", nil)\n\tif err != nil {\n\t\tpanic(err)\n\t}\n\treq.Header.Set(\"x-api-key\", \"sm_your_api_key\")\n\n\tres, err := http.DefaultClient.Do(req)\n\tif err != nil {\n\t\tpanic(err)\n\t}\n\tdefer res.Body.Close()\n\n\tbody, _ := io.ReadAll(res.Body)\n\tfmt.Println(string(body))\n}"
          },
          {
            "lang": "Java",
            "source": "import java.net.URI;\nimport java.net.http.HttpClient;\nimport java.net.http.HttpRequest;\nimport java.net.http.HttpResponse;\n\nHttpRequest request = HttpRequest.newBuilder()\n    .uri(URI.create(\"https://api.sudomock.com/api/v1/webhook-endpoints/overview\"))\n    .header(\"x-api-key\", \"sm_your_api_key\")\n    .GET()\n    .build();\n\nHttpResponse<String> response = HttpClient.newHttpClient()\n    .send(request, HttpResponse.BodyHandlers.ofString());\n\nSystem.out.println(response.body());"
          },
          {
            "lang": ".NET",
            "source": "using System.Net.Http;\nusing System.Text;\n\nvar request = new HttpRequestMessage(HttpMethod.Get, \"https://api.sudomock.com/api/v1/webhook-endpoints/overview\");\nrequest.Headers.Add(\"x-api-key\", \"sm_your_api_key\");\n\nvar client = new HttpClient();\nvar response = await client.SendAsync(request);\n\nConsole.WriteLine(await response.Content.ReadAsStringAsync());"
          },
          {
            "lang": "cURL",
            "source": "curl -X GET \"https://api.sudomock.com/api/v1/webhook-endpoints/overview\" \\\n  -H \"x-api-key: sm_your_api_key\""
          }
        ]
      }
    },
    "/api/v1/webhook-endpoints/{endpoint_id}": {
      "get": {
        "tags": [
          "Webhook endpoints"
        ],
        "summary": "Retrieve a single webhook endpoint",
        "description": "Fetch one endpoint by id. The signing secret comes back masked.",
        "operationId": "get_webhook_endpoint_api_v1_webhook_endpoints__endpoint_id__get",
        "parameters": [
          {
            "name": "endpoint_id",
            "in": "path",
            "required": true,
            "schema": {
              "type": "string",
              "description": "Id of the endpoint to read, as returned when it was created."
            },
            "description": "Id of the endpoint to read, as returned when it was created."
          }
        ],
        "responses": {
          "200": {
            "description": "Successful Response",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/WebhookEndpointResponse"
                }
              }
            }
          }
        },
        "x-mint": {
          "metadata": {
            "sidebarTitle": "Get webhook"
          }
        },
        "security": [
          {
            "ApiKeyAuth": []
          }
        ],
        "x-codeSamples": [
          {
            "lang": "Node.js",
            "source": "const response = await fetch(\"https://api.sudomock.com/api/v1/webhook-endpoints/3fa85f64-5717-4562-b3fc-2c963f66afa6\", {\n  method: \"GET\",\n  headers: { \"x-api-key\": \"sm_your_api_key\" },\n});\n\nconst data = await response.json();\nconsole.log(data);"
          },
          {
            "lang": "PHP",
            "source": "<?php\n\n$ch = curl_init(\"https://api.sudomock.com/api/v1/webhook-endpoints/3fa85f64-5717-4562-b3fc-2c963f66afa6\");\ncurl_setopt($ch, CURLOPT_CUSTOMREQUEST, \"GET\");\ncurl_setopt($ch, CURLOPT_RETURNTRANSFER, true);\ncurl_setopt($ch, CURLOPT_HTTPHEADER, [\n    \"x-api-key: sm_your_api_key\",\n]);\n\n$response = curl_exec($ch);\ncurl_close($ch);\n\necho $response;"
          },
          {
            "lang": "Python",
            "source": "import requests\n\nresponse = requests.get(\n    \"https://api.sudomock.com/api/v1/webhook-endpoints/3fa85f64-5717-4562-b3fc-2c963f66afa6\",\n    headers={\"x-api-key\": \"sm_your_api_key\"},\n)\n\nresponse.raise_for_status()\nprint(response.json())"
          },
          {
            "lang": "Ruby",
            "source": "require \"net/http\"\nrequire \"uri\"\n\nuri = URI(\"https://api.sudomock.com/api/v1/webhook-endpoints/3fa85f64-5717-4562-b3fc-2c963f66afa6\")\nrequest = Net::HTTP::Get.new(uri)\nrequest[\"x-api-key\"] = \"sm_your_api_key\"\n\nresponse = Net::HTTP.start(uri.host, uri.port, use_ssl: true) do |http|\n  http.request(request)\nend\n\nputs response.body"
          },
          {
            "lang": "Go",
            "source": "package main\n\nimport (\n\t\"fmt\"\n\t\"io\"\n\t\"net/http\"\n)\n\nfunc main() {\n\treq, err := http.NewRequest(\"GET\", \"https://api.sudomock.com/api/v1/webhook-endpoints/3fa85f64-5717-4562-b3fc-2c963f66afa6\", nil)\n\tif err != nil {\n\t\tpanic(err)\n\t}\n\treq.Header.Set(\"x-api-key\", \"sm_your_api_key\")\n\n\tres, err := http.DefaultClient.Do(req)\n\tif err != nil {\n\t\tpanic(err)\n\t}\n\tdefer res.Body.Close()\n\n\tbody, _ := io.ReadAll(res.Body)\n\tfmt.Println(string(body))\n}"
          },
          {
            "lang": "Java",
            "source": "import java.net.URI;\nimport java.net.http.HttpClient;\nimport java.net.http.HttpRequest;\nimport java.net.http.HttpResponse;\n\nHttpRequest request = HttpRequest.newBuilder()\n    .uri(URI.create(\"https://api.sudomock.com/api/v1/webhook-endpoints/3fa85f64-5717-4562-b3fc-2c963f66afa6\"))\n    .header(\"x-api-key\", \"sm_your_api_key\")\n    .GET()\n    .build();\n\nHttpResponse<String> response = HttpClient.newHttpClient()\n    .send(request, HttpResponse.BodyHandlers.ofString());\n\nSystem.out.println(response.body());"
          },
          {
            "lang": ".NET",
            "source": "using System.Net.Http;\nusing System.Text;\n\nvar request = new HttpRequestMessage(HttpMethod.Get, \"https://api.sudomock.com/api/v1/webhook-endpoints/3fa85f64-5717-4562-b3fc-2c963f66afa6\");\nrequest.Headers.Add(\"x-api-key\", \"sm_your_api_key\");\n\nvar client = new HttpClient();\nvar response = await client.SendAsync(request);\n\nConsole.WriteLine(await response.Content.ReadAsStringAsync());"
          },
          {
            "lang": "cURL",
            "source": "curl -X GET \"https://api.sudomock.com/api/v1/webhook-endpoints/3fa85f64-5717-4562-b3fc-2c963f66afa6\" \\\n  -H \"x-api-key: sm_your_api_key\""
          }
        ]
      },
      "patch": {
        "tags": [
          "Webhook endpoints"
        ],
        "summary": "Update an existing webhook endpoint",
        "description": "Change the URL, description, event types, event naming, or enabled state. Send only the fields you are changing.",
        "operationId": "update_webhook_endpoint_api_v1_webhook_endpoints__endpoint_id__patch",
        "parameters": [
          {
            "name": "endpoint_id",
            "in": "path",
            "required": true,
            "schema": {
              "type": "string",
              "description": "Id of the endpoint whose settings you want to change."
            },
            "description": "Id of the endpoint whose settings you want to change."
          }
        ],
        "requestBody": {
          "required": true,
          "content": {
            "application/json": {
              "schema": {
                "$ref": "#/components/schemas/WebhookEndpointUpdateRequest"
              }
            }
          }
        },
        "responses": {
          "200": {
            "description": "Successful Response",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/WebhookEndpointResponse"
                }
              }
            }
          }
        },
        "x-mint": {
          "metadata": {
            "sidebarTitle": "Update webhook"
          }
        },
        "security": [
          {
            "ApiKeyAuth": []
          }
        ],
        "x-codeSamples": [
          {
            "lang": "Node.js",
            "source": "const response = await fetch(\"https://api.sudomock.com/api/v1/webhook-endpoints/3fa85f64-5717-4562-b3fc-2c963f66afa6\", {\n  method: \"PATCH\",\n  headers: {\n    \"x-api-key\": \"sm_your_api_key\",\n    \"Content-Type\": \"application/json\",\n  },\n  body: JSON.stringify({\n    \"description\": \"Production render notifications\",\n    \"enabled\": true\n  }),\n});\n\nconst data = await response.json();\nconsole.log(data);"
          },
          {
            "lang": "PHP",
            "source": "<?php\n\n$payload = <<<'JSON'\n{\n  \"description\": \"Production render notifications\",\n  \"enabled\": true\n}\nJSON;\n\n$ch = curl_init(\"https://api.sudomock.com/api/v1/webhook-endpoints/3fa85f64-5717-4562-b3fc-2c963f66afa6\");\ncurl_setopt($ch, CURLOPT_CUSTOMREQUEST, \"PATCH\");\ncurl_setopt($ch, CURLOPT_RETURNTRANSFER, true);\ncurl_setopt($ch, CURLOPT_HTTPHEADER, [\n    \"x-api-key: sm_your_api_key\",\n    \"Content-Type: application/json\",\n]);\ncurl_setopt($ch, CURLOPT_POSTFIELDS, $payload);\n\n$response = curl_exec($ch);\ncurl_close($ch);\n\necho $response;"
          },
          {
            "lang": "Python",
            "source": "import requests\n\npayload = {\n    \"description\": \"Production render notifications\",\n    \"enabled\": true\n}\n\nresponse = requests.patch(\n    \"https://api.sudomock.com/api/v1/webhook-endpoints/3fa85f64-5717-4562-b3fc-2c963f66afa6\",\n    headers={\"x-api-key\": \"sm_your_api_key\"},\n    json=payload,\n)\n\nresponse.raise_for_status()\nprint(response.json())"
          },
          {
            "lang": "Ruby",
            "source": "require \"net/http\"\nrequire \"uri\"\n\nuri = URI(\"https://api.sudomock.com/api/v1/webhook-endpoints/3fa85f64-5717-4562-b3fc-2c963f66afa6\")\nrequest = Net::HTTP::Patch.new(uri)\nrequest[\"x-api-key\"] = \"sm_your_api_key\"\nrequest[\"Content-Type\"] = \"application/json\"\n\nrequest.body = <<~JSON\n  {\n    \"description\": \"Production render notifications\",\n    \"enabled\": true\n  }\nJSON\n\nresponse = Net::HTTP.start(uri.host, uri.port, use_ssl: true) do |http|\n  http.request(request)\nend\n\nputs response.body"
          },
          {
            "lang": "Go",
            "source": "package main\n\nimport (\n\t\"bytes\"\n\t\"fmt\"\n\t\"io\"\n\t\"net/http\"\n)\n\nfunc main() {\n\tpayload := []byte(`{\n  \"description\": \"Production render notifications\",\n  \"enabled\": true\n}`)\n\n\treq, err := http.NewRequest(\"PATCH\", \"https://api.sudomock.com/api/v1/webhook-endpoints/3fa85f64-5717-4562-b3fc-2c963f66afa6\", bytes.NewBuffer(payload))\n\tif err != nil {\n\t\tpanic(err)\n\t}\n\treq.Header.Set(\"x-api-key\", \"sm_your_api_key\")\n\treq.Header.Set(\"Content-Type\", \"application/json\")\n\n\tres, err := http.DefaultClient.Do(req)\n\tif err != nil {\n\t\tpanic(err)\n\t}\n\tdefer res.Body.Close()\n\n\tbody, _ := io.ReadAll(res.Body)\n\tfmt.Println(string(body))\n}"
          },
          {
            "lang": "Java",
            "source": "import java.net.URI;\nimport java.net.http.HttpClient;\nimport java.net.http.HttpRequest;\nimport java.net.http.HttpResponse;\n\nString payload = \"\"\"\n{\n  \"description\": \"Production render notifications\",\n  \"enabled\": true\n}\n\"\"\";\n\nHttpRequest request = HttpRequest.newBuilder()\n    .uri(URI.create(\"https://api.sudomock.com/api/v1/webhook-endpoints/3fa85f64-5717-4562-b3fc-2c963f66afa6\"))\n    .header(\"x-api-key\", \"sm_your_api_key\")\n    .header(\"Content-Type\", \"application/json\")\n    .method(\"PATCH\", HttpRequest.BodyPublishers.ofString(payload))\n    .build();\n\nHttpResponse<String> response = HttpClient.newHttpClient()\n    .send(request, HttpResponse.BodyHandlers.ofString());\n\nSystem.out.println(response.body());"
          },
          {
            "lang": ".NET",
            "source": "using System.Net.Http;\nusing System.Text;\n\nvar payload = \"\"\"\n{\n  \"description\": \"Production render notifications\",\n  \"enabled\": true\n}\n\"\"\";\n\nvar request = new HttpRequestMessage(HttpMethod.Patch, \"https://api.sudomock.com/api/v1/webhook-endpoints/3fa85f64-5717-4562-b3fc-2c963f66afa6\");\nrequest.Headers.Add(\"x-api-key\", \"sm_your_api_key\");\nrequest.Content = new StringContent(payload, Encoding.UTF8, \"application/json\");\n\nvar client = new HttpClient();\nvar response = await client.SendAsync(request);\n\nConsole.WriteLine(await response.Content.ReadAsStringAsync());"
          },
          {
            "lang": "cURL",
            "source": "curl -X PATCH \"https://api.sudomock.com/api/v1/webhook-endpoints/3fa85f64-5717-4562-b3fc-2c963f66afa6\" \\\n  -H \"x-api-key: sm_your_api_key\" \\\n  -H \"Content-Type: application/json\" \\\n  -d '{\n    \"description\": \"Production render notifications\",\n    \"enabled\": true\n  }'"
          }
        ]
      },
      "delete": {
        "tags": [
          "Webhook endpoints"
        ],
        "summary": "Remove an existing webhook endpoint",
        "description": "Delete an endpoint and its delivery history. This cannot be undone.",
        "operationId": "delete_webhook_endpoint_api_v1_webhook_endpoints__endpoint_id__delete",
        "parameters": [
          {
            "name": "endpoint_id",
            "in": "path",
            "required": true,
            "schema": {
              "type": "string",
              "description": "Id of the endpoint to remove, after which nothing is delivered to its URL."
            },
            "description": "Id of the endpoint to remove, after which nothing is delivered to its URL."
          }
        ],
        "responses": {
          "204": {
            "description": "Successful Response"
          }
        },
        "x-mint": {
          "metadata": {
            "sidebarTitle": "Delete webhook"
          }
        },
        "security": [
          {
            "ApiKeyAuth": []
          }
        ],
        "x-codeSamples": [
          {
            "lang": "Node.js",
            "source": "const response = await fetch(\"https://api.sudomock.com/api/v1/webhook-endpoints/3fa85f64-5717-4562-b3fc-2c963f66afa6\", {\n  method: \"DELETE\",\n  headers: { \"x-api-key\": \"sm_your_api_key\" },\n});\n\nconst data = await response.json();\nconsole.log(data);"
          },
          {
            "lang": "PHP",
            "source": "<?php\n\n$ch = curl_init(\"https://api.sudomock.com/api/v1/webhook-endpoints/3fa85f64-5717-4562-b3fc-2c963f66afa6\");\ncurl_setopt($ch, CURLOPT_CUSTOMREQUEST, \"DELETE\");\ncurl_setopt($ch, CURLOPT_RETURNTRANSFER, true);\ncurl_setopt($ch, CURLOPT_HTTPHEADER, [\n    \"x-api-key: sm_your_api_key\",\n]);\n\n$response = curl_exec($ch);\ncurl_close($ch);\n\necho $response;"
          },
          {
            "lang": "Python",
            "source": "import requests\n\nresponse = requests.delete(\n    \"https://api.sudomock.com/api/v1/webhook-endpoints/3fa85f64-5717-4562-b3fc-2c963f66afa6\",\n    headers={\"x-api-key\": \"sm_your_api_key\"},\n)\n\nresponse.raise_for_status()\nprint(response.json())"
          },
          {
            "lang": "Ruby",
            "source": "require \"net/http\"\nrequire \"uri\"\n\nuri = URI(\"https://api.sudomock.com/api/v1/webhook-endpoints/3fa85f64-5717-4562-b3fc-2c963f66afa6\")\nrequest = Net::HTTP::Delete.new(uri)\nrequest[\"x-api-key\"] = \"sm_your_api_key\"\n\nresponse = Net::HTTP.start(uri.host, uri.port, use_ssl: true) do |http|\n  http.request(request)\nend\n\nputs response.body"
          },
          {
            "lang": "Go",
            "source": "package main\n\nimport (\n\t\"fmt\"\n\t\"io\"\n\t\"net/http\"\n)\n\nfunc main() {\n\treq, err := http.NewRequest(\"DELETE\", \"https://api.sudomock.com/api/v1/webhook-endpoints/3fa85f64-5717-4562-b3fc-2c963f66afa6\", nil)\n\tif err != nil {\n\t\tpanic(err)\n\t}\n\treq.Header.Set(\"x-api-key\", \"sm_your_api_key\")\n\n\tres, err := http.DefaultClient.Do(req)\n\tif err != nil {\n\t\tpanic(err)\n\t}\n\tdefer res.Body.Close()\n\n\tbody, _ := io.ReadAll(res.Body)\n\tfmt.Println(string(body))\n}"
          },
          {
            "lang": "Java",
            "source": "import java.net.URI;\nimport java.net.http.HttpClient;\nimport java.net.http.HttpRequest;\nimport java.net.http.HttpResponse;\n\nHttpRequest request = HttpRequest.newBuilder()\n    .uri(URI.create(\"https://api.sudomock.com/api/v1/webhook-endpoints/3fa85f64-5717-4562-b3fc-2c963f66afa6\"))\n    .header(\"x-api-key\", \"sm_your_api_key\")\n    .DELETE()\n    .build();\n\nHttpResponse<String> response = HttpClient.newHttpClient()\n    .send(request, HttpResponse.BodyHandlers.ofString());\n\nSystem.out.println(response.body());"
          },
          {
            "lang": ".NET",
            "source": "using System.Net.Http;\nusing System.Text;\n\nvar request = new HttpRequestMessage(HttpMethod.Delete, \"https://api.sudomock.com/api/v1/webhook-endpoints/3fa85f64-5717-4562-b3fc-2c963f66afa6\");\nrequest.Headers.Add(\"x-api-key\", \"sm_your_api_key\");\n\nvar client = new HttpClient();\nvar response = await client.SendAsync(request);\n\nConsole.WriteLine(await response.Content.ReadAsStringAsync());"
          },
          {
            "lang": "cURL",
            "source": "curl -X DELETE \"https://api.sudomock.com/api/v1/webhook-endpoints/3fa85f64-5717-4562-b3fc-2c963f66afa6\" \\\n  -H \"x-api-key: sm_your_api_key\""
          }
        ]
      }
    },
    "/api/v1/webhook-endpoints/{endpoint_id}/rotate-secret": {
      "post": {
        "tags": [
          "Webhook endpoints"
        ],
        "summary": "Rotate the signing secret",
        "description": "Generate a new secret, returned in FULL once.",
        "operationId": "rotate_webhook_secret_api_v1_webhook_endpoints__endpoint_id__rotate_secret_post",
        "parameters": [
          {
            "name": "endpoint_id",
            "in": "path",
            "required": true,
            "schema": {
              "type": "string",
              "description": "Id of the endpoint whose signing secret is replaced."
            },
            "description": "Id of the endpoint whose signing secret is replaced."
          }
        ],
        "responses": {
          "200": {
            "description": "Successful Response",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/WebhookEndpointSecretResponse"
                }
              }
            }
          }
        },
        "x-mint": {
          "metadata": {
            "sidebarTitle": "Rotate signing secret"
          }
        },
        "security": [
          {
            "ApiKeyAuth": []
          }
        ],
        "x-codeSamples": [
          {
            "lang": "Node.js",
            "source": "const response = await fetch(\"https://api.sudomock.com/api/v1/webhook-endpoints/3fa85f64-5717-4562-b3fc-2c963f66afa6/rotate-secret\", {\n  method: \"POST\",\n  headers: { \"x-api-key\": \"sm_your_api_key\" },\n});\n\nconst data = await response.json();\nconsole.log(data);"
          },
          {
            "lang": "PHP",
            "source": "<?php\n\n$ch = curl_init(\"https://api.sudomock.com/api/v1/webhook-endpoints/3fa85f64-5717-4562-b3fc-2c963f66afa6/rotate-secret\");\ncurl_setopt($ch, CURLOPT_CUSTOMREQUEST, \"POST\");\ncurl_setopt($ch, CURLOPT_RETURNTRANSFER, true);\ncurl_setopt($ch, CURLOPT_HTTPHEADER, [\n    \"x-api-key: sm_your_api_key\",\n]);\n\n$response = curl_exec($ch);\ncurl_close($ch);\n\necho $response;"
          },
          {
            "lang": "Python",
            "source": "import requests\n\nresponse = requests.post(\n    \"https://api.sudomock.com/api/v1/webhook-endpoints/3fa85f64-5717-4562-b3fc-2c963f66afa6/rotate-secret\",\n    headers={\"x-api-key\": \"sm_your_api_key\"},\n)\n\nresponse.raise_for_status()\nprint(response.json())"
          },
          {
            "lang": "Ruby",
            "source": "require \"net/http\"\nrequire \"uri\"\n\nuri = URI(\"https://api.sudomock.com/api/v1/webhook-endpoints/3fa85f64-5717-4562-b3fc-2c963f66afa6/rotate-secret\")\nrequest = Net::HTTP::Post.new(uri)\nrequest[\"x-api-key\"] = \"sm_your_api_key\"\n\nresponse = Net::HTTP.start(uri.host, uri.port, use_ssl: true) do |http|\n  http.request(request)\nend\n\nputs response.body"
          },
          {
            "lang": "Go",
            "source": "package main\n\nimport (\n\t\"fmt\"\n\t\"io\"\n\t\"net/http\"\n)\n\nfunc main() {\n\treq, err := http.NewRequest(\"POST\", \"https://api.sudomock.com/api/v1/webhook-endpoints/3fa85f64-5717-4562-b3fc-2c963f66afa6/rotate-secret\", nil)\n\tif err != nil {\n\t\tpanic(err)\n\t}\n\treq.Header.Set(\"x-api-key\", \"sm_your_api_key\")\n\n\tres, err := http.DefaultClient.Do(req)\n\tif err != nil {\n\t\tpanic(err)\n\t}\n\tdefer res.Body.Close()\n\n\tbody, _ := io.ReadAll(res.Body)\n\tfmt.Println(string(body))\n}"
          },
          {
            "lang": "Java",
            "source": "import java.net.URI;\nimport java.net.http.HttpClient;\nimport java.net.http.HttpRequest;\nimport java.net.http.HttpResponse;\n\nHttpRequest request = HttpRequest.newBuilder()\n    .uri(URI.create(\"https://api.sudomock.com/api/v1/webhook-endpoints/3fa85f64-5717-4562-b3fc-2c963f66afa6/rotate-secret\"))\n    .header(\"x-api-key\", \"sm_your_api_key\")\n    .method(\"POST\", HttpRequest.BodyPublishers.noBody())\n    .build();\n\nHttpResponse<String> response = HttpClient.newHttpClient()\n    .send(request, HttpResponse.BodyHandlers.ofString());\n\nSystem.out.println(response.body());"
          },
          {
            "lang": ".NET",
            "source": "using System.Net.Http;\nusing System.Text;\n\nvar request = new HttpRequestMessage(HttpMethod.Post, \"https://api.sudomock.com/api/v1/webhook-endpoints/3fa85f64-5717-4562-b3fc-2c963f66afa6/rotate-secret\");\nrequest.Headers.Add(\"x-api-key\", \"sm_your_api_key\");\n\nvar client = new HttpClient();\nvar response = await client.SendAsync(request);\n\nConsole.WriteLine(await response.Content.ReadAsStringAsync());"
          },
          {
            "lang": "cURL",
            "source": "curl -X POST \"https://api.sudomock.com/api/v1/webhook-endpoints/3fa85f64-5717-4562-b3fc-2c963f66afa6/rotate-secret\" \\\n  -H \"x-api-key: sm_your_api_key\""
          }
        ]
      }
    },
    "/api/v1/webhook-endpoints/{endpoint_id}/test": {
      "post": {
        "tags": [
          "Webhook endpoints"
        ],
        "summary": "Send a test event",
        "description": "Send a signed webhook.test event to the endpoint.",
        "operationId": "send_test_event_api_v1_webhook_endpoints__endpoint_id__test_post",
        "parameters": [
          {
            "name": "endpoint_id",
            "in": "path",
            "required": true,
            "schema": {
              "type": "string",
              "description": "Id of the endpoint the test event is sent to."
            },
            "description": "Id of the endpoint the test event is sent to."
          }
        ],
        "responses": {
          "202": {
            "description": "Successful Response",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/WebhookTestEventResponse"
                }
              }
            }
          }
        },
        "x-mint": {
          "metadata": {
            "sidebarTitle": "Send test event"
          }
        },
        "security": [
          {
            "ApiKeyAuth": []
          }
        ],
        "x-codeSamples": [
          {
            "lang": "Node.js",
            "source": "const response = await fetch(\"https://api.sudomock.com/api/v1/webhook-endpoints/3fa85f64-5717-4562-b3fc-2c963f66afa6/test\", {\n  method: \"POST\",\n  headers: { \"x-api-key\": \"sm_your_api_key\" },\n});\n\nconst data = await response.json();\nconsole.log(data);"
          },
          {
            "lang": "PHP",
            "source": "<?php\n\n$ch = curl_init(\"https://api.sudomock.com/api/v1/webhook-endpoints/3fa85f64-5717-4562-b3fc-2c963f66afa6/test\");\ncurl_setopt($ch, CURLOPT_CUSTOMREQUEST, \"POST\");\ncurl_setopt($ch, CURLOPT_RETURNTRANSFER, true);\ncurl_setopt($ch, CURLOPT_HTTPHEADER, [\n    \"x-api-key: sm_your_api_key\",\n]);\n\n$response = curl_exec($ch);\ncurl_close($ch);\n\necho $response;"
          },
          {
            "lang": "Python",
            "source": "import requests\n\nresponse = requests.post(\n    \"https://api.sudomock.com/api/v1/webhook-endpoints/3fa85f64-5717-4562-b3fc-2c963f66afa6/test\",\n    headers={\"x-api-key\": \"sm_your_api_key\"},\n)\n\nresponse.raise_for_status()\nprint(response.json())"
          },
          {
            "lang": "Ruby",
            "source": "require \"net/http\"\nrequire \"uri\"\n\nuri = URI(\"https://api.sudomock.com/api/v1/webhook-endpoints/3fa85f64-5717-4562-b3fc-2c963f66afa6/test\")\nrequest = Net::HTTP::Post.new(uri)\nrequest[\"x-api-key\"] = \"sm_your_api_key\"\n\nresponse = Net::HTTP.start(uri.host, uri.port, use_ssl: true) do |http|\n  http.request(request)\nend\n\nputs response.body"
          },
          {
            "lang": "Go",
            "source": "package main\n\nimport (\n\t\"fmt\"\n\t\"io\"\n\t\"net/http\"\n)\n\nfunc main() {\n\treq, err := http.NewRequest(\"POST\", \"https://api.sudomock.com/api/v1/webhook-endpoints/3fa85f64-5717-4562-b3fc-2c963f66afa6/test\", nil)\n\tif err != nil {\n\t\tpanic(err)\n\t}\n\treq.Header.Set(\"x-api-key\", \"sm_your_api_key\")\n\n\tres, err := http.DefaultClient.Do(req)\n\tif err != nil {\n\t\tpanic(err)\n\t}\n\tdefer res.Body.Close()\n\n\tbody, _ := io.ReadAll(res.Body)\n\tfmt.Println(string(body))\n}"
          },
          {
            "lang": "Java",
            "source": "import java.net.URI;\nimport java.net.http.HttpClient;\nimport java.net.http.HttpRequest;\nimport java.net.http.HttpResponse;\n\nHttpRequest request = HttpRequest.newBuilder()\n    .uri(URI.create(\"https://api.sudomock.com/api/v1/webhook-endpoints/3fa85f64-5717-4562-b3fc-2c963f66afa6/test\"))\n    .header(\"x-api-key\", \"sm_your_api_key\")\n    .method(\"POST\", HttpRequest.BodyPublishers.noBody())\n    .build();\n\nHttpResponse<String> response = HttpClient.newHttpClient()\n    .send(request, HttpResponse.BodyHandlers.ofString());\n\nSystem.out.println(response.body());"
          },
          {
            "lang": ".NET",
            "source": "using System.Net.Http;\nusing System.Text;\n\nvar request = new HttpRequestMessage(HttpMethod.Post, \"https://api.sudomock.com/api/v1/webhook-endpoints/3fa85f64-5717-4562-b3fc-2c963f66afa6/test\");\nrequest.Headers.Add(\"x-api-key\", \"sm_your_api_key\");\n\nvar client = new HttpClient();\nvar response = await client.SendAsync(request);\n\nConsole.WriteLine(await response.Content.ReadAsStringAsync());"
          },
          {
            "lang": "cURL",
            "source": "curl -X POST \"https://api.sudomock.com/api/v1/webhook-endpoints/3fa85f64-5717-4562-b3fc-2c963f66afa6/test\" \\\n  -H \"x-api-key: sm_your_api_key\""
          }
        ]
      }
    },
    "/api/v1/webhook-endpoints/{endpoint_id}/deliveries": {
      "get": {
        "tags": [
          "Webhook deliveries"
        ],
        "summary": "Retrieve a list of deliveries",
        "description": "Delivery history for one endpoint, cursor-paginated. Filter by status or event type.",
        "operationId": "list_deliveries_api_v1_webhook_endpoints__endpoint_id__deliveries_get",
        "parameters": [
          {
            "name": "endpoint_id",
            "in": "path",
            "required": true,
            "schema": {
              "type": "string",
              "description": "Id of the endpoint whose delivery log is returned."
            },
            "description": "Id of the endpoint whose delivery log is returned."
          },
          {
            "name": "status",
            "in": "query",
            "required": false,
            "schema": {
              "type": "string",
              "description": "Keep only deliveries in this state, where failed also returns the ones marked dead."
            },
            "description": "Keep only deliveries in this state, where failed also returns the ones marked dead."
          },
          {
            "name": "event_type",
            "in": "query",
            "required": false,
            "schema": {
              "type": "string",
              "description": "Filter by event type. Either spelling of a photo-mockup event matches deliveries logged under the other."
            },
            "description": "Filter by event type. Either spelling of a photo-mockup event matches deliveries logged under the other."
          },
          {
            "name": "cursor",
            "in": "query",
            "required": false,
            "schema": {
              "type": "string",
              "description": "Token from the previous page's X-Webhook-Next-Cursor response header; omit it to start from the newest delivery."
            },
            "description": "Token from the previous page's X-Webhook-Next-Cursor response header; omit it to start from the newest delivery."
          },
          {
            "name": "limit",
            "in": "query",
            "required": false,
            "schema": {
              "type": "integer",
              "maximum": 200,
              "minimum": 1,
              "description": "How many deliveries one page returns, with the rest reachable through the next page's cursor.",
              "default": 50
            },
            "description": "How many deliveries one page returns, with the rest reachable through the next page's cursor."
          }
        ],
        "responses": {
          "200": {
            "description": "Successful Response",
            "content": {
              "application/json": {
                "schema": {
                  "type": "array",
                  "items": {
                    "$ref": "#/components/schemas/WebhookDeliveryResponse"
                  },
                  "title": "Response List Deliveries Api V1 Webhook Endpoints  Endpoint Id  Deliveries Get"
                }
              }
            },
            "headers": {
              "X-Webhook-Next-Cursor": {
                "description": "Opaque cursor for the next page; absent on the last page.",
                "schema": {
                  "type": "string"
                }
              }
            }
          }
        },
        "x-mint": {
          "metadata": {
            "sidebarTitle": "List endpoint deliveries"
          }
        },
        "security": [
          {
            "ApiKeyAuth": []
          }
        ],
        "x-codeSamples": [
          {
            "lang": "Node.js",
            "source": "const response = await fetch(\"https://api.sudomock.com/api/v1/webhook-endpoints/3fa85f64-5717-4562-b3fc-2c963f66afa6/deliveries\", {\n  method: \"GET\",\n  headers: { \"x-api-key\": \"sm_your_api_key\" },\n});\n\nconst data = await response.json();\nconsole.log(data);"
          },
          {
            "lang": "PHP",
            "source": "<?php\n\n$ch = curl_init(\"https://api.sudomock.com/api/v1/webhook-endpoints/3fa85f64-5717-4562-b3fc-2c963f66afa6/deliveries\");\ncurl_setopt($ch, CURLOPT_CUSTOMREQUEST, \"GET\");\ncurl_setopt($ch, CURLOPT_RETURNTRANSFER, true);\ncurl_setopt($ch, CURLOPT_HTTPHEADER, [\n    \"x-api-key: sm_your_api_key\",\n]);\n\n$response = curl_exec($ch);\ncurl_close($ch);\n\necho $response;"
          },
          {
            "lang": "Python",
            "source": "import requests\n\nresponse = requests.get(\n    \"https://api.sudomock.com/api/v1/webhook-endpoints/3fa85f64-5717-4562-b3fc-2c963f66afa6/deliveries\",\n    headers={\"x-api-key\": \"sm_your_api_key\"},\n)\n\nresponse.raise_for_status()\nprint(response.json())"
          },
          {
            "lang": "Ruby",
            "source": "require \"net/http\"\nrequire \"uri\"\n\nuri = URI(\"https://api.sudomock.com/api/v1/webhook-endpoints/3fa85f64-5717-4562-b3fc-2c963f66afa6/deliveries\")\nrequest = Net::HTTP::Get.new(uri)\nrequest[\"x-api-key\"] = \"sm_your_api_key\"\n\nresponse = Net::HTTP.start(uri.host, uri.port, use_ssl: true) do |http|\n  http.request(request)\nend\n\nputs response.body"
          },
          {
            "lang": "Go",
            "source": "package main\n\nimport (\n\t\"fmt\"\n\t\"io\"\n\t\"net/http\"\n)\n\nfunc main() {\n\treq, err := http.NewRequest(\"GET\", \"https://api.sudomock.com/api/v1/webhook-endpoints/3fa85f64-5717-4562-b3fc-2c963f66afa6/deliveries\", nil)\n\tif err != nil {\n\t\tpanic(err)\n\t}\n\treq.Header.Set(\"x-api-key\", \"sm_your_api_key\")\n\n\tres, err := http.DefaultClient.Do(req)\n\tif err != nil {\n\t\tpanic(err)\n\t}\n\tdefer res.Body.Close()\n\n\tbody, _ := io.ReadAll(res.Body)\n\tfmt.Println(string(body))\n}"
          },
          {
            "lang": "Java",
            "source": "import java.net.URI;\nimport java.net.http.HttpClient;\nimport java.net.http.HttpRequest;\nimport java.net.http.HttpResponse;\n\nHttpRequest request = HttpRequest.newBuilder()\n    .uri(URI.create(\"https://api.sudomock.com/api/v1/webhook-endpoints/3fa85f64-5717-4562-b3fc-2c963f66afa6/deliveries\"))\n    .header(\"x-api-key\", \"sm_your_api_key\")\n    .GET()\n    .build();\n\nHttpResponse<String> response = HttpClient.newHttpClient()\n    .send(request, HttpResponse.BodyHandlers.ofString());\n\nSystem.out.println(response.body());"
          },
          {
            "lang": ".NET",
            "source": "using System.Net.Http;\nusing System.Text;\n\nvar request = new HttpRequestMessage(HttpMethod.Get, \"https://api.sudomock.com/api/v1/webhook-endpoints/3fa85f64-5717-4562-b3fc-2c963f66afa6/deliveries\");\nrequest.Headers.Add(\"x-api-key\", \"sm_your_api_key\");\n\nvar client = new HttpClient();\nvar response = await client.SendAsync(request);\n\nConsole.WriteLine(await response.Content.ReadAsStringAsync());"
          },
          {
            "lang": "cURL",
            "source": "curl -X GET \"https://api.sudomock.com/api/v1/webhook-endpoints/3fa85f64-5717-4562-b3fc-2c963f66afa6/deliveries\" \\\n  -H \"x-api-key: sm_your_api_key\""
          }
        ]
      }
    },
    "/api/v1/webhook-endpoints/{endpoint_id}/deliveries/{delivery_id}": {
      "get": {
        "tags": [
          "Webhook deliveries"
        ],
        "summary": "Retrieve a single delivery",
        "description": "Full single delivery row including the captured request body + headers (every attempt) and, for failed/dead attempts, the response body + headers. The list endpoints never carry these large fields.",
        "operationId": "get_delivery_detail_api_v1_webhook_endpoints__endpoint_id__deliveries__delivery_id__get",
        "parameters": [
          {
            "name": "endpoint_id",
            "in": "path",
            "required": true,
            "schema": {
              "type": "string",
              "description": "Id of the endpoint the delivery belongs to."
            },
            "description": "Id of the endpoint the delivery belongs to."
          },
          {
            "name": "delivery_id",
            "in": "path",
            "required": true,
            "schema": {
              "type": "string",
              "description": "Id of the delivery, as listed in the delivery log."
            },
            "description": "Id of the delivery, as listed in the delivery log."
          }
        ],
        "responses": {
          "200": {
            "description": "Successful Response",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/WebhookDeliveryDetailResponse"
                }
              }
            }
          }
        },
        "x-mint": {
          "metadata": {
            "sidebarTitle": "Get delivery"
          }
        },
        "security": [
          {
            "ApiKeyAuth": []
          }
        ],
        "x-codeSamples": [
          {
            "lang": "Node.js",
            "source": "const response = await fetch(\"https://api.sudomock.com/api/v1/webhook-endpoints/3fa85f64-5717-4562-b3fc-2c963f66afa6/deliveries/3fa85f64-5717-4562-b3fc-2c963f66afa6\", {\n  method: \"GET\",\n  headers: { \"x-api-key\": \"sm_your_api_key\" },\n});\n\nconst data = await response.json();\nconsole.log(data);"
          },
          {
            "lang": "PHP",
            "source": "<?php\n\n$ch = curl_init(\"https://api.sudomock.com/api/v1/webhook-endpoints/3fa85f64-5717-4562-b3fc-2c963f66afa6/deliveries/3fa85f64-5717-4562-b3fc-2c963f66afa6\");\ncurl_setopt($ch, CURLOPT_CUSTOMREQUEST, \"GET\");\ncurl_setopt($ch, CURLOPT_RETURNTRANSFER, true);\ncurl_setopt($ch, CURLOPT_HTTPHEADER, [\n    \"x-api-key: sm_your_api_key\",\n]);\n\n$response = curl_exec($ch);\ncurl_close($ch);\n\necho $response;"
          },
          {
            "lang": "Python",
            "source": "import requests\n\nresponse = requests.get(\n    \"https://api.sudomock.com/api/v1/webhook-endpoints/3fa85f64-5717-4562-b3fc-2c963f66afa6/deliveries/3fa85f64-5717-4562-b3fc-2c963f66afa6\",\n    headers={\"x-api-key\": \"sm_your_api_key\"},\n)\n\nresponse.raise_for_status()\nprint(response.json())"
          },
          {
            "lang": "Ruby",
            "source": "require \"net/http\"\nrequire \"uri\"\n\nuri = URI(\"https://api.sudomock.com/api/v1/webhook-endpoints/3fa85f64-5717-4562-b3fc-2c963f66afa6/deliveries/3fa85f64-5717-4562-b3fc-2c963f66afa6\")\nrequest = Net::HTTP::Get.new(uri)\nrequest[\"x-api-key\"] = \"sm_your_api_key\"\n\nresponse = Net::HTTP.start(uri.host, uri.port, use_ssl: true) do |http|\n  http.request(request)\nend\n\nputs response.body"
          },
          {
            "lang": "Go",
            "source": "package main\n\nimport (\n\t\"fmt\"\n\t\"io\"\n\t\"net/http\"\n)\n\nfunc main() {\n\treq, err := http.NewRequest(\"GET\", \"https://api.sudomock.com/api/v1/webhook-endpoints/3fa85f64-5717-4562-b3fc-2c963f66afa6/deliveries/3fa85f64-5717-4562-b3fc-2c963f66afa6\", nil)\n\tif err != nil {\n\t\tpanic(err)\n\t}\n\treq.Header.Set(\"x-api-key\", \"sm_your_api_key\")\n\n\tres, err := http.DefaultClient.Do(req)\n\tif err != nil {\n\t\tpanic(err)\n\t}\n\tdefer res.Body.Close()\n\n\tbody, _ := io.ReadAll(res.Body)\n\tfmt.Println(string(body))\n}"
          },
          {
            "lang": "Java",
            "source": "import java.net.URI;\nimport java.net.http.HttpClient;\nimport java.net.http.HttpRequest;\nimport java.net.http.HttpResponse;\n\nHttpRequest request = HttpRequest.newBuilder()\n    .uri(URI.create(\"https://api.sudomock.com/api/v1/webhook-endpoints/3fa85f64-5717-4562-b3fc-2c963f66afa6/deliveries/3fa85f64-5717-4562-b3fc-2c963f66afa6\"))\n    .header(\"x-api-key\", \"sm_your_api_key\")\n    .GET()\n    .build();\n\nHttpResponse<String> response = HttpClient.newHttpClient()\n    .send(request, HttpResponse.BodyHandlers.ofString());\n\nSystem.out.println(response.body());"
          },
          {
            "lang": ".NET",
            "source": "using System.Net.Http;\nusing System.Text;\n\nvar request = new HttpRequestMessage(HttpMethod.Get, \"https://api.sudomock.com/api/v1/webhook-endpoints/3fa85f64-5717-4562-b3fc-2c963f66afa6/deliveries/3fa85f64-5717-4562-b3fc-2c963f66afa6\");\nrequest.Headers.Add(\"x-api-key\", \"sm_your_api_key\");\n\nvar client = new HttpClient();\nvar response = await client.SendAsync(request);\n\nConsole.WriteLine(await response.Content.ReadAsStringAsync());"
          },
          {
            "lang": "cURL",
            "source": "curl -X GET \"https://api.sudomock.com/api/v1/webhook-endpoints/3fa85f64-5717-4562-b3fc-2c963f66afa6/deliveries/3fa85f64-5717-4562-b3fc-2c963f66afa6\" \\\n  -H \"x-api-key: sm_your_api_key\""
          }
        ]
      }
    },
    "/api/v1/webhook-endpoints/{endpoint_id}/deliveries/{delivery_id}/replay": {
      "post": {
        "tags": [
          "Webhook deliveries"
        ],
        "summary": "Replay a single delivery",
        "description": "Re-send a single delivery. Replays are idempotent, so re-sending is always safe.",
        "operationId": "replay_delivery_api_v1_webhook_endpoints__endpoint_id__deliveries__delivery_id__replay_post",
        "parameters": [
          {
            "name": "endpoint_id",
            "in": "path",
            "required": true,
            "schema": {
              "type": "string",
              "description": "Id of the endpoint the delivery belongs to."
            },
            "description": "Id of the endpoint the delivery belongs to."
          },
          {
            "name": "delivery_id",
            "in": "path",
            "required": true,
            "schema": {
              "type": "string",
              "description": "Id of the delivery to send again."
            },
            "description": "Id of the delivery to send again."
          }
        ],
        "responses": {
          "202": {
            "description": "Successful Response",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/WebhookDeliveryReplayResponse"
                }
              }
            }
          }
        },
        "x-mint": {
          "metadata": {
            "sidebarTitle": "Replay delivery"
          }
        },
        "security": [
          {
            "ApiKeyAuth": []
          }
        ],
        "x-codeSamples": [
          {
            "lang": "Node.js",
            "source": "const response = await fetch(\"https://api.sudomock.com/api/v1/webhook-endpoints/3fa85f64-5717-4562-b3fc-2c963f66afa6/deliveries/3fa85f64-5717-4562-b3fc-2c963f66afa6/replay\", {\n  method: \"POST\",\n  headers: { \"x-api-key\": \"sm_your_api_key\" },\n});\n\nconst data = await response.json();\nconsole.log(data);"
          },
          {
            "lang": "PHP",
            "source": "<?php\n\n$ch = curl_init(\"https://api.sudomock.com/api/v1/webhook-endpoints/3fa85f64-5717-4562-b3fc-2c963f66afa6/deliveries/3fa85f64-5717-4562-b3fc-2c963f66afa6/replay\");\ncurl_setopt($ch, CURLOPT_CUSTOMREQUEST, \"POST\");\ncurl_setopt($ch, CURLOPT_RETURNTRANSFER, true);\ncurl_setopt($ch, CURLOPT_HTTPHEADER, [\n    \"x-api-key: sm_your_api_key\",\n]);\n\n$response = curl_exec($ch);\ncurl_close($ch);\n\necho $response;"
          },
          {
            "lang": "Python",
            "source": "import requests\n\nresponse = requests.post(\n    \"https://api.sudomock.com/api/v1/webhook-endpoints/3fa85f64-5717-4562-b3fc-2c963f66afa6/deliveries/3fa85f64-5717-4562-b3fc-2c963f66afa6/replay\",\n    headers={\"x-api-key\": \"sm_your_api_key\"},\n)\n\nresponse.raise_for_status()\nprint(response.json())"
          },
          {
            "lang": "Ruby",
            "source": "require \"net/http\"\nrequire \"uri\"\n\nuri = URI(\"https://api.sudomock.com/api/v1/webhook-endpoints/3fa85f64-5717-4562-b3fc-2c963f66afa6/deliveries/3fa85f64-5717-4562-b3fc-2c963f66afa6/replay\")\nrequest = Net::HTTP::Post.new(uri)\nrequest[\"x-api-key\"] = \"sm_your_api_key\"\n\nresponse = Net::HTTP.start(uri.host, uri.port, use_ssl: true) do |http|\n  http.request(request)\nend\n\nputs response.body"
          },
          {
            "lang": "Go",
            "source": "package main\n\nimport (\n\t\"fmt\"\n\t\"io\"\n\t\"net/http\"\n)\n\nfunc main() {\n\treq, err := http.NewRequest(\"POST\", \"https://api.sudomock.com/api/v1/webhook-endpoints/3fa85f64-5717-4562-b3fc-2c963f66afa6/deliveries/3fa85f64-5717-4562-b3fc-2c963f66afa6/replay\", nil)\n\tif err != nil {\n\t\tpanic(err)\n\t}\n\treq.Header.Set(\"x-api-key\", \"sm_your_api_key\")\n\n\tres, err := http.DefaultClient.Do(req)\n\tif err != nil {\n\t\tpanic(err)\n\t}\n\tdefer res.Body.Close()\n\n\tbody, _ := io.ReadAll(res.Body)\n\tfmt.Println(string(body))\n}"
          },
          {
            "lang": "Java",
            "source": "import java.net.URI;\nimport java.net.http.HttpClient;\nimport java.net.http.HttpRequest;\nimport java.net.http.HttpResponse;\n\nHttpRequest request = HttpRequest.newBuilder()\n    .uri(URI.create(\"https://api.sudomock.com/api/v1/webhook-endpoints/3fa85f64-5717-4562-b3fc-2c963f66afa6/deliveries/3fa85f64-5717-4562-b3fc-2c963f66afa6/replay\"))\n    .header(\"x-api-key\", \"sm_your_api_key\")\n    .method(\"POST\", HttpRequest.BodyPublishers.noBody())\n    .build();\n\nHttpResponse<String> response = HttpClient.newHttpClient()\n    .send(request, HttpResponse.BodyHandlers.ofString());\n\nSystem.out.println(response.body());"
          },
          {
            "lang": ".NET",
            "source": "using System.Net.Http;\nusing System.Text;\n\nvar request = new HttpRequestMessage(HttpMethod.Post, \"https://api.sudomock.com/api/v1/webhook-endpoints/3fa85f64-5717-4562-b3fc-2c963f66afa6/deliveries/3fa85f64-5717-4562-b3fc-2c963f66afa6/replay\");\nrequest.Headers.Add(\"x-api-key\", \"sm_your_api_key\");\n\nvar client = new HttpClient();\nvar response = await client.SendAsync(request);\n\nConsole.WriteLine(await response.Content.ReadAsStringAsync());"
          },
          {
            "lang": "cURL",
            "source": "curl -X POST \"https://api.sudomock.com/api/v1/webhook-endpoints/3fa85f64-5717-4562-b3fc-2c963f66afa6/deliveries/3fa85f64-5717-4562-b3fc-2c963f66afa6/replay\" \\\n  -H \"x-api-key: sm_your_api_key\""
          }
        ]
      }
    },
    "/api/v1/webhook-endpoints/{endpoint_id}/deliveries/replay-failed": {
      "post": {
        "tags": [
          "Webhook deliveries"
        ],
        "summary": "Replay all failed deliveries",
        "description": "Re-send every failed delivery on one endpoint in a single call. The request is accepted and the deliveries follow.",
        "operationId": "replay_failed_deliveries_api_v1_webhook_endpoints__endpoint_id__deliveries_replay_failed_post",
        "parameters": [
          {
            "name": "endpoint_id",
            "in": "path",
            "required": true,
            "schema": {
              "type": "string",
              "description": "Id of the endpoint whose failed deliveries are all sent again."
            },
            "description": "Id of the endpoint whose failed deliveries are all sent again."
          }
        ],
        "responses": {
          "202": {
            "description": "Successful Response",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/WebhookDeliveryReplayFailedResponse"
                }
              }
            }
          }
        },
        "x-mint": {
          "metadata": {
            "sidebarTitle": "Replay failed deliveries"
          }
        },
        "security": [
          {
            "ApiKeyAuth": []
          }
        ],
        "x-codeSamples": [
          {
            "lang": "Node.js",
            "source": "const response = await fetch(\"https://api.sudomock.com/api/v1/webhook-endpoints/3fa85f64-5717-4562-b3fc-2c963f66afa6/deliveries/replay-failed\", {\n  method: \"POST\",\n  headers: { \"x-api-key\": \"sm_your_api_key\" },\n});\n\nconst data = await response.json();\nconsole.log(data);"
          },
          {
            "lang": "PHP",
            "source": "<?php\n\n$ch = curl_init(\"https://api.sudomock.com/api/v1/webhook-endpoints/3fa85f64-5717-4562-b3fc-2c963f66afa6/deliveries/replay-failed\");\ncurl_setopt($ch, CURLOPT_CUSTOMREQUEST, \"POST\");\ncurl_setopt($ch, CURLOPT_RETURNTRANSFER, true);\ncurl_setopt($ch, CURLOPT_HTTPHEADER, [\n    \"x-api-key: sm_your_api_key\",\n]);\n\n$response = curl_exec($ch);\ncurl_close($ch);\n\necho $response;"
          },
          {
            "lang": "Python",
            "source": "import requests\n\nresponse = requests.post(\n    \"https://api.sudomock.com/api/v1/webhook-endpoints/3fa85f64-5717-4562-b3fc-2c963f66afa6/deliveries/replay-failed\",\n    headers={\"x-api-key\": \"sm_your_api_key\"},\n)\n\nresponse.raise_for_status()\nprint(response.json())"
          },
          {
            "lang": "Ruby",
            "source": "require \"net/http\"\nrequire \"uri\"\n\nuri = URI(\"https://api.sudomock.com/api/v1/webhook-endpoints/3fa85f64-5717-4562-b3fc-2c963f66afa6/deliveries/replay-failed\")\nrequest = Net::HTTP::Post.new(uri)\nrequest[\"x-api-key\"] = \"sm_your_api_key\"\n\nresponse = Net::HTTP.start(uri.host, uri.port, use_ssl: true) do |http|\n  http.request(request)\nend\n\nputs response.body"
          },
          {
            "lang": "Go",
            "source": "package main\n\nimport (\n\t\"fmt\"\n\t\"io\"\n\t\"net/http\"\n)\n\nfunc main() {\n\treq, err := http.NewRequest(\"POST\", \"https://api.sudomock.com/api/v1/webhook-endpoints/3fa85f64-5717-4562-b3fc-2c963f66afa6/deliveries/replay-failed\", nil)\n\tif err != nil {\n\t\tpanic(err)\n\t}\n\treq.Header.Set(\"x-api-key\", \"sm_your_api_key\")\n\n\tres, err := http.DefaultClient.Do(req)\n\tif err != nil {\n\t\tpanic(err)\n\t}\n\tdefer res.Body.Close()\n\n\tbody, _ := io.ReadAll(res.Body)\n\tfmt.Println(string(body))\n}"
          },
          {
            "lang": "Java",
            "source": "import java.net.URI;\nimport java.net.http.HttpClient;\nimport java.net.http.HttpRequest;\nimport java.net.http.HttpResponse;\n\nHttpRequest request = HttpRequest.newBuilder()\n    .uri(URI.create(\"https://api.sudomock.com/api/v1/webhook-endpoints/3fa85f64-5717-4562-b3fc-2c963f66afa6/deliveries/replay-failed\"))\n    .header(\"x-api-key\", \"sm_your_api_key\")\n    .method(\"POST\", HttpRequest.BodyPublishers.noBody())\n    .build();\n\nHttpResponse<String> response = HttpClient.newHttpClient()\n    .send(request, HttpResponse.BodyHandlers.ofString());\n\nSystem.out.println(response.body());"
          },
          {
            "lang": ".NET",
            "source": "using System.Net.Http;\nusing System.Text;\n\nvar request = new HttpRequestMessage(HttpMethod.Post, \"https://api.sudomock.com/api/v1/webhook-endpoints/3fa85f64-5717-4562-b3fc-2c963f66afa6/deliveries/replay-failed\");\nrequest.Headers.Add(\"x-api-key\", \"sm_your_api_key\");\n\nvar client = new HttpClient();\nvar response = await client.SendAsync(request);\n\nConsole.WriteLine(await response.Content.ReadAsStringAsync());"
          },
          {
            "lang": "cURL",
            "source": "curl -X POST \"https://api.sudomock.com/api/v1/webhook-endpoints/3fa85f64-5717-4562-b3fc-2c963f66afa6/deliveries/replay-failed\" \\\n  -H \"x-api-key: sm_your_api_key\""
          }
        ]
      }
    },
    "/api/v1/psd-mockups": {
      "get": {
        "tags": [
          "PSD mockups"
        ],
        "summary": "Retrieve a list of PSD mockups",
        "description": "List your mockups, with pagination, filtering and sorting.",
        "operationId": "list_mockups_api_v1_psd_mockups_get",
        "parameters": [
          {
            "name": "limit",
            "in": "query",
            "required": false,
            "schema": {
              "type": "integer",
              "maximum": 100,
              "minimum": 1,
              "description": "Number of mockups to return (1-100)",
              "default": 20
            },
            "description": "Number of mockups to return (1-100)"
          },
          {
            "name": "offset",
            "in": "query",
            "required": false,
            "schema": {
              "type": "integer",
              "minimum": 0,
              "description": "Number of mockups to skip",
              "default": 0
            },
            "description": "Number of mockups to skip"
          },
          {
            "name": "name",
            "in": "query",
            "required": false,
            "schema": {
              "type": "string",
              "description": "Filter mockups by name (case-insensitive contains)"
            },
            "description": "Filter mockups by name (case-insensitive contains)"
          },
          {
            "name": "created_after",
            "in": "query",
            "required": false,
            "schema": {
              "type": "string",
              "format": "date-time",
              "description": "Filter mockups created after this date (ISO 8601)"
            },
            "description": "Filter mockups created after this date (ISO 8601)"
          },
          {
            "name": "created_before",
            "in": "query",
            "required": false,
            "schema": {
              "type": "string",
              "format": "date-time",
              "description": "Filter mockups created before this date (ISO 8601)"
            },
            "description": "Filter mockups created before this date (ISO 8601)"
          },
          {
            "name": "sort",
            "in": "query",
            "required": false,
            "schema": {
              "type": "string",
              "pattern": "^(name|created_at|updated_at)$",
              "description": "Field to sort by",
              "default": "created_at"
            },
            "description": "Field to sort by"
          },
          {
            "name": "order",
            "in": "query",
            "required": false,
            "schema": {
              "type": "string",
              "pattern": "^(asc|desc)$",
              "description": "Sort order",
              "default": "desc"
            },
            "description": "Sort order"
          }
        ],
        "responses": {
          "200": {
            "description": "Successful Response",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/MockupListResponse"
                }
              }
            }
          }
        },
        "x-mint": {
          "metadata": {
            "sidebarTitle": "List PSD mockups"
          }
        },
        "security": [
          {
            "ApiKeyAuth": []
          }
        ],
        "x-codeSamples": [
          {
            "lang": "Node.js",
            "source": "const response = await fetch(\"https://api.sudomock.com/api/v1/psd-mockups\", {\n  method: \"GET\",\n  headers: { \"x-api-key\": \"sm_your_api_key\" },\n});\n\nconst data = await response.json();\nconsole.log(data);"
          },
          {
            "lang": "PHP",
            "source": "<?php\n\n$ch = curl_init(\"https://api.sudomock.com/api/v1/psd-mockups\");\ncurl_setopt($ch, CURLOPT_CUSTOMREQUEST, \"GET\");\ncurl_setopt($ch, CURLOPT_RETURNTRANSFER, true);\ncurl_setopt($ch, CURLOPT_HTTPHEADER, [\n    \"x-api-key: sm_your_api_key\",\n]);\n\n$response = curl_exec($ch);\ncurl_close($ch);\n\necho $response;"
          },
          {
            "lang": "Python",
            "source": "import requests\n\nresponse = requests.get(\n    \"https://api.sudomock.com/api/v1/psd-mockups\",\n    headers={\"x-api-key\": \"sm_your_api_key\"},\n)\n\nresponse.raise_for_status()\nprint(response.json())"
          },
          {
            "lang": "Ruby",
            "source": "require \"net/http\"\nrequire \"uri\"\n\nuri = URI(\"https://api.sudomock.com/api/v1/psd-mockups\")\nrequest = Net::HTTP::Get.new(uri)\nrequest[\"x-api-key\"] = \"sm_your_api_key\"\n\nresponse = Net::HTTP.start(uri.host, uri.port, use_ssl: true) do |http|\n  http.request(request)\nend\n\nputs response.body"
          },
          {
            "lang": "Go",
            "source": "package main\n\nimport (\n\t\"fmt\"\n\t\"io\"\n\t\"net/http\"\n)\n\nfunc main() {\n\treq, err := http.NewRequest(\"GET\", \"https://api.sudomock.com/api/v1/psd-mockups\", nil)\n\tif err != nil {\n\t\tpanic(err)\n\t}\n\treq.Header.Set(\"x-api-key\", \"sm_your_api_key\")\n\n\tres, err := http.DefaultClient.Do(req)\n\tif err != nil {\n\t\tpanic(err)\n\t}\n\tdefer res.Body.Close()\n\n\tbody, _ := io.ReadAll(res.Body)\n\tfmt.Println(string(body))\n}"
          },
          {
            "lang": "Java",
            "source": "import java.net.URI;\nimport java.net.http.HttpClient;\nimport java.net.http.HttpRequest;\nimport java.net.http.HttpResponse;\n\nHttpRequest request = HttpRequest.newBuilder()\n    .uri(URI.create(\"https://api.sudomock.com/api/v1/psd-mockups\"))\n    .header(\"x-api-key\", \"sm_your_api_key\")\n    .GET()\n    .build();\n\nHttpResponse<String> response = HttpClient.newHttpClient()\n    .send(request, HttpResponse.BodyHandlers.ofString());\n\nSystem.out.println(response.body());"
          },
          {
            "lang": ".NET",
            "source": "using System.Net.Http;\nusing System.Text;\n\nvar request = new HttpRequestMessage(HttpMethod.Get, \"https://api.sudomock.com/api/v1/psd-mockups\");\nrequest.Headers.Add(\"x-api-key\", \"sm_your_api_key\");\n\nvar client = new HttpClient();\nvar response = await client.SendAsync(request);\n\nConsole.WriteLine(await response.Content.ReadAsStringAsync());"
          },
          {
            "lang": "cURL",
            "source": "curl -X GET \"https://api.sudomock.com/api/v1/psd-mockups\" \\\n  -H \"x-api-key: sm_your_api_key\""
          }
        ]
      }
    },
    "/api/v1/psd-mockups/{uuid}": {
      "get": {
        "tags": [
          "PSD mockups"
        ],
        "summary": "Retrieve a single PSD mockup",
        "description": "Read one mockup. The body matches what the upload endpoint returns.",
        "operationId": "get_mockup_detail_api_v1_psd_mockups__uuid__get",
        "parameters": [
          {
            "name": "uuid",
            "in": "path",
            "required": true,
            "schema": {
              "type": "string",
              "minLength": 36,
              "description": "Mockup UUID"
            },
            "description": "Mockup UUID"
          }
        ],
        "responses": {
          "200": {
            "description": "Successful Response",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/UploadResponse"
                }
              }
            }
          }
        },
        "x-mint": {
          "metadata": {
            "sidebarTitle": "Get PSD mockup"
          }
        },
        "security": [
          {
            "ApiKeyAuth": []
          }
        ],
        "x-codeSamples": [
          {
            "lang": "Node.js",
            "source": "const response = await fetch(\"https://api.sudomock.com/api/v1/psd-mockups/3fa85f64-5717-4562-b3fc-2c963f66afa6\", {\n  method: \"GET\",\n  headers: { \"x-api-key\": \"sm_your_api_key\" },\n});\n\nconst data = await response.json();\nconsole.log(data);"
          },
          {
            "lang": "PHP",
            "source": "<?php\n\n$ch = curl_init(\"https://api.sudomock.com/api/v1/psd-mockups/3fa85f64-5717-4562-b3fc-2c963f66afa6\");\ncurl_setopt($ch, CURLOPT_CUSTOMREQUEST, \"GET\");\ncurl_setopt($ch, CURLOPT_RETURNTRANSFER, true);\ncurl_setopt($ch, CURLOPT_HTTPHEADER, [\n    \"x-api-key: sm_your_api_key\",\n]);\n\n$response = curl_exec($ch);\ncurl_close($ch);\n\necho $response;"
          },
          {
            "lang": "Python",
            "source": "import requests\n\nresponse = requests.get(\n    \"https://api.sudomock.com/api/v1/psd-mockups/3fa85f64-5717-4562-b3fc-2c963f66afa6\",\n    headers={\"x-api-key\": \"sm_your_api_key\"},\n)\n\nresponse.raise_for_status()\nprint(response.json())"
          },
          {
            "lang": "Ruby",
            "source": "require \"net/http\"\nrequire \"uri\"\n\nuri = URI(\"https://api.sudomock.com/api/v1/psd-mockups/3fa85f64-5717-4562-b3fc-2c963f66afa6\")\nrequest = Net::HTTP::Get.new(uri)\nrequest[\"x-api-key\"] = \"sm_your_api_key\"\n\nresponse = Net::HTTP.start(uri.host, uri.port, use_ssl: true) do |http|\n  http.request(request)\nend\n\nputs response.body"
          },
          {
            "lang": "Go",
            "source": "package main\n\nimport (\n\t\"fmt\"\n\t\"io\"\n\t\"net/http\"\n)\n\nfunc main() {\n\treq, err := http.NewRequest(\"GET\", \"https://api.sudomock.com/api/v1/psd-mockups/3fa85f64-5717-4562-b3fc-2c963f66afa6\", nil)\n\tif err != nil {\n\t\tpanic(err)\n\t}\n\treq.Header.Set(\"x-api-key\", \"sm_your_api_key\")\n\n\tres, err := http.DefaultClient.Do(req)\n\tif err != nil {\n\t\tpanic(err)\n\t}\n\tdefer res.Body.Close()\n\n\tbody, _ := io.ReadAll(res.Body)\n\tfmt.Println(string(body))\n}"
          },
          {
            "lang": "Java",
            "source": "import java.net.URI;\nimport java.net.http.HttpClient;\nimport java.net.http.HttpRequest;\nimport java.net.http.HttpResponse;\n\nHttpRequest request = HttpRequest.newBuilder()\n    .uri(URI.create(\"https://api.sudomock.com/api/v1/psd-mockups/3fa85f64-5717-4562-b3fc-2c963f66afa6\"))\n    .header(\"x-api-key\", \"sm_your_api_key\")\n    .GET()\n    .build();\n\nHttpResponse<String> response = HttpClient.newHttpClient()\n    .send(request, HttpResponse.BodyHandlers.ofString());\n\nSystem.out.println(response.body());"
          },
          {
            "lang": ".NET",
            "source": "using System.Net.Http;\nusing System.Text;\n\nvar request = new HttpRequestMessage(HttpMethod.Get, \"https://api.sudomock.com/api/v1/psd-mockups/3fa85f64-5717-4562-b3fc-2c963f66afa6\");\nrequest.Headers.Add(\"x-api-key\", \"sm_your_api_key\");\n\nvar client = new HttpClient();\nvar response = await client.SendAsync(request);\n\nConsole.WriteLine(await response.Content.ReadAsStringAsync());"
          },
          {
            "lang": "cURL",
            "source": "curl -X GET \"https://api.sudomock.com/api/v1/psd-mockups/3fa85f64-5717-4562-b3fc-2c963f66afa6\" \\\n  -H \"x-api-key: sm_your_api_key\""
          }
        ]
      },
      "patch": {
        "tags": [
          "PSD mockups"
        ],
        "summary": "Update an existing PSD mockup",
        "description": "Rename a mockup, or set the colours it answers to by name.",
        "operationId": "update_mockup_api_v1_psd_mockups__uuid__patch",
        "parameters": [
          {
            "name": "uuid",
            "in": "path",
            "required": true,
            "schema": {
              "type": "string",
              "minLength": 36,
              "description": "Mockup UUID"
            },
            "description": "Mockup UUID"
          }
        ],
        "requestBody": {
          "required": true,
          "content": {
            "application/json": {
              "schema": {
                "$ref": "#/components/schemas/MockupUpdateRequest"
              }
            }
          }
        },
        "responses": {
          "200": {
            "description": "Successful Response",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/UploadResponse"
                }
              }
            }
          }
        },
        "x-mint": {
          "metadata": {
            "sidebarTitle": "Update PSD mockup"
          }
        },
        "security": [
          {
            "ApiKeyAuth": []
          }
        ],
        "x-codeSamples": [
          {
            "lang": "Node.js",
            "source": "const response = await fetch(\"https://api.sudomock.com/api/v1/psd-mockups/3fa85f64-5717-4562-b3fc-2c963f66afa6\", {\n  method: \"PATCH\",\n  headers: {\n    \"x-api-key\": \"sm_your_api_key\",\n    \"Content-Type\": \"application/json\",\n  },\n  body: JSON.stringify({\n    \"name\": \"Updated Mockup Name\"\n  }),\n});\n\nconst data = await response.json();\nconsole.log(data);"
          },
          {
            "lang": "PHP",
            "source": "<?php\n\n$payload = <<<'JSON'\n{\n  \"name\": \"Updated Mockup Name\"\n}\nJSON;\n\n$ch = curl_init(\"https://api.sudomock.com/api/v1/psd-mockups/3fa85f64-5717-4562-b3fc-2c963f66afa6\");\ncurl_setopt($ch, CURLOPT_CUSTOMREQUEST, \"PATCH\");\ncurl_setopt($ch, CURLOPT_RETURNTRANSFER, true);\ncurl_setopt($ch, CURLOPT_HTTPHEADER, [\n    \"x-api-key: sm_your_api_key\",\n    \"Content-Type: application/json\",\n]);\ncurl_setopt($ch, CURLOPT_POSTFIELDS, $payload);\n\n$response = curl_exec($ch);\ncurl_close($ch);\n\necho $response;"
          },
          {
            "lang": "Python",
            "source": "import requests\n\npayload = {\n    \"name\": \"Updated Mockup Name\"\n}\n\nresponse = requests.patch(\n    \"https://api.sudomock.com/api/v1/psd-mockups/3fa85f64-5717-4562-b3fc-2c963f66afa6\",\n    headers={\"x-api-key\": \"sm_your_api_key\"},\n    json=payload,\n)\n\nresponse.raise_for_status()\nprint(response.json())"
          },
          {
            "lang": "Ruby",
            "source": "require \"net/http\"\nrequire \"uri\"\n\nuri = URI(\"https://api.sudomock.com/api/v1/psd-mockups/3fa85f64-5717-4562-b3fc-2c963f66afa6\")\nrequest = Net::HTTP::Patch.new(uri)\nrequest[\"x-api-key\"] = \"sm_your_api_key\"\nrequest[\"Content-Type\"] = \"application/json\"\n\nrequest.body = <<~JSON\n  {\n    \"name\": \"Updated Mockup Name\"\n  }\nJSON\n\nresponse = Net::HTTP.start(uri.host, uri.port, use_ssl: true) do |http|\n  http.request(request)\nend\n\nputs response.body"
          },
          {
            "lang": "Go",
            "source": "package main\n\nimport (\n\t\"bytes\"\n\t\"fmt\"\n\t\"io\"\n\t\"net/http\"\n)\n\nfunc main() {\n\tpayload := []byte(`{\n  \"name\": \"Updated Mockup Name\"\n}`)\n\n\treq, err := http.NewRequest(\"PATCH\", \"https://api.sudomock.com/api/v1/psd-mockups/3fa85f64-5717-4562-b3fc-2c963f66afa6\", bytes.NewBuffer(payload))\n\tif err != nil {\n\t\tpanic(err)\n\t}\n\treq.Header.Set(\"x-api-key\", \"sm_your_api_key\")\n\treq.Header.Set(\"Content-Type\", \"application/json\")\n\n\tres, err := http.DefaultClient.Do(req)\n\tif err != nil {\n\t\tpanic(err)\n\t}\n\tdefer res.Body.Close()\n\n\tbody, _ := io.ReadAll(res.Body)\n\tfmt.Println(string(body))\n}"
          },
          {
            "lang": "Java",
            "source": "import java.net.URI;\nimport java.net.http.HttpClient;\nimport java.net.http.HttpRequest;\nimport java.net.http.HttpResponse;\n\nString payload = \"\"\"\n{\n  \"name\": \"Updated Mockup Name\"\n}\n\"\"\";\n\nHttpRequest request = HttpRequest.newBuilder()\n    .uri(URI.create(\"https://api.sudomock.com/api/v1/psd-mockups/3fa85f64-5717-4562-b3fc-2c963f66afa6\"))\n    .header(\"x-api-key\", \"sm_your_api_key\")\n    .header(\"Content-Type\", \"application/json\")\n    .method(\"PATCH\", HttpRequest.BodyPublishers.ofString(payload))\n    .build();\n\nHttpResponse<String> response = HttpClient.newHttpClient()\n    .send(request, HttpResponse.BodyHandlers.ofString());\n\nSystem.out.println(response.body());"
          },
          {
            "lang": ".NET",
            "source": "using System.Net.Http;\nusing System.Text;\n\nvar payload = \"\"\"\n{\n  \"name\": \"Updated Mockup Name\"\n}\n\"\"\";\n\nvar request = new HttpRequestMessage(HttpMethod.Patch, \"https://api.sudomock.com/api/v1/psd-mockups/3fa85f64-5717-4562-b3fc-2c963f66afa6\");\nrequest.Headers.Add(\"x-api-key\", \"sm_your_api_key\");\nrequest.Content = new StringContent(payload, Encoding.UTF8, \"application/json\");\n\nvar client = new HttpClient();\nvar response = await client.SendAsync(request);\n\nConsole.WriteLine(await response.Content.ReadAsStringAsync());"
          },
          {
            "lang": "cURL",
            "source": "curl -X PATCH \"https://api.sudomock.com/api/v1/psd-mockups/3fa85f64-5717-4562-b3fc-2c963f66afa6\" \\\n  -H \"x-api-key: sm_your_api_key\" \\\n  -H \"Content-Type: application/json\" \\\n  -d '{\n    \"name\": \"Updated Mockup Name\"\n  }'"
          }
        ]
      }
    },
    "/api/v1/psd-mockups/{uuid}/layers": {
      "get": {
        "tags": [
          "PSD mockups"
        ],
        "summary": "Retrieve the layers of a PSD mockup",
        "description": "Read every layer of a mockup, nested the way Photoshop's Layers panel shows them and listed front-most first. A smart object whose contents hold layers you can fill lists those layers as its children. Send a layer's uuid in hidden_layers on POST /api/v1/renders to leave that layer out of a render.",
        "operationId": "get_mockup_layers_api_v1_psd_mockups__uuid__layers_get",
        "parameters": [
          {
            "name": "uuid",
            "in": "path",
            "required": true,
            "schema": {
              "type": "string",
              "minLength": 36,
              "description": "Mockup UUID",
              "examples": [
                "123e4567-e89b-12d3-a456-426614174000"
              ]
            },
            "description": "Mockup UUID"
          }
        ],
        "responses": {
          "200": {
            "description": "Successful Response",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/MockupLayersResponse"
                }
              }
            }
          }
        },
        "x-mint": {
          "metadata": {
            "sidebarTitle": "Get PSD mockup layers"
          }
        },
        "security": [
          {
            "ApiKeyAuth": []
          }
        ],
        "x-codeSamples": [
          {
            "lang": "Node.js",
            "source": "const response = await fetch(\"https://api.sudomock.com/api/v1/psd-mockups/123e4567-e89b-12d3-a456-426614174000/layers\", {\n  method: \"GET\",\n  headers: { \"x-api-key\": \"sm_your_api_key\" },\n});\n\nconst data = await response.json();\nconsole.log(data);"
          },
          {
            "lang": "PHP",
            "source": "<?php\n\n$ch = curl_init(\"https://api.sudomock.com/api/v1/psd-mockups/123e4567-e89b-12d3-a456-426614174000/layers\");\ncurl_setopt($ch, CURLOPT_CUSTOMREQUEST, \"GET\");\ncurl_setopt($ch, CURLOPT_RETURNTRANSFER, true);\ncurl_setopt($ch, CURLOPT_HTTPHEADER, [\n    \"x-api-key: sm_your_api_key\",\n]);\n\n$response = curl_exec($ch);\ncurl_close($ch);\n\necho $response;"
          },
          {
            "lang": "Python",
            "source": "import requests\n\nresponse = requests.get(\n    \"https://api.sudomock.com/api/v1/psd-mockups/123e4567-e89b-12d3-a456-426614174000/layers\",\n    headers={\"x-api-key\": \"sm_your_api_key\"},\n)\n\nresponse.raise_for_status()\nprint(response.json())"
          },
          {
            "lang": "Ruby",
            "source": "require \"net/http\"\nrequire \"uri\"\n\nuri = URI(\"https://api.sudomock.com/api/v1/psd-mockups/123e4567-e89b-12d3-a456-426614174000/layers\")\nrequest = Net::HTTP::Get.new(uri)\nrequest[\"x-api-key\"] = \"sm_your_api_key\"\n\nresponse = Net::HTTP.start(uri.host, uri.port, use_ssl: true) do |http|\n  http.request(request)\nend\n\nputs response.body"
          },
          {
            "lang": "Go",
            "source": "package main\n\nimport (\n\t\"fmt\"\n\t\"io\"\n\t\"net/http\"\n)\n\nfunc main() {\n\treq, err := http.NewRequest(\"GET\", \"https://api.sudomock.com/api/v1/psd-mockups/123e4567-e89b-12d3-a456-426614174000/layers\", nil)\n\tif err != nil {\n\t\tpanic(err)\n\t}\n\treq.Header.Set(\"x-api-key\", \"sm_your_api_key\")\n\n\tres, err := http.DefaultClient.Do(req)\n\tif err != nil {\n\t\tpanic(err)\n\t}\n\tdefer res.Body.Close()\n\n\tbody, _ := io.ReadAll(res.Body)\n\tfmt.Println(string(body))\n}"
          },
          {
            "lang": "Java",
            "source": "import java.net.URI;\nimport java.net.http.HttpClient;\nimport java.net.http.HttpRequest;\nimport java.net.http.HttpResponse;\n\nHttpRequest request = HttpRequest.newBuilder()\n    .uri(URI.create(\"https://api.sudomock.com/api/v1/psd-mockups/123e4567-e89b-12d3-a456-426614174000/layers\"))\n    .header(\"x-api-key\", \"sm_your_api_key\")\n    .GET()\n    .build();\n\nHttpResponse<String> response = HttpClient.newHttpClient()\n    .send(request, HttpResponse.BodyHandlers.ofString());\n\nSystem.out.println(response.body());"
          },
          {
            "lang": ".NET",
            "source": "using System.Net.Http;\nusing System.Text;\n\nvar request = new HttpRequestMessage(HttpMethod.Get, \"https://api.sudomock.com/api/v1/psd-mockups/123e4567-e89b-12d3-a456-426614174000/layers\");\nrequest.Headers.Add(\"x-api-key\", \"sm_your_api_key\");\n\nvar client = new HttpClient();\nvar response = await client.SendAsync(request);\n\nConsole.WriteLine(await response.Content.ReadAsStringAsync());"
          },
          {
            "lang": "cURL",
            "source": "curl -X GET \"https://api.sudomock.com/api/v1/psd-mockups/123e4567-e89b-12d3-a456-426614174000/layers\" \\\n  -H \"x-api-key: sm_your_api_key\""
          }
        ]
      }
    },
    "/api/v1/psd-mockups/{mockup_uuid}": {
      "delete": {
        "tags": [
          "PSD mockups"
        ],
        "summary": "Remove an existing PSD mockup",
        "description": "Delete a mockup and the files that belong to it. This cannot be undone.",
        "operationId": "delete_mockup_api_v1_psd_mockups__mockup_uuid__delete",
        "parameters": [
          {
            "name": "mockup_uuid",
            "in": "path",
            "required": true,
            "schema": {
              "type": "string",
              "minLength": 36,
              "description": "Mockup UUID to delete"
            },
            "description": "Mockup UUID to delete"
          }
        ],
        "responses": {
          "204": {
            "description": "Mockup deleted successfully"
          }
        },
        "x-mint": {
          "metadata": {
            "sidebarTitle": "Delete PSD mockup"
          }
        },
        "security": [
          {
            "ApiKeyAuth": []
          }
        ],
        "x-codeSamples": [
          {
            "lang": "Node.js",
            "source": "const response = await fetch(\"https://api.sudomock.com/api/v1/psd-mockups/3fa85f64-5717-4562-b3fc-2c963f66afa6\", {\n  method: \"DELETE\",\n  headers: { \"x-api-key\": \"sm_your_api_key\" },\n});\n\nconst data = await response.json();\nconsole.log(data);"
          },
          {
            "lang": "PHP",
            "source": "<?php\n\n$ch = curl_init(\"https://api.sudomock.com/api/v1/psd-mockups/3fa85f64-5717-4562-b3fc-2c963f66afa6\");\ncurl_setopt($ch, CURLOPT_CUSTOMREQUEST, \"DELETE\");\ncurl_setopt($ch, CURLOPT_RETURNTRANSFER, true);\ncurl_setopt($ch, CURLOPT_HTTPHEADER, [\n    \"x-api-key: sm_your_api_key\",\n]);\n\n$response = curl_exec($ch);\ncurl_close($ch);\n\necho $response;"
          },
          {
            "lang": "Python",
            "source": "import requests\n\nresponse = requests.delete(\n    \"https://api.sudomock.com/api/v1/psd-mockups/3fa85f64-5717-4562-b3fc-2c963f66afa6\",\n    headers={\"x-api-key\": \"sm_your_api_key\"},\n)\n\nresponse.raise_for_status()\nprint(response.json())"
          },
          {
            "lang": "Ruby",
            "source": "require \"net/http\"\nrequire \"uri\"\n\nuri = URI(\"https://api.sudomock.com/api/v1/psd-mockups/3fa85f64-5717-4562-b3fc-2c963f66afa6\")\nrequest = Net::HTTP::Delete.new(uri)\nrequest[\"x-api-key\"] = \"sm_your_api_key\"\n\nresponse = Net::HTTP.start(uri.host, uri.port, use_ssl: true) do |http|\n  http.request(request)\nend\n\nputs response.body"
          },
          {
            "lang": "Go",
            "source": "package main\n\nimport (\n\t\"fmt\"\n\t\"io\"\n\t\"net/http\"\n)\n\nfunc main() {\n\treq, err := http.NewRequest(\"DELETE\", \"https://api.sudomock.com/api/v1/psd-mockups/3fa85f64-5717-4562-b3fc-2c963f66afa6\", nil)\n\tif err != nil {\n\t\tpanic(err)\n\t}\n\treq.Header.Set(\"x-api-key\", \"sm_your_api_key\")\n\n\tres, err := http.DefaultClient.Do(req)\n\tif err != nil {\n\t\tpanic(err)\n\t}\n\tdefer res.Body.Close()\n\n\tbody, _ := io.ReadAll(res.Body)\n\tfmt.Println(string(body))\n}"
          },
          {
            "lang": "Java",
            "source": "import java.net.URI;\nimport java.net.http.HttpClient;\nimport java.net.http.HttpRequest;\nimport java.net.http.HttpResponse;\n\nHttpRequest request = HttpRequest.newBuilder()\n    .uri(URI.create(\"https://api.sudomock.com/api/v1/psd-mockups/3fa85f64-5717-4562-b3fc-2c963f66afa6\"))\n    .header(\"x-api-key\", \"sm_your_api_key\")\n    .DELETE()\n    .build();\n\nHttpResponse<String> response = HttpClient.newHttpClient()\n    .send(request, HttpResponse.BodyHandlers.ofString());\n\nSystem.out.println(response.body());"
          },
          {
            "lang": ".NET",
            "source": "using System.Net.Http;\nusing System.Text;\n\nvar request = new HttpRequestMessage(HttpMethod.Delete, \"https://api.sudomock.com/api/v1/psd-mockups/3fa85f64-5717-4562-b3fc-2c963f66afa6\");\nrequest.Headers.Add(\"x-api-key\", \"sm_your_api_key\");\n\nvar client = new HttpClient();\nvar response = await client.SendAsync(request);\n\nConsole.WriteLine(await response.Content.ReadAsStringAsync());"
          },
          {
            "lang": "cURL",
            "source": "curl -X DELETE \"https://api.sudomock.com/api/v1/psd-mockups/3fa85f64-5717-4562-b3fc-2c963f66afa6\" \\\n  -H \"x-api-key: sm_your_api_key\""
          }
        ]
      }
    },
    "/api/v1/mockups": {
      "get": {
        "tags": [
          "PSD mockups"
        ],
        "summary": "Retrieve a list of PSD mockups",
        "description": "List your mockups, with pagination, filtering and sorting.",
        "operationId": "list_mockups_api_v1_mockups_get",
        "deprecated": true,
        "parameters": [
          {
            "name": "limit",
            "in": "query",
            "required": false,
            "schema": {
              "type": "integer",
              "maximum": 100,
              "minimum": 1,
              "description": "Number of mockups to return (1-100)",
              "default": 20
            },
            "description": "Number of mockups to return (1-100)"
          },
          {
            "name": "offset",
            "in": "query",
            "required": false,
            "schema": {
              "type": "integer",
              "minimum": 0,
              "description": "Number of mockups to skip",
              "default": 0
            },
            "description": "Number of mockups to skip"
          },
          {
            "name": "name",
            "in": "query",
            "required": false,
            "schema": {
              "type": "string",
              "description": "Filter mockups by name (case-insensitive contains)"
            },
            "description": "Filter mockups by name (case-insensitive contains)"
          },
          {
            "name": "created_after",
            "in": "query",
            "required": false,
            "schema": {
              "type": "string",
              "format": "date-time",
              "description": "Filter mockups created after this date (ISO 8601)"
            },
            "description": "Filter mockups created after this date (ISO 8601)"
          },
          {
            "name": "created_before",
            "in": "query",
            "required": false,
            "schema": {
              "type": "string",
              "format": "date-time",
              "description": "Filter mockups created before this date (ISO 8601)"
            },
            "description": "Filter mockups created before this date (ISO 8601)"
          },
          {
            "name": "sort",
            "in": "query",
            "required": false,
            "schema": {
              "type": "string",
              "pattern": "^(name|created_at|updated_at)$",
              "description": "Field to sort by",
              "default": "created_at"
            },
            "description": "Field to sort by"
          },
          {
            "name": "order",
            "in": "query",
            "required": false,
            "schema": {
              "type": "string",
              "pattern": "^(asc|desc)$",
              "description": "Sort order",
              "default": "desc"
            },
            "description": "Sort order"
          }
        ],
        "responses": {
          "200": {
            "description": "Successful Response",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/MockupListResponse"
                }
              }
            }
          }
        },
        "x-mint": {
          "metadata": {
            "sidebarTitle": "List PSD mockups"
          }
        },
        "security": [
          {
            "ApiKeyAuth": []
          }
        ],
        "x-codeSamples": [
          {
            "lang": "Node.js",
            "source": "const response = await fetch(\"https://api.sudomock.com/api/v1/mockups\", {\n  method: \"GET\",\n  headers: { \"x-api-key\": \"sm_your_api_key\" },\n});\n\nconst data = await response.json();\nconsole.log(data);"
          },
          {
            "lang": "PHP",
            "source": "<?php\n\n$ch = curl_init(\"https://api.sudomock.com/api/v1/mockups\");\ncurl_setopt($ch, CURLOPT_CUSTOMREQUEST, \"GET\");\ncurl_setopt($ch, CURLOPT_RETURNTRANSFER, true);\ncurl_setopt($ch, CURLOPT_HTTPHEADER, [\n    \"x-api-key: sm_your_api_key\",\n]);\n\n$response = curl_exec($ch);\ncurl_close($ch);\n\necho $response;"
          },
          {
            "lang": "Python",
            "source": "import requests\n\nresponse = requests.get(\n    \"https://api.sudomock.com/api/v1/mockups\",\n    headers={\"x-api-key\": \"sm_your_api_key\"},\n)\n\nresponse.raise_for_status()\nprint(response.json())"
          },
          {
            "lang": "Ruby",
            "source": "require \"net/http\"\nrequire \"uri\"\n\nuri = URI(\"https://api.sudomock.com/api/v1/mockups\")\nrequest = Net::HTTP::Get.new(uri)\nrequest[\"x-api-key\"] = \"sm_your_api_key\"\n\nresponse = Net::HTTP.start(uri.host, uri.port, use_ssl: true) do |http|\n  http.request(request)\nend\n\nputs response.body"
          },
          {
            "lang": "Go",
            "source": "package main\n\nimport (\n\t\"fmt\"\n\t\"io\"\n\t\"net/http\"\n)\n\nfunc main() {\n\treq, err := http.NewRequest(\"GET\", \"https://api.sudomock.com/api/v1/mockups\", nil)\n\tif err != nil {\n\t\tpanic(err)\n\t}\n\treq.Header.Set(\"x-api-key\", \"sm_your_api_key\")\n\n\tres, err := http.DefaultClient.Do(req)\n\tif err != nil {\n\t\tpanic(err)\n\t}\n\tdefer res.Body.Close()\n\n\tbody, _ := io.ReadAll(res.Body)\n\tfmt.Println(string(body))\n}"
          },
          {
            "lang": "Java",
            "source": "import java.net.URI;\nimport java.net.http.HttpClient;\nimport java.net.http.HttpRequest;\nimport java.net.http.HttpResponse;\n\nHttpRequest request = HttpRequest.newBuilder()\n    .uri(URI.create(\"https://api.sudomock.com/api/v1/mockups\"))\n    .header(\"x-api-key\", \"sm_your_api_key\")\n    .GET()\n    .build();\n\nHttpResponse<String> response = HttpClient.newHttpClient()\n    .send(request, HttpResponse.BodyHandlers.ofString());\n\nSystem.out.println(response.body());"
          },
          {
            "lang": ".NET",
            "source": "using System.Net.Http;\nusing System.Text;\n\nvar request = new HttpRequestMessage(HttpMethod.Get, \"https://api.sudomock.com/api/v1/mockups\");\nrequest.Headers.Add(\"x-api-key\", \"sm_your_api_key\");\n\nvar client = new HttpClient();\nvar response = await client.SendAsync(request);\n\nConsole.WriteLine(await response.Content.ReadAsStringAsync());"
          },
          {
            "lang": "cURL",
            "source": "curl -X GET \"https://api.sudomock.com/api/v1/mockups\" \\\n  -H \"x-api-key: sm_your_api_key\""
          }
        ],
        "x-hidden": true
      }
    },
    "/api/v1/mockups/{uuid}": {
      "get": {
        "tags": [
          "PSD mockups"
        ],
        "summary": "Retrieve a single PSD mockup",
        "description": "Read one mockup. The body matches what the upload endpoint returns.",
        "operationId": "get_mockup_detail_api_v1_mockups__uuid__get",
        "deprecated": true,
        "parameters": [
          {
            "name": "uuid",
            "in": "path",
            "required": true,
            "schema": {
              "type": "string",
              "minLength": 36,
              "description": "Mockup UUID"
            },
            "description": "Mockup UUID"
          }
        ],
        "responses": {
          "200": {
            "description": "Successful Response",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/UploadResponse"
                }
              }
            }
          }
        },
        "x-mint": {
          "metadata": {
            "sidebarTitle": "Get PSD mockup"
          }
        },
        "security": [
          {
            "ApiKeyAuth": []
          }
        ],
        "x-codeSamples": [
          {
            "lang": "Node.js",
            "source": "const response = await fetch(\"https://api.sudomock.com/api/v1/mockups/3fa85f64-5717-4562-b3fc-2c963f66afa6\", {\n  method: \"GET\",\n  headers: { \"x-api-key\": \"sm_your_api_key\" },\n});\n\nconst data = await response.json();\nconsole.log(data);"
          },
          {
            "lang": "PHP",
            "source": "<?php\n\n$ch = curl_init(\"https://api.sudomock.com/api/v1/mockups/3fa85f64-5717-4562-b3fc-2c963f66afa6\");\ncurl_setopt($ch, CURLOPT_CUSTOMREQUEST, \"GET\");\ncurl_setopt($ch, CURLOPT_RETURNTRANSFER, true);\ncurl_setopt($ch, CURLOPT_HTTPHEADER, [\n    \"x-api-key: sm_your_api_key\",\n]);\n\n$response = curl_exec($ch);\ncurl_close($ch);\n\necho $response;"
          },
          {
            "lang": "Python",
            "source": "import requests\n\nresponse = requests.get(\n    \"https://api.sudomock.com/api/v1/mockups/3fa85f64-5717-4562-b3fc-2c963f66afa6\",\n    headers={\"x-api-key\": \"sm_your_api_key\"},\n)\n\nresponse.raise_for_status()\nprint(response.json())"
          },
          {
            "lang": "Ruby",
            "source": "require \"net/http\"\nrequire \"uri\"\n\nuri = URI(\"https://api.sudomock.com/api/v1/mockups/3fa85f64-5717-4562-b3fc-2c963f66afa6\")\nrequest = Net::HTTP::Get.new(uri)\nrequest[\"x-api-key\"] = \"sm_your_api_key\"\n\nresponse = Net::HTTP.start(uri.host, uri.port, use_ssl: true) do |http|\n  http.request(request)\nend\n\nputs response.body"
          },
          {
            "lang": "Go",
            "source": "package main\n\nimport (\n\t\"fmt\"\n\t\"io\"\n\t\"net/http\"\n)\n\nfunc main() {\n\treq, err := http.NewRequest(\"GET\", \"https://api.sudomock.com/api/v1/mockups/3fa85f64-5717-4562-b3fc-2c963f66afa6\", nil)\n\tif err != nil {\n\t\tpanic(err)\n\t}\n\treq.Header.Set(\"x-api-key\", \"sm_your_api_key\")\n\n\tres, err := http.DefaultClient.Do(req)\n\tif err != nil {\n\t\tpanic(err)\n\t}\n\tdefer res.Body.Close()\n\n\tbody, _ := io.ReadAll(res.Body)\n\tfmt.Println(string(body))\n}"
          },
          {
            "lang": "Java",
            "source": "import java.net.URI;\nimport java.net.http.HttpClient;\nimport java.net.http.HttpRequest;\nimport java.net.http.HttpResponse;\n\nHttpRequest request = HttpRequest.newBuilder()\n    .uri(URI.create(\"https://api.sudomock.com/api/v1/mockups/3fa85f64-5717-4562-b3fc-2c963f66afa6\"))\n    .header(\"x-api-key\", \"sm_your_api_key\")\n    .GET()\n    .build();\n\nHttpResponse<String> response = HttpClient.newHttpClient()\n    .send(request, HttpResponse.BodyHandlers.ofString());\n\nSystem.out.println(response.body());"
          },
          {
            "lang": ".NET",
            "source": "using System.Net.Http;\nusing System.Text;\n\nvar request = new HttpRequestMessage(HttpMethod.Get, \"https://api.sudomock.com/api/v1/mockups/3fa85f64-5717-4562-b3fc-2c963f66afa6\");\nrequest.Headers.Add(\"x-api-key\", \"sm_your_api_key\");\n\nvar client = new HttpClient();\nvar response = await client.SendAsync(request);\n\nConsole.WriteLine(await response.Content.ReadAsStringAsync());"
          },
          {
            "lang": "cURL",
            "source": "curl -X GET \"https://api.sudomock.com/api/v1/mockups/3fa85f64-5717-4562-b3fc-2c963f66afa6\" \\\n  -H \"x-api-key: sm_your_api_key\""
          }
        ],
        "x-hidden": true
      },
      "patch": {
        "tags": [
          "PSD mockups"
        ],
        "summary": "Update an existing PSD mockup",
        "description": "Rename a mockup, or set the colours it answers to by name.",
        "operationId": "update_mockup_api_v1_mockups__uuid__patch",
        "deprecated": true,
        "parameters": [
          {
            "name": "uuid",
            "in": "path",
            "required": true,
            "schema": {
              "type": "string",
              "minLength": 36,
              "description": "Mockup UUID"
            },
            "description": "Mockup UUID"
          }
        ],
        "requestBody": {
          "required": true,
          "content": {
            "application/json": {
              "schema": {
                "$ref": "#/components/schemas/MockupUpdateRequest"
              }
            }
          }
        },
        "responses": {
          "200": {
            "description": "Successful Response",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/UploadResponse"
                }
              }
            }
          }
        },
        "x-mint": {
          "metadata": {
            "sidebarTitle": "Update PSD mockup"
          }
        },
        "security": [
          {
            "ApiKeyAuth": []
          }
        ],
        "x-codeSamples": [
          {
            "lang": "Node.js",
            "source": "const response = await fetch(\"https://api.sudomock.com/api/v1/mockups/3fa85f64-5717-4562-b3fc-2c963f66afa6\", {\n  method: \"PATCH\",\n  headers: {\n    \"x-api-key\": \"sm_your_api_key\",\n    \"Content-Type\": \"application/json\",\n  },\n  body: JSON.stringify({\n    \"name\": \"Updated Mockup Name\"\n  }),\n});\n\nconst data = await response.json();\nconsole.log(data);"
          },
          {
            "lang": "PHP",
            "source": "<?php\n\n$payload = <<<'JSON'\n{\n  \"name\": \"Updated Mockup Name\"\n}\nJSON;\n\n$ch = curl_init(\"https://api.sudomock.com/api/v1/mockups/3fa85f64-5717-4562-b3fc-2c963f66afa6\");\ncurl_setopt($ch, CURLOPT_CUSTOMREQUEST, \"PATCH\");\ncurl_setopt($ch, CURLOPT_RETURNTRANSFER, true);\ncurl_setopt($ch, CURLOPT_HTTPHEADER, [\n    \"x-api-key: sm_your_api_key\",\n    \"Content-Type: application/json\",\n]);\ncurl_setopt($ch, CURLOPT_POSTFIELDS, $payload);\n\n$response = curl_exec($ch);\ncurl_close($ch);\n\necho $response;"
          },
          {
            "lang": "Python",
            "source": "import requests\n\npayload = {\n    \"name\": \"Updated Mockup Name\"\n}\n\nresponse = requests.patch(\n    \"https://api.sudomock.com/api/v1/mockups/3fa85f64-5717-4562-b3fc-2c963f66afa6\",\n    headers={\"x-api-key\": \"sm_your_api_key\"},\n    json=payload,\n)\n\nresponse.raise_for_status()\nprint(response.json())"
          },
          {
            "lang": "Ruby",
            "source": "require \"net/http\"\nrequire \"uri\"\n\nuri = URI(\"https://api.sudomock.com/api/v1/mockups/3fa85f64-5717-4562-b3fc-2c963f66afa6\")\nrequest = Net::HTTP::Patch.new(uri)\nrequest[\"x-api-key\"] = \"sm_your_api_key\"\nrequest[\"Content-Type\"] = \"application/json\"\n\nrequest.body = <<~JSON\n  {\n    \"name\": \"Updated Mockup Name\"\n  }\nJSON\n\nresponse = Net::HTTP.start(uri.host, uri.port, use_ssl: true) do |http|\n  http.request(request)\nend\n\nputs response.body"
          },
          {
            "lang": "Go",
            "source": "package main\n\nimport (\n\t\"bytes\"\n\t\"fmt\"\n\t\"io\"\n\t\"net/http\"\n)\n\nfunc main() {\n\tpayload := []byte(`{\n  \"name\": \"Updated Mockup Name\"\n}`)\n\n\treq, err := http.NewRequest(\"PATCH\", \"https://api.sudomock.com/api/v1/mockups/3fa85f64-5717-4562-b3fc-2c963f66afa6\", bytes.NewBuffer(payload))\n\tif err != nil {\n\t\tpanic(err)\n\t}\n\treq.Header.Set(\"x-api-key\", \"sm_your_api_key\")\n\treq.Header.Set(\"Content-Type\", \"application/json\")\n\n\tres, err := http.DefaultClient.Do(req)\n\tif err != nil {\n\t\tpanic(err)\n\t}\n\tdefer res.Body.Close()\n\n\tbody, _ := io.ReadAll(res.Body)\n\tfmt.Println(string(body))\n}"
          },
          {
            "lang": "Java",
            "source": "import java.net.URI;\nimport java.net.http.HttpClient;\nimport java.net.http.HttpRequest;\nimport java.net.http.HttpResponse;\n\nString payload = \"\"\"\n{\n  \"name\": \"Updated Mockup Name\"\n}\n\"\"\";\n\nHttpRequest request = HttpRequest.newBuilder()\n    .uri(URI.create(\"https://api.sudomock.com/api/v1/mockups/3fa85f64-5717-4562-b3fc-2c963f66afa6\"))\n    .header(\"x-api-key\", \"sm_your_api_key\")\n    .header(\"Content-Type\", \"application/json\")\n    .method(\"PATCH\", HttpRequest.BodyPublishers.ofString(payload))\n    .build();\n\nHttpResponse<String> response = HttpClient.newHttpClient()\n    .send(request, HttpResponse.BodyHandlers.ofString());\n\nSystem.out.println(response.body());"
          },
          {
            "lang": ".NET",
            "source": "using System.Net.Http;\nusing System.Text;\n\nvar payload = \"\"\"\n{\n  \"name\": \"Updated Mockup Name\"\n}\n\"\"\";\n\nvar request = new HttpRequestMessage(HttpMethod.Patch, \"https://api.sudomock.com/api/v1/mockups/3fa85f64-5717-4562-b3fc-2c963f66afa6\");\nrequest.Headers.Add(\"x-api-key\", \"sm_your_api_key\");\nrequest.Content = new StringContent(payload, Encoding.UTF8, \"application/json\");\n\nvar client = new HttpClient();\nvar response = await client.SendAsync(request);\n\nConsole.WriteLine(await response.Content.ReadAsStringAsync());"
          },
          {
            "lang": "cURL",
            "source": "curl -X PATCH \"https://api.sudomock.com/api/v1/mockups/3fa85f64-5717-4562-b3fc-2c963f66afa6\" \\\n  -H \"x-api-key: sm_your_api_key\" \\\n  -H \"Content-Type: application/json\" \\\n  -d '{\n    \"name\": \"Updated Mockup Name\"\n  }'"
          }
        ],
        "x-hidden": true
      }
    },
    "/api/v1/mockups/{uuid}/layers": {
      "get": {
        "tags": [
          "PSD mockups"
        ],
        "summary": "Retrieve the layers of a PSD mockup",
        "description": "Read every layer of a mockup, nested the way Photoshop's Layers panel shows them and listed front-most first. A smart object whose contents hold layers you can fill lists those layers as its children. Send a layer's uuid in hidden_layers on POST /api/v1/renders to leave that layer out of a render.",
        "operationId": "get_mockup_layers_api_v1_mockups__uuid__layers_get",
        "deprecated": true,
        "parameters": [
          {
            "name": "uuid",
            "in": "path",
            "required": true,
            "schema": {
              "type": "string",
              "minLength": 36,
              "description": "Mockup UUID",
              "examples": [
                "123e4567-e89b-12d3-a456-426614174000"
              ]
            },
            "description": "Mockup UUID"
          }
        ],
        "responses": {
          "200": {
            "description": "Successful Response",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/MockupLayersResponse"
                }
              }
            }
          }
        },
        "x-mint": {
          "metadata": {
            "sidebarTitle": "Get PSD mockup layers"
          }
        },
        "security": [
          {
            "ApiKeyAuth": []
          }
        ],
        "x-codeSamples": [
          {
            "lang": "Node.js",
            "source": "const response = await fetch(\"https://api.sudomock.com/api/v1/mockups/123e4567-e89b-12d3-a456-426614174000/layers\", {\n  method: \"GET\",\n  headers: { \"x-api-key\": \"sm_your_api_key\" },\n});\n\nconst data = await response.json();\nconsole.log(data);"
          },
          {
            "lang": "PHP",
            "source": "<?php\n\n$ch = curl_init(\"https://api.sudomock.com/api/v1/mockups/123e4567-e89b-12d3-a456-426614174000/layers\");\ncurl_setopt($ch, CURLOPT_CUSTOMREQUEST, \"GET\");\ncurl_setopt($ch, CURLOPT_RETURNTRANSFER, true);\ncurl_setopt($ch, CURLOPT_HTTPHEADER, [\n    \"x-api-key: sm_your_api_key\",\n]);\n\n$response = curl_exec($ch);\ncurl_close($ch);\n\necho $response;"
          },
          {
            "lang": "Python",
            "source": "import requests\n\nresponse = requests.get(\n    \"https://api.sudomock.com/api/v1/mockups/123e4567-e89b-12d3-a456-426614174000/layers\",\n    headers={\"x-api-key\": \"sm_your_api_key\"},\n)\n\nresponse.raise_for_status()\nprint(response.json())"
          },
          {
            "lang": "Ruby",
            "source": "require \"net/http\"\nrequire \"uri\"\n\nuri = URI(\"https://api.sudomock.com/api/v1/mockups/123e4567-e89b-12d3-a456-426614174000/layers\")\nrequest = Net::HTTP::Get.new(uri)\nrequest[\"x-api-key\"] = \"sm_your_api_key\"\n\nresponse = Net::HTTP.start(uri.host, uri.port, use_ssl: true) do |http|\n  http.request(request)\nend\n\nputs response.body"
          },
          {
            "lang": "Go",
            "source": "package main\n\nimport (\n\t\"fmt\"\n\t\"io\"\n\t\"net/http\"\n)\n\nfunc main() {\n\treq, err := http.NewRequest(\"GET\", \"https://api.sudomock.com/api/v1/mockups/123e4567-e89b-12d3-a456-426614174000/layers\", nil)\n\tif err != nil {\n\t\tpanic(err)\n\t}\n\treq.Header.Set(\"x-api-key\", \"sm_your_api_key\")\n\n\tres, err := http.DefaultClient.Do(req)\n\tif err != nil {\n\t\tpanic(err)\n\t}\n\tdefer res.Body.Close()\n\n\tbody, _ := io.ReadAll(res.Body)\n\tfmt.Println(string(body))\n}"
          },
          {
            "lang": "Java",
            "source": "import java.net.URI;\nimport java.net.http.HttpClient;\nimport java.net.http.HttpRequest;\nimport java.net.http.HttpResponse;\n\nHttpRequest request = HttpRequest.newBuilder()\n    .uri(URI.create(\"https://api.sudomock.com/api/v1/mockups/123e4567-e89b-12d3-a456-426614174000/layers\"))\n    .header(\"x-api-key\", \"sm_your_api_key\")\n    .GET()\n    .build();\n\nHttpResponse<String> response = HttpClient.newHttpClient()\n    .send(request, HttpResponse.BodyHandlers.ofString());\n\nSystem.out.println(response.body());"
          },
          {
            "lang": ".NET",
            "source": "using System.Net.Http;\nusing System.Text;\n\nvar request = new HttpRequestMessage(HttpMethod.Get, \"https://api.sudomock.com/api/v1/mockups/123e4567-e89b-12d3-a456-426614174000/layers\");\nrequest.Headers.Add(\"x-api-key\", \"sm_your_api_key\");\n\nvar client = new HttpClient();\nvar response = await client.SendAsync(request);\n\nConsole.WriteLine(await response.Content.ReadAsStringAsync());"
          },
          {
            "lang": "cURL",
            "source": "curl -X GET \"https://api.sudomock.com/api/v1/mockups/123e4567-e89b-12d3-a456-426614174000/layers\" \\\n  -H \"x-api-key: sm_your_api_key\""
          }
        ],
        "x-hidden": true
      }
    },
    "/api/v1/mockups/{mockup_uuid}": {
      "delete": {
        "tags": [
          "PSD mockups"
        ],
        "summary": "Remove an existing PSD mockup",
        "description": "Delete a mockup and the files that belong to it. This cannot be undone.",
        "operationId": "delete_mockup_api_v1_mockups__mockup_uuid__delete",
        "deprecated": true,
        "parameters": [
          {
            "name": "mockup_uuid",
            "in": "path",
            "required": true,
            "schema": {
              "type": "string",
              "minLength": 36,
              "description": "Mockup UUID to delete"
            },
            "description": "Mockup UUID to delete"
          }
        ],
        "responses": {
          "204": {
            "description": "Mockup deleted successfully"
          }
        },
        "x-mint": {
          "metadata": {
            "sidebarTitle": "Delete PSD mockup"
          }
        },
        "security": [
          {
            "ApiKeyAuth": []
          }
        ],
        "x-codeSamples": [
          {
            "lang": "Node.js",
            "source": "const response = await fetch(\"https://api.sudomock.com/api/v1/mockups/3fa85f64-5717-4562-b3fc-2c963f66afa6\", {\n  method: \"DELETE\",\n  headers: { \"x-api-key\": \"sm_your_api_key\" },\n});\n\nconst data = await response.json();\nconsole.log(data);"
          },
          {
            "lang": "PHP",
            "source": "<?php\n\n$ch = curl_init(\"https://api.sudomock.com/api/v1/mockups/3fa85f64-5717-4562-b3fc-2c963f66afa6\");\ncurl_setopt($ch, CURLOPT_CUSTOMREQUEST, \"DELETE\");\ncurl_setopt($ch, CURLOPT_RETURNTRANSFER, true);\ncurl_setopt($ch, CURLOPT_HTTPHEADER, [\n    \"x-api-key: sm_your_api_key\",\n]);\n\n$response = curl_exec($ch);\ncurl_close($ch);\n\necho $response;"
          },
          {
            "lang": "Python",
            "source": "import requests\n\nresponse = requests.delete(\n    \"https://api.sudomock.com/api/v1/mockups/3fa85f64-5717-4562-b3fc-2c963f66afa6\",\n    headers={\"x-api-key\": \"sm_your_api_key\"},\n)\n\nresponse.raise_for_status()\nprint(response.json())"
          },
          {
            "lang": "Ruby",
            "source": "require \"net/http\"\nrequire \"uri\"\n\nuri = URI(\"https://api.sudomock.com/api/v1/mockups/3fa85f64-5717-4562-b3fc-2c963f66afa6\")\nrequest = Net::HTTP::Delete.new(uri)\nrequest[\"x-api-key\"] = \"sm_your_api_key\"\n\nresponse = Net::HTTP.start(uri.host, uri.port, use_ssl: true) do |http|\n  http.request(request)\nend\n\nputs response.body"
          },
          {
            "lang": "Go",
            "source": "package main\n\nimport (\n\t\"fmt\"\n\t\"io\"\n\t\"net/http\"\n)\n\nfunc main() {\n\treq, err := http.NewRequest(\"DELETE\", \"https://api.sudomock.com/api/v1/mockups/3fa85f64-5717-4562-b3fc-2c963f66afa6\", nil)\n\tif err != nil {\n\t\tpanic(err)\n\t}\n\treq.Header.Set(\"x-api-key\", \"sm_your_api_key\")\n\n\tres, err := http.DefaultClient.Do(req)\n\tif err != nil {\n\t\tpanic(err)\n\t}\n\tdefer res.Body.Close()\n\n\tbody, _ := io.ReadAll(res.Body)\n\tfmt.Println(string(body))\n}"
          },
          {
            "lang": "Java",
            "source": "import java.net.URI;\nimport java.net.http.HttpClient;\nimport java.net.http.HttpRequest;\nimport java.net.http.HttpResponse;\n\nHttpRequest request = HttpRequest.newBuilder()\n    .uri(URI.create(\"https://api.sudomock.com/api/v1/mockups/3fa85f64-5717-4562-b3fc-2c963f66afa6\"))\n    .header(\"x-api-key\", \"sm_your_api_key\")\n    .DELETE()\n    .build();\n\nHttpResponse<String> response = HttpClient.newHttpClient()\n    .send(request, HttpResponse.BodyHandlers.ofString());\n\nSystem.out.println(response.body());"
          },
          {
            "lang": ".NET",
            "source": "using System.Net.Http;\nusing System.Text;\n\nvar request = new HttpRequestMessage(HttpMethod.Delete, \"https://api.sudomock.com/api/v1/mockups/3fa85f64-5717-4562-b3fc-2c963f66afa6\");\nrequest.Headers.Add(\"x-api-key\", \"sm_your_api_key\");\n\nvar client = new HttpClient();\nvar response = await client.SendAsync(request);\n\nConsole.WriteLine(await response.Content.ReadAsStringAsync());"
          },
          {
            "lang": "cURL",
            "source": "curl -X DELETE \"https://api.sudomock.com/api/v1/mockups/3fa85f64-5717-4562-b3fc-2c963f66afa6\" \\\n  -H \"x-api-key: sm_your_api_key\""
          }
        ],
        "x-hidden": true
      }
    },
    "/api/v1/fonts": {
      "get": {
        "tags": [
          "Fonts"
        ],
        "summary": "Retrieve a list of fonts",
        "description": "List available fonts for text layers: the shared system catalog plus your own uploaded fonts. Supports search, category filtering, and pagination.",
        "operationId": "list_fonts_api_v1_fonts_get",
        "parameters": [
          {
            "name": "page",
            "in": "query",
            "required": false,
            "schema": {
              "type": "integer",
              "minimum": 1,
              "description": "Page number (1-based)",
              "default": 1
            },
            "description": "Page number (1-based)"
          },
          {
            "name": "per_page",
            "in": "query",
            "required": false,
            "schema": {
              "type": "integer",
              "maximum": 100,
              "minimum": 1,
              "description": "Results per page (1-100)",
              "default": 50
            },
            "description": "Results per page (1-100)"
          },
          {
            "name": "category",
            "in": "query",
            "required": false,
            "schema": {
              "type": "string",
              "description": "Filter by category, e.g. 'serif'"
            },
            "description": "Filter by category, e.g. 'serif'"
          },
          {
            "name": "search",
            "in": "query",
            "required": false,
            "schema": {
              "type": "string",
              "description": "Filter by family name (case-insensitive contains)"
            },
            "description": "Filter by family name (case-insensitive contains)"
          },
          {
            "name": "scope",
            "in": "query",
            "required": false,
            "schema": {
              "type": "string",
              "pattern": "^(all|system|custom)$",
              "description": "Which fonts to return: 'all' (system + yours), 'system', or 'custom' (yours only)",
              "default": "all"
            },
            "description": "Which fonts to return: 'all' (system + yours), 'system', or 'custom' (yours only)"
          }
        ],
        "responses": {
          "200": {
            "description": "Successful Response",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/FontListResponse"
                }
              }
            }
          }
        },
        "security": [
          {
            "ApiKeyAuth": []
          }
        ],
        "x-codeSamples": [
          {
            "lang": "Node.js",
            "source": "const response = await fetch(\"https://api.sudomock.com/api/v1/fonts\", {\n  method: \"GET\",\n  headers: { \"x-api-key\": \"sm_your_api_key\" },\n});\n\nconst data = await response.json();\nconsole.log(data);"
          },
          {
            "lang": "PHP",
            "source": "<?php\n\n$ch = curl_init(\"https://api.sudomock.com/api/v1/fonts\");\ncurl_setopt($ch, CURLOPT_CUSTOMREQUEST, \"GET\");\ncurl_setopt($ch, CURLOPT_RETURNTRANSFER, true);\ncurl_setopt($ch, CURLOPT_HTTPHEADER, [\n    \"x-api-key: sm_your_api_key\",\n]);\n\n$response = curl_exec($ch);\ncurl_close($ch);\n\necho $response;"
          },
          {
            "lang": "Python",
            "source": "import requests\n\nresponse = requests.get(\n    \"https://api.sudomock.com/api/v1/fonts\",\n    headers={\"x-api-key\": \"sm_your_api_key\"},\n)\n\nresponse.raise_for_status()\nprint(response.json())"
          },
          {
            "lang": "Ruby",
            "source": "require \"net/http\"\nrequire \"uri\"\n\nuri = URI(\"https://api.sudomock.com/api/v1/fonts\")\nrequest = Net::HTTP::Get.new(uri)\nrequest[\"x-api-key\"] = \"sm_your_api_key\"\n\nresponse = Net::HTTP.start(uri.host, uri.port, use_ssl: true) do |http|\n  http.request(request)\nend\n\nputs response.body"
          },
          {
            "lang": "Go",
            "source": "package main\n\nimport (\n\t\"fmt\"\n\t\"io\"\n\t\"net/http\"\n)\n\nfunc main() {\n\treq, err := http.NewRequest(\"GET\", \"https://api.sudomock.com/api/v1/fonts\", nil)\n\tif err != nil {\n\t\tpanic(err)\n\t}\n\treq.Header.Set(\"x-api-key\", \"sm_your_api_key\")\n\n\tres, err := http.DefaultClient.Do(req)\n\tif err != nil {\n\t\tpanic(err)\n\t}\n\tdefer res.Body.Close()\n\n\tbody, _ := io.ReadAll(res.Body)\n\tfmt.Println(string(body))\n}"
          },
          {
            "lang": "Java",
            "source": "import java.net.URI;\nimport java.net.http.HttpClient;\nimport java.net.http.HttpRequest;\nimport java.net.http.HttpResponse;\n\nHttpRequest request = HttpRequest.newBuilder()\n    .uri(URI.create(\"https://api.sudomock.com/api/v1/fonts\"))\n    .header(\"x-api-key\", \"sm_your_api_key\")\n    .GET()\n    .build();\n\nHttpResponse<String> response = HttpClient.newHttpClient()\n    .send(request, HttpResponse.BodyHandlers.ofString());\n\nSystem.out.println(response.body());"
          },
          {
            "lang": ".NET",
            "source": "using System.Net.Http;\nusing System.Text;\n\nvar request = new HttpRequestMessage(HttpMethod.Get, \"https://api.sudomock.com/api/v1/fonts\");\nrequest.Headers.Add(\"x-api-key\", \"sm_your_api_key\");\n\nvar client = new HttpClient();\nvar response = await client.SendAsync(request);\n\nConsole.WriteLine(await response.Content.ReadAsStringAsync());"
          },
          {
            "lang": "cURL",
            "source": "curl -X GET \"https://api.sudomock.com/api/v1/fonts\" \\\n  -H \"x-api-key: sm_your_api_key\""
          }
        ]
      },
      "post": {
        "tags": [
          "Fonts"
        ],
        "summary": "Create a new font",
        "description": "Upload a custom TTF or OTF font (Pro plan and above). Send either a multipart 'file' or a JSON body with a public 'url'. The font is validated and security-checked before it is stored.",
        "operationId": "upload_font_api_v1_fonts_post",
        "responses": {
          "201": {
            "description": "Successful Response",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/FontResponse"
                }
              }
            }
          }
        },
        "x-mint": {
          "metadata": {
            "sidebarTitle": "Upload custom font"
          }
        },
        "requestBody": {
          "required": true,
          "content": {
            "multipart/form-data": {
              "schema": {
                "type": "object",
                "required": [
                  "file",
                  "license_confirmed"
                ],
                "properties": {
                  "file": {
                    "type": "string",
                    "format": "binary"
                  },
                  "license_confirmed": {
                    "type": "boolean"
                  }
                }
              }
            },
            "application/json": {
              "schema": {
                "description": "JSON body for POST /api/v1/fonts when uploading a font by URL. The\nalternative is a multipart 'file' upload. Send one or the other.",
                "example": {
                  "url": "https://example.com/fonts/MyBrand-Bold.ttf"
                },
                "properties": {
                  "url": {
                    "description": "Public URL of a TTF or OTF font file to fetch",
                    "maxLength": 2048,
                    "minLength": 1,
                    "title": "Url",
                    "type": "string"
                  },
                  "license_confirmed": {
                    "default": false,
                    "description": "Confirmation that you have the right to use and embed this font. Required.",
                    "title": "License Confirmed",
                    "type": "boolean"
                  }
                },
                "required": [
                  "url"
                ],
                "title": "FontUploadRequest",
                "type": "object"
              }
            }
          }
        },
        "security": [
          {
            "ApiKeyAuth": []
          }
        ],
        "x-codeSamples": [
          {
            "lang": "Node.js",
            "source": "const response = await fetch(\"https://api.sudomock.com/api/v1/fonts\", {\n  method: \"POST\",\n  headers: {\n    \"x-api-key\": \"sm_your_api_key\",\n    \"Content-Type\": \"application/json\",\n  },\n  body: JSON.stringify({\n    \"url\": \"https://example.com/fonts/MyBrand-Bold.ttf\"\n  }),\n});\n\nconst data = await response.json();\nconsole.log(data);"
          },
          {
            "lang": "PHP",
            "source": "<?php\n\n$payload = <<<'JSON'\n{\n  \"url\": \"https://example.com/fonts/MyBrand-Bold.ttf\"\n}\nJSON;\n\n$ch = curl_init(\"https://api.sudomock.com/api/v1/fonts\");\ncurl_setopt($ch, CURLOPT_CUSTOMREQUEST, \"POST\");\ncurl_setopt($ch, CURLOPT_RETURNTRANSFER, true);\ncurl_setopt($ch, CURLOPT_HTTPHEADER, [\n    \"x-api-key: sm_your_api_key\",\n    \"Content-Type: application/json\",\n]);\ncurl_setopt($ch, CURLOPT_POSTFIELDS, $payload);\n\n$response = curl_exec($ch);\ncurl_close($ch);\n\necho $response;"
          },
          {
            "lang": "Python",
            "source": "import requests\n\npayload = {\n    \"url\": \"https://example.com/fonts/MyBrand-Bold.ttf\"\n}\n\nresponse = requests.post(\n    \"https://api.sudomock.com/api/v1/fonts\",\n    headers={\"x-api-key\": \"sm_your_api_key\"},\n    json=payload,\n)\n\nresponse.raise_for_status()\nprint(response.json())"
          },
          {
            "lang": "Ruby",
            "source": "require \"net/http\"\nrequire \"uri\"\n\nuri = URI(\"https://api.sudomock.com/api/v1/fonts\")\nrequest = Net::HTTP::Post.new(uri)\nrequest[\"x-api-key\"] = \"sm_your_api_key\"\nrequest[\"Content-Type\"] = \"application/json\"\n\nrequest.body = <<~JSON\n  {\n    \"url\": \"https://example.com/fonts/MyBrand-Bold.ttf\"\n  }\nJSON\n\nresponse = Net::HTTP.start(uri.host, uri.port, use_ssl: true) do |http|\n  http.request(request)\nend\n\nputs response.body"
          },
          {
            "lang": "Go",
            "source": "package main\n\nimport (\n\t\"bytes\"\n\t\"fmt\"\n\t\"io\"\n\t\"net/http\"\n)\n\nfunc main() {\n\tpayload := []byte(`{\n  \"url\": \"https://example.com/fonts/MyBrand-Bold.ttf\"\n}`)\n\n\treq, err := http.NewRequest(\"POST\", \"https://api.sudomock.com/api/v1/fonts\", bytes.NewBuffer(payload))\n\tif err != nil {\n\t\tpanic(err)\n\t}\n\treq.Header.Set(\"x-api-key\", \"sm_your_api_key\")\n\treq.Header.Set(\"Content-Type\", \"application/json\")\n\n\tres, err := http.DefaultClient.Do(req)\n\tif err != nil {\n\t\tpanic(err)\n\t}\n\tdefer res.Body.Close()\n\n\tbody, _ := io.ReadAll(res.Body)\n\tfmt.Println(string(body))\n}"
          },
          {
            "lang": "Java",
            "source": "import java.net.URI;\nimport java.net.http.HttpClient;\nimport java.net.http.HttpRequest;\nimport java.net.http.HttpResponse;\n\nString payload = \"\"\"\n{\n  \"url\": \"https://example.com/fonts/MyBrand-Bold.ttf\"\n}\n\"\"\";\n\nHttpRequest request = HttpRequest.newBuilder()\n    .uri(URI.create(\"https://api.sudomock.com/api/v1/fonts\"))\n    .header(\"x-api-key\", \"sm_your_api_key\")\n    .header(\"Content-Type\", \"application/json\")\n    .POST(HttpRequest.BodyPublishers.ofString(payload))\n    .build();\n\nHttpResponse<String> response = HttpClient.newHttpClient()\n    .send(request, HttpResponse.BodyHandlers.ofString());\n\nSystem.out.println(response.body());"
          },
          {
            "lang": ".NET",
            "source": "using System.Net.Http;\nusing System.Text;\n\nvar payload = \"\"\"\n{\n  \"url\": \"https://example.com/fonts/MyBrand-Bold.ttf\"\n}\n\"\"\";\n\nvar request = new HttpRequestMessage(HttpMethod.Post, \"https://api.sudomock.com/api/v1/fonts\");\nrequest.Headers.Add(\"x-api-key\", \"sm_your_api_key\");\nrequest.Content = new StringContent(payload, Encoding.UTF8, \"application/json\");\n\nvar client = new HttpClient();\nvar response = await client.SendAsync(request);\n\nConsole.WriteLine(await response.Content.ReadAsStringAsync());"
          },
          {
            "lang": "cURL",
            "source": "curl -X POST \"https://api.sudomock.com/api/v1/fonts\" \\\n  -H \"x-api-key: sm_your_api_key\" \\\n  -H \"Content-Type: application/json\" \\\n  -d '{\n    \"url\": \"https://example.com/fonts/MyBrand-Bold.ttf\"\n  }'"
          }
        ]
      }
    },
    "/api/v1/fonts/{uuid}": {
      "get": {
        "tags": [
          "Fonts"
        ],
        "summary": "Retrieve a single font",
        "description": "Fetch a single font by id: a system font, or one of your own uploads.",
        "operationId": "get_font_api_v1_fonts__uuid__get",
        "parameters": [
          {
            "name": "uuid",
            "in": "path",
            "required": true,
            "schema": {
              "type": "string",
              "description": "Font id"
            },
            "description": "Font id"
          }
        ],
        "responses": {
          "200": {
            "description": "Successful Response",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/FontResponse"
                }
              }
            }
          }
        },
        "x-mint": {
          "metadata": {
            "sidebarTitle": "Get font"
          }
        },
        "security": [
          {
            "ApiKeyAuth": []
          }
        ],
        "x-codeSamples": [
          {
            "lang": "Node.js",
            "source": "const response = await fetch(\"https://api.sudomock.com/api/v1/fonts/3fa85f64-5717-4562-b3fc-2c963f66afa6\", {\n  method: \"GET\",\n  headers: { \"x-api-key\": \"sm_your_api_key\" },\n});\n\nconst data = await response.json();\nconsole.log(data);"
          },
          {
            "lang": "PHP",
            "source": "<?php\n\n$ch = curl_init(\"https://api.sudomock.com/api/v1/fonts/3fa85f64-5717-4562-b3fc-2c963f66afa6\");\ncurl_setopt($ch, CURLOPT_CUSTOMREQUEST, \"GET\");\ncurl_setopt($ch, CURLOPT_RETURNTRANSFER, true);\ncurl_setopt($ch, CURLOPT_HTTPHEADER, [\n    \"x-api-key: sm_your_api_key\",\n]);\n\n$response = curl_exec($ch);\ncurl_close($ch);\n\necho $response;"
          },
          {
            "lang": "Python",
            "source": "import requests\n\nresponse = requests.get(\n    \"https://api.sudomock.com/api/v1/fonts/3fa85f64-5717-4562-b3fc-2c963f66afa6\",\n    headers={\"x-api-key\": \"sm_your_api_key\"},\n)\n\nresponse.raise_for_status()\nprint(response.json())"
          },
          {
            "lang": "Ruby",
            "source": "require \"net/http\"\nrequire \"uri\"\n\nuri = URI(\"https://api.sudomock.com/api/v1/fonts/3fa85f64-5717-4562-b3fc-2c963f66afa6\")\nrequest = Net::HTTP::Get.new(uri)\nrequest[\"x-api-key\"] = \"sm_your_api_key\"\n\nresponse = Net::HTTP.start(uri.host, uri.port, use_ssl: true) do |http|\n  http.request(request)\nend\n\nputs response.body"
          },
          {
            "lang": "Go",
            "source": "package main\n\nimport (\n\t\"fmt\"\n\t\"io\"\n\t\"net/http\"\n)\n\nfunc main() {\n\treq, err := http.NewRequest(\"GET\", \"https://api.sudomock.com/api/v1/fonts/3fa85f64-5717-4562-b3fc-2c963f66afa6\", nil)\n\tif err != nil {\n\t\tpanic(err)\n\t}\n\treq.Header.Set(\"x-api-key\", \"sm_your_api_key\")\n\n\tres, err := http.DefaultClient.Do(req)\n\tif err != nil {\n\t\tpanic(err)\n\t}\n\tdefer res.Body.Close()\n\n\tbody, _ := io.ReadAll(res.Body)\n\tfmt.Println(string(body))\n}"
          },
          {
            "lang": "Java",
            "source": "import java.net.URI;\nimport java.net.http.HttpClient;\nimport java.net.http.HttpRequest;\nimport java.net.http.HttpResponse;\n\nHttpRequest request = HttpRequest.newBuilder()\n    .uri(URI.create(\"https://api.sudomock.com/api/v1/fonts/3fa85f64-5717-4562-b3fc-2c963f66afa6\"))\n    .header(\"x-api-key\", \"sm_your_api_key\")\n    .GET()\n    .build();\n\nHttpResponse<String> response = HttpClient.newHttpClient()\n    .send(request, HttpResponse.BodyHandlers.ofString());\n\nSystem.out.println(response.body());"
          },
          {
            "lang": ".NET",
            "source": "using System.Net.Http;\nusing System.Text;\n\nvar request = new HttpRequestMessage(HttpMethod.Get, \"https://api.sudomock.com/api/v1/fonts/3fa85f64-5717-4562-b3fc-2c963f66afa6\");\nrequest.Headers.Add(\"x-api-key\", \"sm_your_api_key\");\n\nvar client = new HttpClient();\nvar response = await client.SendAsync(request);\n\nConsole.WriteLine(await response.Content.ReadAsStringAsync());"
          },
          {
            "lang": "cURL",
            "source": "curl -X GET \"https://api.sudomock.com/api/v1/fonts/3fa85f64-5717-4562-b3fc-2c963f66afa6\" \\\n  -H \"x-api-key: sm_your_api_key\""
          }
        ]
      },
      "delete": {
        "tags": [
          "Fonts"
        ],
        "summary": "Remove an existing font",
        "description": "Delete one of your own uploaded fonts. System fonts cannot be deleted.",
        "operationId": "delete_font_api_v1_fonts__uuid__delete",
        "parameters": [
          {
            "name": "uuid",
            "in": "path",
            "required": true,
            "schema": {
              "type": "string",
              "description": "Font id"
            },
            "description": "Font id"
          }
        ],
        "responses": {
          "200": {
            "description": "Successful Response",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/FontDeleteResponse"
                }
              }
            }
          }
        },
        "x-mint": {
          "metadata": {
            "sidebarTitle": "Delete custom font"
          }
        },
        "security": [
          {
            "ApiKeyAuth": []
          }
        ],
        "x-codeSamples": [
          {
            "lang": "Node.js",
            "source": "const response = await fetch(\"https://api.sudomock.com/api/v1/fonts/3fa85f64-5717-4562-b3fc-2c963f66afa6\", {\n  method: \"DELETE\",\n  headers: { \"x-api-key\": \"sm_your_api_key\" },\n});\n\nconst data = await response.json();\nconsole.log(data);"
          },
          {
            "lang": "PHP",
            "source": "<?php\n\n$ch = curl_init(\"https://api.sudomock.com/api/v1/fonts/3fa85f64-5717-4562-b3fc-2c963f66afa6\");\ncurl_setopt($ch, CURLOPT_CUSTOMREQUEST, \"DELETE\");\ncurl_setopt($ch, CURLOPT_RETURNTRANSFER, true);\ncurl_setopt($ch, CURLOPT_HTTPHEADER, [\n    \"x-api-key: sm_your_api_key\",\n]);\n\n$response = curl_exec($ch);\ncurl_close($ch);\n\necho $response;"
          },
          {
            "lang": "Python",
            "source": "import requests\n\nresponse = requests.delete(\n    \"https://api.sudomock.com/api/v1/fonts/3fa85f64-5717-4562-b3fc-2c963f66afa6\",\n    headers={\"x-api-key\": \"sm_your_api_key\"},\n)\n\nresponse.raise_for_status()\nprint(response.json())"
          },
          {
            "lang": "Ruby",
            "source": "require \"net/http\"\nrequire \"uri\"\n\nuri = URI(\"https://api.sudomock.com/api/v1/fonts/3fa85f64-5717-4562-b3fc-2c963f66afa6\")\nrequest = Net::HTTP::Delete.new(uri)\nrequest[\"x-api-key\"] = \"sm_your_api_key\"\n\nresponse = Net::HTTP.start(uri.host, uri.port, use_ssl: true) do |http|\n  http.request(request)\nend\n\nputs response.body"
          },
          {
            "lang": "Go",
            "source": "package main\n\nimport (\n\t\"fmt\"\n\t\"io\"\n\t\"net/http\"\n)\n\nfunc main() {\n\treq, err := http.NewRequest(\"DELETE\", \"https://api.sudomock.com/api/v1/fonts/3fa85f64-5717-4562-b3fc-2c963f66afa6\", nil)\n\tif err != nil {\n\t\tpanic(err)\n\t}\n\treq.Header.Set(\"x-api-key\", \"sm_your_api_key\")\n\n\tres, err := http.DefaultClient.Do(req)\n\tif err != nil {\n\t\tpanic(err)\n\t}\n\tdefer res.Body.Close()\n\n\tbody, _ := io.ReadAll(res.Body)\n\tfmt.Println(string(body))\n}"
          },
          {
            "lang": "Java",
            "source": "import java.net.URI;\nimport java.net.http.HttpClient;\nimport java.net.http.HttpRequest;\nimport java.net.http.HttpResponse;\n\nHttpRequest request = HttpRequest.newBuilder()\n    .uri(URI.create(\"https://api.sudomock.com/api/v1/fonts/3fa85f64-5717-4562-b3fc-2c963f66afa6\"))\n    .header(\"x-api-key\", \"sm_your_api_key\")\n    .DELETE()\n    .build();\n\nHttpResponse<String> response = HttpClient.newHttpClient()\n    .send(request, HttpResponse.BodyHandlers.ofString());\n\nSystem.out.println(response.body());"
          },
          {
            "lang": ".NET",
            "source": "using System.Net.Http;\nusing System.Text;\n\nvar request = new HttpRequestMessage(HttpMethod.Delete, \"https://api.sudomock.com/api/v1/fonts/3fa85f64-5717-4562-b3fc-2c963f66afa6\");\nrequest.Headers.Add(\"x-api-key\", \"sm_your_api_key\");\n\nvar client = new HttpClient();\nvar response = await client.SendAsync(request);\n\nConsole.WriteLine(await response.Content.ReadAsStringAsync());"
          },
          {
            "lang": "cURL",
            "source": "curl -X DELETE \"https://api.sudomock.com/api/v1/fonts/3fa85f64-5717-4562-b3fc-2c963f66afa6\" \\\n  -H \"x-api-key: sm_your_api_key\""
          }
        ]
      }
    },
    "/api/v1/me": {
      "get": {
        "tags": [
          "Account"
        ],
        "summary": "Retrieve the current account",
        "description": "Returns account details, subscription info, usage statistics, and API key metadata for the authenticated user.",
        "operationId": "get_current_user_info_api_v1_me_get",
        "responses": {
          "200": {
            "description": "Successful Response",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/MeResponse"
                }
              }
            }
          }
        },
        "x-mint": {
          "metadata": {
            "sidebarTitle": "Get account"
          }
        },
        "security": [
          {
            "ApiKeyAuth": []
          }
        ],
        "x-codeSamples": [
          {
            "lang": "Node.js",
            "source": "const response = await fetch(\"https://api.sudomock.com/api/v1/me\", {\n  method: \"GET\",\n  headers: { \"x-api-key\": \"sm_your_api_key\" },\n});\n\nconst data = await response.json();\nconsole.log(data);"
          },
          {
            "lang": "PHP",
            "source": "<?php\n\n$ch = curl_init(\"https://api.sudomock.com/api/v1/me\");\ncurl_setopt($ch, CURLOPT_CUSTOMREQUEST, \"GET\");\ncurl_setopt($ch, CURLOPT_RETURNTRANSFER, true);\ncurl_setopt($ch, CURLOPT_HTTPHEADER, [\n    \"x-api-key: sm_your_api_key\",\n]);\n\n$response = curl_exec($ch);\ncurl_close($ch);\n\necho $response;"
          },
          {
            "lang": "Python",
            "source": "import requests\n\nresponse = requests.get(\n    \"https://api.sudomock.com/api/v1/me\",\n    headers={\"x-api-key\": \"sm_your_api_key\"},\n)\n\nresponse.raise_for_status()\nprint(response.json())"
          },
          {
            "lang": "Ruby",
            "source": "require \"net/http\"\nrequire \"uri\"\n\nuri = URI(\"https://api.sudomock.com/api/v1/me\")\nrequest = Net::HTTP::Get.new(uri)\nrequest[\"x-api-key\"] = \"sm_your_api_key\"\n\nresponse = Net::HTTP.start(uri.host, uri.port, use_ssl: true) do |http|\n  http.request(request)\nend\n\nputs response.body"
          },
          {
            "lang": "Go",
            "source": "package main\n\nimport (\n\t\"fmt\"\n\t\"io\"\n\t\"net/http\"\n)\n\nfunc main() {\n\treq, err := http.NewRequest(\"GET\", \"https://api.sudomock.com/api/v1/me\", nil)\n\tif err != nil {\n\t\tpanic(err)\n\t}\n\treq.Header.Set(\"x-api-key\", \"sm_your_api_key\")\n\n\tres, err := http.DefaultClient.Do(req)\n\tif err != nil {\n\t\tpanic(err)\n\t}\n\tdefer res.Body.Close()\n\n\tbody, _ := io.ReadAll(res.Body)\n\tfmt.Println(string(body))\n}"
          },
          {
            "lang": "Java",
            "source": "import java.net.URI;\nimport java.net.http.HttpClient;\nimport java.net.http.HttpRequest;\nimport java.net.http.HttpResponse;\n\nHttpRequest request = HttpRequest.newBuilder()\n    .uri(URI.create(\"https://api.sudomock.com/api/v1/me\"))\n    .header(\"x-api-key\", \"sm_your_api_key\")\n    .GET()\n    .build();\n\nHttpResponse<String> response = HttpClient.newHttpClient()\n    .send(request, HttpResponse.BodyHandlers.ofString());\n\nSystem.out.println(response.body());"
          },
          {
            "lang": ".NET",
            "source": "using System.Net.Http;\nusing System.Text;\n\nvar request = new HttpRequestMessage(HttpMethod.Get, \"https://api.sudomock.com/api/v1/me\");\nrequest.Headers.Add(\"x-api-key\", \"sm_your_api_key\");\n\nvar client = new HttpClient();\nvar response = await client.SendAsync(request);\n\nConsole.WriteLine(await response.Content.ReadAsStringAsync());"
          },
          {
            "lang": "cURL",
            "source": "curl -X GET \"https://api.sudomock.com/api/v1/me\" \\\n  -H \"x-api-key: sm_your_api_key\""
          }
        ]
      }
    },
    "/api/v1/photo-mockups": {
      "post": {
        "tags": [
          "Photo mockups"
        ],
        "summary": "Create a mockup from a product photo",
        "description": "Turns one product photo into a reusable mockup. By default the request returns the ready mockup; set is_async=true to receive a job URL. Costs 25 credits.",
        "operationId": "create_public_2d_mockup_api_v1_photo_mockups_post",
        "requestBody": {
          "required": true,
          "content": {
            "application/json": {
              "schema": {
                "$ref": "#/components/schemas/PhotoMockupCreateRequest"
              }
            }
          }
        },
        "responses": {
          "201": {
            "description": "Successful Response",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/PhotoMockupDetailResponse"
                }
              }
            }
          },
          "202": {
            "description": "Async creation job accepted",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/PhotoMockupCreateAcceptedResponse"
                }
              }
            }
          }
        },
        "x-mint": {
          "metadata": {
            "sidebarTitle": "Create photo mockup"
          }
        },
        "security": [
          {
            "ApiKeyAuth": []
          }
        ],
        "x-codeSamples": [
          {
            "lang": "Node.js",
            "source": "const response = await fetch(\"https://api.sudomock.com/api/v1/photo-mockups\", {\n  method: \"POST\",\n  headers: {\n    \"x-api-key\": \"sm_your_api_key\",\n    \"Content-Type\": \"application/json\",\n  },\n  body: JSON.stringify({\n    \"name\": \"Front view\",\n    \"source_url\": \"https://example.com/product-photo.jpg\"\n  }),\n});\n\nconst data = await response.json();\nconsole.log(data);"
          },
          {
            "lang": "PHP",
            "source": "<?php\n\n$payload = <<<'JSON'\n{\n  \"name\": \"Front view\",\n  \"source_url\": \"https://example.com/product-photo.jpg\"\n}\nJSON;\n\n$ch = curl_init(\"https://api.sudomock.com/api/v1/photo-mockups\");\ncurl_setopt($ch, CURLOPT_CUSTOMREQUEST, \"POST\");\ncurl_setopt($ch, CURLOPT_RETURNTRANSFER, true);\ncurl_setopt($ch, CURLOPT_HTTPHEADER, [\n    \"x-api-key: sm_your_api_key\",\n    \"Content-Type: application/json\",\n]);\ncurl_setopt($ch, CURLOPT_POSTFIELDS, $payload);\n\n$response = curl_exec($ch);\ncurl_close($ch);\n\necho $response;"
          },
          {
            "lang": "Python",
            "source": "import requests\n\npayload = {\n    \"name\": \"Front view\",\n    \"source_url\": \"https://example.com/product-photo.jpg\"\n}\n\nresponse = requests.post(\n    \"https://api.sudomock.com/api/v1/photo-mockups\",\n    headers={\"x-api-key\": \"sm_your_api_key\"},\n    json=payload,\n)\n\nresponse.raise_for_status()\nprint(response.json())"
          },
          {
            "lang": "Ruby",
            "source": "require \"net/http\"\nrequire \"uri\"\n\nuri = URI(\"https://api.sudomock.com/api/v1/photo-mockups\")\nrequest = Net::HTTP::Post.new(uri)\nrequest[\"x-api-key\"] = \"sm_your_api_key\"\nrequest[\"Content-Type\"] = \"application/json\"\n\nrequest.body = <<~JSON\n  {\n    \"name\": \"Front view\",\n    \"source_url\": \"https://example.com/product-photo.jpg\"\n  }\nJSON\n\nresponse = Net::HTTP.start(uri.host, uri.port, use_ssl: true) do |http|\n  http.request(request)\nend\n\nputs response.body"
          },
          {
            "lang": "Go",
            "source": "package main\n\nimport (\n\t\"bytes\"\n\t\"fmt\"\n\t\"io\"\n\t\"net/http\"\n)\n\nfunc main() {\n\tpayload := []byte(`{\n  \"name\": \"Front view\",\n  \"source_url\": \"https://example.com/product-photo.jpg\"\n}`)\n\n\treq, err := http.NewRequest(\"POST\", \"https://api.sudomock.com/api/v1/photo-mockups\", bytes.NewBuffer(payload))\n\tif err != nil {\n\t\tpanic(err)\n\t}\n\treq.Header.Set(\"x-api-key\", \"sm_your_api_key\")\n\treq.Header.Set(\"Content-Type\", \"application/json\")\n\n\tres, err := http.DefaultClient.Do(req)\n\tif err != nil {\n\t\tpanic(err)\n\t}\n\tdefer res.Body.Close()\n\n\tbody, _ := io.ReadAll(res.Body)\n\tfmt.Println(string(body))\n}"
          },
          {
            "lang": "Java",
            "source": "import java.net.URI;\nimport java.net.http.HttpClient;\nimport java.net.http.HttpRequest;\nimport java.net.http.HttpResponse;\n\nString payload = \"\"\"\n{\n  \"name\": \"Front view\",\n  \"source_url\": \"https://example.com/product-photo.jpg\"\n}\n\"\"\";\n\nHttpRequest request = HttpRequest.newBuilder()\n    .uri(URI.create(\"https://api.sudomock.com/api/v1/photo-mockups\"))\n    .header(\"x-api-key\", \"sm_your_api_key\")\n    .header(\"Content-Type\", \"application/json\")\n    .POST(HttpRequest.BodyPublishers.ofString(payload))\n    .build();\n\nHttpResponse<String> response = HttpClient.newHttpClient()\n    .send(request, HttpResponse.BodyHandlers.ofString());\n\nSystem.out.println(response.body());"
          },
          {
            "lang": ".NET",
            "source": "using System.Net.Http;\nusing System.Text;\n\nvar payload = \"\"\"\n{\n  \"name\": \"Front view\",\n  \"source_url\": \"https://example.com/product-photo.jpg\"\n}\n\"\"\";\n\nvar request = new HttpRequestMessage(HttpMethod.Post, \"https://api.sudomock.com/api/v1/photo-mockups\");\nrequest.Headers.Add(\"x-api-key\", \"sm_your_api_key\");\nrequest.Content = new StringContent(payload, Encoding.UTF8, \"application/json\");\n\nvar client = new HttpClient();\nvar response = await client.SendAsync(request);\n\nConsole.WriteLine(await response.Content.ReadAsStringAsync());"
          },
          {
            "lang": "cURL",
            "source": "curl -X POST \"https://api.sudomock.com/api/v1/photo-mockups\" \\\n  -H \"x-api-key: sm_your_api_key\" \\\n  -H \"Content-Type: application/json\" \\\n  -d '{\n    \"name\": \"Front view\",\n    \"source_url\": \"https://example.com/product-photo.jpg\"\n  }'"
          }
        ]
      },
      "get": {
        "tags": [
          "Photo mockups"
        ],
        "summary": "Retrieve a list of photo mockups",
        "description": "Returns a paginated list of the user's photo mockups with print area summaries. Each mockup includes its status, thumbnail, dimensions, and print area names/bboxes. Ordered by creation date (newest first).",
        "operationId": "list_2d_mockups_api_v1_photo_mockups_get",
        "parameters": [
          {
            "name": "limit",
            "in": "query",
            "required": false,
            "schema": {
              "type": "integer",
              "maximum": 100,
              "minimum": 1,
              "description": "Items per page (max 100)",
              "default": 20
            },
            "description": "Items per page (max 100)"
          },
          {
            "name": "offset",
            "in": "query",
            "required": false,
            "schema": {
              "type": "integer",
              "minimum": 0,
              "description": "Pagination offset",
              "default": 0
            },
            "description": "Pagination offset"
          },
          {
            "name": "customizable_only",
            "in": "query",
            "required": false,
            "schema": {
              "type": "boolean",
              "description": "Return only mockups ready for customization",
              "default": false
            },
            "description": "Return only mockups ready for customization"
          }
        ],
        "responses": {
          "200": {
            "description": "Successful Response",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/PhotoMockupList"
                }
              }
            }
          }
        },
        "security": [
          {
            "ApiKeyAuth": []
          }
        ],
        "x-codeSamples": [
          {
            "lang": "Node.js",
            "source": "const response = await fetch(\"https://api.sudomock.com/api/v1/photo-mockups\", {\n  method: \"GET\",\n  headers: { \"x-api-key\": \"sm_your_api_key\" },\n});\n\nconst data = await response.json();\nconsole.log(data);"
          },
          {
            "lang": "PHP",
            "source": "<?php\n\n$ch = curl_init(\"https://api.sudomock.com/api/v1/photo-mockups\");\ncurl_setopt($ch, CURLOPT_CUSTOMREQUEST, \"GET\");\ncurl_setopt($ch, CURLOPT_RETURNTRANSFER, true);\ncurl_setopt($ch, CURLOPT_HTTPHEADER, [\n    \"x-api-key: sm_your_api_key\",\n]);\n\n$response = curl_exec($ch);\ncurl_close($ch);\n\necho $response;"
          },
          {
            "lang": "Python",
            "source": "import requests\n\nresponse = requests.get(\n    \"https://api.sudomock.com/api/v1/photo-mockups\",\n    headers={\"x-api-key\": \"sm_your_api_key\"},\n)\n\nresponse.raise_for_status()\nprint(response.json())"
          },
          {
            "lang": "Ruby",
            "source": "require \"net/http\"\nrequire \"uri\"\n\nuri = URI(\"https://api.sudomock.com/api/v1/photo-mockups\")\nrequest = Net::HTTP::Get.new(uri)\nrequest[\"x-api-key\"] = \"sm_your_api_key\"\n\nresponse = Net::HTTP.start(uri.host, uri.port, use_ssl: true) do |http|\n  http.request(request)\nend\n\nputs response.body"
          },
          {
            "lang": "Go",
            "source": "package main\n\nimport (\n\t\"fmt\"\n\t\"io\"\n\t\"net/http\"\n)\n\nfunc main() {\n\treq, err := http.NewRequest(\"GET\", \"https://api.sudomock.com/api/v1/photo-mockups\", nil)\n\tif err != nil {\n\t\tpanic(err)\n\t}\n\treq.Header.Set(\"x-api-key\", \"sm_your_api_key\")\n\n\tres, err := http.DefaultClient.Do(req)\n\tif err != nil {\n\t\tpanic(err)\n\t}\n\tdefer res.Body.Close()\n\n\tbody, _ := io.ReadAll(res.Body)\n\tfmt.Println(string(body))\n}"
          },
          {
            "lang": "Java",
            "source": "import java.net.URI;\nimport java.net.http.HttpClient;\nimport java.net.http.HttpRequest;\nimport java.net.http.HttpResponse;\n\nHttpRequest request = HttpRequest.newBuilder()\n    .uri(URI.create(\"https://api.sudomock.com/api/v1/photo-mockups\"))\n    .header(\"x-api-key\", \"sm_your_api_key\")\n    .GET()\n    .build();\n\nHttpResponse<String> response = HttpClient.newHttpClient()\n    .send(request, HttpResponse.BodyHandlers.ofString());\n\nSystem.out.println(response.body());"
          },
          {
            "lang": ".NET",
            "source": "using System.Net.Http;\nusing System.Text;\n\nvar request = new HttpRequestMessage(HttpMethod.Get, \"https://api.sudomock.com/api/v1/photo-mockups\");\nrequest.Headers.Add(\"x-api-key\", \"sm_your_api_key\");\n\nvar client = new HttpClient();\nvar response = await client.SendAsync(request);\n\nConsole.WriteLine(await response.Content.ReadAsStringAsync());"
          },
          {
            "lang": "cURL",
            "source": "curl -X GET \"https://api.sudomock.com/api/v1/photo-mockups\" \\\n  -H \"x-api-key: sm_your_api_key\""
          }
        ]
      }
    },
    "/api/v1/photo-mockups/{mockup_id}/print-areas": {
      "put": {
        "tags": [
          "Photo mockups"
        ],
        "summary": "Replace the print areas of a photo mockup",
        "description": "Replaces a ready photo mockup's printable areas. Each area must be a convex four-point shape within the source image.",
        "operationId": "replace_public_2d_print_areas_api_v1_photo_mockups__mockup_id__print_areas_put",
        "parameters": [
          {
            "name": "mockup_id",
            "in": "path",
            "required": true,
            "schema": {
              "type": "string",
              "description": "Id of the photo mockup whose print areas are replaced."
            },
            "description": "Id of the photo mockup whose print areas are replaced."
          }
        ],
        "requestBody": {
          "required": true,
          "content": {
            "application/json": {
              "schema": {
                "$ref": "#/components/schemas/PhotoMockupPrintAreasUpdate"
              }
            }
          }
        },
        "responses": {
          "200": {
            "description": "Successful Response",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/PhotoMockupPrintAreasUpdateResponse"
                }
              }
            }
          }
        },
        "x-mint": {
          "metadata": {
            "sidebarTitle": "Replace print areas"
          }
        },
        "security": [
          {
            "ApiKeyAuth": []
          }
        ],
        "x-codeSamples": [
          {
            "lang": "Node.js",
            "source": "const response = await fetch(\"https://api.sudomock.com/api/v1/photo-mockups/3fa85f64-5717-4562-b3fc-2c963f66afa6/print-areas\", {\n  method: \"PUT\",\n  headers: {\n    \"x-api-key\": \"sm_your_api_key\",\n    \"Content-Type\": \"application/json\",\n  },\n  body: JSON.stringify({\n    \"print_areas\": [\n      {\n        \"points\": [\n          [\n            200,\n            150\n          ],\n          [\n            600,\n            150\n          ],\n          [\n            620,\n            550\n          ],\n          [\n            180,\n            550\n          ]\n        ]\n      }\n    ]\n  }),\n});\n\nconst data = await response.json();\nconsole.log(data);"
          },
          {
            "lang": "PHP",
            "source": "<?php\n\n$payload = <<<'JSON'\n{\n  \"print_areas\": [\n    {\n      \"points\": [\n        [\n          200,\n          150\n        ],\n        [\n          600,\n          150\n        ],\n        [\n          620,\n          550\n        ],\n        [\n          180,\n          550\n        ]\n      ]\n    }\n  ]\n}\nJSON;\n\n$ch = curl_init(\"https://api.sudomock.com/api/v1/photo-mockups/3fa85f64-5717-4562-b3fc-2c963f66afa6/print-areas\");\ncurl_setopt($ch, CURLOPT_CUSTOMREQUEST, \"PUT\");\ncurl_setopt($ch, CURLOPT_RETURNTRANSFER, true);\ncurl_setopt($ch, CURLOPT_HTTPHEADER, [\n    \"x-api-key: sm_your_api_key\",\n    \"Content-Type: application/json\",\n]);\ncurl_setopt($ch, CURLOPT_POSTFIELDS, $payload);\n\n$response = curl_exec($ch);\ncurl_close($ch);\n\necho $response;"
          },
          {
            "lang": "Python",
            "source": "import requests\n\npayload = {\n    \"print_areas\": [\n        {\n            \"points\": [\n                [\n                    200,\n                    150\n                ],\n                [\n                    600,\n                    150\n                ],\n                [\n                    620,\n                    550\n                ],\n                [\n                    180,\n                    550\n                ]\n            ]\n        }\n    ]\n}\n\nresponse = requests.put(\n    \"https://api.sudomock.com/api/v1/photo-mockups/3fa85f64-5717-4562-b3fc-2c963f66afa6/print-areas\",\n    headers={\"x-api-key\": \"sm_your_api_key\"},\n    json=payload,\n)\n\nresponse.raise_for_status()\nprint(response.json())"
          },
          {
            "lang": "Ruby",
            "source": "require \"net/http\"\nrequire \"uri\"\n\nuri = URI(\"https://api.sudomock.com/api/v1/photo-mockups/3fa85f64-5717-4562-b3fc-2c963f66afa6/print-areas\")\nrequest = Net::HTTP::Put.new(uri)\nrequest[\"x-api-key\"] = \"sm_your_api_key\"\nrequest[\"Content-Type\"] = \"application/json\"\n\nrequest.body = <<~JSON\n  {\n    \"print_areas\": [\n      {\n        \"points\": [\n          [\n            200,\n            150\n          ],\n          [\n            600,\n            150\n          ],\n          [\n            620,\n            550\n          ],\n          [\n            180,\n            550\n          ]\n        ]\n      }\n    ]\n  }\nJSON\n\nresponse = Net::HTTP.start(uri.host, uri.port, use_ssl: true) do |http|\n  http.request(request)\nend\n\nputs response.body"
          },
          {
            "lang": "Go",
            "source": "package main\n\nimport (\n\t\"bytes\"\n\t\"fmt\"\n\t\"io\"\n\t\"net/http\"\n)\n\nfunc main() {\n\tpayload := []byte(`{\n  \"print_areas\": [\n    {\n      \"points\": [\n        [\n          200,\n          150\n        ],\n        [\n          600,\n          150\n        ],\n        [\n          620,\n          550\n        ],\n        [\n          180,\n          550\n        ]\n      ]\n    }\n  ]\n}`)\n\n\treq, err := http.NewRequest(\"PUT\", \"https://api.sudomock.com/api/v1/photo-mockups/3fa85f64-5717-4562-b3fc-2c963f66afa6/print-areas\", bytes.NewBuffer(payload))\n\tif err != nil {\n\t\tpanic(err)\n\t}\n\treq.Header.Set(\"x-api-key\", \"sm_your_api_key\")\n\treq.Header.Set(\"Content-Type\", \"application/json\")\n\n\tres, err := http.DefaultClient.Do(req)\n\tif err != nil {\n\t\tpanic(err)\n\t}\n\tdefer res.Body.Close()\n\n\tbody, _ := io.ReadAll(res.Body)\n\tfmt.Println(string(body))\n}"
          },
          {
            "lang": "Java",
            "source": "import java.net.URI;\nimport java.net.http.HttpClient;\nimport java.net.http.HttpRequest;\nimport java.net.http.HttpResponse;\n\nString payload = \"\"\"\n{\n  \"print_areas\": [\n    {\n      \"points\": [\n        [\n          200,\n          150\n        ],\n        [\n          600,\n          150\n        ],\n        [\n          620,\n          550\n        ],\n        [\n          180,\n          550\n        ]\n      ]\n    }\n  ]\n}\n\"\"\";\n\nHttpRequest request = HttpRequest.newBuilder()\n    .uri(URI.create(\"https://api.sudomock.com/api/v1/photo-mockups/3fa85f64-5717-4562-b3fc-2c963f66afa6/print-areas\"))\n    .header(\"x-api-key\", \"sm_your_api_key\")\n    .header(\"Content-Type\", \"application/json\")\n    .PUT(HttpRequest.BodyPublishers.ofString(payload))\n    .build();\n\nHttpResponse<String> response = HttpClient.newHttpClient()\n    .send(request, HttpResponse.BodyHandlers.ofString());\n\nSystem.out.println(response.body());"
          },
          {
            "lang": ".NET",
            "source": "using System.Net.Http;\nusing System.Text;\n\nvar payload = \"\"\"\n{\n  \"print_areas\": [\n    {\n      \"points\": [\n        [\n          200,\n          150\n        ],\n        [\n          600,\n          150\n        ],\n        [\n          620,\n          550\n        ],\n        [\n          180,\n          550\n        ]\n      ]\n    }\n  ]\n}\n\"\"\";\n\nvar request = new HttpRequestMessage(HttpMethod.Put, \"https://api.sudomock.com/api/v1/photo-mockups/3fa85f64-5717-4562-b3fc-2c963f66afa6/print-areas\");\nrequest.Headers.Add(\"x-api-key\", \"sm_your_api_key\");\nrequest.Content = new StringContent(payload, Encoding.UTF8, \"application/json\");\n\nvar client = new HttpClient();\nvar response = await client.SendAsync(request);\n\nConsole.WriteLine(await response.Content.ReadAsStringAsync());"
          },
          {
            "lang": "cURL",
            "source": "curl -X PUT \"https://api.sudomock.com/api/v1/photo-mockups/3fa85f64-5717-4562-b3fc-2c963f66afa6/print-areas\" \\\n  -H \"x-api-key: sm_your_api_key\" \\\n  -H \"Content-Type: application/json\" \\\n  -d '{\n    \"print_areas\": [\n      {\n        \"points\": [\n          [\n            200,\n            150\n          ],\n          [\n            600,\n            150\n          ],\n          [\n            620,\n            550\n          ],\n          [\n            180,\n            550\n          ]\n        ]\n      }\n    ]\n  }'"
          }
        ]
      }
    },
    "/api/v1/photo-mockups/{mockup_id}": {
      "get": {
        "tags": [
          "Photo mockups"
        ],
        "summary": "Retrieve a single photo mockup",
        "description": "Returns mockup metadata and print-area summaries. Use the mockup_id with POST /api/v1/photo-mockups/{mockup_id}/render to render artwork.",
        "operationId": "get_2d_mockup_public_api_v1_photo_mockups__mockup_id__get",
        "parameters": [
          {
            "name": "mockup_id",
            "in": "path",
            "required": true,
            "schema": {
              "type": "string",
              "description": "Id of the photo mockup to read, as returned when it was created."
            },
            "description": "Id of the photo mockup to read, as returned when it was created."
          }
        ],
        "responses": {
          "200": {
            "description": "Successful Response",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/PhotoMockupDetailResponse"
                }
              }
            }
          }
        },
        "x-mint": {
          "metadata": {
            "sidebarTitle": "Get photo mockup"
          }
        },
        "security": [
          {
            "ApiKeyAuth": []
          }
        ],
        "x-codeSamples": [
          {
            "lang": "Node.js",
            "source": "const response = await fetch(\"https://api.sudomock.com/api/v1/photo-mockups/3fa85f64-5717-4562-b3fc-2c963f66afa6\", {\n  method: \"GET\",\n  headers: { \"x-api-key\": \"sm_your_api_key\" },\n});\n\nconst data = await response.json();\nconsole.log(data);"
          },
          {
            "lang": "PHP",
            "source": "<?php\n\n$ch = curl_init(\"https://api.sudomock.com/api/v1/photo-mockups/3fa85f64-5717-4562-b3fc-2c963f66afa6\");\ncurl_setopt($ch, CURLOPT_CUSTOMREQUEST, \"GET\");\ncurl_setopt($ch, CURLOPT_RETURNTRANSFER, true);\ncurl_setopt($ch, CURLOPT_HTTPHEADER, [\n    \"x-api-key: sm_your_api_key\",\n]);\n\n$response = curl_exec($ch);\ncurl_close($ch);\n\necho $response;"
          },
          {
            "lang": "Python",
            "source": "import requests\n\nresponse = requests.get(\n    \"https://api.sudomock.com/api/v1/photo-mockups/3fa85f64-5717-4562-b3fc-2c963f66afa6\",\n    headers={\"x-api-key\": \"sm_your_api_key\"},\n)\n\nresponse.raise_for_status()\nprint(response.json())"
          },
          {
            "lang": "Ruby",
            "source": "require \"net/http\"\nrequire \"uri\"\n\nuri = URI(\"https://api.sudomock.com/api/v1/photo-mockups/3fa85f64-5717-4562-b3fc-2c963f66afa6\")\nrequest = Net::HTTP::Get.new(uri)\nrequest[\"x-api-key\"] = \"sm_your_api_key\"\n\nresponse = Net::HTTP.start(uri.host, uri.port, use_ssl: true) do |http|\n  http.request(request)\nend\n\nputs response.body"
          },
          {
            "lang": "Go",
            "source": "package main\n\nimport (\n\t\"fmt\"\n\t\"io\"\n\t\"net/http\"\n)\n\nfunc main() {\n\treq, err := http.NewRequest(\"GET\", \"https://api.sudomock.com/api/v1/photo-mockups/3fa85f64-5717-4562-b3fc-2c963f66afa6\", nil)\n\tif err != nil {\n\t\tpanic(err)\n\t}\n\treq.Header.Set(\"x-api-key\", \"sm_your_api_key\")\n\n\tres, err := http.DefaultClient.Do(req)\n\tif err != nil {\n\t\tpanic(err)\n\t}\n\tdefer res.Body.Close()\n\n\tbody, _ := io.ReadAll(res.Body)\n\tfmt.Println(string(body))\n}"
          },
          {
            "lang": "Java",
            "source": "import java.net.URI;\nimport java.net.http.HttpClient;\nimport java.net.http.HttpRequest;\nimport java.net.http.HttpResponse;\n\nHttpRequest request = HttpRequest.newBuilder()\n    .uri(URI.create(\"https://api.sudomock.com/api/v1/photo-mockups/3fa85f64-5717-4562-b3fc-2c963f66afa6\"))\n    .header(\"x-api-key\", \"sm_your_api_key\")\n    .GET()\n    .build();\n\nHttpResponse<String> response = HttpClient.newHttpClient()\n    .send(request, HttpResponse.BodyHandlers.ofString());\n\nSystem.out.println(response.body());"
          },
          {
            "lang": ".NET",
            "source": "using System.Net.Http;\nusing System.Text;\n\nvar request = new HttpRequestMessage(HttpMethod.Get, \"https://api.sudomock.com/api/v1/photo-mockups/3fa85f64-5717-4562-b3fc-2c963f66afa6\");\nrequest.Headers.Add(\"x-api-key\", \"sm_your_api_key\");\n\nvar client = new HttpClient();\nvar response = await client.SendAsync(request);\n\nConsole.WriteLine(await response.Content.ReadAsStringAsync());"
          },
          {
            "lang": "cURL",
            "source": "curl -X GET \"https://api.sudomock.com/api/v1/photo-mockups/3fa85f64-5717-4562-b3fc-2c963f66afa6\" \\\n  -H \"x-api-key: sm_your_api_key\""
          }
        ]
      },
      "patch": {
        "tags": [
          "Photo mockups"
        ],
        "summary": "Update an existing photo mockup",
        "description": "Rename a mockup and/or set the colours it answers to by name. A render may then send a name where it would send a hex code.",
        "operationId": "update_2d_mockup_api_v1_photo_mockups__mockup_id__patch",
        "parameters": [
          {
            "name": "mockup_id",
            "in": "path",
            "required": true,
            "schema": {
              "type": "string",
              "description": "Id of the photo mockup to rename or give named colours."
            },
            "description": "Id of the photo mockup to rename or give named colours."
          }
        ],
        "requestBody": {
          "required": true,
          "content": {
            "application/json": {
              "schema": {
                "$ref": "#/components/schemas/MockupUpdateRequest"
              }
            }
          }
        },
        "responses": {
          "200": {
            "description": "Successful Response",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/PhotoMockupUpdateResponse"
                }
              }
            }
          }
        },
        "x-mint": {
          "metadata": {
            "sidebarTitle": "Update photo mockup"
          }
        },
        "security": [
          {
            "ApiKeyAuth": []
          }
        ],
        "x-codeSamples": [
          {
            "lang": "Node.js",
            "source": "const response = await fetch(\"https://api.sudomock.com/api/v1/photo-mockups/3fa85f64-5717-4562-b3fc-2c963f66afa6\", {\n  method: \"PATCH\",\n  headers: {\n    \"x-api-key\": \"sm_your_api_key\",\n    \"Content-Type\": \"application/json\",\n  },\n  body: JSON.stringify({\n    \"name\": \"Updated Mockup Name\"\n  }),\n});\n\nconst data = await response.json();\nconsole.log(data);"
          },
          {
            "lang": "PHP",
            "source": "<?php\n\n$payload = <<<'JSON'\n{\n  \"name\": \"Updated Mockup Name\"\n}\nJSON;\n\n$ch = curl_init(\"https://api.sudomock.com/api/v1/photo-mockups/3fa85f64-5717-4562-b3fc-2c963f66afa6\");\ncurl_setopt($ch, CURLOPT_CUSTOMREQUEST, \"PATCH\");\ncurl_setopt($ch, CURLOPT_RETURNTRANSFER, true);\ncurl_setopt($ch, CURLOPT_HTTPHEADER, [\n    \"x-api-key: sm_your_api_key\",\n    \"Content-Type: application/json\",\n]);\ncurl_setopt($ch, CURLOPT_POSTFIELDS, $payload);\n\n$response = curl_exec($ch);\ncurl_close($ch);\n\necho $response;"
          },
          {
            "lang": "Python",
            "source": "import requests\n\npayload = {\n    \"name\": \"Updated Mockup Name\"\n}\n\nresponse = requests.patch(\n    \"https://api.sudomock.com/api/v1/photo-mockups/3fa85f64-5717-4562-b3fc-2c963f66afa6\",\n    headers={\"x-api-key\": \"sm_your_api_key\"},\n    json=payload,\n)\n\nresponse.raise_for_status()\nprint(response.json())"
          },
          {
            "lang": "Ruby",
            "source": "require \"net/http\"\nrequire \"uri\"\n\nuri = URI(\"https://api.sudomock.com/api/v1/photo-mockups/3fa85f64-5717-4562-b3fc-2c963f66afa6\")\nrequest = Net::HTTP::Patch.new(uri)\nrequest[\"x-api-key\"] = \"sm_your_api_key\"\nrequest[\"Content-Type\"] = \"application/json\"\n\nrequest.body = <<~JSON\n  {\n    \"name\": \"Updated Mockup Name\"\n  }\nJSON\n\nresponse = Net::HTTP.start(uri.host, uri.port, use_ssl: true) do |http|\n  http.request(request)\nend\n\nputs response.body"
          },
          {
            "lang": "Go",
            "source": "package main\n\nimport (\n\t\"bytes\"\n\t\"fmt\"\n\t\"io\"\n\t\"net/http\"\n)\n\nfunc main() {\n\tpayload := []byte(`{\n  \"name\": \"Updated Mockup Name\"\n}`)\n\n\treq, err := http.NewRequest(\"PATCH\", \"https://api.sudomock.com/api/v1/photo-mockups/3fa85f64-5717-4562-b3fc-2c963f66afa6\", bytes.NewBuffer(payload))\n\tif err != nil {\n\t\tpanic(err)\n\t}\n\treq.Header.Set(\"x-api-key\", \"sm_your_api_key\")\n\treq.Header.Set(\"Content-Type\", \"application/json\")\n\n\tres, err := http.DefaultClient.Do(req)\n\tif err != nil {\n\t\tpanic(err)\n\t}\n\tdefer res.Body.Close()\n\n\tbody, _ := io.ReadAll(res.Body)\n\tfmt.Println(string(body))\n}"
          },
          {
            "lang": "Java",
            "source": "import java.net.URI;\nimport java.net.http.HttpClient;\nimport java.net.http.HttpRequest;\nimport java.net.http.HttpResponse;\n\nString payload = \"\"\"\n{\n  \"name\": \"Updated Mockup Name\"\n}\n\"\"\";\n\nHttpRequest request = HttpRequest.newBuilder()\n    .uri(URI.create(\"https://api.sudomock.com/api/v1/photo-mockups/3fa85f64-5717-4562-b3fc-2c963f66afa6\"))\n    .header(\"x-api-key\", \"sm_your_api_key\")\n    .header(\"Content-Type\", \"application/json\")\n    .method(\"PATCH\", HttpRequest.BodyPublishers.ofString(payload))\n    .build();\n\nHttpResponse<String> response = HttpClient.newHttpClient()\n    .send(request, HttpResponse.BodyHandlers.ofString());\n\nSystem.out.println(response.body());"
          },
          {
            "lang": ".NET",
            "source": "using System.Net.Http;\nusing System.Text;\n\nvar payload = \"\"\"\n{\n  \"name\": \"Updated Mockup Name\"\n}\n\"\"\";\n\nvar request = new HttpRequestMessage(HttpMethod.Patch, \"https://api.sudomock.com/api/v1/photo-mockups/3fa85f64-5717-4562-b3fc-2c963f66afa6\");\nrequest.Headers.Add(\"x-api-key\", \"sm_your_api_key\");\nrequest.Content = new StringContent(payload, Encoding.UTF8, \"application/json\");\n\nvar client = new HttpClient();\nvar response = await client.SendAsync(request);\n\nConsole.WriteLine(await response.Content.ReadAsStringAsync());"
          },
          {
            "lang": "cURL",
            "source": "curl -X PATCH \"https://api.sudomock.com/api/v1/photo-mockups/3fa85f64-5717-4562-b3fc-2c963f66afa6\" \\\n  -H \"x-api-key: sm_your_api_key\" \\\n  -H \"Content-Type: application/json\" \\\n  -d '{\n    \"name\": \"Updated Mockup Name\"\n  }'"
          }
        ]
      },
      "delete": {
        "tags": [
          "Photo mockups"
        ],
        "summary": "Remove an existing photo mockup",
        "description": "Permanently deletes the mockup and its print areas. This action cannot be undone.",
        "operationId": "delete_2d_mockup_api_v1_photo_mockups__mockup_id__delete",
        "parameters": [
          {
            "name": "mockup_id",
            "in": "path",
            "required": true,
            "schema": {
              "type": "string",
              "description": "Id of the photo mockup to delete together with its print areas."
            },
            "description": "Id of the photo mockup to delete together with its print areas."
          }
        ],
        "responses": {
          "200": {
            "description": "Successful Response",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/PhotoMockupDeleteResponse"
                }
              }
            }
          }
        },
        "x-mint": {
          "metadata": {
            "sidebarTitle": "Delete photo mockup"
          }
        },
        "security": [
          {
            "ApiKeyAuth": []
          }
        ],
        "x-codeSamples": [
          {
            "lang": "Node.js",
            "source": "const response = await fetch(\"https://api.sudomock.com/api/v1/photo-mockups/3fa85f64-5717-4562-b3fc-2c963f66afa6\", {\n  method: \"DELETE\",\n  headers: { \"x-api-key\": \"sm_your_api_key\" },\n});\n\nconst data = await response.json();\nconsole.log(data);"
          },
          {
            "lang": "PHP",
            "source": "<?php\n\n$ch = curl_init(\"https://api.sudomock.com/api/v1/photo-mockups/3fa85f64-5717-4562-b3fc-2c963f66afa6\");\ncurl_setopt($ch, CURLOPT_CUSTOMREQUEST, \"DELETE\");\ncurl_setopt($ch, CURLOPT_RETURNTRANSFER, true);\ncurl_setopt($ch, CURLOPT_HTTPHEADER, [\n    \"x-api-key: sm_your_api_key\",\n]);\n\n$response = curl_exec($ch);\ncurl_close($ch);\n\necho $response;"
          },
          {
            "lang": "Python",
            "source": "import requests\n\nresponse = requests.delete(\n    \"https://api.sudomock.com/api/v1/photo-mockups/3fa85f64-5717-4562-b3fc-2c963f66afa6\",\n    headers={\"x-api-key\": \"sm_your_api_key\"},\n)\n\nresponse.raise_for_status()\nprint(response.json())"
          },
          {
            "lang": "Ruby",
            "source": "require \"net/http\"\nrequire \"uri\"\n\nuri = URI(\"https://api.sudomock.com/api/v1/photo-mockups/3fa85f64-5717-4562-b3fc-2c963f66afa6\")\nrequest = Net::HTTP::Delete.new(uri)\nrequest[\"x-api-key\"] = \"sm_your_api_key\"\n\nresponse = Net::HTTP.start(uri.host, uri.port, use_ssl: true) do |http|\n  http.request(request)\nend\n\nputs response.body"
          },
          {
            "lang": "Go",
            "source": "package main\n\nimport (\n\t\"fmt\"\n\t\"io\"\n\t\"net/http\"\n)\n\nfunc main() {\n\treq, err := http.NewRequest(\"DELETE\", \"https://api.sudomock.com/api/v1/photo-mockups/3fa85f64-5717-4562-b3fc-2c963f66afa6\", nil)\n\tif err != nil {\n\t\tpanic(err)\n\t}\n\treq.Header.Set(\"x-api-key\", \"sm_your_api_key\")\n\n\tres, err := http.DefaultClient.Do(req)\n\tif err != nil {\n\t\tpanic(err)\n\t}\n\tdefer res.Body.Close()\n\n\tbody, _ := io.ReadAll(res.Body)\n\tfmt.Println(string(body))\n}"
          },
          {
            "lang": "Java",
            "source": "import java.net.URI;\nimport java.net.http.HttpClient;\nimport java.net.http.HttpRequest;\nimport java.net.http.HttpResponse;\n\nHttpRequest request = HttpRequest.newBuilder()\n    .uri(URI.create(\"https://api.sudomock.com/api/v1/photo-mockups/3fa85f64-5717-4562-b3fc-2c963f66afa6\"))\n    .header(\"x-api-key\", \"sm_your_api_key\")\n    .DELETE()\n    .build();\n\nHttpResponse<String> response = HttpClient.newHttpClient()\n    .send(request, HttpResponse.BodyHandlers.ofString());\n\nSystem.out.println(response.body());"
          },
          {
            "lang": ".NET",
            "source": "using System.Net.Http;\nusing System.Text;\n\nvar request = new HttpRequestMessage(HttpMethod.Delete, \"https://api.sudomock.com/api/v1/photo-mockups/3fa85f64-5717-4562-b3fc-2c963f66afa6\");\nrequest.Headers.Add(\"x-api-key\", \"sm_your_api_key\");\n\nvar client = new HttpClient();\nvar response = await client.SendAsync(request);\n\nConsole.WriteLine(await response.Content.ReadAsStringAsync());"
          },
          {
            "lang": "cURL",
            "source": "curl -X DELETE \"https://api.sudomock.com/api/v1/photo-mockups/3fa85f64-5717-4562-b3fc-2c963f66afa6\" \\\n  -H \"x-api-key: sm_your_api_key\""
          }
        ]
      }
    },
    "/api/v1/photo-mockups/{mockup_id}/render": {
      "post": {
        "tags": [
          "Photo mockups"
        ],
        "summary": "Render a photo mockup",
        "description": "Renders artwork onto a previously created photo mockup identified by the path mockup_id. Artwork can target a saved print area or a whole product surface, and a product offers both. The mockup must be in 'ready' status. Costs 5 credits. Returns CDN URL(s) of the rendered image.",
        "operationId": "render_2d_mockup_public_api_v1_photo_mockups__mockup_id__render_post",
        "parameters": [
          {
            "name": "mockup_id",
            "in": "path",
            "required": true,
            "schema": {
              "type": "string",
              "description": "Id of the photo mockup the artwork is rendered onto."
            },
            "description": "Id of the photo mockup the artwork is rendered onto."
          }
        ],
        "requestBody": {
          "required": true,
          "content": {
            "application/json": {
              "schema": {
                "$ref": "#/components/schemas/PhotoMockupRender"
              }
            }
          }
        },
        "responses": {
          "200": {
            "description": "Successful Response",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/PhotoMockupRenderResponse"
                }
              }
            }
          },
          "202": {
            "description": "Render queued (is_async=true). Poll status_url for the result, or receive a webhook on completion.",
            "content": {
              "application/json": {
                "example": {
                  "job_id": "5f1c0b2a-7d43-4e9a-8c16-0b5d3f7a2e94",
                  "kind": "photo_mockup_render",
                  "status": "queued",
                  "status_url": "/api/v1/jobs/5f1c0b2a-7d43-4e9a-8c16-0b5d3f7a2e94"
                },
                "schema": {
                  "$ref": "#/components/schemas/JobAcceptedResponse"
                }
              }
            }
          }
        },
        "x-mint": {
          "metadata": {
            "sidebarTitle": "Render photo mockup"
          }
        },
        "security": [
          {
            "ApiKeyAuth": []
          }
        ],
        "x-codeSamples": [
          {
            "lang": "Node.js",
            "source": "const response = await fetch(\"https://api.sudomock.com/api/v1/photo-mockups/3fa85f64-5717-4562-b3fc-2c963f66afa6/render\", {\n  method: \"POST\",\n  headers: {\n    \"x-api-key\": \"sm_your_api_key\",\n    \"Content-Type\": \"application/json\",\n  },\n  body: JSON.stringify({\n    \"export_options\": {\n      \"image_format\": \"webp\",\n      \"image_size\": 1920,\n      \"quality\": 95\n    },\n    \"print_areas\": [\n      {\n        \"adjustments\": {\n          \"blend_mode\": \"multiply\",\n          \"opacity\": 90\n        },\n        \"artwork_url\": \"https://example.com/design.png\",\n        \"placement\": {\n          \"fit\": \"fit\",\n          \"position\": \"center\"\n        },\n        \"uuid\": \"223e4567-e89b-12d3-a456-426614174001\"\n      }\n    ]\n  }),\n});\n\nconst data = await response.json();\nconsole.log(data);"
          },
          {
            "lang": "PHP",
            "source": "<?php\n\n$payload = <<<'JSON'\n{\n  \"export_options\": {\n    \"image_format\": \"webp\",\n    \"image_size\": 1920,\n    \"quality\": 95\n  },\n  \"print_areas\": [\n    {\n      \"adjustments\": {\n        \"blend_mode\": \"multiply\",\n        \"opacity\": 90\n      },\n      \"artwork_url\": \"https://example.com/design.png\",\n      \"placement\": {\n        \"fit\": \"fit\",\n        \"position\": \"center\"\n      },\n      \"uuid\": \"223e4567-e89b-12d3-a456-426614174001\"\n    }\n  ]\n}\nJSON;\n\n$ch = curl_init(\"https://api.sudomock.com/api/v1/photo-mockups/3fa85f64-5717-4562-b3fc-2c963f66afa6/render\");\ncurl_setopt($ch, CURLOPT_CUSTOMREQUEST, \"POST\");\ncurl_setopt($ch, CURLOPT_RETURNTRANSFER, true);\ncurl_setopt($ch, CURLOPT_HTTPHEADER, [\n    \"x-api-key: sm_your_api_key\",\n    \"Content-Type: application/json\",\n]);\ncurl_setopt($ch, CURLOPT_POSTFIELDS, $payload);\n\n$response = curl_exec($ch);\ncurl_close($ch);\n\necho $response;"
          },
          {
            "lang": "Python",
            "source": "import requests\n\npayload = {\n    \"export_options\": {\n        \"image_format\": \"webp\",\n        \"image_size\": 1920,\n        \"quality\": 95\n    },\n    \"print_areas\": [\n        {\n            \"adjustments\": {\n                \"blend_mode\": \"multiply\",\n                \"opacity\": 90\n            },\n            \"artwork_url\": \"https://example.com/design.png\",\n            \"placement\": {\n                \"fit\": \"fit\",\n                \"position\": \"center\"\n            },\n            \"uuid\": \"223e4567-e89b-12d3-a456-426614174001\"\n        }\n    ]\n}\n\nresponse = requests.post(\n    \"https://api.sudomock.com/api/v1/photo-mockups/3fa85f64-5717-4562-b3fc-2c963f66afa6/render\",\n    headers={\"x-api-key\": \"sm_your_api_key\"},\n    json=payload,\n)\n\nresponse.raise_for_status()\nprint(response.json())"
          },
          {
            "lang": "Ruby",
            "source": "require \"net/http\"\nrequire \"uri\"\n\nuri = URI(\"https://api.sudomock.com/api/v1/photo-mockups/3fa85f64-5717-4562-b3fc-2c963f66afa6/render\")\nrequest = Net::HTTP::Post.new(uri)\nrequest[\"x-api-key\"] = \"sm_your_api_key\"\nrequest[\"Content-Type\"] = \"application/json\"\n\nrequest.body = <<~JSON\n  {\n    \"export_options\": {\n      \"image_format\": \"webp\",\n      \"image_size\": 1920,\n      \"quality\": 95\n    },\n    \"print_areas\": [\n      {\n        \"adjustments\": {\n          \"blend_mode\": \"multiply\",\n          \"opacity\": 90\n        },\n        \"artwork_url\": \"https://example.com/design.png\",\n        \"placement\": {\n          \"fit\": \"fit\",\n          \"position\": \"center\"\n        },\n        \"uuid\": \"223e4567-e89b-12d3-a456-426614174001\"\n      }\n    ]\n  }\nJSON\n\nresponse = Net::HTTP.start(uri.host, uri.port, use_ssl: true) do |http|\n  http.request(request)\nend\n\nputs response.body"
          },
          {
            "lang": "Go",
            "source": "package main\n\nimport (\n\t\"bytes\"\n\t\"fmt\"\n\t\"io\"\n\t\"net/http\"\n)\n\nfunc main() {\n\tpayload := []byte(`{\n  \"export_options\": {\n    \"image_format\": \"webp\",\n    \"image_size\": 1920,\n    \"quality\": 95\n  },\n  \"print_areas\": [\n    {\n      \"adjustments\": {\n        \"blend_mode\": \"multiply\",\n        \"opacity\": 90\n      },\n      \"artwork_url\": \"https://example.com/design.png\",\n      \"placement\": {\n        \"fit\": \"fit\",\n        \"position\": \"center\"\n      },\n      \"uuid\": \"223e4567-e89b-12d3-a456-426614174001\"\n    }\n  ]\n}`)\n\n\treq, err := http.NewRequest(\"POST\", \"https://api.sudomock.com/api/v1/photo-mockups/3fa85f64-5717-4562-b3fc-2c963f66afa6/render\", bytes.NewBuffer(payload))\n\tif err != nil {\n\t\tpanic(err)\n\t}\n\treq.Header.Set(\"x-api-key\", \"sm_your_api_key\")\n\treq.Header.Set(\"Content-Type\", \"application/json\")\n\n\tres, err := http.DefaultClient.Do(req)\n\tif err != nil {\n\t\tpanic(err)\n\t}\n\tdefer res.Body.Close()\n\n\tbody, _ := io.ReadAll(res.Body)\n\tfmt.Println(string(body))\n}"
          },
          {
            "lang": "Java",
            "source": "import java.net.URI;\nimport java.net.http.HttpClient;\nimport java.net.http.HttpRequest;\nimport java.net.http.HttpResponse;\n\nString payload = \"\"\"\n{\n  \"export_options\": {\n    \"image_format\": \"webp\",\n    \"image_size\": 1920,\n    \"quality\": 95\n  },\n  \"print_areas\": [\n    {\n      \"adjustments\": {\n        \"blend_mode\": \"multiply\",\n        \"opacity\": 90\n      },\n      \"artwork_url\": \"https://example.com/design.png\",\n      \"placement\": {\n        \"fit\": \"fit\",\n        \"position\": \"center\"\n      },\n      \"uuid\": \"223e4567-e89b-12d3-a456-426614174001\"\n    }\n  ]\n}\n\"\"\";\n\nHttpRequest request = HttpRequest.newBuilder()\n    .uri(URI.create(\"https://api.sudomock.com/api/v1/photo-mockups/3fa85f64-5717-4562-b3fc-2c963f66afa6/render\"))\n    .header(\"x-api-key\", \"sm_your_api_key\")\n    .header(\"Content-Type\", \"application/json\")\n    .POST(HttpRequest.BodyPublishers.ofString(payload))\n    .build();\n\nHttpResponse<String> response = HttpClient.newHttpClient()\n    .send(request, HttpResponse.BodyHandlers.ofString());\n\nSystem.out.println(response.body());"
          },
          {
            "lang": ".NET",
            "source": "using System.Net.Http;\nusing System.Text;\n\nvar payload = \"\"\"\n{\n  \"export_options\": {\n    \"image_format\": \"webp\",\n    \"image_size\": 1920,\n    \"quality\": 95\n  },\n  \"print_areas\": [\n    {\n      \"adjustments\": {\n        \"blend_mode\": \"multiply\",\n        \"opacity\": 90\n      },\n      \"artwork_url\": \"https://example.com/design.png\",\n      \"placement\": {\n        \"fit\": \"fit\",\n        \"position\": \"center\"\n      },\n      \"uuid\": \"223e4567-e89b-12d3-a456-426614174001\"\n    }\n  ]\n}\n\"\"\";\n\nvar request = new HttpRequestMessage(HttpMethod.Post, \"https://api.sudomock.com/api/v1/photo-mockups/3fa85f64-5717-4562-b3fc-2c963f66afa6/render\");\nrequest.Headers.Add(\"x-api-key\", \"sm_your_api_key\");\nrequest.Content = new StringContent(payload, Encoding.UTF8, \"application/json\");\n\nvar client = new HttpClient();\nvar response = await client.SendAsync(request);\n\nConsole.WriteLine(await response.Content.ReadAsStringAsync());"
          },
          {
            "lang": "cURL",
            "source": "curl -X POST \"https://api.sudomock.com/api/v1/photo-mockups/3fa85f64-5717-4562-b3fc-2c963f66afa6/render\" \\\n  -H \"x-api-key: sm_your_api_key\" \\\n  -H \"Content-Type: application/json\" \\\n  -d '{\n    \"export_options\": {\n      \"image_format\": \"webp\",\n      \"image_size\": 1920,\n      \"quality\": 95\n    },\n    \"print_areas\": [\n      {\n        \"adjustments\": {\n          \"blend_mode\": \"multiply\",\n          \"opacity\": 90\n        },\n        \"artwork_url\": \"https://example.com/design.png\",\n        \"placement\": {\n          \"fit\": \"fit\",\n          \"position\": \"center\"\n        },\n        \"uuid\": \"223e4567-e89b-12d3-a456-426614174001\"\n      }\n    ]\n  }'"
          }
        ]
      }
    },
    "/api/v1/sudoai/2d-mockups": {
      "post": {
        "tags": [
          "Photo mockups"
        ],
        "summary": "Create a mockup from a product photo",
        "description": "Turns one product photo into a reusable mockup. By default the request returns the ready mockup; set is_async=true to receive a job URL. Costs 25 credits.",
        "operationId": "create_public_2d_mockup_api_v1_sudoai_2d_mockups_post",
        "deprecated": true,
        "requestBody": {
          "required": true,
          "content": {
            "application/json": {
              "schema": {
                "$ref": "#/components/schemas/PhotoMockupCreateRequest"
              }
            }
          }
        },
        "responses": {
          "201": {
            "description": "Successful Response",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/PhotoMockupDetailResponse"
                }
              }
            }
          },
          "202": {
            "description": "Async creation job accepted",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/PhotoMockupCreateAcceptedResponse"
                }
              }
            }
          }
        },
        "x-mint": {
          "metadata": {
            "sidebarTitle": "Create photo mockup"
          }
        },
        "security": [
          {
            "ApiKeyAuth": []
          }
        ],
        "x-codeSamples": [
          {
            "lang": "Node.js",
            "source": "const response = await fetch(\"https://api.sudomock.com/api/v1/sudoai/2d-mockups\", {\n  method: \"POST\",\n  headers: {\n    \"x-api-key\": \"sm_your_api_key\",\n    \"Content-Type\": \"application/json\",\n  },\n  body: JSON.stringify({\n    \"name\": \"Front view\",\n    \"source_url\": \"https://example.com/product-photo.jpg\"\n  }),\n});\n\nconst data = await response.json();\nconsole.log(data);"
          },
          {
            "lang": "PHP",
            "source": "<?php\n\n$payload = <<<'JSON'\n{\n  \"name\": \"Front view\",\n  \"source_url\": \"https://example.com/product-photo.jpg\"\n}\nJSON;\n\n$ch = curl_init(\"https://api.sudomock.com/api/v1/sudoai/2d-mockups\");\ncurl_setopt($ch, CURLOPT_CUSTOMREQUEST, \"POST\");\ncurl_setopt($ch, CURLOPT_RETURNTRANSFER, true);\ncurl_setopt($ch, CURLOPT_HTTPHEADER, [\n    \"x-api-key: sm_your_api_key\",\n    \"Content-Type: application/json\",\n]);\ncurl_setopt($ch, CURLOPT_POSTFIELDS, $payload);\n\n$response = curl_exec($ch);\ncurl_close($ch);\n\necho $response;"
          },
          {
            "lang": "Python",
            "source": "import requests\n\npayload = {\n    \"name\": \"Front view\",\n    \"source_url\": \"https://example.com/product-photo.jpg\"\n}\n\nresponse = requests.post(\n    \"https://api.sudomock.com/api/v1/sudoai/2d-mockups\",\n    headers={\"x-api-key\": \"sm_your_api_key\"},\n    json=payload,\n)\n\nresponse.raise_for_status()\nprint(response.json())"
          },
          {
            "lang": "Ruby",
            "source": "require \"net/http\"\nrequire \"uri\"\n\nuri = URI(\"https://api.sudomock.com/api/v1/sudoai/2d-mockups\")\nrequest = Net::HTTP::Post.new(uri)\nrequest[\"x-api-key\"] = \"sm_your_api_key\"\nrequest[\"Content-Type\"] = \"application/json\"\n\nrequest.body = <<~JSON\n  {\n    \"name\": \"Front view\",\n    \"source_url\": \"https://example.com/product-photo.jpg\"\n  }\nJSON\n\nresponse = Net::HTTP.start(uri.host, uri.port, use_ssl: true) do |http|\n  http.request(request)\nend\n\nputs response.body"
          },
          {
            "lang": "Go",
            "source": "package main\n\nimport (\n\t\"bytes\"\n\t\"fmt\"\n\t\"io\"\n\t\"net/http\"\n)\n\nfunc main() {\n\tpayload := []byte(`{\n  \"name\": \"Front view\",\n  \"source_url\": \"https://example.com/product-photo.jpg\"\n}`)\n\n\treq, err := http.NewRequest(\"POST\", \"https://api.sudomock.com/api/v1/sudoai/2d-mockups\", bytes.NewBuffer(payload))\n\tif err != nil {\n\t\tpanic(err)\n\t}\n\treq.Header.Set(\"x-api-key\", \"sm_your_api_key\")\n\treq.Header.Set(\"Content-Type\", \"application/json\")\n\n\tres, err := http.DefaultClient.Do(req)\n\tif err != nil {\n\t\tpanic(err)\n\t}\n\tdefer res.Body.Close()\n\n\tbody, _ := io.ReadAll(res.Body)\n\tfmt.Println(string(body))\n}"
          },
          {
            "lang": "Java",
            "source": "import java.net.URI;\nimport java.net.http.HttpClient;\nimport java.net.http.HttpRequest;\nimport java.net.http.HttpResponse;\n\nString payload = \"\"\"\n{\n  \"name\": \"Front view\",\n  \"source_url\": \"https://example.com/product-photo.jpg\"\n}\n\"\"\";\n\nHttpRequest request = HttpRequest.newBuilder()\n    .uri(URI.create(\"https://api.sudomock.com/api/v1/sudoai/2d-mockups\"))\n    .header(\"x-api-key\", \"sm_your_api_key\")\n    .header(\"Content-Type\", \"application/json\")\n    .POST(HttpRequest.BodyPublishers.ofString(payload))\n    .build();\n\nHttpResponse<String> response = HttpClient.newHttpClient()\n    .send(request, HttpResponse.BodyHandlers.ofString());\n\nSystem.out.println(response.body());"
          },
          {
            "lang": ".NET",
            "source": "using System.Net.Http;\nusing System.Text;\n\nvar payload = \"\"\"\n{\n  \"name\": \"Front view\",\n  \"source_url\": \"https://example.com/product-photo.jpg\"\n}\n\"\"\";\n\nvar request = new HttpRequestMessage(HttpMethod.Post, \"https://api.sudomock.com/api/v1/sudoai/2d-mockups\");\nrequest.Headers.Add(\"x-api-key\", \"sm_your_api_key\");\nrequest.Content = new StringContent(payload, Encoding.UTF8, \"application/json\");\n\nvar client = new HttpClient();\nvar response = await client.SendAsync(request);\n\nConsole.WriteLine(await response.Content.ReadAsStringAsync());"
          },
          {
            "lang": "cURL",
            "source": "curl -X POST \"https://api.sudomock.com/api/v1/sudoai/2d-mockups\" \\\n  -H \"x-api-key: sm_your_api_key\" \\\n  -H \"Content-Type: application/json\" \\\n  -d '{\n    \"name\": \"Front view\",\n    \"source_url\": \"https://example.com/product-photo.jpg\"\n  }'"
          }
        ],
        "x-hidden": true
      },
      "get": {
        "tags": [
          "Photo mockups"
        ],
        "summary": "Retrieve a list of photo mockups",
        "description": "Returns a paginated list of the user's photo mockups with print area summaries. Each mockup includes its status, thumbnail, dimensions, and print area names/bboxes. Ordered by creation date (newest first).",
        "operationId": "list_2d_mockups_api_v1_sudoai_2d_mockups_get",
        "deprecated": true,
        "parameters": [
          {
            "name": "limit",
            "in": "query",
            "required": false,
            "schema": {
              "type": "integer",
              "maximum": 100,
              "minimum": 1,
              "description": "Items per page (max 100)",
              "default": 20
            },
            "description": "Items per page (max 100)"
          },
          {
            "name": "offset",
            "in": "query",
            "required": false,
            "schema": {
              "type": "integer",
              "minimum": 0,
              "description": "Pagination offset",
              "default": 0
            },
            "description": "Pagination offset"
          },
          {
            "name": "customizable_only",
            "in": "query",
            "required": false,
            "schema": {
              "type": "boolean",
              "description": "Return only mockups ready for customization",
              "default": false
            },
            "description": "Return only mockups ready for customization"
          }
        ],
        "responses": {
          "200": {
            "description": "Successful Response",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/PhotoMockupList"
                }
              }
            }
          }
        },
        "security": [
          {
            "ApiKeyAuth": []
          }
        ],
        "x-codeSamples": [
          {
            "lang": "Node.js",
            "source": "const response = await fetch(\"https://api.sudomock.com/api/v1/sudoai/2d-mockups\", {\n  method: \"GET\",\n  headers: { \"x-api-key\": \"sm_your_api_key\" },\n});\n\nconst data = await response.json();\nconsole.log(data);"
          },
          {
            "lang": "PHP",
            "source": "<?php\n\n$ch = curl_init(\"https://api.sudomock.com/api/v1/sudoai/2d-mockups\");\ncurl_setopt($ch, CURLOPT_CUSTOMREQUEST, \"GET\");\ncurl_setopt($ch, CURLOPT_RETURNTRANSFER, true);\ncurl_setopt($ch, CURLOPT_HTTPHEADER, [\n    \"x-api-key: sm_your_api_key\",\n]);\n\n$response = curl_exec($ch);\ncurl_close($ch);\n\necho $response;"
          },
          {
            "lang": "Python",
            "source": "import requests\n\nresponse = requests.get(\n    \"https://api.sudomock.com/api/v1/sudoai/2d-mockups\",\n    headers={\"x-api-key\": \"sm_your_api_key\"},\n)\n\nresponse.raise_for_status()\nprint(response.json())"
          },
          {
            "lang": "Ruby",
            "source": "require \"net/http\"\nrequire \"uri\"\n\nuri = URI(\"https://api.sudomock.com/api/v1/sudoai/2d-mockups\")\nrequest = Net::HTTP::Get.new(uri)\nrequest[\"x-api-key\"] = \"sm_your_api_key\"\n\nresponse = Net::HTTP.start(uri.host, uri.port, use_ssl: true) do |http|\n  http.request(request)\nend\n\nputs response.body"
          },
          {
            "lang": "Go",
            "source": "package main\n\nimport (\n\t\"fmt\"\n\t\"io\"\n\t\"net/http\"\n)\n\nfunc main() {\n\treq, err := http.NewRequest(\"GET\", \"https://api.sudomock.com/api/v1/sudoai/2d-mockups\", nil)\n\tif err != nil {\n\t\tpanic(err)\n\t}\n\treq.Header.Set(\"x-api-key\", \"sm_your_api_key\")\n\n\tres, err := http.DefaultClient.Do(req)\n\tif err != nil {\n\t\tpanic(err)\n\t}\n\tdefer res.Body.Close()\n\n\tbody, _ := io.ReadAll(res.Body)\n\tfmt.Println(string(body))\n}"
          },
          {
            "lang": "Java",
            "source": "import java.net.URI;\nimport java.net.http.HttpClient;\nimport java.net.http.HttpRequest;\nimport java.net.http.HttpResponse;\n\nHttpRequest request = HttpRequest.newBuilder()\n    .uri(URI.create(\"https://api.sudomock.com/api/v1/sudoai/2d-mockups\"))\n    .header(\"x-api-key\", \"sm_your_api_key\")\n    .GET()\n    .build();\n\nHttpResponse<String> response = HttpClient.newHttpClient()\n    .send(request, HttpResponse.BodyHandlers.ofString());\n\nSystem.out.println(response.body());"
          },
          {
            "lang": ".NET",
            "source": "using System.Net.Http;\nusing System.Text;\n\nvar request = new HttpRequestMessage(HttpMethod.Get, \"https://api.sudomock.com/api/v1/sudoai/2d-mockups\");\nrequest.Headers.Add(\"x-api-key\", \"sm_your_api_key\");\n\nvar client = new HttpClient();\nvar response = await client.SendAsync(request);\n\nConsole.WriteLine(await response.Content.ReadAsStringAsync());"
          },
          {
            "lang": "cURL",
            "source": "curl -X GET \"https://api.sudomock.com/api/v1/sudoai/2d-mockups\" \\\n  -H \"x-api-key: sm_your_api_key\""
          }
        ],
        "x-hidden": true
      }
    },
    "/api/v1/sudoai/2d-mockups/{mockup_id}/print-areas": {
      "put": {
        "tags": [
          "Photo mockups"
        ],
        "summary": "Replace the print areas of a photo mockup",
        "description": "Replaces a ready photo mockup's printable areas. Each area must be a convex four-point shape within the source image.",
        "operationId": "replace_public_2d_print_areas_api_v1_sudoai_2d_mockups__mockup_id__print_areas_put",
        "deprecated": true,
        "parameters": [
          {
            "name": "mockup_id",
            "in": "path",
            "required": true,
            "schema": {
              "type": "string",
              "description": "Id of the photo mockup whose print areas are replaced."
            },
            "description": "Id of the photo mockup whose print areas are replaced."
          }
        ],
        "requestBody": {
          "required": true,
          "content": {
            "application/json": {
              "schema": {
                "$ref": "#/components/schemas/PhotoMockupPrintAreasUpdate"
              }
            }
          }
        },
        "responses": {
          "200": {
            "description": "Successful Response",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/PhotoMockupPrintAreasUpdateResponse"
                }
              }
            }
          }
        },
        "x-mint": {
          "metadata": {
            "sidebarTitle": "Replace print areas"
          }
        },
        "security": [
          {
            "ApiKeyAuth": []
          }
        ],
        "x-codeSamples": [
          {
            "lang": "Node.js",
            "source": "const response = await fetch(\"https://api.sudomock.com/api/v1/sudoai/2d-mockups/3fa85f64-5717-4562-b3fc-2c963f66afa6/print-areas\", {\n  method: \"PUT\",\n  headers: {\n    \"x-api-key\": \"sm_your_api_key\",\n    \"Content-Type\": \"application/json\",\n  },\n  body: JSON.stringify({\n    \"print_areas\": [\n      {\n        \"points\": [\n          [\n            200,\n            150\n          ],\n          [\n            600,\n            150\n          ],\n          [\n            620,\n            550\n          ],\n          [\n            180,\n            550\n          ]\n        ]\n      }\n    ]\n  }),\n});\n\nconst data = await response.json();\nconsole.log(data);"
          },
          {
            "lang": "PHP",
            "source": "<?php\n\n$payload = <<<'JSON'\n{\n  \"print_areas\": [\n    {\n      \"points\": [\n        [\n          200,\n          150\n        ],\n        [\n          600,\n          150\n        ],\n        [\n          620,\n          550\n        ],\n        [\n          180,\n          550\n        ]\n      ]\n    }\n  ]\n}\nJSON;\n\n$ch = curl_init(\"https://api.sudomock.com/api/v1/sudoai/2d-mockups/3fa85f64-5717-4562-b3fc-2c963f66afa6/print-areas\");\ncurl_setopt($ch, CURLOPT_CUSTOMREQUEST, \"PUT\");\ncurl_setopt($ch, CURLOPT_RETURNTRANSFER, true);\ncurl_setopt($ch, CURLOPT_HTTPHEADER, [\n    \"x-api-key: sm_your_api_key\",\n    \"Content-Type: application/json\",\n]);\ncurl_setopt($ch, CURLOPT_POSTFIELDS, $payload);\n\n$response = curl_exec($ch);\ncurl_close($ch);\n\necho $response;"
          },
          {
            "lang": "Python",
            "source": "import requests\n\npayload = {\n    \"print_areas\": [\n        {\n            \"points\": [\n                [\n                    200,\n                    150\n                ],\n                [\n                    600,\n                    150\n                ],\n                [\n                    620,\n                    550\n                ],\n                [\n                    180,\n                    550\n                ]\n            ]\n        }\n    ]\n}\n\nresponse = requests.put(\n    \"https://api.sudomock.com/api/v1/sudoai/2d-mockups/3fa85f64-5717-4562-b3fc-2c963f66afa6/print-areas\",\n    headers={\"x-api-key\": \"sm_your_api_key\"},\n    json=payload,\n)\n\nresponse.raise_for_status()\nprint(response.json())"
          },
          {
            "lang": "Ruby",
            "source": "require \"net/http\"\nrequire \"uri\"\n\nuri = URI(\"https://api.sudomock.com/api/v1/sudoai/2d-mockups/3fa85f64-5717-4562-b3fc-2c963f66afa6/print-areas\")\nrequest = Net::HTTP::Put.new(uri)\nrequest[\"x-api-key\"] = \"sm_your_api_key\"\nrequest[\"Content-Type\"] = \"application/json\"\n\nrequest.body = <<~JSON\n  {\n    \"print_areas\": [\n      {\n        \"points\": [\n          [\n            200,\n            150\n          ],\n          [\n            600,\n            150\n          ],\n          [\n            620,\n            550\n          ],\n          [\n            180,\n            550\n          ]\n        ]\n      }\n    ]\n  }\nJSON\n\nresponse = Net::HTTP.start(uri.host, uri.port, use_ssl: true) do |http|\n  http.request(request)\nend\n\nputs response.body"
          },
          {
            "lang": "Go",
            "source": "package main\n\nimport (\n\t\"bytes\"\n\t\"fmt\"\n\t\"io\"\n\t\"net/http\"\n)\n\nfunc main() {\n\tpayload := []byte(`{\n  \"print_areas\": [\n    {\n      \"points\": [\n        [\n          200,\n          150\n        ],\n        [\n          600,\n          150\n        ],\n        [\n          620,\n          550\n        ],\n        [\n          180,\n          550\n        ]\n      ]\n    }\n  ]\n}`)\n\n\treq, err := http.NewRequest(\"PUT\", \"https://api.sudomock.com/api/v1/sudoai/2d-mockups/3fa85f64-5717-4562-b3fc-2c963f66afa6/print-areas\", bytes.NewBuffer(payload))\n\tif err != nil {\n\t\tpanic(err)\n\t}\n\treq.Header.Set(\"x-api-key\", \"sm_your_api_key\")\n\treq.Header.Set(\"Content-Type\", \"application/json\")\n\n\tres, err := http.DefaultClient.Do(req)\n\tif err != nil {\n\t\tpanic(err)\n\t}\n\tdefer res.Body.Close()\n\n\tbody, _ := io.ReadAll(res.Body)\n\tfmt.Println(string(body))\n}"
          },
          {
            "lang": "Java",
            "source": "import java.net.URI;\nimport java.net.http.HttpClient;\nimport java.net.http.HttpRequest;\nimport java.net.http.HttpResponse;\n\nString payload = \"\"\"\n{\n  \"print_areas\": [\n    {\n      \"points\": [\n        [\n          200,\n          150\n        ],\n        [\n          600,\n          150\n        ],\n        [\n          620,\n          550\n        ],\n        [\n          180,\n          550\n        ]\n      ]\n    }\n  ]\n}\n\"\"\";\n\nHttpRequest request = HttpRequest.newBuilder()\n    .uri(URI.create(\"https://api.sudomock.com/api/v1/sudoai/2d-mockups/3fa85f64-5717-4562-b3fc-2c963f66afa6/print-areas\"))\n    .header(\"x-api-key\", \"sm_your_api_key\")\n    .header(\"Content-Type\", \"application/json\")\n    .PUT(HttpRequest.BodyPublishers.ofString(payload))\n    .build();\n\nHttpResponse<String> response = HttpClient.newHttpClient()\n    .send(request, HttpResponse.BodyHandlers.ofString());\n\nSystem.out.println(response.body());"
          },
          {
            "lang": ".NET",
            "source": "using System.Net.Http;\nusing System.Text;\n\nvar payload = \"\"\"\n{\n  \"print_areas\": [\n    {\n      \"points\": [\n        [\n          200,\n          150\n        ],\n        [\n          600,\n          150\n        ],\n        [\n          620,\n          550\n        ],\n        [\n          180,\n          550\n        ]\n      ]\n    }\n  ]\n}\n\"\"\";\n\nvar request = new HttpRequestMessage(HttpMethod.Put, \"https://api.sudomock.com/api/v1/sudoai/2d-mockups/3fa85f64-5717-4562-b3fc-2c963f66afa6/print-areas\");\nrequest.Headers.Add(\"x-api-key\", \"sm_your_api_key\");\nrequest.Content = new StringContent(payload, Encoding.UTF8, \"application/json\");\n\nvar client = new HttpClient();\nvar response = await client.SendAsync(request);\n\nConsole.WriteLine(await response.Content.ReadAsStringAsync());"
          },
          {
            "lang": "cURL",
            "source": "curl -X PUT \"https://api.sudomock.com/api/v1/sudoai/2d-mockups/3fa85f64-5717-4562-b3fc-2c963f66afa6/print-areas\" \\\n  -H \"x-api-key: sm_your_api_key\" \\\n  -H \"Content-Type: application/json\" \\\n  -d '{\n    \"print_areas\": [\n      {\n        \"points\": [\n          [\n            200,\n            150\n          ],\n          [\n            600,\n            150\n          ],\n          [\n            620,\n            550\n          ],\n          [\n            180,\n            550\n          ]\n        ]\n      }\n    ]\n  }'"
          }
        ],
        "x-hidden": true
      }
    },
    "/api/v1/sudoai/2d-mockups/{mockup_id}": {
      "get": {
        "tags": [
          "Photo mockups"
        ],
        "summary": "Retrieve a single photo mockup",
        "description": "Returns mockup metadata and print-area summaries. Use the mockup_id with POST /api/v1/photo-mockups/{mockup_id}/render to render artwork.",
        "operationId": "get_2d_mockup_public_api_v1_sudoai_2d_mockups__mockup_id__get",
        "deprecated": true,
        "parameters": [
          {
            "name": "mockup_id",
            "in": "path",
            "required": true,
            "schema": {
              "type": "string",
              "description": "Id of the photo mockup to read, as returned when it was created."
            },
            "description": "Id of the photo mockup to read, as returned when it was created."
          }
        ],
        "responses": {
          "200": {
            "description": "Successful Response",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/PhotoMockupDetailResponse"
                }
              }
            }
          }
        },
        "x-mint": {
          "metadata": {
            "sidebarTitle": "Get photo mockup"
          }
        },
        "security": [
          {
            "ApiKeyAuth": []
          }
        ],
        "x-codeSamples": [
          {
            "lang": "Node.js",
            "source": "const response = await fetch(\"https://api.sudomock.com/api/v1/sudoai/2d-mockups/3fa85f64-5717-4562-b3fc-2c963f66afa6\", {\n  method: \"GET\",\n  headers: { \"x-api-key\": \"sm_your_api_key\" },\n});\n\nconst data = await response.json();\nconsole.log(data);"
          },
          {
            "lang": "PHP",
            "source": "<?php\n\n$ch = curl_init(\"https://api.sudomock.com/api/v1/sudoai/2d-mockups/3fa85f64-5717-4562-b3fc-2c963f66afa6\");\ncurl_setopt($ch, CURLOPT_CUSTOMREQUEST, \"GET\");\ncurl_setopt($ch, CURLOPT_RETURNTRANSFER, true);\ncurl_setopt($ch, CURLOPT_HTTPHEADER, [\n    \"x-api-key: sm_your_api_key\",\n]);\n\n$response = curl_exec($ch);\ncurl_close($ch);\n\necho $response;"
          },
          {
            "lang": "Python",
            "source": "import requests\n\nresponse = requests.get(\n    \"https://api.sudomock.com/api/v1/sudoai/2d-mockups/3fa85f64-5717-4562-b3fc-2c963f66afa6\",\n    headers={\"x-api-key\": \"sm_your_api_key\"},\n)\n\nresponse.raise_for_status()\nprint(response.json())"
          },
          {
            "lang": "Ruby",
            "source": "require \"net/http\"\nrequire \"uri\"\n\nuri = URI(\"https://api.sudomock.com/api/v1/sudoai/2d-mockups/3fa85f64-5717-4562-b3fc-2c963f66afa6\")\nrequest = Net::HTTP::Get.new(uri)\nrequest[\"x-api-key\"] = \"sm_your_api_key\"\n\nresponse = Net::HTTP.start(uri.host, uri.port, use_ssl: true) do |http|\n  http.request(request)\nend\n\nputs response.body"
          },
          {
            "lang": "Go",
            "source": "package main\n\nimport (\n\t\"fmt\"\n\t\"io\"\n\t\"net/http\"\n)\n\nfunc main() {\n\treq, err := http.NewRequest(\"GET\", \"https://api.sudomock.com/api/v1/sudoai/2d-mockups/3fa85f64-5717-4562-b3fc-2c963f66afa6\", nil)\n\tif err != nil {\n\t\tpanic(err)\n\t}\n\treq.Header.Set(\"x-api-key\", \"sm_your_api_key\")\n\n\tres, err := http.DefaultClient.Do(req)\n\tif err != nil {\n\t\tpanic(err)\n\t}\n\tdefer res.Body.Close()\n\n\tbody, _ := io.ReadAll(res.Body)\n\tfmt.Println(string(body))\n}"
          },
          {
            "lang": "Java",
            "source": "import java.net.URI;\nimport java.net.http.HttpClient;\nimport java.net.http.HttpRequest;\nimport java.net.http.HttpResponse;\n\nHttpRequest request = HttpRequest.newBuilder()\n    .uri(URI.create(\"https://api.sudomock.com/api/v1/sudoai/2d-mockups/3fa85f64-5717-4562-b3fc-2c963f66afa6\"))\n    .header(\"x-api-key\", \"sm_your_api_key\")\n    .GET()\n    .build();\n\nHttpResponse<String> response = HttpClient.newHttpClient()\n    .send(request, HttpResponse.BodyHandlers.ofString());\n\nSystem.out.println(response.body());"
          },
          {
            "lang": ".NET",
            "source": "using System.Net.Http;\nusing System.Text;\n\nvar request = new HttpRequestMessage(HttpMethod.Get, \"https://api.sudomock.com/api/v1/sudoai/2d-mockups/3fa85f64-5717-4562-b3fc-2c963f66afa6\");\nrequest.Headers.Add(\"x-api-key\", \"sm_your_api_key\");\n\nvar client = new HttpClient();\nvar response = await client.SendAsync(request);\n\nConsole.WriteLine(await response.Content.ReadAsStringAsync());"
          },
          {
            "lang": "cURL",
            "source": "curl -X GET \"https://api.sudomock.com/api/v1/sudoai/2d-mockups/3fa85f64-5717-4562-b3fc-2c963f66afa6\" \\\n  -H \"x-api-key: sm_your_api_key\""
          }
        ],
        "x-hidden": true
      },
      "patch": {
        "tags": [
          "Photo mockups"
        ],
        "summary": "Update an existing photo mockup",
        "description": "Rename a mockup and/or set the colours it answers to by name. A render may then send a name where it would send a hex code.",
        "operationId": "update_2d_mockup_api_v1_sudoai_2d_mockups__mockup_id__patch",
        "deprecated": true,
        "parameters": [
          {
            "name": "mockup_id",
            "in": "path",
            "required": true,
            "schema": {
              "type": "string",
              "description": "Id of the photo mockup to rename or give named colours."
            },
            "description": "Id of the photo mockup to rename or give named colours."
          }
        ],
        "requestBody": {
          "required": true,
          "content": {
            "application/json": {
              "schema": {
                "$ref": "#/components/schemas/MockupUpdateRequest"
              }
            }
          }
        },
        "responses": {
          "200": {
            "description": "Successful Response",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/PhotoMockupUpdateResponse"
                }
              }
            }
          }
        },
        "x-mint": {
          "metadata": {
            "sidebarTitle": "Update photo mockup"
          }
        },
        "security": [
          {
            "ApiKeyAuth": []
          }
        ],
        "x-codeSamples": [
          {
            "lang": "Node.js",
            "source": "const response = await fetch(\"https://api.sudomock.com/api/v1/sudoai/2d-mockups/3fa85f64-5717-4562-b3fc-2c963f66afa6\", {\n  method: \"PATCH\",\n  headers: {\n    \"x-api-key\": \"sm_your_api_key\",\n    \"Content-Type\": \"application/json\",\n  },\n  body: JSON.stringify({\n    \"name\": \"Updated Mockup Name\"\n  }),\n});\n\nconst data = await response.json();\nconsole.log(data);"
          },
          {
            "lang": "PHP",
            "source": "<?php\n\n$payload = <<<'JSON'\n{\n  \"name\": \"Updated Mockup Name\"\n}\nJSON;\n\n$ch = curl_init(\"https://api.sudomock.com/api/v1/sudoai/2d-mockups/3fa85f64-5717-4562-b3fc-2c963f66afa6\");\ncurl_setopt($ch, CURLOPT_CUSTOMREQUEST, \"PATCH\");\ncurl_setopt($ch, CURLOPT_RETURNTRANSFER, true);\ncurl_setopt($ch, CURLOPT_HTTPHEADER, [\n    \"x-api-key: sm_your_api_key\",\n    \"Content-Type: application/json\",\n]);\ncurl_setopt($ch, CURLOPT_POSTFIELDS, $payload);\n\n$response = curl_exec($ch);\ncurl_close($ch);\n\necho $response;"
          },
          {
            "lang": "Python",
            "source": "import requests\n\npayload = {\n    \"name\": \"Updated Mockup Name\"\n}\n\nresponse = requests.patch(\n    \"https://api.sudomock.com/api/v1/sudoai/2d-mockups/3fa85f64-5717-4562-b3fc-2c963f66afa6\",\n    headers={\"x-api-key\": \"sm_your_api_key\"},\n    json=payload,\n)\n\nresponse.raise_for_status()\nprint(response.json())"
          },
          {
            "lang": "Ruby",
            "source": "require \"net/http\"\nrequire \"uri\"\n\nuri = URI(\"https://api.sudomock.com/api/v1/sudoai/2d-mockups/3fa85f64-5717-4562-b3fc-2c963f66afa6\")\nrequest = Net::HTTP::Patch.new(uri)\nrequest[\"x-api-key\"] = \"sm_your_api_key\"\nrequest[\"Content-Type\"] = \"application/json\"\n\nrequest.body = <<~JSON\n  {\n    \"name\": \"Updated Mockup Name\"\n  }\nJSON\n\nresponse = Net::HTTP.start(uri.host, uri.port, use_ssl: true) do |http|\n  http.request(request)\nend\n\nputs response.body"
          },
          {
            "lang": "Go",
            "source": "package main\n\nimport (\n\t\"bytes\"\n\t\"fmt\"\n\t\"io\"\n\t\"net/http\"\n)\n\nfunc main() {\n\tpayload := []byte(`{\n  \"name\": \"Updated Mockup Name\"\n}`)\n\n\treq, err := http.NewRequest(\"PATCH\", \"https://api.sudomock.com/api/v1/sudoai/2d-mockups/3fa85f64-5717-4562-b3fc-2c963f66afa6\", bytes.NewBuffer(payload))\n\tif err != nil {\n\t\tpanic(err)\n\t}\n\treq.Header.Set(\"x-api-key\", \"sm_your_api_key\")\n\treq.Header.Set(\"Content-Type\", \"application/json\")\n\n\tres, err := http.DefaultClient.Do(req)\n\tif err != nil {\n\t\tpanic(err)\n\t}\n\tdefer res.Body.Close()\n\n\tbody, _ := io.ReadAll(res.Body)\n\tfmt.Println(string(body))\n}"
          },
          {
            "lang": "Java",
            "source": "import java.net.URI;\nimport java.net.http.HttpClient;\nimport java.net.http.HttpRequest;\nimport java.net.http.HttpResponse;\n\nString payload = \"\"\"\n{\n  \"name\": \"Updated Mockup Name\"\n}\n\"\"\";\n\nHttpRequest request = HttpRequest.newBuilder()\n    .uri(URI.create(\"https://api.sudomock.com/api/v1/sudoai/2d-mockups/3fa85f64-5717-4562-b3fc-2c963f66afa6\"))\n    .header(\"x-api-key\", \"sm_your_api_key\")\n    .header(\"Content-Type\", \"application/json\")\n    .method(\"PATCH\", HttpRequest.BodyPublishers.ofString(payload))\n    .build();\n\nHttpResponse<String> response = HttpClient.newHttpClient()\n    .send(request, HttpResponse.BodyHandlers.ofString());\n\nSystem.out.println(response.body());"
          },
          {
            "lang": ".NET",
            "source": "using System.Net.Http;\nusing System.Text;\n\nvar payload = \"\"\"\n{\n  \"name\": \"Updated Mockup Name\"\n}\n\"\"\";\n\nvar request = new HttpRequestMessage(HttpMethod.Patch, \"https://api.sudomock.com/api/v1/sudoai/2d-mockups/3fa85f64-5717-4562-b3fc-2c963f66afa6\");\nrequest.Headers.Add(\"x-api-key\", \"sm_your_api_key\");\nrequest.Content = new StringContent(payload, Encoding.UTF8, \"application/json\");\n\nvar client = new HttpClient();\nvar response = await client.SendAsync(request);\n\nConsole.WriteLine(await response.Content.ReadAsStringAsync());"
          },
          {
            "lang": "cURL",
            "source": "curl -X PATCH \"https://api.sudomock.com/api/v1/sudoai/2d-mockups/3fa85f64-5717-4562-b3fc-2c963f66afa6\" \\\n  -H \"x-api-key: sm_your_api_key\" \\\n  -H \"Content-Type: application/json\" \\\n  -d '{\n    \"name\": \"Updated Mockup Name\"\n  }'"
          }
        ],
        "x-hidden": true
      },
      "delete": {
        "tags": [
          "Photo mockups"
        ],
        "summary": "Remove an existing photo mockup",
        "description": "Permanently deletes the mockup and its print areas. This action cannot be undone.",
        "operationId": "delete_2d_mockup_api_v1_sudoai_2d_mockups__mockup_id__delete",
        "deprecated": true,
        "parameters": [
          {
            "name": "mockup_id",
            "in": "path",
            "required": true,
            "schema": {
              "type": "string",
              "description": "Id of the photo mockup to delete together with its print areas."
            },
            "description": "Id of the photo mockup to delete together with its print areas."
          }
        ],
        "responses": {
          "200": {
            "description": "Successful Response",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/PhotoMockupDeleteResponse"
                }
              }
            }
          }
        },
        "x-mint": {
          "metadata": {
            "sidebarTitle": "Delete photo mockup"
          }
        },
        "security": [
          {
            "ApiKeyAuth": []
          }
        ],
        "x-codeSamples": [
          {
            "lang": "Node.js",
            "source": "const response = await fetch(\"https://api.sudomock.com/api/v1/sudoai/2d-mockups/3fa85f64-5717-4562-b3fc-2c963f66afa6\", {\n  method: \"DELETE\",\n  headers: { \"x-api-key\": \"sm_your_api_key\" },\n});\n\nconst data = await response.json();\nconsole.log(data);"
          },
          {
            "lang": "PHP",
            "source": "<?php\n\n$ch = curl_init(\"https://api.sudomock.com/api/v1/sudoai/2d-mockups/3fa85f64-5717-4562-b3fc-2c963f66afa6\");\ncurl_setopt($ch, CURLOPT_CUSTOMREQUEST, \"DELETE\");\ncurl_setopt($ch, CURLOPT_RETURNTRANSFER, true);\ncurl_setopt($ch, CURLOPT_HTTPHEADER, [\n    \"x-api-key: sm_your_api_key\",\n]);\n\n$response = curl_exec($ch);\ncurl_close($ch);\n\necho $response;"
          },
          {
            "lang": "Python",
            "source": "import requests\n\nresponse = requests.delete(\n    \"https://api.sudomock.com/api/v1/sudoai/2d-mockups/3fa85f64-5717-4562-b3fc-2c963f66afa6\",\n    headers={\"x-api-key\": \"sm_your_api_key\"},\n)\n\nresponse.raise_for_status()\nprint(response.json())"
          },
          {
            "lang": "Ruby",
            "source": "require \"net/http\"\nrequire \"uri\"\n\nuri = URI(\"https://api.sudomock.com/api/v1/sudoai/2d-mockups/3fa85f64-5717-4562-b3fc-2c963f66afa6\")\nrequest = Net::HTTP::Delete.new(uri)\nrequest[\"x-api-key\"] = \"sm_your_api_key\"\n\nresponse = Net::HTTP.start(uri.host, uri.port, use_ssl: true) do |http|\n  http.request(request)\nend\n\nputs response.body"
          },
          {
            "lang": "Go",
            "source": "package main\n\nimport (\n\t\"fmt\"\n\t\"io\"\n\t\"net/http\"\n)\n\nfunc main() {\n\treq, err := http.NewRequest(\"DELETE\", \"https://api.sudomock.com/api/v1/sudoai/2d-mockups/3fa85f64-5717-4562-b3fc-2c963f66afa6\", nil)\n\tif err != nil {\n\t\tpanic(err)\n\t}\n\treq.Header.Set(\"x-api-key\", \"sm_your_api_key\")\n\n\tres, err := http.DefaultClient.Do(req)\n\tif err != nil {\n\t\tpanic(err)\n\t}\n\tdefer res.Body.Close()\n\n\tbody, _ := io.ReadAll(res.Body)\n\tfmt.Println(string(body))\n}"
          },
          {
            "lang": "Java",
            "source": "import java.net.URI;\nimport java.net.http.HttpClient;\nimport java.net.http.HttpRequest;\nimport java.net.http.HttpResponse;\n\nHttpRequest request = HttpRequest.newBuilder()\n    .uri(URI.create(\"https://api.sudomock.com/api/v1/sudoai/2d-mockups/3fa85f64-5717-4562-b3fc-2c963f66afa6\"))\n    .header(\"x-api-key\", \"sm_your_api_key\")\n    .DELETE()\n    .build();\n\nHttpResponse<String> response = HttpClient.newHttpClient()\n    .send(request, HttpResponse.BodyHandlers.ofString());\n\nSystem.out.println(response.body());"
          },
          {
            "lang": ".NET",
            "source": "using System.Net.Http;\nusing System.Text;\n\nvar request = new HttpRequestMessage(HttpMethod.Delete, \"https://api.sudomock.com/api/v1/sudoai/2d-mockups/3fa85f64-5717-4562-b3fc-2c963f66afa6\");\nrequest.Headers.Add(\"x-api-key\", \"sm_your_api_key\");\n\nvar client = new HttpClient();\nvar response = await client.SendAsync(request);\n\nConsole.WriteLine(await response.Content.ReadAsStringAsync());"
          },
          {
            "lang": "cURL",
            "source": "curl -X DELETE \"https://api.sudomock.com/api/v1/sudoai/2d-mockups/3fa85f64-5717-4562-b3fc-2c963f66afa6\" \\\n  -H \"x-api-key: sm_your_api_key\""
          }
        ],
        "x-hidden": true
      }
    },
    "/api/v1/sudoai/2d-mockups/{mockup_id}/render": {
      "post": {
        "tags": [
          "Photo mockups"
        ],
        "summary": "Render a photo mockup",
        "description": "Renders artwork onto a previously created photo mockup identified by the path mockup_id. Artwork can target a saved print area or a whole product surface, and a product offers both. The mockup must be in 'ready' status. Costs 5 credits. Returns CDN URL(s) of the rendered image.",
        "operationId": "render_2d_mockup_public_api_v1_sudoai_2d_mockups__mockup_id__render_post",
        "deprecated": true,
        "parameters": [
          {
            "name": "mockup_id",
            "in": "path",
            "required": true,
            "schema": {
              "type": "string",
              "description": "Id of the photo mockup the artwork is rendered onto."
            },
            "description": "Id of the photo mockup the artwork is rendered onto."
          }
        ],
        "requestBody": {
          "required": true,
          "content": {
            "application/json": {
              "schema": {
                "$ref": "#/components/schemas/PhotoMockupRender"
              }
            }
          }
        },
        "responses": {
          "200": {
            "description": "Successful Response",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/PhotoMockupRenderResponse"
                }
              }
            }
          },
          "202": {
            "description": "Render queued (is_async=true). Poll status_url for the result, or receive a webhook on completion.",
            "content": {
              "application/json": {
                "example": {
                  "job_id": "5f1c0b2a-7d43-4e9a-8c16-0b5d3f7a2e94",
                  "kind": "photo_mockup_render",
                  "status": "queued",
                  "status_url": "/api/v1/jobs/5f1c0b2a-7d43-4e9a-8c16-0b5d3f7a2e94"
                },
                "schema": {
                  "$ref": "#/components/schemas/JobAcceptedResponse"
                }
              }
            }
          }
        },
        "x-mint": {
          "metadata": {
            "sidebarTitle": "Render photo mockup"
          }
        },
        "security": [
          {
            "ApiKeyAuth": []
          }
        ],
        "x-codeSamples": [
          {
            "lang": "Node.js",
            "source": "const response = await fetch(\"https://api.sudomock.com/api/v1/sudoai/2d-mockups/3fa85f64-5717-4562-b3fc-2c963f66afa6/render\", {\n  method: \"POST\",\n  headers: {\n    \"x-api-key\": \"sm_your_api_key\",\n    \"Content-Type\": \"application/json\",\n  },\n  body: JSON.stringify({\n    \"export_options\": {\n      \"image_format\": \"webp\",\n      \"image_size\": 1920,\n      \"quality\": 95\n    },\n    \"print_areas\": [\n      {\n        \"adjustments\": {\n          \"blend_mode\": \"multiply\",\n          \"opacity\": 90\n        },\n        \"artwork_url\": \"https://example.com/design.png\",\n        \"placement\": {\n          \"fit\": \"fit\",\n          \"position\": \"center\"\n        },\n        \"uuid\": \"223e4567-e89b-12d3-a456-426614174001\"\n      }\n    ]\n  }),\n});\n\nconst data = await response.json();\nconsole.log(data);"
          },
          {
            "lang": "PHP",
            "source": "<?php\n\n$payload = <<<'JSON'\n{\n  \"export_options\": {\n    \"image_format\": \"webp\",\n    \"image_size\": 1920,\n    \"quality\": 95\n  },\n  \"print_areas\": [\n    {\n      \"adjustments\": {\n        \"blend_mode\": \"multiply\",\n        \"opacity\": 90\n      },\n      \"artwork_url\": \"https://example.com/design.png\",\n      \"placement\": {\n        \"fit\": \"fit\",\n        \"position\": \"center\"\n      },\n      \"uuid\": \"223e4567-e89b-12d3-a456-426614174001\"\n    }\n  ]\n}\nJSON;\n\n$ch = curl_init(\"https://api.sudomock.com/api/v1/sudoai/2d-mockups/3fa85f64-5717-4562-b3fc-2c963f66afa6/render\");\ncurl_setopt($ch, CURLOPT_CUSTOMREQUEST, \"POST\");\ncurl_setopt($ch, CURLOPT_RETURNTRANSFER, true);\ncurl_setopt($ch, CURLOPT_HTTPHEADER, [\n    \"x-api-key: sm_your_api_key\",\n    \"Content-Type: application/json\",\n]);\ncurl_setopt($ch, CURLOPT_POSTFIELDS, $payload);\n\n$response = curl_exec($ch);\ncurl_close($ch);\n\necho $response;"
          },
          {
            "lang": "Python",
            "source": "import requests\n\npayload = {\n    \"export_options\": {\n        \"image_format\": \"webp\",\n        \"image_size\": 1920,\n        \"quality\": 95\n    },\n    \"print_areas\": [\n        {\n            \"adjustments\": {\n                \"blend_mode\": \"multiply\",\n                \"opacity\": 90\n            },\n            \"artwork_url\": \"https://example.com/design.png\",\n            \"placement\": {\n                \"fit\": \"fit\",\n                \"position\": \"center\"\n            },\n            \"uuid\": \"223e4567-e89b-12d3-a456-426614174001\"\n        }\n    ]\n}\n\nresponse = requests.post(\n    \"https://api.sudomock.com/api/v1/sudoai/2d-mockups/3fa85f64-5717-4562-b3fc-2c963f66afa6/render\",\n    headers={\"x-api-key\": \"sm_your_api_key\"},\n    json=payload,\n)\n\nresponse.raise_for_status()\nprint(response.json())"
          },
          {
            "lang": "Ruby",
            "source": "require \"net/http\"\nrequire \"uri\"\n\nuri = URI(\"https://api.sudomock.com/api/v1/sudoai/2d-mockups/3fa85f64-5717-4562-b3fc-2c963f66afa6/render\")\nrequest = Net::HTTP::Post.new(uri)\nrequest[\"x-api-key\"] = \"sm_your_api_key\"\nrequest[\"Content-Type\"] = \"application/json\"\n\nrequest.body = <<~JSON\n  {\n    \"export_options\": {\n      \"image_format\": \"webp\",\n      \"image_size\": 1920,\n      \"quality\": 95\n    },\n    \"print_areas\": [\n      {\n        \"adjustments\": {\n          \"blend_mode\": \"multiply\",\n          \"opacity\": 90\n        },\n        \"artwork_url\": \"https://example.com/design.png\",\n        \"placement\": {\n          \"fit\": \"fit\",\n          \"position\": \"center\"\n        },\n        \"uuid\": \"223e4567-e89b-12d3-a456-426614174001\"\n      }\n    ]\n  }\nJSON\n\nresponse = Net::HTTP.start(uri.host, uri.port, use_ssl: true) do |http|\n  http.request(request)\nend\n\nputs response.body"
          },
          {
            "lang": "Go",
            "source": "package main\n\nimport (\n\t\"bytes\"\n\t\"fmt\"\n\t\"io\"\n\t\"net/http\"\n)\n\nfunc main() {\n\tpayload := []byte(`{\n  \"export_options\": {\n    \"image_format\": \"webp\",\n    \"image_size\": 1920,\n    \"quality\": 95\n  },\n  \"print_areas\": [\n    {\n      \"adjustments\": {\n        \"blend_mode\": \"multiply\",\n        \"opacity\": 90\n      },\n      \"artwork_url\": \"https://example.com/design.png\",\n      \"placement\": {\n        \"fit\": \"fit\",\n        \"position\": \"center\"\n      },\n      \"uuid\": \"223e4567-e89b-12d3-a456-426614174001\"\n    }\n  ]\n}`)\n\n\treq, err := http.NewRequest(\"POST\", \"https://api.sudomock.com/api/v1/sudoai/2d-mockups/3fa85f64-5717-4562-b3fc-2c963f66afa6/render\", bytes.NewBuffer(payload))\n\tif err != nil {\n\t\tpanic(err)\n\t}\n\treq.Header.Set(\"x-api-key\", \"sm_your_api_key\")\n\treq.Header.Set(\"Content-Type\", \"application/json\")\n\n\tres, err := http.DefaultClient.Do(req)\n\tif err != nil {\n\t\tpanic(err)\n\t}\n\tdefer res.Body.Close()\n\n\tbody, _ := io.ReadAll(res.Body)\n\tfmt.Println(string(body))\n}"
          },
          {
            "lang": "Java",
            "source": "import java.net.URI;\nimport java.net.http.HttpClient;\nimport java.net.http.HttpRequest;\nimport java.net.http.HttpResponse;\n\nString payload = \"\"\"\n{\n  \"export_options\": {\n    \"image_format\": \"webp\",\n    \"image_size\": 1920,\n    \"quality\": 95\n  },\n  \"print_areas\": [\n    {\n      \"adjustments\": {\n        \"blend_mode\": \"multiply\",\n        \"opacity\": 90\n      },\n      \"artwork_url\": \"https://example.com/design.png\",\n      \"placement\": {\n        \"fit\": \"fit\",\n        \"position\": \"center\"\n      },\n      \"uuid\": \"223e4567-e89b-12d3-a456-426614174001\"\n    }\n  ]\n}\n\"\"\";\n\nHttpRequest request = HttpRequest.newBuilder()\n    .uri(URI.create(\"https://api.sudomock.com/api/v1/sudoai/2d-mockups/3fa85f64-5717-4562-b3fc-2c963f66afa6/render\"))\n    .header(\"x-api-key\", \"sm_your_api_key\")\n    .header(\"Content-Type\", \"application/json\")\n    .POST(HttpRequest.BodyPublishers.ofString(payload))\n    .build();\n\nHttpResponse<String> response = HttpClient.newHttpClient()\n    .send(request, HttpResponse.BodyHandlers.ofString());\n\nSystem.out.println(response.body());"
          },
          {
            "lang": ".NET",
            "source": "using System.Net.Http;\nusing System.Text;\n\nvar payload = \"\"\"\n{\n  \"export_options\": {\n    \"image_format\": \"webp\",\n    \"image_size\": 1920,\n    \"quality\": 95\n  },\n  \"print_areas\": [\n    {\n      \"adjustments\": {\n        \"blend_mode\": \"multiply\",\n        \"opacity\": 90\n      },\n      \"artwork_url\": \"https://example.com/design.png\",\n      \"placement\": {\n        \"fit\": \"fit\",\n        \"position\": \"center\"\n      },\n      \"uuid\": \"223e4567-e89b-12d3-a456-426614174001\"\n    }\n  ]\n}\n\"\"\";\n\nvar request = new HttpRequestMessage(HttpMethod.Post, \"https://api.sudomock.com/api/v1/sudoai/2d-mockups/3fa85f64-5717-4562-b3fc-2c963f66afa6/render\");\nrequest.Headers.Add(\"x-api-key\", \"sm_your_api_key\");\nrequest.Content = new StringContent(payload, Encoding.UTF8, \"application/json\");\n\nvar client = new HttpClient();\nvar response = await client.SendAsync(request);\n\nConsole.WriteLine(await response.Content.ReadAsStringAsync());"
          },
          {
            "lang": "cURL",
            "source": "curl -X POST \"https://api.sudomock.com/api/v1/sudoai/2d-mockups/3fa85f64-5717-4562-b3fc-2c963f66afa6/render\" \\\n  -H \"x-api-key: sm_your_api_key\" \\\n  -H \"Content-Type: application/json\" \\\n  -d '{\n    \"export_options\": {\n      \"image_format\": \"webp\",\n      \"image_size\": 1920,\n      \"quality\": 95\n    },\n    \"print_areas\": [\n      {\n        \"adjustments\": {\n          \"blend_mode\": \"multiply\",\n          \"opacity\": 90\n        },\n        \"artwork_url\": \"https://example.com/design.png\",\n        \"placement\": {\n          \"fit\": \"fit\",\n          \"position\": \"center\"\n        },\n        \"uuid\": \"223e4567-e89b-12d3-a456-426614174001\"\n      }\n    ]\n  }'"
          }
        ],
        "x-hidden": true
      }
    },
    "/api/v1/studio/create-session": {
      "post": {
        "tags": [
          "Studio"
        ],
        "summary": "Create a new Studio session",
        "description": "Generates an opaque session token for the Studio iframe on WooCommerce, custom storefronts, and Shopify storefronts that call through the App Proxy. No unauthenticated access. API key never leaves the server.",
        "operationId": "create_studio_session_api_v1_studio_create_session_post",
        "requestBody": {
          "content": {
            "application/json": {
              "schema": {
                "$ref": "#/components/schemas/CreateSessionRequest"
              }
            }
          },
          "required": true
        },
        "responses": {
          "200": {
            "description": "Successful Response",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/CreateSessionResponse"
                }
              }
            }
          }
        },
        "x-mint": {
          "metadata": {
            "sidebarTitle": "Create Studio session"
          }
        },
        "security": [
          {
            "ApiKeyAuth": []
          }
        ],
        "x-codeSamples": [
          {
            "lang": "Node.js",
            "source": "const response = await fetch(\"https://api.sudomock.com/api/v1/studio/create-session\", {\n  method: \"POST\",\n  headers: {\n    \"x-api-key\": \"sm_your_api_key\",\n    \"Content-Type\": \"application/json\",\n  },\n  body: JSON.stringify({\n    \"allowed_origin\": \"https://your-store.example.com\",\n    \"mockup_type\": \"psd\",\n    \"mockup_uuid\": \"c315f78f-d2c7-4541-b240-a9372842de94\",\n    \"product_id\": \"8342019283\",\n    \"session_kind\": \"customize\",\n    \"variant_id\": \"44912837465\"\n  }),\n});\n\nconst data = await response.json();\nconsole.log(data);"
          },
          {
            "lang": "PHP",
            "source": "<?php\n\n$payload = <<<'JSON'\n{\n  \"allowed_origin\": \"https://your-store.example.com\",\n  \"mockup_type\": \"psd\",\n  \"mockup_uuid\": \"c315f78f-d2c7-4541-b240-a9372842de94\",\n  \"product_id\": \"8342019283\",\n  \"session_kind\": \"customize\",\n  \"variant_id\": \"44912837465\"\n}\nJSON;\n\n$ch = curl_init(\"https://api.sudomock.com/api/v1/studio/create-session\");\ncurl_setopt($ch, CURLOPT_CUSTOMREQUEST, \"POST\");\ncurl_setopt($ch, CURLOPT_RETURNTRANSFER, true);\ncurl_setopt($ch, CURLOPT_HTTPHEADER, [\n    \"x-api-key: sm_your_api_key\",\n    \"Content-Type: application/json\",\n]);\ncurl_setopt($ch, CURLOPT_POSTFIELDS, $payload);\n\n$response = curl_exec($ch);\ncurl_close($ch);\n\necho $response;"
          },
          {
            "lang": "Python",
            "source": "import requests\n\npayload = {\n    \"allowed_origin\": \"https://your-store.example.com\",\n    \"mockup_type\": \"psd\",\n    \"mockup_uuid\": \"c315f78f-d2c7-4541-b240-a9372842de94\",\n    \"product_id\": \"8342019283\",\n    \"session_kind\": \"customize\",\n    \"variant_id\": \"44912837465\"\n}\n\nresponse = requests.post(\n    \"https://api.sudomock.com/api/v1/studio/create-session\",\n    headers={\"x-api-key\": \"sm_your_api_key\"},\n    json=payload,\n)\n\nresponse.raise_for_status()\nprint(response.json())"
          },
          {
            "lang": "Ruby",
            "source": "require \"net/http\"\nrequire \"uri\"\n\nuri = URI(\"https://api.sudomock.com/api/v1/studio/create-session\")\nrequest = Net::HTTP::Post.new(uri)\nrequest[\"x-api-key\"] = \"sm_your_api_key\"\nrequest[\"Content-Type\"] = \"application/json\"\n\nrequest.body = <<~JSON\n  {\n    \"allowed_origin\": \"https://your-store.example.com\",\n    \"mockup_type\": \"psd\",\n    \"mockup_uuid\": \"c315f78f-d2c7-4541-b240-a9372842de94\",\n    \"product_id\": \"8342019283\",\n    \"session_kind\": \"customize\",\n    \"variant_id\": \"44912837465\"\n  }\nJSON\n\nresponse = Net::HTTP.start(uri.host, uri.port, use_ssl: true) do |http|\n  http.request(request)\nend\n\nputs response.body"
          },
          {
            "lang": "Go",
            "source": "package main\n\nimport (\n\t\"bytes\"\n\t\"fmt\"\n\t\"io\"\n\t\"net/http\"\n)\n\nfunc main() {\n\tpayload := []byte(`{\n  \"allowed_origin\": \"https://your-store.example.com\",\n  \"mockup_type\": \"psd\",\n  \"mockup_uuid\": \"c315f78f-d2c7-4541-b240-a9372842de94\",\n  \"product_id\": \"8342019283\",\n  \"session_kind\": \"customize\",\n  \"variant_id\": \"44912837465\"\n}`)\n\n\treq, err := http.NewRequest(\"POST\", \"https://api.sudomock.com/api/v1/studio/create-session\", bytes.NewBuffer(payload))\n\tif err != nil {\n\t\tpanic(err)\n\t}\n\treq.Header.Set(\"x-api-key\", \"sm_your_api_key\")\n\treq.Header.Set(\"Content-Type\", \"application/json\")\n\n\tres, err := http.DefaultClient.Do(req)\n\tif err != nil {\n\t\tpanic(err)\n\t}\n\tdefer res.Body.Close()\n\n\tbody, _ := io.ReadAll(res.Body)\n\tfmt.Println(string(body))\n}"
          },
          {
            "lang": "Java",
            "source": "import java.net.URI;\nimport java.net.http.HttpClient;\nimport java.net.http.HttpRequest;\nimport java.net.http.HttpResponse;\n\nString payload = \"\"\"\n{\n  \"allowed_origin\": \"https://your-store.example.com\",\n  \"mockup_type\": \"psd\",\n  \"mockup_uuid\": \"c315f78f-d2c7-4541-b240-a9372842de94\",\n  \"product_id\": \"8342019283\",\n  \"session_kind\": \"customize\",\n  \"variant_id\": \"44912837465\"\n}\n\"\"\";\n\nHttpRequest request = HttpRequest.newBuilder()\n    .uri(URI.create(\"https://api.sudomock.com/api/v1/studio/create-session\"))\n    .header(\"x-api-key\", \"sm_your_api_key\")\n    .header(\"Content-Type\", \"application/json\")\n    .POST(HttpRequest.BodyPublishers.ofString(payload))\n    .build();\n\nHttpResponse<String> response = HttpClient.newHttpClient()\n    .send(request, HttpResponse.BodyHandlers.ofString());\n\nSystem.out.println(response.body());"
          },
          {
            "lang": ".NET",
            "source": "using System.Net.Http;\nusing System.Text;\n\nvar payload = \"\"\"\n{\n  \"allowed_origin\": \"https://your-store.example.com\",\n  \"mockup_type\": \"psd\",\n  \"mockup_uuid\": \"c315f78f-d2c7-4541-b240-a9372842de94\",\n  \"product_id\": \"8342019283\",\n  \"session_kind\": \"customize\",\n  \"variant_id\": \"44912837465\"\n}\n\"\"\";\n\nvar request = new HttpRequestMessage(HttpMethod.Post, \"https://api.sudomock.com/api/v1/studio/create-session\");\nrequest.Headers.Add(\"x-api-key\", \"sm_your_api_key\");\nrequest.Content = new StringContent(payload, Encoding.UTF8, \"application/json\");\n\nvar client = new HttpClient();\nvar response = await client.SendAsync(request);\n\nConsole.WriteLine(await response.Content.ReadAsStringAsync());"
          },
          {
            "lang": "cURL",
            "source": "curl -X POST \"https://api.sudomock.com/api/v1/studio/create-session\" \\\n  -H \"x-api-key: sm_your_api_key\" \\\n  -H \"Content-Type: application/json\" \\\n  -d '{\n    \"allowed_origin\": \"https://your-store.example.com\",\n    \"mockup_type\": \"psd\",\n    \"mockup_uuid\": \"c315f78f-d2c7-4541-b240-a9372842de94\",\n    \"product_id\": \"8342019283\",\n    \"session_kind\": \"customize\",\n    \"variant_id\": \"44912837465\"\n  }'"
          }
        ]
      }
    },
    "/api/v1/studio/config": {
      "get": {
        "tags": [
          "Studio"
        ],
        "summary": "Retrieve the Studio config",
        "description": "Returns the API key's complete effective Studio configuration.",
        "operationId": "get_studio_config_api_v1_studio_config_get",
        "responses": {
          "200": {
            "description": "Successful Response",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/StudioConfigResponse"
                }
              }
            }
          }
        },
        "security": [
          {
            "ApiKeyAuth": []
          }
        ],
        "x-codeSamples": [
          {
            "lang": "Node.js",
            "source": "const response = await fetch(\"https://api.sudomock.com/api/v1/studio/config\", {\n  method: \"GET\",\n  headers: { \"x-api-key\": \"sm_your_api_key\" },\n});\n\nconst data = await response.json();\nconsole.log(data);"
          },
          {
            "lang": "PHP",
            "source": "<?php\n\n$ch = curl_init(\"https://api.sudomock.com/api/v1/studio/config\");\ncurl_setopt($ch, CURLOPT_CUSTOMREQUEST, \"GET\");\ncurl_setopt($ch, CURLOPT_RETURNTRANSFER, true);\ncurl_setopt($ch, CURLOPT_HTTPHEADER, [\n    \"x-api-key: sm_your_api_key\",\n]);\n\n$response = curl_exec($ch);\ncurl_close($ch);\n\necho $response;"
          },
          {
            "lang": "Python",
            "source": "import requests\n\nresponse = requests.get(\n    \"https://api.sudomock.com/api/v1/studio/config\",\n    headers={\"x-api-key\": \"sm_your_api_key\"},\n)\n\nresponse.raise_for_status()\nprint(response.json())"
          },
          {
            "lang": "Ruby",
            "source": "require \"net/http\"\nrequire \"uri\"\n\nuri = URI(\"https://api.sudomock.com/api/v1/studio/config\")\nrequest = Net::HTTP::Get.new(uri)\nrequest[\"x-api-key\"] = \"sm_your_api_key\"\n\nresponse = Net::HTTP.start(uri.host, uri.port, use_ssl: true) do |http|\n  http.request(request)\nend\n\nputs response.body"
          },
          {
            "lang": "Go",
            "source": "package main\n\nimport (\n\t\"fmt\"\n\t\"io\"\n\t\"net/http\"\n)\n\nfunc main() {\n\treq, err := http.NewRequest(\"GET\", \"https://api.sudomock.com/api/v1/studio/config\", nil)\n\tif err != nil {\n\t\tpanic(err)\n\t}\n\treq.Header.Set(\"x-api-key\", \"sm_your_api_key\")\n\n\tres, err := http.DefaultClient.Do(req)\n\tif err != nil {\n\t\tpanic(err)\n\t}\n\tdefer res.Body.Close()\n\n\tbody, _ := io.ReadAll(res.Body)\n\tfmt.Println(string(body))\n}"
          },
          {
            "lang": "Java",
            "source": "import java.net.URI;\nimport java.net.http.HttpClient;\nimport java.net.http.HttpRequest;\nimport java.net.http.HttpResponse;\n\nHttpRequest request = HttpRequest.newBuilder()\n    .uri(URI.create(\"https://api.sudomock.com/api/v1/studio/config\"))\n    .header(\"x-api-key\", \"sm_your_api_key\")\n    .GET()\n    .build();\n\nHttpResponse<String> response = HttpClient.newHttpClient()\n    .send(request, HttpResponse.BodyHandlers.ofString());\n\nSystem.out.println(response.body());"
          },
          {
            "lang": ".NET",
            "source": "using System.Net.Http;\nusing System.Text;\n\nvar request = new HttpRequestMessage(HttpMethod.Get, \"https://api.sudomock.com/api/v1/studio/config\");\nrequest.Headers.Add(\"x-api-key\", \"sm_your_api_key\");\n\nvar client = new HttpClient();\nvar response = await client.SendAsync(request);\n\nConsole.WriteLine(await response.Content.ReadAsStringAsync());"
          },
          {
            "lang": "cURL",
            "source": "curl -X GET \"https://api.sudomock.com/api/v1/studio/config\" \\\n  -H \"x-api-key: sm_your_api_key\""
          }
        ]
      },
      "put": {
        "tags": [
          "Studio"
        ],
        "summary": "Update the Studio config",
        "description": "Updates the Studio appearance and controls for this API key.",
        "operationId": "update_studio_config_api_v1_studio_config_put",
        "requestBody": {
          "content": {
            "application/json": {
              "schema": {
                "$ref": "#/components/schemas/UpdateStudioConfigRequest"
              }
            }
          },
          "required": true
        },
        "responses": {
          "200": {
            "description": "Successful Response",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/StudioConfigResponse"
                }
              }
            }
          }
        },
        "security": [
          {
            "ApiKeyAuth": []
          }
        ],
        "x-codeSamples": [
          {
            "lang": "Node.js",
            "source": "const response = await fetch(\"https://api.sudomock.com/api/v1/studio/config\", {\n  method: \"PUT\",\n  headers: {\n    \"x-api-key\": \"sm_your_api_key\",\n    \"Content-Type\": \"application/json\",\n  },\n  body: JSON.stringify({\n    \"config\": {\n      \"accentColor\": \"#FF5733\",\n      \"theme\": \"dark\"\n    },\n    \"config_version\": 3\n  }),\n});\n\nconst data = await response.json();\nconsole.log(data);"
          },
          {
            "lang": "PHP",
            "source": "<?php\n\n$payload = <<<'JSON'\n{\n  \"config\": {\n    \"accentColor\": \"#FF5733\",\n    \"theme\": \"dark\"\n  },\n  \"config_version\": 3\n}\nJSON;\n\n$ch = curl_init(\"https://api.sudomock.com/api/v1/studio/config\");\ncurl_setopt($ch, CURLOPT_CUSTOMREQUEST, \"PUT\");\ncurl_setopt($ch, CURLOPT_RETURNTRANSFER, true);\ncurl_setopt($ch, CURLOPT_HTTPHEADER, [\n    \"x-api-key: sm_your_api_key\",\n    \"Content-Type: application/json\",\n]);\ncurl_setopt($ch, CURLOPT_POSTFIELDS, $payload);\n\n$response = curl_exec($ch);\ncurl_close($ch);\n\necho $response;"
          },
          {
            "lang": "Python",
            "source": "import requests\n\npayload = {\n    \"config\": {\n        \"accentColor\": \"#FF5733\",\n        \"theme\": \"dark\"\n    },\n    \"config_version\": 3\n}\n\nresponse = requests.put(\n    \"https://api.sudomock.com/api/v1/studio/config\",\n    headers={\"x-api-key\": \"sm_your_api_key\"},\n    json=payload,\n)\n\nresponse.raise_for_status()\nprint(response.json())"
          },
          {
            "lang": "Ruby",
            "source": "require \"net/http\"\nrequire \"uri\"\n\nuri = URI(\"https://api.sudomock.com/api/v1/studio/config\")\nrequest = Net::HTTP::Put.new(uri)\nrequest[\"x-api-key\"] = \"sm_your_api_key\"\nrequest[\"Content-Type\"] = \"application/json\"\n\nrequest.body = <<~JSON\n  {\n    \"config\": {\n      \"accentColor\": \"#FF5733\",\n      \"theme\": \"dark\"\n    },\n    \"config_version\": 3\n  }\nJSON\n\nresponse = Net::HTTP.start(uri.host, uri.port, use_ssl: true) do |http|\n  http.request(request)\nend\n\nputs response.body"
          },
          {
            "lang": "Go",
            "source": "package main\n\nimport (\n\t\"bytes\"\n\t\"fmt\"\n\t\"io\"\n\t\"net/http\"\n)\n\nfunc main() {\n\tpayload := []byte(`{\n  \"config\": {\n    \"accentColor\": \"#FF5733\",\n    \"theme\": \"dark\"\n  },\n  \"config_version\": 3\n}`)\n\n\treq, err := http.NewRequest(\"PUT\", \"https://api.sudomock.com/api/v1/studio/config\", bytes.NewBuffer(payload))\n\tif err != nil {\n\t\tpanic(err)\n\t}\n\treq.Header.Set(\"x-api-key\", \"sm_your_api_key\")\n\treq.Header.Set(\"Content-Type\", \"application/json\")\n\n\tres, err := http.DefaultClient.Do(req)\n\tif err != nil {\n\t\tpanic(err)\n\t}\n\tdefer res.Body.Close()\n\n\tbody, _ := io.ReadAll(res.Body)\n\tfmt.Println(string(body))\n}"
          },
          {
            "lang": "Java",
            "source": "import java.net.URI;\nimport java.net.http.HttpClient;\nimport java.net.http.HttpRequest;\nimport java.net.http.HttpResponse;\n\nString payload = \"\"\"\n{\n  \"config\": {\n    \"accentColor\": \"#FF5733\",\n    \"theme\": \"dark\"\n  },\n  \"config_version\": 3\n}\n\"\"\";\n\nHttpRequest request = HttpRequest.newBuilder()\n    .uri(URI.create(\"https://api.sudomock.com/api/v1/studio/config\"))\n    .header(\"x-api-key\", \"sm_your_api_key\")\n    .header(\"Content-Type\", \"application/json\")\n    .PUT(HttpRequest.BodyPublishers.ofString(payload))\n    .build();\n\nHttpResponse<String> response = HttpClient.newHttpClient()\n    .send(request, HttpResponse.BodyHandlers.ofString());\n\nSystem.out.println(response.body());"
          },
          {
            "lang": ".NET",
            "source": "using System.Net.Http;\nusing System.Text;\n\nvar payload = \"\"\"\n{\n  \"config\": {\n    \"accentColor\": \"#FF5733\",\n    \"theme\": \"dark\"\n  },\n  \"config_version\": 3\n}\n\"\"\";\n\nvar request = new HttpRequestMessage(HttpMethod.Put, \"https://api.sudomock.com/api/v1/studio/config\");\nrequest.Headers.Add(\"x-api-key\", \"sm_your_api_key\");\nrequest.Content = new StringContent(payload, Encoding.UTF8, \"application/json\");\n\nvar client = new HttpClient();\nvar response = await client.SendAsync(request);\n\nConsole.WriteLine(await response.Content.ReadAsStringAsync());"
          },
          {
            "lang": "cURL",
            "source": "curl -X PUT \"https://api.sudomock.com/api/v1/studio/config\" \\\n  -H \"x-api-key: sm_your_api_key\" \\\n  -H \"Content-Type: application/json\" \\\n  -d '{\n    \"config\": {\n      \"accentColor\": \"#FF5733\",\n      \"theme\": \"dark\"\n    },\n    \"config_version\": 3\n  }'"
          }
        ]
      }
    },
    "/api/v1/studio/actions/consume": {
      "post": {
        "tags": [
          "Studio"
        ],
        "summary": "Consume a Studio action",
        "description": "Server-only exactly-once confirmation of a Studio action against its bound successful render.",
        "operationId": "consume_action_api_v1_studio_actions_consume_post",
        "requestBody": {
          "required": true,
          "content": {
            "application/json": {
              "schema": {
                "$ref": "#/components/schemas/StudioActionRequest"
              }
            }
          }
        },
        "responses": {
          "200": {
            "description": "Successful Response",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/StudioActionResponse"
                }
              }
            }
          }
        },
        "x-mint": {
          "metadata": {
            "sidebarTitle": "Consume Studio action"
          }
        },
        "security": [
          {
            "ApiKeyAuth": []
          }
        ],
        "x-codeSamples": [
          {
            "lang": "Node.js",
            "source": "const response = await fetch(\"https://api.sudomock.com/api/v1/studio/actions/consume\", {\n  method: \"POST\",\n  headers: {\n    \"x-api-key\": \"sm_your_api_key\",\n    \"Content-Type\": \"application/json\",\n  },\n  body: JSON.stringify({\n    \"message_session_id\": \"7d1b4a90-2e63-4f18-bb27-1c9a0e4d7f52\",\n    \"payload\": {\n      \"mockup_uuid\": \"c315f78f-d2c7-4541-b240-a9372842de94\",\n      \"render_uuid\": \"9b2e5f31-4c8d-4a76-8f0b-2d7e6c1a9354\"\n    },\n    \"request_id\": \"0f9c2d1e-7b44-4a2f-9a0d-6c1f2b8e5d33\",\n    \"type\": \"studio.mockup-saved\",\n    \"version\": 1\n  }),\n});\n\nconst data = await response.json();\nconsole.log(data);"
          },
          {
            "lang": "PHP",
            "source": "<?php\n\n$payload = <<<'JSON'\n{\n  \"message_session_id\": \"7d1b4a90-2e63-4f18-bb27-1c9a0e4d7f52\",\n  \"payload\": {\n    \"mockup_uuid\": \"c315f78f-d2c7-4541-b240-a9372842de94\",\n    \"render_uuid\": \"9b2e5f31-4c8d-4a76-8f0b-2d7e6c1a9354\"\n  },\n  \"request_id\": \"0f9c2d1e-7b44-4a2f-9a0d-6c1f2b8e5d33\",\n  \"type\": \"studio.mockup-saved\",\n  \"version\": 1\n}\nJSON;\n\n$ch = curl_init(\"https://api.sudomock.com/api/v1/studio/actions/consume\");\ncurl_setopt($ch, CURLOPT_CUSTOMREQUEST, \"POST\");\ncurl_setopt($ch, CURLOPT_RETURNTRANSFER, true);\ncurl_setopt($ch, CURLOPT_HTTPHEADER, [\n    \"x-api-key: sm_your_api_key\",\n    \"Content-Type: application/json\",\n]);\ncurl_setopt($ch, CURLOPT_POSTFIELDS, $payload);\n\n$response = curl_exec($ch);\ncurl_close($ch);\n\necho $response;"
          },
          {
            "lang": "Python",
            "source": "import requests\n\npayload = {\n    \"message_session_id\": \"7d1b4a90-2e63-4f18-bb27-1c9a0e4d7f52\",\n    \"payload\": {\n        \"mockup_uuid\": \"c315f78f-d2c7-4541-b240-a9372842de94\",\n        \"render_uuid\": \"9b2e5f31-4c8d-4a76-8f0b-2d7e6c1a9354\"\n    },\n    \"request_id\": \"0f9c2d1e-7b44-4a2f-9a0d-6c1f2b8e5d33\",\n    \"type\": \"studio.mockup-saved\",\n    \"version\": 1\n}\n\nresponse = requests.post(\n    \"https://api.sudomock.com/api/v1/studio/actions/consume\",\n    headers={\"x-api-key\": \"sm_your_api_key\"},\n    json=payload,\n)\n\nresponse.raise_for_status()\nprint(response.json())"
          },
          {
            "lang": "Ruby",
            "source": "require \"net/http\"\nrequire \"uri\"\n\nuri = URI(\"https://api.sudomock.com/api/v1/studio/actions/consume\")\nrequest = Net::HTTP::Post.new(uri)\nrequest[\"x-api-key\"] = \"sm_your_api_key\"\nrequest[\"Content-Type\"] = \"application/json\"\n\nrequest.body = <<~JSON\n  {\n    \"message_session_id\": \"7d1b4a90-2e63-4f18-bb27-1c9a0e4d7f52\",\n    \"payload\": {\n      \"mockup_uuid\": \"c315f78f-d2c7-4541-b240-a9372842de94\",\n      \"render_uuid\": \"9b2e5f31-4c8d-4a76-8f0b-2d7e6c1a9354\"\n    },\n    \"request_id\": \"0f9c2d1e-7b44-4a2f-9a0d-6c1f2b8e5d33\",\n    \"type\": \"studio.mockup-saved\",\n    \"version\": 1\n  }\nJSON\n\nresponse = Net::HTTP.start(uri.host, uri.port, use_ssl: true) do |http|\n  http.request(request)\nend\n\nputs response.body"
          },
          {
            "lang": "Go",
            "source": "package main\n\nimport (\n\t\"bytes\"\n\t\"fmt\"\n\t\"io\"\n\t\"net/http\"\n)\n\nfunc main() {\n\tpayload := []byte(`{\n  \"message_session_id\": \"7d1b4a90-2e63-4f18-bb27-1c9a0e4d7f52\",\n  \"payload\": {\n    \"mockup_uuid\": \"c315f78f-d2c7-4541-b240-a9372842de94\",\n    \"render_uuid\": \"9b2e5f31-4c8d-4a76-8f0b-2d7e6c1a9354\"\n  },\n  \"request_id\": \"0f9c2d1e-7b44-4a2f-9a0d-6c1f2b8e5d33\",\n  \"type\": \"studio.mockup-saved\",\n  \"version\": 1\n}`)\n\n\treq, err := http.NewRequest(\"POST\", \"https://api.sudomock.com/api/v1/studio/actions/consume\", bytes.NewBuffer(payload))\n\tif err != nil {\n\t\tpanic(err)\n\t}\n\treq.Header.Set(\"x-api-key\", \"sm_your_api_key\")\n\treq.Header.Set(\"Content-Type\", \"application/json\")\n\n\tres, err := http.DefaultClient.Do(req)\n\tif err != nil {\n\t\tpanic(err)\n\t}\n\tdefer res.Body.Close()\n\n\tbody, _ := io.ReadAll(res.Body)\n\tfmt.Println(string(body))\n}"
          },
          {
            "lang": "Java",
            "source": "import java.net.URI;\nimport java.net.http.HttpClient;\nimport java.net.http.HttpRequest;\nimport java.net.http.HttpResponse;\n\nString payload = \"\"\"\n{\n  \"message_session_id\": \"7d1b4a90-2e63-4f18-bb27-1c9a0e4d7f52\",\n  \"payload\": {\n    \"mockup_uuid\": \"c315f78f-d2c7-4541-b240-a9372842de94\",\n    \"render_uuid\": \"9b2e5f31-4c8d-4a76-8f0b-2d7e6c1a9354\"\n  },\n  \"request_id\": \"0f9c2d1e-7b44-4a2f-9a0d-6c1f2b8e5d33\",\n  \"type\": \"studio.mockup-saved\",\n  \"version\": 1\n}\n\"\"\";\n\nHttpRequest request = HttpRequest.newBuilder()\n    .uri(URI.create(\"https://api.sudomock.com/api/v1/studio/actions/consume\"))\n    .header(\"x-api-key\", \"sm_your_api_key\")\n    .header(\"Content-Type\", \"application/json\")\n    .POST(HttpRequest.BodyPublishers.ofString(payload))\n    .build();\n\nHttpResponse<String> response = HttpClient.newHttpClient()\n    .send(request, HttpResponse.BodyHandlers.ofString());\n\nSystem.out.println(response.body());"
          },
          {
            "lang": ".NET",
            "source": "using System.Net.Http;\nusing System.Text;\n\nvar payload = \"\"\"\n{\n  \"message_session_id\": \"7d1b4a90-2e63-4f18-bb27-1c9a0e4d7f52\",\n  \"payload\": {\n    \"mockup_uuid\": \"c315f78f-d2c7-4541-b240-a9372842de94\",\n    \"render_uuid\": \"9b2e5f31-4c8d-4a76-8f0b-2d7e6c1a9354\"\n  },\n  \"request_id\": \"0f9c2d1e-7b44-4a2f-9a0d-6c1f2b8e5d33\",\n  \"type\": \"studio.mockup-saved\",\n  \"version\": 1\n}\n\"\"\";\n\nvar request = new HttpRequestMessage(HttpMethod.Post, \"https://api.sudomock.com/api/v1/studio/actions/consume\");\nrequest.Headers.Add(\"x-api-key\", \"sm_your_api_key\");\nrequest.Content = new StringContent(payload, Encoding.UTF8, \"application/json\");\n\nvar client = new HttpClient();\nvar response = await client.SendAsync(request);\n\nConsole.WriteLine(await response.Content.ReadAsStringAsync());"
          },
          {
            "lang": "cURL",
            "source": "curl -X POST \"https://api.sudomock.com/api/v1/studio/actions/consume\" \\\n  -H \"x-api-key: sm_your_api_key\" \\\n  -H \"Content-Type: application/json\" \\\n  -d '{\n    \"message_session_id\": \"7d1b4a90-2e63-4f18-bb27-1c9a0e4d7f52\",\n    \"payload\": {\n      \"mockup_uuid\": \"c315f78f-d2c7-4541-b240-a9372842de94\",\n      \"render_uuid\": \"9b2e5f31-4c8d-4a76-8f0b-2d7e6c1a9354\"\n    },\n    \"request_id\": \"0f9c2d1e-7b44-4a2f-9a0d-6c1f2b8e5d33\",\n    \"type\": \"studio.mockup-saved\",\n    \"version\": 1\n  }'"
          }
        ]
      }
    }
  },
  "components": {
    "schemas": {
      "AdjustmentLayers": {
        "properties": {
          "brightness": {
            "type": "integer",
            "maximum": 150.0,
            "minimum": -150.0,
            "description": "Brightness adjustment (-150 to 150). 0=no change.",
            "default": 0
          },
          "contrast": {
            "type": "integer",
            "maximum": 100.0,
            "minimum": -100.0,
            "description": "Contrast adjustment (-100 to 100). 0=no change.",
            "default": 0
          },
          "opacity": {
            "type": "integer",
            "maximum": 100.0,
            "minimum": 0.0,
            "description": "Artwork opacity (0=fully transparent, 100=fully opaque). Default 100.",
            "default": 100
          },
          "saturation": {
            "type": "integer",
            "maximum": 100.0,
            "minimum": -100.0,
            "description": "Saturation adjustment (-100 to 100). 0=no change, -100=grayscale.",
            "default": 0
          },
          "vibrance": {
            "type": "integer",
            "maximum": 100.0,
            "minimum": -100.0,
            "description": "Vibrance adjustment (-100 to 100). Similar to saturation but preserves skin tones.",
            "default": 0
          },
          "blur": {
            "type": "integer",
            "maximum": 100.0,
            "minimum": 0.0,
            "description": "Gaussian blur amount (0=sharp, 100=max blur). Useful for background effects.",
            "default": 0
          }
        },
        "type": "object",
        "title": "AdjustmentLayers",
        "description": "Image adjustment parameters applied to the user's artwork before blending into the mockup.\nApplied after fit transformation, does not affect PSD-level adjustments."
      },
      "AssetInput": {
        "properties": {
          "url": {
            "anyOf": [
              {
                "type": "string"
              },
              {
                "type": "null"
              }
            ],
            "description": "URL to the user's image (HTTP/HTTPS or data: URL). Either url or base64 must be provided. The server fetches the image, so the request stays small: the right choice for large files.",
            "examples": [
              "https://example.com/user-design.png"
            ]
          },
          "base64": {
            "anyOf": [
              {
                "type": "string"
              },
              {
                "type": "null"
              }
            ],
            "description": "Raw base64-encoded image bytes (no data: prefix). Either url or base64 must be provided. Saves the server-side fetch for small images already in memory. Base64 adds about a third to the file size and the whole request must finish uploading within 60 seconds, so send large files by url."
          },
          "content_type": {
            "anyOf": [
              {
                "type": "string",
                "pattern": "^image/(png|jpeg|webp|gif)$"
              },
              {
                "type": "null"
              }
            ],
            "description": "MIME type when using base64 field. Supported: image/png, image/jpeg, image/webp, image/gif. Defaults to image/png if omitted.",
            "examples": [
              "image/png"
            ]
          },
          "fit": {
            "type": "string",
            "enum": [
              "fill",
              "fit",
              "crop"
            ],
            "description": "How the artwork meets the smart object area. 'fit' scales it until it fits inside, keeping proportions, which can leave empty space. 'fill' stretches it to the bounds and does not keep its proportions. 'crop' covers the area and cuts the overflow, keeping proportions. 'contain' and 'cover' are the older names for 'fit' and 'crop' and are still accepted. Defaults to 'fit': a caller who says nothing is not asking to have their artwork distorted, and a silently stretched design is a defect the caller cannot see.",
            "default": "fit"
          },
          "size": {
            "anyOf": [
              {
                "$ref": "#/components/schemas/AssetSize"
              },
              {
                "type": "null"
              }
            ],
            "description": "Custom size override: the box the artwork is fitted into, in the smart object's own pixels. Width and height are both optional and each must be at least 1 pixel; an axis left out is the smart object's own size on that axis, and a size with neither axis is ignored."
          },
          "position": {
            "anyOf": [
              {
                "$ref": "#/components/schemas/AssetPosition"
              },
              {
                "type": "null"
              }
            ],
            "description": "Custom position override (top/left in pixels). With size, the top-left corner of the size box in the smart object's own pixels, which stays axis-aligned: rotate turns the artwork inside it, never the box. Without size, it places the whole smart object on the mockup instead, its top-left corner at left/top in the template's own pixels; a smart object in a clipping group or inside a masked group can stay where the template has it."
          },
          "rotate": {
            "type": "number",
            "maximum": 360.0,
            "minimum": -360.0,
            "description": "Rotation angle in degrees (clockwise positive). Applied to the artwork before it is fitted, so the turned artwork, corners included, is what fit places inside the still axis-aligned size box at position.",
            "default": 0,
            "examples": [
              15
            ]
          },
          "flip_horizontal": {
            "type": "boolean",
            "description": "Flip artwork horizontally (left-right mirror)",
            "default": false
          },
          "flip_vertical": {
            "type": "boolean",
            "description": "Flip artwork vertically (top-bottom mirror)",
            "default": false
          },
          "remove_background": {
            "type": "boolean",
            "description": "Remove the image background before placing the artwork; the subject is isolated onto a clean transparent cutout. Adds 25 credits per artwork to the render cost.",
            "default": false
          }
        },
        "type": "object",
        "title": "AssetInput",
        "description": "The image to place into a smart object, and how it should sit there.\n\nImage source priority: base64 > url (including data: URLs)\n- base64: Raw base64 string (no data: prefix). Suits small images already in memory.\n- url: HTTP/HTTPS URL or data:image/...;base64,... URL. Suits large files.",
        "example": {
          "fit": "fill",
          "flip_horizontal": false,
          "flip_vertical": false,
          "position": {
            "left": 20,
            "top": 10
          },
          "rotate": 15,
          "size": {
            "height": 600,
            "width": 800
          },
          "url": "https://example.com/user-design.png"
        }
      },
      "AssetPosition": {
        "properties": {
          "top": {
            "anyOf": [
              {
                "type": "number"
              },
              {
                "type": "null"
              }
            ],
            "description": "Top offset in pixels",
            "examples": [
              100
            ]
          },
          "left": {
            "anyOf": [
              {
                "type": "number"
              },
              {
                "type": "null"
              }
            ],
            "description": "Left offset in pixels",
            "examples": [
              100
            ]
          }
        },
        "type": "object",
        "title": "AssetPosition",
        "description": "Where the artwork sits inside the smart object.\n\nFractional pixels are accepted."
      },
      "AssetSize": {
        "properties": {
          "width": {
            "anyOf": [
              {
                "type": "number",
                "minimum": 1.0
              },
              {
                "type": "null"
              }
            ],
            "description": "Custom width in pixels",
            "examples": [
              800
            ]
          },
          "height": {
            "anyOf": [
              {
                "type": "number",
                "minimum": 1.0
              },
              {
                "type": "null"
              }
            ],
            "description": "Custom height in pixels",
            "examples": [
              600
            ]
          }
        },
        "type": "object",
        "title": "AssetSize",
        "description": "How large the artwork is drawn inside the smart object.\n\nFractional pixels are accepted."
      },
      "BackgroundRemovalData": {
        "properties": {
          "url": {
            "type": "string",
            "description": "URL of the transparent-PNG cutout"
          },
          "width": {
            "type": "integer",
            "description": "Cutout width in pixels"
          },
          "height": {
            "type": "integer",
            "description": "Cutout height in pixels"
          },
          "credits_charged": {
            "type": "integer",
            "description": "Credits charged for this operation"
          }
        },
        "type": "object",
        "required": [
          "url",
          "width",
          "height",
          "credits_charged"
        ],
        "title": "BackgroundRemovalData",
        "description": "Result payload for POST /api/v1/remove-background."
      },
      "BackgroundRemovalRequest": {
        "properties": {
          "url": {
            "anyOf": [
              {
                "type": "string"
              },
              {
                "type": "null"
              }
            ],
            "description": "URL of the image to process (HTTP/HTTPS). Either url or base64 must be provided."
          },
          "base64": {
            "anyOf": [
              {
                "type": "string"
              },
              {
                "type": "null"
              }
            ],
            "description": "Raw base64-encoded image bytes (no data: prefix). Either url or base64 must be provided."
          },
          "content_type": {
            "anyOf": [
              {
                "type": "string",
                "pattern": "^image/(png|jpeg|webp|gif)$"
              },
              {
                "type": "null"
              }
            ],
            "description": "MIME type when using base64 field. Defaults to image/png if omitted."
          },
          "idempotency_key": {
            "anyOf": [
              {
                "type": "string",
                "maxLength": 255,
                "minLength": 1
              },
              {
                "type": "null"
              }
            ],
            "description": "Retry-stable request identifier. Required in both this field and the Idempotency-Key header for Studio calls."
          }
        },
        "additionalProperties": false,
        "type": "object",
        "title": "BackgroundRemovalRequest",
        "description": "Body for POST /api/v1/remove-background.\n\nImage source priority mirrors AssetInput: base64 > url.",
        "example": {
          "url": "https://example.com/product-photo.jpg"
        }
      },
      "BackgroundRemovalResponse": {
        "properties": {
          "data": {
            "$ref": "#/components/schemas/BackgroundRemovalData",
            "description": "The cutout image, its dimensions and the credits charged."
          },
          "success": {
            "type": "boolean",
            "description": "Success status",
            "default": true
          }
        },
        "type": "object",
        "required": [
          "data"
        ],
        "title": "BackgroundRemovalResponse",
        "description": "The cutout image and where to fetch it.",
        "example": {
          "data": {
            "credits_charged": 25,
            "height": 3000,
            "url": "https://cdn.sudomock.com/mockup-assets/bg-cutouts/9c4e1a7f3b2d8e6045a1c93f7b20de84.png",
            "width": 2400
          },
          "success": true
        }
      },
      "ColorOverlay": {
        "properties": {
          "hex": {
            "anyOf": [
              {
                "type": "string",
                "pattern": "^#[0-9A-Fa-f]{6}$"
              },
              {
                "type": "null"
              }
            ],
            "description": "Hex color code (e.g., '#FF5733'). Send this or 'label'.",
            "examples": [
              "#FF5733"
            ]
          },
          "label": {
            "anyOf": [
              {
                "type": "string",
                "maxLength": 32,
                "minLength": 1
              },
              {
                "type": "null"
              }
            ],
            "description": "One of the colours saved on this mockup, by the name you gave it. Send this instead of 'hex' to keep calling a colour what your own catalogue calls it. Names match exactly, and are set with PATCH /api/v1/psd-mockups/{uuid}."
          },
          "blending_mode": {
            "type": "string",
            "description": "Blend mode for color overlay. Common values: 'normal', 'multiply' (fabric/textile mockups), 'screen', 'overlay', 'soft_light'. All 27 Photoshop blend modes supported.",
            "default": "normal",
            "examples": [
              "multiply"
            ]
          }
        },
        "type": "object",
        "title": "ColorOverlay",
        "description": "A colour laid over the smart object, with a blending mode.",
        "example": {
          "blending_mode": "multiply",
          "hex": "#FF5733"
        }
      },
      "CreateSessionRequest": {
        "properties": {
          "mockup_type": {
            "anyOf": [
              {
                "type": "string",
                "enum": [
                  "psd",
                  "2d"
                ]
              },
              {
                "type": "null"
              }
            ],
            "description": "Which editor the session opens, psd or 2d."
          },
          "session_kind": {
            "anyOf": [
              {
                "type": "string",
                "enum": [
                  "setup",
                  "customize"
                ]
              },
              {
                "type": "null"
              }
            ],
            "description": "What the session is for, setup or customize."
          },
          "mockup_uuid": {
            "anyOf": [
              {
                "type": "string"
              },
              {
                "type": "null"
              }
            ],
            "description": "UUID of the mockup to customize",
            "examples": [
              "c315f78f-d2c7-4541-b240-a9372842de94"
            ]
          },
          "product_id": {
            "anyOf": [
              {
                "type": "string",
                "maxLength": 255
              },
              {
                "type": "null"
              }
            ],
            "description": "Product ID from the platform",
            "examples": [
              "8342019283"
            ]
          },
          "variant_id": {
            "anyOf": [
              {
                "type": "string",
                "maxLength": 255
              },
              {
                "type": "null"
              }
            ],
            "description": "Variant ID from the platform",
            "examples": [
              "44912837465"
            ]
          },
          "allowed_origin": {
            "anyOf": [
              {
                "type": "string",
                "maxLength": 2048
              },
              {
                "type": "null"
              }
            ],
            "description": "HTTPS origin of the page that embeds the editor.",
            "examples": [
              "https://your-store.example.com"
            ]
          },
          "config": {
            "anyOf": [
              {
                "$ref": "#/components/schemas/StudioConfigPatch"
              },
              {
                "type": "null"
              }
            ],
            "description": "Optional session-only Studio config override. Not persisted."
          },
          "action_id": {
            "anyOf": [
              {
                "type": "string",
                "maxLength": 64,
                "minLength": 1,
                "pattern": "^[A-Za-z0-9][A-Za-z0-9._:-]{0,63}$"
              },
              {
                "type": "null"
              }
            ],
            "description": "Your own routing identifier for the action this session completes.",
            "examples": [
              "add-to-cart"
            ]
          },
          "artwork": {
            "anyOf": [
              {
                "items": {
                  "$ref": "#/components/schemas/StudioArtworkInput"
                },
                "type": "array"
              },
              {
                "$ref": "#/components/schemas/StudioArtworkInput"
              },
              {
                "type": "null"
              }
            ],
            "description": "Optional session-locked artwork: a list with one entry per target, up to 8. A single object is also accepted and locks one target. Every target must belong to the explicitly bound mockup, and no target may repeat. Base64 takes precedence over url. The customer may edit placement and appearance but cannot replace, remove, add, or retarget artwork."
          }
        },
        "additionalProperties": false,
        "type": "object",
        "title": "CreateSessionRequest",
        "example": {
          "allowed_origin": "https://your-store.example.com",
          "mockup_type": "psd",
          "mockup_uuid": "c315f78f-d2c7-4541-b240-a9372842de94",
          "product_id": "8342019283",
          "session_kind": "customize",
          "variant_id": "44912837465"
        }
      },
      "CreateSessionResponse": {
        "properties": {
          "success": {
            "type": "boolean",
            "const": true,
            "description": "True when the session was created.",
            "default": true
          },
          "mockup_type": {
            "type": "string",
            "enum": [
              "psd",
              "2d"
            ],
            "description": "Which editor this session opens, psd or 2d."
          },
          "session": {
            "type": "string",
            "description": "Opaque token the editor is opened with.",
            "examples": [
              "sess_xQ8pM2vK7nR4tB1yH6zJ3wL5sD9fG0aC2eN8uV4iT7o"
            ]
          },
          "expires_in": {
            "type": "integer",
            "description": "Seconds the session stays valid while it sits idle.",
            "examples": [
              900
            ]
          },
          "message_session_id": {
            "type": "string",
            "description": "Identifier your page matches every editor message against.",
            "examples": [
              "7d1b4a90-2e63-4f18-bb27-1c9a0e4d7f52"
            ]
          },
          "bootstrap_secret": {
            "type": "string",
            "description": "One-time secret your page sends to complete the handshake.",
            "examples": [
              "wAKBqgAce_HWV01uenTwEPrczjPkIt9xH0BSjQ1S68A"
            ]
          }
        },
        "additionalProperties": false,
        "type": "object",
        "required": [
          "mockup_type",
          "session",
          "expires_in",
          "message_session_id",
          "bootstrap_secret"
        ],
        "title": "CreateSessionResponse"
      },
      "ExportOptions": {
        "properties": {
          "image_format": {
            "type": "string",
            "enum": [
              "png",
              "jpg",
              "webp"
            ],
            "description": "Output format: 'webp' (30-70% smaller, recommended), 'png' (lossless), 'jpg' (smallest, no transparency)",
            "default": "webp"
          },
          "image_size": {
            "anyOf": [
              {
                "type": "integer",
                "maximum": 10000.0,
                "minimum": 100.0
              },
              {
                "type": "string",
                "const": "original"
              }
            ],
            "description": "Output width in pixels (100-10000), or \"original\" to render a PSD template at its own size and resolution: the template's own width and, unless dpi is set, the resolution the PSD was saved with. Height auto-calculated from the source aspect ratio. Renders on an account in trial are capped at 1024: a larger width is rejected with error_code OUTPUT_RESOLUTION_LIMIT (HTTP 402) and is never silently downscaled. Add a payment method to render at full width.",
            "default": 2048,
            "examples": [
              2048,
              "original"
            ]
          },
          "quality": {
            "type": "integer",
            "maximum": 100.0,
            "minimum": 1.0,
            "description": "Compression quality for JPG/WebP (1-100). Ignored for PNG (always lossless). Default: 90.",
            "default": 90
          },
          "dpi": {
            "anyOf": [
              {
                "type": "integer",
                "maximum": 2400.0,
                "minimum": 72.0
              },
              {
                "type": "null"
              }
            ],
            "description": "Resolution tag stamped into the output file metadata (JPG/WebP via Exif XResolution, PNG via pHYs), e.g. 300 for print. This is metadata only: it does NOT change the pixels. Pixel dimensions are controlled by image_size: set image_size = print_size_inches * dpi for a true print-ready file (e.g. 12 in * 300 = 3600 px). Range 72-2400. Default: null (opt-in). Omitting it does not leave the file untagged: the encoder writes a default ~25.4 DPI (1 px/mm) tag. With image_size \"original\" and no dpi, the file carries the PSD's own resolution. All three formats carry the tag, but for maximum print-tool compatibility prefer jpg or png, because WebP stores resolution in Exif and not every viewer surfaces it.",
            "examples": [
              300
            ]
          }
        },
        "type": "object",
        "title": "ExportOptions",
        "description": "Format, size and quality of the rendered file.",
        "example": {
          "image_format": "webp",
          "image_size": 2048,
          "quality": 95
        }
      },
      "FontDeleteResponse": {
        "properties": {
          "success": {
            "type": "boolean",
            "description": "Always true on a successful response.",
            "default": true
          }
        },
        "type": "object",
        "title": "FontDeleteResponse",
        "description": "Confirmation that one of your uploaded fonts was removed.",
        "example": {
          "success": true
        }
      },
      "FontListResponse": {
        "properties": {
          "success": {
            "type": "boolean",
            "description": "Always true on a successful response.",
            "default": true
          },
          "data": {
            "items": {
              "$ref": "#/components/schemas/FontResponse"
            },
            "type": "array",
            "description": "The fonts on this page."
          },
          "pagination": {
            "$ref": "#/components/schemas/FontPagination",
            "description": "Page number, page size and total matching fonts."
          }
        },
        "type": "object",
        "required": [
          "data",
          "pagination"
        ],
        "title": "FontListResponse",
        "description": "List response wrapper for GET /api/v1/fonts.",
        "example": {
          "data": [
            {
              "category": "sans-serif",
              "created_at": "2026-07-13T00:00:00+00:00",
              "family": "Open Sans",
              "file_url": "https://cdn.sudomock.com/mockup-assets/fonts/web/9f1c2d3e-4a5b-6c7d-8e9f-0a1b2c3d4e5f.woff2",
              "is_premium": false,
              "is_system": true,
              "license": "OFL",
              "postscript_name": "OpenSans-Regular",
              "subfamily": "Regular",
              "uuid": "9f1c2d3e-4a5b-6c7d-8e9f-0a1b2c3d4e5f",
              "preview_url": null
            },
            {
              "category": "serif",
              "created_at": "2026-07-13T00:00:00+00:00",
              "family": "Playfair Display",
              "file_url": "https://cdn.sudomock.com/mockup-assets/fonts/web/4b8e6a71-2c05-4f93-ae17-6d3c9b204e58.woff2",
              "is_premium": false,
              "is_system": true,
              "license": "OFL",
              "postscript_name": "PlayfairDisplay-Bold",
              "subfamily": "Bold",
              "uuid": "4b8e6a71-2c05-4f93-ae17-6d3c9b204e58",
              "preview_url": null
            }
          ],
          "pagination": {
            "page": 1,
            "per_page": 50,
            "total": 2
          },
          "success": true
        }
      },
      "FontPagination": {
        "properties": {
          "page": {
            "type": "integer",
            "description": "Current page (1-based)"
          },
          "per_page": {
            "type": "integer",
            "description": "Results per page"
          },
          "total": {
            "type": "integer",
            "description": "Total fonts matching the query"
          }
        },
        "type": "object",
        "required": [
          "page",
          "per_page",
          "total"
        ],
        "title": "FontPagination",
        "description": "Pagination envelope for the font list."
      },
      "FontResponse": {
        "properties": {
          "uuid": {
            "type": "string",
            "description": "Font id",
            "examples": [
              "7f3a2b1c-9d4e-4a6f-b8c2-1e5d7a0c3f94"
            ]
          },
          "family": {
            "type": "string",
            "description": "Font family name, e.g. 'Open Sans'",
            "examples": [
              "Open Sans"
            ]
          },
          "subfamily": {
            "anyOf": [
              {
                "type": "string"
              },
              {
                "type": "null"
              }
            ],
            "description": "Style within the family, e.g. 'Bold Italic'",
            "examples": [
              "Regular"
            ]
          },
          "postscript_name": {
            "type": "string",
            "description": "PostScript name, the stable key used to reference this font when rendering text layers",
            "examples": [
              "OpenSans-Regular"
            ]
          },
          "category": {
            "anyOf": [
              {
                "type": "string"
              },
              {
                "type": "null"
              }
            ],
            "description": "Catalog category, e.g. 'sans-serif', 'serif', 'display'",
            "examples": [
              "sans-serif"
            ]
          },
          "license": {
            "anyOf": [
              {
                "type": "string"
              },
              {
                "type": "null"
              }
            ],
            "description": "License identifier (system fonts)",
            "examples": [
              "OFL"
            ]
          },
          "is_premium": {
            "type": "boolean",
            "description": "Whether this is a premium catalog font",
            "default": false
          },
          "is_system": {
            "type": "boolean",
            "description": "True for the shared system catalog, False for a font you uploaded",
            "examples": [
              true
            ]
          },
          "preview_url": {
            "anyOf": [
              {
                "type": "string"
              },
              {
                "type": "null"
              }
            ],
            "description": "Legacy rendered preview image, when available; new catalog entries no longer include one (use file_url for live previews)"
          },
          "file_url": {
            "anyOf": [
              {
                "type": "string"
              },
              {
                "type": "null"
              }
            ],
            "description": "URL of the web-optimized WOFF2 file for live @font-face preview: a public CDN URL for system fonts, a short-lived link for your own uploads. Null for premium fonts; the original TTF/OTF source is never exposed.",
            "examples": [
              "https://cdn.sudomock.com/mockup-assets/fonts/web/7f3a2b1c-9d4e-4a6f-b8c2-1e5d7a0c3f94.woff2"
            ]
          },
          "created_at": {
            "anyOf": [
              {
                "type": "string"
              },
              {
                "type": "null"
              }
            ],
            "description": "When the font was added",
            "examples": [
              "2026-07-13T09:14:22+00:00"
            ]
          }
        },
        "type": "object",
        "required": [
          "uuid",
          "family",
          "postscript_name",
          "is_system"
        ],
        "title": "FontResponse",
        "description": "A single font in the catalog: a shared system font, or one of the\ncaller's own uploaded fonts.",
        "example": {
          "category": "sans-serif",
          "created_at": "2026-07-13T00:00:00+00:00",
          "family": "Open Sans",
          "file_url": "https://cdn.sudomock.com/mockup-assets/fonts/web/9f1c2d3e-4a5b-6c7d-8e9f-0a1b2c3d4e5f.woff2",
          "is_premium": false,
          "is_system": true,
          "license": "OFL",
          "postscript_name": "OpenSans-Regular",
          "subfamily": "Regular",
          "uuid": "9f1c2d3e-4a5b-6c7d-8e9f-0a1b2c3d4e5f",
          "preview_url": null
        }
      },
      "GroupLayer": {
        "properties": {
          "uuid": {
            "type": "string",
            "description": "Unique identifier for the group layer",
            "examples": [
              "5e8b0c72-9a41-4d36-b7f8-2c60d1e94537"
            ]
          },
          "name": {
            "type": "string",
            "description": "Name of the group layer",
            "examples": [
              "Outlined logo"
            ]
          },
          "has_stroke_effect": {
            "type": "boolean",
            "description": "Whether the group has at least one outline of its own",
            "default": true
          },
          "stroke_count": {
            "type": "integer",
            "minimum": 1.0,
            "description": "Number of outlines owned by this group, in front-to-back stroke_color order",
            "examples": [
              2
            ]
          }
        },
        "type": "object",
        "required": [
          "uuid",
          "name",
          "stroke_count"
        ],
        "title": "GroupLayer",
        "description": "Group layer with editable outlines in upload/detail responses."
      },
      "GroupLayerInput": {
        "properties": {
          "uuid": {
            "type": "string",
            "pattern": "^[0-9a-f]{8}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{12}$",
            "description": "UUID of the group layer to update (from the upload/detail response group_layers list)",
            "examples": [
              "b2c14e08-5a7d-4f36-a91b-7e0d5c283a64"
            ]
          },
          "stroke_color": {
            "anyOf": [
              {
                "type": "string"
              },
              {
                "items": {
                  "anyOf": [
                    {
                      "type": "string"
                    },
                    {
                      "type": "null"
                    }
                  ]
                },
                "type": "array"
              }
            ],
            "description": "Color for the group's outlines. Send a hex value like \"#FFFFFF\" to recolor the front outline, or a list in stroke_count order (front to back). Use null to keep an outline's original color; extra entries are ignored. The change affects everything inside this group.",
            "examples": [
              "#FFFFFF",
              [
                "#FFFFFF",
                null
              ]
            ]
          }
        },
        "type": "object",
        "required": [
          "uuid",
          "stroke_color"
        ],
        "title": "GroupLayerInput",
        "description": "Group outline override for rendering."
      },
      "JobAcceptedResponse": {
        "properties": {
          "job_id": {
            "type": "string",
            "description": "Identifier of the queued job, used to poll its status.",
            "examples": [
              "5f1c0b2a-7d43-4e9a-8c16-0b5d3f7a2e94"
            ]
          },
          "kind": {
            "type": "string",
            "description": "The kind of work accepted: render, upload, or photo_mockup_render.",
            "examples": [
              "render"
            ]
          },
          "status": {
            "type": "string",
            "description": "State of the job when this response was returned, usually queued.",
            "examples": [
              "queued"
            ]
          },
          "status_url": {
            "type": "string",
            "description": "Path to poll for this job's status.",
            "examples": [
              "/api/v1/jobs/5f1c0b2a-7d43-4e9a-8c16-0b5d3f7a2e94"
            ]
          }
        },
        "type": "object",
        "required": [
          "job_id",
          "kind",
          "status",
          "status_url"
        ],
        "title": "JobAcceptedResponse",
        "description": "Acknowledgement that an async request was accepted as a job."
      },
      "JobError": {
        "properties": {
          "error_code": {
            "type": "string",
            "description": "Stable code for this failure, safe to branch on in your own code.",
            "examples": [
              "JOB_FAILED"
            ]
          },
          "message": {
            "type": "string",
            "description": "Plain language explanation of what went wrong.",
            "examples": [
              "The job could not be completed."
            ]
          }
        },
        "type": "object",
        "required": [
          "error_code",
          "message"
        ],
        "title": "JobError",
        "description": "Why a job produced no result."
      },
      "JobListItem": {
        "properties": {
          "job_id": {
            "type": "string",
            "description": "Identifier of this job.",
            "examples": [
              "5f1c0b2a-7d43-4e9a-8c16-0b5d3f7a2e94"
            ]
          },
          "kind": {
            "type": "string",
            "description": "What this job does: render, video, upload, 2d_create, 2d_render, photo_mockup_create or photo_mockup_render.",
            "examples": [
              "video"
            ]
          },
          "status": {
            "type": "string",
            "enum": [
              "queued",
              "dispatched",
              "running",
              "succeeded",
              "failed",
              "cancelled"
            ],
            "description": "Where the job stands, and it is over once this reads succeeded, failed or cancelled."
          },
          "result_url": {
            "anyOf": [
              {
                "type": "string"
              },
              {
                "type": "null"
              }
            ],
            "description": "Link to the finished file, or the path of the mockup that was created, and null until the job succeeds.",
            "examples": [
              "https://cdn.sudomock.com/mockup-assets/videos/5f1c0b2a/clip.mp4"
            ]
          },
          "mockup_uuid": {
            "anyOf": [
              {
                "type": "string"
              },
              {
                "type": "null"
              }
            ],
            "description": "Identifier of the mockup this job created, and null for jobs that hand back a file instead."
          },
          "error": {
            "anyOf": [
              {
                "$ref": "#/components/schemas/JobError"
              },
              {
                "type": "null"
              }
            ],
            "description": "Why the job produced no result, and null unless it failed or was cancelled."
          },
          "credits_charged": {
            "anyOf": [
              {
                "type": "integer"
              },
              {
                "type": "null"
              }
            ],
            "description": "Credits you actually paid for this job, which is zero once a failed or cancelled job has been refunded.",
            "examples": [
              38
            ]
          },
          "payg": {
            "anyOf": [
              {
                "$ref": "#/components/schemas/JobPaygCost"
              },
              {
                "type": "null"
              }
            ],
            "description": "Pay as you go cost of this job, and null when it was paid for with plan or extra credits."
          },
          "watermark": {
            "anyOf": [
              {
                "$ref": "#/components/schemas/JobWatermark"
              },
              {
                "type": "null"
              }
            ],
            "description": "Why this result is marked and how to get unmarked results, and null when the result is clean."
          },
          "created_at": {
            "type": "string",
            "description": "When this job was submitted.",
            "examples": [
              "2026-09-18T10:24:31.482913+00:00"
            ]
          },
          "updated_at": {
            "type": "string",
            "description": "When this job last changed.",
            "examples": [
              "2026-09-18T10:41:07.118204+00:00"
            ]
          },
          "model": {
            "anyOf": [
              {
                "type": "string"
              },
              {
                "type": "null"
              }
            ],
            "description": "The video model that produced this clip, present on video jobs only."
          },
          "outcome_tier": {
            "anyOf": [
              {
                "type": "string"
              },
              {
                "type": "null"
              }
            ],
            "description": "The quality level this clip was produced at, present on video jobs only.",
            "examples": [
              "standard"
            ]
          },
          "duration_seconds": {
            "anyOf": [
              {
                "type": "integer"
              },
              {
                "type": "null"
              }
            ],
            "description": "Length of the clip in seconds, and null for a job that is not a video.",
            "examples": [
              4
            ]
          },
          "audio": {
            "anyOf": [
              {
                "type": "boolean"
              },
              {
                "type": "null"
              }
            ],
            "description": "Whether the clip was produced with sound, and null for a job that is not a video.",
            "examples": [
              false
            ]
          },
          "mockup_name": {
            "anyOf": [
              {
                "type": "string"
              },
              {
                "type": "null"
              }
            ],
            "description": "Name of the mockup this job started from, and null when it started from an image instead.",
            "examples": [
              "Heavyweight Tee"
            ]
          },
          "poster_url": {
            "anyOf": [
              {
                "type": "string"
              },
              {
                "type": "null"
              }
            ],
            "description": "Link to a still frame you can show before the clip plays, and null until that frame exists."
          }
        },
        "type": "object",
        "required": [
          "job_id",
          "kind",
          "status",
          "created_at",
          "updated_at"
        ],
        "title": "JobListItem",
        "description": "One job in the list, with the extra details a list view shows.",
        "example": {
          "created_at": "2026-09-18T10:24:31.482913+00:00",
          "credits_charged": 38,
          "job_id": "5f1c0b2a-7d43-4e9a-8c16-0b5d3f7a2e94",
          "kind": "video",
          "model": "veo-3.1-fast",
          "outcome_tier": "standard",
          "result_url": "https://cdn.sudomock.com/mockup-assets/videos/5f1c0b2a/clip.mp4",
          "status": "succeeded",
          "updated_at": "2026-09-18T10:41:07.118204+00:00",
          "error": null,
          "mockup_uuid": null,
          "payg": null,
          "watermark": null
        }
      },
      "JobListResponse": {
        "properties": {
          "jobs": {
            "items": {
              "$ref": "#/components/schemas/JobListItem"
            },
            "type": "array",
            "description": "The jobs on this page, newest first."
          },
          "next_cursor": {
            "anyOf": [
              {
                "type": "string"
              },
              {
                "type": "null"
              }
            ],
            "description": "Send this back as cursor to read the next page, and null when this is the last page."
          }
        },
        "type": "object",
        "required": [
          "jobs"
        ],
        "title": "JobListResponse",
        "description": "A page of your jobs, newest first.",
        "example": {
          "jobs": [
            {
              "audio": false,
              "created_at": "2026-09-18T10:24:31.482913+00:00",
              "credits_charged": 38,
              "duration_seconds": 4,
              "job_id": "5f1c0b2a-7d43-4e9a-8c16-0b5d3f7a2e94",
              "kind": "video",
              "mockup_name": "Heavyweight Tee",
              "model": "veo-3.1-fast",
              "outcome_tier": "standard",
              "poster_url": "https://cdn.sudomock.com/mockup-assets/videos/5f1c0b2a/poster.webp",
              "result_url": "https://cdn.sudomock.com/mockup-assets/videos/5f1c0b2a/clip.mp4",
              "status": "succeeded",
              "updated_at": "2026-09-18T10:41:07.118204+00:00",
              "error": null,
              "mockup_uuid": null,
              "payg": null,
              "watermark": null
            }
          ],
          "next_cursor": "MjAyNi0wOS0xOFQxMDoyNDozMS40ODI5MTMrMDA6MDB8NWYxYzBiMmEtN2Q0My00ZTlhLThjMTYtMGI1ZDNmN2EyZTk0"
        }
      },
      "JobPaygCost": {
        "properties": {
          "credits": {
            "anyOf": [
              {
                "type": "integer"
              },
              {
                "type": "null"
              }
            ],
            "description": "Credits this job bills.",
            "examples": [
              38
            ]
          },
          "unit_price": {
            "anyOf": [
              {
                "type": "number"
              },
              {
                "type": "null"
              }
            ],
            "description": "Price of one credit in US dollars for this account.",
            "examples": [
              0.0093
            ]
          },
          "cost": {
            "anyOf": [
              {
                "type": "number"
              },
              {
                "type": "null"
              }
            ],
            "description": "Total US dollars for this job, the credits multiplied by the unit price.",
            "examples": [
              0.3534
            ]
          }
        },
        "type": "object",
        "title": "JobPaygCost",
        "description": "What this job costs at the account's pay as you go rate."
      },
      "JobStatusResponse": {
        "properties": {
          "job_id": {
            "type": "string",
            "description": "Identifier of this job.",
            "examples": [
              "5f1c0b2a-7d43-4e9a-8c16-0b5d3f7a2e94"
            ]
          },
          "kind": {
            "type": "string",
            "description": "What this job does: render, video, upload, 2d_create, 2d_render, photo_mockup_create or photo_mockup_render.",
            "examples": [
              "video"
            ]
          },
          "status": {
            "type": "string",
            "enum": [
              "queued",
              "dispatched",
              "running",
              "succeeded",
              "failed",
              "cancelled"
            ],
            "description": "Where the job stands, and it is over once this reads succeeded, failed or cancelled."
          },
          "result_url": {
            "anyOf": [
              {
                "type": "string"
              },
              {
                "type": "null"
              }
            ],
            "description": "Link to the finished file, or the path of the mockup that was created, and null until the job succeeds.",
            "examples": [
              "https://cdn.sudomock.com/mockup-assets/videos/5f1c0b2a/clip.mp4"
            ]
          },
          "mockup_uuid": {
            "anyOf": [
              {
                "type": "string"
              },
              {
                "type": "null"
              }
            ],
            "description": "Identifier of the mockup this job created, and null for jobs that hand back a file instead."
          },
          "error": {
            "anyOf": [
              {
                "$ref": "#/components/schemas/JobError"
              },
              {
                "type": "null"
              }
            ],
            "description": "Why the job produced no result, and null unless it failed or was cancelled."
          },
          "credits_charged": {
            "anyOf": [
              {
                "type": "integer"
              },
              {
                "type": "null"
              }
            ],
            "description": "Credits you actually paid for this job, which is zero once a failed or cancelled job has been refunded.",
            "examples": [
              38
            ]
          },
          "payg": {
            "anyOf": [
              {
                "$ref": "#/components/schemas/JobPaygCost"
              },
              {
                "type": "null"
              }
            ],
            "description": "Pay as you go cost of this job, and null when it was paid for with plan or extra credits."
          },
          "watermark": {
            "anyOf": [
              {
                "$ref": "#/components/schemas/JobWatermark"
              },
              {
                "type": "null"
              }
            ],
            "description": "Why this result is marked and how to get unmarked results, and null when the result is clean."
          },
          "created_at": {
            "type": "string",
            "description": "When this job was submitted.",
            "examples": [
              "2026-09-18T10:24:31.482913+00:00"
            ]
          },
          "updated_at": {
            "type": "string",
            "description": "When this job last changed.",
            "examples": [
              "2026-09-18T10:41:07.118204+00:00"
            ]
          },
          "model": {
            "anyOf": [
              {
                "type": "string"
              },
              {
                "type": "null"
              }
            ],
            "description": "The video model that produced this clip, present on video jobs only."
          },
          "outcome_tier": {
            "anyOf": [
              {
                "type": "string"
              },
              {
                "type": "null"
              }
            ],
            "description": "The quality level this clip was produced at, present on video jobs only.",
            "examples": [
              "standard"
            ]
          }
        },
        "type": "object",
        "required": [
          "job_id",
          "kind",
          "status",
          "created_at",
          "updated_at"
        ],
        "title": "JobStatusResponse",
        "description": "Where a job stands right now, and its result once it has finished.",
        "example": {
          "created_at": "2026-09-18T10:24:31.482913+00:00",
          "credits_charged": 38,
          "job_id": "5f1c0b2a-7d43-4e9a-8c16-0b5d3f7a2e94",
          "kind": "video",
          "model": "veo-3.1-fast",
          "outcome_tier": "standard",
          "result_url": "https://cdn.sudomock.com/mockup-assets/videos/5f1c0b2a/clip.mp4",
          "status": "succeeded",
          "updated_at": "2026-09-18T10:41:07.118204+00:00",
          "error": null,
          "mockup_uuid": null,
          "payg": null,
          "watermark": null
        }
      },
      "JobWatermark": {
        "properties": {
          "reason": {
            "type": "string",
            "description": "Why this result was marked."
          },
          "remove_url": {
            "type": "string",
            "description": "Where to go to start getting unmarked results.",
            "examples": [
              "https://sudomock.com/dashboard/billing?action=topup#payg-section"
            ]
          }
        },
        "type": "object",
        "required": [
          "reason",
          "remove_url"
        ],
        "title": "JobWatermark",
        "description": "Why the result carries a watermark, and where to get results without one."
      },
      "MeAccountData": {
        "properties": {
          "uuid": {
            "type": "string",
            "description": "User UUID",
            "examples": [
              "c33f5fdf-346e-4c37-8686-9afcca4645ef"
            ]
          },
          "email": {
            "type": "string",
            "description": "User email address",
            "examples": [
              "user@example.com"
            ]
          },
          "name": {
            "anyOf": [
              {
                "type": "string"
              },
              {
                "type": "null"
              }
            ],
            "description": "Account or company name",
            "examples": [
              "Acme Corp"
            ]
          },
          "created_at": {
            "type": "string",
            "format": "date-time",
            "description": "Account creation timestamp",
            "examples": [
              "2025-06-15T10:30:00Z"
            ]
          }
        },
        "type": "object",
        "required": [
          "uuid",
          "email",
          "created_at"
        ],
        "title": "MeAccountData",
        "description": "Account information in /me response",
        "example": {
          "created_at": "2025-06-15T10:30:00Z",
          "email": "user@example.com",
          "name": "Acme Corp",
          "uuid": "123e4567-e89b-12d3-a456-426614174000"
        }
      },
      "MeApiKeyData": {
        "properties": {
          "name": {
            "type": "string",
            "description": "API key name",
            "examples": [
              "Production Key"
            ]
          },
          "created_at": {
            "type": "string",
            "format": "date-time",
            "description": "When the API key was created",
            "examples": [
              "2025-06-15T10:30:00Z"
            ]
          },
          "last_used_at": {
            "anyOf": [
              {
                "type": "string",
                "format": "date-time"
              },
              {
                "type": "null"
              }
            ],
            "description": "Last time the API key was used",
            "examples": [
              "2026-01-05T00:25:00Z"
            ]
          },
          "total_requests": {
            "type": "integer",
            "description": "Total credit-consuming operations recorded for this API key",
            "examples": [
              847293
            ]
          }
        },
        "type": "object",
        "required": [
          "name",
          "created_at",
          "total_requests"
        ],
        "title": "MeApiKeyData",
        "description": "API key metadata in /me response",
        "example": {
          "created_at": "2025-06-15T10:30:00Z",
          "last_used_at": "2026-01-05T00:25:00Z",
          "name": "Production Key",
          "total_requests": 847293
        }
      },
      "MeOrganizationData": {
        "properties": {
          "id": {
            "type": "string",
            "description": "Organization UUID",
            "examples": [
              "97d7a314-29be-47b5-997c-df7f0ca71eb8"
            ]
          },
          "name": {
            "type": "string",
            "description": "Organization name",
            "examples": [
              "Acme"
            ]
          }
        },
        "type": "object",
        "required": [
          "id",
          "name"
        ],
        "title": "MeOrganizationData",
        "description": "Organization the request acts on in /me response",
        "example": {
          "id": "123e4567-e89b-12d3-a456-426614174000",
          "name": "Acme"
        }
      },
      "MeResponse": {
        "properties": {
          "data": {
            "$ref": "#/components/schemas/MeResponseData",
            "description": "Response data"
          },
          "success": {
            "type": "boolean",
            "description": "Success status",
            "default": true,
            "examples": [
              true
            ]
          }
        },
        "type": "object",
        "required": [
          "data"
        ],
        "title": "MeResponse",
        "description": "Your account, plan, usage and remaining credits.",
        "example": {
          "data": {
            "account": {
              "created_at": "2025-06-15T10:30:00Z",
              "email": "user@example.com",
              "name": "Acme Corp",
              "uuid": "123e4567-e89b-12d3-a456-426614174000"
            },
            "api_key": {
              "created_at": "2025-06-15T10:30:00Z",
              "last_used_at": "2026-01-05T00:25:00Z",
              "name": "Production Key",
              "total_requests": 847293
            },
            "organization": {
              "id": "123e4567-e89b-12d3-a456-426614174000",
              "name": "Acme"
            },
            "subscription": {
              "billing_channel": "stripe",
              "current_period_end": "2026-02-05T00:00:00Z",
              "plan": "pro-25k",
              "status": "active",
              "tier": "pro"
            },
            "usage": {
              "billing_period_end": "2026-02-01T00:00:00Z",
              "billing_period_start": "2026-01-01T00:00:00Z",
              "credits_limit": 50000,
              "credits_remaining": 37153,
              "credits_used_this_month": 12847,
              "prepaid_balance": 0.0,
              "prepaid_balance_currency": "USD"
            }
          },
          "success": true
        }
      },
      "MeResponseData": {
        "properties": {
          "account": {
            "$ref": "#/components/schemas/MeAccountData",
            "description": "User account information"
          },
          "organization": {
            "$ref": "#/components/schemas/MeOrganizationData",
            "description": "Organization that owns the subscription and usage below"
          },
          "subscription": {
            "$ref": "#/components/schemas/MeSubscriptionData",
            "description": "Subscription details"
          },
          "usage": {
            "$ref": "#/components/schemas/MeUsageData",
            "description": "Usage statistics"
          },
          "api_key": {
            "anyOf": [
              {
                "$ref": "#/components/schemas/MeApiKeyData"
              },
              {
                "type": "null"
              }
            ],
            "description": "Current API key metadata"
          }
        },
        "type": "object",
        "required": [
          "account",
          "organization",
          "subscription",
          "usage"
        ],
        "title": "MeResponseData",
        "description": "Data payload in /me response"
      },
      "MeSubscriptionData": {
        "properties": {
          "plan": {
            "type": "string",
            "description": "Plan slug (e.g., 'pro-25k', 'scale-100k', 'free')",
            "examples": [
              "pro-25k"
            ]
          },
          "tier": {
            "type": "string",
            "description": "Plan tier for feature gating (e.g., 'free', 'pro', 'scale')",
            "examples": [
              "pro"
            ]
          },
          "status": {
            "type": "string",
            "description": "Subscription status: 'active', 'cancelled', 'past_due', 'expired', 'paused'",
            "examples": [
              "active"
            ]
          },
          "current_period_end": {
            "anyOf": [
              {
                "type": "string",
                "format": "date-time"
              },
              {
                "type": "null"
              }
            ],
            "description": "End of current billing period",
            "examples": [
              "2026-02-05T00:00:00Z"
            ]
          },
          "billing_channel": {
            "type": "string",
            "enum": [
              "shopify",
              "stripe",
              "none"
            ],
            "description": "Which billing channel currently owns this subscription.",
            "default": "none",
            "examples": [
              "stripe"
            ]
          }
        },
        "type": "object",
        "required": [
          "plan",
          "tier",
          "status"
        ],
        "title": "MeSubscriptionData",
        "description": "Subscription information in /me response",
        "example": {
          "billing_channel": "stripe",
          "current_period_end": "2026-02-05T00:00:00Z",
          "plan": "pro-25k",
          "status": "active",
          "tier": "pro"
        }
      },
      "MeUsageData": {
        "properties": {
          "credits_used_this_month": {
            "type": "integer",
            "description": "Credits used in current billing period",
            "examples": [
              12847
            ]
          },
          "credits_limit": {
            "type": "integer",
            "description": "Total credits available per month from plan",
            "examples": [
              50000
            ]
          },
          "credits_remaining": {
            "type": "integer",
            "description": "Credits remaining (calculated)",
            "examples": [
              37153
            ]
          },
          "billing_period_start": {
            "type": "string",
            "format": "date-time",
            "description": "Start of current billing period",
            "examples": [
              "2026-01-01T00:00:00Z"
            ]
          },
          "billing_period_end": {
            "type": "string",
            "format": "date-time",
            "description": "End of current billing period",
            "examples": [
              "2026-02-01T00:00:00Z"
            ]
          },
          "prepaid_balance": {
            "type": "number",
            "description": "Prepaid balance remaining, in prepaid_balance_currency. 0 when the account holds no balance (never null). Independent of the credits_* fields above, which count a subscription allotment.",
            "examples": [
              4.3
            ]
          },
          "prepaid_balance_currency": {
            "type": "string",
            "description": "ISO 4217 currency of prepaid_balance. Always USD today.",
            "examples": [
              "USD"
            ]
          }
        },
        "type": "object",
        "required": [
          "credits_used_this_month",
          "credits_limit",
          "credits_remaining",
          "billing_period_start",
          "billing_period_end",
          "prepaid_balance",
          "prepaid_balance_currency"
        ],
        "title": "MeUsageData",
        "description": "Usage statistics in /me response",
        "example": {
          "billing_period_end": "2026-02-01T00:00:00Z",
          "billing_period_start": "2026-01-01T00:00:00Z",
          "credits_limit": 50000,
          "credits_remaining": 37153,
          "credits_used_this_month": 12847,
          "prepaid_balance": 4.3,
          "prepaid_balance_currency": "USD"
        }
      },
      "MockupColour": {
        "properties": {
          "label": {
            "type": "string",
            "maxLength": 32,
            "minLength": 1,
            "description": "What you call this colour, e.g. 'blue jean'. Matched exactly when a render asks for it."
          },
          "hex": {
            "type": "string",
            "pattern": "^#[0-9A-Fa-f]{6}$",
            "description": "The colour the name paints, e.g. '#6A8296'."
          }
        },
        "type": "object",
        "required": [
          "label",
          "hex"
        ],
        "title": "MockupColour",
        "description": "A name this mockup answers to, and the colour it paints."
      },
      "MockupLayer": {
        "properties": {
          "uuid": {
            "type": "string",
            "description": "The layer's UUID. Send it in hidden_layers to leave the layer out of a render. A smart object, text layer or group listed in the mockup's smart_objects, text_layers or group_layers carries the same UUID here.",
            "examples": [
              "423e4567-e89b-12d3-a456-426614174003"
            ]
          },
          "name": {
            "type": "string",
            "description": "The layer's name in the PSD.",
            "examples": [
              "Sleeve badge"
            ]
          },
          "kind": {
            "type": "string",
            "description": "What the layer is: artboard, group, smart_object, text, pixel, shape, fill or adjustment.",
            "examples": [
              "group"
            ]
          },
          "visible": {
            "type": "boolean",
            "description": "Whether the layer is shown in the source file. False as well when a group or artboard around it is hidden.",
            "examples": [
              true
            ]
          },
          "children": {
            "items": {
              "$ref": "#/components/schemas/MockupLayer"
            },
            "type": "array",
            "description": "The layers inside this layer, front-most first: a group's own layers, or the layers of a smart object's contents when those contents hold layers you can fill. Copies of one smart object share their contents, which are listed under one copy. An artboard's own layers are listed right before the artboard at the top level, not here. Empty for every other layer."
          }
        },
        "type": "object",
        "required": [
          "uuid",
          "name",
          "kind",
          "visible"
        ],
        "title": "MockupLayer",
        "description": "One layer of a PSD mockup, as Photoshop's Layers panel shows it."
      },
      "MockupLayersData": {
        "properties": {
          "mockup_uuid": {
            "type": "string",
            "description": "The mockup these layers belong to.",
            "examples": [
              "123e4567-e89b-12d3-a456-426614174000"
            ]
          },
          "layers": {
            "items": {
              "$ref": "#/components/schemas/MockupLayer"
            },
            "type": "array",
            "description": "Top-level layers, front-most first, in the order Photoshop's Layers panel lists them. A group carries its own layers in children, and so does a smart object whose contents hold layers you can fill."
          }
        },
        "type": "object",
        "required": [
          "mockup_uuid",
          "layers"
        ],
        "title": "MockupLayersData",
        "description": "The layers of one PSD mockup."
      },
      "MockupLayersResponse": {
        "properties": {
          "success": {
            "type": "boolean",
            "description": "Always true on a successful response.",
            "default": true,
            "examples": [
              true
            ]
          },
          "data": {
            "$ref": "#/components/schemas/MockupLayersData",
            "description": "The mockup's layers."
          }
        },
        "type": "object",
        "required": [
          "data"
        ],
        "title": "MockupLayersResponse",
        "description": "Every layer of a PSD mockup, nested the way Photoshop's Layers panel shows them.",
        "example": {
          "data": {
            "layers": [
              {
                "children": [
                  {
                    "children": [],
                    "kind": "text",
                    "name": "Badge text",
                    "uuid": "523e4567-e89b-12d3-a456-426614174004",
                    "visible": true
                  },
                  {
                    "children": [],
                    "kind": "shape",
                    "name": "Badge shape",
                    "uuid": "623e4567-e89b-12d3-a456-426614174005",
                    "visible": true
                  }
                ],
                "kind": "group",
                "name": "Sleeve badge",
                "uuid": "423e4567-e89b-12d3-a456-426614174003",
                "visible": true
              },
              {
                "children": [],
                "kind": "text",
                "name": "Name",
                "uuid": "323e4567-e89b-12d3-a456-426614174002",
                "visible": true
              },
              {
                "children": [],
                "kind": "text",
                "name": "Nickname",
                "uuid": "923e4567-e89b-12d3-a456-426614174008",
                "visible": false
              },
              {
                "children": [],
                "kind": "smart_object",
                "name": "Main Design",
                "uuid": "223e4567-e89b-12d3-a456-426614174001",
                "visible": true
              },
              {
                "children": [],
                "kind": "pixel",
                "name": "T-shirt",
                "uuid": "723e4567-e89b-12d3-a456-426614174006",
                "visible": true
              },
              {
                "children": [],
                "kind": "fill",
                "name": "Background",
                "uuid": "823e4567-e89b-12d3-a456-426614174007",
                "visible": true
              }
            ],
            "mockup_uuid": "123e4567-e89b-12d3-a456-426614174000"
          },
          "success": true
        }
      },
      "MockupListData": {
        "properties": {
          "mockups": {
            "items": {
              "$ref": "#/components/schemas/UploadResponseData"
            },
            "type": "array",
            "description": "List of mockup templates"
          },
          "total": {
            "type": "integer",
            "description": "Total number of mockups matching filters",
            "examples": [
              137
            ]
          },
          "limit": {
            "type": "integer",
            "description": "Results per page",
            "examples": [
              20
            ]
          },
          "offset": {
            "type": "integer",
            "description": "Pagination offset",
            "examples": [
              0
            ]
          }
        },
        "type": "object",
        "required": [
          "mockups",
          "total",
          "limit",
          "offset"
        ],
        "title": "MockupListData",
        "description": "Typed data payload for mockup list response"
      },
      "MockupListResponse": {
        "properties": {
          "success": {
            "type": "boolean",
            "description": "Always true on a successful response.",
            "default": true,
            "examples": [
              true
            ]
          },
          "data": {
            "$ref": "#/components/schemas/MockupListData",
            "description": "The page of mockups, with its total, limit and offset."
          }
        },
        "type": "object",
        "required": [
          "data"
        ],
        "title": "MockupListResponse",
        "description": "List response wrapper for GET /api/v1/psd-mockups",
        "example": {
          "data": {
            "limit": 20,
            "mockups": [
              {
                "collections": [],
                "group_layers": [],
                "height": 5000,
                "name": "Heavyweight tee front",
                "smart_objects": [
                  {
                    "layer_name": "Front print",
                    "name": "Front print",
                    "position": {
                      "height": 3413,
                      "width": 3000,
                      "x": 512,
                      "y": 730
                    },
                    "print_area_presets": [
                      {
                        "name": "Default",
                        "position": {
                          "height": 3413,
                          "width": 3000,
                          "x": 0,
                          "y": 0
                        },
                        "size": {
                          "height": 3413,
                          "width": 3000
                        },
                        "thumbnails": [],
                        "uuid": "d07f5b18-2c94-4e83-a6b1-95f3c8e27a40"
                      }
                    ],
                    "size": {
                      "height": 3413,
                      "width": 3000
                    },
                    "uuid": "b41a7e52-93c8-4d61-8f07-2ae5c9d04713",
                    "blend_mode": null,
                    "quad": null
                  }
                ],
                "text_layers": [],
                "thumbnail": "https://cdn.sudomock.com/mockup-assets/8f2c1d90-6b4e-4a37-9e55-0d1c7a3f21b8/thumbnails/thumb_720.webp",
                "thumbnails": [
                  {
                    "url": "https://cdn.sudomock.com/mockup-assets/8f2c1d90-6b4e-4a37-9e55-0d1c7a3f21b8/thumbnails/thumb_720.webp",
                    "width": 720
                  }
                ],
                "uuid": "8f2c1d90-6b4e-4a37-9e55-0d1c7a3f21b8",
                "width": 4000
              }
            ],
            "offset": 0,
            "total": 1
          },
          "success": true
        }
      },
      "MockupUpdateRequest": {
        "properties": {
          "name": {
            "anyOf": [
              {
                "type": "string",
                "maxLength": 255,
                "minLength": 1
              },
              {
                "type": "null"
              }
            ],
            "description": "New mockup name"
          },
          "colors": {
            "anyOf": [
              {
                "items": {
                  "$ref": "#/components/schemas/MockupColour"
                },
                "type": "array",
                "maxItems": 96
              },
              {
                "type": "null"
              }
            ],
            "description": "The colours this mockup answers to by name. Replaces the whole list, so send every colour you want to keep. Send [] to clear it."
          }
        },
        "type": "object",
        "title": "MockupUpdateRequest",
        "description": "Update request for PATCH /api/v1/psd-mockups/{uuid}",
        "example": {
          "name": "Updated Mockup Name"
        }
      },
      "PaletteColour": {
        "properties": {
          "hex": {
            "type": "string",
            "pattern": "^#[0-9A-Fa-f]{6}$",
            "description": "Color value as a #rrggbb hex string.",
            "examples": [
              "#1a1a1a"
            ]
          },
          "label": {
            "anyOf": [
              {
                "type": "string",
                "maxLength": 32
              },
              {
                "type": "null"
              }
            ],
            "description": "Your own name for this color.",
            "examples": [
              "Black Heather"
            ]
          }
        },
        "additionalProperties": false,
        "type": "object",
        "required": [
          "hex"
        ],
        "title": "PaletteColour",
        "description": "One colour the editor offers, with your name for it."
      },
      "PhotoMockup": {
        "properties": {
          "mockup_id": {
            "type": "string",
            "description": "Unique identifier for the mockup.",
            "examples": [
              "893ea326-278b-480b-b130-87dd6aee06dc"
            ]
          },
          "name": {
            "type": "string",
            "description": "Display name of the mockup.",
            "examples": [
              "Front view"
            ]
          },
          "status": {
            "type": "string",
            "description": "Preparation state of the mockup: draft, processing, ready or error.",
            "examples": [
              "ready"
            ]
          },
          "customizable": {
            "type": "boolean",
            "description": "Whether the mockup is ready to accept artwork."
          },
          "thumbnail_url": {
            "anyOf": [
              {
                "type": "string"
              },
              {
                "type": "null"
              }
            ],
            "description": "URL of the mockup's thumbnail image."
          },
          "source_width": {
            "anyOf": [
              {
                "type": "integer"
              },
              {
                "type": "null"
              }
            ],
            "description": "Width of the source image in pixels.",
            "examples": [
              2048
            ]
          },
          "source_height": {
            "anyOf": [
              {
                "type": "integer"
              },
              {
                "type": "null"
              }
            ],
            "description": "Height of the source image in pixels.",
            "examples": [
              2048
            ]
          },
          "print_areas": {
            "items": {
              "$ref": "#/components/schemas/PhotoMockupPrintArea"
            },
            "type": "array",
            "description": "Printable areas saved on this mockup."
          },
          "version": {
            "type": "integer",
            "description": "Version of this mockup's saved definition.",
            "default": 1
          },
          "created_at": {
            "type": "string",
            "format": "date-time",
            "description": "When the mockup was created.",
            "examples": [
              "2026-09-18T10:24:31.482913Z"
            ]
          },
          "updated_at": {
            "type": "string",
            "format": "date-time",
            "description": "When the mockup was last updated.",
            "examples": [
              "2026-09-18T10:41:07.118204Z"
            ]
          }
        },
        "type": "object",
        "required": [
          "mockup_id",
          "name",
          "status",
          "customizable",
          "created_at",
          "updated_at"
        ],
        "title": "PhotoMockup"
      },
      "PhotoMockupAdjustments": {
        "properties": {
          "brightness": {
            "type": "integer",
            "maximum": 150.0,
            "minimum": -150.0,
            "description": "Brightness applied to the artwork, from -150 to 150, where 0 keeps it unchanged.",
            "default": 0
          },
          "contrast": {
            "type": "integer",
            "maximum": 100.0,
            "minimum": -100.0,
            "description": "Contrast applied to the artwork, from -100 to 100, where 0 keeps it unchanged.",
            "default": 0
          },
          "opacity": {
            "type": "integer",
            "maximum": 100.0,
            "minimum": 0.0,
            "description": "How opaque the artwork is, from 0 for fully transparent to 100 for opaque.",
            "default": 100
          },
          "saturation": {
            "type": "integer",
            "maximum": 100.0,
            "minimum": -100.0,
            "description": "Saturation applied to the artwork, from -100 for grayscale to 100 for fully saturated.",
            "default": 0
          },
          "vibrance": {
            "type": "integer",
            "maximum": 100.0,
            "minimum": -100.0,
            "description": "Saturation that affects muted colors more than already vivid ones, from -100 to 100.",
            "default": 0
          },
          "blur": {
            "type": "integer",
            "maximum": 100.0,
            "minimum": 0.0,
            "description": "Softens the artwork, from 0 for sharp to 100 for the strongest blur.",
            "default": 0
          },
          "blend_mode": {
            "type": "string",
            "enum": [
              "multiply",
              "normal",
              "screen",
              "lighten",
              "soft_light",
              "overlay",
              "darken"
            ],
            "description": "How the artwork sits on the product surface. 'multiply' keeps the material texture visible and is the best choice on light fabric (default); 'normal' reproduces the artwork colors exactly, whatever the product color, and is the right choice when a brand color has to match the supplied file; 'screen' lightens the artwork against the surface, which is worth reaching for only when you want that lighter result, since the default already adapts to a dark garment; 'lighten' keeps the artwork only where it is brighter than the surface; 'soft_light' gives a subtle, low-contrast finish that follows the surface; 'overlay' deepens contrast so the artwork reads as part of the material; 'darken' keeps the artwork only where it is darker than the surface.",
            "default": "multiply"
          }
        },
        "additionalProperties": false,
        "type": "object",
        "title": "PhotoMockupAdjustments",
        "description": "Outcome-level controls for the photo mockup render."
      },
      "PhotoMockupCreateAcceptedResponse": {
        "properties": {
          "job_id": {
            "type": "string",
            "description": "Identifier of the queued job, used to poll its status."
          },
          "kind": {
            "type": "string",
            "enum": [
              "2d_create",
              "photo_mockup_create"
            ],
            "description": "The kind of work accepted, which is always a photo mockup create."
          },
          "status": {
            "type": "string",
            "enum": [
              "queued",
              "dispatched",
              "running",
              "succeeded",
              "failed",
              "cancelled"
            ],
            "description": "State of the job when this response was returned."
          },
          "status_url": {
            "type": "string",
            "description": "Path to poll for this job's status."
          }
        },
        "type": "object",
        "required": [
          "job_id",
          "kind",
          "status",
          "status_url"
        ],
        "title": "PhotoMockupCreateAcceptedResponse",
        "description": "Async photo mockup create acknowledgement.",
        "example": {
          "job_id": "5f1c0b2a-7d43-4e9a-8c16-0b5d3f7a2e94",
          "kind": "photo_mockup_create",
          "status": "queued",
          "status_url": "/api/v1/jobs/5f1c0b2a-7d43-4e9a-8c16-0b5d3f7a2e94"
        }
      },
      "PhotoMockupCreateRequest": {
        "properties": {
          "source_url": {
            "anyOf": [
              {
                "type": "string"
              },
              {
                "type": "null"
              }
            ],
            "description": "Public HTTPS URL of the source image.",
            "examples": [
              "https://example.com/product-photo.jpg"
            ]
          },
          "source_base64": {
            "anyOf": [
              {
                "type": "string"
              },
              {
                "type": "null"
              }
            ],
            "description": "Base64-encoded source image, with or without a data URL prefix."
          },
          "name": {
            "anyOf": [
              {
                "type": "string",
                "maxLength": 255
              },
              {
                "type": "null"
              }
            ],
            "description": "Optional display name for the mockup.",
            "examples": [
              "Front view"
            ]
          },
          "is_async": {
            "type": "boolean",
            "description": "If true, the mockup is QUEUED and the call returns 202 immediately with a job_id (poll GET /api/v1/jobs/{job_id}, or receive a webhook if one is configured); result_url carries the new mockup_uuid on success. If false (default), the create runs synchronously and returns the mockup.",
            "default": false
          },
          "print_areas": {
            "anyOf": [
              {
                "items": {
                  "$ref": "#/components/schemas/PhotoMockupPrintAreaInput"
                },
                "type": "array",
                "maxItems": 8,
                "minItems": 1
              },
              {
                "type": "null"
              }
            ],
            "description": "Optional: 1-8 convex four-point printable areas in source-image pixels. When provided, these areas are used verbatim and automatic print-area detection is skipped."
          }
        },
        "additionalProperties": false,
        "type": "object",
        "title": "PhotoMockupCreateRequest",
        "description": "Create a reusable photo mockup from one source image.",
        "example": {
          "name": "Front view",
          "source_url": "https://example.com/product-photo.jpg"
        }
      },
      "PhotoMockupDeleteData": {
        "properties": {
          "deleted": {
            "type": "string",
            "description": "UUID of the deleted mockup."
          }
        },
        "type": "object",
        "required": [
          "deleted"
        ],
        "title": "PhotoMockupDeleteData"
      },
      "PhotoMockupDeleteResponse": {
        "properties": {
          "data": {
            "$ref": "#/components/schemas/PhotoMockupDeleteData",
            "description": "Which mockup was deleted."
          },
          "success": {
            "type": "boolean",
            "const": true,
            "description": "Always true on a successful response.",
            "default": true
          }
        },
        "type": "object",
        "required": [
          "data"
        ],
        "title": "PhotoMockupDeleteResponse",
        "example": {
          "data": {
            "deleted": "893ea326-278b-480b-b130-87dd6aee06dc"
          },
          "success": true
        }
      },
      "PhotoMockupDetail": {
        "properties": {
          "mockup_id": {
            "type": "string",
            "description": "Unique identifier for the mockup.",
            "examples": [
              "893ea326-278b-480b-b130-87dd6aee06dc"
            ]
          },
          "name": {
            "type": "string",
            "description": "Display name of the mockup.",
            "examples": [
              "Front view"
            ]
          },
          "status": {
            "type": "string",
            "description": "Preparation state of the mockup: draft, processing, ready or error.",
            "examples": [
              "ready"
            ]
          },
          "customizable": {
            "type": "boolean",
            "description": "Whether the mockup is ready to accept artwork."
          },
          "thumbnail_url": {
            "anyOf": [
              {
                "type": "string"
              },
              {
                "type": "null"
              }
            ],
            "description": "URL of the mockup's thumbnail image."
          },
          "source_width": {
            "anyOf": [
              {
                "type": "integer"
              },
              {
                "type": "null"
              }
            ],
            "description": "Width of the source image in pixels.",
            "examples": [
              2048
            ]
          },
          "source_height": {
            "anyOf": [
              {
                "type": "integer"
              },
              {
                "type": "null"
              }
            ],
            "description": "Height of the source image in pixels.",
            "examples": [
              2048
            ]
          },
          "quads": {
            "items": {
              "$ref": "#/components/schemas/PhotoMockupPrintArea"
            },
            "type": "array",
            "description": "Printable areas saved on this mockup."
          },
          "surfaces": {
            "items": {
              "$ref": "#/components/schemas/PhotoMockupSurface"
            },
            "type": "array",
            "description": "Printable product surfaces in the photo, each addressable as a render target."
          },
          "version": {
            "type": "integer",
            "description": "Version of this mockup's saved definition.",
            "default": 1
          },
          "created_at": {
            "type": "string",
            "format": "date-time",
            "description": "When the mockup was created.",
            "examples": [
              "2026-09-18T10:24:31.482913Z"
            ]
          },
          "updated_at": {
            "type": "string",
            "format": "date-time",
            "description": "When the mockup was last updated.",
            "examples": [
              "2026-09-18T10:41:07.118204Z"
            ]
          }
        },
        "type": "object",
        "required": [
          "mockup_id",
          "name",
          "status",
          "customizable",
          "created_at",
          "updated_at"
        ],
        "title": "PhotoMockupDetail"
      },
      "PhotoMockupDetailResponse": {
        "properties": {
          "data": {
            "$ref": "#/components/schemas/PhotoMockupDetail",
            "description": "The mockup, its printable areas and its product surfaces."
          },
          "success": {
            "type": "boolean",
            "const": true,
            "description": "Always true on a successful response.",
            "default": true
          }
        },
        "type": "object",
        "required": [
          "data"
        ],
        "title": "PhotoMockupDetailResponse",
        "example": {
          "data": {
            "created_at": "2026-09-18T10:24:31.482913Z",
            "customizable": true,
            "mockup_id": "893ea326-278b-480b-b130-87dd6aee06dc",
            "name": "Front view",
            "quads": [
              {
                "name": "Front",
                "points": [
                  [
                    518.0,
                    646.0
                  ],
                  [
                    1534.0,
                    638.0
                  ],
                  [
                    1541.0,
                    1662.0
                  ],
                  [
                    511.0,
                    1670.0
                  ]
                ],
                "print_area_id": "19be48d4-c810-4420-86e3-7ec2a4d85571",
                "sort_order": 0
              }
            ],
            "source_height": 2048,
            "source_width": 2048,
            "status": "ready",
            "surfaces": [
              {
                "bbox": {
                  "height": 1552.0,
                  "width": 1244.0,
                  "x": 402.0,
                  "y": 286.0
                },
                "points": [
                  [
                    402.0,
                    318.0
                  ],
                  [
                    724.0,
                    286.0
                  ],
                  [
                    1324.0,
                    286.0
                  ],
                  [
                    1646.0,
                    318.0
                  ],
                  [
                    1646.0,
                    742.0
                  ],
                  [
                    1452.0,
                    806.0
                  ],
                  [
                    1452.0,
                    1838.0
                  ],
                  [
                    596.0,
                    1838.0
                  ],
                  [
                    596.0,
                    806.0
                  ],
                  [
                    402.0,
                    742.0
                  ]
                ],
                "surface_uuid": "733ee99a-f41f-4b9b-bf33-2ffa489f96db"
              }
            ],
            "updated_at": "2026-09-18T10:41:07.118204Z",
            "version": 1,
            "thumbnail_url": null
          },
          "success": true
        }
      },
      "PhotoMockupExportOptions": {
        "properties": {
          "image_format": {
            "type": "string",
            "enum": [
              "png",
              "jpg",
              "webp"
            ],
            "description": "Output format: 'webp' (30-70% smaller, recommended), 'png' (lossless), 'jpg' (smallest, no transparency)",
            "default": "webp"
          },
          "image_size": {
            "type": "integer",
            "maximum": 10000.0,
            "minimum": 100.0,
            "description": "Length of the output's longer side in pixels (100-10000); the other side follows the product photo's proportions. Renders on an account in trial are capped at 1024: a larger image_size is rejected with error_code OUTPUT_RESOLUTION_LIMIT (HTTP 402) and is never silently downscaled. Add a payment method to render at full size.",
            "default": 2048
          },
          "quality": {
            "type": "integer",
            "maximum": 100.0,
            "minimum": 1.0,
            "description": "Compression quality for JPG/WebP (1-100). Ignored for PNG (always lossless). Default: 90.",
            "default": 90
          },
          "dpi": {
            "anyOf": [
              {
                "type": "integer",
                "maximum": 2400.0,
                "minimum": 72.0
              },
              {
                "type": "null"
              }
            ],
            "description": "Resolution tag stamped into the output file metadata (JPG/WebP via Exif XResolution, PNG via pHYs), e.g. 300 for print. This is metadata only: it does NOT change the pixels. Pixel dimensions are controlled by image_size: set image_size = print_size_inches * dpi for a true print-ready file (e.g. 12 in * 300 = 3600 px). Range 72-2400. Default: null (opt-in). Omitting it does not leave the file untagged: the encoder writes a default ~25.4 DPI (1 px/mm) tag. All three formats carry the tag, but for maximum print-tool compatibility prefer jpg or png, because WebP stores resolution in Exif and not every viewer surfaces it.",
            "examples": [
              300
            ]
          }
        },
        "type": "object",
        "title": "PhotoMockupExportOptions",
        "description": "Format, size and quality of a photo mockup render.",
        "example": {
          "image_format": "webp",
          "image_size": 2048,
          "quality": 95
        }
      },
      "PhotoMockupList": {
        "properties": {
          "data": {
            "items": {
              "$ref": "#/components/schemas/PhotoMockup"
            },
            "type": "array",
            "description": "The mockups on this page, newest first."
          },
          "total": {
            "type": "integer",
            "description": "Total number of mockups matching the query."
          },
          "limit": {
            "type": "integer",
            "description": "Results per page."
          },
          "offset": {
            "type": "integer",
            "description": "Number of mockups skipped before this page."
          },
          "success": {
            "type": "boolean",
            "const": true,
            "description": "Always true on a successful response.",
            "default": true
          }
        },
        "type": "object",
        "required": [
          "data",
          "total",
          "limit",
          "offset"
        ],
        "title": "PhotoMockupList",
        "example": {
          "data": [
            {
              "created_at": "2026-09-18T10:24:31.482913Z",
              "customizable": true,
              "mockup_id": "893ea326-278b-480b-b130-87dd6aee06dc",
              "name": "Front view",
              "print_areas": [
                {
                  "name": "Front",
                  "points": [
                    [
                      518.0,
                      646.0
                    ],
                    [
                      1534.0,
                      638.0
                    ],
                    [
                      1541.0,
                      1662.0
                    ],
                    [
                      511.0,
                      1670.0
                    ]
                  ],
                  "print_area_id": "19be48d4-c810-4420-86e3-7ec2a4d85571",
                  "sort_order": 0
                }
              ],
              "source_height": 2048,
              "source_width": 2048,
              "status": "ready",
              "updated_at": "2026-09-18T10:41:07.118204Z",
              "version": 1,
              "thumbnail_url": null
            },
            {
              "created_at": "2026-09-16T08:12:55.301764Z",
              "customizable": true,
              "mockup_id": "5c74b1e0-9f38-4a26-b0d5-6e2a83c94f17",
              "name": "Ceramic mug",
              "print_areas": [],
              "source_height": 1600,
              "source_width": 1600,
              "status": "ready",
              "updated_at": "2026-09-16T08:13:42.669102Z",
              "version": 1,
              "thumbnail_url": null
            }
          ],
          "limit": 20,
          "offset": 0,
          "success": true,
          "total": 2
        }
      },
      "PhotoMockupPlacement": {
        "properties": {
          "position": {
            "type": "string",
            "enum": [
              "center",
              "top_left",
              "top_center",
              "top_right",
              "center_left",
              "center_right",
              "left_center",
              "right_center",
              "bottom_left",
              "bottom_center",
              "bottom_right"
            ],
            "description": "Predefined position within print area",
            "default": "center"
          },
          "coverage": {
            "anyOf": [
              {
                "type": "integer",
                "maximum": 100.0,
                "minimum": 10.0
              },
              {
                "type": "null"
              }
            ],
            "description": "How much of the product surface the artwork spans, 10 to 100. Spans the whole surface by default. Belongs to a surface_uuid target, and cannot be combined with an explicit width and height."
          },
          "fit": {
            "anyOf": [
              {
                "type": "string",
                "enum": [
                  "fill",
                  "fit",
                  "crop"
                ]
              },
              {
                "type": "null"
              }
            ],
            "description": "How the artwork meets the print area. 'fit' scales it until it fits inside and keeps its proportions, which is the default and can leave empty space. 'fill' stretches it to the edges and does not keep proportions. 'crop' covers the area and cuts the overflow, keeping proportions. 'contain' and 'cover' are the older names for 'fit' and 'crop' and are still accepted. Always targets the whole print area. Belongs to a uuid target, and cannot be combined with an explicit width and height."
          },
          "offset_x": {
            "type": "number",
            "description": "Horizontal offset in print-area pixels, measured from the anchor that 'position' picks, positive right. With the default position of 'center' that anchor is the middle of the print area.",
            "default": 0
          },
          "offset_y": {
            "type": "number",
            "description": "Vertical offset in print-area pixels, measured from the anchor that 'position' picks, positive down. With the default position of 'center' that anchor is the middle of the print area.",
            "default": 0
          },
          "width": {
            "anyOf": [
              {
                "type": "number",
                "maximum": 30000.0,
                "minimum": 1.0
              },
              {
                "type": "null"
              }
            ],
            "description": "Artwork width in target pixels. Must be sent together with 'height'. An exact box belongs to either kind of target: send it instead of 'fit' on a print area, or instead of 'coverage' on a surface. Width and height are independent, so any aspect ratio is allowed."
          },
          "height": {
            "anyOf": [
              {
                "type": "number",
                "maximum": 30000.0,
                "minimum": 1.0
              },
              {
                "type": "null"
              }
            ],
            "description": "Artwork height in target pixels. Must be sent together with 'width'. An exact box belongs to either kind of target: send it instead of 'fit' on a print area, or instead of 'coverage' on a surface. Width and height are independent, so any aspect ratio is allowed."
          },
          "rotation": {
            "type": "number",
            "maximum": 360.0,
            "minimum": -360.0,
            "description": "Rotation in degrees (clockwise positive)",
            "default": 0
          }
        },
        "additionalProperties": false,
        "type": "object",
        "title": "PhotoMockupPlacement",
        "description": "Where the artwork sits on the render target, and how big it is.\n\nSizing has exactly one spelling per target. On a product surface that is\ncoverage: how much of the surface the artwork spans. On a print area it is\neither fit, or an explicit width and height in print-area pixels; the two\naxes are independent, so stretching on one axis only is a supported\nplacement rather than an error, which is what makes this path as free as\nthe PSD path.\n\nEvery option has exactly one spelling: offset_x, offset_y and rotation.\nA second accepted spelling for the same option would let two callers write\nthe same placement two ways and force a precedence rule to break the tie,\nso unrecognised keys are rejected rather than translated.\n\nEvery pixel length here is a print-area pixel: the frame is the bounding\nbox of the print area's own four corner points, in the pixels of the\nproduct photo the mockup was built from. It is not a fraction of anything,\nand image_size does not change it. The artwork is cut to the print area\nitself, its own four-cornered outline and its mask, not to that bounding box.\n\nrotation is applied before the artwork is positioned, and a rotated artwork\noccupies its rotated bounding box: a 100x50 box sent with rotation 45 lands\nas a 106x106 footprint. width and height describe the box before rotation."
      },
      "PhotoMockupPrintArea": {
        "properties": {
          "print_area_id": {
            "type": "string",
            "description": "Unique identifier for the print area.",
            "examples": [
              "19be48d4-c810-4420-86e3-7ec2a4d85571"
            ]
          },
          "points": {
            "anyOf": [
              {
                "items": {
                  "items": {
                    "type": "number"
                  },
                  "type": "array"
                },
                "type": "array"
              },
              {
                "type": "null"
              }
            ],
            "description": "The area's four [x, y] corner points in source image pixels.",
            "examples": [
              [
                [
                  512,
                  640
                ],
                [
                  1536,
                  640
                ],
                [
                  1536,
                  1664
                ],
                [
                  512,
                  1664
                ]
              ]
            ]
          },
          "name": {
            "anyOf": [
              {
                "type": "string"
              },
              {
                "type": "null"
              }
            ],
            "description": "Label for the print area, such as 'Front'.",
            "examples": [
              "Front"
            ]
          },
          "sort_order": {
            "type": "integer",
            "description": "Position of this print area in the mockup's own order, starting at 0.",
            "default": 0
          }
        },
        "type": "object",
        "required": [
          "print_area_id"
        ],
        "title": "PhotoMockupPrintArea"
      },
      "PhotoMockupPrintAreaInput": {
        "properties": {
          "points": {
            "items": {
              "items": {
                "type": "number"
              },
              "type": "array"
            },
            "type": "array",
            "maxItems": 4,
            "minItems": 4,
            "description": "Four [x, y] points in image coordinates."
          },
          "name": {
            "anyOf": [
              {
                "type": "string",
                "maxLength": 120
              },
              {
                "type": "null"
              }
            ],
            "description": "Optional print-area label, e.g. \"Front\" or \"Back\"."
          }
        },
        "additionalProperties": false,
        "type": "object",
        "required": [
          "points"
        ],
        "title": "PhotoMockupPrintAreaInput",
        "description": "Four image coordinates defining one printable area."
      },
      "PhotoMockupPrintAreaRender": {
        "properties": {
          "uuid": {
            "anyOf": [
              {
                "type": "string",
                "pattern": "^[0-9a-f]{8}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{12}$"
              },
              {
                "type": "null"
              }
            ],
            "description": "UUID of a saved print area, a bounded zone drawn on a product.",
            "examples": [
              "19be48d4-c810-4420-86e3-7ec2a4d85571"
            ]
          },
          "surface_uuid": {
            "anyOf": [
              {
                "type": "string",
                "pattern": "^[0-9a-f]{8}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{12}$"
              },
              {
                "type": "null"
              }
            ],
            "description": "UUID of a printable product surface. A product carrying saved print areas still has one, and it is a separate render target from them.",
            "examples": [
              "733ee99a-f41f-4b9b-bf33-2ffa489f96db"
            ]
          },
          "base64": {
            "anyOf": [
              {
                "type": "string"
              },
              {
                "type": "null"
              }
            ],
            "description": "Base64-encoded artwork image."
          },
          "artwork_url": {
            "anyOf": [
              {
                "type": "string"
              },
              {
                "type": "null"
              }
            ],
            "description": "Artwork image URL",
            "examples": [
              "https://example.com/design.png"
            ]
          },
          "color": {
            "anyOf": [
              {
                "type": "string"
              },
              {
                "type": "null"
              }
            ],
            "description": "Solid color as a hex code (e.g., '#FF0000'), or the name of a colour saved on this mockup (e.g., 'blue jean'). Names match exactly and are set with PATCH /api/v1/photo-mockups/{uuid}.",
            "examples": [
              "#6A8296"
            ]
          },
          "adjustments": {
            "anyOf": [
              {
                "$ref": "#/components/schemas/PhotoMockupAdjustments"
              },
              {
                "type": "null"
              }
            ],
            "description": "Optional visual adjustments for the artwork."
          },
          "placement": {
            "anyOf": [
              {
                "$ref": "#/components/schemas/PhotoMockupPlacement"
              },
              {
                "type": "null"
              }
            ],
            "description": "Where the artwork sits and how big it is. position, offset_x, offset_y and rotation apply to either target. Sizing follows the target: coverage on a surface_uuid target, and either fit or an explicit width and height on a uuid target."
          },
          "flip_horizontal": {
            "type": "boolean",
            "description": "Flip artwork horizontally (left-right mirror)",
            "default": false
          },
          "flip_vertical": {
            "type": "boolean",
            "description": "Flip artwork vertically (top-bottom mirror)",
            "default": false
          },
          "remove_background": {
            "type": "boolean",
            "description": "Remove the image background before placing the artwork; the subject is isolated onto a clean transparent cutout. Adds 25 credits per artwork to the render cost.",
            "default": false
          }
        },
        "additionalProperties": false,
        "type": "object",
        "title": "PhotoMockupPrintAreaRender",
        "description": "Per-print-area artwork configuration for a photo mockup render.\nMirrors SmartObjectInput pattern from PSD render endpoint."
      },
      "PhotoMockupPrintAreasUpdate": {
        "properties": {
          "print_areas": {
            "items": {
              "$ref": "#/components/schemas/PhotoMockupPrintAreaInput"
            },
            "type": "array",
            "maxItems": 8,
            "minItems": 0,
            "description": "Up to eight printable areas, saved row by row from the top and left to right inside each row, whatever the array order. An empty array saves the mockup without bounded placement zones."
          }
        },
        "additionalProperties": false,
        "type": "object",
        "required": [
          "print_areas"
        ],
        "title": "PhotoMockupPrintAreasUpdate",
        "description": "Replace a mockup's printable areas.",
        "example": {
          "print_areas": [
            {
              "points": [
                [
                  200,
                  150
                ],
                [
                  600,
                  150
                ],
                [
                  620,
                  550
                ],
                [
                  180,
                  550
                ]
              ]
            }
          ]
        }
      },
      "PhotoMockupPrintAreasUpdateData": {
        "properties": {
          "mockup_id": {
            "type": "string",
            "description": "Unique identifier of the mockup whose print areas were replaced.",
            "examples": [
              "893ea326-278b-480b-b130-87dd6aee06dc"
            ]
          },
          "print_areas": {
            "items": {
              "$ref": "#/components/schemas/PhotoMockupPrintArea"
            },
            "type": "array",
            "description": "The mockup's printable areas after the replacement, in the order they were saved."
          }
        },
        "type": "object",
        "required": [
          "mockup_id"
        ],
        "title": "PhotoMockupPrintAreasUpdateData"
      },
      "PhotoMockupPrintAreasUpdateResponse": {
        "properties": {
          "data": {
            "$ref": "#/components/schemas/PhotoMockupPrintAreasUpdateData",
            "description": "The mockup and the printable areas it carries after the replacement."
          },
          "success": {
            "type": "boolean",
            "const": true,
            "description": "Always true on a successful response.",
            "default": true
          }
        },
        "type": "object",
        "required": [
          "data"
        ],
        "title": "PhotoMockupPrintAreasUpdateResponse",
        "example": {
          "data": {
            "mockup_id": "893ea326-278b-480b-b130-87dd6aee06dc",
            "print_areas": [
              {
                "name": "Front",
                "points": [
                  [
                    518.0,
                    646.0
                  ],
                  [
                    1534.0,
                    638.0
                  ],
                  [
                    1541.0,
                    1662.0
                  ],
                  [
                    511.0,
                    1670.0
                  ]
                ],
                "print_area_id": "19be48d4-c810-4420-86e3-7ec2a4d85571",
                "sort_order": 0
              },
              {
                "points": [
                  [
                    742.0,
                    1742.0
                  ],
                  [
                    1312.0,
                    1735.0
                  ],
                  [
                    1318.0,
                    2010.0
                  ],
                  [
                    736.0,
                    2017.0
                  ]
                ],
                "print_area_id": "a0c7d215-93f8-4f0b-9a64-58b1e2c7d430",
                "sort_order": 1,
                "name": null
              }
            ]
          },
          "success": true
        }
      },
      "PhotoMockupPrintFile": {
        "properties": {
          "export_path": {
            "type": "string",
            "description": "Public URL of the rendered output"
          },
          "duration_ms": {
            "anyOf": [
              {
                "type": "integer"
              },
              {
                "type": "null"
              }
            ],
            "description": "Render duration in milliseconds"
          },
          "export_format": {
            "anyOf": [
              {
                "type": "string"
              },
              {
                "type": "null"
              }
            ],
            "description": "Output format used (png, jpg, webp)"
          }
        },
        "type": "object",
        "required": [
          "export_path"
        ],
        "title": "PhotoMockupPrintFile",
        "description": "Photo mockup render output file."
      },
      "PhotoMockupRender": {
        "properties": {
          "print_areas": {
            "items": {
              "$ref": "#/components/schemas/PhotoMockupPrintAreaRender"
            },
            "type": "array",
            "maxItems": 8,
            "minItems": 1,
            "description": "Artwork configuration per render target. Use uuid for a saved print area, and surface_uuid for a whole product surface. A product can be rendered either way, and saving a print area on it does not take its surface away."
          },
          "export_options": {
            "$ref": "#/components/schemas/PhotoMockupExportOptions",
            "description": "Export configuration for format, size and quality. Every field has a default, so the whole object is optional."
          },
          "is_async": {
            "type": "boolean",
            "description": "If true, the render is QUEUED and the call returns 202 immediately with a job_id (poll GET /api/v1/jobs/{job_id}, or receive a webhook if one is configured); result_url carries the rendered image URL on success. If false (default), the render runs synchronously and returns the result.",
            "default": false
          }
        },
        "additionalProperties": false,
        "type": "object",
        "required": [
          "print_areas"
        ],
        "title": "PhotoMockupRender",
        "description": "Body for POST /api/v1/photo-mockups/{mockup_id}/render.\n\nThe mockup UUID is taken from the path; the body carries only per-print-area\nartwork configuration and export options.",
        "example": {
          "export_options": {
            "image_format": "webp",
            "image_size": 1920,
            "quality": 95
          },
          "print_areas": [
            {
              "adjustments": {
                "blend_mode": "multiply",
                "opacity": 90
              },
              "artwork_url": "https://example.com/design.png",
              "placement": {
                "fit": "fit",
                "position": "center"
              },
              "uuid": "223e4567-e89b-12d3-a456-426614174001"
            }
          ]
        }
      },
      "PhotoMockupRenderResponse": {
        "properties": {
          "data": {
            "$ref": "#/components/schemas/PhotoMockupRenderResult",
            "description": "Rendered output files"
          },
          "success": {
            "type": "boolean",
            "description": "Success status",
            "default": true
          }
        },
        "type": "object",
        "required": [
          "data"
        ],
        "title": "PhotoMockupRenderResponse",
        "description": "The finished photo-mockup render and where to fetch it.",
        "example": {
          "data": {
            "print_files": [
              {
                "duration_ms": 1840,
                "export_format": "webp",
                "export_path": "https://cdn.sudomock.com/mockup-assets/renders/2d/893ea326-278b-480b-b130-87dd6aee06dc/ac0a5f31-6d2e-4d1b-9c4c-1e7f2b6a5d08.webp"
              }
            ],
            "render_uuid": "ac0a5f31-6d2e-4d1b-9c4c-1e7f2b6a5d08"
          },
          "success": true
        }
      },
      "PhotoMockupRenderResult": {
        "properties": {
          "print_files": {
            "items": {
              "$ref": "#/components/schemas/PhotoMockupPrintFile"
            },
            "type": "array",
            "description": "List of rendered outputs"
          },
          "render_uuid": {
            "anyOf": [
              {
                "type": "string"
              },
              {
                "type": "null"
              }
            ],
            "description": "Identifier for this render."
          }
        },
        "type": "object",
        "required": [
          "print_files"
        ],
        "title": "PhotoMockupRenderResult",
        "description": "Data payload in a photo mockup render response."
      },
      "PhotoMockupSurface": {
        "properties": {
          "surface_uuid": {
            "type": "string",
            "description": "Unique identifier for the printable product surface."
          },
          "points": {
            "anyOf": [
              {
                "items": {
                  "items": {
                    "type": "number"
                  },
                  "type": "array"
                },
                "type": "array"
              },
              {
                "type": "null"
              }
            ],
            "description": "Outline of the surface as [x, y] points in source image pixels."
          },
          "bbox": {
            "anyOf": [
              {
                "additionalProperties": {
                  "type": "number"
                },
                "type": "object"
              },
              {
                "type": "null"
              }
            ],
            "description": "Box enclosing the surface, with x, y, width and height in source pixels."
          }
        },
        "type": "object",
        "required": [
          "surface_uuid"
        ],
        "title": "PhotoMockupSurface",
        "description": "One printable product in the photo, addressed by its own id.\n\nSend ``surface_uuid`` as a render target to print across the whole product."
      },
      "PhotoMockupUpdateData": {
        "properties": {
          "uuid": {
            "type": "string",
            "description": "Unique identifier for the mockup."
          },
          "name": {
            "anyOf": [
              {
                "type": "string"
              },
              {
                "type": "null"
              }
            ],
            "description": "Display name of the mockup after the update."
          },
          "colors": {
            "items": {
              "$ref": "#/components/schemas/MockupColour"
            },
            "type": "array",
            "description": "The colours this mockup answers to by name after the update."
          }
        },
        "type": "object",
        "required": [
          "uuid"
        ],
        "title": "PhotoMockupUpdateData"
      },
      "PhotoMockupUpdateResponse": {
        "properties": {
          "data": {
            "$ref": "#/components/schemas/PhotoMockupUpdateData",
            "description": "The mockup as it stands after the update."
          },
          "success": {
            "type": "boolean",
            "const": true,
            "description": "Always true on a successful response.",
            "default": true
          }
        },
        "type": "object",
        "required": [
          "data"
        ],
        "title": "PhotoMockupUpdateResponse",
        "example": {
          "data": {
            "colors": [
              {
                "hex": "#6A8296",
                "label": "blue jean"
              },
              {
                "hex": "#E4DED3",
                "label": "bone"
              }
            ],
            "name": "Front view",
            "uuid": "893ea326-278b-480b-b130-87dd6aee06dc"
          },
          "success": true
        }
      },
      "Position": {
        "properties": {
          "x": {
            "type": "integer",
            "description": "Left edge in pixels, relative to the containing frame (top-left origin)."
          },
          "y": {
            "type": "integer",
            "description": "Top edge in pixels, relative to the containing frame (top-left origin)."
          },
          "width": {
            "type": "integer",
            "description": "Width in pixels"
          },
          "height": {
            "type": "integer",
            "description": "Height in pixels"
          }
        },
        "type": "object",
        "required": [
          "x",
          "y",
          "width",
          "height"
        ],
        "title": "Position",
        "description": "Bounding box in pixels, relative to the frame that contains it."
      },
      "PrintAreaPreset": {
        "properties": {
          "uuid": {
            "type": "string",
            "description": "Unique identifier for the preset",
            "examples": [
              "d07f5b18-2c94-4e83-a6b1-95f3c8e27a40"
            ]
          },
          "name": {
            "type": "string",
            "description": "Name of the preset (e.g., 'Default')",
            "examples": [
              "Default"
            ]
          },
          "thumbnails": {
            "items": {
              "$ref": "#/components/schemas/ThumbnailSize"
            },
            "type": "array",
            "description": "Thumbnail previews of the preset"
          },
          "size": {
            "$ref": "#/components/schemas/Size",
            "description": "Size dimensions of the print area"
          },
          "position": {
            "$ref": "#/components/schemas/Position",
            "description": "Position relative to smart object (x, y, width, height)"
          }
        },
        "type": "object",
        "required": [
          "uuid",
          "name",
          "size",
          "position"
        ],
        "title": "PrintAreaPreset",
        "description": "Print area preset configuration for smart object"
      },
      "PrintFile": {
        "properties": {
          "export_path": {
            "type": "string",
            "description": "Path to the rendered output file",
            "examples": [
              "https://cdn.sudomock.com/mockup-assets/renders/c315f78f-d2c7-4541-b240-a9372842de94/render_5ec56e42-4afe-4267-bf21-6f8f586d16bb.webp"
            ]
          },
          "smart_object_uuid": {
            "type": "string",
            "description": "UUID of the first Smart Object in the request; an empty string for a render without Smart Objects, including text-only and group-only renders.",
            "examples": [
              "6bdc8897-3eee-4356-b717-8bc3c9249946"
            ]
          },
          "render_uuid": {
            "anyOf": [
              {
                "type": "string"
              },
              {
                "type": "null"
              }
            ],
            "description": "The render's transaction id (also the async job uuid). Returned so storefront/Studio fulfillment flows can correlate the render; null on legacy paths.",
            "examples": [
              "5ec56e42-4afe-4267-bf21-6f8f586d16bb"
            ]
          }
        },
        "type": "object",
        "required": [
          "export_path",
          "smart_object_uuid"
        ],
        "title": "PrintFile",
        "description": "Individual print file in render response",
        "example": {
          "export_path": "https://cdn.sudomock.com/mockup-assets/renders/c315f78f-d2c7-4541-b240-a9372842de94/render_8f2c1d4e.webp",
          "smart_object_uuid": "223e4567-e89b-12d3-a456-426614174001"
        }
      },
      "PublicTwoDAdjustments": {
        "properties": {
          "brightness": {
            "type": "integer",
            "maximum": 150.0,
            "minimum": -150.0,
            "description": "Brightness applied to the artwork, from -150 to 150, where 0 keeps it unchanged.",
            "default": 0
          },
          "contrast": {
            "type": "integer",
            "maximum": 100.0,
            "minimum": -100.0,
            "description": "Contrast applied to the artwork, from -100 to 100, where 0 keeps it unchanged.",
            "default": 0
          },
          "opacity": {
            "type": "integer",
            "maximum": 100.0,
            "minimum": 0.0,
            "description": "How opaque the artwork is, from 0 for fully transparent to 100 for opaque.",
            "default": 100
          },
          "saturation": {
            "type": "integer",
            "maximum": 100.0,
            "minimum": -100.0,
            "description": "Saturation applied to the artwork, from -100 for grayscale to 100 for fully saturated.",
            "default": 0
          },
          "vibrance": {
            "type": "integer",
            "maximum": 100.0,
            "minimum": -100.0,
            "description": "Saturation that affects muted colors more than already vivid ones, from -100 to 100.",
            "default": 0
          },
          "blur": {
            "type": "integer",
            "maximum": 100.0,
            "minimum": 0.0,
            "description": "Softens the artwork, from 0 for sharp to 100 for the strongest blur.",
            "default": 0
          },
          "blend_mode": {
            "type": "string",
            "enum": [
              "multiply",
              "normal",
              "screen",
              "lighten",
              "soft_light",
              "overlay",
              "darken"
            ],
            "description": "How the artwork sits on the product surface. 'multiply' keeps the material texture visible and is the best choice on light fabric (default); 'normal' reproduces the artwork colors exactly, whatever the product color, and is the right choice when a brand color has to match the supplied file; 'screen' lightens the artwork against the surface, which is worth reaching for only when you want that lighter result, since the default already adapts to a dark garment; 'lighten' keeps the artwork only where it is brighter than the surface; 'soft_light' gives a subtle, low-contrast finish that follows the surface; 'overlay' deepens contrast so the artwork reads as part of the material; 'darken' keeps the artwork only where it is darker than the surface.",
            "default": "multiply"
          }
        },
        "additionalProperties": false,
        "type": "object",
        "title": "PublicTwoDAdjustments",
        "description": "Deprecated name for `PhotoMockupAdjustments`. Same shape, kept so a client generated from an earlier spec keeps the type name it already has.",
        "deprecated": true
      },
      "PublicTwoDMockupCreateAcceptedResponse": {
        "properties": {
          "job_id": {
            "type": "string",
            "description": "Identifier of the queued job, used to poll its status."
          },
          "kind": {
            "type": "string",
            "enum": [
              "2d_create",
              "photo_mockup_create"
            ],
            "description": "The kind of work accepted, which is always a photo mockup create."
          },
          "status": {
            "type": "string",
            "enum": [
              "queued",
              "dispatched",
              "running",
              "succeeded",
              "failed",
              "cancelled"
            ],
            "description": "State of the job when this response was returned."
          },
          "status_url": {
            "type": "string",
            "description": "Path to poll for this job's status."
          }
        },
        "type": "object",
        "required": [
          "job_id",
          "kind",
          "status",
          "status_url"
        ],
        "title": "PublicTwoDMockupCreateAcceptedResponse",
        "description": "Deprecated name for `PhotoMockupCreateAcceptedResponse`. Same shape, kept so a client generated from an earlier spec keeps the type name it already has.",
        "example": {
          "job_id": "5f1c0b2a-7d43-4e9a-8c16-0b5d3f7a2e94",
          "kind": "photo_mockup_create",
          "status": "queued",
          "status_url": "/api/v1/jobs/5f1c0b2a-7d43-4e9a-8c16-0b5d3f7a2e94"
        },
        "deprecated": true
      },
      "PublicTwoDMockupDeleteData": {
        "properties": {
          "deleted": {
            "type": "string",
            "description": "UUID of the deleted mockup."
          }
        },
        "type": "object",
        "required": [
          "deleted"
        ],
        "title": "PublicTwoDMockupDeleteData",
        "deprecated": true,
        "description": "Deprecated name for `PhotoMockupDeleteData`. Same shape, kept so a client generated from an earlier spec keeps the type name it already has."
      },
      "PublicTwoDMockupDeleteResponse": {
        "properties": {
          "data": {
            "$ref": "#/components/schemas/PhotoMockupDeleteData",
            "description": "Which mockup was deleted."
          },
          "success": {
            "type": "boolean",
            "const": true,
            "description": "Always true on a successful response.",
            "default": true
          }
        },
        "type": "object",
        "required": [
          "data"
        ],
        "title": "PublicTwoDMockupDeleteResponse",
        "example": {
          "data": {
            "deleted": "893ea326-278b-480b-b130-87dd6aee06dc"
          },
          "success": true
        },
        "deprecated": true,
        "description": "Deprecated name for `PhotoMockupDeleteResponse`. Same shape, kept so a client generated from an earlier spec keeps the type name it already has."
      },
      "PublicTwoDMockupDetail": {
        "properties": {
          "mockup_id": {
            "type": "string",
            "description": "Unique identifier for the mockup.",
            "examples": [
              "893ea326-278b-480b-b130-87dd6aee06dc"
            ]
          },
          "name": {
            "type": "string",
            "description": "Display name of the mockup.",
            "examples": [
              "Front view"
            ]
          },
          "status": {
            "type": "string",
            "description": "Preparation state of the mockup: draft, processing, ready or error.",
            "examples": [
              "ready"
            ]
          },
          "customizable": {
            "type": "boolean",
            "description": "Whether the mockup is ready to accept artwork."
          },
          "thumbnail_url": {
            "anyOf": [
              {
                "type": "string"
              },
              {
                "type": "null"
              }
            ],
            "description": "URL of the mockup's thumbnail image."
          },
          "source_width": {
            "anyOf": [
              {
                "type": "integer"
              },
              {
                "type": "null"
              }
            ],
            "description": "Width of the source image in pixels.",
            "examples": [
              2048
            ]
          },
          "source_height": {
            "anyOf": [
              {
                "type": "integer"
              },
              {
                "type": "null"
              }
            ],
            "description": "Height of the source image in pixels.",
            "examples": [
              2048
            ]
          },
          "quads": {
            "items": {
              "$ref": "#/components/schemas/PhotoMockupPrintArea"
            },
            "type": "array",
            "description": "Printable areas saved on this mockup."
          },
          "surfaces": {
            "items": {
              "$ref": "#/components/schemas/PhotoMockupSurface"
            },
            "type": "array",
            "description": "Printable product surfaces in the photo, each addressable as a render target."
          },
          "version": {
            "type": "integer",
            "description": "Version of this mockup's saved definition.",
            "default": 1
          },
          "created_at": {
            "type": "string",
            "format": "date-time",
            "description": "When the mockup was created.",
            "examples": [
              "2026-09-18T10:24:31.482913Z"
            ]
          },
          "updated_at": {
            "type": "string",
            "format": "date-time",
            "description": "When the mockup was last updated.",
            "examples": [
              "2026-09-18T10:41:07.118204Z"
            ]
          }
        },
        "type": "object",
        "required": [
          "mockup_id",
          "name",
          "status",
          "customizable",
          "created_at",
          "updated_at"
        ],
        "title": "PublicTwoDMockupDetail",
        "deprecated": true,
        "description": "Deprecated name for `PhotoMockupDetail`. Same shape, kept so a client generated from an earlier spec keeps the type name it already has."
      },
      "PublicTwoDMockupDetailResponse": {
        "properties": {
          "data": {
            "$ref": "#/components/schemas/PhotoMockupDetail",
            "description": "The mockup, its printable areas and its product surfaces."
          },
          "success": {
            "type": "boolean",
            "const": true,
            "description": "Always true on a successful response.",
            "default": true
          }
        },
        "type": "object",
        "required": [
          "data"
        ],
        "title": "PublicTwoDMockupDetailResponse",
        "example": {
          "data": {
            "created_at": "2026-09-18T10:24:31.482913Z",
            "customizable": true,
            "mockup_id": "893ea326-278b-480b-b130-87dd6aee06dc",
            "name": "Front view",
            "quads": [
              {
                "name": "Front",
                "points": [
                  [
                    518.0,
                    646.0
                  ],
                  [
                    1534.0,
                    638.0
                  ],
                  [
                    1541.0,
                    1662.0
                  ],
                  [
                    511.0,
                    1670.0
                  ]
                ],
                "print_area_id": "19be48d4-c810-4420-86e3-7ec2a4d85571",
                "sort_order": 0
              }
            ],
            "source_height": 2048,
            "source_width": 2048,
            "status": "ready",
            "surfaces": [
              {
                "bbox": {
                  "height": 1552.0,
                  "width": 1244.0,
                  "x": 402.0,
                  "y": 286.0
                },
                "points": [
                  [
                    402.0,
                    318.0
                  ],
                  [
                    724.0,
                    286.0
                  ],
                  [
                    1324.0,
                    286.0
                  ],
                  [
                    1646.0,
                    318.0
                  ],
                  [
                    1646.0,
                    742.0
                  ],
                  [
                    1452.0,
                    806.0
                  ],
                  [
                    1452.0,
                    1838.0
                  ],
                  [
                    596.0,
                    1838.0
                  ],
                  [
                    596.0,
                    806.0
                  ],
                  [
                    402.0,
                    742.0
                  ]
                ],
                "surface_uuid": "733ee99a-f41f-4b9b-bf33-2ffa489f96db"
              }
            ],
            "updated_at": "2026-09-18T10:41:07.118204Z",
            "version": 1,
            "thumbnail_url": null
          },
          "success": true
        },
        "deprecated": true,
        "description": "Deprecated name for `PhotoMockupDetailResponse`. Same shape, kept so a client generated from an earlier spec keeps the type name it already has."
      },
      "PublicTwoDMockupListItem": {
        "properties": {
          "mockup_id": {
            "type": "string",
            "description": "Unique identifier for the mockup.",
            "examples": [
              "893ea326-278b-480b-b130-87dd6aee06dc"
            ]
          },
          "name": {
            "type": "string",
            "description": "Display name of the mockup.",
            "examples": [
              "Front view"
            ]
          },
          "status": {
            "type": "string",
            "description": "Preparation state of the mockup: draft, processing, ready or error.",
            "examples": [
              "ready"
            ]
          },
          "customizable": {
            "type": "boolean",
            "description": "Whether the mockup is ready to accept artwork."
          },
          "thumbnail_url": {
            "anyOf": [
              {
                "type": "string"
              },
              {
                "type": "null"
              }
            ],
            "description": "URL of the mockup's thumbnail image."
          },
          "source_width": {
            "anyOf": [
              {
                "type": "integer"
              },
              {
                "type": "null"
              }
            ],
            "description": "Width of the source image in pixels.",
            "examples": [
              2048
            ]
          },
          "source_height": {
            "anyOf": [
              {
                "type": "integer"
              },
              {
                "type": "null"
              }
            ],
            "description": "Height of the source image in pixels.",
            "examples": [
              2048
            ]
          },
          "print_areas": {
            "items": {
              "$ref": "#/components/schemas/PhotoMockupPrintArea"
            },
            "type": "array",
            "description": "Printable areas saved on this mockup."
          },
          "version": {
            "type": "integer",
            "description": "Version of this mockup's saved definition.",
            "default": 1
          },
          "created_at": {
            "type": "string",
            "format": "date-time",
            "description": "When the mockup was created.",
            "examples": [
              "2026-09-18T10:24:31.482913Z"
            ]
          },
          "updated_at": {
            "type": "string",
            "format": "date-time",
            "description": "When the mockup was last updated.",
            "examples": [
              "2026-09-18T10:41:07.118204Z"
            ]
          }
        },
        "type": "object",
        "required": [
          "mockup_id",
          "name",
          "status",
          "customizable",
          "created_at",
          "updated_at"
        ],
        "title": "PublicTwoDMockupListItem",
        "deprecated": true,
        "description": "Deprecated name for `PhotoMockup`. Same shape, kept so a client generated from an earlier spec keeps the type name it already has."
      },
      "PublicTwoDMockupListResponse": {
        "properties": {
          "data": {
            "items": {
              "$ref": "#/components/schemas/PhotoMockup"
            },
            "type": "array",
            "description": "The mockups on this page, newest first."
          },
          "total": {
            "type": "integer",
            "description": "Total number of mockups matching the query."
          },
          "limit": {
            "type": "integer",
            "description": "Results per page."
          },
          "offset": {
            "type": "integer",
            "description": "Number of mockups skipped before this page."
          },
          "success": {
            "type": "boolean",
            "const": true,
            "description": "Always true on a successful response.",
            "default": true
          }
        },
        "type": "object",
        "required": [
          "data",
          "total",
          "limit",
          "offset"
        ],
        "title": "PublicTwoDMockupListResponse",
        "example": {
          "data": [
            {
              "created_at": "2026-09-18T10:24:31.482913Z",
              "customizable": true,
              "mockup_id": "893ea326-278b-480b-b130-87dd6aee06dc",
              "name": "Front view",
              "print_areas": [
                {
                  "name": "Front",
                  "points": [
                    [
                      518.0,
                      646.0
                    ],
                    [
                      1534.0,
                      638.0
                    ],
                    [
                      1541.0,
                      1662.0
                    ],
                    [
                      511.0,
                      1670.0
                    ]
                  ],
                  "print_area_id": "19be48d4-c810-4420-86e3-7ec2a4d85571",
                  "sort_order": 0
                }
              ],
              "source_height": 2048,
              "source_width": 2048,
              "status": "ready",
              "updated_at": "2026-09-18T10:41:07.118204Z",
              "version": 1,
              "thumbnail_url": null
            },
            {
              "created_at": "2026-09-16T08:12:55.301764Z",
              "customizable": true,
              "mockup_id": "5c74b1e0-9f38-4a26-b0d5-6e2a83c94f17",
              "name": "Ceramic mug",
              "print_areas": [],
              "source_height": 1600,
              "source_width": 1600,
              "status": "ready",
              "updated_at": "2026-09-16T08:13:42.669102Z",
              "version": 1,
              "thumbnail_url": null
            }
          ],
          "limit": 20,
          "offset": 0,
          "success": true,
          "total": 2
        },
        "deprecated": true,
        "description": "Deprecated name for `PhotoMockupList`. Same shape, kept so a client generated from an earlier spec keeps the type name it already has."
      },
      "PublicTwoDPrintArea": {
        "properties": {
          "print_area_id": {
            "type": "string",
            "description": "Unique identifier for the print area.",
            "examples": [
              "19be48d4-c810-4420-86e3-7ec2a4d85571"
            ]
          },
          "points": {
            "anyOf": [
              {
                "items": {
                  "items": {
                    "type": "number"
                  },
                  "type": "array"
                },
                "type": "array"
              },
              {
                "type": "null"
              }
            ],
            "description": "The area's four [x, y] corner points in source image pixels.",
            "examples": [
              [
                [
                  512,
                  640
                ],
                [
                  1536,
                  640
                ],
                [
                  1536,
                  1664
                ],
                [
                  512,
                  1664
                ]
              ]
            ]
          },
          "name": {
            "anyOf": [
              {
                "type": "string"
              },
              {
                "type": "null"
              }
            ],
            "description": "Label for the print area, such as 'Front'.",
            "examples": [
              "Front"
            ]
          },
          "sort_order": {
            "type": "integer",
            "description": "Position of this print area in the mockup's own order, starting at 0.",
            "default": 0
          }
        },
        "type": "object",
        "required": [
          "print_area_id"
        ],
        "title": "PublicTwoDPrintArea",
        "deprecated": true,
        "description": "Deprecated name for `PhotoMockupPrintArea`. Same shape, kept so a client generated from an earlier spec keeps the type name it already has."
      },
      "PublicTwoDSurface": {
        "properties": {
          "surface_uuid": {
            "type": "string",
            "description": "Unique identifier for the printable product surface."
          },
          "points": {
            "anyOf": [
              {
                "items": {
                  "items": {
                    "type": "number"
                  },
                  "type": "array"
                },
                "type": "array"
              },
              {
                "type": "null"
              }
            ],
            "description": "Outline of the surface as [x, y] points in source image pixels."
          },
          "bbox": {
            "anyOf": [
              {
                "additionalProperties": {
                  "type": "number"
                },
                "type": "object"
              },
              {
                "type": "null"
              }
            ],
            "description": "Box enclosing the surface, with x, y, width and height in source pixels."
          }
        },
        "type": "object",
        "required": [
          "surface_uuid"
        ],
        "title": "PublicTwoDSurface",
        "description": "Deprecated name for `PhotoMockupSurface`. Same shape, kept so a client generated from an earlier spec keeps the type name it already has.",
        "deprecated": true
      },
      "RenderRequest": {
        "properties": {
          "mockup_uuid": {
            "type": "string",
            "pattern": "^[0-9a-f]{8}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{12}$",
            "description": "UUID of the mockup to render. Must be a valid UUID, for example c315f78f-d2c7-4541-b240-a9372842de94. Obtained from the POST /api/v1/psd/upload or GET /api/v1/psd-mockups response.",
            "examples": [
              "c315f78f-d2c7-4541-b240-a9372842de94"
            ]
          },
          "smart_objects": {
            "items": {
              "$ref": "#/components/schemas/SmartObjectInput"
            },
            "type": "array",
            "description": "List of smart objects with their assets. Required unless text_layers, group_layers or hidden_layers is provided."
          },
          "text_layers": {
            "anyOf": [
              {
                "items": {
                  "$ref": "#/components/schemas/TextLayerInput"
                },
                "type": "array",
                "maxItems": 50
              },
              {
                "type": "null"
              }
            ],
            "description": "Up to 50 text-layer overrides. Each entry targets a text-layer UUID and provides exactly one of text for a single-style layer or segments for a mixed-style layer. Omitted layers and styling fields keep their authored values."
          },
          "group_layers": {
            "anyOf": [
              {
                "items": {
                  "$ref": "#/components/schemas/GroupLayerInput"
                },
                "type": "array",
                "maxItems": 50
              },
              {
                "type": "null"
              }
            ],
            "description": "Group outline overrides. Each entry addresses a listed group by its own UUID; the change affects everything inside that group."
          },
          "hidden_layers": {
            "anyOf": [
              {
                "items": {
                  "type": "string",
                  "pattern": "^[0-9a-f]{8}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{12}$"
                },
                "type": "array",
                "maxItems": 50
              },
              {
                "type": "null"
              }
            ],
            "description": "Up to 50 layers to leave out of this render, each by the UUID that GET /api/v1/psd-mockups/{uuid}/layers lists for it, including the layers inside a smart object's contents. Hiding a group hides every layer inside it, and a layer clipped to a hidden layer is hidden with it, as in Photoshop. A layer hidden inside a smart object's contents is hidden in every copy of that smart object. A layer cannot be hidden and edited in the same request, and a smart object that receives an image cannot have layers inside it hidden. Omit to draw every layer the template shows.",
            "examples": [
              [
                "423e4567-e89b-12d3-a456-426614174003"
              ]
            ]
          },
          "export_options": {
            "$ref": "#/components/schemas/ExportOptions",
            "description": "Export configuration for format, size and quality. Every field has a default, so the whole object is optional."
          },
          "export_label": {
            "anyOf": [
              {
                "type": "string",
                "maxLength": 100
              },
              {
                "type": "null"
              }
            ],
            "description": "Optional label for export file naming (max 100 chars, alphanumeric + hyphen/underscore)",
            "examples": [
              "summer-tee-front"
            ]
          },
          "is_async": {
            "type": "boolean",
            "description": "If true, the render is QUEUED and the call returns 202 immediately with a job_id (poll GET /api/v1/jobs/{job_id}, or receive a webhook if one is configured). If false (default), the render runs synchronously and returns the result.",
            "default": false
          }
        },
        "type": "object",
        "required": [
          "mockup_uuid"
        ],
        "title": "RenderRequest",
        "description": "What to render: which mockup, what goes into it, and how to export it.",
        "example": {
          "export_options": {
            "image_format": "webp",
            "image_size": 1920,
            "quality": 95
          },
          "mockup_uuid": "123e4567-e89b-12d3-a456-426614174000",
          "smart_objects": [
            {
              "asset": {
                "fit": "fill",
                "position": {
                  "left": 100,
                  "top": 100
                },
                "rotate": 0,
                "size": {
                  "height": 600,
                  "width": 800
                },
                "url": "https://example.com/user-design.png"
              },
              "color": {
                "blending_mode": "multiply",
                "hex": "#FFFFFF"
              },
              "uuid": "223e4567-e89b-12d3-a456-426614174001"
            }
          ]
        }
      },
      "RenderResponse": {
        "properties": {
          "data": {
            "$ref": "#/components/schemas/RenderResponseData",
            "description": "Response data"
          },
          "success": {
            "type": "boolean",
            "description": "Success status",
            "default": true
          },
          "warnings": {
            "anyOf": [
              {
                "items": {
                  "$ref": "#/components/schemas/RenderWarning"
                },
                "type": "array"
              },
              {
                "type": "null"
              }
            ],
            "description": "Non-fatal advisories about this render (e.g. requested size above the mockup's native resolution). Omitted when none.",
            "examples": [
              [
                {
                  "code": "OUTPUT_EXCEEDS_MAX_RESOLUTION",
                  "message": "Requested 4096px is above this mockup's native 3000px. The result is enlarged and may look softer than its native resolution. For the sharpest output, request 3000px or less."
                }
              ]
            ]
          }
        },
        "type": "object",
        "required": [
          "data"
        ],
        "title": "RenderResponse",
        "description": "The finished render and where to fetch it.",
        "example": {
          "data": {
            "print_files": [
              {
                "export_path": "https://cdn.sudomock.com/mockup-assets/renders/c315f78f-d2c7-4541-b240-a9372842de94/render_8f2c1d4e.webp",
                "smart_object_uuid": "223e4567-e89b-12d3-a456-426614174001"
              }
            ]
          },
          "success": true
        }
      },
      "RenderResponseData": {
        "properties": {
          "print_files": {
            "items": {
              "$ref": "#/components/schemas/PrintFile"
            },
            "type": "array",
            "description": "List of rendered print files"
          },
          "render_uuid": {
            "anyOf": [
              {
                "type": "string"
              },
              {
                "type": "null"
              }
            ],
            "description": "The render's transaction id (also the async job uuid). Echoed at the data level for convenience; null on legacy paths."
          }
        },
        "type": "object",
        "required": [
          "print_files"
        ],
        "title": "RenderResponseData",
        "description": "Data payload in render response"
      },
      "RenderWarning": {
        "properties": {
          "code": {
            "type": "string",
            "description": "Stable advisory code"
          },
          "message": {
            "type": "string",
            "description": "Human-readable, non-fatal advisory"
          }
        },
        "type": "object",
        "required": [
          "code",
          "message"
        ],
        "title": "RenderWarning",
        "description": "Non-fatal advisory attached to a successful render."
      },
      "Size": {
        "properties": {
          "width": {
            "type": "integer",
            "description": "Width in pixels"
          },
          "height": {
            "type": "integer",
            "description": "Height in pixels"
          }
        },
        "type": "object",
        "required": [
          "width",
          "height"
        ],
        "title": "Size",
        "description": "Width and height in pixels."
      },
      "SmartObjectInput": {
        "properties": {
          "uuid": {
            "type": "string",
            "pattern": "^[0-9a-f]{8}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{12}$",
            "description": "UUID of the smart object to render",
            "examples": [
              "b41a7e52-93c8-4d61-8f07-2ae5c9d04713"
            ]
          },
          "asset": {
            "anyOf": [
              {
                "$ref": "#/components/schemas/AssetInput"
              },
              {
                "type": "null"
              }
            ],
            "description": "Asset configuration (image to place)"
          },
          "color": {
            "anyOf": [
              {
                "$ref": "#/components/schemas/ColorOverlay"
              },
              {
                "type": "null"
              }
            ],
            "description": "Color overlay configuration"
          },
          "adjustment_layers": {
            "anyOf": [
              {
                "$ref": "#/components/schemas/AdjustmentLayers"
              },
              {
                "type": "null"
              }
            ],
            "description": "Image adjustments applied to your artwork after the fit transform and before it is blended into the mockup. PSD-level adjustment layers are not affected."
          }
        },
        "type": "object",
        "required": [
          "uuid"
        ],
        "title": "SmartObjectInput",
        "description": "One smart object and what goes into it.",
        "example": {
          "asset": {
            "fit": "fill",
            "rotate": 0,
            "url": "https://example.com/user-design.png"
          },
          "color": {
            "blending_mode": "multiply",
            "hex": "#FF5733"
          },
          "uuid": "223e4567-e89b-12d3-a456-426614174001"
        }
      },
      "SmartObjectResponse": {
        "properties": {
          "uuid": {
            "type": "string",
            "description": "Unique identifier for the smart object",
            "examples": [
              "b41a7e52-93c8-4d61-8f07-2ae5c9d04713"
            ]
          },
          "name": {
            "type": "string",
            "description": "Display name of the smart object",
            "examples": [
              "Front print"
            ]
          },
          "size": {
            "$ref": "#/components/schemas/Size",
            "description": "Size dimensions of the smart object"
          },
          "position": {
            "$ref": "#/components/schemas/Position",
            "description": "Bounding box (x, y, width, height) relative to the containing frame: the PSD canvas for a top-level smart object, the parent smart object's own document for one listed inside another."
          },
          "print_area_presets": {
            "items": {
              "$ref": "#/components/schemas/PrintAreaPreset"
            },
            "type": "array",
            "description": "Print area preset configurations"
          },
          "layer_name": {
            "anyOf": [
              {
                "type": "string"
              },
              {
                "type": "null"
              }
            ],
            "description": "Original PSD layer name",
            "examples": [
              "Front print"
            ]
          },
          "quad": {
            "anyOf": [
              {
                "items": {
                  "items": {
                    "type": "number"
                  },
                  "type": "array"
                },
                "type": "array"
              },
              {
                "type": "null"
              }
            ],
            "description": "Four display coordinates for the editable area, in the same frame as position. Only available on Scale tier plans (null on Free/Starter/Pro).",
            "examples": [
              [
                [
                  512.0,
                  742.0
                ],
                [
                  3512.0,
                  730.0
                ],
                [
                  3499.0,
                  4143.0
                ],
                [
                  524.0,
                  4131.0
                ]
              ]
            ]
          },
          "blend_mode": {
            "anyOf": [
              {
                "type": "string"
              },
              {
                "type": "null"
              }
            ],
            "description": "The blend mode this smart object layer carries in the PSD, lowercase (e.g. 'normal', 'multiply', 'soft_light'). Null in the mockup list; request a single mockup to read it.",
            "examples": [
              "multiply"
            ]
          },
          "instance_count": {
            "anyOf": [
              {
                "type": "integer"
              },
              {
                "type": "null"
              }
            ],
            "description": "Number of PSD layers this input drives (smart object instancing); null/1 = single layer",
            "examples": [
              3
            ]
          },
          "smart_objects": {
            "items": {
              "$ref": "#/components/schemas/SmartObjectResponse"
            },
            "type": "array",
            "description": "Smart objects inside this smart object's own contents, in layer order. Fill any of them by UUID in the same render, like a top-level one. Left out when there are none."
          },
          "text_layers": {
            "items": {
              "$ref": "#/components/schemas/TextLayer"
            },
            "type": "array",
            "description": "Text layers inside this smart object's own contents, in layer order. Edit any of them by UUID in the same render, like a top-level one. Left out when there are none."
          }
        },
        "type": "object",
        "required": [
          "uuid",
          "name",
          "size",
          "position",
          "print_area_presets"
        ],
        "title": "SmartObjectResponse",
        "description": "A smart object found in the uploaded file, with the UUID you address it by.",
        "example": {
          "blend_mode": "normal",
          "layer_name": "Smart Object 1",
          "name": "Main Design",
          "position": {
            "height": 600,
            "width": 800,
            "x": 100,
            "y": 100
          },
          "print_area_presets": [
            {
              "name": "Default",
              "position": {
                "height": 3413,
                "width": 3000,
                "x": 0,
                "y": 0
              },
              "size": {
                "height": 3413,
                "width": 3000
              },
              "thumbnails": [],
              "uuid": "preset-uuid-here"
            }
          ],
          "quad": [
            [
              100,
              100
            ],
            [
              900,
              100
            ],
            [
              900,
              700
            ],
            [
              100,
              700
            ]
          ],
          "size": {
            "height": 3413,
            "width": 3000
          },
          "uuid": "123e4567-e89b-12d3-a456-426614174000"
        }
      },
      "StudioActionContext": {
        "properties": {
          "shop": {
            "anyOf": [
              {
                "type": "string",
                "maxLength": 255,
                "minLength": 1
              },
              {
                "type": "null"
              }
            ],
            "description": "Store domain the session was opened for.",
            "examples": [
              "your-store.myshopify.com"
            ]
          },
          "product_id": {
            "anyOf": [
              {
                "type": "string",
                "maxLength": 255,
                "minLength": 1
              },
              {
                "type": "null"
              }
            ],
            "description": "Product identifier from your store platform.",
            "examples": [
              "8342019283"
            ]
          },
          "variant_id": {
            "anyOf": [
              {
                "type": "string",
                "maxLength": 255,
                "minLength": 1
              },
              {
                "type": "null"
              }
            ],
            "description": "Variant identifier from your store platform.",
            "examples": [
              "44912837465"
            ]
          }
        },
        "additionalProperties": false,
        "type": "object",
        "title": "StudioActionContext"
      },
      "StudioActionPayload": {
        "properties": {
          "mockup_uuid": {
            "type": "string",
            "format": "uuid",
            "description": "Identifier of the mockup the action was produced from.",
            "examples": [
              "c315f78f-d2c7-4541-b240-a9372842de94"
            ]
          },
          "render_uuid": {
            "type": "string",
            "format": "uuid",
            "description": "Identifier of the successful render this action confirms.",
            "examples": [
              "9b2e5f31-4c8d-4a76-8f0b-2d7e6c1a9354"
            ]
          },
          "action_id": {
            "anyOf": [
              {
                "type": "string",
                "maxLength": 64,
                "minLength": 1,
                "pattern": "^[A-Za-z0-9][A-Za-z0-9._:-]{0,63}$"
              },
              {
                "type": "null"
              }
            ],
            "description": "Routing identifier the session was opened with.",
            "examples": [
              "add-to-cart"
            ]
          },
          "action_context": {
            "$ref": "#/components/schemas/StudioActionContext",
            "description": "Store context the session was opened with, which must match to confirm the action."
          },
          "render_parameters": {
            "anyOf": [
              {
                "additionalProperties": true,
                "type": "object"
              },
              {
                "type": "null"
              }
            ],
            "description": "Source-safe PSD or photo mockup render parameters emitted by the completed customize action.",
            "examples": [
              {
                "export_options": {
                  "image_format": "webp",
                  "image_size": 1920,
                  "quality": 95
                },
                "print_areas": [
                  {
                    "adjustments": {
                      "blend_mode": "multiply",
                      "opacity": 90
                    },
                    "artwork_url": "https://example.com/design.png",
                    "placement": {
                      "fit": "fit",
                      "position": "center"
                    },
                    "uuid": "223e4567-e89b-12d3-a456-426614174001"
                  }
                ]
              }
            ]
          },
          "artwork_sources": {
            "anyOf": [
              {
                "items": {
                  "$ref": "#/components/schemas/StudioArtworkSource"
                },
                "type": "array",
                "maxItems": 8
              },
              {
                "type": "null"
              }
            ],
            "description": "Public artwork URLs per target, as emitted by Studio. Forwarded unchanged from the editor message; echoed back on the receipt."
          }
        },
        "additionalProperties": false,
        "type": "object",
        "required": [
          "mockup_uuid",
          "render_uuid"
        ],
        "title": "StudioActionPayload"
      },
      "StudioActionReceipt": {
        "properties": {
          "version": {
            "type": "integer",
            "const": 1,
            "description": "Version of the Studio action receipt format."
          },
          "request_id": {
            "type": "string",
            "format": "uuid",
            "description": "Identifier of the action message this receipt answers.",
            "examples": [
              "0f9c2d1e-7b44-4a2f-9a0d-6c1f2b8e5d33"
            ]
          },
          "message_session_id": {
            "type": "string",
            "format": "uuid",
            "description": "Identifier of the Studio session the action came from.",
            "examples": [
              "7d1b4a90-2e63-4f18-bb27-1c9a0e4d7f52"
            ]
          },
          "type": {
            "type": "string",
            "enum": [
              "studio.mockup-saved",
              "studio.design-submitted"
            ],
            "description": "Studio result this receipt confirms."
          },
          "mockup_type": {
            "type": "string",
            "enum": [
              "psd",
              "2d"
            ],
            "description": "Kind of mockup the confirmed action belongs to."
          },
          "session_kind": {
            "type": "string",
            "enum": [
              "setup",
              "customize"
            ],
            "description": "Kind of Studio session the action came from."
          },
          "action_id": {
            "anyOf": [
              {
                "type": "string"
              },
              {
                "type": "null"
              }
            ],
            "description": "Routing identifier the session was opened with.",
            "examples": [
              "add-to-cart"
            ]
          },
          "action_context": {
            "$ref": "#/components/schemas/StudioActionContext",
            "description": "Store context the session was opened with."
          },
          "mockup_uuid": {
            "type": "string",
            "format": "uuid",
            "description": "Identifier of the mockup the confirmed render belongs to.",
            "examples": [
              "c315f78f-d2c7-4541-b240-a9372842de94"
            ]
          },
          "render_uuid": {
            "type": "string",
            "format": "uuid",
            "description": "Identifier of the render this receipt confirms.",
            "examples": [
              "9b2e5f31-4c8d-4a76-8f0b-2d7e6c1a9354"
            ]
          },
          "render_parameters": {
            "anyOf": [
              {
                "additionalProperties": true,
                "type": "object"
              },
              {
                "type": "null"
              }
            ],
            "description": "Server-confirmed, source-safe PSD or 2D parameters bound to the successful render.",
            "examples": [
              {
                "export_options": {
                  "image_format": "webp",
                  "image_size": 1920,
                  "quality": 95
                },
                "print_areas": [
                  {
                    "adjustments": {
                      "blend_mode": "multiply",
                      "opacity": 90
                    },
                    "artwork_url": "https://example.com/design.png",
                    "placement": {
                      "fit": "fit",
                      "position": "center"
                    },
                    "uuid": "223e4567-e89b-12d3-a456-426614174001"
                  }
                ]
              }
            ]
          },
          "artwork_sources": {
            "anyOf": [
              {
                "items": {
                  "$ref": "#/components/schemas/StudioArtworkSource"
                },
                "type": "array"
              },
              {
                "type": "null"
              }
            ],
            "description": "The artwork URLs supplied with this action, returned unchanged. Not stored and not server-confirmed: on a replayed action this echoes what the replay attempt sent, and a differing value does not make the action conflict."
          }
        },
        "additionalProperties": false,
        "type": "object",
        "required": [
          "version",
          "request_id",
          "message_session_id",
          "type",
          "mockup_type",
          "session_kind",
          "action_context",
          "mockup_uuid",
          "render_uuid"
        ],
        "title": "StudioActionReceipt"
      },
      "StudioActionRequest": {
        "properties": {
          "version": {
            "type": "integer",
            "const": 1,
            "description": "Version of the Studio action message format."
          },
          "request_id": {
            "type": "string",
            "format": "uuid",
            "description": "Identifier of the action message, so a repeated call returns the same receipt.",
            "examples": [
              "0f9c2d1e-7b44-4a2f-9a0d-6c1f2b8e5d33"
            ]
          },
          "message_session_id": {
            "type": "string",
            "format": "uuid",
            "description": "Identifier of the Studio session that emitted the action.",
            "examples": [
              "7d1b4a90-2e63-4f18-bb27-1c9a0e4d7f52"
            ]
          },
          "type": {
            "type": "string",
            "enum": [
              "studio.mockup-saved",
              "studio.design-submitted"
            ],
            "description": "Studio result this request confirms."
          },
          "payload": {
            "$ref": "#/components/schemas/StudioActionPayload",
            "description": "Identifiers and parameters of the Studio action to confirm."
          }
        },
        "additionalProperties": false,
        "type": "object",
        "required": [
          "version",
          "request_id",
          "message_session_id",
          "type",
          "payload"
        ],
        "title": "StudioActionRequest",
        "example": {
          "message_session_id": "7d1b4a90-2e63-4f18-bb27-1c9a0e4d7f52",
          "payload": {
            "mockup_uuid": "c315f78f-d2c7-4541-b240-a9372842de94",
            "render_uuid": "9b2e5f31-4c8d-4a76-8f0b-2d7e6c1a9354"
          },
          "request_id": "0f9c2d1e-7b44-4a2f-9a0d-6c1f2b8e5d33",
          "type": "studio.mockup-saved",
          "version": 1
        }
      },
      "StudioActionResponse": {
        "properties": {
          "success": {
            "type": "boolean",
            "const": true,
            "description": "Always true when the action was confirmed.",
            "default": true
          },
          "replayed": {
            "type": "boolean",
            "description": "True when this action was already confirmed and its receipt is returned again.",
            "examples": [
              false
            ]
          },
          "receipt": {
            "$ref": "#/components/schemas/StudioActionReceipt",
            "description": "Confirmed record of the Studio action."
          },
          "order_assets": {
            "anyOf": [
              {
                "$ref": "#/components/schemas/StudioOrderAssets"
              },
              {
                "type": "null"
              }
            ],
            "description": "Preview, artwork and print file links to keep on the order line. Returned for a submitted design of an add-to-cart session when files were kept for it. A repeat returns the links the order has at that time. Left out otherwise."
          }
        },
        "additionalProperties": false,
        "type": "object",
        "required": [
          "replayed",
          "receipt"
        ],
        "title": "StudioActionResponse"
      },
      "StudioArtworkInput": {
        "properties": {
          "target_uuid": {
            "type": "string",
            "pattern": "^[0-9a-f]{8}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{12}$",
            "description": "Smart Object id for PSD. For a photo mockup, either a saved print area id or a product surface id. The same field accepts both.",
            "examples": [
              "7c1f4b02-9d3e-4a68-b5c1-0e2d9a6f83b4"
            ]
          },
          "url": {
            "anyOf": [
              {
                "type": "string",
                "maxLength": 2048
              },
              {
                "type": "null"
              }
            ],
            "description": "HTTPS artwork URL. Ignored when base64 is also supplied.",
            "examples": [
              "https://cdn.example.com/design.png"
            ]
          },
          "base64": {
            "anyOf": [
              {
                "type": "string",
                "maxLength": 89478488,
                "minLength": 4
              },
              {
                "type": "null"
              }
            ],
            "description": "Canonical raw base64 artwork, up to 64 MB decoded. Takes precedence when url is also supplied."
          },
          "placement": {
            "anyOf": [
              {
                "$ref": "#/components/schemas/StudioSeedPlacement"
              },
              {
                "type": "null"
              }
            ],
            "description": "Optional opening placement for this design, in percentages of the target's own region. Omit it to open where the editor opens today."
          },
          "adjustments": {
            "anyOf": [
              {
                "$ref": "#/components/schemas/StudioSeedAdjustments"
              },
              {
                "type": "null"
              }
            ],
            "description": "Optional opening appearance for this design. Send back what a finished session reported to carry a look from one mockup of a product to the next. Omit it to open at the editor's own values. A PSD target reads brightness, contrast, saturation, vibrance, opacity and blur; a photo target reads opacity and blend_mode."
          }
        },
        "additionalProperties": false,
        "type": "object",
        "required": [
          "target_uuid"
        ],
        "title": "StudioArtworkInput"
      },
      "StudioArtworkSource": {
        "properties": {
          "uuid": {
            "anyOf": [
              {
                "type": "string",
                "pattern": "^[0-9a-f]{8}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{12}$"
              },
              {
                "type": "null"
              }
            ],
            "description": "Print area this artwork was placed on.",
            "examples": [
              "6f1c8d42-0b57-4e39-a6d8-3c95b1e740af"
            ]
          },
          "surface_uuid": {
            "anyOf": [
              {
                "type": "string",
                "pattern": "^[0-9a-f]{8}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{12}$"
              },
              {
                "type": "null"
              }
            ],
            "description": "Product surface this artwork covers.",
            "examples": [
              "2b7e4f19-8c3d-4a60-9e15-7d0c6b3a58e2"
            ]
          },
          "smart_object_uuid": {
            "anyOf": [
              {
                "type": "string",
                "pattern": "^[0-9a-f]{8}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{12}$"
              },
              {
                "type": "null"
              }
            ],
            "description": "Smart object this artwork was placed on.",
            "examples": [
              "a3d95c07-61e2-4f8b-b204-5e9c1f7d3a86"
            ]
          },
          "url": {
            "type": "string",
            "maxLength": 2048,
            "description": "Public URL of the artwork image the shopper ended up with.",
            "examples": [
              "https://cdn.example.com/design-cutout.png"
            ]
          }
        },
        "additionalProperties": false,
        "type": "object",
        "required": [
          "url"
        ],
        "title": "StudioArtworkSource",
        "description": "Public URL of the artwork a shopper ended up with, per target.\n\nStudio emits this alongside render_parameters so the host page can keep the\nimage the shopper paid for, background-removal cutouts in particular, which\nthe render request itself carries as inline data and therefore cannot name.\n\nIt is caller-supplied and echoed back verbatim, exactly like action_context:\nthe server does not attest that these URLs belong to this render, and does\nnot store them on the receipt. Never put a URL from here into\nrender_parameters: those are bound to the render and any edit there\nmakes the cart call fail."
      },
      "StudioConfigPatch": {
        "properties": {
          "primaryColor": {
            "anyOf": [
              {
                "type": "string",
                "pattern": "^#[0-9A-Fa-f]{6}$"
              },
              {
                "type": "null"
              }
            ],
            "description": "Primary color of the editor interface.",
            "default": "#0f172a"
          },
          "accentColor": {
            "anyOf": [
              {
                "type": "string",
                "pattern": "^#[0-9A-Fa-f]{6}$"
              },
              {
                "type": "null"
              }
            ],
            "description": "Accent color for highlights and active states in the editor.",
            "default": "#da7756"
          },
          "backgroundColor": {
            "anyOf": [
              {
                "type": "string",
                "pattern": "^#[0-9A-Fa-f]{6}$"
              },
              {
                "type": "null"
              }
            ],
            "description": "Background color of the editor.",
            "default": "#f1f5f9"
          },
          "panelBackground": {
            "anyOf": [
              {
                "type": "string",
                "pattern": "^#[0-9A-Fa-f]{6}$"
              },
              {
                "type": "null"
              }
            ],
            "description": "Background color of the editor panels.",
            "default": "#ffffff"
          },
          "textColor": {
            "anyOf": [
              {
                "type": "string",
                "pattern": "^#[0-9A-Fa-f]{6}$"
              },
              {
                "type": "null"
              }
            ],
            "description": "Color of the text in the editor.",
            "default": "#0f172a"
          },
          "borderColor": {
            "anyOf": [
              {
                "type": "string",
                "pattern": "^#[0-9A-Fa-f]{6}$"
              },
              {
                "type": "null"
              }
            ],
            "description": "Color of the borders and dividers in the editor.",
            "default": "#e2e8f0"
          },
          "successColor": {
            "anyOf": [
              {
                "type": "string",
                "pattern": "^#[0-9A-Fa-f]{6}$"
              },
              {
                "type": "null"
              }
            ],
            "description": "Color the editor uses to confirm a completed action.",
            "default": "#16a34a"
          },
          "borderRadius": {
            "anyOf": [
              {
                "type": "integer",
                "maximum": 20.0,
                "minimum": 0.0
              },
              {
                "type": "null"
              }
            ],
            "description": "Corner radius of the editor controls, in pixels.",
            "default": 10
          },
          "logoUrl": {
            "anyOf": [
              {
                "type": "string",
                "maxLength": 2048
              },
              {
                "type": "null"
              }
            ],
            "description": "HTTPS address of the logo shown in the editor header.",
            "examples": [
              "https://your-store.example.com/assets/logo.png"
            ]
          },
          "fontFamily": {
            "anyOf": [
              {
                "type": "string",
                "maxLength": 64,
                "minLength": 1,
                "pattern": "^[A-Za-z0-9][A-Za-z0-9 ,._-]*$"
              },
              {
                "type": "null"
              }
            ],
            "description": "Font family the editor uses for its own text.",
            "examples": [
              "Inter, sans-serif"
            ]
          },
          "headerText": {
            "anyOf": [
              {
                "type": "string",
                "maxLength": 96
              },
              {
                "type": "null"
              }
            ],
            "description": "Title shown in the editor header.",
            "default": "Customize Your Design"
          },
          "uploadText": {
            "anyOf": [
              {
                "type": "string",
                "maxLength": 96,
                "minLength": 1
              },
              {
                "type": "null"
              }
            ],
            "description": "Prompt shown in the editor upload area.",
            "default": "Drop image or click to upload"
          },
          "secondaryActionLabel": {
            "anyOf": [
              {
                "type": "string",
                "maxLength": 96,
                "minLength": 1
              },
              {
                "type": "null"
              }
            ],
            "description": "Label on the editor secondary action button.",
            "default": "Render Preview"
          },
          "loadingText": {
            "anyOf": [
              {
                "type": "string",
                "maxLength": 96,
                "minLength": 1
              },
              {
                "type": "null"
              }
            ],
            "description": "Text shown while the primary action is running.",
            "default": "Adding..."
          },
          "successText": {
            "anyOf": [
              {
                "type": "string",
                "maxLength": 96,
                "minLength": 1
              },
              {
                "type": "null"
              }
            ],
            "description": "Text shown once the primary action succeeds.",
            "default": "Added!"
          },
          "psdPrimaryActionLabel": {
            "anyOf": [
              {
                "type": "string",
                "maxLength": 96,
                "minLength": 1
              },
              {
                "type": "null"
              }
            ],
            "description": "Label on the primary action button in the PSD editor.",
            "default": "Add to Cart"
          },
          "twoDSetupPrimaryActionLabel": {
            "anyOf": [
              {
                "type": "string",
                "maxLength": 96,
                "minLength": 1
              },
              {
                "type": "null"
              }
            ],
            "description": "Label on the primary action button in a photo mockup setup session.",
            "default": "Save Mockup"
          },
          "twoDCustomizePrimaryActionLabel": {
            "anyOf": [
              {
                "type": "string",
                "maxLength": 96,
                "minLength": 1
              },
              {
                "type": "null"
              }
            ],
            "description": "Label on the primary action button in a photo mockup customize session.",
            "default": "Add to Cart"
          },
          "psdShowAdjustments": {
            "anyOf": [
              {
                "type": "boolean"
              },
              {
                "type": "null"
              }
            ],
            "description": "Shows or hides the image adjustment controls in the PSD editor.",
            "default": true
          },
          "psdShowColorOverlay": {
            "anyOf": [
              {
                "type": "boolean"
              },
              {
                "type": "null"
              }
            ],
            "description": "Shows or hides the color overlay control in the PSD editor.",
            "default": true
          },
          "psdShowTextLayers": {
            "anyOf": [
              {
                "type": "boolean"
              },
              {
                "type": "null"
              }
            ],
            "description": "Shows or hides the text layer controls in the PSD editor.",
            "default": true
          },
          "psdShowFitMode": {
            "anyOf": [
              {
                "type": "boolean"
              },
              {
                "type": "null"
              }
            ],
            "description": "Shows or hides the fit mode control in the PSD editor.",
            "default": true
          },
          "psdShowPosition": {
            "anyOf": [
              {
                "type": "boolean"
              },
              {
                "type": "null"
              }
            ],
            "description": "Shows or hides the position controls in the PSD editor.",
            "default": true
          },
          "psdShowSize": {
            "anyOf": [
              {
                "type": "boolean"
              },
              {
                "type": "null"
              }
            ],
            "description": "Shows or hides the size controls in the PSD editor.",
            "default": true
          },
          "psdShowRotation": {
            "anyOf": [
              {
                "type": "boolean"
              },
              {
                "type": "null"
              }
            ],
            "description": "Shows or hides the rotation control in the PSD editor.",
            "default": true
          },
          "psdShowFlip": {
            "anyOf": [
              {
                "type": "boolean"
              },
              {
                "type": "null"
              }
            ],
            "description": "Shows or hides the flip controls in the PSD editor.",
            "default": true
          },
          "psdShowExportOptions": {
            "anyOf": [
              {
                "type": "boolean"
              },
              {
                "type": "null"
              }
            ],
            "description": "Shows or hides the export options in the PSD editor.",
            "default": true
          },
          "psdShowZoomControls": {
            "anyOf": [
              {
                "type": "boolean"
              },
              {
                "type": "null"
              }
            ],
            "description": "Shows or hides the zoom controls in the PSD editor.",
            "default": true
          },
          "psdShowUndoRedo": {
            "anyOf": [
              {
                "type": "boolean"
              },
              {
                "type": "null"
              }
            ],
            "description": "Shows or hides the undo and redo controls in the PSD editor.",
            "default": true
          },
          "psdAutoRender": {
            "anyOf": [
              {
                "type": "boolean"
              },
              {
                "type": "null"
              }
            ],
            "description": "Renders a new preview after each change in the PSD editor.",
            "default": true
          },
          "psdAutoRenderDelay": {
            "anyOf": [
              {
                "type": "integer",
                "maximum": 3000.0,
                "minimum": 300.0
              },
              {
                "type": "null"
              }
            ],
            "description": "Milliseconds the PSD editor waits after a change before it renders.",
            "default": 800
          },
          "autoDesignCallback": {
            "anyOf": [
              {
                "type": "boolean"
              },
              {
                "type": "null"
              }
            ],
            "description": "Reports design changes to your page while the shopper edits.",
            "default": false
          },
          "psdLayout": {
            "anyOf": [
              {
                "type": "string",
                "enum": [
                  "full",
                  "compact"
                ]
              },
              {
                "type": "null"
              }
            ],
            "description": "Layout of the PSD editor, full or compact.",
            "default": "full"
          },
          "twoDShowArtwork": {
            "anyOf": [
              {
                "type": "boolean"
              },
              {
                "type": "null"
              }
            ],
            "description": "Shows or hides the artwork upload control in the photo mockup editor.",
            "default": true
          },
          "twoDShowFill": {
            "anyOf": [
              {
                "type": "boolean"
              },
              {
                "type": "null"
              }
            ],
            "description": "Shows or hides the fill color control in the photo mockup editor.",
            "default": true
          },
          "twoDShowBlend": {
            "anyOf": [
              {
                "type": "boolean"
              },
              {
                "type": "null"
              }
            ],
            "description": "Shows or hides the blend mode control in the photo mockup editor.",
            "default": true
          },
          "twoDShowOpacity": {
            "anyOf": [
              {
                "type": "boolean"
              },
              {
                "type": "null"
              }
            ],
            "description": "Shows or hides the opacity control in the photo mockup editor.",
            "default": true
          },
          "twoDShowTransform": {
            "anyOf": [
              {
                "type": "boolean"
              },
              {
                "type": "null"
              }
            ],
            "description": "Shows or hides the transform controls in the photo mockup editor.",
            "default": true
          },
          "twoDShowZoom": {
            "anyOf": [
              {
                "type": "boolean"
              },
              {
                "type": "null"
              }
            ],
            "description": "Shows or hides the zoom controls in the photo mockup editor.",
            "default": true
          },
          "twoDShowExport": {
            "anyOf": [
              {
                "type": "boolean"
              },
              {
                "type": "null"
              }
            ],
            "description": "Shows or hides the export options in the photo mockup editor.",
            "default": true
          },
          "twoDShowBackgroundRemoval": {
            "anyOf": [
              {
                "type": "boolean"
              },
              {
                "type": "null"
              }
            ],
            "description": "Shows or hides the background removal control in the photo mockup editor.",
            "default": true
          },
          "colorPalette": {
            "anyOf": [
              {
                "items": {
                  "$ref": "#/components/schemas/PaletteColour"
                },
                "type": "array",
                "maxItems": 96,
                "minItems": 1
              },
              {
                "type": "null"
              }
            ],
            "description": "Named colors the product comes in, and the only ones the editor offers.",
            "examples": [
              [
                {
                  "hex": "#1a1a1a",
                  "label": "Black"
                },
                {
                  "hex": "#f5f5f5",
                  "label": "Natural"
                }
              ]
            ]
          },
          "showClose": {
            "anyOf": [
              {
                "type": "boolean"
              },
              {
                "type": "null"
              }
            ],
            "description": "Shows or hides the close button in the editor header.",
            "default": true
          },
          "theme": {
            "anyOf": [
              {
                "type": "string",
                "enum": [
                  "light",
                  "dark"
                ]
              },
              {
                "type": "null"
              }
            ],
            "description": "Theme the editor opens in, light or dark.",
            "default": "light"
          },
          "locale": {
            "anyOf": [
              {
                "type": "string",
                "enum": [
                  "en",
                  "tr"
                ]
              },
              {
                "type": "null"
              }
            ],
            "description": "Language the editor panel is shown in.",
            "default": "en"
          },
          "maxFileSize": {
            "anyOf": [
              {
                "type": "integer",
                "maximum": 50.0,
                "minimum": 1.0
              },
              {
                "type": "null"
              }
            ],
            "description": "Largest upload the editor accepts, in megabytes.",
            "default": 15
          }
        },
        "additionalProperties": false,
        "type": "object",
        "title": "StudioConfigPatch"
      },
      "StudioConfigResponse": {
        "properties": {
          "success": {
            "type": "boolean",
            "description": "True when the configuration was returned.",
            "default": true
          },
          "config": {
            "additionalProperties": true,
            "type": "object",
            "description": "The effective Studio configuration for this API key.",
            "default": {},
            "examples": [
              {
                "accentColor": "#da7756",
                "backgroundColor": "#f1f5f9",
                "borderRadius": 10,
                "headerText": "Customize Your Design",
                "primaryColor": "#0f172a",
                "uploadText": "Drop image or click to upload"
              }
            ]
          },
          "config_version": {
            "type": "integer",
            "description": "Version of the stored configuration, which rises with every update.",
            "default": 0,
            "examples": [
              3
            ]
          }
        },
        "type": "object",
        "title": "StudioConfigResponse"
      },
      "StudioOrderAssets": {
        "properties": {
          "preview_url": {
            "anyOf": [
              {
                "type": "string"
              },
              {
                "type": "null"
              }
            ],
            "description": "Link to the preview image the shopper approved.",
            "examples": [
              "https://cdn.sudomock.com/mockup-assets/order-assets/c315f78f-d2c7-4541-b240-a9372842de94/9b2e5f31-4c8d-4a76-8f0b-2d7e6c1a9354/preview/render_9b2e5f31-4c8d-4a76-8f0b-2d7e6c1a9354.webp"
            ]
          },
          "artwork_urls": {
            "items": {
              "type": "string"
            },
            "type": "array",
            "description": "Links to the artwork files kept for the order.",
            "examples": [
              [
                "https://cdn.sudomock.com/mockup-assets/order-assets/c315f78f-d2c7-4541-b240-a9372842de94/9b2e5f31-4c8d-4a76-8f0b-2d7e6c1a9354/a3d95c07-61e2-4f8b-b204-5e9c1f7d3a86/5f1c0b2a7d434e9a.png"
              ]
            ]
          },
          "print_file_urls": {
            "items": {
              "type": "string"
            },
            "type": "array",
            "description": "Links to the full-resolution print files kept for the order, one per smart object whose inner layers were filled or hidden. Left out when there are none.",
            "examples": [
              [
                "https://cdn.sudomock.com/mockup-assets/order-assets/c315f78f-d2c7-4541-b240-a9372842de94/9b2e5f31-4c8d-4a76-8f0b-2d7e6c1a9354/print/3f9c2a7e5b1d4c8a9e6f0b2d7a4c1e8f5b3d9a6c2e7f1b4d8a0c5e9f3b7d2a6c.png"
              ]
            ]
          }
        },
        "additionalProperties": false,
        "type": "object",
        "title": "StudioOrderAssets",
        "description": "Links to keep on the order line of a confirmed add-to-cart action."
      },
      "StudioSeedAdjustments": {
        "properties": {
          "brightness": {
            "anyOf": [
              {
                "type": "integer",
                "maximum": 100.0,
                "minimum": -100.0
              },
              {
                "type": "null"
              }
            ],
            "description": "Brightness, -100 to 100. Omit for the editor's own.",
            "examples": [
              10
            ]
          },
          "contrast": {
            "anyOf": [
              {
                "type": "integer",
                "maximum": 100.0,
                "minimum": -100.0
              },
              {
                "type": "null"
              }
            ],
            "description": "Contrast, -100 to 100. Omit for the editor's own.",
            "examples": [
              8
            ]
          },
          "saturation": {
            "anyOf": [
              {
                "type": "integer",
                "maximum": 100.0,
                "minimum": -100.0
              },
              {
                "type": "null"
              }
            ],
            "description": "Saturation, -100 to 100. Omit for the editor's own.",
            "examples": [
              -5
            ]
          },
          "vibrance": {
            "anyOf": [
              {
                "type": "integer",
                "maximum": 100.0,
                "minimum": -100.0
              },
              {
                "type": "null"
              }
            ],
            "description": "Vibrance, -100 to 100. Omit for the editor's own.",
            "examples": [
              15
            ]
          },
          "opacity": {
            "anyOf": [
              {
                "type": "integer",
                "maximum": 100.0,
                "minimum": 0.0
              },
              {
                "type": "null"
              }
            ],
            "description": "Opacity, 0 to 100. Omit for the editor's own.",
            "examples": [
              80
            ]
          },
          "blur": {
            "anyOf": [
              {
                "type": "number",
                "maximum": 20.0,
                "minimum": 0.0
              },
              {
                "type": "null"
              }
            ],
            "description": "Blur, 0 to 20, in half steps. Omit for the editor's own.",
            "examples": [
              2.5
            ]
          },
          "blend_mode": {
            "anyOf": [
              {
                "type": "string",
                "enum": [
                  "multiply",
                  "normal",
                  "screen",
                  "lighten",
                  "soft_light",
                  "overlay",
                  "darken"
                ]
              },
              {
                "type": "null"
              }
            ],
            "description": "How the artwork sits on the product surface. Photo targets only. Omit for the editor's own."
          }
        },
        "additionalProperties": false,
        "type": "object",
        "title": "StudioSeedAdjustments",
        "description": "How a design looks when the editor opens it.\n\nOne spelling for both target kinds, because this is a request rather than\na report: the merchant asks for an opening appearance and the session\neither honours it or refuses to open. Which keys a target can honour\ndiffers, and a key the target cannot honour refuses the session, the same\nway an unsupported placement does.\n\nNothing carries a default. A placement can afford them because `box` is\nrequired, so that object never exists half-filled; this one has no\nrequired key at all, so a default would be a value the merchant never\nsent, echoed back as though they had.\n\nThe bounds are the ones the editor's own controls span, not the wider set\nthe finished image accepts. Seeding a brightness the control cannot reach\nopens a session whose preview disagrees with its result from the first\nframe, and the shopper, the only person present, has no way to know.\nSuch a seed is refused, as an unsupported placement is."
      },
      "StudioSeedAutoBox": {
        "properties": {
          "mode": {
            "type": "string",
            "const": "auto",
            "description": "Marks this box as an allowance the design fits inside."
          },
          "coverage": {
            "type": "integer",
            "maximum": 100.0,
            "minimum": 10.0,
            "description": "Percentage of the target region the design is allowed to fill.",
            "examples": [
              85
            ]
          }
        },
        "additionalProperties": false,
        "type": "object",
        "required": [
          "mode",
          "coverage"
        ],
        "title": "StudioSeedAutoBox",
        "description": "An allowance. The artwork keeps its own proportions inside it."
      },
      "StudioSeedManualBox": {
        "properties": {
          "mode": {
            "type": "string",
            "const": "manual",
            "description": "Marks this box as an explicit width and height."
          },
          "width_percent": {
            "type": "number",
            "maximum": 300.0,
            "exclusiveMinimum": 0.0,
            "description": "Percentage of the target region's WIDTH.",
            "examples": [
              80.0
            ]
          },
          "height_percent": {
            "type": "number",
            "maximum": 300.0,
            "exclusiveMinimum": 0.0,
            "description": "Percentage of the target region's HEIGHT.",
            "examples": [
              60.0
            ]
          }
        },
        "additionalProperties": false,
        "type": "object",
        "required": [
          "mode",
          "width_percent",
          "height_percent"
        ],
        "title": "StudioSeedManualBox",
        "description": "The box itself. The only spelling that can carry a ratio of its own."
      },
      "StudioSeedPlacement": {
        "properties": {
          "box": {
            "oneOf": [
              {
                "$ref": "#/components/schemas/StudioSeedAutoBox"
              },
              {
                "$ref": "#/components/schemas/StudioSeedManualBox"
              }
            ],
            "description": "How large the design starts: an allowance, or the box itself.",
            "examples": [
              {
                "coverage": 85,
                "mode": "auto"
              }
            ],
            "discriminator": {
              "propertyName": "mode",
              "mapping": {
                "auto": "#/components/schemas/StudioSeedAutoBox",
                "manual": "#/components/schemas/StudioSeedManualBox"
              }
            }
          },
          "fit": {
            "type": "string",
            "enum": [
              "fill",
              "fit",
              "crop"
            ],
            "description": "How the artwork's pixels meet the box.",
            "default": "fit"
          },
          "offset_x_percent": {
            "type": "number",
            "maximum": 100.0,
            "minimum": -100.0,
            "description": "Percentage of the region WIDTH, from the region centre, positive right.",
            "default": 0,
            "examples": [
              12.5
            ]
          },
          "offset_y_percent": {
            "type": "number",
            "maximum": 100.0,
            "minimum": -100.0,
            "description": "Percentage of the region HEIGHT, from the region centre, positive down.",
            "default": 0,
            "examples": [
              -8.0
            ]
          },
          "rotation": {
            "type": "number",
            "maximum": 360.0,
            "minimum": -360.0,
            "description": "Degrees about the box centre, clockwise positive.",
            "default": 0,
            "examples": [
              -15.0
            ]
          },
          "flip_horizontal": {
            "type": "boolean",
            "description": "Flip artwork horizontally (left-right mirror)",
            "default": false
          },
          "flip_vertical": {
            "type": "boolean",
            "description": "Flip artwork vertically (top-bottom mirror)",
            "default": false
          }
        },
        "additionalProperties": false,
        "type": "object",
        "required": [
          "box"
        ],
        "title": "StudioSeedPlacement",
        "description": "Where a locked design starts, in the units of the region that holds it.\n\nEvery length here is a percentage of the target's own region (the print\narea's bounding box for a photo mockup, the Smart Object's embedded frame\nfor PSD), because that is the one denominator both sides already have without a\nsecond round trip. Offsets run from the region CENTRE, positive right and\ndown, and the unit lives in the field name so a reader who has only ever\nseen an example still cannot mistake it for pixels.\n\n``box`` is one branch or the other, never a mixture: a width with no height\nis not a smaller request, it is an unanswerable one, and the branch makes\nit unsendable rather than merely rejected.\n\nThis is a starting point, not a lock. The customer may move it afterwards."
      },
      "SudoAIPlacement": {
        "properties": {
          "position": {
            "type": "string",
            "enum": [
              "center",
              "top_left",
              "top_center",
              "top_right",
              "center_left",
              "center_right",
              "left_center",
              "right_center",
              "bottom_left",
              "bottom_center",
              "bottom_right"
            ],
            "description": "Predefined position within print area",
            "default": "center"
          },
          "coverage": {
            "anyOf": [
              {
                "type": "integer",
                "maximum": 100.0,
                "minimum": 10.0
              },
              {
                "type": "null"
              }
            ],
            "description": "How much of the product surface the artwork spans, 10 to 100. Spans the whole surface by default. Belongs to a surface_uuid target, and cannot be combined with an explicit width and height."
          },
          "fit": {
            "anyOf": [
              {
                "type": "string",
                "enum": [
                  "fill",
                  "fit",
                  "crop"
                ]
              },
              {
                "type": "null"
              }
            ],
            "description": "How the artwork meets the print area. 'fit' scales it until it fits inside and keeps its proportions, which is the default and can leave empty space. 'fill' stretches it to the edges and does not keep proportions. 'crop' covers the area and cuts the overflow, keeping proportions. 'contain' and 'cover' are the older names for 'fit' and 'crop' and are still accepted. Always targets the whole print area. Belongs to a uuid target, and cannot be combined with an explicit width and height."
          },
          "offset_x": {
            "type": "number",
            "description": "Horizontal offset in print-area pixels, measured from the anchor that 'position' picks, positive right. With the default position of 'center' that anchor is the middle of the print area.",
            "default": 0
          },
          "offset_y": {
            "type": "number",
            "description": "Vertical offset in print-area pixels, measured from the anchor that 'position' picks, positive down. With the default position of 'center' that anchor is the middle of the print area.",
            "default": 0
          },
          "width": {
            "anyOf": [
              {
                "type": "number",
                "maximum": 30000.0,
                "minimum": 1.0
              },
              {
                "type": "null"
              }
            ],
            "description": "Artwork width in target pixels. Must be sent together with 'height'. An exact box belongs to either kind of target: send it instead of 'fit' on a print area, or instead of 'coverage' on a surface. Width and height are independent, so any aspect ratio is allowed."
          },
          "height": {
            "anyOf": [
              {
                "type": "number",
                "maximum": 30000.0,
                "minimum": 1.0
              },
              {
                "type": "null"
              }
            ],
            "description": "Artwork height in target pixels. Must be sent together with 'width'. An exact box belongs to either kind of target: send it instead of 'fit' on a print area, or instead of 'coverage' on a surface. Width and height are independent, so any aspect ratio is allowed."
          },
          "rotation": {
            "type": "number",
            "maximum": 360.0,
            "minimum": -360.0,
            "description": "Rotation in degrees (clockwise positive)",
            "default": 0
          }
        },
        "additionalProperties": false,
        "type": "object",
        "title": "SudoAIPlacement",
        "description": "Deprecated name for `PhotoMockupPlacement`. Same shape, kept so a client generated from an earlier spec keeps the type name it already has.",
        "deprecated": true
      },
      "SudoAIPrintFile": {
        "properties": {
          "export_path": {
            "type": "string",
            "description": "Public URL of the rendered output"
          },
          "duration_ms": {
            "anyOf": [
              {
                "type": "integer"
              },
              {
                "type": "null"
              }
            ],
            "description": "Render duration in milliseconds"
          },
          "export_format": {
            "anyOf": [
              {
                "type": "string"
              },
              {
                "type": "null"
              }
            ],
            "description": "Output format used (png, jpg, webp)"
          }
        },
        "type": "object",
        "required": [
          "export_path"
        ],
        "title": "SudoAIPrintFile",
        "description": "Deprecated name for `PhotoMockupPrintFile`. Same shape, kept so a client generated from an earlier spec keeps the type name it already has.",
        "deprecated": true
      },
      "SudoAIRenderResponseData": {
        "properties": {
          "print_files": {
            "items": {
              "$ref": "#/components/schemas/PhotoMockupPrintFile"
            },
            "type": "array",
            "description": "List of rendered outputs"
          },
          "render_uuid": {
            "anyOf": [
              {
                "type": "string"
              },
              {
                "type": "null"
              }
            ],
            "description": "Identifier for this render."
          }
        },
        "type": "object",
        "required": [
          "print_files"
        ],
        "title": "SudoAIRenderResponseData",
        "description": "Deprecated name for `PhotoMockupRenderResult`. Same shape, kept so a client generated from an earlier spec keeps the type name it already has.",
        "deprecated": true
      },
      "TextLayer": {
        "properties": {
          "uuid": {
            "type": "string",
            "description": "Unique identifier for the text layer",
            "examples": [
              "c7d41f6a-2b58-4e93-9a10-6f83b2c5d417"
            ]
          },
          "name": {
            "type": "string",
            "description": "Name of the text layer",
            "examples": [
              "Brand name"
            ]
          },
          "text_content": {
            "anyOf": [
              {
                "type": "string"
              },
              {
                "type": "null"
              }
            ],
            "description": "Current text content of the layer",
            "examples": [
              "SUMMER CLUB"
            ]
          },
          "font_postscript_name": {
            "anyOf": [
              {
                "type": "string"
              },
              {
                "type": "null"
              }
            ],
            "description": "PostScript name of the font used by this layer",
            "examples": [
              "Montserrat-Bold"
            ]
          },
          "font_size": {
            "anyOf": [
              {
                "type": "number"
              },
              {
                "type": "null"
              }
            ],
            "description": "Effective font size in pixels at the PSD's native resolution",
            "examples": [
              120.0
            ]
          },
          "color": {
            "anyOf": [
              {
                "type": "string"
              },
              {
                "type": "null"
              }
            ],
            "description": "Text color as hex (e.g. #FFFFFF)",
            "examples": [
              "#FFFFFF"
            ]
          },
          "font_available": {
            "anyOf": [
              {
                "type": "boolean"
              },
              {
                "type": "null"
              }
            ],
            "description": "Whether the layer's font is available for editable rendering. When false, edits render with a default font unless a font is supplied."
          },
          "is_editable": {
            "type": "boolean",
            "description": "Whether this layer's text can be replaced at render time",
            "default": false
          },
          "segment_count": {
            "type": "integer",
            "description": "Number of styled segments in this layer. 1 = single-style (edit with 'text'); 2+ = styled segments (edit with 'segments', each segment keeps its own styling)",
            "default": 1
          },
          "segments": {
            "anyOf": [
              {
                "items": {
                  "$ref": "#/components/schemas/TextSegment"
                },
                "type": "array"
              },
              {
                "type": "null"
              }
            ],
            "description": "The layer's styled segments, present when segment_count > 1. Override any subset by index at render time; omitted segments keep their original text."
          },
          "visible": {
            "anyOf": [
              {
                "type": "boolean"
              },
              {
                "type": "null"
              }
            ],
            "description": "Whether the layer is shown by default in the source file. A hidden layer can still be targeted; its text then renders. Null when unknown (older mockups)."
          },
          "has_stroke_effect": {
            "type": "boolean",
            "description": "Whether this text layer has at least one outline of its own.",
            "default": false
          },
          "stroke_count": {
            "type": "integer",
            "description": "Number of outlines owned by this text layer, in front-to-back stroke_color order.",
            "default": 0
          },
          "has_color_overlay": {
            "type": "boolean",
            "description": "Whether the layer's visible color comes from a color effect. When true, a color override changes that effect's color.",
            "default": false
          },
          "has_clipped_artwork": {
            "anyOf": [
              {
                "type": "boolean"
              },
              {
                "type": "null"
              }
            ],
            "description": "Whether some content in the design is clipped to this layer's letters. When true, replacing this text also re-shapes that clipped content to the new letters. Null when it could not be determined for this mockup."
          },
          "suggested_edit_together": {
            "anyOf": [
              {
                "items": {
                  "type": "string"
                },
                "type": "array"
              },
              {
                "type": "null"
              }
            ],
            "description": "UUIDs of other text layers that carry the same text stacked with this one, such as a fill plus an outline copy. Sending the same replacement text to all of them keeps the design consistent. Advisory only: each layer is still edited on its own by UUID, never linked automatically. Null when it could not be determined.",
            "examples": [
              [
                "a2f9c481-30d7-4b6e-8c52-1d9e7f34ab60"
              ]
            ]
          },
          "enclosing_group_layers": {
            "anyOf": [
              {
                "items": {
                  "type": "string"
                },
                "type": "array"
              },
              {
                "type": "null"
              }
            ],
            "description": "UUIDs of enclosing group layers whose outlines also affect this text layer, nearest first. Advisory only: each group is edited separately through group_layers. Null when it could not be determined.",
            "examples": [
              [
                "5e8b0c72-9a41-4d36-b7f8-2c60d1e94537"
              ]
            ]
          }
        },
        "type": "object",
        "required": [
          "uuid",
          "name"
        ],
        "title": "TextLayer",
        "description": "Text layer metadata in upload/detail responses"
      },
      "TextLayerInput": {
        "properties": {
          "uuid": {
            "type": "string",
            "pattern": "^[0-9a-f]{8}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{12}$",
            "description": "UUID of the text layer to update (from the upload/detail response text_layers list)",
            "examples": [
              "4d7f1a2e-6c83-4b19-9e5a-2f0c8d3b6471"
            ]
          },
          "text": {
            "anyOf": [
              {
                "type": "string",
                "maxLength": 500,
                "minLength": 1
              },
              {
                "type": "null"
              }
            ],
            "description": "Replacement text (1-500 characters) for single-style layers (segment_count = 1)",
            "examples": [
              "Isabella"
            ]
          },
          "segments": {
            "anyOf": [
              {
                "items": {
                  "$ref": "#/components/schemas/TextSegmentInput"
                },
                "type": "array",
                "maxItems": 32,
                "minItems": 1
              },
              {
                "type": "null"
              }
            ],
            "description": "Styled-segment overrides for multi-style layers (segment_count > 1). Override any subset by index; omitted segments keep their original text."
          },
          "font": {
            "anyOf": [
              {
                "type": "string",
                "maxLength": 255
              },
              {
                "type": "null"
              }
            ],
            "description": "Font to render with: a font uuid from GET /fonts, or a PostScript name. Single-style layers only. Omit to keep the layer's original font.",
            "examples": [
              "OpenSans-Bold"
            ]
          },
          "font_size": {
            "anyOf": [
              {
                "type": "number",
                "maximum": 2000.0,
                "exclusiveMinimum": 0.0
              },
              {
                "type": "null"
              }
            ],
            "description": "Font size in pixels at the mockup's native resolution. Single-style layers only. Omit to keep the original size.",
            "examples": [
              48.0
            ]
          },
          "color": {
            "anyOf": [
              {
                "type": "string",
                "pattern": "^#?[0-9a-fA-F]{6}$"
              },
              {
                "type": "null"
              }
            ],
            "description": "Text color as hex, e.g. #1A1A1A. Single-style layers only. Applies to the color you see: when the layer's visible color comes from a color effect, that effect takes the new color. Omit to keep the original color.",
            "examples": [
              "#1A1A1A"
            ]
          },
          "stroke_color": {
            "anyOf": [
              {
                "type": "string"
              },
              {
                "items": {
                  "anyOf": [
                    {
                      "type": "string"
                    },
                    {
                      "type": "null"
                    }
                  ]
                },
                "type": "array"
              },
              {
                "type": "null"
              }
            ],
            "description": "Color for this text layer's own outlines. Send a hex value like \"#FFFFFF\" to recolor the front outline, or a list in stroke_count order (front to back). Use null to keep an outline's original color; extra entries are ignored. Layers with no outlines ignore this value with a warning. Single-style layers only. Omit to keep all original outline colors.",
            "examples": [
              "#FFFFFF",
              [
                "#FFFFFF",
                null
              ]
            ]
          },
          "fit": {
            "type": "string",
            "enum": [
              "shrink",
              "clip",
              "overflow"
            ],
            "description": "How longer replacement text is handled for single-style point text: 'overflow' (default) preserves the designed size and may extend beyond the original area; 'shrink' scales the text down to fit; 'clip' preserves the size and cuts it at the last character that fits. Paragraph text continues to wrap within its box.",
            "default": "overflow"
          },
          "vertical_align": {
            "type": "string",
            "enum": [
              "top",
              "bottom",
              "center"
            ],
            "description": "Where text that 'fit': 'shrink' scaled down sits vertically within the original text area: 'top' (default) keeps the designed position, 'center' centers it in the area, 'bottom' aligns it to the area's bottom edge. Only applies when shrinking actually occurs; single-style point text only.",
            "default": "top"
          }
        },
        "type": "object",
        "required": [
          "uuid"
        ],
        "title": "TextLayerInput",
        "description": "Text layer override for rendering",
        "example": {
          "color": "#FFFFFF",
          "text": "Isabella",
          "uuid": "323e4567-e89b-12d3-a456-426614174002"
        }
      },
      "TextSegment": {
        "properties": {
          "index": {
            "type": "integer",
            "description": "Stable segment position within the layer (0-based)"
          },
          "text": {
            "type": "string",
            "description": "The segment's current text",
            "default": ""
          },
          "font_postscript_name": {
            "anyOf": [
              {
                "type": "string"
              },
              {
                "type": "null"
              }
            ],
            "description": "PostScript name of the segment's font"
          },
          "font_size": {
            "anyOf": [
              {
                "type": "number"
              },
              {
                "type": "null"
              }
            ],
            "description": "Segment font size in pixels at the PSD's native resolution"
          },
          "color": {
            "anyOf": [
              {
                "type": "string"
              },
              {
                "type": "null"
              }
            ],
            "description": "Segment text color as hex (e.g. #FFFFFF)"
          }
        },
        "type": "object",
        "required": [
          "index"
        ],
        "title": "TextSegment",
        "description": "One styled segment of a multi-style text layer (upload/detail responses)."
      },
      "TextSegmentInput": {
        "properties": {
          "index": {
            "type": "integer",
            "maximum": 31.0,
            "minimum": 0.0,
            "description": "Segment to replace (0-based, from the layer's segments list)"
          },
          "text": {
            "type": "string",
            "maxLength": 200,
            "minLength": 1,
            "description": "Replacement text for this segment (1-200 characters). The segment keeps its own font, size, and color."
          }
        },
        "type": "object",
        "required": [
          "index",
          "text"
        ],
        "title": "TextSegmentInput",
        "description": "One styled-segment override for a multi-style text layer."
      },
      "ThumbnailSize": {
        "properties": {
          "width": {
            "type": "integer",
            "description": "Thumbnail width in pixels"
          },
          "url": {
            "type": "string",
            "description": "Public URL to the thumbnail image"
          }
        },
        "type": "object",
        "required": [
          "width",
          "url"
        ],
        "title": "ThumbnailSize",
        "description": "Thumbnail with size and URL"
      },
      "TwoDMockupCreateRequest": {
        "properties": {
          "source_url": {
            "anyOf": [
              {
                "type": "string"
              },
              {
                "type": "null"
              }
            ],
            "description": "Public HTTPS URL of the source image.",
            "examples": [
              "https://example.com/product-photo.jpg"
            ]
          },
          "source_base64": {
            "anyOf": [
              {
                "type": "string"
              },
              {
                "type": "null"
              }
            ],
            "description": "Base64-encoded source image, with or without a data URL prefix."
          },
          "name": {
            "anyOf": [
              {
                "type": "string",
                "maxLength": 255
              },
              {
                "type": "null"
              }
            ],
            "description": "Optional display name for the mockup.",
            "examples": [
              "Front view"
            ]
          },
          "is_async": {
            "type": "boolean",
            "description": "If true, the mockup is QUEUED and the call returns 202 immediately with a job_id (poll GET /api/v1/jobs/{job_id}, or receive a webhook if one is configured); result_url carries the new mockup_uuid on success. If false (default), the create runs synchronously and returns the mockup.",
            "default": false
          },
          "print_areas": {
            "anyOf": [
              {
                "items": {
                  "$ref": "#/components/schemas/PhotoMockupPrintAreaInput"
                },
                "type": "array",
                "maxItems": 8,
                "minItems": 1
              },
              {
                "type": "null"
              }
            ],
            "description": "Optional: 1-8 convex four-point printable areas in source-image pixels. When provided, these areas are used verbatim and automatic print-area detection is skipped."
          }
        },
        "additionalProperties": false,
        "type": "object",
        "title": "TwoDMockupCreateRequest",
        "description": "Deprecated name for `PhotoMockupCreateRequest`. Same shape, kept so a client generated from an earlier spec keeps the type name it already has.",
        "example": {
          "name": "Front view",
          "source_url": "https://example.com/product-photo.jpg"
        },
        "deprecated": true
      },
      "TwoDMockupPrintAreaRender": {
        "properties": {
          "uuid": {
            "anyOf": [
              {
                "type": "string",
                "pattern": "^[0-9a-f]{8}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{12}$"
              },
              {
                "type": "null"
              }
            ],
            "description": "UUID of a saved print area, a bounded zone drawn on a product.",
            "examples": [
              "19be48d4-c810-4420-86e3-7ec2a4d85571"
            ]
          },
          "surface_uuid": {
            "anyOf": [
              {
                "type": "string",
                "pattern": "^[0-9a-f]{8}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{12}$"
              },
              {
                "type": "null"
              }
            ],
            "description": "UUID of a printable product surface. A product carrying saved print areas still has one, and it is a separate render target from them.",
            "examples": [
              "733ee99a-f41f-4b9b-bf33-2ffa489f96db"
            ]
          },
          "base64": {
            "anyOf": [
              {
                "type": "string"
              },
              {
                "type": "null"
              }
            ],
            "description": "Base64-encoded artwork image."
          },
          "artwork_url": {
            "anyOf": [
              {
                "type": "string"
              },
              {
                "type": "null"
              }
            ],
            "description": "Artwork image URL",
            "examples": [
              "https://example.com/design.png"
            ]
          },
          "color": {
            "anyOf": [
              {
                "type": "string"
              },
              {
                "type": "null"
              }
            ],
            "description": "Solid color as a hex code (e.g., '#FF0000'), or the name of a colour saved on this mockup (e.g., 'blue jean'). Names match exactly and are set with PATCH /api/v1/photo-mockups/{uuid}.",
            "examples": [
              "#6A8296"
            ]
          },
          "adjustments": {
            "anyOf": [
              {
                "$ref": "#/components/schemas/PhotoMockupAdjustments"
              },
              {
                "type": "null"
              }
            ],
            "description": "Optional visual adjustments for the artwork."
          },
          "placement": {
            "anyOf": [
              {
                "$ref": "#/components/schemas/PhotoMockupPlacement"
              },
              {
                "type": "null"
              }
            ],
            "description": "Where the artwork sits and how big it is. position, offset_x, offset_y and rotation apply to either target. Sizing follows the target: coverage on a surface_uuid target, and either fit or an explicit width and height on a uuid target."
          },
          "flip_horizontal": {
            "type": "boolean",
            "description": "Flip artwork horizontally (left-right mirror)",
            "default": false
          },
          "flip_vertical": {
            "type": "boolean",
            "description": "Flip artwork vertically (top-bottom mirror)",
            "default": false
          },
          "remove_background": {
            "type": "boolean",
            "description": "Remove the image background before placing the artwork; the subject is isolated onto a clean transparent cutout. Adds 25 credits per artwork to the render cost.",
            "default": false
          }
        },
        "additionalProperties": false,
        "type": "object",
        "title": "TwoDMockupPrintAreaRender",
        "description": "Deprecated name for `PhotoMockupPrintAreaRender`. Same shape, kept so a client generated from an earlier spec keeps the type name it already has.",
        "deprecated": true
      },
      "TwoDMockupRenderByPathRequest": {
        "properties": {
          "print_areas": {
            "items": {
              "$ref": "#/components/schemas/PhotoMockupPrintAreaRender"
            },
            "type": "array",
            "maxItems": 8,
            "minItems": 1,
            "description": "Artwork configuration per render target. Use uuid for a saved print area, and surface_uuid for a whole product surface. A product can be rendered either way, and saving a print area on it does not take its surface away."
          },
          "export_options": {
            "$ref": "#/components/schemas/PhotoMockupExportOptions",
            "description": "Export configuration for format, size and quality. Every field has a default, so the whole object is optional."
          },
          "is_async": {
            "type": "boolean",
            "description": "If true, the render is QUEUED and the call returns 202 immediately with a job_id (poll GET /api/v1/jobs/{job_id}, or receive a webhook if one is configured); result_url carries the rendered image URL on success. If false (default), the render runs synchronously and returns the result.",
            "default": false
          }
        },
        "additionalProperties": false,
        "type": "object",
        "required": [
          "print_areas"
        ],
        "title": "TwoDMockupRenderByPathRequest",
        "description": "Deprecated name for `PhotoMockupRender`. Same shape, kept so a client generated from an earlier spec keeps the type name it already has.",
        "example": {
          "export_options": {
            "image_format": "webp",
            "image_size": 1920,
            "quality": 95
          },
          "print_areas": [
            {
              "adjustments": {
                "blend_mode": "multiply",
                "opacity": 90
              },
              "artwork_url": "https://example.com/design.png",
              "placement": {
                "fit": "fit",
                "position": "center"
              },
              "uuid": "223e4567-e89b-12d3-a456-426614174001"
            }
          ]
        },
        "deprecated": true
      },
      "TwoDMockupRenderResponse": {
        "properties": {
          "data": {
            "$ref": "#/components/schemas/PhotoMockupRenderResult",
            "description": "Rendered output files"
          },
          "success": {
            "type": "boolean",
            "description": "Success status",
            "default": true
          }
        },
        "type": "object",
        "required": [
          "data"
        ],
        "title": "TwoDMockupRenderResponse",
        "description": "Deprecated name for `PhotoMockupRenderResponse`. Same shape, kept so a client generated from an earlier spec keeps the type name it already has.",
        "example": {
          "data": {
            "print_files": [
              {
                "duration_ms": 1840,
                "export_format": "webp",
                "export_path": "https://cdn.sudomock.com/mockup-assets/renders/2d/893ea326-278b-480b-b130-87dd6aee06dc/ac0a5f31-6d2e-4d1b-9c4c-1e7f2b6a5d08.webp"
              }
            ],
            "render_uuid": "ac0a5f31-6d2e-4d1b-9c4c-1e7f2b6a5d08"
          },
          "success": true
        },
        "deprecated": true
      },
      "TwoDPrintAreaInput": {
        "properties": {
          "points": {
            "items": {
              "items": {
                "type": "number"
              },
              "type": "array"
            },
            "type": "array",
            "maxItems": 4,
            "minItems": 4,
            "description": "Four [x, y] points in image coordinates."
          },
          "name": {
            "anyOf": [
              {
                "type": "string",
                "maxLength": 120
              },
              {
                "type": "null"
              }
            ],
            "description": "Optional print-area label, e.g. \"Front\" or \"Back\"."
          }
        },
        "additionalProperties": false,
        "type": "object",
        "required": [
          "points"
        ],
        "title": "TwoDPrintAreaInput",
        "description": "Deprecated name for `PhotoMockupPrintAreaInput`. Same shape, kept so a client generated from an earlier spec keeps the type name it already has.",
        "deprecated": true
      },
      "TwoDPrintAreasUpdateRequest": {
        "properties": {
          "print_areas": {
            "items": {
              "$ref": "#/components/schemas/PhotoMockupPrintAreaInput"
            },
            "type": "array",
            "maxItems": 8,
            "minItems": 0,
            "description": "Up to eight printable areas, saved row by row from the top and left to right inside each row, whatever the array order. An empty array saves the mockup without bounded placement zones."
          }
        },
        "additionalProperties": false,
        "type": "object",
        "required": [
          "print_areas"
        ],
        "title": "TwoDPrintAreasUpdateRequest",
        "description": "Deprecated name for `PhotoMockupPrintAreasUpdate`. Same shape, kept so a client generated from an earlier spec keeps the type name it already has.",
        "example": {
          "print_areas": [
            {
              "points": [
                [
                  200,
                  150
                ],
                [
                  600,
                  150
                ],
                [
                  620,
                  550
                ],
                [
                  180,
                  550
                ]
              ]
            }
          ]
        },
        "deprecated": true
      },
      "UpdateStudioConfigRequest": {
        "properties": {
          "config_version": {
            "type": "integer",
            "minimum": 0.0,
            "description": "Version you last read, which must still be the stored one.",
            "examples": [
              3
            ]
          },
          "config": {
            "$ref": "#/components/schemas/StudioConfigPatch",
            "description": "Configuration values to merge into the stored configuration."
          }
        },
        "additionalProperties": false,
        "type": "object",
        "required": [
          "config_version",
          "config"
        ],
        "title": "UpdateStudioConfigRequest",
        "example": {
          "config": {
            "accentColor": "#FF5733",
            "theme": "dark"
          },
          "config_version": 3
        }
      },
      "UploadRequest": {
        "properties": {
          "psd_file_url": {
            "type": "string",
            "minLength": 1,
            "description": "URL to the PSD file to upload. HTTP/HTTPS URLs only. Supports up to Adobe's official PSD file size limit, 300s download timeout.",
            "examples": [
              "https://example.com/heavyweight-tee.psd"
            ]
          },
          "psd_name": {
            "anyOf": [
              {
                "type": "string",
                "maxLength": 255
              },
              {
                "type": "null"
              }
            ],
            "description": "Name for the mockup template (auto-generated if not provided)",
            "examples": [
              "Heavyweight tee front"
            ]
          },
          "is_async": {
            "type": "boolean",
            "description": "If true, the upload is QUEUED and the call returns 202 immediately with a job_id (poll GET /api/v1/jobs/{job_id}, or receive a webhook if one is configured); result_url carries the new mockup_uuid on success. If false (default), the upload runs synchronously and returns the mockup.",
            "default": false
          }
        },
        "type": "object",
        "required": [
          "psd_file_url"
        ],
        "title": "UploadRequest",
        "description": "The PSD to ingest and what to call it.",
        "example": {
          "psd_file_url": "https://example.com/heavyweight-tee.psd",
          "psd_name": "Heavyweight tee front"
        }
      },
      "UploadResponse": {
        "properties": {
          "data": {
            "$ref": "#/components/schemas/UploadResponseData",
            "description": "Response data"
          },
          "success": {
            "type": "boolean",
            "description": "Success status",
            "default": true
          },
          "message": {
            "type": "string",
            "description": "Optional message about the operation",
            "default": ""
          },
          "warnings": {
            "anyOf": [
              {
                "items": {
                  "$ref": "#/components/schemas/UploadWarning"
                },
                "type": "array"
              },
              {
                "type": "null"
              }
            ],
            "description": "Non-fatal advisories about this upload (e.g. hidden smart object layers that are not exposed for personalization). Omitted when none."
          }
        },
        "type": "object",
        "required": [
          "data"
        ],
        "title": "UploadResponse",
        "description": "The ingested mockup with every layer you can address in a render.",
        "example": {
          "data": {
            "collections": [],
            "group_layers": [],
            "height": 5000,
            "name": "Heavyweight tee front",
            "smart_objects": [
              {
                "blend_mode": "multiply",
                "layer_name": "Front print",
                "name": "Front print",
                "position": {
                  "height": 3413,
                  "width": 3000,
                  "x": 512,
                  "y": 730
                },
                "print_area_presets": [
                  {
                    "name": "Default",
                    "position": {
                      "height": 3413,
                      "width": 3000,
                      "x": 0,
                      "y": 0
                    },
                    "size": {
                      "height": 3413,
                      "width": 3000
                    },
                    "thumbnails": [],
                    "uuid": "d07f5b18-2c94-4e83-a6b1-95f3c8e27a40"
                  }
                ],
                "quad": [
                  [
                    512.0,
                    742.0
                  ],
                  [
                    3512.0,
                    730.0
                  ],
                  [
                    3499.0,
                    4143.0
                  ],
                  [
                    524.0,
                    4131.0
                  ]
                ],
                "size": {
                  "height": 3413,
                  "width": 3000
                },
                "uuid": "b41a7e52-93c8-4d61-8f07-2ae5c9d04713"
              }
            ],
            "text_layers": [],
            "thumbnail": "https://cdn.sudomock.com/mockup-assets/8f2c1d90-6b4e-4a37-9e55-0d1c7a3f21b8/thumbnails/thumb_720.webp",
            "thumbnails": [
              {
                "url": "https://cdn.sudomock.com/mockup-assets/8f2c1d90-6b4e-4a37-9e55-0d1c7a3f21b8/thumbnails/thumb_720.webp",
                "width": 720
              },
              {
                "url": "https://cdn.sudomock.com/mockup-assets/8f2c1d90-6b4e-4a37-9e55-0d1c7a3f21b8/thumbnails/thumb_480.webp",
                "width": 480
              },
              {
                "url": "https://cdn.sudomock.com/mockup-assets/8f2c1d90-6b4e-4a37-9e55-0d1c7a3f21b8/thumbnails/thumb_240.webp",
                "width": 240
              }
            ],
            "uuid": "8f2c1d90-6b4e-4a37-9e55-0d1c7a3f21b8",
            "width": 4000
          },
          "message": "",
          "success": true
        }
      },
      "UploadResponseData": {
        "properties": {
          "uuid": {
            "type": "string",
            "description": "Unique identifier for the mockup",
            "examples": [
              "8f2c1d90-6b4e-4a37-9e55-0d1c7a3f21b8"
            ]
          },
          "name": {
            "type": "string",
            "description": "Name of the mockup",
            "examples": [
              "Heavyweight tee front"
            ]
          },
          "thumbnail": {
            "type": "string",
            "description": "Main thumbnail URL (720px width). Empty string if generation failed.",
            "default": "",
            "examples": [
              "https://cdn.sudomock.com/mockup-assets/8f2c1d90-6b4e-4a37-9e55-0d1c7a3f21b8/thumbnails/thumb_720.webp"
            ]
          },
          "width": {
            "anyOf": [
              {
                "type": "integer"
              },
              {
                "type": "null"
              }
            ],
            "description": "Always populated after successful upload. Represents original PSD canvas width in pixels.",
            "examples": [
              4000
            ]
          },
          "height": {
            "anyOf": [
              {
                "type": "integer"
              },
              {
                "type": "null"
              }
            ],
            "description": "Always populated after successful upload. Represents original PSD canvas height in pixels.",
            "examples": [
              5000
            ]
          },
          "smart_objects": {
            "items": {
              "$ref": "#/components/schemas/SmartObjectResponse"
            },
            "type": "array",
            "description": "List of smart objects in the PSD"
          },
          "text_layers": {
            "items": {
              "$ref": "#/components/schemas/TextLayer"
            },
            "type": "array",
            "description": "Text layers detected in the PSD. Editable layers accept text replacement at render time."
          },
          "group_layers": {
            "items": {
              "$ref": "#/components/schemas/GroupLayer"
            },
            "type": "array",
            "description": "Group layers whose outlines can be recolored. Changing a group outline affects everything inside that group; groups not listed keep their authored effects."
          },
          "collections": {
            "items": {},
            "type": "array",
            "description": "Reserved for future use. Currently always empty."
          },
          "thumbnails": {
            "items": {
              "$ref": "#/components/schemas/ThumbnailSize"
            },
            "type": "array",
            "description": "Array of thumbnail URLs at different sizes"
          }
        },
        "type": "object",
        "required": [
          "uuid",
          "name",
          "smart_objects"
        ],
        "title": "UploadResponseData",
        "description": "Data payload in upload response"
      },
      "UploadWarning": {
        "properties": {
          "code": {
            "type": "string",
            "description": "Stable advisory code (PSD_HIDDEN_SMART_OBJECTS, FREE_PSD_RETENTION, PSD_LIGHT_ADJUSTMENT_UNSUPPORTED, PSD_GRADIENT_MAP_UNSUPPORTED, PSD_NESTED_CONTENTS_UNAVAILABLE)"
          },
          "message": {
            "type": "string",
            "description": "Human-readable, non-fatal advisory"
          }
        },
        "type": "object",
        "required": [
          "code",
          "message"
        ],
        "title": "UploadWarning",
        "description": "Non-fatal advisory attached to a successful upload.\n\nFive codes today, and they are independent: one upload can earn several.\n  - PSD_LIGHT_ADJUSTMENT_UNSUPPORTED: the PSD carries a Photoshop 27.10 Light\n    adjustment layer, which renders read as plain Brightness/Contrast and so\n    drop its exposure lift (renders come out darker than Photoshop).\n  - PSD_GRADIENT_MAP_UNSUPPORTED: the PSD carries visible Gradient Map\n    adjustment layers that renders do not apply yet (a Noise gradient, a\n    color stop outside RGB, or a method other than Perceptual, Linear,\n    Classic or Smooth), so renders show the layers below without them.\n    One advisory gives the count.\n  - PSD_HIDDEN_SMART_OBJECTS: the PSD carries hidden smart object layers that\n    are not exposed for personalization.\n  - FREE_PSD_RETENTION: the account has no active subscription, so this\n    uploaded template is removed after a period without a render. A\n    subscriber never sees it.\n  - PSD_NESTED_CONTENTS_UNAVAILABLE: the contents of a smart object could\n    not be read, so the layers inside it are not offered as separate slots.\n    The smart object itself still renders as designed.\n\n`code` is stable, so integrations can switch on it. The message may be\nreworded."
      },
      "VideoOptions": {
        "properties": {
          "duration_seconds": {
            "type": "integer",
            "maximum": 15.0,
            "minimum": 1.0,
            "description": "Clip length in seconds chosen by the customer. Must be one of the supported durations; the endpoint rejects an unsupported value with 400. The credit cost scales with this value.",
            "default": 4
          },
          "audio": {
            "type": "boolean",
            "description": "Generate sound with the clip. Default OFF (muted clips are cheaper). Audio increases the credit cost on models that charge an audio premium. Note: motion='showcase' always includes sound, so the endpoint treats it as audio=true and prices it accordingly.",
            "default": false
          },
          "motion": {
            "type": "string",
            "enum": [
              "ambient",
              "showcase"
            ],
            "description": "'ambient' = subtle looping hero motion that keeps the print readable (muted unless audio=true); 'showcase' = one deliberate cinematic camera/product move, always with sound (priced as audio=true).",
            "default": "ambient"
          },
          "advanced_model": {
            "anyOf": [
              {
                "type": "string"
              },
              {
                "type": "null"
              }
            ],
            "description": "Advanced override for the automatic quality selection. Unsupported values are rejected. null = automatic (recommended)."
          }
        },
        "type": "object",
        "title": "VideoOptions",
        "description": "Animation options for a POST /renders/video request.\n\nThe still is produced from the same mockup_uuid + smart_objects payload as a\nnormal render, then animated into a short video. SudoMock picks the best video\nmodel for the image automatically; `advanced_model` is an optional override.\n\nYou choose `duration_seconds` and `audio`, and the credit cost scales with both.\n`duration_seconds` must be one of the chosen model's allowed durations, or the\nendpoint returns 400 INVALID_VIDEO_DURATION otherwise. The 1..15 range here is a\ncoarse guard; the exact allowed set depends on the model."
      },
      "VideoRenderAcceptedResponse": {
        "properties": {
          "job_id": {
            "type": "string",
            "description": "Identifier of the accepted job, used to poll its status.",
            "examples": [
              "5f1c0b2a-7d43-4e9a-8c16-0b5d3f7a2e94"
            ]
          },
          "kind": {
            "type": "string",
            "const": "video",
            "description": "The kind of work accepted, which is always a video."
          },
          "status": {
            "type": "string",
            "enum": [
              "queued",
              "dispatched",
              "running",
              "succeeded",
              "failed",
              "cancelled"
            ],
            "description": "State of the job when this response was returned."
          },
          "status_url": {
            "type": "string",
            "description": "Path to poll for this job's status.",
            "examples": [
              "/api/v1/jobs/5f1c0b2a-7d43-4e9a-8c16-0b5d3f7a2e94"
            ]
          },
          "model": {
            "type": "string",
            "description": "The video model chosen for this clip."
          },
          "outcome_tier": {
            "type": "string",
            "description": "The quality level this clip is produced at.",
            "examples": [
              "standard"
            ]
          },
          "estimated_credits": {
            "anyOf": [
              {
                "type": "integer"
              },
              {
                "type": "null"
              }
            ],
            "description": "Credits this clip costs, which is null only when an accepted job's original quote is no longer known.",
            "examples": [
              38
            ]
          },
          "duration_seconds": {
            "type": "integer",
            "description": "Length of the clip in seconds.",
            "examples": [
              4
            ]
          },
          "audio": {
            "type": "boolean",
            "description": "Whether the clip is produced with sound.",
            "examples": [
              false
            ]
          }
        },
        "type": "object",
        "required": [
          "job_id",
          "kind",
          "status",
          "status_url",
          "model",
          "outcome_tier",
          "duration_seconds",
          "audio"
        ],
        "title": "VideoRenderAcceptedResponse",
        "description": "Acknowledgement that a video mockup was accepted and is being produced.",
        "example": {
          "audio": false,
          "duration_seconds": 4,
          "estimated_credits": 38,
          "job_id": "5f1c0b2a-7d43-4e9a-8c16-0b5d3f7a2e94",
          "kind": "video",
          "model": "veo-3.1-fast",
          "outcome_tier": "standard",
          "status": "queued",
          "status_url": "/api/v1/jobs/5f1c0b2a-7d43-4e9a-8c16-0b5d3f7a2e94"
        }
      },
      "VideoRenderRequest": {
        "properties": {
          "mockup_uuid": {
            "anyOf": [
              {
                "type": "string",
                "pattern": "^[0-9a-f]{8}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{12}$"
              },
              {
                "type": "null"
              }
            ],
            "description": "RENDER MODE: UUID of the mockup to animate (from GET /api/v1/psd-mockups or POST /api/v1/psd/upload). Required in render mode; omit in raw-image mode."
          },
          "smart_objects": {
            "anyOf": [
              {
                "items": {
                  "$ref": "#/components/schemas/SmartObjectInput"
                },
                "type": "array",
                "minItems": 1
              },
              {
                "type": "null"
              }
            ],
            "description": "RENDER MODE: smart objects with their assets, identical to a still render (at least 1 required). Required in render mode; omit in raw-image mode."
          },
          "export_options": {
            "$ref": "#/components/schemas/ExportOptions",
            "description": "RENDER MODE: still-render export configuration (the i2v input frame). Format/size/quality. Ignored in raw-image mode."
          },
          "image_url": {
            "anyOf": [
              {
                "type": "string"
              },
              {
                "type": "null"
              }
            ],
            "description": "RAW-IMAGE MODE: a public https png/jpg URL to animate directly (general image-to-video, no render). Supply this OR (mockup_uuid + smart_objects), never both."
          },
          "video": {
            "$ref": "#/components/schemas/VideoOptions",
            "description": "Animation options (duration, audio, motion, optional advanced_model override)."
          },
          "webhook": {
            "anyOf": [
              {
                "additionalProperties": true,
                "type": "object"
              },
              {
                "type": "null"
              }
            ],
            "description": "Completion events (video.succeeded, video.failed) are delivered to the webhook endpoints on your account that subscribe to them. GET /api/v1/jobs/{job_id} stays the source of truth."
          }
        },
        "type": "object",
        "title": "VideoRenderRequest",
        "description": "Request body for POST /api/v1/renders/video.\n\nSupply exactly one of two input modes. Render mode (mockup_uuid and\nsmart_objects, optionally export_options) mirrors a still render: the\nstill is produced first, then animated. Raw-image mode\n(image_url) animates a public https png or jpg directly with no render\nstep, and the render fields are ignored.\n\nBoth modes take the video animation options and an optional completion\nwebhook. The call always queues a job; poll GET /api/v1/jobs/{job_id} for\nthe result. Sending both modes, or neither, returns 400.",
        "example": {
          "mockup_uuid": "123e4567-e89b-12d3-a456-426614174000",
          "smart_objects": [
            {
              "asset": {
                "fit": "fill",
                "url": "https://example.com/user-design.png"
              },
              "uuid": "223e4567-e89b-12d3-a456-426614174001"
            }
          ],
          "video": {
            "audio": false,
            "duration_seconds": 4,
            "motion": "ambient",
            "advanced_model": null
          }
        }
      },
      "WebhookDeliveryDetailResponse": {
        "properties": {
          "id": {
            "type": "string",
            "description": "Unique identifier for this delivery.",
            "examples": [
              "3d682132-5477-4ffc-b33d-6e750c9c9f1f"
            ]
          },
          "endpoint_id": {
            "type": "string",
            "description": "Identifier of the webhook endpoint this delivery was sent to.",
            "examples": [
              "b5cd6284-f6a0-4cfc-94df-781353e30dfd"
            ]
          },
          "job_id": {
            "type": "string",
            "description": "Identifier of the job this event was raised for.",
            "examples": [
              "4a4bfe21-d9d2-43a4-9877-b6ca4aec4349"
            ]
          },
          "event_type": {
            "type": "string",
            "description": "Event type this delivery carries, such as render.succeeded.",
            "examples": [
              "render.succeeded"
            ]
          },
          "status": {
            "type": "string",
            "description": "Current state of this delivery, such as delivered or failed.",
            "examples": [
              "failed"
            ]
          },
          "http_status": {
            "anyOf": [
              {
                "type": "integer"
              },
              {
                "type": "null"
              }
            ],
            "description": "HTTP status code your endpoint returned on the latest attempt.",
            "examples": [
              500
            ]
          },
          "attempt": {
            "type": "integer",
            "description": "Attempt counter for this delivery, rising with each retry.",
            "examples": [
              0
            ]
          },
          "last_error": {
            "anyOf": [
              {
                "type": "string"
              },
              {
                "type": "null"
              }
            ],
            "description": "Error recorded for the latest attempt.",
            "examples": [
              "non-2xx response: 500"
            ]
          },
          "created_at": {
            "type": "string",
            "format": "date-time",
            "description": "Time this delivery was first recorded.",
            "examples": [
              "2026-09-18T09:24:12.615000Z"
            ]
          },
          "updated_at": {
            "anyOf": [
              {
                "type": "string",
                "format": "date-time"
              },
              {
                "type": "null"
              }
            ],
            "description": "Time this delivery was last updated.",
            "examples": [
              "2026-09-18T09:24:12.983000Z"
            ]
          },
          "request_body": {
            "anyOf": [
              {
                "type": "string"
              },
              {
                "type": "null"
              }
            ],
            "description": "The JSON body sent to your endpoint on the latest attempt.",
            "examples": [
              "{\"created_at\":\"2026-09-18T09:24:11.482713+00:00\",\"error\":null,\"event\":\"render.succeeded\",\"job_id\":\"4a4bfe21-d9d2-43a4-9877-b6ca4aec4349\",\"kind\":\"render\",\"result_url\":\"https://cdn.sudomock.com/mockup-assets/renders/c315f78f-d2c7-4541-b240-a9372842de94/render_8f2c1d4e.webp\",\"status\":\"succeeded\"}"
            ]
          },
          "request_headers": {
            "anyOf": [
              {
                "type": "string"
              },
              {
                "type": "null"
              }
            ],
            "description": "Headers sent with the latest attempt, as a JSON string.",
            "examples": [
              "{\"Content-Type\":\"application/json\",\"User-Agent\":\"SudoMock-Webhook/1.0\",\"X-SudoMock-Signature\":\"2b4ddbe7024e2e0e732fb27374c3e0dedda3dbf2392abe78e9785c836f54832b\",\"X-SudoMock-Timestamp\":\"1789723451\"}"
            ]
          },
          "response_body": {
            "anyOf": [
              {
                "type": "string"
              },
              {
                "type": "null"
              }
            ],
            "description": "Body your endpoint returned on a failed or dead attempt.",
            "examples": [
              "Internal Server Error"
            ]
          },
          "response_headers": {
            "anyOf": [
              {
                "type": "string"
              },
              {
                "type": "null"
              }
            ],
            "description": "Headers your endpoint returned on a failed or dead attempt, as a JSON string.",
            "examples": [
              "{\"content-type\":\"text/plain;charset=UTF-8\"}"
            ]
          }
        },
        "type": "object",
        "required": [
          "id",
          "endpoint_id",
          "job_id",
          "event_type",
          "status",
          "attempt",
          "created_at"
        ],
        "title": "WebhookDeliveryDetailResponse",
        "description": "A single delivery row WITH the captured request/response detail.\n\nReturned ONLY by the per-delivery detail endpoint; the list endpoints\n(/deliveries, /events) never carry these large fields. Capture rules (latest attempt; a retry overwrites the\nsame row):\n  - request_body / request_headers  -> captured on EVERY delivery attempt.\n  - response_body / response_headers -> captured ONLY on failed/dead attempts\n    (NULL on success, because a 2xx body is intentionally not stored). response_body\n    is truncated to 16384 chars.\n\nRequest and response headers are returned as JSON strings.",
        "example": {
          "attempt": 2,
          "created_at": "2026-09-18T09:24:12.615000Z",
          "endpoint_id": "b5cd6284-f6a0-4cfc-94df-781353e30dfd",
          "event_type": "render.succeeded",
          "http_status": 500,
          "id": "3d682132-5477-4ffc-b33d-6e750c9c9f1f",
          "job_id": "4a4bfe21-d9d2-43a4-9877-b6ca4aec4349",
          "last_error": "non-2xx response: 500",
          "request_body": "{\"created_at\":\"2026-09-18T09:24:11.482713+00:00\",\"error\":null,\"event\":\"render.succeeded\",\"job_id\":\"4a4bfe21-d9d2-43a4-9877-b6ca4aec4349\",\"kind\":\"render\",\"result_url\":\"https://cdn.sudomock.com/mockup-assets/renders/c315f78f-d2c7-4541-b240-a9372842de94/render_8f2c1d4e.webp\",\"status\":\"succeeded\"}",
          "request_headers": "{\"Content-Type\":\"application/json\",\"User-Agent\":\"SudoMock-Webhook/1.0\",\"X-SudoMock-Signature\":\"2b4ddbe7024e2e0e732fb27374c3e0dedda3dbf2392abe78e9785c836f54832b\",\"X-SudoMock-Timestamp\":\"1789723451\"}",
          "response_body": "Internal Server Error",
          "response_headers": "{\"content-type\":\"text/plain;charset=UTF-8\"}",
          "status": "failed",
          "updated_at": "2026-09-18T09:25:47.201000Z"
        }
      },
      "WebhookDeliveryReplayFailedResponse": {
        "properties": {
          "status": {
            "type": "string",
            "description": "Confirms the failed deliveries were accepted and will be sent to your endpoint again.",
            "examples": [
              "enqueued"
            ]
          },
          "count": {
            "type": "integer",
            "description": "How many failed deliveries were picked up to be sent again.",
            "examples": [
              7
            ]
          }
        },
        "type": "object",
        "required": [
          "status",
          "count"
        ],
        "title": "WebhookDeliveryReplayFailedResponse",
        "description": "Acknowledgement returned when an endpoint's failed deliveries are accepted for a resend.",
        "example": {
          "count": 7,
          "status": "enqueued"
        }
      },
      "WebhookDeliveryReplayResponse": {
        "properties": {
          "status": {
            "type": "string",
            "description": "Confirms the delivery was accepted and will be sent to your endpoint again.",
            "examples": [
              "enqueued"
            ]
          },
          "delivery_id": {
            "type": "string",
            "description": "Identifier of the delivery being sent again, the one you asked for.",
            "examples": [
              "3d682132-5477-4ffc-b33d-6e750c9c9f1f"
            ]
          }
        },
        "type": "object",
        "required": [
          "status",
          "delivery_id"
        ],
        "title": "WebhookDeliveryReplayResponse",
        "description": "Acknowledgement returned when one delivery is accepted for a resend.",
        "example": {
          "delivery_id": "3d682132-5477-4ffc-b33d-6e750c9c9f1f",
          "status": "enqueued"
        }
      },
      "WebhookDeliveryResponse": {
        "properties": {
          "id": {
            "type": "string",
            "description": "Unique identifier for this delivery.",
            "examples": [
              "3d682132-5477-4ffc-b33d-6e750c9c9f1f"
            ]
          },
          "endpoint_id": {
            "type": "string",
            "description": "Identifier of the webhook endpoint this delivery was sent to.",
            "examples": [
              "b5cd6284-f6a0-4cfc-94df-781353e30dfd"
            ]
          },
          "job_id": {
            "type": "string",
            "description": "Identifier of the job this event was raised for.",
            "examples": [
              "4a4bfe21-d9d2-43a4-9877-b6ca4aec4349"
            ]
          },
          "event_type": {
            "type": "string",
            "description": "Event type this delivery carries, such as render.succeeded.",
            "examples": [
              "render.succeeded"
            ]
          },
          "status": {
            "type": "string",
            "description": "Current state of this delivery, such as delivered or failed.",
            "examples": [
              "delivered"
            ]
          },
          "http_status": {
            "anyOf": [
              {
                "type": "integer"
              },
              {
                "type": "null"
              }
            ],
            "description": "HTTP status code your endpoint returned on the latest attempt.",
            "examples": [
              200
            ]
          },
          "attempt": {
            "type": "integer",
            "description": "Attempt counter for this delivery, rising with each retry.",
            "examples": [
              0
            ]
          },
          "last_error": {
            "anyOf": [
              {
                "type": "string"
              },
              {
                "type": "null"
              }
            ],
            "description": "Error recorded for the latest attempt."
          },
          "created_at": {
            "type": "string",
            "format": "date-time",
            "description": "Time this delivery was first recorded.",
            "examples": [
              "2026-09-18T09:24:12.615000Z"
            ]
          },
          "updated_at": {
            "anyOf": [
              {
                "type": "string",
                "format": "date-time"
              },
              {
                "type": "null"
              }
            ],
            "description": "Time this delivery was last updated.",
            "examples": [
              "2026-09-18T09:24:12.983000Z"
            ]
          }
        },
        "type": "object",
        "required": [
          "id",
          "endpoint_id",
          "job_id",
          "event_type",
          "status",
          "attempt",
          "created_at"
        ],
        "title": "WebhookDeliveryResponse",
        "description": "A single delivery-attempt log row.",
        "example": {
          "attempt": 0,
          "created_at": "2026-09-18T09:24:12.615000Z",
          "endpoint_id": "b5cd6284-f6a0-4cfc-94df-781353e30dfd",
          "event_type": "render.succeeded",
          "http_status": 200,
          "id": "3d682132-5477-4ffc-b33d-6e750c9c9f1f",
          "job_id": "4a4bfe21-d9d2-43a4-9877-b6ca4aec4349",
          "status": "delivered",
          "updated_at": "2026-09-18T09:24:12.983000Z",
          "last_error": null
        }
      },
      "WebhookEndpointCreateRequest": {
        "properties": {
          "url": {
            "type": "string",
            "maxLength": 2048,
            "minLength": 1,
            "description": "https endpoint URL"
          },
          "description": {
            "anyOf": [
              {
                "type": "string",
                "maxLength": 255
              },
              {
                "type": "null"
              }
            ],
            "description": "Optional label that helps you recognize this endpoint."
          },
          "event_types": {
            "items": {
              "type": "string",
              "enum": [
                "render.succeeded",
                "render.failed",
                "upload.succeeded",
                "video.succeeded",
                "video.failed",
                "2d_mockup.ready",
                "2d_mockup.rejected",
                "2d_mockup.failed",
                "2d_render.succeeded",
                "2d_render.failed",
                "photo_mockup.ready",
                "photo_mockup.rejected",
                "photo_mockup.failed",
                "photo_mockup_render.succeeded",
                "photo_mockup_render.failed",
                "webhook.test"
              ]
            },
            "type": "array",
            "description": "Subscribed event types; empty = all events (wildcard)."
          },
          "event_naming": {
            "anyOf": [
              {
                "type": "string",
                "enum": [
                  "legacy",
                  "current"
                ]
              },
              {
                "type": "null"
              }
            ],
            "description": "Which spelling of the photo-mockup events this endpoint receives: 'current' (photo_mockup.*, photo_mockup_render.*) or 'legacy' (2d_mockup.*, 2d_render.*). The payload's kind follows. Omit it and the endpoint is pinned to the spelling event_types is written in: the family names for a list that subscribes to them, otherwise 'legacy', the spelling this contract publishes."
          }
        },
        "type": "object",
        "required": [
          "url"
        ],
        "title": "WebhookEndpointCreateRequest",
        "description": "Create a webhook endpoint.",
        "example": {
          "description": "Production render notifications",
          "event_types": [
            "render.succeeded",
            "render.failed"
          ],
          "url": "https://your-app.example.com/hooks/sudomock"
        }
      },
      "WebhookEndpointResponse": {
        "properties": {
          "id": {
            "type": "string",
            "description": "Unique identifier for the webhook endpoint.",
            "examples": [
              "b5cd6284-f6a0-4cfc-94df-781353e30dfd"
            ]
          },
          "url": {
            "type": "string",
            "description": "The https URL that receives this endpoint's events.",
            "examples": [
              "https://your-app.example.com/hooks/sudomock"
            ]
          },
          "secret": {
            "type": "string",
            "description": "Masked: whsec_****<last4>",
            "examples": [
              "whsec_****e865"
            ]
          },
          "description": {
            "anyOf": [
              {
                "type": "string"
              },
              {
                "type": "null"
              }
            ],
            "description": "Your label for this endpoint.",
            "examples": [
              "Production render notifications"
            ]
          },
          "event_types": {
            "items": {
              "type": "string"
            },
            "type": "array",
            "description": "Event types this endpoint receives; an empty list means every event.",
            "examples": [
              [
                "render.succeeded",
                "render.failed"
              ]
            ]
          },
          "enabled": {
            "type": "boolean",
            "description": "Whether this endpoint currently receives events.",
            "examples": [
              true
            ]
          },
          "event_naming": {
            "type": "string",
            "description": "The event-name spelling this endpoint is pinned to: 'legacy' or 'current'.",
            "default": "legacy"
          },
          "created_at": {
            "type": "string",
            "format": "date-time",
            "description": "Time the endpoint was created.",
            "examples": [
              "2026-09-18T09:24:11.482713Z"
            ]
          },
          "updated_at": {
            "anyOf": [
              {
                "type": "string",
                "format": "date-time"
              },
              {
                "type": "null"
              }
            ],
            "description": "Time the endpoint was last updated.",
            "examples": [
              "2026-09-18T09:31:02.117845Z"
            ]
          }
        },
        "type": "object",
        "required": [
          "id",
          "url",
          "secret",
          "enabled",
          "created_at"
        ],
        "title": "WebhookEndpointResponse",
        "description": "Endpoint metadata with the secret MASKED (`whsec_****<last4>`).",
        "example": {
          "created_at": "2026-09-18T09:24:11.482713Z",
          "description": "Production render notifications",
          "enabled": true,
          "event_naming": "legacy",
          "event_types": [
            "render.succeeded",
            "render.failed"
          ],
          "id": "b5cd6284-f6a0-4cfc-94df-781353e30dfd",
          "secret": "whsec_****e865",
          "updated_at": "2026-09-18T09:31:02.117845Z",
          "url": "https://your-app.example.com/hooks/sudomock"
        }
      },
      "WebhookEndpointSecretResponse": {
        "properties": {
          "id": {
            "type": "string",
            "description": "Unique identifier for the webhook endpoint.",
            "examples": [
              "b5cd6284-f6a0-4cfc-94df-781353e30dfd"
            ]
          },
          "url": {
            "type": "string",
            "description": "The https URL that receives this endpoint's events.",
            "examples": [
              "https://your-app.example.com/hooks/sudomock"
            ]
          },
          "secret": {
            "type": "string",
            "description": "FULL signing secret. Shown only once.",
            "examples": [
              "whsec_cb79146988c2f928cc0760c737c67368080948cdadf7a20c14311290682ee865"
            ]
          },
          "description": {
            "anyOf": [
              {
                "type": "string"
              },
              {
                "type": "null"
              }
            ],
            "description": "Your label for this endpoint.",
            "examples": [
              "Production render notifications"
            ]
          },
          "event_types": {
            "items": {
              "type": "string"
            },
            "type": "array",
            "description": "Event types this endpoint receives; an empty list means every event.",
            "examples": [
              [
                "render.succeeded",
                "render.failed"
              ]
            ]
          },
          "enabled": {
            "type": "boolean",
            "description": "Whether this endpoint currently receives events.",
            "examples": [
              true
            ]
          },
          "event_naming": {
            "type": "string",
            "description": "The event-name spelling this endpoint is pinned to: 'legacy' or 'current'.",
            "default": "legacy"
          },
          "created_at": {
            "type": "string",
            "format": "date-time",
            "description": "Time the endpoint was created.",
            "examples": [
              "2026-09-18T09:24:11.482713Z"
            ]
          },
          "updated_at": {
            "anyOf": [
              {
                "type": "string",
                "format": "date-time"
              },
              {
                "type": "null"
              }
            ],
            "description": "Time the endpoint was last updated.",
            "examples": [
              "2026-09-18T09:31:02.117845Z"
            ]
          }
        },
        "type": "object",
        "required": [
          "id",
          "url",
          "secret",
          "enabled",
          "created_at"
        ],
        "title": "WebhookEndpointSecretResponse",
        "description": "Returned ONLY by create + rotate-secret: the FULL plaintext secret.\n\nOverrides the masked `secret` field with the real value (shown once).",
        "example": {
          "created_at": "2026-09-18T09:24:11.482713Z",
          "description": "Production render notifications",
          "enabled": true,
          "event_naming": "legacy",
          "event_types": [
            "render.succeeded",
            "render.failed"
          ],
          "id": "b5cd6284-f6a0-4cfc-94df-781353e30dfd",
          "secret": "whsec_cb79146988c2f928cc0760c737c67368080948cdadf7a20c14311290682ee865",
          "updated_at": "2026-09-18T09:24:11.482713Z",
          "url": "https://your-app.example.com/hooks/sudomock"
        }
      },
      "WebhookEndpointUpdateRequest": {
        "properties": {
          "url": {
            "anyOf": [
              {
                "type": "string",
                "maxLength": 2048,
                "minLength": 1
              },
              {
                "type": "null"
              }
            ],
            "description": "New https URL that receives this endpoint's events."
          },
          "description": {
            "anyOf": [
              {
                "type": "string",
                "maxLength": 255
              },
              {
                "type": "null"
              }
            ],
            "description": "New label for this endpoint."
          },
          "event_types": {
            "anyOf": [
              {
                "items": {
                  "type": "string",
                  "enum": [
                    "render.succeeded",
                    "render.failed",
                    "upload.succeeded",
                    "video.succeeded",
                    "video.failed",
                    "2d_mockup.ready",
                    "2d_mockup.rejected",
                    "2d_mockup.failed",
                    "2d_render.succeeded",
                    "2d_render.failed",
                    "photo_mockup.ready",
                    "photo_mockup.rejected",
                    "photo_mockup.failed",
                    "photo_mockup_render.succeeded",
                    "photo_mockup_render.failed",
                    "webhook.test"
                  ]
                },
                "type": "array"
              },
              {
                "type": "null"
              }
            ],
            "description": "New list of event types for this endpoint; leave it empty to receive every event."
          },
          "enabled": {
            "anyOf": [
              {
                "type": "boolean"
              },
              {
                "type": "null"
              }
            ],
            "description": "Set to false to pause deliveries, or true to resume them."
          },
          "event_naming": {
            "anyOf": [
              {
                "type": "string",
                "enum": [
                  "legacy",
                  "current"
                ]
              },
              {
                "type": "null"
              }
            ],
            "description": "Re-pin the endpoint to 'current' or 'legacy' event names once its handler is ready for them."
          }
        },
        "type": "object",
        "title": "WebhookEndpointUpdateRequest",
        "description": "Partial update. Any subset of fields; all optional.",
        "example": {
          "description": "Production render notifications",
          "enabled": true
        }
      },
      "WebhookOverviewDay": {
        "properties": {
          "date": {
            "type": "string",
            "description": "Calendar day these counts belong to.",
            "examples": [
              "2026-09-18"
            ]
          },
          "total": {
            "type": "integer",
            "description": "How many deliveries were recorded on this day.",
            "examples": [
              128
            ]
          },
          "failed": {
            "type": "integer",
            "description": "How many of that day's deliveries ended without your endpoint accepting them.",
            "examples": [
              3
            ]
          }
        },
        "additionalProperties": true,
        "type": "object",
        "required": [
          "date",
          "total",
          "failed"
        ],
        "title": "WebhookOverviewDay",
        "description": "One day of delivery counts inside the overview window."
      },
      "WebhookOverviewEndpointRollup": {
        "properties": {
          "total": {
            "type": "integer",
            "description": "How many deliveries this endpoint received in the window.",
            "examples": [
              420
            ]
          },
          "failed": {
            "type": "integer",
            "description": "How many of this endpoint's deliveries ended without being accepted.",
            "examples": [
              12
            ]
          },
          "last_activity": {
            "anyOf": [
              {
                "type": "string"
              },
              {
                "type": "null"
              }
            ],
            "description": "When this endpoint last received a delivery, left empty if it never has.",
            "examples": [
              "2026-09-18T09:24:12.615000Z"
            ]
          }
        },
        "additionalProperties": true,
        "type": "object",
        "required": [
          "total",
          "failed"
        ],
        "title": "WebhookOverviewEndpointRollup",
        "description": "One endpoint's share of the overview window."
      },
      "WebhookOverviewResponse": {
        "properties": {
          "global": {
            "$ref": "#/components/schemas/WebhookOverviewTotals",
            "description": "Combined counts for the window, together with the day by day series."
          },
          "by_endpoint": {
            "additionalProperties": {
              "$ref": "#/components/schemas/WebhookOverviewEndpointRollup"
            },
            "type": "object",
            "description": "Counts for each endpoint you own, keyed by its id."
          }
        },
        "additionalProperties": true,
        "type": "object",
        "required": [
          "global",
          "by_endpoint"
        ],
        "title": "WebhookOverviewResponse",
        "description": "Delivery rollup covering every endpoint you own, for the window you asked for.",
        "example": {
          "by_endpoint": {
            "b5cd6284-f6a0-4cfc-94df-781353e30dfd": {
              "failed": 12,
              "last_activity": "2026-09-18T09:24:12.615000Z",
              "total": 420
            },
            "e91b7a10-2c4d-4f83-9a55-1d0f6b8c3e27": {
              "failed": 7,
              "last_activity": "2026-09-18T08:57:44.208000Z",
              "total": 422
            }
          },
          "global": {
            "days": [
              {
                "date": "2026-09-17",
                "failed": 7,
                "total": 401
              },
              {
                "date": "2026-09-18",
                "failed": 12,
                "total": 441
              }
            ],
            "failed": 19,
            "total": 842
          }
        }
      },
      "WebhookOverviewTotals": {
        "properties": {
          "total": {
            "type": "integer",
            "description": "How many deliveries were recorded across the window.",
            "examples": [
              842
            ]
          },
          "failed": {
            "type": "integer",
            "description": "How many of those deliveries ended without your endpoint accepting them.",
            "examples": [
              19
            ]
          },
          "days": {
            "items": {
              "$ref": "#/components/schemas/WebhookOverviewDay"
            },
            "type": "array",
            "description": "Day by day counts ready to plot, where a day with no deliveries can be missing."
          }
        },
        "additionalProperties": true,
        "type": "object",
        "required": [
          "total",
          "failed",
          "days"
        ],
        "title": "WebhookOverviewTotals",
        "description": "Delivery counts for the whole window, across every endpoint you own."
      },
      "WebhookTestEventResponse": {
        "properties": {
          "status": {
            "type": "string",
            "description": "Confirms the test event was accepted and is on its way to your endpoint.",
            "examples": [
              "enqueued"
            ]
          },
          "event_type": {
            "type": "string",
            "description": "Event type the test carries, so your handler can tell it apart from real traffic.",
            "examples": [
              "webhook.test"
            ]
          },
          "job_id": {
            "type": "string",
            "description": "Identifier this test event is raised for, which you can match against the delivery log.",
            "examples": [
              "4a4bfe21-d9d2-43a4-9877-b6ca4aec4349"
            ]
          }
        },
        "type": "object",
        "required": [
          "status",
          "event_type",
          "job_id"
        ],
        "title": "WebhookTestEventResponse",
        "description": "Acknowledgement returned when a test event is accepted for delivery.",
        "example": {
          "event_type": "webhook.test",
          "job_id": "4a4bfe21-d9d2-43a4-9877-b6ca4aec4349",
          "status": "enqueued"
        }
      }
    },
    "securitySchemes": {
      "ApiKeyAuth": {
        "type": "apiKey",
        "in": "header",
        "name": "x-api-key",
        "description": "API key with sm_ prefix. Get your key at https://sudomock.com/dashboard/api-keys"
      }
    }
  },
  "tags": [
    {
      "name": "PSD mockups",
      "description": "Turn a Photoshop file into a reusable mockup, then render it."
    },
    {
      "name": "Photo mockups",
      "description": "Turn a product photo into a reusable mockup, then render artwork onto it."
    },
    {
      "name": "Video mockups",
      "description": "Render a mockup as a short video."
    },
    {
      "name": "Fonts",
      "description": "Upload and manage the fonts available to text layers."
    },
    {
      "name": "Background removal",
      "description": "Isolate a subject from its background as a standalone step."
    },
    {
      "name": "Studio",
      "description": "Open an embedded editor session and read what the customer produced in it."
    },
    {
      "name": "Webhook endpoints",
      "description": "Register signed endpoints and manage their secrets."
    },
    {
      "name": "Webhook deliveries",
      "description": "Inspect, replay and retry what those endpoints received."
    },
    {
      "name": "Jobs",
      "description": "Poll queued renders and read their results."
    },
    {
      "name": "Account",
      "description": "Read the current account, its plan and its remaining credits."
    }
  ],
  "servers": [
    {
      "url": "https://api.sudomock.com",
      "description": "Production"
    }
  ]
}