CEL

CEL Variables Reference

Context variables available in CEL expressions across Twisp APIs.

Twisp uses Common Expression Language extensively for computation across the API. Different contexts expose different variables depending on their purpose. This reference documents what variables are available in each context.

Overview

ContextPrimary VariableDescription
IndexesdocumentThe record being indexed
Calculationscontext.varsTransaction and account context
Tran CodesparamsPost-time parameters

Indexes

Custom indexes use CEL expressions to define partition keys, sort keys, and filter constraints. In all index expressions, the primary variable is document, which represents the record being indexed.

Available Variables

VariableTypeDescription
documentProtobuf messageThe entity being indexed

The type of document depends on the on field specified when creating the index:

Partition Expressions

Partition keys determine how records are grouped in the index.

mutation CreatePartitionedIndex {
  schema {
    createIndex(
      input: {
        name: "entries_by_account"
        on: Entry
        partition: [
          { alias: "accountId", value: "document.account_id" }
          { alias: "journalId", value: "document.journal_id" }
        ]
      }
    ) { name }
  }
}

Partition expressions can return arrays to create multiple index entries. For example this create multiple partitions for the account id and each of it's parent account sets (at time of posting):

partition: [
  {
    alias: "accountId",
    value: "document.parent_account_ids + [document.account_id]"
  }
]

Sort Expressions

Sort keys define the ordering within each partition. In this example sorting either by th

mutation CreateSortedIndex {
  schema {
    createIndex(
      input: {
        name: "entries_by_effective"
        on: Entry
        partition: [{ alias: "accountId", value: "document.account_id" }]
        sort: [
          {
            alias: "effective"
            value: "'effective' in document.metadata && document.metadata.effective != null ? document.metadata.effective : document.created"
            type: STRING
            sort: DESC
          }
        ]
      }
    ) { name }
  }
}

Filter Constraints

Constraints are boolean expressions that must all evaluate to true for a record to be included in the index.

mutation CreateFilteredIndex {
  schema {
    createIndex(
      input: {
        name: "active_entries"
        on: Entry
        partition: [{ alias: "accountId", value: "document.account_id" }]
        constraints: {
          isNotVoidEntry: "!document.is_void_entry"
          isNotVoidedEntry: "!document.is_voided_entry"
          isSettled: "document.layer == SETTLED" 
        }
      }
    ) { name }
  }
}

Calculations

Calculations define how balances are computed and grouped. CEL expressions are used in dimension definitions and conditions.

Available Variables

VariableTypeDescription
context.vars.transactionTransactionThe parent transaction of the entry
context.vars.accountAccountThe account the entry is posted to
documentEntryThe entry being evaluated (in conditions)

Dimension Expressions

Dimensions define how balances are grouped. Common use cases include grouping by date, metadata values, or account properties.

mutation CreateEffectiveDateCalculation {
  createCalculation(
    input: {
      calculationId: "5867b5dd-fc69-416c-80f5-62e8a53610d5"
      code: "EFFECTIVE_DATE"
      description: "Track balances per effective date."
      dimensions: [
        {
          alias: "effectiveDate"
          value: "context.vars.transaction.effective"
        }
      ]
      scope: LOCAL
    }
  ) {
    calculationId
    code
  }
}

Multi-dimensional calculations:

mutation CreateMultiDimensionCalculation {
  createCalculation(
    input: {
      calculationId: "a1b2c3d4-e5f6-7890-abcd-ef1234567890"
      code: "BY_CURRENCY_AND_DATE"
      description: "Track balances by currency and effective date."
      dimensions: [
        {
          alias: "currency"
          value: "context.vars.account.metadata.currency"
        }
        {
          alias: "effectiveDate"
          value: "context.vars.transaction.effective"
        }
      ]
      scope: LOCAL
    }
  ) { calculationId }
}

Condition Expressions

Conditions filter which entries are included in the calculation. They must evaluate to a boolean.

