> ## Documentation Index
> Fetch the complete documentation index at: https://musubinetwork.com/llms.txt
> Use this file to discover all available pages before exploring further.

# API Conventions

> Common patterns, response formats, and conventions used across all Musubi APIs.

All Musubi APIs follow the same conventions regardless of participant type.

## Base URL

All endpoints are prefixed with `/api/v1`:

```
https://your-backend.example.com/api/v1/orders
```

## Response Envelope

Every successful response wraps the payload in a standard envelope:

<Tabs>
  <Tab title="Single Resource">
    ```json theme={null}
    {
      "data": {
        "intent_id": "f47ac10b-58cc-4372-a567-0e02b2c3d479",
        "status": "PENDING",
        "source_currency": "JPYSC0",
        "target_amount": "100000"
      },
      "meta": {
        "request_id": "req_a1b2c3d4",
        "timestamp": "2025-03-15T09:00:00.000Z"
      }
    }
    ```
  </Tab>

  <Tab title="Paginated List">
    ```json theme={null}
    {
      "data": [
        { "intent_id": "f47ac10b-...", "status": "SETTLED" },
        { "intent_id": "8b3e7d1a-...", "status": "PENDING" }
      ],
      "meta": {
        "request_id": "req_e5f6g7h8",
        "timestamp": "2025-03-15T09:00:01.000Z"
      },
      "pagination": {
        "page": 1,
        "page_size": 20,
        "total_items": 42,
        "total_pages": 3
      }
    }
    ```
  </Tab>

  <Tab title="Error">
    ```json theme={null}
    {
      "error": {
        "code": "VALIDATION_ERROR",
        "message": "target_amount must be a positive number",
        "details": [
          { "field": "target_amount", "reason": "must be greater than 0" }
        ]
      },
      "meta": {
        "request_id": "req_x9y0z1a2",
        "timestamp": "2025-03-15T09:00:02.000Z"
      }
    }
    ```
  </Tab>
</Tabs>

## Error Codes

| Code               | HTTP Status | Description                                                 |
| ------------------ | ----------- | ----------------------------------------------------------- |
| `VALIDATION_ERROR` | 400         | Missing or invalid request fields                           |
| `UNAUTHORIZED`     | 401         | Missing or invalid JWT token                                |
| `NOT_FOUND`        | 404         | Order, quote, or settlement not found                       |
| `CONFLICT`         | 409         | Invalid state transition (e.g., cancelling a SETTLED order) |
| `CANTON_ERROR`     | 502         | Settlement network unavailable                              |
| `INTERNAL_ERROR`   | 500         | Unexpected server error                                     |

## Pagination

List endpoints accept these query parameters:

| Parameter   | Default | Range | Description             |
| ----------- | ------- | ----- | ----------------------- |
| `page`      | 1       | 1+    | Page number (1-indexed) |
| `page_size` | 20      | 1-100 | Items per page          |

## Filtering & Sorting

Order list endpoints support:

| Parameter         | Example                | Description                                                       |
| ----------------- | ---------------------- | ----------------------------------------------------------------- |
| `status`          | `PENDING,QUOTED`       | Comma-separated status filter                                     |
| `source_currency` | `JPYSC0`               | Filter by source currency                                         |
| `target_currency` | `USDCx`                | Filter by target currency                                         |
| `created_after`   | `2025-03-01T00:00:00Z` | Orders created after this timestamp                               |
| `created_before`  | `2025-03-31T23:59:59Z` | Orders created before this timestamp                              |
| `sort_by`         | `created_at`           | Sort field: `created_at`, `target_amount`, `status`, `settled_at` |
| `sort_order`      | `desc`                 | Sort direction: `asc` or `desc`                                   |

## Data Formats

| Type            | Format        | Example                                |
| --------------- | ------------- | -------------------------------------- |
| Timestamps      | ISO 8601 UTC  | `2025-03-15T09:00:00.000Z`             |
| Decimal amounts | String        | `"10000000"`, `"112.0"`                |
| IDs             | UUID v4       | `f47ac10b-58cc-4372-a567-0e02b2c3d479` |
| Party IDs       | Canton format | `SenderInstitution::209fa2c...b341`    |
| Field names     | snake\_case   | `source_currency`, `intent_id`         |

<Note>
  Decimal amounts are strings to prevent floating-point precision loss. Always parse them as decimals in your application, not as floats.
</Note>

## Server-Sent Events (SSE)

Each participant API provides an SSE endpoint for real-time updates. Connect using `EventSource`:

```javascript theme={null}
const events = new EventSource(
  'https://your-backend.example.com/api/v1/orders/events',
  { headers: { 'Authorization': `Bearer ${token}` } }
);

events.addEventListener('order_updated', (e) => {
  const order = JSON.parse(e.data);
  console.log(`Order ${order.intent_id} is now ${order.status}`);
});

events.addEventListener('heartbeat', () => {
  // Keepalive every 30 seconds
});
```

| Behavior     | Detail                                                         |
| ------------ | -------------------------------------------------------------- |
| Heartbeat    | Every 30 seconds                                               |
| Reconnection | Automatic via EventSource                                      |
| Filtering    | Optional `intent_id` query parameter to watch a specific order |

## Currencies

The testnet supports two stablecoins:

| Code     | Name                    | Peg     |
| -------- | ----------------------- | ------- |
| `JPYSC0` | Japanese Yen Stablecoin | 1:1 JPY |
| `USDCx`  | Canton-wrapped USDC     | 1:1 USD |
