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

# Audits

> Check a photo you already have.

A verification certifies a photo taken live, right now, through a link. An **audit** checks a file that already exists: a photo someone emailed you, one sitting in your system, one you downloaded. No link, no camera, no person on the other end.

By default Rial runs three checks on every audited file: is it a photo of a screen, does it look AI-generated, and is it already online. Describe the photo (`expectedObject`, `context`) and it also checks that it shows that; send `conditionAspects` and it scores the condition. Because no device stood behind the photo, there is no `rial: true/false`; you get the checks that tripped and decide.

## One call

```ts theme={"dark"}
import { readFile } from 'node:fs/promises';
import { createRial } from '@rial/sdk';

const rial = createRial({ apiKey: process.env.RIAL_API_KEY });

const result = await rial.audits.run({
  file: await readFile('claim-9912.jpg'),
  contentType: 'image/jpeg',
  expectedObject: '2021 Toyota Corolla',
  conditionAspects: ['paint', 'bumper'],
  metadata: { claimId: 'CLM-9912' },
});
```

`audits.run` uploads the file, starts the analysis and waits for the result. It takes a few seconds.

## What you get back

```json theme={"dark"}
{
  "id": "vfy_…",
  "status": "completed",
  "verdict": { "signals": [{ "type": "ai_detected", "confidence": 0.81 }] },
  "objectMatch": { "status": "match" },
  "condition": { "score": 7.5, "label": "good" }
}
```

* `verdict.signals` lists the checks that tripped. Empty means every check that ran came back clean. `screen_detected` is a photo of a screen, `ai_detected` an AI-generated image, `found_online` an image already published. One check tripping never stops the others, so two can appear together.
* `objectMatch` says whether the photo shows your `expectedObject`.
* `condition` scores each aspect 0 to 10 with a one-line reason.

Every field is explained in [Verdicts](https://docs.rial.io/verdicts.md).

## Don't wait

`audits.create` uploads and starts the analysis, then returns at once. Read the result later with `verifications.get(id)`, or pass `webhookUrl` and Rial POSTs `verification.completed` to you.

```ts theme={"dark"}
const started = await rial.audits.create({
  file,
  contentType: 'image/jpeg',
  webhookUrl: 'https://your.app/rial',
  metadata: { claimId: 'CLM-9912' },
});
started.id; // vfy_…
```

## Only AI detection

Pass `checks` to run only the checks you name. `checks: ['ai']` will check for AI generation, skipping screen detection and found online.

```ts theme={"dark"}
const result = await rial.audits.run({
  file: await readFile('receipt-4471.jpg'),
  contentType: 'image/jpeg',
  checks: ['ai'],
  metadata: { orderId: 'ORD-4471' },
});

result.verdict?.signals; // [] or [{ type: 'ai_detected', confidence: 0.93 }]
```

`checks` takes any of `'screen'`, `'ai'` and `'reverse'` (found online). Leave it out and all three run.

Available today in the [sandbox](https://docs.rial.io/sandbox.md), and in production with the next release. Needs `@rial/sdk` 0.4.0 or later.

## AI only, in one call

Send the photo and get the verdict back in the same response. Available today in the [sandbox](https://docs.rial.io/sandbox.md), and in production with the next release.

```bash theme={"dark"}
curl https://sandbox.api.rial.io/v1/audits/sync \
  -H "Authorization: Bearer $RIAL_API_KEY" \
  -F image=@receipt-4471.jpg \
  -F checks=ai \
  -F 'metadata={"orderId":"ORD-4471"}'
```

| Field | Required | What it is |
| - | - | - |
| `image` | yes | The photo: JPEG, PNG, WebP, HEIC or HEIF, up to 4 MB. |
| `checks` | no | Only `ai`. |
| `metadata` | no | JSON object with your own keys, returned with the result and in webhooks. |
| `webhook_url` | no | HTTPS URL that also receives the result. |

| Status | What it means |
| - | - |
| `201` | The verdict is in the body, same shape as `GET /v1/verifications/{id}`. |
| `202` | The photo is stored and the analysis finishes in the background. Read it with `GET /v1/verifications/{id}` or wait for the webhook. |
| `413` `image_too_large_for_sync` | Over 4 MB. Use the regular flow. |
| `415` | Not `multipart/form-data`, or not a supported image. |
| `422` `checks_not_supported` | Asked for other checks. Use the regular flow. |
| `429` `too_many_requests` | Over 8 audits per second in the sandbox. Wait `Retry-After` seconds. |

Other checks, `expectedObject`, `conditionAspects` and `context` go through the regular flow above.

## Input

| Field | Required | What it is |
| - | - | - |
| `file` | yes | The bytes: a `Buffer`, `Uint8Array` or `Blob`. |
| `contentType` | yes | `image/jpeg`, `image/png`, `image/webp`, `image/heic` or `image/heif`. |
| `expectedObject` | no | What must appear in the photo. Turns on the object check. |
| `conditionAspects` | no | Aspects to score, up to 6. Turns on the condition check. |
| `context` | no | `{ kind, summary }` describing what the photo is supposed to show. Turns on the context check. |
| `checks` | no | Run only these: `'screen'`, `'ai'`, `'reverse'`. Default: all three. |
| `webhookUrl` | no | HTTPS URL that receives the result. |
| `metadata` | no | Your own keys, returned with the result and in webhooks. |

Audits are billed like verifications. They go through the Node SDK today, or `POST /v1/audits/sync` for AI only; for another language, write to [developers@rial.io](mailto:developers@rial.io).


This documentation is built and hosted on [Mintlify](https://mintlify.com), a developer documentation platform.