mutation CreateConditionalCalculation {
  createCalculation(
    input: {
      calculationId: "b2c3d4e5-f6a7-8901-bcde-f23456789012"
      code: "POLICY_PAYMENTS"
      description: "Track only entries to accounts with policy payment metadata."
      dimensions: [
        { alias: "effectiveDate", value: "context.vars.transaction.effective" }
      ]
      condition: "has(context.vars.account.metadata.policyPayment)"
      scope: LOCAL
    }
  ) { calculationId }
}

Using entry fields in conditions:

condition: "document.layer == 0 && document.direction == 0"

Tran Codes

Tran codes are templates that define how transactions and entries are created. CEL expressions are used extensively to dynamically compute values at post time.

Available Variables

VariableTypeDescription
paramsStructParameters passed when posting the transaction
varsStructCalculated variables defined in the tran code's vars field

Parameter Access

Parameters are defined in the tran code and passed at post time. Access them with params.<paramName>:

mutation CreateTranCode {
  createTranCode(
    input: {
      code: "TRANSFER"
      description: "Transfer funds between accounts"
      params: [
        { name: "amount", type: TYPE_DECIMAL, description: "Transfer amount" }
        { name: "fromAccount", type: TYPE_UUID, description: "Source account" }
        { name: "toAccount", type: TYPE_UUID, description: "Destination account" }
        { name: "memo", type: TYPE_STRING, default: "'Transfer'", description: "Optional memo" }
      ]
      transaction: {
        description: "'Transfer ' + string(params.amount) + ' - ' + params.memo"
      }
      entries: [
        {
          entryType: "'TRANSFER_DR'"
          accountId: "params.fromAccount"
          direction: "'DEBIT'"
          units: "params.amount"
          currency: "'USD'"
        }
        {
          entryType: "'TRANSFER_CR'"
          accountId: "params.toAccount"
          direction: "'CREDIT'"
          units: "params.amount"
          currency: "'USD'"
        }
      ]
    }
  ) { code }
}

Vars (Scratch Pad)

The vars field provides a scratch pad for intermediate calculations. Variables defined here can be referenced in transaction and entry expressions:

mutation CreateTranCodeWithVars {
  createTranCode(
    input: {
      code: "TRANSFER_WITH_FEE"
      description: "Transfer with calculated fee"
      params: [
        { name: "amount", type: TYPE_DECIMAL }
        { name: "fromAccount", type: TYPE_UUID }
        { name: "toAccount", type: TYPE_UUID }
        { name: "feeAccount", type: TYPE_UUID }
      ]
      vars: {
        feeRate: "'0.025'"
        feeAmount: "decimal(params.amount) * decimal(vars.feeRate)"
        netAmount: "decimal(params.amount) - vars.feeAmount"
      }
      entries: [
        {
          entryType: "'TRANSFER_DR'"
          accountId: "params.fromAccount"
          direction: "'DEBIT'"
          units: "params.amount"
          currency: "'USD'"
        }
        {
          entryType: "'TRANSFER_CR'"
          accountId: "params.toAccount"
          direction: "'CREDIT'"
          units: "vars.netAmount"
          currency: "'USD'"
        }
        {
          entryType: "'FEE_CR'"
          accountId: "params.feeAccount"
          direction: "'CREDIT'"
          units: "vars.feeAmount"
          currency: "'USD'"
        }
      ]
    }
  ) { code }
}

Entry Conditions

Entry conditions determine whether an entry should be created. Useful for optional entries:

entries: [
  {
    entryType: "'FEE'"
    accountId: "params.feeAccount"
    direction: "'CREDIT'"
    units: "params.feeAmount"
    currency: "'USD'"
    condition: "params.feeAmount > decimal('0.00')"
  }
]

Transaction Fields

All fields in the transaction block accept CEL expressions:

FieldExpected TypeExample
journalIdUUID"uuid('b28f5684-0834-4292-8016-d2f2fb0367a9')"
correlationIdString"params.correlationId"
externalIdString"params.externalId"
effectiveDate"date('2024-01-15')" or "params.effectiveDate"
descriptionString"'Payment: ' + string(params.amount)"
metadataJSON"{ 'source': 'api', 'amount': string(params.amount) }"

