Documentation menu

API reference

Convert

POST /v1/convert changes a file to another format and returns it in the response.

Endpoint

POST/v1/convert

Converts one file to the format you name and returns the result as the response body. Nothing is stored. The endpoint accepts images, PDFs, audio, tables and fonts. Video and office documents must be sent as a job with operation: "convert".

A conversion aims to keep quality, not to save bytes. It uses fixed, high settings (see quality when converting), and it returns the converted file even when that file is larger than the input. To change the format and control the size, use compress with a format option.

Request

Authenticate with Authorization: Bearer $SMOL_API_KEY. Send the file in one of two forms. The file can be up to 25 MB (26,214,400 bytes), or 10 MB with a test key.

Raw body

The request body is the bytes of the file. Options go in the query string. Give the file's name with ?filename= or with a Content-Disposition request header. If both are present, the query parameter is used.

raw body
POST /v1/convert?to=webp&filename=photo.jpg HTTP/1.1
Host: api.smolmac.com
Authorization: Bearer $SMOL_API_KEY
Content-Length: 1614027

<the bytes of the file>
  • Any Content-Type other than multipart/form-data is treated as a raw body. The header's value is not used to detect the file type.
  • Send a Content-Length header. It is required with a test key. With a live key a body without it is accepted and streamed.

Multipart form

Send multipart/form-data with these parts:

PartRequiredContent
fileYesThe file. Its name is taken from the part unless ?filename= is given.
optionsNoA JSON object of options, as text. It has the same shape as options on a job, for example {"image":{"format":"avif","quality":60}}.

Options may also be given in the query string of a multipart request. Where an option appears in both places, the query string wins, field by field.

The file name

The name is optional for most files. It is used for two things: to tell apart formats that share a container or have no signature (see type detection), and to name the file that comes back. Only the last path component is used.

Options

OptionTypeDescription
to *stringThe target format, for example webp. Letter case is ignored. The full path convert.to is also accepted, and is the name to use in JSON options. A request without it is refused with invalid_options.
pageintegerPDF input only. The page to render, counted from 1. Default 1. A page beyond the end of the document is refused with invalid_options. Full path: convert.page.
dpiintegerPDF input only. The resolution of the rendered page. 36 to 600. Default 144. Full path: convert.dpi.
presetstringThe name or id of a preset. Its options are applied first, and the options in the request override them field by field. A preset can supply the target.
filenamestringNot an option: the name of the file. Required for table inputs, which are recognised by their extension.

In a multipart request the same options go in the options part as {"convert":{"to":"webp"}}. These spellings of a target are also accepted: jpeg for jpg, tif for tiff, heif for heic, htm for html, markdown for md, and jsonl for ndjson.

Targets

The targets allowed depend on the kind of file you send.

InputTargetsDirect request
Image (JPEG, PNG, WebP, AVIF, HEIC, GIF, TIFF, BMP)jpg, png, webp, avif, heic, tiff, bmp, gif, pdfYes
PDFpng, jpg. One page per request.Yes
Audio (MP3, AAC, WAV, FLAC, M4A, OGG, Opus, WMA)m4a, mp3, wav, flac, oggYes
Table (CSV, TSV, JSON, NDJSON, HTML, Markdown)csv, tsv, json, ndjson, html, md, xlsxYes
Font (TTF, OTF, WOFF, WOFF2)ttf, otf, woff, woff2Yes
Videomp4, mov, webm, mkvNo. Use a job.
Word documentpdf, docx, odt, rtf, txt, htmlNo. Use a job.
Spreadsheetpdf, xlsx, ods, csv, htmlNo. Use a job.
Presentationpdf, pptx, odpNo. Use a job.
  • A target outside the list for the file's kind is refused with unsupported_target. The message lists the targets that are allowed.
  • Camera RAW files are refused with unsupported_input. Use compress, which decodes them.
  • An animated GIF or WebP keeps its frames when the target is GIF or WebP. For any other target the first frame is used, and the result carries a warning.
  • A font conversion changes the container only. In a table conversion every cell is text.
  • A JSON table input is an array of objects, an array of arrays, or an object that holds such an array under data or rows. NDJSON input has one such value per line. JSON and NDJSON output is one object per row, keyed by the cells of the first row.

Response

Status 200. The body is the converted file. The details are in the headers. Smol-Kept-Original is always false on this endpoint.

