---
title: "Run several SQL statements with an explicit transaction"
method: POST
path: "/projects/v1/{project_id}/sql/batch"
tags: ["Projects"]
---

# Run several SQL statements with an explicit transaction

`POST /projects/v1/{project_id}/sql/batch`

## Request

- Base URL: `https://api.run402.com`
- URL: `https://api.run402.com/projects/v1/{project_id}/sql/batch`
- Auth: HTTP bearer

Runs up to 100 statements against the project's schema with the project service key. Each entry is exactly one statement. transaction "all" (default) runs them in one transaction: the first failure rolls back every statement and answers 400 SQL_BATCH_STATEMENT_FAILED naming its index. transaction "each" gives every statement its own transaction and reports each outcome, so later statements still run; status is "partial" when any failed.

## Path parameters

- `project_id` string, required: Run402 project ID. Public IDs are not UUIDs.

## Request body

- object
  - `statements` object[], required
    - `sql` string, required
    - `params` unknown[]
      - unknown
  - `transaction` 'all' | 'each'

## Response `200`

The batch ran

- object
  - `status` 'ok' | 'partial'
  - `schema` string
  - `transaction` 'all' | 'each'
  - `results` object[]
    - `index` integer, required
    - `status` 'ok' | 'error', required
    - `command` unknown
    - `rows` object[]
    - `row_count` integer
    - `fields` object[]
    - `message` string
  - `warnings` object[]: Warnings that never change the result: ROUTE_RETIRING (the caller used a route being retired; next_actions names the successor or the upgrade), SCHEMA_CHANGE_OUTSIDE_MIGRATION (DDL on a project with a live release, which the release no longer describes; next_actions: create_migration), MULTI_STATEMENT_TEXT_BODY (several statements in one text body; use the batch route).
    - `code` 'ROUTE_RETIRING' | 'SCHEMA_CHANGE_OUTSIDE_MIGRATION' | 'MULTI_STATEMENT_TEXT_BODY', required
    - `severity` string
    - `message` string, required
    - `next_actions` object[], required

## Other responses

- `400`: Bad body, or (transaction all) a statement failed and the batch rolled back: SQL_BATCH_STATEMENT_FAILED with details.index
- `401`: Missing or invalid authentication. Run402-originated JSON bodies use the canonical ErrorEnvelope.
- `403`: A blocked statement pattern, SQL outside the project's own schema (TENANT_SQL_BOUNDARY), another project's key, or a control-plane-gated project

---

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