Browse by type
TabPFN is a foundation model for tabular data that outperforms traditional methods while being dramatically faster. This client library provides easy access to the TabPFN API, enabling state-of-the-art tabular machine learning in just a few lines of code.
[!TIP]
Dive right in with our interactive Colab notebook! It's the best way to get a hands-on feel for TabPFN, walking you through installation, classification, and regression examples.
This API is now in a stable release. It has been extensively tested and is used across multiple use cases. While we continue to make improvements, the core service is reliable for day-to-day use. Please reach out to us if you encounter any stability issues.
This is a cloud-based service: your data will be sent to our servers for processing.
Please only upload data you have permission to share, and avoid sensitive, confidential, or personally identifiable information. Consider anonymizing or pseudonymizing your data in line with your organization’s policies.
Choose the right TabPFN implementation for your needs:
pip install --upgrade tabpfn-client
Set a token first — fit() raises without one and never prompts. Generate it at
ux.priorlabs.ai/account/api-keys:
export TABPFN_TOKEN="<your-token>"
See Authentication for the alternatives.
from tabpfn_client import init, TabPFNClassifier, TabPFNRegressor
from sklearn.datasets import load_breast_cancer
from sklearn.model_selection import train_test_split
# Load an example dataset
X, y = load_breast_cancer(return_X_y=True)
X_train, X_test, y_train, y_test = train_test_split(X, y, test_size=0.5, random_state=42)
# Use it like any sklearn model
model = TabPFNClassifier()
model.fit(X_train, y_train)
# Get predictions
predictions = model.predict(X_test)
# Get probability estimates
probabilities = model.predict_proba(X_test)
Thinking mode trades extra fit-time compute for higher predictive quality. The server explores additional configurations during fit() and returns a tuned model; predict() then runs as usual.
from tabpfn_client import TabPFNClassifier
# Simplest form: enable with defaults (effort="medium").
model = TabPFNClassifier(thinking_mode=True)
model.fit(X_train, y_train)
model.predict(X_test)
Knobs:
thinking_mode: bool = False — enable thinking with default effort. Equivalent to thinking_effort="medium".thinking_effort: {"medium", "high"} | None — effort level. Setting this also enables thinking, so thinking_mode=True is optional when you've set the level explicitly.thinking_timeout_s: float | None — budget for the fit, in seconds. Only consulted when thinking is enabled. Capped at 2400 (40 minutes).thinking_metric: str | None — optimization metric for the fit. Only consulted when thinking is enabled. See the constructor docstring of TabPFNClassifier / TabPFNRegressor for the full list of supported metrics per task (classification, multiclass, regression) and their aliases.model = TabPFNClassifier(
thinking_effort="high",
thinking_timeout_s=600,
thinking_metric="roc_auc",
)
Notes:
model_path at its default ("auto", which lets the server pick the latest default — currently a v3 model) or set it explicitly to a v3 model. Combining thinking with a v2 or v2.5 model_path raises ValueError client-side.thinking_timeout_s and thinking_metric are only consulted when thinking is enabled; passing them without thinking_mode=True or thinking_effort=... raises ValueError.fit_mode="fit_with_cache" caches the fit so repeated predictions against it are faster. Use it when you fit once and predict many times.
from tabpfn_client import TabPFNRegressor
model = TabPFNRegressor(fit_mode="fit_with_cache")
model.fit(X_train, y_train)
model.predict(X_test) # served from the cache built during fit()
model.predict(X_other)
fit() records the id of the fitted model as model_id_. Assign it to a fresh estimator to predict against the same fit without re-uploading your training data — from another process or another machine:
later = TabPFNRegressor(fit_mode="fit_with_cache")
later.model_id_ = model.model_id_
later.predict(X_test)
Notes:
fit_mode accepts "fit_preprocessors" (the default) or "fit_with_cache".Authentication is token-based. Generate a token at ux.priorlabs.ai/account/api-keys, then supply it in one of two ways.
Via the environment, which needs no code changes:
export TABPFN_TOKEN="<your-token>"
Or in code, before the first fit or predict:
import tabpfn_client
tabpfn_client.set_access_token("<your-token>")
If neither is set, init() raises a RuntimeError explaining where to get a token. It
never prompts — this is a library, so authentication is not allowed to block on input.
The one exception is interactive_login() below, which you call yourself.
If you would rather not copy a token by hand, call interactive_login() explicitly:
from tabpfn_client import interactive_login
interactive_login()
It offers two routes:
open_browser=False to skip the browser entirely.Either way the token is verified and cached, so later runs need no input.
This is opt-in only. init(), fit(), and predict() never trigger it — they use the
token sources above and fail with instructions when none is available.
interactive_login() is also the only thing that writes the token cache. A token supplied
through TABPFN_TOKEN or set_access_token() stays in memory for that process and is
never copied to disk.
To read back the token in use, for example to pass it to another machine:
import tabpfn_client
token = tabpfn_client.get_access_token()
If you've subscribed to the TabPFN AWS Marketplace listing and deployed the container to a SageMaker real-time endpoint, you can invoke it through tabpfn_client.sagemaker using a near-identical scikit-learn surface. There is no PriorLabs API token in this path — you authenticate to your own AWS account, and predict calls are billed by AWS SageMaker rather than against your TabPFN usage allowance.
Install with the optional sagemaker extra to pull in boto3:
pip install --upgrade 'tabpfn-client[sagemaker]'
Then point the estimator at your endpoint:
from tabpfn_client.sagemaker import TabPFNClassifier, TabPFNRegressor
from sklearn.datasets import load_breast_cancer
from sklearn.model_selection import train_test_split
X, y = load_breast_cancer(return_X_y=True)
X_train, X_test, y_train, y_test = train_test_split(X, y, test_size=0.5, random_state=42)
clf = TabPFNClassifier(
endpoint_name="your-sagemaker-endpoint-name",
region_name="us-east-1",
)
clf.fit(X_train, y_train)
clf.predict(X_test)
clf.predict_proba(X_test)
Notes:
boto3 credential chain (env vars, ~/.aws/credentials, instance profile, SSO, etc.). Pass boto_session=session to use an explicit boto3.Session.fit() does not call the endpoint — it stores X_train / y_train on the estimator. Training data is shipped with the next predict* call, which is where the actual fit runs on the endpoint. There is no separate training job.use_kv_cache=True opts into the v3 KV-cache path on the server: the first predict* round-trip uploads training data and captures a model_id, and subsequent calls send only X_test and the id. Default to True when you'll call predict* more than once on the same training data; leave it off if every call uses a different training set (no reuse), since the cache becomes dead weight on the endpoint.tabpfn_client.TabPFNClassifier / TabPFNRegressor so the same code is portable between the managed API and a SageMaker endpoint, modulo endpoint_name / region_name.Thinking mode is supported on SageMaker by passing the same thinking_mode / thinking_effort / thinking_timeout_s / thinking_metric kwargs:
clf = TabPFNClassifier(
endpoint_name="your-sagemaker-endpoint-name",
region_name="us-east-1",
thinking_mode=True,
thinking_effort="medium",
)
The first predict* call after fit() runs the fit on the endpoint and can take from tens of seconds up to several minutes depending on thinking_effort and data size; the fitted model is cached on the endpoint and subsequent calls are fast. Caching is required when thinking is enabled (the client sets use_kv_cache=True automatically) — without it every prediction would redo the fit, which would exceed SageMaker's synchronous invoke window. Only thinking_effort="medium" is reliable within the real-time endpoint's ~60 s sync window for the first call; "high" may exceed it and is currently best-effort.
If you've deployed TabPFN to an Azure AI Foundry managed online endpoint, you can invoke it through tabpfn_client.foundry using the same scikit-learn surface. There is no PriorLabs API token in this path — you authenticate against your own Foundry endpoint with its bearer key, and predict calls are billed by Azure rather than against your TabPFN usage allowance.
Point the estimator at your endpoint URL and pass the bearer key:
from tabpfn_client.foundry import TabPFNClassifier, TabPFNRegressor
from sklearn.datasets import load_breast_cancer
from sklearn.model_selection import train_test_split
X, y = load_breast_cancer(return_X_y=True)
X_train, X_test, y_train, y_test = train_test_split(X, y, test_size=0.5, random_state=42)
clf = TabPFNClassifier(
endpoint_url="https://<your-endpoint>.<region>.inference.ml.azure.com/predict",
api_key="<your-foundry-bearer-token>",
)
clf.fit(X_train, y_train)
clf.predict(X_test)
clf.predict_proba(X_test)
Notes:
endpoint_url is the full Foundry scoring URL, including the /predict path. The bearer key is sent as Authorization: Bearer <api_key>.application/json; the Foundry path does not use multipart, so all data travels JSON-encoded.Set use_kv_cache=True if you will call predict* more than once on the same training data. The first call ships X_train / y_train to the endpoint, runs the fit there, and gets back a model_id. The client caches that id, and every subsequent call sends only X_test plus the id — the server skips the fit and runs inference only. That makes follow-up calls dramatically faster on non-trivial training sets, and shrinks the wire payload from O(n_train + n_test) down to O(n_test):
```python clf = TabPFNClassifier( endpoint_url="https://..inference.ml.azure.com/predict", api_key="", use_kv_cache=True, ) clf.fit(X_train, y_train) clf.predict(X_test_a)
$ claude mcp add tabpfn-client \
-- python -m otcore.mcp_server <graph>