> ## Documentation Index
> Fetch the complete documentation index at: https://docs.sully.ai/llms.txt
> Use this file to discover all available pages before exploring further.

# Note Generation v2 (legacy compatibility)

> Access newer models while preserving an existing Note Generation v1 integration. For legacy customers only.

<Warning>
  **Note Generation v2 is only meant for legacy customers.** Its primary purpose is backward
  compatibility with existing systems built on [Note Generation v1](https://legacy.docs.sully.ai/documentation/guides/clinical-notes), while
  bringing newer model capabilities to those integrations. For new integrations,
  use [Note Generation v3](/note-generation-v3).
</Warning>

The request body, authentication, responses, polling, and webhooks remain
compatible with Note Generation v1.

## Migrate from Note Generation v1

Use `POST /v2/notes` to generate notes with Note Generation v2:

| Operation | Note Generation v1 endpoint | Note Generation v2 endpoint |
| - | - | - |
| Create | `POST /v1/notes` | `POST /v2/notes` |
| Poll | `GET /v1/notes/{noteId}` | `GET /v2/notes/{noteId}` |
| Delete | `DELETE /v1/notes/{noteId}` | `DELETE /v2/notes/{noteId}` |

For accounts enabled for Note Generation v2, GET and DELETE work across both
versions. Notes created through either version can be retrieved or deleted
through either version using the same `noteId`.

Send your existing Note Generation v1 request body and `X-Account-Id` and `X-Api-Key` headers
unchanged.

## Lifecycle

1. `POST /v2/notes` validates and accepts the job.
2. Store the returned `noteId`.
3. Poll `GET /v2/notes/{noteId}` until `status` is `STATUS_DONE` or
   `STATUS_ERROR`.
4. Read the note from `payload.markdown` and, when requested, structured output
   from `payload.json`.
5. Optionally delete the resource with `DELETE /v2/notes/{noteId}`.

## TypeScript SDK

```ts theme={null}
import SullyAI from "@sullyai/sullyai";

type CreateNoteResponse = {
  status: string;
  data: { noteId: string };
};

type GetNoteResponse = {
  status: string;
  data: {
    status: "STATUS_PROCESSING" | "STATUS_DONE" | "STATUS_ERROR";
    payload?: { markdown?: string; json?: unknown };
  };
};

const client = new SullyAI({
  apiKey: process.env.SULLY_API_KEY,
  accountID: process.env.SULLY_ACCOUNT_ID,
  baseURL: process.env.SULLY_API_BASE_URL,
});

const created = await client.post<CreateNoteResponse>("/v2/notes", {
  body: {
    transcript:
      "Clinician: What brings you in today? Patient: I have had a dry cough for three days.",
    noteType: { type: "soap" },
    language: "en",
  },
  maxRetries: 0,
});

const note = await client.get<GetNoteResponse>(
  `/v2/notes/${created.data.noteId}`,
);

console.log(note.data.status, note.data.payload?.markdown);
```

## Python SDK

```python theme={null}
import os

import httpx
from sullyai import SullyAI

client = SullyAI(
    api_key=os.environ["SULLY_API_KEY"],
    account_id=os.environ["SULLY_ACCOUNT_ID"],
    base_url=os.environ["SULLY_API_BASE_URL"],
)

created_response = client.post(
    "/v2/notes",
    cast_to=httpx.Response,
    body={
        "transcript": (
            "Clinician: What brings you in today? "
            "Patient: I have had a dry cough for three days."
        ),
        "noteType": {"type": "soap"},
        "language": "en",
    },
    options={"max_retries": 0},
)
created = created_response.json()

note_response = client.get(
    f"/v2/notes/{created['data']['noteId']}",
    cast_to=httpx.Response,
)
note = note_response.json()

print(note["data"]["status"], note["data"].get("payload", {}).get("markdown"))
```

## Create a note

```bash theme={null}
curl "$SULLY_API_BASE_URL/v2/notes" \
  --request POST \
  --header "X-Account-Id: $SULLY_ACCOUNT_ID" \
  --header "X-Api-Key: $SULLY_API_KEY" \
  --header "Content-Type: application/json" \
  --data '{
    "transcript": "Clinician: What brings you in today? Patient: I have had a dry cough for three days.",
    "noteType": { "type": "soap" },
    "patientInfo": {
      "name": "Example Patient",
      "dateOfBirth": "1980-01-01",
      "gender": "female"
    },
    "instructions": ["Be concise", "Do not infer missing facts"],
    "language": "en"
  }'
```

Response (`200`):

```json theme={null}
{
  "status": "ok",
  "data": { "noteId": "note_..." },
  "date": "2026-09-22T20:15:30Z"
}
```

## Request fields

| Field | Type | Required | Notes |
| - | - | -: | - |
| `transcript` | string | Yes | Encounter transcript; 1 to 100,000 characters. |
| `noteType.type` | string | Yes | `soap`, `custom`, `note_style`, or `note_template`. |
| `noteType.template` | string or template object | Sometimes | Required for `note_template`; used by custom template modes. |
| `noteType.includeJson` | boolean | No | Requests structured output in addition to Markdown. |
| `language` | string | No | `en` (default), `es`, `fr`, `de`, `it`, `pt`, `ru`, or `zh`. |
| `patientInfo` | object | No | Optional `name`, `dateOfBirth`, and `gender` strings. |
| `context` | string | No | Additional encounter context; maximum 50,000 characters. |
| `previousNote` | string | No | Prior note context; maximum 50,000 characters. |
| `medicationList` | string | No | Medication context; maximum 50,000 characters. |
| `instructions` | string\[] | No | Additional note-writing instructions. |
| `date` | string | No | Encounter date supplied by your application. |

## Poll the note

```bash theme={null}
curl "$SULLY_API_BASE_URL/v2/notes/$NOTE_ID" \
  --header "X-Account-Id: $SULLY_ACCOUNT_ID" \
  --header "X-Api-Key: $SULLY_API_KEY"
```

While the job is running:

```json theme={null}
{
  "status": "ok",
  "data": { "status": "STATUS_PROCESSING" },
  "date": "2026-09-22T20:15:31Z"
}
```

When generation succeeds:

```json theme={null}
{
  "status": "ok",
  "data": {
    "status": "STATUS_DONE",
    "payload": {
      "markdown": "# Subjective\nThe patient reports a dry cough for three days.\n..."
    }
  },
  "date": "2026-09-22T20:15:40Z"
}
```

When `includeJson` is enabled and structured output is available,
`data.payload.json` is a JSON object. A failed job remains retrievable with
`status: "STATUS_ERROR"`.

Poll every 1–2 seconds until `STATUS_DONE` or `STATUS_ERROR`.

## Delete a note

```bash theme={null}
curl "$SULLY_API_BASE_URL/v2/notes/$NOTE_ID" \
  --request DELETE \
  --header "X-Account-Id: $SULLY_ACCOUNT_ID" \
  --header "X-Api-Key: $SULLY_API_KEY"
```

The response (`200`) contains
`data.message: "Note deleted successfully"`.

## Errors

Error response:

```json theme={null}
{
  "status": "error",
  "data": { "message": "The request is invalid." },
  "date": "2026-09-22T20:15:30Z"
}
```

| Status | Meaning |
| - | - |
| `400` | Invalid body |
| `401` | Missing or invalid credentials |
| `402` | Insufficient credits |
| `404` | Endpoint unavailable or note not found |
| `409` | Billing operation conflict |
| `422` | Template unavailable |
| `502` | Generated output invalid |
| `429` | Rate limit reached |
| `503` | Generation or billing temporarily unavailable |
| `504` | Request setup timed out |


This documentation is built and hosted on [Mintlify](https://mintlify.com), a developer documentation platform.