Skip to content

Submit Batch API

Use this endpoint to submit a batch of debit instructions against linked customers.

The endpoint accepts the batch synchronously and returns 202 Accepted. Rows are processed asynchronously and reach a terminal state within 24 hours. Partners poll Get Batch Status to retrieve per-row outcomes.

URL path - /billing/sites/{siteId}/batches

Method - POST

Overview

A batch contains 1 to 1000 rows. Each row targets a customer by customerReference and carries a partner-supplied rowReference and amount in cents.

Submission is idempotent on batchReference:

  • Resubmitting the same batchReference with an identical body returns the original receipt.
  • Resubmitting with a different body returns 409 Conflict.
  • A batchReference is retained for 90 days from first submission. Values older than 90 days may be reused for a fresh batch.

Rows are validated asynchronously. If a row's customerReference is not in linked state at the moment of debit execution, the row terminates with customerNotActive rather than being rejected at submission. Partners should treat customerNotActive as retriable in a subsequent batch once the link is re-established.

Request Headers

Header Name Header Value Notes
Content-Type application/json
Authorization Bearer access_token Access token must include scope billing:batches:submit
Pyng-Api-Version urn:pyng:api:billing:version:v1 Required. See API Versions.

Path Parameters

Parameter Key Parameter Data Type Notes
siteId string Unique identifier of the Site under which the batch is being submitted. The Site must belong to the calling Organisation.

Body Parameters

Parameter Key Parameter Data Type Required Notes
batchReference string Y Partner-supplied identifier for the batch. Unique within the partner.
rows array Y 1 to 1000 entries. See Row.

Row

Parameter Key Parameter Data Type Required Notes
rowReference string Y Partner-supplied identifier for the row. Unique within the batch.
customerReference string Y Identifier of the customer to debit. Must reference a customer in linked state.
amount integer Y Debit amount in the Site's minor currency unit (AUD cents at launch). Must be a positive integer. Minimum value is 1.
description string N Optional partner-facing description used for reconciliation.

Response

Status Code - 202 Accepted

Parameter Key Parameter Data Type Required Notes
data object Y object of BatchSubmissionResponse type
traceId string Y Unique identifier of the request

BatchSubmissionResponse

Parameter Key Parameter Data Type Required Notes
batchReference string Y Partner-supplied batch reference echoed back
state string Y One of BatchState. For a freshly submitted batch, accepted. For an idempotent replay of a batch already in flight, the current state.
submittedAt integer Y Unix timestamp in milliseconds, when the batch was first accepted by Pyng
rowCount integer Y Number of rows in the batch

BatchState

Value Notes
accepted Batch has been received and queued for processing
inProgress At least one row has reached a terminal state; others are pending
settled All rows have reached a terminal state

Examples

Request

POST /billing/sites/{siteId}/batches HTTP/1.1
Host: sample.pyng.com.au
Authorization: Bearer access_token
Content-Type: application/json
Pyng-Api-Version: urn:pyng:api:billing:version:v1

{
  "batchReference": "acme-20260504-001",
  "rows": [
    {
      "rowReference": "INV-1234",
      "customerReference": "ACME-001",
      "amount": 12500,
      "description": "Invoice #1234"
    },
    {
      "rowReference": "INV-1235",
      "customerReference": "ACME-002",
      "amount": 5000
    }
  ]
}

Response

HTTP/1.1 202 Accepted
Content-Type: application/json;charset=UTF-8

{
  "data": {
    "batchReference": "acme-20260504-001",
    "state": "accepted",
    "submittedAt": 1777939200000,
    "rowCount": 2
  },
  "traceId": "9ae2e340-b983-4274-b400-c974a9ab40ab"
}

Error Response — Validation

HTTP/1.1 400 Bad Request
Content-Type: application/json;charset=UTF-8

{
  "errors": [
    {
      "code": "urn:pyng:platform:billing:error:batch:row-reference-duplicate",
      "displayMessage": "rowReference must be unique within the batch.",
      "target": "rows[1].rowReference"
    }
  ],
  "traceId": "9ae2e340-b983-4274-b400-c974a9ab40ab"
}

Error Response — Idempotency Conflict

HTTP/1.1 409 Conflict
Content-Type: application/json;charset=UTF-8

{
  "errors": [
    {
      "code": "urn:pyng:platform:billing:error:batch:idempotency-conflict",
      "displayMessage": "A batch with this batchReference already exists with a different body.",
      "target": "batchReference"
    }
  ],
  "traceId": "9ae2e340-b983-4274-b400-c974a9ab40ab"
}