---
title: "Upload Batch"
method: POST
path: "/batches"
tags: ["batches"]
---

# Upload Batch

`POST /batches`

## Request

- Base URL: `https://api.licenscheck.com` (the document declares no server; this is the origin it was published from)
- URL: `https://api.licenscheck.com/batches`
- Auth: none declared

Upload a CSV of contractors (the request body, as text/csv) and get back its columns, matches and cost.

Nothing runs or is charged yet: the batch is a draft, matched by the columns guessed from its headers.
Check them, change them with POST /batches/{id}/preview if needed, then POST /batches/{id}/run. Only the
cell values are kept, never the file; a draft nobody runs is deleted after a day.

Args:
    request: The request, whose body is the file.
    filename: The file's name.
    key: Injected: the caller's paid key.
    batches: Injected `BatchRepository`.
    licenses: Injected `LicenseRepository`, for matching.
    keys: Injected `ApiKeyRepository`, for the cost.

Returns:
    The draft.

Raises:
    HTTPException: 413 or 422 for a file that can't be read; 429 for too many uploads.

## Query parameters

- `filename` string: The file's name, for display.

## Response `201`

Successful Response

- BatchOut: A batch: its file, where it is, and its rows by outcome.
  - `id` string, uuid, required: The batch's ID.
  - `filename` string, required: The uploaded file's name.
  - `status` 'draft' | 'queued' | 'running' | 'done' | 'failed', required: Where a batch verification is: uploaded, waiting, being verified, or finished. Attributes: DRAFT: Uploaded and matched, waiting for the customer to confirm the columns and cost. QUEUED: Confirmed; waiting for a worker. RUNNING: A worker is reading each matched row's verdict. DONE: Every matched row has its verdict. FAILED: The worker gave up on it; rows verified before that keep their results.
  - `columns` ColumnOut[], required: The file's columns, in order.
    - `name` string, required: The header.
    - `sample` string, required: The first row's value in it.
    - `role` 'license_number' | 'name' | 'state' | 'keep', required: What one uploaded column holds, as the customer confirmed it. Attributes: LICENSE_NUMBER: The license number. NAME: The licensee or business name. STATE: The license's state. KEEP: Anything else: passed through to the results untouched.
  - `rows` integer, required: Data rows in the file.
  - `matched` integer, required: Rows matched to one contractor: verified, one verification each.
  - `ambiguous` integer, required: Rows several contractors could be: never charged until you pick one.
  - `not_found` integer, required: Rows no license matches: never charged.
  - `invalid` integer, required: Rows with no usable number or name, or an unknown state: never charged.
  - `with_number` integer, required: Rows with a license number.
  - `processed` integer, required: Matched rows verified so far.
  - `levels` object, required: Verified rows by verdict: clear, review, risk.
  - `verifications` integer, required: New verifications the batch has used.
  - `created_at` string, date-time, required: When it was uploaded.
  - `finished_at` string, date-time, nullable, required: When it finished, if it has.
  - `cost` CostOut, required: What running the batch will use, before it runs.
    - `verifications` integer, required: New verifications it needs: each matched license once, less those already verified today.
    - `already_verified` integer, required: Matched licenses verified today already: free again.
    - `included_left` integer, nullable, required: Verifications left on the plan this month; null for no cap.
    - `overage_cents` integer, nullable, required: Each verification past those, in US cents.
    - `max_cost_cents` integer, nullable, required: The most running it can add to the bill, in US cents; null for no cap.

## Other responses

- `401`: No API key, or one that's wrong or revoked.
- `403`: A free key: batches need a paid plan.
- `413`: The file is over 2 MB.
- `422`: Not a CSV, not UTF-8, or over 1,000 rows, 50 columns or 500 characters a cell.
- `429`: Too many uploads in a short time.

---

[API](https://skmtc.dev/licenscheck/apis/licenscheck-api.md) · [All operations](https://skmtc.dev/licenscheck/apis/licenscheck-api/llms.txt) · [OpenAPI document](https://skmtc.dev/licenscheck/apis/licenscheck-api/revisions/472db933f385?raw)
