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

# HTTP API

> Call sdvm-audit-1 and sdvm-fix-1 from any language. Base URL, authentication, the sample shape, and limits.

The Python SDK is a thin client over three HTTPS endpoints: one per model, and one that chains them. Anything the SDK does, you can do with a POST.

| Endpoint       | Does                                                                                                                               |
| -------------- | ---------------------------------------------------------------------------------------------------------------------------------- |
| `POST /audit`  | Runs `sdvm-audit-1`; returns each sample unchanged plus an `audit` block.                                                          |
| `POST /fix`    | Runs `sdvm-fix-1`; returns each sample plus a `fix` block.                                                                         |
| `POST /refine` | Runs `sdvm-audit-1 -> sdvm-fix-1 -> sdvm-audit-1`; returns each sample with `audit` (before the fix), `fix` and `reaudit` (after). |

Each endpoint takes an optional `config` for the stages it runs: `{"votes"}` on `/audit`, `{"max_attempts"}` on `/fix`, and `{"audit": {...}, "fix": {...}, "reaudit": {...}}` on `/refine`. See [Core concepts](/core-concepts#the-refine-pipeline).

## Base URL

```text theme={"theme":{"light":"material-theme-lighter","dark":"material-theme-darker"}}
https://api.sdvm.ai
```

## Authentication

Send your API key as a bearer token. Keys are created on your [profile page](https://sdvm.ai/profile).

```bash theme={"theme":{"light":"material-theme-lighter","dark":"material-theme-darker"}}
curl https://api.sdvm.ai/audit \
  -H "Authorization: Bearer $SDVM_API_KEY" \
  -H "Content-Type: application/json" \
  -d '{
    "data": [
      {
        "task_type": "multiple_choice",
        "context": "What is the capital of France?",
        "choices": ["Berlin", "Paris", "Madrid", "Rome"],
        "answer_index": 1,
        "style": "qa"
      }
    ],
    "config": {"votes": 3}
  }'
```

## The sample shape

Every element of `data` is a JSON object with a `task_type`. Unknown keys on a multiple-choice sample are passthrough metadata and come back untouched.

<Tabs>
  <Tab title="text">
    ```json theme={"theme":{"light":"material-theme-lighter","dark":"material-theme-darker"}}
    { "task_type": "text", "text": "she sels sea shells by the sea shor" }
    ```
  </Tab>

  <Tab title="multiple_choice">
    ```json wrap theme={"theme":{"light":"material-theme-lighter","dark":"material-theme-darker"}}
    {
      "task_type": "multiple_choice",
      "context": "A woman applies mascara. she",
      "choices": ["applies it to her lashes.", "drives off.", "mixes a bowl.", "exits."],
      "answer_index": 0,
      "style": "continuation"
    }
    ```

    `style` is `"continuation"` for a sentence stem (HellaSwag) or `"qa"` for a complete question (MMLU). See [Multiple choice](/sample-types/multiple-choice).
  </Tab>

  <Tab title="question_answer">
    ```json wrap theme={"theme":{"light":"material-theme-lighter","dark":"material-theme-darker"}}
    {
      "task_type": "question_answer",
      "question": "Natalia sold 48 clips in April and half as many in May. How many altogether?",
      "answer": "She sold 48 / 2 = 24 clips in May, so 48 + 24 = 72 altogether."
    }
    ```

    Two fields, no choices. `answer` is whatever the dataset publishes — a bare value, a sentence, or a worked solution. See [Question and answer](/sample-types/question-answer).
  </Tab>

  <Tab title="conversation">
    ```json wrap theme={"theme":{"light":"material-theme-lighter","dark":"material-theme-darker"}}
    {
      "task_type": "conversation",
      "messages": [
        { "role": "user", "content": "how do i reverse a list in python" },
        { "role": "assistant", "content": "Use slicing: `xs[::-1]` returns a reversed copy, or `xs.reverse()` in place." }
      ]
    }
    ```

    A chat transcript in the OpenAI messages shape, roles `system` / `user` / `assistant`. `turns` (`"last"` default, or `"all"`) is how much of it the models read. See [Conversation](/sample-types/conversation).
  </Tab>
</Tabs>

Responses carry the samples back under `audited_data`, `fixed_data` or `refined_data`, with counts, `cost_usd`, `input_tokens` and `output_tokens`.

## Errors

| Status | Meaning                                                                                                                                                                   |
| ------ | ------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
| 401    | Invalid or revoked API key.                                                                                                                                               |
| 402    | Insufficient credits.                                                                                                                                                     |
| 422    | Validation error: empty or oversized list, malformed sample, sample too large for the model, or estimated cost over the per-request limit. The `detail` field says which. |
| 429    | More than 100 requests per minute.                                                                                                                                        |

## Limits

Up to 100 samples per request and 100 requests per minute per key. Pricing is token-based with a \$0.01 minimum per request; see [Pricing](/pricing).

<Note>
  The endpoint pages in this section are generated from the service's OpenAPI specification, so field names, defaults and ranges match what the server enforces.
</Note>
