# Read a job's result

> What a succeeded job delivered: its files, one page at a time, and a summary.

`GET https://api.refabric.com/v1/jobs/{job_id}/result`

**Authentication.** A key with `jobs:read`: a job and its files are your account's.

**Key features**

- Pages of 100 files by default, 200 at most; in the order the job delivered them.

**Common use cases**

- Download what a job made once it has succeeded.

**Conflicts.** Until the job has succeeded it answers `409`: `result_not_ready` while it runs, `job_failed` when it failed, `cancelled` when it was cancelled.

**See also**

- `GET /v1/jobs/{job_id}`
- `GET /v1/files/{ref}`

Authentication: `Authorization: Key $REFABRIC_API_KEY`, scope `jobs:read`.

## Path parameters

- `job_id` (string, _required_)

## Query parameters

- `limit` (integer, _optional_, default: `100`, 1 to 200) — Items per page: default 100, at most 200.
- `cursor` (string | null, _optional_) — The previous page's `next_cursor`, copied back as it came, for the next page. Never build one.

## Header parameters

- `Refabric-Version` (string, _optional_, format: date) — The contract version you wrote against (a date). Absent: the current version.
- `X-Request-ID` (string, _optional_, max length 128) — Your own id for this request; we answer it back under X-Client-Request-ID.

## Response 200

Done: the answer is in the body.

- `job_id` (string, _required_) — The job.
  Example: `9b2f4c1d0e8a`
- `files` (array<object>, _required_) — The files, in the order the job delivered them.
  - `url` (string, _required_) — Where the file is. A public, permanent address you can open or download.
    Example: `https://files.refabric.com/art/3f2a.png`
  - `media_type` (string, _required_) — The file's standard media type.
    Example: `image/png`
  - `file` (string, _required_) — Its address; pass it to a task as it is.
    Example: `art:3f2a`
  - `task` (string | null, _optional_) — The task that made it.
    Example: `image.expand`
  - `job_id` (string | null, _optional_) — The job that made it.
    Example: `9b2f4c1d0e8a`
  - `created_at` (string | null, _optional_) — When it was made, ISO-8601 in UTC.
    Example: `2026-10-05T09:30:12Z`
  - `data` (object | null, _optional_) — What the file means, in the record vocabulary.
    - `name` (string | null, _optional_) — The record's name.
      Example: `SS27`
    - `description` (string | null, _optional_) — What the record is, in words.
      Example: `A calm palette.`
    - `status` (string | null, _optional_) — Whether it can be used yet.
      Values: `processing` (Still being made or analysed. Read it again later.); `ready` (Finished. It can be passed to a task.); `failed` (It could not be made. Its content is missing.)
      Example: `ready`
    - `colours` (array<object> | null, _optional_) — Its colours.
      Example: `[{"hex":"#1f2a44"}]`
      - `hex` (string, _required_) — The colour as `#rrggbb`.
        Example: `#1f2a44`
      - `name` (string | null, _optional_) — Its name, when known.
        Example: `Navy`
      - `pantone` (string | null, _optional_) — The nearest Pantone code, when known.
        Example: `19-4024 TCX`
    - `items` (array<object> | null, _optional_) — Its parts (a pose preset: its poses and views).
      Example: `[{"type":"fabric"}]`
      - ItemEntry
        - `type` (string, _required_) — What the part is.
          Values: `fabric` (A fabric: its swatch or a photo of it. When the image is a fabric swatch or a photo of a fabric.); `print` (A print or pattern. When the image is a print or pattern.); `look` (A garment or outfit, as a photo or a design. When the image is a garment or an outfit.); `detail` (A close crop of one detail of a look or a product (a collar, a pocket). When the image is a close crop of one detail.); `design` (One cell of a range plan: a design made for one garment line.); `other` (Any other image the record holds. When the image is none of the other kinds.); `product` (A photo of the product itself, as supplied (`view`: which side). When the photo is the product itself; `view` says which side.); `label` (A photo of the product's label (care, size or brand label). When the photo is of the product's label.); `ghost` (The product on an invisible (ghost) mannequin (`view`: which side). When you want the product shown on an invisible mannequin.); `flat` (The product laid flat, as a flat-lay photo (`view`: which side). When you want the product laid flat.); `close_up` (A close-up of the product's fabric and finish (one per product in a shoot). Not `detail`, which is a crop of one trim or component of a look. When you want a close-up of the product's fabric and finish.)
          Example: `fabric`
        - `view` (string | null, _optional_) — Which side it shows.
          Example: `front`
        - `name` (string | null, _optional_) — Its name.
          Example: `Wool twill`
        - `external_id` (string | null, _optional_) — Your own id for it, when you sent one.
          Example: `SKU-1`
        - `description` (string | null, _optional_) — What it is, in words.
          Example: `A navy wool twill.`
        - `url` (string | null, _optional_) — Its image — pass it to a task as it is.
          Example: `https://files.refabric.com/art/3f2a.png`
        - `status` (string | null, _optional_) — Whether it can be used yet.
          Values: `processing` (Still being made or analysed. Read it again later.); `ready` (Finished. It can be passed to a task.); `failed` (It could not be made. Its content is missing.)
          Example: `ready`
      - PresetItem
        - `kind` (string, _required_) — How the entry names what it wants: a saved pose, an image, words, or a product view.
          Example: `view`
        - `ref` (string, _required_) — The pose's address (`pose:…`); empty for a view.
          Example: `pose:812`
        - `angle` (string | null, _required_) — The pose's camera angle.
          Example: `front`
        - `view` (string | null, _required_) — The product view it shows.
          Example: `back`
    - `keywords` (array<string> | null, _optional_) — Words that sum it up.
      Example: `["tailoring"]`
