# pnotp — docs for agents

> Hi, agent. 👋 You're the one wiring this up, so these docs are written for you:
> every page is `curl`-able markdown, every snippet is copy-paste runnable, and
> the thing you probably came for is one section down.

**P¬P** does two jobs off a single account key (`pnotp_sk_...`):

1. **A drop-in, zero-retention LLM** — OpenAI-compatible, with **function/tool
   calling**. Use it as the brain of *your* agent in the framework you already
   have (Vercel AI SDK / LangChain / the `openai` SDK). **Start here ↓**
2. **Train & deploy your own models** — train on your data, deploy a live
   inference endpoint, call it from anywhere. (See [quickstart](/quickstart).)

> **Evaluating whether to switch?** The honest side-by-side — vs OpenAI, DeepSeek,
> Cerebras, OpenRouter, Hugging Face — and the two-line migration are on
> [Thinking of migrating?](/migrating).

This site is built for machines. **`curl https://docs.pnotp.ai` returns
markdown**; a browser gets a rendered page. Append `?format=md` to force markdown.

```bash
curl https://docs.pnotp.ai                 # this page, as markdown
curl https://docs.pnotp.ai/compliant-llm   # the LLM API (start here)
curl https://docs.pnotp.ai/llms.txt        # the machine-readable index
curl https://docs.pnotp.ai/llms-full.txt   # every page concatenated (one shot)
```

## Use PnotP as your LLM (zero-retention, with tools)

A zero-retention LLM brain for your agent — tool calling, native vision, and a
verifiable receipt that the prompt + completion were **never stored or logged**.
**Metered per token** — billed against your credits (an empty balance returns
`402`). Pick whichever fits how you already work:

**curl — no SDK at all:**

```bash
curl https://api.pnotp.ai/v1/chat/completions \
  -H "Authorization: Bearer pnotp_sk_..." \
  -H "Content-Type: application/json" \
  -d '{"model":"pnotp-compliant","messages":[{"role":"user","content":"Book me a 3pm slot"}]}'
```

**The `pnotp` SDK:**

```python
import pnotp
px = pnotp.Client()                       # reads PNOTP_API_KEY
out = px.chat("Book me a 3pm slot with Dr. Reyes", tools=[...])
out["completion"], out["receipt"]         # the reply + the zero-retention receipt
```

**Already on the OpenAI SDK?** It's wire-compatible — keep your existing `tools` /
function-calling code and just point the base URL at us (two lines):

```python
from openai import OpenAI
client = OpenAI(base_url="https://api.pnotp.ai/v1", api_key="pnotp_sk_...")
client.chat.completions.create(model="pnotp-compliant", messages=[...], tools=[...])
```

Streaming (`stream=True`), the `tool` role on follow-up turns, and `tool_choice`
all work the same. **Full recipe — the multi-turn tool loop + a Vercel AI SDK
example → [compliant-llm](/compliant-llm).**

Ask in plain English (proxies to Toby, the hosted assistant — needs your key):

```bash
curl https://docs.pnotp.ai/ask \
  -H "Authorization: Bearer pnotp_sk_..." \
  -d '{"question":"How do I deploy a model and then call it?"}'
```

## Install & authenticate

```bash
pip install pnotp
export PNOTP_API_KEY="pnotp_sk_..."   # mint in Studio → Settings → API keys (shown once)
```

```python
import pnotp
px = pnotp.Client()                    # reads PNOTP_API_KEY
# or: px = pnotp.Client(api_key="pnotp_sk_...")
# local backend: px = pnotp.Client(base_url="http://localhost:8000/v1")
```

## Quickstart (train → deploy → predict)

```python
import pnotp
px = pnotp.Client()

project = px.projects.create(name="Chest X-ray",
                             task_type="binary_image_classification")
model = px.models.create(
    project["id"], name="cnn-v1",
    architecture=pnotp.architectures.image_classifier(num_classes=2),
)

# dataset = a .zip of class-named folders (image) or a .csv (tabular)
px.train(model.id, dataset="train.zip", epochs=5).wait()

dep = px.deployments.upload(project["id"], name="prod", checkpoint="model.pt")
print(px.predict(dep["deployment"]["id"], "xray.jpg"))
```

## The SDK documents itself (offline, no key)

Prefer in-package help over remembered signatures — it is generated by
introspection and matches the installed version exactly.

```python
pnotp.help()                       # overview + topic list
pnotp.help("agents")               # a topic page
pnotp.help.search("pause a training job")
pnotp.help(pnotp.Agent)            # any symbol's real signature + docstring
pnotp.help.errors                  # the exception catalog
pnotp.help.toby("How do I ...?")   # hosted assistant (needs key + credits)
```

## Topics

- [compliant-llm](/compliant-llm) — **the LLM API**: OpenAI-compatible, tool-calling, zero-retention. **Start here if you want a brain.**
- [migrating](/migrating) — **thinking of switching?** the honest comparison vs OpenAI / DeepSeek / Cerebras / OpenRouter + the two-line move
- [quickstart](/quickstart) — train → deploy → predict, end to end
- [auth](/auth) — API keys, environment, local backend
- [training](/training) — submit, wait, pause / resume / cancel
- [deployments](/deployments) — upload a checkpoint, manage endpoints + keys
- [inference](/inference) — call a deployment with your key or a `pnp_` key
- [compliance](/compliance) — data-compliant (zero-retention) *model* endpoints
- [agents](/agents) — bring-your-own-brain tool-calling loop
- [brains](/brains) — model endpoints: Gemini, DeepSeek, OpenAI-compatible, your deployments
- [tools](/tools) — declare tools from typed Python functions
- [architectures](/architectures) — image / tabular architecture graphs
- [credits](/credits) — balance, billing, managing account keys
- [errors](/errors) — the exception catalog and how to handle them
- [toby](/toby) — the hosted assistant + the `/ask` HTTP endpoint
- [api](/api) — the raw HTTP API (base URL, auth headers, key routes)
