{
  "$schema": "https://json-schema.org/draft/2020-12/schema",
  "$id": "https://artifacts.apis.io/poof-bg/json-schema/poof-bg-job-schema.json",
  "title": "Job",
  "description": "A video background removal job, as returned with 202 by POST /remove and by GET /jobs/{id}.",
  "x-generated": "2026-10-31",
  "x-method": "derived",
  "x-generator": "derive-json-schema.py",
  "x-source": "openapi/poof-bg-openapi.json#/components/schemas/Job",
  "type": "object",
  "required": [
    "id",
    "status",
    "progress",
    "created_at",
    "started_at",
    "completed_at",
    "duration_seconds",
    "fps",
    "width",
    "height",
    "frames",
    "credits",
    "format",
    "channels",
    "status_url",
    "result_url",
    "expires_at",
    "error",
    "stats"
  ],
  "properties": {
    "id": {
      "type": "string",
      "description": "Job ID, prefixed with job_"
    },
    "status": {
      "type": "string",
      "enum": [
        "queued",
        "processing",
        "completed",
        "failed"
      ],
      "description": "Job state. queued and processing are transient; completed and failed are terminal."
    },
    "progress": {
      "type": "number",
      "minimum": 0,
      "maximum": 1,
      "description": "Fraction of the video processed so far, 0 to 1"
    },
    "created_at": {
      "type": "string",
      "format": "date-time",
      "description": "When the job was accepted"
    },
    "started_at": {
      "type": [
        "string",
        "null"
      ],
      "format": "date-time",
      "description": "When processing began; null while queued"
    },
    "completed_at": {
      "type": [
        "string",
        "null"
      ],
      "format": "date-time",
      "description": "When the job reached completed or failed; null until then"
    },
    "duration_seconds": {
      "type": "number",
      "description": "Source video duration in seconds"
    },
    "fps": {
      "type": "number",
      "description": "Source frame rate"
    },
    "width": {
      "type": "integer",
      "description": "Source video width in pixels"
    },
    "height": {
      "type": "integer",
      "description": "Source video height in pixels"
    },
    "frames": {
      "type": "integer",
      "description": "Number of frames in the source video"
    },
    "credits": {
      "type": "integer",
      "description": "Credits charged for this job (5 per second of source video, rounded up; 10 per second above 30 fps). Animated GIF input is billed at 5 credits per second whatever its frame rate. Refunded automatically if the job fails."
    },
    "format": {
      "type": "string",
      "enum": [
        "webm",
        "mov",
        "mp4",
        "gif"
      ],
      "description": "Requested output format"
    },
    "channels": {
      "type": "string",
      "enum": [
        "rgba",
        "rgb",
        "alpha"
      ],
      "description": "Requested output channels"
    },
    "status_url": {
      "type": "string",
      "format": "uri",
      "description": "URL of the job; GET it to poll for progress"
    },
    "result_url": {
      "type": [
        "string",
        "null"
      ],
      "format": "uri",
      "description": "Direct download URL of the result on the Poof CDN (https://cdn.poof.bg/...). Needs no API key; anyone with the link can download the file until expires_at. Served with Content-Disposition: attachment; filename=result.<ext>. Null until the job is completed."
    },
    "expires_at": {
      "type": [
        "string",
        "null"
      ],
      "format": "date-time",
      "description": "When the result is deleted, 24 hours after completion; null until the job is completed. After this time result_url stops working and the job returns 404 job_not_found."
    },
    "error": {
      "type": [
        "object",
        "null"
      ],
      "description": "Set when status is failed, null otherwise",
      "required": [
        "code",
        "message"
      ],
      "properties": {
        "code": {
          "type": "string",
          "description": "Machine-readable error code"
        },
        "message": {
          "type": "string",
          "description": "Human-readable description of the failure"
        }
      }
    },
    "stats": {
      "type": [
        "object",
        "null"
      ],
      "additionalProperties": true,
      "description": "Processing statistics, set once the job is completed and null otherwise. output_width, output_height and processing_seconds are guaranteed (the output is capped at 4096 px on the longest side (4K), or smaller with size; width and height above are the source dimensions). Other keys are informational and may change.",
      "properties": {
        "output_width": {
          "type": "integer",
          "description": "Output width in pixels"
        },
        "output_height": {
          "type": "integer",
          "description": "Output height in pixels"
        },
        "processing_seconds": {
          "type": "number",
          "description": "Wall-clock processing time, from started_at to completed_at"
        }
      }
    }
  }
}