---
title: "Create a portfolio account"
method: POST
path: "/v1/portfolios/{portfolioSlug}/accounts"
tags: ["Accounts"]
---

# Create a portfolio account

`POST /v1/portfolios/{portfolioSlug}/accounts`

## Request

- Base URL: `https://api.tokenbooks.io` (the document declares no server; this is the origin it was published from)
- URL: `https://api.tokenbooks.io/v1/portfolios/{portfolioSlug}/accounts`
- Auth: API key in header `x-api-key`

Creates one Chart of Accounts row. Requires Advanced Ledger; when it is unavailable, returns HTTP 403 with the flat response fields statusCode: 403, code: "FeatureNotEnabledError", and message containing the complete actionable reason: "Advanced Ledger is required to create accounts. Ask a workspace owner or billing manager to enable it." Omit subType and normalBalanceType to derive them from the account type and currency. A requested parent must have the same account type as the new account and must not carry journal activity. Returning the canonical account response also requires ledger-account view permission.

## Path parameters

- `portfolioSlug` string, required

## Request body

- CreateAccountRequestDto
  - `accountNumber` string, required: Portfolio-unique ledger account number.
  - `name` string, required: Ledger account name.
  - `accountType` 'ASSET' | 'LIABILITY' | 'EQUITY' | 'INCOME' | 'EXPENSE', required: Top-level account type.
  - `currencyAssetId` string, required: Currency asset identifier for the account.
  - `subType` string: Account subtype. Derived from the account type when omitted.
  - `normalBalanceType` 'DR' | 'CR': Normal-balance side. Derived from the account type when omitted.
  - `parentAccountNumber` string, nullable: Parent ledger account number. Omit or send null for a root account.
  - `paymentLabel` string, nullable: Optional label shown in payment account selection.
  - `isActive` boolean: Whether the account starts active. Defaults to true.

## Response `201`

The created account in the shared account row shape.

- AccountResponseDto
  - `accountNumber` string, required: Ledger account number.
  - `name` string, required: Ledger account name.
  - `paymentLabel` string, nullable, required: Optional label shown in payment account selection.
  - `accountType` 'ASSET' | 'LIABILITY' | 'EQUITY' | 'INCOME' | 'EXPENSE', required: Top-level account type.
  - `subType` string, required: Persisted account subtype.
  - `normalBalanceType` 'DR' | 'CR', required: Debit or credit normal-balance side.
  - `isActive` boolean, required: Whether the account is currently marked active.
  - `origin` 'SYSTEM_MANAGED' | 'SYSTEM_DEFAULT' | 'USER_MANAGED', required: Which code path created this account: engine-managed, engine fallback, or user-created. A user-created value may also mean the one-time backfill migration could not disambiguate an older row.
  - `createdBy` object, nullable, required: Creator of a user-created account, when known. Null for system-generated accounts and for accounts created before creator tracking existed.
    - `userId` string, required
  - `hierarchy` object, required
    - `parentAccountNumber` string, nullable, required: Parent ledger account number, or null for a root account.
    - `depth` integer, required: Hierarchy depth.
    - `hasChildren` boolean, required: Whether the account has direct child accounts.
    - `isFilterContext` boolean, required: Whether the row is included only as ancestor context for a direct filter match.
  - `asset` object, nullable, required
    - `assetId` string, required: Public asset identifier.
    - `symbol` string, required: Asset symbol.
  - `currency` object, required
    - `assetId` string, required: Public currency asset identifier.
    - `symbol` string, required: Currency symbol.
  - `wallet` object, nullable, required
    - `chainId` string, required: Chain ID
    - `address` string, required: Wallet address
    - `name` string, required: Wallet display name.
  - `balance` object
    - `currentBalance` string, required: Draft-inclusive operational balance in the account currency across all journal statuses, with the normal-balance side positive.

## Other responses

- `409`

---

[API](https://skmtc.dev/tokenbooks/apis/tokenbooks-public-api.md) · [All operations](https://skmtc.dev/tokenbooks/apis/tokenbooks-public-api/llms.txt) · [OpenAPI document](https://skmtc.dev/tokenbooks/apis/tokenbooks-public-api/revisions/180622e6255e?raw)
