Chart of Accounts
The chart of accounts is the account structure the rest of the ERP hangs off. Ledgers reference it directly; cashbooks reference it through a GL code. Create these records first.
Base path: https://api-etl.akaun.com/core2/tnt/dm/erp/chart-of-acc
Authentication covers credentials, Data API the envelope and query parameters, and ERP Core API the shared errors and filters.
The fast path:
- To see what you would get,
POST /etl-ep/default-gl-codes: it returns the default financial report sections and writes nothing. - Setting up a tenant from nothing,
POST /etl-ep/create-with-glcodewithname,codeandtxn_type(create with default GL codes). Its codes are six-digit numbers with camel-case names, so if your chart uses other codes, decide first whether you will rename them or build the chart yourself. PlainPOST /etl-epmakes an account with nothing to post to until GL codes are added, and cashbooks need a GL code to reference. - To update,
PUT /etl-epthe whole container withguid,revisionandstatus. Permission is checked against the specific account.
Permissions
The access key’s owner needs one of these for each operation:
| Operation | Permissions (any one) |
|---|---|
| Create | TNT_LOG_CHART_OF_ACC_OWNER, TNT_LOG_CHART_OF_ACC_ADMIN, TNT_API_CHART_OF_ACC_CREATE |
| Read | TNT_LOG_CHART_OF_ACC_OWNER, TNT_LOG_CHART_OF_ACC_ADMIN, TNT_API_CHART_OF_ACC_READ |
| Update | TNT_LOG_CHART_OF_ACC_OWNER, TNT_LOG_CHART_OF_ACC_ADMIN, TNT_API_CHART_OF_ACC_UPDATE |
| Delete | TNT_LOG_CHART_OF_ACC_OWNER, TNT_LOG_CHART_OF_ACC_ADMIN, TNT_API_CHART_OF_ACC_DELETE |
A tenant owner or admin passes all of these regardless.
Endpoints
| Operation | Integration path (/etl-ep) | Back-office path |
|---|---|---|
| Create | POST /etl-ep | POST / |
| Update | PUT /etl-ep | PUT / |
| Delete | DELETE /etl-ep/{guid} | DELETE /{guid} |
| List all | GET /etl-ep | GET / |
| Get one | GET /etl-ep/{guid} | GET /{guid} |
| Query | GET /etl-ep/query | GET /query |
Two further endpoints help you build a chart of accounts from scratch:
| Operation | Integration path (/etl-ep) | Back-office path |
|---|---|---|
| Create with default GL codes | POST /etl-ep/create-with-glcode | POST /create-with-glcode |
| Default GL code template | POST /etl-ep/default-gl-codes | POST /default-gl-codes |
create-with-glcode creates the account and its default GL code set in one call. default-gl-codes returns the default financial report sections without writing anything, so you can inspect the template first.
create-with-glcode rather than plain POST /etl-ep. An account created without GL codes has nothing to post to until GL codes are added, and cashbooks need a GL code to reference.The ChartOfAccContainer
{
"bl_fi_mst_chart_of_acc": { },
"financialReportSections": [ ]
}bl_fi_mst_chart_of_acc
| Field | Type | On create | Description |
|---|---|---|---|
guid | UUID | Optional | Generated if omitted. Required on update. If you supply it on create, it must not already exist. |
name | string | Required | Account name. |
code | string | Required | Account code. |
txn_type | string | Required | Transaction type this account is used for. |
descr | string | Optional | Description. |
status | string | Optional | Defaults to ACTIVE. |
revision | UUID | Optional | Generated if omitted. Send the value you read back when updating. |
vrsn | string | Server-assigned | Version marker. |
created_date | datetime | Server-assigned | |
updated_date | datetime | Server-assigned | |
created_by_subject_guid | UUID | Server-assigned | Set from the access key’s owner. |
updated_by_subject_guid | UUID | Server-assigned | Set from the access key’s owner. |
Create fails with CHARTSOFACC_OBJECT_NAME_IS_NULL_OR_EMPTY, ..._CODE_IS_NULL_OR_EMPTY or ..._TXNTYPE_IS_NULL_OR_EMPTY when a required field is missing.
financialReportSections
Optional. Each section groups GL categories for financial reporting:
| Field | Type | Description |
|---|---|---|
accNo | string | Account number for the section. |
code | string | Section code. |
name | string | Section name. |
glCategories | array | GL categories in the section, each with code, name, guid, level_value, group_guid, status, descr, category_group. |
Send [] if you are not using report sections.
Create an account
POST /core2/tnt/dm/erp/chart-of-acc/etl-ep
curl -X POST "https://api-etl.akaun.com/core2/tnt/dm/erp/chart-of-acc/etl-ep" \
-H "AccessId: YOUR_ACCESS_ID" \
-H "AccessKey: YOUR_ACCESS_KEY" \
-H "tenantCode: YOUR_TENANT_CODE" \
-H "Content-Type: application/json" \
-d '{
"bl_fi_mst_chart_of_acc": {
"name": "Main Chart of Accounts",
"code": "COA-MAIN-01",
"txn_type": "GENERAL",
"descr": "Primary chart of accounts",
"status": "ACTIVE"
},
"financialReportSections": []
}'Response
{
"code": "OK_RESPONSE",
"data": {
"bl_fi_mst_chart_of_acc": {
"guid": "8d1e4b77-2c60-4f19-93a5-6e0b2d8c4a71",
"name": "Main Chart of Accounts",
"code": "COA-MAIN-01",
"txn_type": "GENERAL",
"descr": "Primary chart of accounts",
"status": "ACTIVE",
"revision": "5e9c3a81-7d42-4b06-9f18-2a7b4c6e8d50",
"created_date": "2026-09-14T09:30:00+08:00"
},
"financialReportSections": []
},
"message": ""
}Keep the returned guid: ledgers reference it as chart_of_acc_hdr_guid.
Create an account with its default GL codes
POST /core2/tnt/dm/erp/chart-of-acc/etl-ep/create-with-glcode
Takes the same ChartOfAccContainer as plain create, and additionally generates the default GL code set for the account. This is normally what you want when setting up a tenant. See the note under Endpoints.
curl -X POST "https://api-etl.akaun.com/core2/tnt/dm/erp/chart-of-acc/etl-ep/create-with-glcode" \
-H "AccessId: YOUR_ACCESS_ID" \
-H "AccessKey: YOUR_ACCESS_KEY" \
-H "tenantCode: YOUR_TENANT_CODE" \
-H "Content-Type: application/json" \
-d '{
"bl_fi_mst_chart_of_acc": {
"name": "Main Chart of Accounts",
"code": "COA-MAIN-01",
"txn_type": "GENERAL",
"status": "ACTIVE"
},
"financialReportSections": []
}'The response is the created ChartOfAccContainer. Sent with [], it comes back with
financialReportSections filled with the stock set (the one default-gl-codes
shows). Shortened to one section:
{
"code": "OK_RESPONSE",
"data": {
"bl_fi_mst_chart_of_acc": {
"guid": "8d1e4b77-2c60-4f19-93a5-6e0b2d8c4a71",
"name": "Main Chart of Accounts",
"code": "COA-MAIN-01",
"status": "ACTIVE"
},
"financialReportSections": [
{ "accNo": "110000", "code": "CurrentAssets", "name": "CurrentAssets", "glCategories": [ ] }
]
},
"message": ""
}The GL codes are written separately. Read them back through the GL code endpoints rather than expecting them in this response body.
Requires the same create permission as POST /etl-ep.
Inspect the default GL code template
POST /core2/tnt/dm/erp/chart-of-acc/etl-ep/default-gl-codes
Returns the default financial report sections without writing anything, so you can see what create-with-glcode would generate. The body is an optional raw JSON string used to steer the template; send none to get the stock set.
curl -X POST "https://api-etl.akaun.com/core2/tnt/dm/erp/chart-of-acc/etl-ep/default-gl-codes" \
-H "AccessId: YOUR_ACCESS_ID" \
-H "AccessKey: YOUR_ACCESS_KEY" \
-H "tenantCode: YOUR_TENANT_CODE"Response: an array of FinancialReportSection, eighteen of them in the stock set at the time of
writing (CurrentAssets, FixedAssets, CurrentLiabilities, SalesRevenue, CostOfGoodsSold,
GeneralExpenses and the rest). Each section holds its GL categories, and each category the GL codes
create-with-glcode would write. Shortened to one section:
{
"code": "OK_RESPONSE",
"message": "",
"data": [
{
"accNo": "110000",
"code": "CurrentAssets",
"name": "CurrentAssets",
"glCategories": [
{
"accNo": "110100",
"code": "Cash",
"name": "Cash",
"glCodes": [
{ "accNo": "110101", "code": "cashDraws", "name": "Cash Drawers" },
{ "accNo": "110102", "code": "cashOnHand", "name": "Cash On Hand" }
]
},
{
"accNo": "110300",
"code": "Inventory",
"name": "Inventory",
"glCodes": [
{ "accNo": "110301", "code": "inventory", "name": "Inventory" }
]
}
]
}
]
}The stock numbering is six digits (110000 for the section, 110100 for a category, 110101 for a
code), and the codes are camel-case names such as cashOnHand. If your chart uses other codes, such as
mnemonic ones like INV-LAPTOP, decide before you call create-with-glcode whether you will rename
these afterwards or build the chart yourself.
This endpoint computes the template in memory and does no permission check beyond authentication.
Update an account
PUT /core2/tnt/dm/erp/chart-of-acc/etl-ep
Send the whole container with guid set. On update, revision and status are both required as well as guid. Permission is checked against the specific account, so TNT_API_CHART_OF_ACC_UPDATE granted on one account does not permit editing another.
curl -X PUT "https://api-etl.akaun.com/core2/tnt/dm/erp/chart-of-acc/etl-ep" \
-H "AccessId: YOUR_ACCESS_ID" \
-H "AccessKey: YOUR_ACCESS_KEY" \
-H "tenantCode: YOUR_TENANT_CODE" \
-H "Content-Type: application/json" \
-d '{
"bl_fi_mst_chart_of_acc": {
"guid": "8d1e4b77-2c60-4f19-93a5-6e0b2d8c4a71",
"name": "Main Chart of Accounts (2026)",
"code": "COA-MAIN-01",
"txn_type": "GENERAL",
"status": "ACTIVE",
"revision": "5e9c3a81-7d42-4b06-9f18-2a7b4c6e8d50"
}
}'The answer is the account as saved, with a new revision:
{
"code": "OK_RESPONSE",
"data": {
"bl_fi_mst_chart_of_acc": {
"guid": "8d1e4b77-2c60-4f19-93a5-6e0b2d8c4a71",
"name": "Main Chart of Accounts (2026)",
"code": "COA-MAIN-01",
"status": "ACTIVE",
"revision": "0b7d2e95-6a14-4c83-b5f9-1e8a3c7d4f26"
},
"financialReportSections": []
},
"message": ""
}Delete an account
DELETE /core2/tnt/dm/erp/chart-of-acc/etl-ep/{guid}
curl -X DELETE "https://api-etl.akaun.com/core2/tnt/dm/erp/chart-of-acc/etl-ep/8d1e4b77-2c60-4f19-93a5-6e0b2d8c4a71" \
-H "AccessId: YOUR_ACCESS_ID" \
-H "AccessKey: YOUR_ACCESS_KEY" \
-H "tenantCode: YOUR_TENANT_CODE"Response
{ "code": "OK_RESPONSE", "data": true, "message": "" }Returns 404 with CLIENT_VALIDATION_GUID_DOES_NOT_EXIST if the account does not exist, and 403 if the key’s owner has no delete permission on it.
Deleting an account that ledgers or GL codes still reference will leave those records pointing at a deleted account. Detach them first.
List all accounts
GET /core2/tnt/dm/erp/chart-of-acc/etl-epThe answer is the envelope without paging fields, one container per record:
{
"code": "OK_RESPONSE",
"message": "",
"data": [
{
"bl_fi_mst_chart_of_acc": { "guid": "8d1e4b77-2c60-4f19-93a5-6e0b2d8c4a71", "code": "COA-MAIN-01", "status": "ACTIVE" },
"financialReportSections": null
}
]
}Streams every account, including those the key’s owner may not read, which arrive as their guid and "status": "PERMISSION_DENIED" only (Redacted records). No paging: use /etl-ep/query for that.
Get one account
GET /core2/tnt/dm/erp/chart-of-acc/etl-ep/{guid}
curl "https://api-etl.akaun.com/core2/tnt/dm/erp/chart-of-acc/etl-ep/8d1e4b77-2c60-4f19-93a5-6e0b2d8c4a71" \
-H "AccessId: YOUR_ACCESS_ID" \
-H "AccessKey: YOUR_ACCESS_KEY" \
-H "tenantCode: YOUR_TENANT_CODE"{
"code": "OK_RESPONSE",
"data": {
"bl_fi_mst_chart_of_acc": {
"guid": "8d1e4b77-2c60-4f19-93a5-6e0b2d8c4a71",
"name": "Main Chart of Accounts (2026)",
"code": "COA-MAIN-01",
"txn_type": "GENERAL",
"status": "ACTIVE"
},
"financialReportSections": null
},
"message": ""
}The account is looked up before the permission is checked: an unknown guid answers 404
CLIENT_VALIDATION_GUID_DOES_NOT_EXIST, an account you may not read answers 403.
Query accounts
GET /core2/tnt/dm/erp/chart-of-acc/etl-ep/query
In addition to the shared query parameters:
| Parameter | Type | Description |
|---|---|---|
txn_type | string | Filter by transaction type. |
code | string | Exact code match. |
name | string | Exact name match. |
descr | string | Match on description. |
hdr_guids | UUID set | Fetch a specific set of accounts. Repeat the parameter. |
curl -G "https://api-etl.akaun.com/core2/tnt/dm/erp/chart-of-acc/etl-ep/query" \
-H "AccessId: YOUR_ACCESS_ID" \
-H "AccessKey: YOUR_ACCESS_KEY" \
-H "tenantCode: YOUR_TENANT_CODE" \
--data-urlencode "txn_type=GENERAL" \
--data-urlencode "status=ACTIVE" \
--data-urlencode "limit=50" \
--data-urlencode "calcTotalRecords=true"Response
{
"totalRecords": 1,
"offset": 0,
"limit": 50,
"code": "OK_RESPONSE",
"message": null,
"data": [
{
"bl_fi_mst_chart_of_acc": {
"guid": "8d1e4b77-2c60-4f19-93a5-6e0b2d8c4a71",
"code": "COA-MAIN-01",
"name": "Main Chart of Accounts",
"txn_type": "GENERAL",
"status": "ACTIVE"
},
"financialReportSections": null
}
]
}The query answers "message": null where most endpoints send ""; test code, never message.
Related
- Accounting API — the generated inventory of this family’s
etl-eproutes, where the eight chart-of-accounts routes are listed with ledgers and cashbooks. It lists paths only; the bodies, requirements and failure modes are here. - Ledger — the next thing to create; it references the account you just made
- Data API — hosts, headers, paging, the response envelope and limits