How it works
A conversion is four steps: we work out what the file really is, find a route to the format you asked for, run it, and hand you the result. Here is each one.
We detect the format from the bytes, not the name
A file called report.pdf is not necessarily a PDF, and a file with no extension at all is usually still identifiable. So the first thing that happens is that we read the opening bytes of the upload and match them against known format signatures.
This matters more than it sounds. Trusting the extension means a renamed file either fails with a confusing error or, worse, gets fed to the wrong tool. Reading the bytes means a mislabelled file converts correctly anyway, and a file that genuinely is not what it claims is rejected clearly.
Conversions are a graph, not a list
Every supported conversion is an edge between two formats, and each edge records how faithful it is, roughly how expensive it is, and the largest input it accepts. That graph is what the format pages are generated from, and it is published in full through the API.
If no edge exists between the two formats you named, you are told so immediately rather than after an upload. Nothing is silently routed through a lossy intermediate format to make a conversion appear to work.
Fast conversions run inline; slow ones queue
Resizing an image finishes in well under a second, so it runs inside the request and the answer comes back with the result already attached. Rendering a long document or transcoding video does not, so those are queued and picked up by a separate pool of workers.
You never have to guess which you got. A finished job comes back with the result; a queued one comes back with a job id, a queue position and an estimate, and you poll it or wait for the email.
On the Plus plan queued work jumps ahead of free-tier jobs, which is what the priority flag on that plan means in practice.
Nothing is converted twice by two different code paths
The website, the API and convert-by-email are three doors into one pipeline. They differ only in how the caller is identified — a session cookie, a bearer token, or the sender of an email — and then run exactly the same code.
That is a deliberate constraint rather than an implementation detail. Two implementations of "check the quota, sniff the bytes, guard the archive" is how one of them ends up skipping a step for the callers least likely to notice.