API Docs - TypstDrive
{#each navSections as section} {/each}
{#if activeSection === 'overview'}

Overview

The TypstDrive Render API lets you compile Typst markup into PNG images or PDF documents programmatically. Authenticate with an API key and POST Typst code — get back binary output.

PNG output

First page rendered at 2× scale

PDF output

Full multi-page PDF document

Cached results

Identical inputs skip recompilation

Base URL

{baseUrl}
{/if} {#if activeSection === 'auth'}

Authentication

All requests must include an API key in the Authorization header.

Header format

{@html hljs.highlight('Authorization: Bearer td_your_api_key_here', { language: 'bash' }).value}

Keep your keys secret

API keys grant access to your account's uploaded files during compilation. Never expose them in client-side code or commit them to version control.

Managing keys

Create, regenerate, and revoke keys in Settings → API Keys. The full key is shown only once at creation time.

{/if} {#if activeSection === 'endpoint'}

POST /v1/render

POST /v1/render

Compile Typst markup and return rendered output as PNG, PDF, or HTML. Results are cached for 1 hour — identical inputs return the cached result without recompiling.

Request headers

Header Value
Authorization Bearer <api-key> — required
Content-Type application/json — required

Request body

{@html hSchema}

Response

200 OK Response body with Content-Type: image/png, application/pdf, or text/html

Compilation errors

422 Unprocessable Entity JSON body describing every Typst error. error is a readable summary; details lists each diagnostic with its message, severity, and source line and column.
{@html hCompileErr}

Account files available automatically

Files uploaded to your TypstDrive account are available by filename inside your Typst code. Pass additional files inline via the files array to supplement or override them.

{/if} {#if activeSection === 'examples'}

Examples

{#each [ { id: 'curl-png', label: 'cURL — render PNG', icon: 'mdi:bash', iconColor: 'text-gray-400', code: hCurlPng, raw: curlPng }, { id: 'curl-pdf', label: 'cURL — render PDF', icon: 'mdi:bash', iconColor: 'text-gray-400', code: hCurlPdf, raw: curlPdf }, { id: 'curl-html', label: 'cURL — render HTML', icon: 'mdi:bash', iconColor: 'text-gray-400', code: hCurlHtml, raw: curlHtml }, { id: 'js', label: 'JavaScript / TypeScript', icon: 'mdi:language-javascript', iconColor: 'text-yellow-400', code: hJs, raw: jsExample }, { id: 'python', label: 'Python (httpx)', icon: 'mdi:language-python', iconColor: 'text-blue-400', code: hPython, raw: pythonExample}, { id: 'files', label: 'Python — with inline files', icon: 'mdi:file-image-outline', iconColor: 'text-purple-400', code: hFiles, raw: filesExample }, ] as ex}

{ex.label}

{@html ex.code}
{/each}
{/if} {#if activeSection === 'rate-limits'}

Rate Limits

60

requests / minute per key

10

API keys per account

Caching saves quota

Identical inputs (same code + files) skip recompilation and are served from cache for up to 1 hour. Cached responses return instantly and do not consume your rate limit.

When exceeded

429 Too Many Requests — wait for the current 60-second window to reset.
{/if} {#if activeSection === 'errors'}

Error Reference

{#each [ { code: '400', name: 'Bad Request', desc: 'Invalid format value, empty code, or malformed JSON body.' }, { code: '401', name: 'Unauthorized', desc: 'Missing or invalid Authorization header, or unknown API key.' }, { code: '422', name: 'Unprocessable Entity', desc: 'Your Typst code compiled with errors. The JSON body lists each error message with its source line and column.' }, { code: '429', name: 'Too Many Requests', desc: 'Rate limit exceeded. Wait for the current 60-second window to reset.' }, { code: '500', name: 'Internal Server Error', desc: 'Unexpected server error. Try again after a short delay.' }, ] as err}
{err.code}

{err.name}

{err.desc}

{/each}

Error body

Compilation failures (422) return a JSON body with an error summary and a details array. All other errors return plain text describing the issue.

{/if}