mochify-app Upload API
Chunked upload for large images on unreliable connections; feeds the same pipeline as /v1/squish
Chunked upload for large images on unreliable connections; feeds the same pipeline as /v1/squish
Every API here is available over the APIs.io API and to AI agents over MCP.
One button, every client — Claude, Cursor, VS Code and the rest.
https://apis.io/mcp
find_apisBrowse and filter every API in the catalog.get_api_artifactsOne API's artifacts, grouped by type.get_openapiThe primary OpenAPI for this API.find_similar_apisAPIs that look like this one.apis_io_searchSTART HERE — APIs, providers and tags for one query, each with its total.resolveTurn a domain, URL or GitHub org into the provider it belongs to.find_cohortsEvery scored population of providers in the catalog.curl "https://apis.io/api/v1/apis/mochify-app:mochify-app-upload-api"
curl "https://apis.io/api/v1/apis?limit=25"
Discovery needs no key. Ratings and market analysis are Pro.
Free tier, no form to fill in. Signing in shares your email address with us — we store it to create your key and to recognise you if you sign in with another provider. See our Privacy Policy and Terms.
A second provider on the same verified email joins the account you already have.
openapi: 3.2.0
info:
title: Mochify Upload API
version: 1.0.0
description: Mochify's REST API for zero-retention image compression, PDF page extraction/splitting, and AI image generation. Images and PDFs are streamed into RAM at api.mochify.app, processed, and returned; the original bytes are never written to disk. Authenticate with an x-api-key header (dashboard-issued key) for quota tracking, or omit auth entirely for anonymous, IP-metered use on the free tier.
contact:
url: https://mochify.app/docs
servers:
- url: https://api.mochify.app
description: Production
security:
- bearerAuth: []
- apiKeyAuth: []
- {}
tags:
- name: Upload
description: Chunked upload for large images on unreliable connections; feeds the same pipeline as /v1/squish
paths:
/v1/upload/init:
post:
operationId: initUpload
tags:
- Upload
summary: Start a chunked upload session
description: For large files over unreliable connections. The reassembled bytes feed the same pipeline as POST /v1/squish once complete.
requestBody:
required: true
content:
application/json:
schema:
type: object
required:
- totalBytes
properties:
totalBytes:
type: integer
description: Declared final size; enforced against the plan's size ceiling and a 75 MB hard cap.
type:
type: string
width:
type: string
height:
type: string
quality:
type: string
smartCompress:
type: boolean
smartCrop:
type: string
crop:
type: string
removeBackground:
type: boolean
stripExif:
type: boolean
generate:
type: string
background:
type: string
optimizeForWeb:
type: boolean
hdr:
type: boolean
clarity:
type: boolean
lossless:
type: boolean
quantize:
type: boolean
description: Lossy (palette) png. Same semantics as /v1/squish's quantize.
targetBytes:
type: string
description: Byte ceiling for the output, as a decimal string. Same semantics and same validation as /v1/squish's targetBytes query parameter.
targetLever:
type: string
enum:
- quality
- dimensions
- both
description: Which knob targetBytes may turn. Same semantics as /v1/squish's targetLever.
description: Same processing parameters as /v1/squish's query string, accepted here as JSON fields; applied when the session completes.
responses:
'200':
description: Session created.
content:
application/json:
schema:
type: object
properties:
sessionId:
type: string
chunkSize:
type: integer
description: Advisory chunk size in bytes (5 MB).
expiresInSeconds:
type: integer
'400':
description: Missing or invalid totalBytes.
content:
application/json: {}
'413':
description: Declared size exceeds the plan's ceiling or the 75 MB session cap.
content:
application/json: {}
'429':
description: Quota exhausted.
content:
application/json: {}
'503':
description: Too many concurrent upload sessions.
headers:
Retry-After:
schema:
type: integer
content:
application/json: {}
/v1/upload/chunk:
post:
operationId: uploadChunk
tags:
- Upload
summary: Append a chunk to an upload session
parameters:
- name: session
in: query
required: true
schema:
type: string
- name: index
in: query
required: true
schema:
type: integer
minimum: 0
description: Chunks must arrive in order starting at 0.
requestBody:
required: true
content:
application/octet-stream:
schema:
type: string
format: binary
responses:
'200':
description: Chunk accepted.
content:
application/json:
schema:
type: object
properties:
received:
type: integer
'400':
description: Missing session/index, or empty chunk.
content:
application/json: {}
'403':
description: Session belongs to a different caller.
content:
application/json: {}
'404':
description: Session not found or expired.
content:
application/json: {}
'409':
description: Chunk received out of order.
content:
application/json: {}
'413':
description: Upload exceeds its declared totalBytes.
content:
application/json: {}
'415':
description: Chunk 0 failed the magic-byte format check.
content:
application/json: {}
/v1/upload/complete:
post:
operationId: completeUpload
tags:
- Upload
summary: Finish a chunked upload and receive the processed image
description: Runs the reassembled bytes through the same pipeline as POST /v1/squish, using the parameters supplied at init. Response shape matches /v1/squish's 200 response.
parameters:
- name: session
in: query
required: true
schema:
type: string
responses:
'200':
description: Same as POST /v1/squish's 200 response.
content:
image/jpeg: {}
image/png: {}
image/webp: {}
image/avif: {}
image/jxl: {}
application/zip: {}
'400':
description: Missing session parameter.
content:
text/plain: {}
components:
securitySchemes:
bearerAuth:
type: http
scheme: bearer
description: 'Dashboard-issued API key sent as `Authorization: Bearer <key>`. This is the header documented on /docs and in the dashboard, and the one to prefer. A signed-in session token is accepted here too. Note: a bearer token that cannot be resolved does not fail the request, it falls through to anonymous IP-based free-tier limits, so a wrong key behaves exactly like sending no key at all. Send the key as x-api-key instead if you want an unusable key reported back to you.'
apiKeyAuth:
type: apiKey
in: header
name: x-api-key
description: The same dashboard-issued API key, sent in the x-api-key header. Used by /v1/squish, /v1/pdf, /v1/generate, /v1/checkTokens, /v1/upload/*. Unlike the bearer header, a key that cannot be resolved is reported as invalid rather than silently downgraded. If no credential is sent at all, these endpoints fall back to anonymous IP-based rate limiting on the free tier rather than rejecting the request.