# Pull contracts (/guides/pull-contracts)

Pull contracts after [Set up your product](/guides/setup/) publishes a revision. Use Python 3.11 through 3.14. Install the SDK in your project's Python environment and copy its merchant test key from recuut:

```bash
pip install "recuut>=0.11.0"
export RECUUT_API_KEY="recuut_test_..."
```

The CLI uses `https://api.recuut.com` by default. For a local or staging deployment, set `RECUUT_API_URL` to its API origin before pulling, or pass `--api-url` to the command. Use that same origin for your application and transaction receipt checks.

Generate a top-level `recuut_contracts` package so the imports match these guides. Configure its location in `pyproject.toml`:

```toml title="pyproject.toml"
[tool.recuut]
contracts-output-dir = "recuut_contracts"
```

Download the published revisions for the merchant API key in your environment:

```bash
recuut pull-contracts -v
```

The command prints planned changes before it writes files. Commit the generated files. In CI, run this check with the key you generated them with:

```bash
recuut pull-contracts --check
```

`--check` compares every published revision visible to that key, so test and live catalogs can differ. [Go live](/guides/go-live/) covers the live check.

For the **Text generation API** example, the configured directory becomes a Python package containing `__init__.py` and a resource module such as `text_generator__generated.py`. The package re-exports names such as `TextGenerationV1`, `TextGenerationV1Payment`, and `TextGenerationV1ReportedValues`, which are used in the framework guides. The generated payment's `complete(...)` method requires every variable marked **Output**. Input variables must be supplied before access: FastAPI reads them from validated handler arguments, while Django passes them to `payment.access(...)` after serializer validation. The module name comes from the resource key; class names come from the revision name and number. Use the imports printed by `recuut pull-contracts -v`.

If no published revision is visible, verify that the test key belongs to the expected workspace and that the revision is published. If `--check` reports drift, rerun the verbose pull, review the diff, and commit the generated change. For authentication or connection errors, fix the key or API origin first. A new revision can produce new types because its usage contract changed. A price change does not change the variables.

Then protect a route with [FastAPI](/guides/fastapi/) or [Django](/guides/django/). To generate a standalone app for one revision instead, [try an example](/guides/example/).
