# get_result

> Get one job

`GET /api/v2/results/{id}`

Status, output once it is done, and what it charged. Keep calling every 15-30 seconds until status is SUCCEEDED, FAILED or CANCELED. An id from the other key mode (test vs live) answers 404. Needs the `results:read` scope.

- Auth: API key (Authorization: Bearer)
- Key scope needed: `results:read`
- Raw spec: https://app.diffusr.ai/api/v2/openapi.json

## Path

| Name | Type | Required | Description |
| --- | --- | --- | --- |
| `id` | string | yes | The job id from a make call. |

## Example

**cURL**

```bash
curl "https://app.diffusr.ai/api/v2/results/run_8Hk2xxxxxxxx" \
  -H "Authorization: Bearer $DIFFUSR_KEY"
```

**TypeScript**

```ts
import { Diffusr } from "diffusr";

const d = new Diffusr(); // reads DIFFUSR_KEY
const result = await d.getResult("run_8Hk2xxxxxxxx");
console.log(result.status, result.output?.url);
```

**Python**

```python
from diffusr import Diffusr

d = Diffusr()  # reads DIFFUSR_KEY
result = d.get_result("run_8Hk2xxxxxxxx")
print(result["status"], result.get("output"))
```

## Response

### 200 ApiResult

The job.

| Name | Type | Required | Description |
| --- | --- | --- | --- |
| `id` | string | yes |  |
| `status` | "PENDING" \| "RUNNING" \| "SUCCEEDED" \| "FAILED" \| "CANCELED" | yes | PENDING and RUNNING = keep waiting. SUCCEEDED, FAILED and CANCELED are final. |
| `model` | string | yes |  |
| `credits_estimated` | number | no |  |
| `created_at` | string | yes |  |
| `finished_at` | string | no |  |
| `output` | object | no | Present once SUCCEEDED. |
| `output.kind` | "IMAGE" \| "VIDEO" \| "AUDIO" | yes |  |
| `output.url` | string | yes | Public link to the file. |
| `output.thumbnail_url` | string | no |  |
| `output.width` | number | no |  |
| `output.height` | number | no |  |
| `output.duration_sec` | number | no |  |
| `error` | object | no | Present when FAILED. |
| `error.code` | string | yes |  |
| `error.message` | string | yes |  |
| `request_id` | string | no | The X-Request-Id of the request that started the job. |
| `test` | true | no | true when a test key made the call: the price is real, nothing real ran. Absent for live keys. |
| `charge` | object | yes |  |
| `charge.quoted_credits` | number \| null | yes | The most the call could charge (null for a run with no API quote). |
| `charge.charged_credits` | number | yes | What the call has charged so far. Work that was never delivered is not counted. A test run is always 0. |
| `charge.final` | boolean | yes | true once the run is over: the number can no longer change. |
| `price` | object | no |  |
| `price.credits` | number | yes | The most this call costs, in whole credits (1 credit = $0.01). |
| `price.usd` | string | yes | The same price in US dollars, e.g. "0.0336". |
| `price.tariff` | "direct" \| "outcome" | yes | "direct" = your prompt goes to the model as sent; "outcome" = a result we shape (Recast, creator video). |
| `price.tariff_version` | string | yes |  |
| `price.expires_at` | string | yes | The quoted price holds until then (ISO time). |
| `next` | string | no | Present while the job is not finished. |

## Errors

Every error body is `{ error, code, request_id, ... }`. See https://diffusr.ai/docs/errors.

- 401: Missing, wrong, revoked or expired API key (code UNAUTHORIZED, KEY_REVOKED, KEY_EXPIRED).
- 403: The key may not do this (SCOPE_DENIED, MODEL_NOT_ALLOWED, TEST_MODE_UNSUPPORTED, ACCOUNT_BLOCKED, allowance_exceeded).
- 404: No such id, or it is not yours, or it belongs to the other key mode (NOT_FOUND).
- 429: Too many requests or jobs (RATE_LIMITED, CONCURRENCY_LIMIT, UPLOAD_QUOTA, …). Wait Retry-After seconds, then retry.
- 500: Our fault (INTERNAL_ERROR). Quote request_id to support.
- 503: Paused or busy (API_PAUSED, MODEL_PAUSED, PROVIDER_PAUSED, PROVIDER_BUSY, UNAVAILABLE). Wait Retry-After seconds, then retry.

## Charges

Free. No credits are spent.
