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

# API Overview

> Base URL, authentication, and error handling for the Pangram REST API

For more information on billing units and pricing, check our [pricing page for developers](https://www.pangram.com/pricing?category=developers).

## Base URLs

AI detection and bulk AI detection use the following base URL:

```
https://text.external-api.pangram.com
```

File uploads use the following base URL:

```
https://file-external.api.pangram.com
```

The plagiarism detection endpoint uses a separate base URL:

```
https://plagiarism.api.pangram.com
```

## Authentication

All API requests must include your API key in the `x-api-key` header.

<Tabs>
  <Tab title="cURL">
    ```bash theme={null}
    curl -X POST https://text.external-api.pangram.com/task \
      -H "Content-Type: application/json" \
      -H "x-api-key: <your-api-key>" \
      -d '{"text": "Your text here", "model": "default"}'
    ```
  </Tab>

  <Tab title="Python">
    ```python theme={null}
    import requests

    response = requests.post(
        "https://text.external-api.pangram.com/task",
        headers={
            "Content-Type": "application/json",
            "x-api-key": "<your-api-key>",
        },
        json={"text": "Your text here", "model": "default"},
    )
    task_id = response.json()["task_id"]

    result = requests.get(
        f"https://text.external-api.pangram.com/task/{task_id}",
        headers={"x-api-key": "<your-api-key>"},
    )
    ```
  </Tab>

  <Tab title="JavaScript">
    ```javascript theme={null}
    const submitResponse = await fetch("https://text.external-api.pangram.com/task", {
      method: "POST",
      headers: {
        "Content-Type": "application/json",
        "x-api-key": "<your-api-key>"
      },
      body: JSON.stringify({ text: "Your text here", model: "default" })
    });

    const { task_id } = await submitResponse.json();

    const resultResponse = await fetch(`https://text.external-api.pangram.com/task/${task_id}`, {
      headers: {
        "x-api-key": "<your-api-key>"
      }
    });
    ```
  </Tab>
</Tabs>

## Model Discovery

Call [`GET /models`](/api-reference/models) to retrieve the ordered model selectors available to your API key. The catalog is entitlement- and availability-aware; do not hard-code it or assume every account sees the same values.

Pass one returned selector as `model` when creating a text or bulk job. One selector applies to the entire request. New integrations should always send it explicitly.

## Async Task Flow

Submit text with `POST /task`, then poll `GET /task/{task_id}` until the returned `stage` is `STAGE_SUCCESS` or `STAGE_FAILED`.

## Bulk Flow

Submit many texts with `POST /bulk`, poll `GET /bulk/{bulk_id}` until the returned `status` is `succeeded`, `failed`, or `partial`, then page through `GET /bulk/{bulk_id}/results`.

Bulk completion time depends on the number and length of submitted items and current system load. Use `GET /bulk/{bulk_id}` to monitor progress.

Bulk metadata and results are retained for 48 hours after terminal completion. Bulk `created_at` and `completed_at` values are Unix epoch seconds encoded as strings.

## File Upload Flow

Submit documents as `multipart/form-data` to `https://file-external.api.pangram.com`. Include one or more `files` fields and set `public_dashboard_link=true` when you need a shareable result link.

## Error Codes

| Status Code                 | Description                                                                                                     |
| --------------------------- | --------------------------------------------------------------------------------------------------------------- |
| `400 Bad Request`           | The request body is not properly formatted.                                                                     |
| `401 Unauthorized`          | The `x-api-key` is missing or invalid.                                                                          |
| `402 Payment Required`      | The account has insufficient credits.                                                                           |
| `403 Forbidden`             | The requested model is not enabled for the API key, or the API key does not own the requested task or bulk job. |
| `404 Not Found`             | The requested task or bulk job does not exist.                                                                  |
| `413 Payload Too Large`     | The bulk request exceeds the maximum billable units.                                                            |
| `422 Unprocessable Entity`  | The input text or model selector is invalid.                                                                    |
| `429 Too Many Requests`     | The API key exceeds its configured rate limit.                                                                  |
| `500 Internal Server Error` | There was an error processing the request.                                                                      |
| `503 Service Unavailable`   | The selected model is temporarily unavailable.                                                                  |

If you are running into errors, please reach out at [support@pangram.com](mailto:support@pangram.com).
