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

# Async Validation Jobs

> Create, list, inspect, and download asynchronous email validation jobs

# Async Validation Jobs

Use asynchronous validation jobs for larger email lists that should be processed in the background. Jobs are Product Control Plane-owned public API workflows: the API authenticates with `X-API-Key`, reserves credits for unique submitted emails, validates asynchronously, finalizes charges for High-Value Validations, and refunds unused reserved credits.

## Endpoints

| Method | Endpoint                                            | Purpose                                                                          |
| ------ | --------------------------------------------------- | -------------------------------------------------------------------------------- |
| `POST` | `https://api.gtmapis.com/v1/validate/batch`         | Create an asynchronous validation job.                                           |
| `POST` | `https://api.gtmapis.com/v1/csv/prepare-upload`     | Create a signed upload URL for CSV validation files.                             |
| `POST` | `https://api.gtmapis.com/v1/csv/start-processing`   | Start parsing and validation for a signed CSV upload.                            |
| `GET`  | `https://api.gtmapis.com/v1/csv/jobs`               | List validation jobs for the API key account.                                    |
| `GET`  | `https://api.gtmapis.com/v1/csv/jobs/{id}`          | Get status, progress, summary counts, and download handoff metadata for one job. |
| `GET`  | `https://api.gtmapis.com/v1/csv/jobs/{id}/download` | Get a signed results CSV download URL.                                           |

## Required Scope

Scoped API keys need `email:validate:bulk`. Legacy unrestricted keys retain compatible access until rotated.

## Create Job

Use this JSON endpoint for scripts and SDKs that already have an array of emails. It accepts up to 500,000 submitted emails; valid duplicates are deduplicated before credit reservation.

```bash cURL theme={null}
curl -X POST https://api.gtmapis.com/v1/validate/batch \
  -H "Content-Type: application/json" \
  -H "X-API-Key: gtm_test_1234567890abcdef1234567890abcdef" \
  -d '{
    "emails": ["john@company.com", "jane@company.com"],
    "webhook_url": "https://example.com/gtmapis-webhook"
  }'
```

## Signed CSV Upload

Use this flow for large CSV files so the file body goes directly to Storage instead of through the API proxy.

```bash cURL theme={null}
curl -X POST https://api.gtmapis.com/v1/csv/prepare-upload \
  -H "Content-Type: application/json" \
  -H "X-API-Key: gtm_test_1234567890abcdef1234567890abcdef" \
  -d '{ "filename": "leads.csv" }'
```

Upload the CSV file to the returned `upload_url`, then start processing:

```bash cURL theme={null}
curl -X POST https://api.gtmapis.com/v1/csv/start-processing \
  -H "Content-Type: application/json" \
  -H "X-API-Key: gtm_test_1234567890abcdef1234567890abcdef" \
  -d '{
    "batch_id": "job_123",
    "email_column": "email"
  }'
```

## List Jobs

```bash cURL theme={null}
curl "https://api.gtmapis.com/v1/csv/jobs?limit=20" \
  -H "X-API-Key: gtm_test_1234567890abcdef1234567890abcdef"
```

## Get Job Status

```bash cURL theme={null}
curl https://api.gtmapis.com/v1/csv/jobs/job_123 \
  -H "X-API-Key: gtm_test_1234567890abcdef1234567890abcdef"
```

Status responses include job state, progress, summary counts, credits reserved, credits consumed, credits refunded, effective credits per High-Value Validation, and download handoff metadata without exposing internal validation batch table shape.

```json theme={null}
{
  "id": "job_123",
  "status": "completed",
  "progress": { "processed": 1000, "total": 1000, "percent": 100 },
  "results": {
    "total_rows": 1200,
    "unique_emails": 1000,
    "valid": 350,
    "valid_role_based": 250,
    "invalid": 150,
    "risky": 200,
    "unknown": 50,
    "role_based": 250,
    "high_value": 350,
    "catch_all": 200,
    "credits_reserved": 1000,
    "credits_charged": 350,
    "credits_consumed": 350,
    "credits_refunded": 650,
    "credits_per_high_value_validation": 1
  },
  "credit_reservation": {
    "reserved": true,
    "reserved_credits": 1000,
    "credits_charged": 350,
    "credits_consumed": 350,
    "refunded_credits": 650,
    "credits_per_high_value_validation": 1,
    "finalized": true
  }
}
```

## Get Download URL

```bash cURL theme={null}
curl "https://api.gtmapis.com/v1/csv/jobs/job_123/download?mode=url" \
  -H "X-API-Key: gtm_test_1234567890abcdef1234567890abcdef"
```

Agents and scripts should use `mode=url` and follow the signed URL instead of pulling raw CSV content through MCP.

## Credit Behavior

* Credits are reserved up front for unique submitted emails.
* Only High-Value Validations are charged when processing completes.
* Role-based, catch-all, invalid, risky, and unknown results are refunded from the reservation.
* Failed-job recovery should refund unused reservations idempotently.
* Use `results.high_value`, `results.credits_consumed`, and `results.credits_per_high_value_validation` to measure cost per usable lead instead of raw cost per lookup.
