Browse Docs
On This Page

Models Reference

This page lists the main public response models used by the API.

ErrorResponse

All error responses share this envelope. Some errors include additional context fields.

FieldTypeRequiredDescription
errorstringyesMachine-readable error code (e.g. "request.empty_file")
detailstring|nullyesHuman-readable explanation

Additional fields may appear depending on the error code. See Errors for full examples.

Example:

{
  "error": "request.invalid_extension",
  "detail": "File extension '.mp3' is not accepted by this compressor."
}

JobAcceptedResponse (POST /compress)

FieldTypeRequiredDescription
idstringyesUnique job identifier (GUIDv7)
statusstringyesInitial status ("Queued")
fileNamestringyesOriginal filename stem (without extension)
formatstringyesCompression format (e.g. "jpg", "png", "pdf")
stats.inputP50Bytesnumber|nullyesMedian input size from recent jobs (null if no history)
stats.inputMeanBytesnumber|nullyesMean input size from recent jobs (null if no history)
stats.sampleCountnumberyesNumber of recent jobs in the stats sample
stats.asOfUtcstring|nullnoWhen the stats snapshot was computed (ISO 8601)
stats.validUntilUtcstring|nullnoWhen the stats snapshot expires (ISO 8601)
timeline.uploadStartedAtstringyesUpload start timestamp (ISO 8601)
timeline.uploadFinishedAtstringyesUpload finish timestamp (ISO 8601)
timeline.queuedAtstringyesWhen the job entered the queue (ISO 8601)
queue.poolstringyesWorker pool name (e.g. "ImagePool")
queue.positionnumberyesPosition in the queue
queue.weightnumberyesScheduling weight for this job
queue.totalQueuednumberyesTotal jobs currently queued in this pool
queue.estimatestring|nullnoEstimated wait time (e.g. "< 5s")
metrics.inputBytesnumber|nullyesInput file size in bytes (null if not yet measured)
metrics.uploadMsnumberyesUpload duration in milliseconds
metrics.processingMsnumberyesProcessing duration in milliseconds (0 at submission)
metrics.totalMsnumberyesTotal elapsed time in milliseconds

Example -- JPG compression accepted:

{
  "id": "0195e2a0-1234-7000-8000-000000000001",
  "status": "Queued",
  "fileName": "photo",
  "format": "jpg",
  "stats": {
    "inputP50Bytes": 4200000,
    "inputMeanBytes": 5100000,
    "sampleCount": 128,
    "asOfUtc": "2026-02-23T10:00:00Z",
    "validUntilUtc": "2026-02-23T10:05:00Z"
  },
  "timeline": {
    "uploadStartedAt": "2026-02-23T10:01:00.000Z",
    "uploadFinishedAt": "2026-02-23T10:01:00.450Z",
    "queuedAt": "2026-02-23T10:01:00.460Z"
  },
  "queue": {
    "pool": "ImagePool",
    "position": 3,
    "weight": 2.5,
    "totalQueued": 7,
    "estimate": "< 5s"
  },
  "metrics": {
    "inputBytes": 10333959,
    "uploadMs": 450,
    "processingMs": 0,
    "totalMs": 460
  }
}

JobStatusResponse (GET /compress/job/{id})

FieldTypeRequiredDescription
idstringyesJob identifier
statusstringyes"Queued", "Running", "Succeeded", "Failed", or "Canceled"
formatstringyesCompression format (e.g. "jpg", "png", "pdf")
progress.percentnumberyesCompletion percentage (0--100)
progress.phasestring|nullnoCurrent processing phase
metrics.inputBytesnumberyesInput file size in bytes
metrics.outputBytesnumberyesOutput file size in bytes
metrics.creditCostnumberyesCredits charged for this job
metrics.compressionRationumber|nullnoCompressed / original ratio (e.g. 0.33)
metrics.savingsPercentnumber|nullnoSpace savings percentage (e.g. 66.9)
errorobject|nullnoError details (failed jobs only)
error.codestringMachine-readable failure code
error.detailstringHuman-readable failure detail
outputobject|nullnoOutput file summary (succeeded jobs only)
output.fileNamestringOutput filename
output.contentTypestringMIME type of the output
output.fileCountnumberNumber of output files

Example -- Succeeded JPG compression:

{
  "id": "0195e2a0-1234-7000-8000-000000000001",
  "status": "Succeeded",
  "format": "jpg",
  "progress": {
    "percent": 100,
    "phase": null
  },
  "metrics": {
    "inputBytes": 10333959,
    "outputBytes": 3421187,
    "creditCost": 1,
    "compressionRatio": 0.33,
    "savingsPercent": 66.9
  },
  "error": null,
  "output": {
    "fileName": "photo-compressed.jpg",
    "contentType": "image/jpeg",
    "fileCount": 1
  }
}

GetCompressorsResponse (GET /compress/compressors)

FieldTypeRequiredDescription
compressorsCompressorItem[]yesList of all available compressors
sourceFormatToobjectyesFormat graph: source format → list of output options with costing
maxFileSizeBytesnumberyesGlobal max file size for current tier
maxConcurrentJobsnumberyesGlobal max concurrent jobs for current tier
maxBatchFilesnumberyesGlobal max batch files for current tier

