﻿---
name: document-attachments
description: >
  Instructs AI agents how to attach, detach, and list file attachments on
  Kyriba entities. Supports attaching previously uploaded files (from the
  Data API) to bank accounts or payment transfers.
version: 1.0.0
scopes:
  - attachments-scope
authors:
  - kyriba
tags:
  - kyriba
  - platform
  - attachments
  - 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: Document Attachments

---

## Required Kyriba Permission

```
attachments-scope
```

This is a Kyriba access permission — not an OAuth scope parameter. Do NOT add `scope=` to the token request.

---

## What are Document Attachments?

Enables attaching uploaded files to Kyriba entities (bank accounts or transfers). Files must first be uploaded via the **Data API** (`POST /api/v1/data`) to get a `fileId` (UUID). That UUID is then used here to attach the file to one or more entities.

---

## Base URL

```
https://api.demo.kyriba.com/api/v1/attachments
```

---

##  entityType is a PATH segment - not a query parameter

```
GET  /api/v1/attachments/ACCOUNT
GET  /api/v1/attachments/TRANSFER
POST /api/v1/attachments/ACCOUNT
DELETE /api/v1/attachments/ACCOUNT
```

> Do **not** pass `entityType` as a query param - it belongs in the URL path.

---

## Endpoints

| Method | Path | Description |
|--------|------|-------------|
| `GET` | `/api/v1/attachments/{entityType}` | List entities and their attached files |
| `POST` | `/api/v1/attachments/{entityType}` | Attach file(s) to entities matching a filter |
| `DELETE` | `/api/v1/attachments/{entityType}` | Detach file(s) from entities matching a filter |

### `entityType` values: `ACCOUNT` or `TRANSFER`

---

## Pagination

Uses standard `page.limit` / `page.offset`.

###  Non-Standard Response Metadata

```json
{
  "metadata": {
    "numberOfTotalResults": 545,
    "pageLimit": 100,
    "pageOffset": 0,
    "pageResults": 100,
    "links": { "current": "...", "next": "...", "prev": "..." }
  },
  "results": [ ... ]
}
```

| Standard name | Actual field name |
|---|---|
| `total` | `numberOfTotalResults` |
| `count` | `pageResults` |
| `limit` | `pageLimit` |
| `offset` | `pageOffset` |

---

## Filter

Filter is **optional**. When provided, it selects which entities to target.

**Filterable fields:**

| entityType | Filterable fields |
|---|---|
| `ACCOUNT` | `uuid`, `code` |
| `TRANSFER` | `uuid`, `code` |

>  Fields like `hasAttachments` and `status` are **not** filterable here - they will return `400`.

---

## Key Response Fields (per `results[]` item)

| Field | Description |
|---|---|
| `uuid` | Entity UUID (bank account or transfer) - **not** `entityUuid` |
| `fileIds[]` | Array of attached files - **not** `files[]` |
| `fileIds[].uuid` | File UUID |
| `fileIds[].name` | File name |

---

## Example Requests

**List all accounts with their attachments:**
```
GET /api/v1/attachments/ACCOUNT?page.limit=100&page.offset=0
```

**GET list response:**
```json
{
  "metadata": {
    "pageLimit": 100,
    "pageOffset": 0,
    "pageResults": 2,
    "numberOfTotalResults": 2
  },
  "results": [ ... ]
}
```
> Response key is always `results`. Stop paginating when `len(results) < pageLimit`.

**List attachments for a specific account:**
```
GET /api/v1/attachments/ACCOUNT?filter=code==ACCOUNT_FR_001&page.limit=100&page.offset=0
```

**Attach a file to accounts matching a filter:**
```http
POST /api/v1/attachments/ACCOUNT?fileIds=<fileUuid>&filter=code==ACCOUNT_FR_001
```

**Detach a file:**
```http
DELETE /api/v1/attachments/ACCOUNT?fileIds=<fileUuid>&filter=code==ACCOUNT_FR_001
```

---

## Workflow

```
1. POST /api/v1/data            (Data API)   -> fileId (UUID)
2. POST /api/v1/attachments/ACCOUNT?fileIds={fileId}&filter=code==ACCOUNT_FR
```

---

##  Common Mistakes

| Wrong | Correct |
|---|---|
| `?entityType=ACCOUNT` (query param) | `/api/v1/attachments/ACCOUNT` (path segment) |
| Response key `files[]` | Response key `fileIds[]` |
| Response key `entityUuid` | Response key `uuid` |
| Filter `hasAttachments==true` | Not supported - returns `400` |
| Metadata key `total` | `numberOfTotalResults` |
| Metadata key `count` | `pageResults` |

---

## Critical Rules

1. `entityType` is always a **path segment** - never a query parameter
2. Response files are under `fileIds[]` not `files[]`
3. Response entity identifier is `uuid` not `entityUuid`
4. Only `uuid` and `code` are filterable - other fields return `400`
5. Filter is optional - omit it to list attachments for all entities of that type
6. `fileIds` in POST/DELETE are UUIDs from the **Data API** upload response

---

## Error Reference

| Status | Meaning |
|---|---|
| `200` | Success |
| `400` | Invalid filter field (only `uuid` and `code` supported) |
| `403` | Required Kyriba permission not configured on your API client |
| `404` | File or entity not found |

---

## OpenAPI Spec

- OpenAPI: `https://developer.kyriba.com/static/apis/document-attachments/document-attachments.yaml`