---
title: "Raise one signing per document for one set of parties"
method: POST
path: "/v1/batches"
tags: ["Batches"]
---

# Raise one signing per document for one set of parties

`POST /v1/batches`

## Request

- Base URL: `https://sign-api.tvarka.pro`
- URL: `https://sign-api.tvarka.pro/v1/batches`
- Auth: one of:
  - HTTP bearer
  - API key in header `X-Api-Key`
  - OAuth 2 (authorization code, authorization URL `https://sign-api.tvarka.pro/oauth/authorize`, token URL `https://sign-api.tvarka.pro/oauth/token`, scopes: `sign.read`, `sign.signings`)

Batch operations group documents for coordinated creation and status
tracking, with one API call and one batch identifier. Each document
follows its own signing ceremony and receives its own signature.
Signers complete the authentication and signing steps for each document.

Creation is atomic: either every signing in the batch is raised, or
the error response means none was.
Combined source bytes and combined prepared bytes each have a
100,000,000-byte limit, including repeated uses of the same file token.
Known oversized inputs are refused before stored-file reads; remote
downloads and stored-file reads use the remaining byte allowance.
Aggregate overflow returns 413. A remote-download refusal returns
400 with the document URL pointer. Flattening complexity and its
cooperative processing budget are shared across all batch documents.

## Headers

- `Idempotency-Key` string

## Request body

- object
  - `title` string, required
  - `documents` object[], required
    - `name` string, required
    - `content` string, byte
    - `fileToken` string, uuid
    - `flatten` boolean
  - `signers` SignerRequest[], required
    - `role` 'signer' | 'viewer': A `viewer` is recorded but never invited, never gets a ceremony link, and never holds up completion. Tvarka sends them nothing. At least one signer is required.
    - `email` string, email, required
    - `name` string
    - `language` 'lt' | 'en' | 'et' | 'lv' | 'pl' | 'uk' | 'ru' | 'de' | 'fr' | 'es' | 'it' | 'nl' | 'sv' | 'da' | 'nb' | 'fi': Per signer, for their email and ceremony page. Left out, the signer gets the language of the company's country: lt for a Lithuanian company, de for a German one, and en where that language is not on the list. The list grew on 2026-09-14 and is additive: every value accepted before is still accepted, and the API answers an unknown one exactly as before.
    - `personalCode` string: Optional Lithuanian identity lock. Tvarka stores a keyed hash and encrypted value, never returns the code, and refuses a different authenticated signer.
    - `methods` SigningMethod[]: Per-signer allow-list. `nfc` uses the Tvarka Sign mobile app; Smart-ID and Mobile-ID use the hosted page or mobile app.
    - `signingPurpose` 'signature' | 'confirmation' | 'visa' | 'registration': Immutable per-signer ADOC signed-metadata purpose. Non-default values require ADOC; omit for viewers. Approval uses confirmation. Non-default purposes require a native app that displays the purpose, or signing through the hosted browser ceremony. Covers a parallel signature over the container content and its signed metadata; does not create a registration number/date or counter-sign an earlier signature.
    - `visibleSignature` union: Any workspace may place this signer's visible PDF stamp. Use either page coordinates in PDF points from the lower-left MediaBox corner, or one existing unsigned signature field. The accepted value is immutable and returned on the signer. PDF only; field binding cannot be combined with `document.flatten: true`. `page` is 1-based. Coordinates are finite PDF points (1/72 inch) in unrotated page space; x/y are offsets even when the MediaBox origin is nonzero. The whole box must fit MediaBox and CropBox. Minimum size is 148 x 52 pt; placement requires /UserUnit: 1. A field must have one usable visible widget, be unsigned and unlocked, and meet the same geometry rules. Earlier field locks, ambiguous names and fields already reserved for another signer are rejected. Explicit positions do not become cascade anchors. Do not send this property for viewers. No entitlement is needed (v1.13.1); the company logo and VIP whitelabel are separate. Omit the property to use normal corner placement; configured workspace branding still applies.
      - object
        - `page` integer, required
        - `x` number, required
        - `y` number, required
        - `width` number, required
        - `height` number, required
      - object
        - `field` string, required
    - `authentication` ESignAuthentication: `level: esign` only, refused on a qualified signing. One way to protect this signer's link: `email_link` (default), `access_code` with `code` (4 to 64 characters you give the signer yourself; Tvarka keeps only a hash), or `sms` with `phoneNumber` (E.164; `422 authentication-unavailable` when SMS codes are not switched on, and never a quiet fall back to the email link).
      - `type` 'email_link' | 'access_code' | 'sms', required
      - `code` string
      - `phoneNumber` string
  - `delivery` 'link' | 'email'
  - `signingOrder` 'parallel' | 'sequential'
  - `returnUrl` string, uri: Exact registered HTTPS return URL; requires returnState. Qualified signatures only.
  - `returnState` string
  - `webhookUrl` string, uri
  - `externalId` string
  - `expiresInDays` integer
  - `softDeadlineInDays` integer: Applied to every signing the batch raises.

