<!-- Generated from the de/docs page by the site build (site/integrations/md-twins.mjs); never edit by hand. -->

# Quickstart

OpenQASM 3 hinein, kanonische Counts heraus. Der komplette Happy Path; jedes Feld steht in der [API-Referenz](https://pauli.xyz/reference), die rohe Spezifikation unter [`/openapi.json`](https://pauli.xyz/openapi.json).

## 0 · API-Key anlegen

[Erstellen Sie einen Workspace](https://pauli.xyz/de/signup) und holen Sie einen Admin-Key; jeder Client unten liest ihn aus der Umgebung:

```
export PAULI_API_KEY=pauli_sk_…   # shown once at creation; rotate any time
```

## 1 · Qiskit

Jedes Gerät der Registry ist ein Qiskit-`BackendV2`: Gerät wählen, ausführen, Counts in Qiskits eigener Schlüsselordnung lesen. Läufe bleiben an das gewählte Backend gebunden und weichen nie stillschweigend aus:

```
pip install qiskit-pauli   # Python ≥ 3.10
```

```
from qiskit import QuantumCircuit
from qiskit_pauli import PauliProvider

qc = QuantumCircuit(3, 3)                 # GHZ
qc.h(0); qc.cx(0, 1); qc.cx(0, 2)
qc.measure(range(3), range(3))

provider = PauliProvider()                # reads PAULI_API_KEY
backend = provider.least_busy(simulator=True)  # drop simulator=True for hardware
counts = backend.run(qc, shots=1000).result().get_counts()
print(counts)                             # {'000': 489, '111': 511}
```

Der Rest dieser Seite läuft über `provider.client`, den vollständigen typisierten Client unter jedem Backend: Geld als exaktes `Decimal` (ein float wirft), ein Idempotenzschlüssel bei jedem Submit, Exceptions entlang der stabilen Codes unten.

## 2 · Die Flotte schätzen (kostenlos)

Ein Aufruf bepreist *Ihren* Schaltkreis auf jedem geeigneten Gerät, mit erwarteter Warteschlange, Fidelity und begründeten Ausschlüssen:

```
from qiskit import qasm3

client = provider.client                  # the full pauli-sdk client
fleet = client.jobs.estimate(qasm3.dumps(qc), shots=1000)
for e in fleet.estimates:                 # cheapest first
    print(e.device, e.amount, e.predicted_queue_seconds, e.fidelity_score)
for x in fleet.excluded:                  # reasoned exclusions, complete
    print(x.device, x.reasons[0].code)
```

```
ionq.simulator 0.000000 1.0 1.0
ionq.qpu.forte-enterprise-1 2.700000 6871.0 0.953
```

## 3 · Mit Policy einreichen

Wählen Sie `cheapest`, `fastest`, `highest_fidelity` oder `balanced`; pinnen Sie ein Gerät, oder beschränken Sie nach Anbieter, Preis, Warteschlange oder Region. Der Job kehrt sofort mit Routing-Entscheidung und exakten Kosten zurück; jeder Submit trägt einen Idempotenzschlüssel (automatisch erzeugt, sofern Sie keinen übergeben), sodass eine Wiederholung nie doppelt einreichen kann:

```
job = client.jobs.submit(qasm3.dumps(qc), shots=1000,
                         policy="highest_fidelity", only=["ionq"],
                         allow_simulator_fallback=True, max_spend_usd="10.00",
                         idempotency_key="exp-042-run-7",
                         webhook_url="https://example.com/hooks/pauli")
print(job.routing_decision.selected_device, job.cost_estimate.amount)
```

Fehler vor der Ausführung weichen auf das nächstbeste Gerät aus, außer bei `allow_fallback=False`; jeder Sprung wird protokolliert, und Sie zahlen nur für das Gerät, das ausgeführt hat.

## 4 · Abfragen oder den Webhook nehmen

```
job.wait()   # jittered backoff to a terminal state; timeout=… to bound it
# created → validating → estimating → queued → transpiling → submitted → running → completed
```

Mit einer `webhook_url` (nur https) POSTet jeder Zustandsübergang genau einmal, signiert mit dem Webhook-Secret des einreichenden Keys (bei der Key-Erstellung angezeigt); deduplizieren Sie über `X-Pauli-Event-Id`:

```
import hashlib, hmac, time

def verify(secret: str, body: bytes, header: str, tolerance: int = 300) -> bool:
    pairs = [p.split("=", 1) for p in header.split(",")]  # header: X-Pauli-Signature
    t = next(v for k, v in pairs if k == "t")
    if abs(time.time() - int(t)) > tolerance:
        return False
    expected = hmac.new(secret.encode(), f"{t}.".encode() + body, hashlib.sha256).hexdigest()
    return any(hmac.compare_digest(expected, v) for k, v in pairs if k == "v1")
```

Das SDK liefert dieses Rezept als `pauli_sdk.webhooks.unwrap(body, headers, secret=…)`.

## 5 · Ergebnisse: eine Bit-Reihenfolge

```
{
  "counts": {"000": 489, "111": 511},
  "bit_ordering": "cbit0_left",
  "register_map": {"c": ["q[0]", "q[1]", "q[2]"]},
  "metadata": {"provider_job_id": "…", "calibration_snapshot_id": "…"},
  "insights": {"shape": "cat_pair", "confidence": "high", "headline": "GHZ-like cat state: …"},
  "billing": {"billed_usd": "2.470000"}
}
```

**Die Counts-Konvention**: das Zeichen ganz links jedes Schlüssels ist das klassische Bit 0 des zuerst deklarierten Registers; Register werden in Deklarationsreihenfolge flachgelegt. Jeder Anbieter wird darauf normalisiert; Analysecode verzweigt nie.

**Insights**: eine rein hinweisende Klassifikation der Histogrammform (Katzenzustand, uniform, periodischer Kamm, Porter-Thomas-Speckle, …) mit Klartext-Überschrift und Shots-bewusster Konfidenz, allein aus den Counts abgeleitet. Eine Lesehilfe, nie eine Bewertungsfläche.

## 6 · Eigene Zugangsdaten (BYOK)

Registrieren Sie Zugangsdaten (/console/credentials oder `PUT /v1/credentials/{provider}`), und Jobs auf diesem Anbieter laufen unter Ihrem Konto: der Anbieter stellt Ihnen direkt in Rechnung; Ihre Wallet zahlt nur die Plattformgebühr ([Preise](https://pauli.xyz/de/pricing)). Schätzungen, Status und Ergebnisse zeigen `byok`; ein Fallback wechselt nie den Abrechnungsmodus.

## 7 · Agenten (MCP)

Model Context Protocol unter `https://pauli.xyz/mcp` (Streamable HTTP), gleicher Bearer-Key. Die Tools spiegeln den Ablauf dieser Seite.

```
claude mcp add --transport http pauli https://pauli.xyz/mcp \
  --header "Authorization: Bearer $PAULI_API_KEY"
```

## 8 · Bezahlen aus dem Agenten

Ein bezahlter Submit über Ihr Guthaben hinaus liefert `402` `billing.insufficient_credits`; sein `detail` ist eine Payment-Challenge mit Fehlbetrag, Auflade-Endpoint und dem Weg, die Gutschrift zu bestätigen. Laden Sie auf (Top-ups liefern eine gehostete `checkout_url`, die ein Mensch abschließt), dann reichen Sie mit demselben `Idempotency-Key` erneut ein. Auto-Top-up (`PATCH /v1/billing/settings`) füllt von einer hinterlegten Karte nach, bevor Jobs die 402 je sehen. MCP-Tool-Ergebnisse tragen dieselbe Challenge wörtlich.

Die anderen 402, `billing.monthly_cap_exceeded` und `billing.key_cap_exceeded`, sind von Ihnen gesetzte Deckel; sie tragen keine Challenge. Heben Sie den Deckel an, wenn die Ausgabe gewollt ist.

---

## Fehler

Jeder Fehler ist `{"error": {"code", "message", "detail?", "request_id"}}` mit stabilem Code; das Register ist [`/public/errors`](https://pauli.xyz/public/errors). Nennen Sie dem Support die `request_id`. Die ersten, denen Sie begegnen:

| Code | Bedeutung |
| --- | --- |
| program.invalid | Das OpenQASM 3 parste nicht; das detail trägt Zeile und Spalte. |
| routing.no_feasible_device | Nichts kann dieses Programm unter Ihren Bedingungen ausführen; das detail listet die Gründe je Gerät. |
| billing.insufficient_credits | 402: Fehlbetrag aufladen und erneut einreichen (Abschnitt 8). |
