# Invoice API

A minimal API for creating, retrieving, filtering, and reviewing invoice data.

The API supports both incoming supplier invoices and outgoing customer invoices.

BASE URL: https://example.in.bosbec.io

## Invoice object

An invoice contains the following fields:

```json
{
  "invoice_id": "INV-1042",
  "external_invoice_number": "1231451",
  "invoice_date": "2026-08-14",
  "counter_party": "Nordic Office AB",
  "amount": 78500,
  "vat": 15700,
  "account": "5410",
  "category": "Equipment",
  "status": "paid",
  "direction": "incoming"
}
```

### Fields

| Field | Type | Description |
|---|---|---|
| `invoice_id` | string | Internal unique identifier generated when the invoice is created. |
| `external_invoice_number` | string | Invoice number supplied by the counterparty. |
| `invoice_date` | date | Invoice date in `YYYY-MM-DD` format. |
| `counter_party` | string | Supplier for incoming invoices or customer for outgoing invoices. |
| `amount` | number | Total invoice amount. |
| `vat` | number | VAT amount included in the invoice. |
| `account` | string | Accounting account associated with the invoice. |
| `category` | string | Category used to classify the invoice. |
| `status` | string | Current invoice status, for example `paid`, `unpaid`, `overdue`, or `cancelled`. |
| `direction` | string | `incoming` for supplier invoices or `outgoing` for customer invoices. |

---

# Endpoints

## Create invoice

`POST /invoices`

Creates a new invoice.

### Request

```json
{
  "external_invoice_number": "1231451",
  "invoice_date": "2026-08-14",
  "counter_party": "Nordic Office AB",
  "amount": 78500,
  "vat": 15700,
  "account": "5410",
  "category": "Equipment",
  "status": "paid",
  "direction": "incoming"
}
```

The `invoice_id` is generated automatically.

### Response

```json
{
  "invoice_id": "INV-1042"
}
```

---

## Get invoices

`GET /invoices`

Returns invoices matching the supplied filters.

### Query parameters

| Parameter | Description |
|---|---|
| `invoice_id` | Filter by internal invoice ID. |
| `external_invoice_number` | Filter by external invoice number. |
| `counter_party` | Filter by supplier or customer. |
| `direction` | Filter by `incoming` or `outgoing`. |
| `status` | Filter by invoice status. |
| `account` | Filter by accounting account. |
| `category` | Filter by category. |
| `from_date` | Only invoices on or after this date. |
| `to_date` | Only invoices on or before this date. |
| `min_amount` | Minimum invoice amount. |
| `max_amount` | Maximum invoice amount. |
| `page_size` | Maximum number of invoices to return. |
| `page` | Number of invoices to skip for pagination. |

### Examples

Find incoming invoices over 50,000:

```http
GET /invoices?direction=incoming&min_amount=50000
```

Find invoices from a specific supplier:

```http
GET /invoices?counter_party=Nordic%20Office%20AB&direction=incoming
```

Search for invoices with the same external invoice number:

```http
GET /invoices?external_invoice_number=1231451
```

### Response

```json
{
  "result": {
    "invoice_id": "INV-2",
    "external_invoice_number": "1231451",
    "invoice_date": "2026-08-14",
    "counter_party": "Nordic Office AB",
    "amount": "78500",
    "vat": "15700",
    "account": "5410",
    "category": "Equipment",
    "status": "paid",
    "direction": "incoming"
  },
  "page": "1",
  "page_size": "1",
  "total_pages": "2"
}
```

## Get invoice summary

`GET /invoice-summary`

Returns an aggregated summary for one specific `counter_party`, `account`, or `category`. Calculations are performed by the API rather than by the client.

Exactly one of `counter_party`, `account`, or `category` must be supplied. The API summarizes only invoices matching that value.

### Query parameters

| Parameter | Description |
|---|---|
| `direction` | `incoming` or `outgoing`. |
| `counter_party` | Return a summary for one specific supplier or customer. |
| `account` | Return a summary for one specific accounting account. |
| `category` | Return a summary for one specific category. |
| `from_date` | Start of the period. Defaults to 7 days back. |
| `to_date` | End of the period. Defaults to today. |

### Example

```http
GET /invoice-summary?direction=incoming&from_date=2026-08-01&to_date=2026-08-31&account=5410
```

### Response

```json
{
  "from_date": "2026-08-01",
  "to_date": "2026-08-31",
  "direction": "incoming",
  "summary": {
    "invoice_count": 14,
    "total_amount": 284500
  }
}
```

---

# Invoice Flags

Flags represent invoices that may require human review. A flag does not necessarily mean that an invoice is incorrect.

Possible flag types could include:

- `possible_duplicate`
- `unusual_amount`
- `unexpected_account`
- `vat_anomaly`

## Get invoice flags

`GET /invoice-flags`

Returns invoice review flags.

### Query parameters

| Parameter | Description |
|---|---|
| `invoice_id` | Return flags for a specific invoice. |
| `flag_type` | Filter by type of flag. |
| `risk_level` | Filter by risk level. |

### Example

```http
GET /invoice-flags?flag_type=possible_duplicate
```

### Response

```json
[
  {
    "flag_id": "FLAG-21",
    "invoice_id": "INV-1088",
    "flag_type": "possible_duplicate",
    "risk_level": "high",
    "related_invoice_id": "INV-1042",
    "reason": "Matching external invoice number, counterparty and amount."
  }
]
```

---

## Create invoice flag

`POST /invoice-flags`

Creates a review flag for an invoice.

### Request

```json
{
  "invoice_id": "INV-1088",
  "flag_type": "possible_duplicate",
  "risk_level": "high",
  "related_invoice_id": "INV-1042",
  "reason": "Matching external invoice number, counterparty and amount."
}
```
### Response

```json
{
  "flag_id": "FLAG-21"
}
```

The `flag_id` is generated automatically.

---

# Example AI usage

The API is designed so that filtering and calculations can be performed by the backend while an AI client interprets the user's intent and the returned data.

For example:

**User:**  
"Do we have any incoming invoices from Nordic Office AB over 50,000?"

**API request:**

```http
GET /invoices?direction=incoming&counter_party=Nordic%20Office%20AB&min_amount=50000
```

Or:

**User:**  
"Are there any invoices that may have been registered twice?"

**API request:**

```http
GET /invoice-flags?flag_type=possible_duplicate
```

The API performs data retrieval, filtering, and aggregation. The AI is responsible for interpreting the user's question and explaining the returned results.

---

# Claude sandbox access

If Claude blocks API calls because the domain is not allowed in its sandbox, update the Claude capabilities settings:

1. Open **Capabilities** at `claude.ai/settings/capabilities`, or select your profile in the sidebar and then **Settings** > **Capabilities**.
2. Enable **Code execution and file creation**.
3. Enable **Allow network egress**.
4. Under **Additional allowed domains**, add `*.bosbec.io`.
5. Start a new chat before trying the API call again. The sandbox reads the allowlist when the chat starts.