Skip to main content
POST
/
statements
/
users
/
{tenantUserId}
/
{periodStart}
/
{periodEnd}
/
finalize
Finalize a statement
curl --request POST \
  --url https://api.royalti.io/statements/users/{tenantUserId}/{periodStart}/{periodEnd}/finalize \
  --header 'Authorization: Bearer <token>'
import requests

url = "https://api.royalti.io/statements/users/{tenantUserId}/{periodStart}/{periodEnd}/finalize"

headers = {"Authorization": "Bearer <token>"}

response = requests.post(url, headers=headers)

print(response.text)
const options = {method: 'POST', headers: {Authorization: 'Bearer <token>'}};

fetch('https://api.royalti.io/statements/users/{tenantUserId}/{periodStart}/{periodEnd}/finalize', options)
.then(res => res.json())
.then(res => console.log(res))
.catch(err => console.error(err));
<?php

$curl = curl_init();

curl_setopt_array($curl, [
CURLOPT_URL => "https://api.royalti.io/statements/users/{tenantUserId}/{periodStart}/{periodEnd}/finalize",
CURLOPT_RETURNTRANSFER => true,
CURLOPT_ENCODING => "",
CURLOPT_MAXREDIRS => 10,
CURLOPT_TIMEOUT => 30,
CURLOPT_HTTP_VERSION => CURL_HTTP_VERSION_1_1,
CURLOPT_CUSTOMREQUEST => "POST",
CURLOPT_HTTPHEADER => [
"Authorization: Bearer <token>"
],
]);

$response = curl_exec($curl);
$err = curl_error($curl);

curl_close($curl);

if ($err) {
echo "cURL Error #:" . $err;
} else {
echo $response;
}
package main

import (
"fmt"
"net/http"
"io"
)

func main() {

url := "https://api.royalti.io/statements/users/{tenantUserId}/{periodStart}/{periodEnd}/finalize"

req, _ := http.NewRequest("POST", url, nil)

req.Header.Add("Authorization", "Bearer <token>")

res, _ := http.DefaultClient.Do(req)

defer res.Body.Close()
body, _ := io.ReadAll(res.Body)

fmt.Println(string(body))

}
HttpResponse<String> response = Unirest.post("https://api.royalti.io/statements/users/{tenantUserId}/{periodStart}/{periodEnd}/finalize")
.header("Authorization", "Bearer <token>")
.asString();
require 'uri'
require 'net/http'

url = URI("https://api.royalti.io/statements/users/{tenantUserId}/{periodStart}/{periodEnd}/finalize")

http = Net::HTTP.new(url.host, url.port)
http.use_ssl = true

request = Net::HTTP::Post.new(url)
request["Authorization"] = 'Bearer <token>'

response = http.request(request)
puts response.read_body
{
  "message": "<string>",
  "data": {
    "id": "3c90c3cc-0d44-4b50-8888-8dd25736052a",
    "TenantUserId": "3c90c3cc-0d44-4b50-8888-8dd25736052a",
    "periodStart": "2023-11-07T05:31:56Z",
    "periodEnd": "2023-11-07T05:31:56Z",
    "flags": {
      "onHold": true,
      "disputed": true
    },
    "gross": "<string>",
    "net": "<string>",
    "paidAmount": "<string>",
    "priorBalance": "<string>",
    "reportingCurrency": "USD",
    "frozenAt": "2023-11-07T05:31:56Z",
    "lastCalculatedAt": "2023-11-07T05:31:56Z",
    "ok": true
  }
}
{
"status": "error",
"message": "Unauthorized"
}
{
"status": "error",
"message": "Resource not found"
}

Description

Finalize statement Transitions the active Statement for (tenantUserId, periodStart..periodEnd) from draft to finalized. If no persisted draft row exists yet, one is first generated from the ledger (generateAndPersistStatement) then finalized. Appends a StatementStatusEvent to statusHistory and writes an explicit AuditLog row (Statement does not extend AuditableModel, so auto-audit hooks never fire here). Authorization:
  • Required role: admin or higher

Code Examples

const response = await fetch('https://api.royalti.io/statements/users/example-id/example-id/example-id/finalize', {
  method: 'POST',
  headers: {
    'Content-Type': 'application/json'
  },
  body: JSON.stringify({})
});

const data = await response.json();
console.log(data);
import requests

response = requests.post(
  'https://api.royalti.io/statements/users/example-id/example-id/example-id/finalize',
  json={}
)

data = response.json()
print(data)
curl -X POST https://api.royalti.io/statements/users/example-id/example-id/example-id/finalize \
  -H "Content-Type: application/json" \
  -d '{}'

Authorizations

Authorization
string
header
required

JWT Authorization header using the Bearer scheme. Format: "Bearer {token}"

Path Parameters

tenantUserId
string<uuid>
required
periodStart
string<date-time>
required
periodEnd
string<date-time>
required

Response

Statement finalized.

Every statements response wraps the payload in { status, message, data }. data carries the per-endpoint payload PLUS the per-tenant feature flag.

status
enum<string>
Available options:
success,
error
message
string
data
object

Response payload shared by the ITEM 2 lifecycle mutations (finalize, payments, adjustments, hold, resume, void, disputes): the updated Statement row, shaped via the same shapeForClient mapper as StatementRosterRow, plus ok: true. The underlying Sequelize row carries additional endpoint-specific detail (e.g. statusHistory) not exhaustively modeled here — treat this as the roster-row core.