## Response `201`

The batch and every signing it raised.

- Batch
  - `batchId` string, uuid
  - `title` string
  - `externalId` string, nullable
  - `createdAt` string, date-time
  - `signings` Signing[]
    - `signingId` string, uuid
    - `status` 'pending' | 'completed' | 'declined' | 'cancelled' | 'expired' | 'failed': `pending` - at least one signer can still sign. `completed` - every signer signed. `declined` - somebody declined and nobody else can still sign. `expired` - the window closed first. `cancelled` - you retracted it. `failed` - the signing could not be prepared.
    - `level` 'qualified' | 'esign'
    - `processingStage` 'awaiting_signers' | 'finalizing': While `pending`: `finalizing` once every signer signed and the file is being sealed (a simple e-signature's document timestamp).
    - `title` string
    - `delivery` 'link' | 'email'
    - `signingOrder` 'parallel' | 'sequential': `sequential` releases one signer at a time in the order they were posted. The signers who are waiting hold a ceremony link that answers 404 until their turn, so the ordering is enforced rather than merely unsent. A decline stops the workflow at the decliner's turn: the signing settles `declined` and the signers still waiting are cancelled.
    - `softDeadlineAt` string, date-time, nullable: The date the signing is wanted by, as opposed to `expiresAt`, which is the date it dies on. Nothing expires here; it is when the one automatic reminder goes out.
    - `externalId` string, nullable
    - `templateId` string, uuid: Present when the signing was sent from a template (v1.14.0).
    - `createdAt` string, date-time
    - `expiresAt` string, date-time, nullable
    - `completedAt` string, date-time, nullable
    - `completionMode` 'qes_ceremony' | 'esign_ceremony' | 'sandbox_simulation' | 'null', nullable: `qes_ceremony` means human eID signing. `esign_ceremony` means a completed simple e-signature. `sandbox_simulation` exercises lifecycle/webhook integration and creates no signature; its artifact is flagged `sandbox: true`.
    - `erasedAt` string, date-time, nullable
    - `detail` string: Present when the status needs a sentence of explanation.
    - `signers` Signer[]
      - `signerId` string, uuid
      - `role` 'signer' | 'viewer': A `viewer` is a recorded non-signing party: no invitation is raised, no ceremony link exists, and they never hold up completion. Tvarka sends them nothing - you hold the webhook and the download, and distribute. At least one signer is required.
      - `email` string, email, nullable
      - `name` string, nullable
      - `language` 'lt' | 'en' | 'et' | 'lv' | 'pl' | 'uk' | 'ru' | 'de' | 'fr' | 'es' | 'it' | 'nl' | 'sv' | 'da' | 'nb' | 'fi'
      - `status` 'pending' | 'signed' | 'declined' | 'cancelled' | 'expired' | 'failed' | 'simulated' | 'waiting' | 'recorded': `waiting` - a sequential signer whose turn has not come; their ceremony link answers 404 until it does. `failed` - the signer's requested PDF stamp could not be prepared. `recorded` - a viewer. Never invited, never blocks completion.
      - `ceremonyUrl` string, uri: Present only while this signer can still sign. A finished or retracted invitation has no live URL.
      - `signedAt` string, date-time, nullable
      - `declinedAt` string, date-time, nullable
      - `declineReason` string
      - `methodsAllowed` SigningMethod[]
      - `actualMethod` 'nfc' | 'smart_id' | 'mobile_id': The orchestration methods. For direct LT ATK reader, USB, raw CAdES and lower-level NFC integration, use the ATK API.
      - `identityLocked` boolean
      - `authentication` object: `level: esign` signers: the protection type only, never the code.
        - `type` 'email_link' | 'access_code' | 'sms'
      - `signingPurpose` 'signature' | 'confirmation' | 'visa' | 'registration' | 'null', nullable: Accepted immutable purpose; null for a viewer.
      - `visibleSignature` union: The accepted placement, or null. A signer of a signing sent from a template carries the role's saved box (`TemplateVisibleSignature`, v1.14.1).
        - union: Any workspace may place this signer's visible PDF stamp. Use either page coordinates in PDF points from the lower-left MediaBox corner, or one existing unsigned signature field. The accepted value is immutable and returned on the signer. PDF only; field binding cannot be combined with `document.flatten: true`. `page` is 1-based. Coordinates are finite PDF points (1/72 inch) in unrotated page space; x/y are offsets even when the MediaBox origin is nonzero. The whole box must fit MediaBox and CropBox. Minimum size is 148 x 52 pt; placement requires /UserUnit: 1. A field must have one usable visible widget, be unsigned and unlocked, and meet the same geometry rules. Earlier field locks, ambiguous names and fields already reserved for another signer are rejected. Explicit positions do not become cascade anchors. Do not send this property for viewers. No entitlement is needed (v1.13.1); the company logo and VIP whitelabel are separate. Omit the property to use normal corner placement; configured workspace branding still applies.
          - object
            - `page` integer, required
            - `x` number, required
            - `y` number, required
            - `width` number, required
            - `height` number, required
          - object
            - `field` string, required
        - union: A box saved on a template role, and the box a signer gets from it (v1.14.1). The shape of `VisibleSignature`. The sizes are those of the template's level, the sizes the Tvarka Sign app saves it with: at least the default qualified stamp (103.18 x 35.72 pt) or the default e-signature mark (119.06 x 45.64 pt), and at most three times that. When a qualified template is sent, the box is checked by these sizes and must fit the PDF. A box sent to `POST /v1/templates` is a box sent in a request, so it keeps the `VisibleSignature` rules, 148 x 52 pt at least. A field binding keeps the field rules of `VisibleSignature`.
          - object
            - `page` integer, required
            - `x` number, required
            - `y` number, required
            - `width` number, required
            - `height` number, required
          - object
            - `field` string, required
      - `identityMatched` boolean, nullable: True only after a locked signer completes the real ceremony.
      - `simulatedAt` string, date-time, nullable
      - `emailStatus` 'not_requested' | 'pending' | 'accepted' | 'failed' | 'cancelled' | 'unknown': Initial invitation email state. Accepted means the email backend accepted the message, not inbox delivery. Unknown denotes legacy best-effort delivery whose outcome was not recorded. Sequential signers stay not_requested until their turn is released.
      - `emailAcceptedAt` string, date-time, nullable
    - `document` SignedDocument: The newest signed output. Absent until somebody signs, except on a sandbox simulation, where it describes the unsigned artifact.
      - `sha256` string
      - `bytes` integer
      - `mimeType` string
      - `sandbox` boolean: Present and true only on a sandbox simulation. The bytes are a real file to which no signature was added.
      - `signed` boolean: Present and false only on a sandbox simulation. Absent on a real signing, where the output is signed by definition.
    - `evidence` object: A completed simple e-signature (`level: esign`).
      - `available` boolean: False once erased.
      - `referenceCode` string
      - `verificationUrl` string, uri
      - `separateSummary` boolean
      - `sealedAt` string, date-time, nullable
      - `sandbox` boolean
      - `validation` object
        - `status` 'notApplicable'

## Other responses

- `400`: An RFC 9457 problem document.
- `401`: An RFC 9457 problem document.
- `402`: An RFC 9457 problem document.
- `403`: An RFC 9457 problem document.
- `409`: The idempotency key conflicts, is pending, or has an erased or expired result.
- `413`: An RFC 9457 problem document.
- `422`: An RFC 9457 problem document.
- `429`: An RFC 9457 problem document.
- `503`: An RFC 9457 problem document.

---

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