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

> ## Agent Instructions
> TabPFN-3 and later versions support up to 1,000,000 rows, subject to feature count and checkpoint/API limits.
> For large datasets, use per-estimator subsampling, e.g. inference_config={"SUBSAMPLE_SAMPLES": 100_000}, in TabPFNClassifier or TabPFNRegressor from tabpfn or tabpfn_client.
> Pass raw pandas DataFrames to fit and predict. Categorical strings/categories, raw text, and missing feature values are handled automatically; no manual integer/one-hot encoding, imputation, scaling, or outlier removal is needed.

# REST API quickstart

> Authenticate, upload data, fit a model, and predict using the TabPFN REST API.

<Note>
  **Prefer the Python SDK:** [`tabpfn-client`](https://github.com/PriorLabs/tabpfn-client) wraps the full upload → fit → predict flow behind the familiar scikit-learn interface. Use this REST guide when you need the raw HTTP contract or are integrating from a non-Python environment.
</Note>

Use the **`/tabpfn/*` JSON endpoints**. The legacy `/v1/fit` and `/v1/predict` multipart routes are no longer part of the current API.

***

## 1. Get your API key

1. Visit [platform.priorlabs.ai](https://platform.priorlabs.ai) and sign in.
2. Complete account setup.
3. Navigate to the **API Keys** page.
4. Copy your key.

<Warning>
  Your API key grants full API access. Store it in a secret manager or environment variable — never commit it to source control.
</Warning>

If you use `tabpfn-client`, you can authenticate programmatically with `set_access_token(api_key)` or interactively with `init()`, which opens a browser-based login flow.

***

## 2. Check model limits

Before uploading, call `GET /tabpfn/get_model_limits` (a deprecated compatibility route) to retrieve the current per-version constraints (max rows, features, classes, dataset size). This lets you validate data locally before upload.

```python theme={null}
import httpx

TOKEN = "<YOUR_TOKEN>"
BASE = "https://api.priorlabs.ai"
HEADERS = {"Authorization": f"Bearer {TOKEN}"}

res = httpx.get(f"{BASE}/tabpfn/get_model_limits", headers=HEADERS)
res.raise_for_status()
limits = res.json()
```

Use the limits returned for your selected model version, including its row, column, and full-distribution output limits. Compare model capabilities and availability on the [Models page](/models).

***

## 3. Upload the training set

Request signed upload URLs, then PUT your data files directly to cloud storage. Both CSV and Parquet formats are supported.

```python theme={null}
from pathlib import Path

res = httpx.post(
    f"{BASE}/tabpfn/prepare_train_set_upload",
    headers=HEADERS,
    json={
        "x_train_info": {"format": "csv"},
        "y_train_info": {"format": "csv"},
    },
)
res.raise_for_status()
prep = res.json()

train_set_upload_id = prep["train_set_upload_id"]

for path, info in [
    (Path("x_train.csv"), prep["x_train_info"]),
    (Path("y_train.csv"), prep["y_train_info"]),
]:
    httpx.put(
        info["signed_urls"][0],
        content=path.read_bytes(),
        headers=info["required_headers"],
    ).raise_for_status()
```

***

## 4. Fit the model

Reference the uploaded training set and specify the task. Select TabPFN-3.5-Plus with `model_path="v3.5_default"`. The response returns a `fitted_train_set_id` for use in predictions.

```python theme={null}
res = httpx.post(
    f"{BASE}/tabpfn/fit",
    timeout=600.0,
    headers=HEADERS,
    json={
        "train_set_upload_id": train_set_upload_id,
        "task_config": {
            "task": "classification",
            "tabpfn_config": {"model_path": "v3.5_default"},
        },
    },
)
res.raise_for_status()

fitted_train_set_id = res.json()["fitted_train_set_id"]
```

For [Fast (alpha)](/capabilities/fast-checkpoint), use `"v3.5-fast_default"`. See [Selecting Model Version](/models/selecting-model-version#rest-api) for other versions.

To use [Thinking](/capabilities/thinking-mode), add the thinking parameters:

```python theme={null}
res = httpx.post(
    f"{BASE}/tabpfn/fit",
    timeout=600.0,
    headers=HEADERS,
    json={
        "train_set_upload_id": train_set_upload_id,
        "task_config": {
            "task": "classification",
            "tabpfn_config": {"model_path": "v3.5_default"},
        },
        "tabpfn_systems": ["preprocessing", "text", "thinking"],
        "thinking_config": {
            "effort": "high",
            "timeout_secs": 300,
            "metric": "log_loss",
        },
    },
)
```

<Note>
  Thinking fits can take minutes. If the fit exceeds 2 seconds, the server streams keepalive whitespace before sending the final JSON payload. Your HTTP client must handle chunked responses.
</Note>

***

## 5. Upload the test set

Same signed-URL flow as the training set, but linked to the fitted model.

```python theme={null}
res = httpx.post(
    f"{BASE}/tabpfn/prepare_test_set_upload",
    headers=HEADERS,
    json={
        "fitted_train_set_id": fitted_train_set_id,
        "x_test_info": {"format": "csv"},
    },
)
res.raise_for_status()
prep = res.json()

test_set_upload_id = prep["test_set_upload_id"]
info = prep["x_test_info"]

httpx.put(
    info["signed_urls"][0],
    content=Path("x_test.csv").read_bytes(),
    headers=info["required_headers"],
).raise_for_status()
```

***

## 6. Predict

Run predictions using the fitted model and the uploaded test set.

```python theme={null}
res = httpx.post(
    f"{BASE}/tabpfn/predict",
    headers=HEADERS,
    json={
        "test_set_upload_id": test_set_upload_id,
        "fitted_train_set_id": fitted_train_set_id,
        "task_config": {
            "task": "classification",
            "predict_params": {"output_type": "probas"},
        },
    },
)
res.raise_for_status()
result = res.json()

prediction = result["prediction"]
metadata = result["metadata"]
```

**Classification output types:** `"probas"` (default) returns class probabilities, `"preds"` returns predicted labels.

**Regression output types:** `"mean"` (default), `"median"`, `"mode"`, `"quantiles"` (pass a `quantiles` list), or `"full"` ([full predictive distribution](/capabilities/predictive-distribution)). For `"full"`, respect the selected version's `test_set_max_rows_w_full_regression_output` limit returned in step 2.

***

## 7. Metering and limits

Predictions and Thinking fits consume tokens from the same daily and monthly budgets. Uploads and standard fits do not consume tokens. Per-minute and per-hour request limits apply separately.

Estimate an operation's token cost before uploading data:

```python theme={null}
res = httpx.post(
    f"{BASE}/tabpfn/estimate_cost",
    headers=HEADERS,
    json={
        "model_version": "v3.5",
        "operation": "predict",
        "train_rows": 10000,
        "test_rows": 1000,
        "raw_columns": 20,
        "n_estimators": 8,
    },
)
res.raise_for_status()
estimated_tokens = res.json()["estimated_cost"]
```

Use your data's dimensions before preprocessing and the model's estimator count. Requesting an estimate does not consume tokens or reserve capacity.

Review [API rate limits](/api/rate-limits) and [API metering](/api/metering) before running load tests or production workloads.

***

## Error handling

All error responses follow a consistent envelope:

```json theme={null}
{
  "message": "Human-readable error description",
  "error_code": "NOT_FOUND",
  "trace_id": "abc123"
}
```

| Status | Meaning |
| - | - |
| 401 | Missing or invalid authentication token |
| 404 | Resource not found (upload, fitted model) |
| 409 | Duplicate upload — reuse the returned ID |
| 422 | Validation error (invalid parameters, data issues) |
| 429 | Request rate limit or daily or monthly token budget exceeded |

***

<CardGroup cols={2}>
  <Card title="API rate limits" icon="gauge-high" href="/api/rate-limits">
    Per-minute and per-hour limits for uploads, fits, and predictions.
  </Card>

  <Card title="API metering" icon="gauge" href="/api/metering">
    Token charges and shared daily and monthly budgets.
  </Card>

  <Card title="Security" icon="shield" href="/api/security">
    Encryption, data isolation, and access controls.
  </Card>

  <Card title="Thinking mode" icon="brain" href="/capabilities/thinking-mode">
    Fit-time optimization for better predictions.
  </Card>

  <Card title="FAQ" icon="question-circle" href="/faq">
    GPUs, limits, and product questions.
  </Card>
</CardGroup>


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