Reporting Periods

Reporting Periods #

A Reporting Period defines the time span (usually 12 months) for which the operations of an Entity are reported. Reporting Periods are usually connected with a Calendar year, though they do not have to follow it in terms of starting and ending. Each calendar year however can only be associated with a single Reporting Period for each Entity.

Properties #

Direct Properties #

PropertyTypeDefinition
Calendar YearIntThe calendar year associated with the Resource
Period CountIntA number representing the cardinal year that the Entity has been in operation. This number is used in generating sequential Transaction numbers
StatusStringMust be one of OPEN, ADJUSTING or CLOSED, and defaults to OPEN. Only Journal Entries can be posted to an ADJUSTING period. Nothing can be posted to a CLOSED period, and its Balances cannot be changed. Months within an OPEN period can be locked one at a time with a Month Close

Indirect Properties #

PropertyTypeDefinition
Closing RatesListFor Entities with Foreign Currency Transactions, Closing Rates are the Exchange Rates used to translate the closing balances of Accounts with Foreign Currency Transactions during the year to the Entity’s reporting Currency at the end of the Reporting Period
Closing TransactionsListThese are transactions recorded at the closing of a Reporting Period to translate the closing balances of accounts with Foreign Currency Transactions per the appropriate Closing Rate

Basics #

To record a Reporting Period, you need to provide the calendar year and the period count.

Request #

curl --location --request POST 'https://api.microbooks.io/books/v1/reporting-period' \
    --header "Authorization: Bearer <bearer_token>" \
    --data-raw '{
            "calendar_year": 2023,
            "period_count": 2
        }'
import requests

url = "https://api.microbooks.io/books/v1/reporting-period"
body = {
    "calendar_year": 2023,
    "period_count": 2
}
headers = {"Authorization": "Bearer <bearer_token>"}

response = requests.request("POST", url, headers=headers, json=body)

print(response.text)
var request = require('request');
var options = {
    'method': 'POST',
    'url': 'https://api.microbooks.io/books/v1/reporting-period',
    'headers': {'Authorization': 'Bearer <bearer_token>'},
    'body': '{
        "calendar_year": 2023,
        "period_count": 2
    }'
};
request(options, function (error, response) {
    if (error) throw new Error(error);
    console.log(response.body);
});
$client = new Client();
$body = '{
    "calendar_year": 2023,
    "period_count": 2
}';
$request = new Request('POST', 'https://api.microbooks.io/books/v1/reporting-period', 
    [headers' => ['Authorization' => 'Bearer <bearer_token>']], 
    $body
);
$res = $client->sendAsync($request)->wait();
echo $res->getBody();
var client = new RestClient("https://api.microbooks.io/books/v1/reporting-period");
client.Timeout = -1;
var request = new RestRequest(Method.POST);
var body = "{
    \"calendar_year\": 2023,
    \"period_count\": 2
}";
request.AddParameter("text/plain", body,  ParameterType.RequestBody);
request.AddHeader("Authorization", "Bearer " + <bearer_token>);
IRestResponse response = client.Execute(request);
Console.WriteLine(response.Content);

Response #

{
    "status": "success",
    "message": "ReportingPeriod: 2023 created successfully",
    "resource": {
        "status": "OPEN",
        "calendar_year": 2023,
        "period_count": 2,
        "span": "Jan 1, 2023 - Dec 31, 2023",
        "entity_id": 1,
        "id": 3
    }
}

Variations #

Multiple Entities #

In case of managing multiple Entities (Branches, Daughters), you might need to specify the specifc Entity to which the Resource relates. This is accomplished by including that Entity’s Id in the call.

{
    "calendar_year": 2023,
    "period_count": 2
    "entity_id": 4
}

Operations #

Reopen a Period #

A closed Reporting Period is reopened by updating its status to OPEN, which allows its Balances to be corrected. Update the status back to CLOSED when you are done.

Changing the status needs books:close.
Any change of status (to ADJUSTING, CLOSED or back to OPEN), and creating a period with a status other than OPEN, needs a token with the books:close scope, and the caller must own the Entity. books:write is enough for every other change.
PUT /books/v1/reporting-period/{id}
{
    "status": "OPEN"
}

Start the Year Close #