Entry Fields

All fields in each entry accept CEL expressions:

FieldExpected TypeExample
entryTypeString"'ACH_CREDIT'"
accountIdUUID"params.accountId"
layerEnumeration"SETTLED" or "PENDING" or "ENCUMBRANCE"
directionEnumeration"DEBIT" or "CREDIT"
unitsDecimal"params.amount" or "decimal('100.00')"
currencyString"'USD'" or "params.currency"
descriptionString"'Entry for ' + params.memo"
metadataCEL Map/JSON"{ 'lineItem': params.lineItem }"
conditionBoolean"params.amount > decimal('0')"

Entity Field Reference

Account Fields

FieldTypeDescription
account_idUUIDUnique identifier
statusEnumACTIVE, LOCKED, or INACTIVE
nameStringAccount name
codeStringShorthand code
normal_balance_typeEnumDEBIT (0) or CREDIT (1)
descriptionStringAccount description
metadataStructArbitrary JSON data
createdTimestampCreation time
modifiedTimestampLast modification time
external_idStringExternal system identifier

Account Set Fields

FieldTypeDescription
account_set_idUUIDUnique identifier
journal_idUUIDAssociated journal
account_idUUIDAssociated account ID
nameStringSet name
descriptionStringSet description
metadataStructArbitrary JSON data
createdTimestampCreation time
modifiedTimestampLast modification time
codeStringUnique code
has_membersBooleanWhether set has members

Transaction Fields

FieldTypeDescription
transaction_idUUIDUnique identifier
tran_code_idUUIDAssociated tran code
journal_idUUIDAssociated journal
correlation_idStringGroups related transactions
external_idStringExternal system identifier
effectiveDateAccounting effective date
descriptionStringTransaction description
metadataStructArbitrary JSON data
createdTimestampCreation time
modifiedTimestampLast modification time

Entry Fields

FieldTypeDescription
entry_idUUIDUnique identifier
transaction_idUUIDParent transaction
journal_idUUIDAssociated journal
account_idUUIDTarget account
entry_typeStringEntry type code
layerEnumSETTLED (0), PENDING (1), or ENCUMBRANCE (2)
directionEnumDEBIT (0) or CREDIT (1)
descriptionStringEntry description
amountMoneyEntry amount with currency
metadataStructArbitrary JSON data
createdTimestampCreation time
modifiedTimestampLast modification time
parent_account_idsList[UUID]Parent account set IDs
is_void_entryBooleanTrue if this is a voiding entry
is_voided_entryBooleanTrue if this entry was voided

TranCode Fields

FieldTypeDescription
tran_code_idUUIDUnique identifier
codeStringUnique code identifier
descriptionStringTran code description
statusEnumACTIVE, LOCKED, or INACTIVE
paramsListParameter definitions
transactionStructTransaction template
entriesListEntry templates
metadataStructArbitrary JSON data
createdTimestampCreation time
modifiedTimestampLast modification time

Balance Fields

FieldTypeDescription
journal_idUUIDAssociated journal
account_idUUIDAssociated account
transaction_idUUIDLast transaction
entry_idUUIDLast entry
currencyStringCurrency code
settledBalanceAmountSettled layer balance
pendingBalanceAmountPending layer balance
encumbranceBalanceAmountEncumbrance layer balance
createdTimestampCreation time
modifiedTimestampLast modification time
calculation_idUUIDAssociated calculation
dimensionsStructDimension values

Type Constructors

When working with CEL expressions, use these constructors to create typed values:

ConstructorExampleDescription
uuid(string)uuid('a1b2c3d4-...')Parse UUID from string
decimal(string)decimal('100.50')High-precision decimal
money(string, string)money('100.00', 'USD')Money with currency
date(string)date('2024-01-15')Parse date (YYYY-MM-DD)
timestamp(string)timestamp('2024-01-15T10:30:00Z')Parse ISO 8601 timestamp
bool(string)bool('true')Parse boolean
int(string)int('42')Parse integer
string(any)string(params.amount)Convert to string

For a complete list of functions, see the CEL Functions Reference.