Every API here is available over the APIs.io API and to AI agents over MCP.
openapi: 3.2.0
info:
title: SudoMock Jobs 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.
Every 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
servers:
- url: https://api.sudomock.com
description: Production
tags:
- name: Jobs
description: Poll queued renders and read their results.
paths:
/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;
using System.Text;
var request = new HttpRequestMessage(HttpMethod.Get, "https://api.sudomock.com/api/v1/jobs");
request.Headers.Add("x-api-key", "sm_your_api_key");
var client = new HttpClient();
var response = await client.SendAsync(request);
Console.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;
using System.Text;
var request = new HttpRequestMessage(HttpMethod.Get, "https://api.sudomock.com/api/v1/jobs/3fa85f64-5717-4562-b3fc-2c963f66afa6");
request.Headers.Add("x-api-key", "sm_your_api_key");
var client = new HttpClient();
var response = await client.SendAsync(request);
Console.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\""
components:
schemas:
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
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.
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.
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
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
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.
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