Skip to main content
Prefer the Python SDK: 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.
New integrations should target the /tabpfn/* JSON endpoints. The legacy /v1/fit and /v1/predict multipart routes will remain available for a short period of time — see the TabPFN-3 changelog.

1. Get your API key

  1. Visit ux.priorlabs.ai and sign in.
  2. Complete account setup.
  3. Navigate to the API Keys page.
  4. Copy your key.
Your API key grants full API access. Store it in a secret manager or environment variable — never commit it to source control.
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 to retrieve the current per-version constraints (max rows, features, classes, dataset size). This lets you validate data locally before upload.
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()
Key v3 limits: up to 1M train rows, 100M train cells, 200K test rows, 160 classes, 2,000 columns, and 5 GB max upload size.

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.
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. The response returns a fitted_train_set_id for use in predictions.
res = httpx.post(
    f"{BASE}/tabpfn/fit",
    headers=HEADERS,
    json={
        "train_set_upload_id": train_set_upload_id,
        "task": "classification",
    },
)
res.raise_for_status()

fitted_train_set_id = res.json()["fitted_train_set_id"]
To enable thinking mode, add the thinking parameters:
res = httpx.post(
    f"{BASE}/tabpfn/fit",
    headers=HEADERS,
    json={
        "train_set_upload_id": train_set_upload_id,
        "task": "classification",
        "thinking_effort": "high",
        "thinking_timeout_s": 300,
        "thinking_effort_metric": "log_loss",
    },
)
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.

5. Upload the test set

Same signed-URL flow as the training set, but linked to the fitted model.
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.
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, limited to 400 test rows).

7. Metering and limits

Predictions consume tokens from daily and monthly pools. Thinking fits have a separate monthly quota. Read API metering before running load tests or production workloads.

Error handling

All error responses follow a consistent envelope:
{
  "message": "Human-readable error description",
  "error_code": "NOT_FOUND",
  "trace_id": "abc123"
}
StatusMeaning
401Missing or invalid authentication token
404Resource not found (upload, fitted model)
409Duplicate upload — reuse the returned ID
422Validation error (invalid parameters, data issues)
429Rate limit — daily, monthly, or thinking fit quota exceeded

API metering

Token budgets, usage pools, and thinking fit limits.

Security

Encryption, data isolation, and access controls.

Thinking mode

Fit-time optimization for better predictions.

FAQ

GPUs, limits, and product questions.