﻿---
name: webhook-routing-status-changed
description: >
  Instructs AI agents how to receive and handle Kyriba payment routing
  status-changed webhook events. Kyriba POSTs a notification whenever
  a payment file changes routing status (e.g. TRANSMITTED, VALID, REJECTED).
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 - Routing 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 routing file** changes status in Kyriba. Use it to track payment file progress without polling the Payment Files Status API.

---

## 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-f22a1e1380c6",
  "kyribaEntity": "payment",
  "eventType": "routing_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": {
    "fileStatus": {
      "statusDetails": {
        "status": "TRANSMITTED",
        "nextAction": "NONE",
        "lastACK": {
          "bankACK": null,
          "kyribaAck": "(1) Sent to the bank",
          "lastACKTime": "2023-03-29T06:52:34Z"
        }
      },
      "associatedFileImport": {
        "fileName": "document.txt",
        "fileId": "962ca363-9f8b-4f67-93c0-dee82840a4bf"
      },
      "linkedRemittance": {
        "remittanceNumber": "DOMTHAB00018"
      }
    }
  }
}
```

---

## Key Fields

| Field | Description |
|---|---|
| `eventId` | UUID - use for deduplication |
| `eventDetails.fileStatus.statusDetails.status` | Current routing status |
| `eventDetails.fileStatus.statusDetails.nextAction` | Required next action |
| `eventDetails.fileStatus.statusDetails.lastACK.bankACK` | Bank acknowledgement code. Can be `null`. |
| `eventDetails.fileStatus.statusDetails.lastACK.kyribaAck` | Kyriba ACK description. **Note: `kyribaAck` (lowercase `c`)** |
| `eventDetails.fileStatus.statusDetails.lastACK.lastACKTime` | ISO-8601 timestamp of last ACK |
| `eventDetails.fileStatus.associatedFileImport.fileName` | Imported file name |
| `eventDetails.fileStatus.associatedFileImport.fileId` | Imported file UUID |
| `eventDetails.fileStatus.linkedRemittance.remittanceNumber` | Remittance number |

### `nextAction` values (partial - open set)

`NONE` · `TRANSMIT` · `SIGN_LEVEL1` · `SIGN_LEVEL2` · `SIGN_LEVEL3` · `PROCESS_AGAIN` · `WAIT_ANSWER` · `RELEASE_FILE` · `DELETE_REMITTANCE_FILE` · `WAIT_FOR_FCA_ANSWER` · `UPLOADING` · `REBUILDING` · `REBUILD_THE_FILE`

---

##  Common Mistake

| Wrong | Correct |
|---|---|
| `lastACK.kyribaACK` (uppercase CK) | `lastACK.kyribaAck` (lowercase `c`) |

---

## Critical Rules

1. Always return `202`
2. Use `eventId` for deduplication
3. Treat `status` and `nextAction` as open sets - skip unknown values
4. `bankACK` and `kyribaAck` can be `null`

---

## OpenAPI Spec

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