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

# Capital

> Investment products, Fixed Return and Share Offering, that let an entity put idle balances to work.

Capital lets an entity put idle balances to work through the Capital APIs, `/products` and `/product-orders`. An order reserves the commercial terms for a product; confirming it debits the entity's funding account and creates the capital account, which is tracked through to payout.

The available capital products are:

* **Fixed Return**: Invest a fixed principal at a rate locked in at the point of purchase, for a set tenor of 7, 30, 60, 90, or 180 days. Interest accrues daily and is paid out at maturity, or on an early liquidation subject to a penalty on accrued interest.
* **Share Offering**: Purchase whole shares at a fixed offer price. Shares are held for a lock period before they become transferable, and inventory is reserved at the point of order.

### The investment flow

1. **Browse.** Call `GET /products` to list the products visible to the entity, then `GET /products/:id` for the full terms and the documents to affirm.
2. **Reserve.** Call `POST /product-orders`. This creates a 15-minute reservation holding an immutable commercial quote. No funds move at this stage.
3. **Confirm.** Call `POST /product-orders/:id/confirm` before the reservation expires. Nuvion debits the funding wallet once, creates the capital account, and records a `PURCHASE` transaction.
4. **Track.** Use `GET /product-orders`, `GET /capital-portfolio`, and `GET /capital-transactions` to show holdings, order history, and transaction history.
5. **Withdraw.** For Fixed Return, call `GET /product-orders/:id/withdrawal/preview` to show the payout, then `POST /product-orders/:id/withdrawal` to initiate it.

<Note>
  All monetary values are expressed in the smallest currency unit. `50000000` = ₦500,000.00.
</Note>

### Capital order statuses

| Status | Terminal | Description |
| - | - | - |
| `RESERVED` | No | Quote reserved and awaiting confirmation. Expires after 15 minutes |
| `CONFIRMING` | No | Confirmation in progress; the funding wallet debit is being applied |
| `APPROVED` | Yes | Debit settled and the capital account created |
| `EXPIRED` | Yes | The reservation expired before it was confirmed |
| `REJECTED` | Yes | Confirmation failed eligibility, product, or sale window re-checks |
| `RECOVERY_REQUIRED` | No | The debit succeeded but post-debit persistence failed. Under review |

### Capital account lifecycle

Fixed Return accounts:

| Status | Terminal | Description |
| - | - | - |
| `ACTIVE` | No | Accruing interest daily, before maturity |
| `MATURED` | No | Tenor complete and awaiting the maturity payout |
| `EARLY_LIQUIDATING` | No | Early withdrawal initiated; payout is being settled |
| `WITHDRAWN` | Yes | Early liquidation payout settled |
| `CLOSING` | No | Maturity payout initiated; payment is being settled |
| `CLOSED` | Yes | Maturity payout settled and the account closed |

Share Offering accounts:

| Status | Terminal | Description |
| - | - | - |
| `LOCKED` | No | Shares held within the lock period |
| `ALLOTMENT_ADJUSTED` | No | Units held were adjusted by the issuer's allotment |
| `ALLOTMENT_CONFIRMED` | No | All units requested were allotted by the issuer |
| `TRANSFERABLE` | No | Lock period expired; units are transferable |
| `REFUNDED` | Yes | Unallocated value refunded to the funding wallet |

### Browse available products

`GET /products` returns only the products the authenticated entity is eligible for. Hidden products, products whose owner is inactive, and share offerings with no remaining inventory are excluded. Sold-out share offerings that still hold inventory are returned with `availability.status` set to `sold_out` and cannot be ordered.

<CodeGroup>
  ```bash curl theme={null}
  curl "https://api.nuvion.dev/products?capital_product_type=FIXED_RETURN&currency=NGN&limit=25" \
    -H "Authorization: Bearer $NUVION_API_KEY" \
    -H "Content-Type: application/json"
  ```
</CodeGroup>

List responses carry commercial terms in `config` but never include product documents. Fetch `GET /products/:id` for the detail view, which adds the `config.documents` array to affirm at order time.

***

### Reserve an investment

Creating an order reserves the commercial terms for 15 minutes. The product type is resolved from `product_id` and determines which amount field is accepted: `principal` for Fixed Return, `amount` for Share Offering. Nuvion rejects the wrong one.

