---
title: "Submit an async batch job"
method: POST
path: "/v1/batches"
tags: ["Batches"]
---

# Submit an async batch job

`POST /v1/batches`

## Request

- Base URL: `https://api.scholarfeed.org` (the document declares no server; this is the origin it was published from)
- URL: `https://api.scholarfeed.org/v1/batches`
- Auth: HTTP bearer

Submit an async batch job for processing.

Requires the `Idempotency-Key` header — a client-supplied string that scopes
deduplication per account. Retrying with the same key returns the same job id
(no duplicate row), backed by the `UNIQUE(account_id, idempotency_key)` constraint
on the `batch_jobs` table (migration 122).

Returns **202 Accepted** with `{id, status:"queued"}`. The job id can be
used with `GET /v1/batches/{id}` to poll for status and results.

**Batch submission is accepted but not processed until the worker ships
(BATCH2-01, discovery-gated).** Submitted batches persist as 'queued' rows
in `batch_jobs` until the processing worker is activated. This is intentional —
the scaffold lets developers integrate the contract end-to-end while the
async execution infrastructure is under active development.

**Idempotency:** A retried POST with the same `Idempotency-Key` (for the same
account) returns the existing job id with 202 — no duplicate row is created.
Two different accounts may reuse the same key string without conflict
(uniqueness is scoped per account).

Rate limit: 10/minute per account (provisional).

Returns 400 if the Idempotency-Key header is empty or whitespace.
Returns 401 if not authenticated.
Returns 413 if any single operation exceeds 8 KB or the whole payload exceeds 1 MB.
Returns 422 if the Idempotency-Key header is absent.

## Headers

- `Idempotency-Key` string, required

## Request body

- BatchSubmitRequest: Body for submitting an async batch job.
  - `requests` object[], required: List of operations to run in batch. Shape is provisional and finalised when the worker ships (BATCH2-01). Maximum 10,000 operations per batch — larger batches should be split across multiple jobs.

## Response `202`

Successful Response

- BatchSubmitResponse: Response returned on successful batch submission (202 Accepted).
  - `id` string, required: UUID of the created batch job. Use this with GET /v1/batches/{id} to poll status.
  - `status` string, required: Initial job status. Always 'queued' — the batch has been accepted and persisted, but the processing worker (BATCH2-01) is not yet active. The status will remain 'queued' until the worker ships.

## Other responses

- `422`: Validation Error

---

[API](https://skmtc.dev/scholarfeed/apis/scholar-feed-api.md) · [All operations](https://skmtc.dev/scholarfeed/apis/scholar-feed-api/llms.txt) · [OpenAPI document](https://skmtc.dev/scholarfeed/apis/scholar-feed-api/revisions/fc3200d27505?raw)
