SOAPNoteAPI
Multiple10 min5 steps

Upload Audio and Get a SOAP Note

Upload an audio recording of a clinical encounter and receive a transcribed, structured SOAP note.

1

Prepare your audio file

The API accepts audio files up to 25 MB in the following formats: MP3, M4A, WAV, OGG, WebM, and FLAC. For best transcription accuracy, use a sample rate of 16 kHz or higher with minimal background noise.
2

Upload with Python

Use multipart/form-data to upload the audio file along with the specialty. The API transcribes the audio and returns a SOAP note.
Python
import os
import requests

api_key = os.environ["SOAPNOTEAPI_KEY"]

with open("encounter.mp3", "rb") as audio_file:
    response = requests.post(
        "https://api.soapnoteapi.com/v1/note/audio",
        headers={
            "Authorization": f"Bearer {api_key}",
        },
        files={
            "audio": ("encounter.mp3", audio_file, "audio/mpeg"),
        },
        data={
            "specialty": "nurse_practitioner",
        },
    )

result = response.json()
print("Note ID:", result["noteId"])
print("Status:", result["status"])
3

Upload with Node.js

In Node.js 18+, use the built-in FormData and fetch APIs. Read the file with fs and wrap it in a Blob.
JavaScript
import { readFile } from "node:fs/promises";

const apiKey = process.env.SOAPNOTEAPI_KEY;
const audioBuffer = await readFile("encounter.mp3");

const formData = new FormData();
formData.append("audio", new Blob([audioBuffer], { type: "audio/mpeg" }), "encounter.mp3");
formData.append("specialty", "nurse_practitioner");

const response = await fetch("https://api.soapnoteapi.com/v1/note/audio", {
  method: "POST",
  headers: {
    "Authorization": `Bearer ${apiKey}`,
  },
  body: formData,
});

const result = await response.json();
console.log("Note ID:", result.noteId);
console.log("Status:", result.status);
4

Poll for results

Audio processing takes a few seconds. If the initial response has "status": "processing", poll the note endpoint until it completes.
Python
import time
import requests

def wait_for_note(noteId: str, api_key: str, timeout: int = 120) -> dict:
    """Poll until the note is ready or the timeout is reached."""
    url = f"https://api.soapnoteapi.com/v1/audio/status/{noteId}"
    headers = {"Authorization": f"Bearer {api_key}"}
    deadline = time.time() + timeout

    while time.time() < deadline:
        response = requests.get(url, headers=headers)
        response.raise_for_status()
        data = response.json()

        if data["status"] == "completed":
            return data
        if data["status"] == "failed":
            raise RuntimeError(f"Note generation failed: {data.get('message', 'unknown error')}")

        time.sleep(2)

    raise TimeoutError(f"Note {noteId} did not complete within {timeout}s")


# Usage
note = wait_for_note(result["noteId"], api_key)
print("Subjective:", note["subjective"])
5

Handle the response

Once complete, the note has the same structure as a text-generated note. The response also includes a transcript field with the raw transcription from the audio.
JSON
# Completed audio note response (same shape as text-to-SOAP)
{
  "noteId": "note_xyz789",
  "subjective": "...",
  "objective": "...",
  "assessment": "...",
  "plan": "...",
  "expires_at": "2026-09-21T00:00:00Z"
}

Ready to start building?

Get a free API key and $10 in credit — no credit card required.

Get your free API key