Statements

Generate a full statement for a period, with opening and closing balances per asset.

Before You Start

Read the following guides before proceeding:

GuideWhy
Getting StartedPlatform overview and setup
Api BasicsRequired headers and request configuration
AuthenticationHow to obtain the corporation token
Activity HistoryThe feed is the per-item view of the same data

Overview

A statement is the accounting view of a period: every transaction in the window, plus opening and
closing balances, debits and credits per asset, and the corporation's legal and bank details for the
header. It is what a finance team reconciles against and what an auditor asks for.

Unlike the activity feed, it is bounded by dates rather than paginated, and it carries balance
aggregates the feed does not.


Generate a Statement

POST /api/v1/activity/statement/full

Requires a corporation token. No permission is declared — any authenticated employee can generate it.

Request body:

{
  "start": 1704067200,
  "end": 1706745599
}
FieldTypeRequiredDescription
startintegerYesStart of the period, as a Unix timestamp in seconds. Rounded down to the start of that day
endintegerYesEnd of the period, as a Unix timestamp in seconds. Rounded up to the end of that day

Constraints:

  • Both must be positive.
  • start must be strictly before end.
  • The window must be at most 6 months. A longer range is rejected with
    End time must be within 6 months from start time.

Both bounds are rounded to day boundaries, so a request for a few hours returns a full day, and
start and end on the same date return that one day rather than an empty statement.

Response:

{
  "owner": "0xA7E41d5680dE394EaA2ed417169DFf56840Fb3EE",
  "chain_id": 8453,
  "created_at": 1706745600,
  "period": { },
  "company_data": { },
  "company_bank_accounts": { },
  "balances": [
    {
      "currency": "WUSD",
      "opening": 1000.50,
      "closing": 1250.75,
      "debit": 500.25,
      "credit": 750.50
    }
  ],
  "transactions": [
    {
      "id": "64120850-73a1-4df5-a074-d463258c9deb",
      "type": "Sepa",
      "direction": "Outbound",
      "amount": 95.50,
      "currency": "WUSD",
      "created_at": 1704106800,
      "updated_at": 1704110400,
      "source": { },
      "destination": { },
      "operations": [
        {
          "account_address": "0xA7E41d5680dE394EaA2ed417169DFf56840Fb3EE",
          "token_address": "0x0774164DC20524Bb239b39D1DC42573C3E4C6976",
          "token_symbol": "WUSD",
          "amount": 50.25,
          "resulting_balance": 1050.75,
          "hash": "0x1a2b3c4d5e6f7890abcdef1234567890abcdef12",
          "created_at": 1704106800
        }
      ]
    }
  ]
}
FieldDescription
ownerThe corporation's wallet address
chain_idChain the statement covers
created_atUnix timestamp at which the statement was generated
periodThe time range covered, after rounding
company_dataLegal and registration information for the statement header
company_bank_accountsThe corporation's bank accounts
balances[]Per-asset aggregates for the period
balances[].currencyAsset symbol
balances[].openingBalance at the start of the period
balances[].closingBalance at the end of the period
balances[].debitTotal outgoing during the period
balances[].creditTotal incoming during the period
transactions[]Every transaction in the period
transactions[].amountTotal value of the transaction in currency
transactions[].operations[]The individual on-chain operations that made it up
transactions[].operations[].resulting_balanceBalance of that token on that account after the operation

Timestamps in the statement are Unix seconds, not ISO 8601. The activity feed reports
created_at as 2024-01-01T10:00:00Z; the statement reports the same instant as 1704106800. Two
shapes for the same field name across two endpoints.

The statement is scoped to one chain — the chain_id fixed into the corporation token at login.
A corporation operating on more than one chain needs one statement per chain, generated from a token
logged in against each.

Code

const response = await fetch(`${baseUrl}/api/v1/activity/statement/full`, {
  method: 'POST',
  headers: {
    'Authorization': `Bearer ${corporationToken}`,
    'Content-Type': 'application/json'
  },
  body: JSON.stringify({
    start: Math.floor(new Date('2024-01-01').getTime() / 1000),
    end: Math.floor(new Date('2024-01-31').getTime() / 1000)
  })
});
const statement = await response.json();
response = requests.post(
    f"{base_url}/api/v1/activity/statement/full",
    headers={
        "Authorization": f"Bearer {corporation_token}",
        "Content-Type": "application/json",
    },
    json={
        "start": int(datetime(2024, 1, 1).timestamp()),
        "end": int(datetime(2024, 1, 31).timestamp()),
    },
)
statement = response.json()
body, _ := json.Marshal(map[string]int64{
    "start": periodStart.Unix(),
    "end":   periodEnd.Unix(),
})

req, _ := http.NewRequest("POST", baseURL+"/api/v1/activity/statement/full", bytes.NewBuffer(body))
req.Header.Set("Authorization", "Bearer "+corporationToken)
req.Header.Set("Content-Type", "application/json")

resp, _ := http.DefaultClient.Do(req)
defer resp.Body.Close()

var statement ActivityFullStatementResponse
json.NewDecoder(resp.Body).Decode(&statement)

Limitations

  • Six months maximum per statement. Longer periods must be assembled from several calls, and the
    day-boundary rounding means consecutive windows must not overlap on the join date.
  • The response is JSON only. There is no PDF or CSV rendering.
  • The statement is not paginated. A high-volume period returns one large document.
  • There is no statement history — each call generates the document afresh.

Error Handling

{
  "error_reason": "ErrorInvalidField",
  "error_description": "End time must be within 6 months from start time",
  "error_category": {
    "category": "CategoryValidationFailure",
    "http_status_code": 400
  },
  "error_details": [
    { "key": "field", "details": "end" },
    { "key": "issue", "details": "range_exceeds_6_months" }
  ]
}

Validation Errors (400)

Error ReasonError DetailsDescriptionResolution
ErrorInvalidFieldfield: startStart time must be a positive Unix timestampSend seconds, not milliseconds
ErrorInvalidFieldfield: endEnd time must be a positive Unix timestampAs above
ErrorInvalidFieldissue: invalid_rangeStart time must be before end timeSwap the bounds
ErrorInvalidFieldissue: range_exceeds_6_monthsEnd time must be within 6 months from start timeSplit into shorter periods

Server Errors (500)

Error ReasonDescriptionResolution
ErrorGeneralStatement generation failureA downstream service was unavailable. Retry; for a long period, try a shorter one

Did this page help you?