CompressorItem

FieldTypeRequiredDescription
jobstringyesJob type identifier (e.g. "image.jpg-compress")
categorystringyesCategory ("images" or "documents")
costingDiscoveryCostingInfoyesCosting strategy and rates
endpointstringyesSubmission endpoint ("/api/compress")
inputFormatsstring[]yesAccepted formats (dotless: ["jpg", "jpeg"])
outputFormatsstring[]yesOutput formats (dotless: ["jpg"])
maxFileSizeBytesnumberyesMax file size for current tier
maxConcurrentJobsnumberyesMax concurrent jobs for current tier

CompressorEdge (in sourceFormatTo)

FieldTypeRequiredDescription
sourceFormatstringyesInput format (e.g. "jpg")
targetFormatstringyesOutput format (e.g. "jpg")
jobstringyesJob type identifier
endpointstringnoSubmission endpoint
categorystringyesCompressor category
costingDiscoveryCostingInfoyesCosting strategy and rates
maxFileSizeBytesnumberyesMax file size for current tier
maxConcurrentJobsnumberyesMax concurrent jobs for current tier

DiscoveryCostingInfo

FieldTypeRequiredDescription
strategystringyes"Fixed", "PerMegabyte", "PerPage", etc.
baseCostnumberyesBase credit cost
incrementnumber|nullnoChunk size for PerMegabyte/PerPage (e.g. 40 = per 40 MB)
incrementUnitstring|nullnoUnit label ("mb", "pages", "minutes")
displaySuffixstringyesHuman-readable cost label (e.g. "per 40 MB")

CompressCostEstimateResponse (GET /compress/estimate/{format})

FieldTypeRequiredDescription
jobstringyesJob type identifier
categorystringyesCompressor category
estimatedCreditsnumberyesEstimated credit cost (minimum if inputs omitted)
costingDiscoveryCostingInfoyesCosting strategy and rates
inputsobjectyesInput values used for the estimate
inputs.fileSizeBytesnumber|nullyesResolved file size in bytes
inputs.fileSizeMbnumber|nullyesProvided MB value
limitsobjectyesTier-specific limits
limits.maxFileSizeBytesnumber|nullyesMax file size for current tier

CompressorsListResponse (legacy: GET /compress)

FieldTypeRequiredDescription
routestringyesSubmit endpoint
compressorsLegacyCompressorItem[]yesList of all available compressors

LegacyCompressorItem

FieldTypeRequiredDescription
jobIdstringyesJob type identifier (e.g. "image.jpg-compress")
categorystringyesCategory ("images" or "documents")
poolstringyesWorker pool name
inputFormatsstring[]yesAccepted input format extensions (dotted: [".jpg"])
outputFormatsstring[]yesOutput format extensions (dotted: [".jpg"])

Example (legacy):

{
  "route": "/api/compress",
  "compressors": [
    {
      "jobId": "image.jpg-compress",
      "category": "images",
      "pool": "ImagePool",
      "inputFormats": [".jpg", ".jpeg"],
      "outputFormats": [".jpg"]
    }
  ]
}

CompareResponse (GET /compress/job/{id}/compare)

Before/after comparison data for visual quality verification.

FieldTypeRequiredDescription
beforeImagestringyesBase64-encoded preview of the original
afterImagestringyesBase64-encoded preview of the compressed output
originalBytesnumberyesOriginal file size in bytes
compressedBytesnumberyesCompressed file size in bytes
beforeMimeTypestringyesMIME type of before preview
afterMimeTypestringyesMIME type of after preview
previewWidthnumberyesPreview image width
previewHeightnumberyesPreview image height
afterPreviewWidthnumberyesAfter-preview width (actual-size mode)
afterPreviewHeightnumberyesAfter-preview height (actual-size mode)
inputWidthnumberyesOriginal image width
inputHeightnumberyesOriginal image height
outputWidthnumberyesCompressed image width
outputHeightnumberyesCompressed image height
wasResizedbooleanyesWhether the image was resized during compression

EntitlementsResponse (GET /compress/entitlements/me)

FieldTypeRequiredDescription
userIdstring|nullnoUser ID
organizationIdstring|nullnoOrganization GUID
planIdstringyesPlan identifier
planNamestringyesDisplay name of the plan
accessDisplayNamestring|nullnoShort display label (e.g. "Pro")
totalCreditsnumberyesTotal available credits
planCreditsnumberyesCredits from plan allocation
loyaltyCreditsnumberyesLoyalty/bonus credits
walletCreditsnumberyesPurchased wallet credits
sourcestringyesCredit source ("accounts.tools.fast" or "compress.fast")
tierstringyes"pro"

Example -- Pro tier (API key authenticated):

{
  "userId": "0195e2a0-1234-7000-8000-000000000099",
  "organizationId": "0195e2a0-1234-7000-8000-000000000050",
  "planId": "pro",
  "planName": "Pro",
  "accessDisplayName": "Pro",
  "totalCredits": 4850,
  "planCredits": 5000,
  "loyaltyCredits": 0,
  "walletCredits": 0,
  "source": "accounts.tools.fast",
  "tier": "pro"
}
Copied.