Moving a Reporting Period from OPEN to ADJUSTING (or straight to CLOSED) starts the year close. If months of the year other than the last are not month-closed, the update lists them under warnings; with the Entity’s reconciliation_before_close set to enforce it is refused instead (detail code 108). The year’s last month is never month-closed: it stays open for adjusting entries until the period is CLOSED, when every month of the year counts as closed.

PUT /books/v1/reporting-period/{id}
{
    "status": "ADJUSTING"
}
{
    "status": "success",
    "message": "ReportingPeriod: 2026 updated successfully",
    "resource": {"id": 3, "calendar_year": 2026, "period_count": 2, "status": "ADJUSTING", "span": "Jan 1, 2026 - Dec 31, 2026"},
    "warnings": [
        {
            "code": "open_months",
            "message": "These months of 2026 are not closed: 2026-10, 2026-11. Close them with POST /month-close/close to lock them before the year closes.",
            "months": ["2026-10", "2026-11"]
        }
    ]
}

Date Period #

The Date Period endpoint takes a date and returns the Reporting Period within which the date lies.

Request #

curl --location --request GET 'https://api.microbooks.io/books/v1/reporting-period/date-period?date=2021-03-20' \
--header "Authorization: Bearer <bearer_token>"
import requests

url = "https://api.microbooks.io/books/v1/reporting-period/date-period?date=2021-03-20"
body = {}
headers = {"Authorization": "Bearer <bearer_token>"}

response = requests.request("GET", url, headers=headers, json=body)

print(response.text)
var request = require('request');
var options = {
    'method': 'GET',
    'url': 'https://api.microbooks.io/books/v1/reporting-period/date-period?date=2021-03-20',
    'headers': {'Authorization': 'Bearer <bearer_token>'},
    'body': '{}'
};
request(options, function (error, response) {
    if (error) throw new Error(error);
    console.log(response.body);
});
$client = new Client();
$body = null;
$request = new Request('GET', 'https://api.microbooks.io/books/v1/reporting-period/date-period?date=2021-03-20', 
    [headers' => ['Authorization' => 'Bearer <bearer_token>']], 
    $body
);
$res = $client->sendAsync($request)->wait();
echo $res->getBody();
var client = new RestClient("https://api.microbooks.io/books/v1/reporting-period/date-period?date=2021-03-20");
client.Timeout = -1;
var request = new RestRequest(Method.GET);
var body = null;
request.AddParameter("text/plain", body,  ParameterType.RequestBody);
request.AddHeader("Authorization", "Bearer " + <bearer_token>);
IRestResponse response = client.Execute(request);
Console.WriteLine(response.Content);

Response #

{
    "status": "success",
    "period": {
        "uuid": "e400be70-c80d-49c3-abdb-fbc08de7f034",
        "id": 2,
        "entity_id": 1,
        "period_count": 2,
        "status": "OPEN",
        "calendar_year": 2021,
        "closing_date": null
    }
}

Transaction Currencies #

This endpoint returns a list of the Foreign Currencies used in Transactions for the Entity during the given Reporting Period.

Request #

curl --location --request GET 'https://api.microbooks.io/books/v1/reporting-period/1/transaction-currencies' \
--header "Authorization: Bearer <bearer_token>"
import requests

url = "https://api.microbooks.io/books/v1/reporting-period/1/transaction-currencies"
body = {}
headers = {"Authorization": "Bearer <bearer_token>"}

response = requests.request("GET", url, headers=headers, json=body)

print(response.text)
var request = require('request');
var options = {
    'method': 'GET',
    'url': 'https://api.microbooks.io/books/v1/reporting-period/1/transaction-currencies',
    'headers': {'Authorization': 'Bearer <bearer_token>'},
    'body': '{}'
};
request(options, function (error, response) {
    if (error) throw new Error(error);
    console.log(response.body);
});
$client = new Client();
$body = null;
$request = new Request('GET', 'https://api.microbooks.io/books/v1/reporting-period/1/transaction-currencies', 
    [headers' => ['Authorization' => 'Bearer <bearer_token>']], 
    $body
);
$res = $client->sendAsync($request)->wait();
echo $res->getBody();
var client = new RestClient("https://api.microbooks.io/books/v1/reporting-period/1/transaction-currencies");
client.Timeout = -1;
var request = new RestRequest(Method.GET);
var body = null;
request.AddParameter("text/plain", body,  ParameterType.RequestBody);
request.AddHeader("Authorization", "Bearer " + <bearer_token>);
IRestResponse response = client.Execute(request);
Console.WriteLine(response.Content);

Response #

{
    "status": "success",
    "transaction_currencies": [
        {
            "currency_id": 2,
            "currency_code": "EUR"
        },
        {
            "currency_id": 5,
            "currency_code": "GBP"
        }
    ]
}

Prepare Closing Transactions #

Taking a Reporting Period Id and the Forex Account Id (the Account to which the translation differences should be posted), this endpoint creates the Journal Entries necessary to ensure the Closing Balances of Foreign Currency denominated Accounts are at the Period’s Closing Rate for their denominated Currency. Optionally, providing the Account Id only creates Translation Transactions for that specific Account.

Request #

curl --location --request POST 'https://api.microbooks.io/books/v1/reporting-period/prepare-closing-transactions' \
--header "Authorization: Bearer <bearer_token>" \
--data-raw '{
   "reporting_period_id": 1,
   "forex_account_id": 1
}'
import requests

url = "https://api.microbooks.io/books/v1/reporting-period/prepare-closing-transactions"
body = {
    "reporting_period_id": 1,
    "forex_account_id": 1
}
headers = {"Authorization": "Bearer <bearer_token>"}

response = requests.request("POST", url, headers=headers, json=body)

print(response.text)
var request = require('request');
var options = {
    'method': 'POST',
    'url': 'https://api.microbooks.io/books/v1/reporting-period/prepare-closing-transactions',
    'headers': {'Authorization': 'Bearer <bearer_token>'},
    'body': '{
        "reporting_period_id": 1,
        "forex_account_id": 1
    }'
};
request(options, function (error, response) {
    if (error) throw new Error(error);
    console.log(response.body);
});
$client = new Client();
$body = '{
    "reporting_period_id": 1,
    "forex_account_id": 1
}';
$request = new Request('POST', 'https://api.microbooks.io/books/v1/reporting-period/prepare-closing-transactions', 
    [headers' => ['Authorization' => 'Bearer <bearer_token>']], 
    $body
);
$res = $client->sendAsync($request)->wait();
echo $res->getBody();
var client = new RestClient("https://api.microbooks.io/books/v1/reporting-period/prepare-closing-transactions");
client.Timeout = -1;
var request = new RestRequest(Method.POST);
var body = "{
    \"reporting_period_id\": 1,
    \"forex_account_id\": 1
}";
request.AddParameter("text/plain", body,  ParameterType.RequestBody);
request.AddHeader("Authorization", "Bearer " + <bearer_token>);
IRestResponse response = client.Execute(request);
Console.WriteLine(response.Content);

