# Python Quickstart

Use Python `requests` to run the full async redaction flow.

## Prerequisites

- Python 3.9+
- `pip install requests`
- `REDACT_API_KEY` set in your environment

## Example

```python
import os
import time
import requests

api_key = os.environ["REDACT_API_KEY"]
base_url = "https://api.redactpdf.ai"

headers = {
    "X-API-Key": api_key,
    "X-Idempotency-Key": "python-example-001",
}

with open("/absolute/path/contract.pdf", "rb") as f:
    files = [("files", ("contract.pdf", f, "application/pdf"))]
    data = {
        "pii_categories": '["Person","Email","PhoneNumber"]',
        "retention": "ephemeral",
    }

    create = requests.post(f"{base_url}/v1/jobs", headers=headers, files=files, data=data, timeout=60)
    create.raise_for_status()
    job = create.json()

job_id = job["job_id"]
print("created", job_id)

while True:
    status = requests.get(
        f"{base_url}/v1/jobs/{job_id}",
        headers={"X-API-Key": api_key},
        timeout=30,
    )
    status.raise_for_status()
    payload = status.json()

    active = [d for d in payload["documents"] if d["status"] in ["uploaded", "analyzing", "redacting"]]
    if not active:
        break

    time.sleep(2)

for doc in payload["documents"]:
    if doc["status"] != "redacted":
        print("skipping", doc["file_name"], doc["status"])
        continue

    output = requests.get(
        f"{base_url}/v1/documents/{doc['id']}/output",
        headers={"X-API-Key": api_key},
        timeout=120,
    )
    output.raise_for_status()

    target = doc["file_name"].replace(".pdf", "") + "-redacted.pdf"
    with open(target, "wb") as wf:
        wf.write(output.content)

    print("saved", target)
```

## Next steps

- [Jobs API reference](https://redactpdf.ai/docs/api-reference/jobs.md)
- [Error handling guide](https://redactpdf.ai/docs/guides/error-handling.md)
