---
title: "Quickstart"
url: https://docs.agentsverify.dev/quickstart
---

# Quickstart

Verify one address or a larger list with the same flow: create a verification, upload a CSV, then read saved progress and results.

## 1\. Get your key and check credits

[](https://docs.agentsverify.dev/quickstart#1-get-your-key-and-check-credits)

Copy your key from the [dashboard](https://app.agentsverify.dev/dashboard/api-keys) and store it as `AGENTS_VERIFY_API_KEY` in your terminal or server environment.

```
curl --fail-with-body 'https://api.agentsverify.dev/v1/credits' \  --header "X-API-Key: ${AGENTS_VERIFY_API_KEY:?Set your API key}"
```

The `credits` value is your available balance. This read does not reserve credits. For current file-size and row limits, call `GET /v1/verifications`.

## 2\. Prepare a CSV

[](https://docs.agentsverify.dev/quickstart#2-prepare-a-csv)

Create a one-column UTF-8 file named `contacts.csv`, with an explicit `email` header and your addresses below it:

```
emailperson@example.com
```

The address above is a format example. Use your own addresses for real verification. Standard CSV quoting, an optional initial BOM and LF or CRLF are supported. Blank records, extra columns or malformed addresses reject the whole file before checks or credit holds. Duplicates are checked once.

## 3\. Create and upload

[](https://docs.agentsverify.dev/quickstart#3-create-and-upload)

Generate a UUID and save it as `REQUEST_ID` before the first request. Reuse it when recovering that same submission.

Creation is a bodyless POST. Compute the byte length from the actual file:

```
curl --request POST 'https://api.agentsverify.dev/v1/verifications' \  --fail-with-body \  --header "X-API-Key: ${AGENTS_VERIFY_API_KEY:?Set your API key}" \  --header "Idempotency-Key: ${REQUEST_ID:?Set and save a UUID first}" \  --header "X-Upload-Content-Length: $(wc -c < contacts.csv)" \  --header "X-Upload-Filename: contacts.csv"
```

HTTP `201` creates a verification; HTTP `200` recovers it. Save the returned `id`. When the receipt contains `upload`, PUT the CSV bytes to `upload.url` without API credentials.

This Node.js example performs both stages. Save it as `upload.mjs` and run `node upload.mjs contacts.csv` with both environment variables set:

```
async function uploadCsv(filePath, apiKey, idempotencyKey) {  const {readFile} = await import('node:fs/promises');  const {basename} = await import('node:path');  if (!apiKey || !idempotencyKey) {    throw new Error('Set AGENTS_VERIFY_API_KEY and your saved REQUEST_ID');  }  const csv = await readFile(filePath);  if (csv.length === 0) throw new Error('The CSV file is empty');  const filename = encodeURIComponent(basename(filePath));  const created = await fetch('https://api.agentsverify.dev/v1/verifications', {    method: 'POST', redirect: 'manual',    headers: {      'X-API-Key': apiKey,      'Idempotency-Key': idempotencyKey,      'X-Upload-Content-Length': String(csv.length),      'X-Upload-Filename': filename    }  });  const receipt = await created.json();  if (created.status !== 200 && created.status !== 201) {    throw new Error(receipt.issue?.message || 'API request rejected');  }  if (receipt.upload) {    const stored = await fetch(receipt.upload.url, {      method: 'PUT', body: csv, credentials: 'omit', redirect: 'manual',      headers: {        'Content-Type': 'text/csv',        'Content-Range': 'bytes 0-' + (csv.length - 1) + '/' + csv.length,        'X-Goog-Meta-Original-Filename': filename      }    });    if (stored.status === 308) {      throw new Error('Upload incomplete: resume the saved session');    }    if (stored.status !== 200 && stored.status !== 201) {      throw new Error('Storage rejected the upload (HTTP ' + stored.status + ')');    }  }  return receipt.id;}
const verificationId = await uploadCsv(  process.argv[2] || 'contacts.csv',  process.env.AGENTS_VERIFY_API_KEY,  process.env.REQUEST_ID);console.log('Verification ID:', verificationId);
```

The example transfers a whole file. It does not resume incomplete transfers. Storage HTTP `200` or `201` confirms receipt. After confirmation, the job can briefly remain `uploading` while the backend detects completion. Continue polling instead of re-uploading.

## 4\. Follow progress and download results

[](https://docs.agentsverify.dev/quickstart#4-follow-progress-and-download-results)

Poll `GET /v1/verifications/{id}` and respect `Retry-After`. Read `issue` for actionable guidance. Whole-file validation and processing start automatically; no completion or batching call is needed.

Download `GET /v1/verifications/{id}/results` for finalized CSV outcomes. Partial results contain finished checks; a header-only CSV means none are available yet. Read saved results again without submitting another verification.

Continue with the [complete workflow](https://docs.agentsverify.dev/guides/verification-workflow), [results and credits](https://docs.agentsverify.dev/guides/results-and-credits) or [endpoint reference](https://docs.agentsverify.dev/api-reference).

## Resume an interrupted upload

[](https://docs.agentsverify.dev/quickstart#resume-an-interrupted-upload)

Send an empty PUT to the same private `upload.url` with `Content-Range: bytes */<total bytes>`. HTTP `200` or `201` means complete. A `308` response identifies persisted bytes in `Range`. Continue at the next byte, or byte zero if no Range is present, following the [storage resumption protocol](https://docs.cloud.google.com/storage/docs/performing-resumable-uploads#resume-upload).

Keep omitting API credentials from storage requests. Recover an uncertain API creation using the original `Idempotency-Key`; a new identity creates new work and can charge again.
