> ## Documentation Index
> Fetch the complete documentation index at: https://docs.r3al.ai/llms.txt
> Use this file to discover all available pages before exploring further.

# Jobs: upload, quantize, qat, download

> Upload a model, submit a job, poll it, and download the deliverable.

Quantization jobs run on R3AL GPU infrastructure. The flow is always: upload the model, submit the job (which returns a `job_id`), poll the job, then download its artifacts.

## Upload a model

Models are uploaded to R2 with a presigned PUT. Ask for a grant, then `PUT` the file bytes to the returned URL.

```bash theme={null}
curl -X POST https://platform.r3al.ai/v1/uploads \
  -H "Authorization: Bearer r3l_live_..." \
  -H "Content-Type: application/json" \
  -d '{"filename": "model.onnx", "content_type": "application/octet-stream", "size_bytes": 10485760}'
```

```json theme={null}
{ "upload_url": "https://...presigned...", "object_key": "uploads/ab12/model.onnx" }
```

`PUT` the file to `upload_url`, then reference it in a job as `r2://<object_key>`. Single uploads are limited to 5 GB. Calibration images are uploaded the same way.

## Submit a job

Jobs accept `r2://<key>` model references and always return `202` with a `job_id`.

| Endpoint            | Purpose                                                    | Notes                                           |
| ------------------- | ---------------------------------------------------------- | ----------------------------------------------- |
| `POST /v1/quantize` | PTQ: model in, quantized ONNX out                          | `method`: `ptq_static` (default), `ptq_dynamic` |
| `POST /v1/qat`      | QAT: model + `calibration_data`, train, quantized ONNX out | Always async                                    |

```bash theme={null}
curl -X POST https://platform.r3al.ai/v1/quantize \
  -H "Authorization: Bearer r3l_live_..." \
  -H "Content-Type: application/json" \
  -d '{"model": "r2://uploads/ab12/model.onnx", "method": "ptq_static", "calibration_data": ["r2://uploads/ab12/img1.jpg"]}'
```

```json theme={null}
{ "job_id": "job_abc123", "status": "pending" }
```

<Note>
  Both `quantize` and `qat` are asynchronous: they return a `job_id` immediately, since a run can take longer than an HTTP client's timeout. Poll the job for progress and the result.
</Note>

## Poll a job

```bash theme={null}
curl https://platform.r3al.ai/v1/jobs/job_abc123 \
  -H "Authorization: Bearer r3l_live_..."
```

```json theme={null}
{
  "job_id": "job_abc123",
  "status": "running",
  "progress": 62.0,
  "progress_message": "calibrating",
  "result": null
}
```

`status` moves through `pending`, `running`, then a terminal `completed` or `error`. On `completed`, `result` carries the deliverable metadata; on `error`, an `error` object with a `code` and message.

## Download artifacts

Once a job is `completed`, request presigned download URLs for its artifacts.

```bash theme={null}
curl https://platform.r3al.ai/v1/jobs/job_abc123/artifacts \
  -H "Authorization: Bearer r3l_live_..."
```

```json theme={null}
{
  "artifacts": [
    { "filename": "model.quantized.zip", "url": "https://...presigned-get..." }
  ]
}
```

Download each `url` (presigned GET). The bundle contains the quantized ONNX model and `r3alai_manifest.json`.

## Delete a job

```bash theme={null}
curl -X DELETE https://platform.r3al.ai/v1/jobs/job_abc123 \
  -H "Authorization: Bearer r3l_live_..."
```

Removes the job and its artifacts. `404` if the id does not exist.

## Usage and plan

```bash theme={null}
curl https://platform.r3al.ai/v1/usage \
  -H "Authorization: Bearer r3l_live_..."
```

Returns your plan and remaining free runs. Each `quantize` or `qat` job consumes one run; a run beyond your quota fails with `402 plan_limit_reached` (see [Errors](/api/errors)).

## Method field

`method` applies to `POST /v1/quantize` only:

* `ptq_static` (default): requires `calibration_data` (a list of uploaded image refs).
* `ptq_dynamic`: no calibration data needed; it quantizes MatMul and Gemm layers, so it suits MatMul-heavy models rather than convolution-heavy backbones.

QAT settings (`wbit`, `abit`, `epochs`) go on `POST /v1/qat`. See the [Python SDK](/sdk/quantizer) for the field-level reference; only the transport differs.