- `has_more` (boolean, _required_) — More files are on the next page.
  Example: `false`
- `next_cursor` (string | null, _optional_) — Present when `has_more`: send it as `cursor` to the result read for the rest.
- `summary` (object | null, _optional_) — Present when the task has words to count.
  - `requested` (integer | null, _optional_) — Outputs asked for.
    Example: `3`
  - `delivered` (integer | null, _optional_) — Outputs made.
    Example: `2`
  - `warnings` (array<object> | null, _optional_) — Notes on what was not made.
    - `code` (string, _required_) — The warning's catalogue code.
      Example: `output_not_produced`
    - `message` (string, _required_) — What happened, in words.
      Example: `This pose was not made.`
    - `field` (string | null, _optional_) — The request field it is about.
      Example: `poses.items[1]`

```json
{
  "job_id": "9b2f4c1d0e8a",
  "files": [],
  "has_more": false,
  "next_cursor": null,
  "summary": {}
}
```

## Response 400

The request cannot be read as it was sent (a header, the URL or the body's form).

```json
{
  "error": {
    "code": "string",
    "type": "invalid_request",
    "message": "string",
    "field": "string",
    "retryable": true,
    "docs": "string",
    "request_id": "string",
    "ctx": {
      "required": 0,
      "balance": 0,
      "retry_after": 0
    },
    "input": null,
    "job_id": "string",
    "required": 0,
    "balance": 0
  }
}
```

## Response 401

No valid API key was sent.

```json
{
  "error": {
    "code": "string",
    "type": "invalid_request",
    "message": "string",
    "field": "string",
    "retryable": true,
    "docs": "string",
    "request_id": "string",
    "ctx": {
      "required": 0,
      "balance": 0,
      "retry_after": 0
    },
    "input": null,
    "job_id": "string",
    "required": 0,
    "balance": 0
  }
}
```

## Response 403

Your key or your plan does not allow this.

```json
{
  "error": {
    "code": "string",
    "type": "invalid_request",
    "message": "string",
    "field": "string",
    "retryable": true,
    "docs": "string",
    "request_id": "string",
    "ctx": {
      "required": 0,
      "balance": 0,
      "retry_after": 0
    },
    "input": null,
    "job_id": "string",
    "required": 0,
    "balance": 0
  }
}
```

## Response 404

Nothing has this address.

```json
{
  "error": {
    "code": "string",
    "type": "invalid_request",
    "message": "string",
    "field": "string",
    "retryable": true,
    "docs": "string",
    "request_id": "string",
    "ctx": {
      "required": 0,
      "balance": 0,
      "retry_after": 0
    },
    "input": null,
    "job_id": "string",
    "required": 0,
    "balance": 0
  }
}
```

## Response 409

The request conflicts with the current state of what it names.

```json
{
  "error": {
    "code": "string",
    "type": "invalid_request",
    "message": "string",
    "field": "string",
    "retryable": true,
    "docs": "string",
    "request_id": "string",
    "ctx": {
      "required": 0,
      "balance": 0,
      "retry_after": 0
    },
    "input": null,
    "job_id": "string",
    "required": 0,
    "balance": 0
  }
}
```

## Response 422

A field is missing or has a value this operation cannot use.

```json
{
  "error": {
    "code": "string",
    "type": "invalid_request",
    "message": "string",
    "field": "string",
    "retryable": true,
    "docs": "string",
    "request_id": "string",
    "ctx": {
      "required": 0,
      "balance": 0,
      "retry_after": 0
    },
    "input": null,
    "job_id": "string",
    "required": 0,
    "balance": 0
  }
}
```

## Response 429

Too many requests: wait for the number of seconds in the Retry-After header.

```json
{
  "error": {
    "code": "string",
    "type": "invalid_request",
    "message": "string",
    "field": "string",
    "retryable": true,
    "docs": "string",
    "request_id": "string",
    "ctx": {
      "required": 0,
      "balance": 0,
      "retry_after": 0
    },
    "input": null,
    "job_id": "string",
    "required": 0,
    "balance": 0
  }
}
```

## Response 500

Something went wrong on our side; retry, and quote the request id if it keeps happening.

```json
{
  "error": {
    "code": "string",
    "type": "invalid_request",
    "message": "string",
    "field": "string",
    "retryable": true,
    "docs": "string",
    "request_id": "string",
    "ctx": {
      "required": 0,
      "balance": 0,
      "retry_after": 0
    },
    "input": null,
    "job_id": "string",
    "required": 0,
    "balance": 0
  }
}
```

## Request

```python
import os
import requests

url = "https://api.refabric.com/v1/jobs/{job_id}/result"

headers = {"Authorization": f"Key {os.environ['REFABRIC_API_KEY']}"}

response = requests.get(url, headers=headers)

print(response.json())
```

```javascript
const url = 'https://api.refabric.com/v1/jobs/{job_id}/result';
const options = {method: 'GET', headers: {Authorization: `Key ${process.env.REFABRIC_API_KEY}`}};

try {
    const response = await fetch(url, options);
    const data = await response.json();
    console.log(data);
} catch (error) {
    console.error(error);
}
```

```bash
curl --request GET \
    --url https://api.refabric.com/v1/jobs/{job_id}/result \
    --header "Authorization: Key $REFABRIC_API_KEY"
```