Response #

{
    "status": "success",
    "closing_transactions": [
        {
            "transaction_type": "JN",
            "transaction_date": "2022-12-31T00:00:00.000000Z",
            "account_id": 2,
            "narration": "EUR 2022 Forex Balance Translation",
            "reference": "EUR",
            "currency_id": 1,
            "transaction_no": "JN02/0001",
            "exchange_rate_id": 4,
            "entity_id": 1,
            "id": 3,
            "transaction_name": "Journal Entry",
            "is_posted": false,
            "is_credited": true,
            "amount": 1000,
            "tax": {
                "total": 0
            },
            "assignable": true,
            "clearable": true,
            "has_integrity": true,
            "line_items": [...],
            "clearances": [],
            "assignments": []
        },
        {
            "transaction_type": "JN",
            "transaction_date": "2022-12-31T00:00:00.000000Z",
            "account_id": 3,
            "narration": "GBP 2022 Forex Balance Translation",
            "reference": "GBP",
            "currency_id": 1,
            "transaction_no": "JN02/0002",
            "exchange_rate_id": 4,
            "entity_id": 1,
            "id": 4,
            "transaction_name": "Journal Entry",
            "is_posted": false,
            "is_credited": false,
            "amount": 1000,
            "tax": {
                "total": 0
            },
            "assignable": true,
            "clearable": true,
            "has_integrity": true,
            "line_items": [...],
            "clearances": [],
            "assignments": []
        }
    ]
}

List Closing Transactions #