HeaderTypeDescription
Content-TypestringThe media type of the returned file, for example image/avif.
Content-LengthintegerThe size of the returned file in bytes.
Content-Dispositionstringattachment with a file name: the name you sent, with its extension replaced by the output format's. file is used when you sent no name.
Cache-ControlstringAlways no-store.
Smol-Request-IdstringThe id of this request. Quote it to support.
Smol-VersionstringThe version of the API that answered, for example 2026-10-01.
Smol-Original-SizeintegerBytes received.
Smol-Output-SizeintegerBytes returned.
Smol-Savings-PercentnumberThe share of the original size that was saved, with one decimal. Negative when the output is larger.
Smol-Output-FormatstringThe format of the returned file, for example avif.
Smol-Kept-Originalbooleantrue when nothing smaller could be made and your input is returned. See Kept original.
Smol-Billedbooleantrue when the request was charged. Always false with a test key and for kept-original results.
Smol-ResultJSONThe full result object as compact JSON on one line. Characters outside printable ASCII are replaced by ?.
RateLimit-LimitintegerThe size of your rate limit bucket.
RateLimit-RemainingintegerRequests left in the bucket.
RateLimit-ResetintegerSeconds until the bucket is full again. See Limits.

Errors

An error has a JSON body in place of the file. See Errors for the format and for what to do about each code.

CodeStatusWhen
missing_file400The body is empty, or the multipart form has no file part.
invalid_options400An option is unknown or has a value that is not allowed. The options part is not valid JSON.
bad_request400The multipart body cannot be parsed. A test key sent a raw body without Content-Length. The preset named does not exist.
missing_key401No Authorization header.
invalid_key401The key is not a valid key.
revoked_key401The key has been revoked.
no_payment_method402A live key on an account with no plan.
payment_required402A live key on an account with an unpaid invoice.
spend_cap_reached402The account has reached its monthly spend cap.
test_mode_sample_required402A test key sent a file that is not a published sample.
account_suspended403The account is suspended.
ip_not_allowed403The key may not be used from this IP address.
feature_not_enabled403The output would be HEIC, and HEIC output is not enabled for the account. This covers image.format=heic, a convert target of heic, and a HEIC file compressed with image.format left at original.
file_too_large413The file is over 25 MB, or over 10 MB with a test key.
unsupported_input415The file type is not recognised, or this endpoint does not handle it.
unsupported_target415The target is not available for this kind of file.
use_async_job415The file is a video or an office document. These need a job.
limit_exceeded422The file is over a pixel, page, frame or length limit.
encrypted_pdf422The PDF needs a password to open.
processing_failed422The file could not be processed. It may be damaged.
rate_limited429Too many requests per second.
concurrency_limited429Too many direct requests in progress at once.
internal500Something went wrong on our side.
engine_busy503The service is at capacity for a moment.
timeout504Processing took longer than 120 seconds.

Examples

Convert a PNG to WebP:

curl -X POST "https://api.smolmac.com/v1/convert?to=webp" \
  -H "Authorization: Bearer $SMOL_API_KEY" \
  --data-binary @diagram.png \
  -o diagram.webp

Render page 2 of a PDF as a PNG at 200 dpi:

bash
curl -X POST "https://api.smolmac.com/v1/convert?to=png&page=2&dpi=200" \
  -H "Authorization: Bearer $SMOL_API_KEY" \
  --data-binary @report.pdf \
  -o report-page-2.png

Convert a CSV file to a spreadsheet. The file name is needed so that the CSV is recognised:

bash
curl -X POST "https://api.smolmac.com/v1/convert?to=xlsx&filename=orders.csv" \
  -H "Authorization: Bearer $SMOL_API_KEY" \
  --data-binary @orders.csv \
  -o orders.xlsx

Example response

200 OK
HTTP/1.1 200 OK
Content-Type: image/webp
Content-Length: 96274
Content-Disposition: attachment; filename="diagram.webp"; filename*=UTF-8''diagram.webp
Cache-Control: no-store
Smol-Version: 2026-10-01
RateLimit-Limit: 40
RateLimit-Remaining: 39
RateLimit-Reset: 1
Smol-Request-Id: req_Bv2Kq9XtL0mZs4Wd7HcR
Smol-Original-Size: 842113
Smol-Output-Size: 96274
Smol-Savings-Percent: 88.6
Smol-Output-Format: webp
Smol-Kept-Original: false
Smol-Billed: true
Smol-Result: {"kind":"image","input_format":"png","output_format":"webp","original_size":842113,"output_size":96274,"savings_percent":88.6,"kept_original":false,"increased":false,"width":1600,"height":900,"pages":null,"duration_seconds":null,"video_codec":null,"warnings":[]}

<the bytes of diagram.webp>