# Jobs API

Jobs are the core async unit in the Redact PDF AI API.

Each job can include one or many PDF documents.

## `POST /v1/jobs`

Create a redaction job by uploading files as `multipart/form-data`.

### Headers

- `X-API-Key` (required)
- `X-Idempotency-Key` (optional, recommended)

### Form fields

- `files` (required): one or more PDF files
- `pii_categories` (optional): JSON array string, for example `["Person","Email","PhoneNumber"]`. See [PII categories](https://www.redact-pdf.ai/docs/guides/pii-categories.md).
- `pii_included_terms` (optional): JSON array string of terms to **always** redact, even when not detected as PII. See [Redaction rules](https://www.redact-pdf.ai/docs/guides/redaction-rules.md).
- `pii_excluded_terms` (optional): JSON array string of terms to **never** redact, even when detected as PII. See [Redaction rules](https://www.redact-pdf.ai/docs/guides/redaction-rules.md).
- `retention` (optional): `ephemeral` or `studio` (default `ephemeral`)

Omitted `pii_*` fields fall back to the API key owner's dashboard defaults.

### cURL example

```bash
curl -sS -X POST "https://www.redact-pdf.ai/v1/jobs" \
  -H "X-API-Key: YOUR_API_KEY" \
  -H "X-Idempotency-Key: customer-123-invoice-456" \
  -F 'files=@/absolute/path/document.pdf;type=application/pdf' \
  -F 'pii_categories=["Person","Email","PhoneNumber","Address"]' \
  -F 'pii_included_terms=["Project Titan"]' \
  -F 'pii_excluded_terms=["Acme Corp"]' \
  -F 'retention=ephemeral'
```

### Response example

```json
{
  "job_id": "b3f2b2e0-6f30-4f3e-8a7b-2f2a20a7d91c",
  "status": "analyzing",
  "retention": "ephemeral",
  "created_at": "2026-02-14T12:05:44Z",
  "documents": [
    {
      "id": "7f4f4f85-6b7a-4f88-9a8a-7b9a6a2d2fd0",
      "file_name": "document.pdf",
      "status": "uploaded",
      "page_count": 3,
      "error_message": null
    }
  ]
}
```

## Large files: direct-to-blob upload

For large PDFs, avoid streaming bytes through the API. Use the two-step flow so
the file goes straight to storage:

1. `POST /v1/jobs/init` with file metadata (JSON) — returns a `job_id` and one
   short-lived `upload_url` per file. Accepts the same redaction config
   (`pii_categories`, `pii_included_terms`, `pii_excluded_terms`, `retention`)
   and `X-Idempotency-Key`. **PDFs only** (images use multipart `POST /v1/jobs`).
2. `PUT` each file directly to its `upload_url` (`x-ms-blob-type: BlockBlob`).
3. `POST /v1/jobs/{job_id}/commit` — verifies the blobs landed and releases the
   job. Idempotent; safe to retry.

```bash
# 1. reserve
curl -sS -X POST "https://www.redact-pdf.ai/v1/jobs/init" \
  -H "X-API-Key: YOUR_API_KEY" -H "Content-Type: application/json" \
  -d '{"files":[{"filename":"big.pdf","content_type":"application/pdf","size_bytes":12345678}],"retention":"ephemeral"}'

# 2. upload straight to the returned upload_url
curl -sS -X PUT "<upload_url>" \
  -H "x-ms-blob-type: BlockBlob" -H "Content-Type: application/pdf" \
  --data-binary @big.pdf

# 3. commit
curl -sS -X POST "https://www.redact-pdf.ai/v1/jobs/JOB_ID/commit" \
  -H "X-API-Key: YOUR_API_KEY"
```

## `GET /v1/jobs/{job_id}`

Get current status for a job and all documents.

### cURL example

```bash
curl -sS -X GET "https://www.redact-pdf.ai/v1/jobs/JOB_ID" \
  -H "X-API-Key: YOUR_API_KEY"
```

### Job lifecycle

Documents move through:

- `uploaded`
- `analyzing`
- `redacting`
- `redacted` (terminal success)
- `error` (terminal failure)

A job is considered complete when all documents are terminal.

## `DELETE /v1/jobs/{job_id}`

Delete a job and purge associated data (subject to retention policy).

### cURL example

```bash
curl -sS -X DELETE "https://www.redact-pdf.ai/v1/jobs/JOB_ID" \
  -H "X-API-Key: YOUR_API_KEY"
```

### Response example

```json
{
  "success": true
}
```

## Errors

Common status codes:

- `400`: invalid request
- `401`: unauthorized
- `402`: quota exceeded
- `404`: job not found
- `429`: rate limited

See [Error handling](https://www.redact-pdf.ai/docs/guides/error-handling.md) for retry strategy.