This endpoint retrieves the translation Transactions created for the given Reporting Period. Optionally, providing the Account Id retrieves the Translation Transactions for that specific Account.

Request #

curl --location --request GET 'https://api.microbooks.io/books/v1/reporting-period/1/list-closing-transactions' \
--header "Authorization: Bearer <bearer_token>"
import requests

url = "https://api.microbooks.io/books/v1/reporting-period/1/list-closing-transactions"
body = {}
headers = {"Authorization": "Bearer <bearer_token>"}

response = requests.request("GET", url, headers=headers, json=body)

print(response.text)
var request = require('request');
var options = {
    'method': 'GET',
    'url': 'https://api.microbooks.io/books/v1/reporting-period/1/list-closing-transactions',
    'headers': {'Authorization': 'Bearer <bearer_token>'},
    'body': '{}'
};
request(options, function (error, response) {
    if (error) throw new Error(error);
    console.log(response.body);
});
$client = new Client();
$body = null;
$request = new Request('GET', 'https://api.microbooks.io/books/v1/reporting-period/1/list-closing-transactions', 
    [headers' => ['Authorization' => 'Bearer <bearer_token>']], 
    $body
);
$res = $client->sendAsync($request)->wait();
echo $res->getBody();
var client = new RestClient("https://api.microbooks.io/books/v1/reporting-period/1/list-closing-transactions");
client.Timeout = -1;
var request = new RestRequest(Method.GET);
var body = null;
request.AddParameter("text/plain", body,  ParameterType.RequestBody);
request.AddHeader("Authorization", "Bearer " + <bearer_token>);
IRestResponse response = client.Execute(request);
Console.WriteLine(response.Content);

Response #

{
    "status": "success",
    "closing_transactions": {
        "Breanne Connelly II": [
            {
                "currency": "EUR",
                "closing_rate": "100.0000",
                "currency_balance": -100,
                "local_balance": -11000,
                "foreign_balance": -10000,
                "translation": -1000,
                "posted": false
            }
        ],
        "Maximillia Welch": [
            {
                "currency": "GBP",
                "closing_rate": "100.0000",
                "currency_balance": -100,
                "local_balance": -9000,
                "foreign_balance": -10000,
                "translation": -1000,
                "posted": false
            }
        ]
    }
}

Post Closing Transactions #

After the Closing Transactions have been prepared, this endpoint posts them to the Ledger. Optionally, providing the Account Id only posts Translation Transactions for that specific Account.

Request #

curl --location --request POST 'https://api.microbooks.io/books/v1/reporting-period/post-closing-transactions' \
--header "Authorization: Bearer <bearer_token>" \
--data-raw '{
    "reporting_period_id": 1
}'
import requests

url = "https://api.microbooks.io/books/v1/reporting-period/post-closing-transactions"
body = {
    "reporting_period_id": 1,
}
headers = {"Authorization": "Bearer <bearer_token>"}

response = requests.request("POST", url, headers=headers, json=body)

print(response.text)
var request = require('request');
var options = {
    'method': 'POST',
    'url': 'https://api.microbooks.io/books/v1/reporting-period/post-closing-transactions',
    'headers': {'Authorization': 'Bearer <bearer_token>'},
    'body': '{
        "reporting_period_id": 1
    }'
};
request(options, function (error, response) {
    if (error) throw new Error(error);
    console.log(response.body);
});
$client = new Client();
$body = '{
    "reporting_period_id": 1,
}';
$request = new Request('POST', 'https://api.microbooks.io/books/v1/reporting-period/post-closing-transactions', 
    [headers' => ['Authorization' => 'Bearer <bearer_token>']], 
    $body
);
$res = $client->sendAsync($request)->wait();
echo $res->getBody();
var client = new RestClient("https://api.microbooks.io/books/v1/reporting-period/post-closing-transactions");
client.Timeout = -1;
var request = new RestRequest(Method.POST);
var body = "{
    \"reporting_period_id\": 1,
}";
request.AddParameter("text/plain", body,  ParameterType.RequestBody);
request.AddHeader("Authorization", "Bearer " + <bearer_token>);
IRestResponse response = client.Execute(request);
Console.WriteLine(response.Content);

Response #

{
    "status": "success",
    "message": "Closing Transactions posted successfully"
}

Closing Rates #

