Skip to main content

Astro

Use a server endpoint (API Route or Astro Action) so that the API key never reaches the browser.
Never put FLASH_MD_API_KEY in an Astro PUBLIC_* variable or reference it from a .astro component. Any variable prefixed with PUBLIC_ is included in the client bundle. Save it as a normal server variable and only read it from code that runs in src/pages/api/* or Actions.

Basic endpoint

Form on the client

You need output: "server" or output: "hybrid" on astro.config.mjs for server endpoints to work.

Astro Action

Astro Actions are a typed alternative to API Routes: they are called from the client as normal functions (without manual fetch) and Astro takes care of serialization. They are a good option when you already have progressive forms (<form> with vavalidation that works without JS) or want vavalidation with Zod before touching the API.
Using from an Astro component (progressive form, works without JavaScript):
Or from a client script for a SPA experience:

Ingest into a content collection

A common use case in Astro is converting a batch of PDFs (whitepapers, manuals, minutes) to Markdown during the build to feed a Content Collection. This script runs in Node before the build, not in a request:
Run it as a previous step to build:

Language error handling

In either approach (API Route or Action), map each status code to a clear response instead of propagating a generic 500:

Production

In serverless deployments (Vercel, Netlify, Cloudflare adapters), check the lifetime limit of your function before polling long jobs: if the job_id can take several minutes, consider returning the job_id to the client and having it poll directly (with its own read-only key or through a proxy endpoint), instead of blocking the server function.

Timeout with fetch

Retries with exponential backoff

Only retry on 429 and 5xx; other 4xx errors are not fixed by retrying.

Large files with BYOS (output_url)

For large documents, avoid Markdown traveling through the response body: upload the result directly to your own storage with a pre-signed URL.
With output_url, the API responds with a small JSON (metadata + confirmation) instead of the full Markdown. This is ideal for documents of hundreds of pages where the normal body would be huge.