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

# Guía rápida

OpenQASM 3 de entrada, counts canónicos de salida. El camino feliz completo; cada campo está en la [referencia de la API](https://pauli.xyz/reference), la especificación cruda en [`/openapi.json`](https://pauli.xyz/openapi.json).

## 0 · Obtener una clave

[Cree un espacio de trabajo](https://pauli.xyz/es/signup), obtenga una clave de administrador; cada cliente de abajo la lee del entorno:

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

## 1 · Qiskit

Cada dispositivo del registro es un `BackendV2` de Qiskit: elija uno, ejecute y lea los counts en el orden de claves propio de Qiskit. Las ejecuciones quedan fijadas al backend elegido, nunca un fallback silencioso:

```
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}
```

El resto de esta página usa `provider.client`, el cliente tipado completo bajo cada backend: dinero como `Decimal` exacto (un float lanza excepción), una clave de idempotencia en cada envío, excepciones ligadas a los códigos estables de abajo.

## 2 · Estimar la flota (gratis)

Una sola llamada cotiza *su* circuito en cada dispositivo elegible, con cola prevista, fidelidad y exclusiones razonadas:

```
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 · Enviar con una política

Elija `cheapest`, `fastest`, `highest_fidelity` o `balanced`; fije un dispositivo, o restrinja por proveedor, precio, cola o región. El job vuelve de inmediato con la decisión de routing y el costo exacto; cada envío lleva una clave de idempotencia (autogenerada salvo que pase la suya), así que un reintento nunca puede duplicar el envío:

```
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)
```

Un fallo previo a la ejecución recurre al siguiente mejor dispositivo, salvo con `allow_fallback=False`; cada salto queda registrado, y usted paga solo por el dispositivo que ejecutó.

## 4 · Sondear, o recibir el webhook

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

Con un `webhook_url` (solo https), cada transición de estado hace un POST una vez, firmado con el secreto de webhook de la clave que envió (mostrado al crear la clave); deduplique por `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")
```

El SDK incluye esta receta como `pauli_sdk.webhooks.unwrap(body, headers, secret=…)`.

## 5 · Resultados: un solo orden de bits

```
{
  "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"}
}
```

**La convención de counts**: el carácter más a la izquierda de cada clave es el bit clásico 0 del primer registro declarado; los registros se aplanan en orden de declaración. Todos los proveedores se normalizan a ella; el código de análisis nunca se bifurca.

**Insights**: una clasificación orientativa de la forma del histograma (estado gato, uniforme, peine periódico, moteado de Porter-Thomas, …) con un titular en lenguaje llano y una confianza ajustada al número de shots, derivada solo de los counts. Una ayuda de lectura, nunca una superficie de puntuación.

## 6 · Sus propias credenciales (BYOK)

Registre credenciales (/console/credentials o `PUT /v1/credentials/{provider}`) y los jobs de ese proveedor se ejecutan bajo su cuenta: el proveedor le factura directamente; su monedero paga solo la tarifa de plataforma ([precios](https://pauli.xyz/es/pricing)). Estimaciones, estado y resultados muestran `byok`; el fallback nunca cruza modos de facturación.

## 7 · Agentes (MCP)

Model Context Protocol en `https://pauli.xyz/mcp` (Streamable HTTP), con la misma clave bearer. Las herramientas reflejan el flujo de esta página.

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

## 8 · Pagar desde un agente

Un envío de pago que supere su saldo devuelve `402` `billing.insufficient_credits`; su `detail` es un desafío de pago que nombra el faltante, el endpoint de recarga y cómo confirmar el abono. Fóndelo (las recargas devuelven un `checkout_url` alojado para que lo complete una persona) y reenvíe con la misma `Idempotency-Key`. La recarga automática (`PATCH /v1/billing/settings`) repone desde una tarjeta guardada antes de que los jobs vean el 402. Los resultados de las herramientas MCP llevan el mismo desafío, textual.

Los otros 402, `billing.monthly_cap_exceeded` y `billing.key_cap_exceeded`, son topes que usted fija; no llevan desafío. Suba el tope si el gasto es intencional.

---

## Errores

Cada error es `{"error": {"code", "message", "detail?", "request_id"}}` con un código estable; el registro es [`/public/errors`](https://pauli.xyz/public/errors). Cite el `request_id` a soporte. Los primeros que encontrará:

| Código | Significado |
| --- | --- |
| program.invalid | El OpenQASM 3 no parseó; el detail lleva línea y columna. |
| routing.no_feasible_device | Nada puede ejecutar este programa bajo sus restricciones; el detail lista las razones por dispositivo. |
| billing.insufficient_credits | 402: fonde el faltante y reenvíe (sección 8). |