<CodeGroup>
  ```bash Fixed Return theme={null}
  curl -X POST https://api.nuvion.dev/product-orders \
    -H "Authorization: Bearer $NUVION_API_KEY" \
    -H "Content-Type: application/json" \
    -d '{
      "product_id": "01HXYZ0085ABCDEFGHJKMNPQRS",
      "account_id": "01HXYZ0086ABCDEFGHJKMNPQRS",
      "principal": 50000000,
      "lock_investment": false,
      "agreement_acceptances": [
        {
          "document_name": "Fixed Return Terms and Conditions",
          "action_type": "affirmation"
        }
      ]
    }'
  ```

  ```bash Share Offering theme={null}
  curl -X POST https://api.nuvion.dev/product-orders \
    -H "Authorization: Bearer $NUVION_API_KEY" \
    -H "Content-Type: application/json" \
    -d '{
      "product_id": "01HXYZ0081ABCDEFGHJKMNPQRS",
      "account_id": "01HXYZ0109ABCDEFGHJKMNPQRS",
      "amount": 10060000,
      "agreement_acceptances": [
        {
          "document_name": "Offer Prospectus",
          "action_type": "affirmation"
        },
        {
          "document_name": "Share Purchase Agreement",
          "action_type": "affirmation"
        }
      ]
    }'
  ```
</CodeGroup>

