﻿---
name: webhook-batch-status-changed
description: >
  Instructs AI agents how to receive and handle Kyriba payment batch
  status-changed webhook events. Kyriba POSTs a notification whenever
  a payment batch (remittance) changes status.
version: 1.0.0
authors:
  - kyriba
tags:
  - kyriba
  - webhook
  - spi
  - payments
  - api
---

> **Auth** — POST {AUTH_BASE_URL}/oauth/token · Basic base64(CLIENT_ID:CLIENT_SECRET) · no scope.
> Use token_type verbatim — do not hardcode `Bearer`. On 401: retry once with the other scheme (`token` vs `Bearer`). On 429: wait Kyriba-Customer-Rate-Limit-Reset.

# Kyriba API Skill: Webhook - Batch Status Changed

>  This is an **inbound webhook (SPI)** - Kyriba calls your server. You do not call Kyriba.

>  No OAuth scope needed. Authentication is via HMAC signature on the `kyriba-webhook-payload-signature` header.

---

## What is this webhook?

Fires whenever a **payment batch (remittance)** changes status in Kyriba. Similar to routing-status-changed but at the batch level, not the individual file level.

---

## Your server must

1. Expose `POST` on any path you configure in Kyriba
2. Validate the `kyriba-webhook-payload-signature` header
3. Return `202 Accepted`

---

## Inbound Payload

```json
{
  "webhookApiVersion": "v1",
  "eventId": "577a0805-cd2e-4607-a40f-f22a1e1380c9",
  "kyribaEntity": "payment",
  "eventType": "batch_status_changed",
  "eventTime": "2023-03-23T06:52:10.134Z",
  "kyribaPlatform": { "baseUrl": "https://www.demo.kyriba.com" },
  "kyribaCustomer": { "code": "ACMECORP" },
  "kyribaUser": { "code": "JOHNSMITH", "uuid": "123e4567-..." },
  "eventDetails": {
    "batchStatus": {
      "statusDetails": {
        "status": {
          "status": "VALID",
          "nextAction": "NONE"
        },
        "lastACK": {
          "bankACK": "ACSC",
          "kyribaACK": "(4) PSR received",
          "lastACKTime": "2022-01-21T13:16:26.000Z"
        }
      },
      "associatedBatchDetails": {
        "remittanceNumber": "DOMTHUS06171",
        "batchId": "DOMTHUS06171",
        "remittanceIdentifier": "identifier 1",
        "transfersQuantity": 25,
        "repository": "TEST_REPO"
      }
    }
  }
}
```

---

## Key Fields

| Field | Description |
|---|---|
| `eventId` | UUID - use for deduplication |
| `eventDetails.batchStatus.statusDetails.status.status` | Batch status value |
| `eventDetails.batchStatus.statusDetails.status.nextAction` | Required next action |
| `eventDetails.batchStatus.statusDetails.lastACK.bankACK` | Bank ACK code. Can be `null`. |
| `eventDetails.batchStatus.statusDetails.lastACK.kyribaACK` | Kyriba ACK. **Note: `kyribaACK` (uppercase CK)** |
| `eventDetails.batchStatus.statusDetails.lastACK.lastACKTime` | ISO-8601 timestamp |
| `eventDetails.batchStatus.associatedBatchDetails.remittanceNumber` | Remittance number |
| `eventDetails.batchStatus.associatedBatchDetails.batchId` | Batch ID |
| `eventDetails.batchStatus.associatedBatchDetails.transfersQuantity` | Number of transfers in batch |
| `eventDetails.batchStatus.associatedBatchDetails.repository` | Repository name |

### Batch status values (partial - open set)

`CONSTITUTED` · `GENERATED` · `SIGNED_LEVEL_1` · `SIGNED_LEVEL_2` · `SIGNED_LEVEL_3` · `TRANSMITTED` · `ACK_RECEIVED` · `VALID` · `DELIVERED` · `PARTIALLY_VALID` · `REJECTED` · `CANCELLATION_REQUESTED` · `REJECTED_BY_EXCHANGE_CHANNEL` · `TO_BE_DELETED` · `TO_BE_MODIFIED`

---

##  Routing vs Batch ACK field name difference

| Webhook | ACK field name |
|---|---|
| `routing-status-changed` | `kyribaAck` (lowercase `c`) |
| `batch-status-changed` | `kyribaACK` (uppercase `CK`) |

---

## Critical Rules

1. Always return `202`
2. Use `eventId` for deduplication
3. `status` is nested: `batchStatus.statusDetails.status.status` (double nesting)
4. Treat `status` and `nextAction` as open sets

---

## OpenAPI Spec

- OpenAPI: `https://developer.kyriba.com/static/apis/webhook-batch-status-changed/payment-batch_status_changed.yaml`