This endpoint retrieves the Closing Rates for Foreign Currencies used in Transactions during the given Reporting Period.

Request #

curl --location --request GET 'https://api.microbooks.io/books/v1/reporting-period/1/closing-rates' \
--header "Authorization: Bearer <bearer_token>"
import requests

url = "https://api.microbooks.io/books/v1/reporting-period/1/closing-rates"
body = {}
headers = {"Authorization": "Bearer <bearer_token>"}

response = requests.request("GET", url, headers=headers, json=body)

print(response.text)
var request = require('request');
var options = {
    'method': 'GET',
    'url': 'https://api.microbooks.io/books/v1/reporting-period/1/closing-rates',
    'headers': {'Authorization': 'Bearer <bearer_token>'},
    'body': '{}'
};
request(options, function (error, response) {
    if (error) throw new Error(error);
    console.log(response.body);
});
$client = new Client();
$body = null;
$request = new Request('GET', 'https://api.microbooks.io/books/v1/reporting-period/1/closing-rates', 
    [headers' => ['Authorization' => 'Bearer <bearer_token>']], 
    $body
);
$res = $client->sendAsync($request)->wait();
echo $res->getBody();
var client = new RestClient("https://api.microbooks.io/books/v1/reporting-period/1/closing-rates");
client.Timeout = -1;
var request = new RestRequest(Method.GET);
var body = null;
request.AddParameter("text/plain", body,  ParameterType.RequestBody);
request.AddHeader("Authorization", "Bearer " + <bearer_token>);
IRestResponse response = client.Execute(request);
Console.WriteLine(response.Content);

Response #

{
    "status": "success",
    "closing_rates": [
        {
            "uuid": "6c2cd8bb-33ec-4721-b19d-f8c7049488d3",
            "id": 1,
            "entity_id": 1,
            "exchange_rate": {
                "uuid": "b3cb2a3b-308a-4bac-b8fa-762e747f4d7e",
                "id": 1,
                "entity_id": 1,
                "currency_id": 2,
                "valid_from": "2022-09-27T22:00:08.000000Z",
                "valid_to": "2022-10-21T13:02:21.000000Z",
                "rate": "100.0000"
            }
        },
        {
            "uuid": "4bbd98dd-6de7-4a8c-8810-994a7b676c7b",
            "id": 2,
            "entity_id": 1,
            "exchange_rate": {
                "uuid": "e90bcf87-1e58-4fc7-bfa9-43e59cb888d1",
                "id": 2,
                "entity_id": 1,
                "currency_id": 4,
                "valid_from": "2022-10-01T14:25:38.000000Z",
                "valid_to": "2022-10-21T13:02:21.000000Z",
                "rate": "150.0000"
            }
        }
    ]
}

Errors #

Below are the Errors that are returned by the Reporting Period Resource.

Detail CodeHTTP StatusNameDefinition
100400Orphaned ItemsCannot recycle the Reporting Period Resource because it has dependent Resources
101400Missing EntityThe Reporting Period Resource requires an existing because it relates Transactions associated with an Entity Resource to an operations cycle
102400Missing Reporting PeriodThe Entity does not have a Reporting Period Resource for the given year
103400Invalid Account TypeThe Translation Forex Account must be of type Equity because Foreign Balance Translation Gains/Losses are reported via the Statement of Comprehensive Income
104400Invalid Period StatusForeign Balance Translation can only be performed when the Reporting Period Resource’s status is Adjusting, which prohibits the posting of further Transactions for the period thus ensuring that the Balances translated are final for the period
105400Missing Closing RateOne of the Foreign Currencies used in Transactions during the Reporting Period does not have the Exchange Rate at which Balances for Accounts denominated in that Currency should be translated for Reporting
106400Resource Not FoundThe Forex Account Resource with the given Id does not exist
107400Duplicate Reporting PeriodAn Entity can only have one Reporting Period per calendar year
108400Open MonthsThe Entity’s reconciliation_before_close is enforce, so the Reporting Period cannot leave OPEN while months of its year other than the last are open. The message lists them; close them first. Returned under status
422422ValidationA field is missing, malformed or not recognised. The field is the key under errors

Errors use the standard error envelope, which also lists the request-level codes (401, 403, 404, 429 and others) that any endpoint can return.