See [Create a capital order](/api-reference/capital#create-a-capital-order) for the full field-by-field request schema.

#### Response

```json theme={null}
{
  "status": "success",
  "message": "Capital order reserved successfully",
  "data": {
    "id": "01HXYZ0088ABCDEFGHJKMNPQRS",
    "entity_id": "01HXYZ1234ABCDEFGHJKMNPQRS",
    "status": "RESERVED",
    "expires_at": 1787098500000,
    "currency": "NGN",
    "quote": {
      "product_id": "01HXYZ0085ABCDEFGHJKMNPQRS",
      "product_owner_id": "01HXYZ0087ABCDEFGHJKMNPQRS",
      "product_type": "FIXED_RETURN",
      "currency": "NGN",
      "principal": 50000000,
      "total_debit": 50000000,
      "tenor_days": 90,
      "locked_rate": 0.18,
      "rate_source": "band:Tier 2",
      "day_count": 365,
      "is_locked": false,
      "allow_early_withdrawal": true,
      "earliest_withdrawal_days": 30,
      "penalty": {
        "primary": 0.25
      },
      "deductibles": [
        {
          "name": "Withholding Tax",
          "value": 0.1,
          "value_type": "percentage",
          "applicable_to": "interest"
        }
      ]
    }
  }
}
```

<Note>
  **Share Offering inventory:** if the requested shares exceed the remaining inventory, the order is allocated down to what is available. The returned quote carries the adjusted `allocated_shares` and `total_debit`.
</Note>

***

### Confirm the order

Confirmation is the only step that moves funds. Nuvion re-evaluates eligibility, product and owner status, and the sale window before any debit, then debits the funding wallet using a deterministic transfer reference.

<CodeGroup>
  ```bash curl theme={null}
  curl -X POST https://api.nuvion.dev/product-orders/01HXYZ0088ABCDEFGHJKMNPQRS/confirm \
    -H "Authorization: Bearer $NUVION_API_KEY" \
    -H "Content-Type: application/json"
  ```

  ```json 200 OK theme={null}
  {
    "status": "success",
    "message": "Capital order confirmed successfully",
    "data": {
      "id": "01HXYZ0088ABCDEFGHJKMNPQRS",
      "entity_id": "01HXYZ1234ABCDEFGHJKMNPQRS",
      "status": "APPROVED",
      "capital_account_id": "01HXYZ0089ABCDEFGHJKMNPQRS",
      "user_capital_account_id": "01HXYZ0090ABCDEFGHJKMNPQRS",
      "transfer_reference": "capital-fixed-return:01HXYZ0088ABCDEFGHJKMNPQRS"
    }
  }
  ```
</CodeGroup>

This endpoint does not require a request body. The stored quote is authoritative: Nuvion never accepts client-supplied amounts, rates, inventory, or agreements.

Retries are safe. A repeated call resumes from the persisted transfer and order state and never issues a second debit. If the debit succeeds but the records that follow it cannot be written, the order moves to `RECOVERY_REQUIRED` and Nuvion reconciles it rather than re-debiting; further calls return `409 error_transfer_already_processing`.

***

### Track the portfolio

`GET /capital-portfolio` returns the authenticated entity's invested totals grouped by currency. Nuvion accrues Fixed Return interest from the account terms at request time; Share Offering value uses the units held and the latest market price.

<CodeGroup>
  ```bash curl theme={null}
  curl https://api.nuvion.dev/capital-portfolio \
    -H "Authorization: Bearer $NUVION_API_KEY" \
    -H "Content-Type: application/json"
  ```

  ```json 200 OK theme={null}
  {
    "message": "Capital portfolio retrieved successfully",
    "status": "success",
    "data": {
      "currencies": [
        {
          "currency": "NGN",
          "totals": {
            "investment": {
              "amount_invested": 50000000,
              "total_return": 739726,
              "current_value": 50739726
            }
          }
        },
        {
          "currency": "USD",
          "totals": {
            "investment": {
              "amount_invested": 10251000,
              "total_return": null,
              "current_value": null
            }
          }
        }
      ]
    }
  }
  ```
</CodeGroup>

`total_return` and `current_value` are `null`, not zero, for a currency when any included holding lacks a valid valuation, which happens for a share offering before its first price update.

***

### Withdraw

Withdrawal applies to Fixed Return accounts. Preview the payout first (it's read-only and has no side effects), then initiate it.

Nuvion selects the path from the account state and the current time. Before maturity, an `ACTIVE` account that is unlocked and past its earliest action day follows the early-liquidation rules and incurs the penalty. From `MATURED`, the contractual maturity payout applies with no penalty.

<CodeGroup>
  ```bash Preview theme={null}
  curl https://api.nuvion.dev/product-orders/01HXYZ0088ABCDEFGHJKMNPQRS/withdrawal/preview \
    -H "Authorization: Bearer $NUVION_API_KEY" \
    -H "Content-Type: application/json"
  ```

  ```json 200 OK Early theme={null}
  {
    "message": "Capital withdrawal preview generated successfully",
    "status": "success",
    "data": {
      "id": "01HXYZ0089ABCDEFGHJKMNPQRS",
      "entity_id": "01HXYZ1234ABCDEFGHJKMNPQRS",
      "gross_interest": 739726,
      "penalty_rate": 0.25,
      "penalty_amount": 184931,
      "total_deductions": 55479,
      "net_payout": 50499316,
      "days_elapsed": 30
    }
  }
  ```

  ```json 200 OK Mature theme={null}
  {
    "message": "Capital withdrawal preview generated successfully",
    "status": "success",
    "data": {
      "id": "01HXYZ0089ABCDEFGHJKMNPQRS",
      "entity_id": "01HXYZ1234ABCDEFGHJKMNPQRS",
      "gross_interest": 2219178,
      "penalty_rate": 0,
      "penalty_amount": 0,
      "total_deductions": 221917,
      "net_payout": 51997261,
      "days_elapsed": 90
    }
  }
  ```
</CodeGroup>

To initiate the payout, `POST` to the same path without `/preview`. The response is the updated order detail, including the new `capital_account.lifecycle` state.

<CodeGroup>
  ```bash curl theme={null}
  curl -X POST https://api.nuvion.dev/product-orders/01HXYZ0088ABCDEFGHJKMNPQRS/withdrawal \
    -H "Authorization: Bearer $NUVION_API_KEY" \
    -H "Content-Type: application/json"
  ```
</CodeGroup>

This endpoint does not require a request body. The stored account snapshot is authoritative; Nuvion never accepts client-supplied amounts, rates, or settlement accounts.

An account that is already `CLOSING` or terminal returns its current state rather than starting a second payout. Nuvion rejects withdrawal with `400 error_operation_invalid_for_state` for locked accounts, non-Fixed-Return accounts, products with early withdrawal disabled, and requests made before the earliest action day.

***

### Transaction history

Nuvion records every movement on a capital account as an immutable `CapitalTransaction`. Pass the account ULID as the required `capital_id` filter.

<CodeGroup>
  ```bash curl theme={null}
  curl "https://api.nuvion.dev/capital-transactions?capital_id=01HXYZ0089ABCDEFGHJKMNPQRS&limit=25" \
    -H "Authorization: Bearer $NUVION_API_KEY" \
    -H "Content-Type: application/json"
  ```
</CodeGroup>

Transaction metadata is redacted from the entity's view.

***

### Notifications

Nuvion emails the entity on the key lifecycle events for their investment: confirmation of the investment, an upcoming maturity reminder, maturity, and early liquidation. An investment certificate is available for download once an order is approved.


This documentation is built and hosted on [Mintlify](https://mintlify.com), a developer documentation platform.