POST multipart audio to the backend

JSON is the default for REST, but audio is binary. The right way to send binary data to a backend is multipart/form-data, the same format HTML forms use for file uploads. Browsers give you FormData to build the payload with zero boilerplate.

frontend/src/App.tsx
typescript
const uploadAudio = useCallback(
  async (audioBlob: Blob) => {
    const formData = new FormData();
    formData.append('audio', audioBlob, 'recording.webm');

    const transcribeResponse = await fetch('/api/transcribe', {
      method: 'POST',
      body: formData,
    });

    if (!transcribeResponse.ok) {
      throw new Error(
        `Transcription failed: ${transcribeResponse.statusText}`
      );
    }

    const transcribeData = await transcribeResponse.json();
    setRawText(transcribeData.text || '');
  },
  [useLLM, systemPrompt]
);

FormData.append takes three arguments: the field name the backend will use, the Blob itself, and a filename. Do not set a Content-Type header manually. The browser adds the right multipart boundary automatically.

multipart/form-data includes a random boundary string that separates fields. The browser generates this boundary when you pass FormData to fetch. If you set Content-Type yourself, you override the boundary and the server cannot parse the request. Let the browser handle it.

AI prompt: Try it: craft a multipart curl request

Loading practice…

Quiz: Quiz

Loading practice…

Checkpoint: Browser recording checkpoint

Loading practice…