# Quickstart

> Create a workspace, make an API key and run your first text and image checks with cURL, JavaScript fetch or Python requests.

Source: https://fileverity.com/en/docs/quickstart

This page takes you from sign-up to your first results. You need a Fileverity login, a terminal with curl and jq and, for the image example, a JPEG, PNG or WebP file.

## 1. Open the Console

Sign in at [fileverity.com/console](https://fileverity.com/console) with an email code or Google. Your first sign-in creates a personal workspace with its own prepaid balance.

Your first workspace starts with 5 free image or document checks and 5,000 free text characters. No card is needed. One free start per person, and a limited number per company email domain. Teammates should join through an invitation. The free start is used before your balance. See [Pricing and billing](https://fileverity.com/en/docs/pricing.md#free-start).

## 2. Create an API key

Open **API keys**, choose **Create key**, name it and pick a mode. Create a **Test** key first: it returns fixed sample results, never calls a model and is never charged. The full key is shown once, so copy it now.

Keep the key out of source control and out of browser code. Export it as an environment variable:

**Environment: Shell**

```bash
export FILEVERITY_API_KEY=fv_test_...
```

## 3. Verify your key

`GET /models` works with any valid key and is never charged. A `200` response that lists the models means the key is good. A `401` means the key is missing, mistyped or revoked.

**Verify your key: cURL**

```bash
curl -i https://api.fileverity.com/v1/models \
  -H "Authorization: Bearer $FILEVERITY_API_KEY"
```

**Verify your key: JavaScript**

```javascript
const response = await fetch("https://api.fileverity.com/v1/models", {
  headers: { Authorization: "Bearer " + process.env.FILEVERITY_API_KEY },
});
console.log(response.status);
```

**Verify your key: Python**

```python
import os
import requests

response = requests.get("https://api.fileverity.com/v1/models", headers={"Authorization": "Bearer " + os.environ["FILEVERITY_API_KEY"]})
print(response.status_code)
```

## 4. Check some text

Send plain text of at least 100 words to `POST /text/detections`. The examples read the text from a file, so save any passage of 100 words or more as `essay.txt` first. This command writes a sample:

**Write essay.txt**

```bash
cat > essay.txt <<'EOF'
Honestly, the delivery was a mess. The driver turned up at six in the evening,
the pallet was wet on one side, and nobody at the depot would pick up the
phone until Monday. I photographed everything before signing, which is the
only reason we have a leg to stand on. In today's fast-paced logistics
landscape, it is essential for businesses to prioritize reliable delivery
performance, as timely and undamaged shipments play a pivotal role in
fostering customer trust and long-term satisfaction. We lost two days. Marta
rebuilt the schedule by hand and the Leeds order still went out late. Moving
forward, it is crucial to implement robust quality assurance measures and
establish clear communication channels, ensuring that all stakeholders remain
aligned and that potential issues are proactively addressed. For now I am
asking for a credit note and a named contact. Not another apology.
EOF
```

**First text check: cURL**

```bash
curl https://api.fileverity.com/v1/text/detections \
  -H "Authorization: Bearer $FILEVERITY_API_KEY" \
  -H "Content-Type: application/json" \
  -d "$(jq -Rs '{text: .}' essay.txt)"
```

**First text check: JavaScript**

```javascript
import { readFile } from "node:fs/promises";

const response = await fetch("https://api.fileverity.com/v1/text/detections", {
  method: "POST",
  headers: {
    Authorization: "Bearer " + process.env.FILEVERITY_API_KEY,
    "Content-Type": "application/json",
  },
  body: JSON.stringify({ text: await readFile("essay.txt", "utf8") }),
});
const detection = await response.json();
if (!response.ok) throw new Error(detection.error.code + ": " + detection.error.message);
console.log(detection.verdict, detection.ai_fraction);
```

**First text check: Python**

```python
import os
import requests

response = requests.post(
    "https://api.fileverity.com/v1/text/detections",
    headers={"Authorization": "Bearer " + os.environ["FILEVERITY_API_KEY"]},
    json={"text": open("essay.txt", encoding="utf-8").read()},
)
detection = response.json()
if not response.ok:
    raise RuntimeError(detection["error"]["code"] + ": " + detection["error"]["message"])
print(detection["verdict"], detection["ai_fraction"])
```

With a test key the response is a fixed result for human-written text. With a live key it looks like this:

**Response, live key**

```json
{
  "id": "tdet_8Hk2pQ4vN9sL1xR7cW3mY6zB",
  "object": "text.detection",
  "created": 1793664000,
  "model": "fvdoc-3-text-2026-11-03",
  "livemode": true,
  "language": "en",
  "verdict": "mixed",
  "score": 0.97,
  "ai_fraction": 0.41,
  "segments": [
    {
      "start": 212,
      "end": 433,
      "score": 0.97
    },
    {
      "start": 579,
      "end": 790,
      "score": 0.93
    }
  ],
  "usage": {
    "characters": 1412,
    "free_characters": 0,
    "billed_units": 2
  }
}
```

Details, including how offsets work, are on [Text detections](https://fileverity.com/en/docs/text-detections.md).

## 5. Check an image

Images and documents take two calls: upload the file, then create an analysis that references it. An analysis is one image or document check. `Prefer: wait=60` holds the request until the result is ready, for up to 60 seconds.

**First image check: cURL**

```bash
FILE_ID=$(curl -s https://api.fileverity.com/v1/files \
  -H "Authorization: Bearer $FILEVERITY_API_KEY" \
  -F file=@photo.jpg | jq -r .id)

curl https://api.fileverity.com/v1/analyses \
  -H "Authorization: Bearer $FILEVERITY_API_KEY" \
  -H "Content-Type: application/json" \
  -H "Prefer: wait=60" \
  -d "{\"model\": \"fvimg-2\", \"file\": \"$FILE_ID\"}"
```

**First image check: JavaScript**

```javascript
import { readFile } from "node:fs/promises";

const headers = { Authorization: "Bearer " + process.env.FILEVERITY_API_KEY };

const form = new FormData();
form.append("file", new Blob([await readFile("photo.jpg")], { type: "image/jpeg" }), "photo.jpg");
const file = await (await fetch("https://api.fileverity.com/v1/files", { method: "POST", headers, body: form })).json();

const response = await fetch("https://api.fileverity.com/v1/analyses", {
  method: "POST",
  headers: { ...headers, "Content-Type": "application/json", Prefer: "wait=60" },
  body: JSON.stringify({ model: "fvimg-2", file: file.id }),
});
const analysis = await response.json();
console.log(analysis.status, analysis.summary, analysis.report_url);
```

**First image check: Python**

```python
import os
import requests

headers = {"Authorization": "Bearer " + os.environ["FILEVERITY_API_KEY"]}

file = requests.post("https://api.fileverity.com/v1/files", headers=headers, files={"file": open("photo.jpg", "rb")}).json()

response = requests.post(
    "https://api.fileverity.com/v1/analyses",
    headers={**headers, "Prefer": "wait=60"},
    json={"model": "fvimg-2", "file": file["id"]},
)
analysis = response.json()
print(analysis["status"], analysis["summary"], analysis["report_url"])
```

A finished analysis returns `200` with `status: succeeded`, a short `summary` and the full `result.report`. If the wait runs out first, you get `202` with `status: processing`; fetch it later with `GET /analyses/{id}` or receive a webhook. See [Analyses](https://fileverity.com/en/docs/analyses.md).

**Response, live key**

```json
{
  "id": "an_8Hk2pQ4vN9sL1xR7cW3mY6zB",
  "object": "analysis",
  "created": 1793700120,
  "model": "fvimg-2-2026-10-30",
  "livemode": true,
  "status": "succeeded",
  "file": {
    "name": "claim-photo.jpg",
    "bytes": 2481920,
    "format": "jpeg"
  },
  "report_id": "FV-7K2M-9QXD-4T8R",
  "report_url": "https://fileverity.com/verify/FV-7K2M-9QXD-4T8R",
  "summary": {
    "level": "L2",
    "assessment": "authentic_untouched",
    "action": "accept",
    "ai": "very_low",
    "edit": "none"
  },
  "result": {
    "report": {
      "schema": "fileverity.report/1",
      "id": "FV-7K2M-9QXD-4T8R"
    },
    "stamped_at": 1793700130
  },
  "error": null,
  "progress": null,
  "usage": {
    "amount": 199,
    "currency": "usd",
    "funding": "balance"
  },
  "metadata": {
    "order_id": "A-10492"
  },
  "completed_at": 1793700131,
  "expires_at": 1794304931
}
```

> **Note.** With a test key the file is validated but not stored, and the analysis returns a fixed sample immediately. Its report ID starts with `FV-TEST-` and has no public verification page.

## 6. Go live

- Create a **Live** key in the Console and use it in place of the test key. The same code works unchanged.
- Use the free start, or add funds to your workspace balance in **Balance**. The minimum top-up is US$19.
- Set a monthly spend limit on the key, and add a [webhook endpoint](https://fileverity.com/en/docs/webhooks.md) instead of polling.
- Send an `Idempotency-Key` on POST requests so a retry never runs a check twice. See [Idempotency](https://fileverity.com/en/docs/idempotency.md).

For what each check examines and where teams use it, see the [AI image detection API](https://fileverity.com/en/api/ai-image-detection) and [Document fraud detection API](https://fileverity.com/en/api/document-fraud-detection).

Next: [Sample code](https://fileverity.com/en/docs/sample-code.md) has complete Node.js and Python programs for every check and for webhooks. Then read [Authentication and keys](https://fileverity.com/en/docs/authentication.md), [Errors](https://fileverity.com/en/docs/errors.md) and the [API reference](https://fileverity.com/en/docs/api-reference.md). If something does not work, write to [hello@fileverity.com](mailto:hello@fileverity.com) or use the [contact page](https://fileverity.com/en/contact), and include the request ID from the `x-request-id` header.

