Data Dictionary

Loan Data Dictionary

This guide explains the core persistence tables Embarc uses to store loans, repayment schedules, monetary movements, and related balances. It focuses on the columns you most often read when building integrations or troubleshooting loan state. Where behaviour differs between Fixed Schedule and Dynamic Schedule products we call that out explicitly.

Conventions

  • Numeric columns are stored in major currency units (scale depends on tenant currency settings unless noted).
  • Dates are stored in tenant-local time (DATE without time component).
  • Most “*_derived” fields are recalculated by the platform after every servicing action (repayments, waivers, interest accrual, etc.).

Loan Master

ColumnDescriptionNotes / schedule differences
idPrimary key.Referenced by every child table.
account_noSystem-generated loan number (unique).Often used in statements/receipts.
external_idOptional external reference (UUID/string).Keep unique; integration middleware relies on it for idempotency.
client_idBorrower reference (m_client.id).Dynamic Schedule loans treat down payments as the first repayment for this borrower; no special linkage required.
product_idLoan product. Drives schedule generator, charges, accounting rules.Choose Dynamic Schedule products when you expect down payments, buy-downs, or staged interest.
loan_type_enumBorrower type enum.Embarc deployments typically use INDIVIDUAL.
loan_status_idCurrent lifecycle state (submitted, approved, disbursed, closed…).Approval changes this from 100 (submitted) to 200 (approved).
fund_id, loan_officer_id, loanpurpose_cv_idOperational metadata for reporting.Unchanged by schedule type.
loan_transaction_strategy_code / _nameRepayment allocation strategy. Dynamic Schedule products must use advanced-payment-allocation-strategy.
term_frequency, term_period_frequency_enumFull loan term (e.g., 12 months).
submittedon_date, approvedon_date, disbursedon_date, closedon_date, writtenoffon_date, etc.Lifecycle timestamps.Dynamic Schedule loans may have rescheduledon_date populated when you regenerate staged grids.
expected_disbursedon_date / expected_maturedon_datePlanned dates.
principal_amount_proposedAmount requested in the application.
approved_principalAmount approved. Copied to schedule as the base principal.
net_disbursal_amountAmount expected to disburse net of disbursement charges.
principal_disbursed_derived, principal_repaid_derived, principal_outstanding_derivedRunning totals for principal.If the loan has a down-payment period the amount collected in that period reduces principal_outstanding_derived immediately even though the first instalment might still be in the future.
interest_charged_derived, interest_repaid_derived, interest_outstanding_derivedInterest aggregates.For Dynamic Schedule loans with capitalisation, these exclude deferred income (see balance tables below).
fee_charges_*_derived, penalty_charges_*_derivedAggregates for fees and penalties.
total_overpaid_derived, overpaidon_dateAmount currently held as overpayment (credit balance).Applies to both schedule types.
is_npa, charged_off_on_dateNon-performing / charge-off tracking.Dynamic Schedule charge-off behaviour is configurable (charge_off_behaviour on the product); the column indicates whether charge-off has been applied.
enable_installment_level_delinquencyWhen true, Embarc tracks delinquency per instalment.Often enabled for Dynamic Schedule BNPL so each instalment can be surfaced separately.
interest_recalcualated_onLast business date on which daily interest was recomputed.Used by both schedules when interest recalculation is enabled.

Dynamic Schedule auxiliary tables

Dynamic Schedule loans create additional rows that store precomputed interest grids and promotional balances:

  • m_progressive_loan_model (json_model, business_date) – snapshot of the advanced schedule used for future interest forecasts.
  • m_loan_capitalized_income_balance – deferred interest amounts pending recognition.
  • m_loan_buy_down_fee_balance – outstanding promotional subsidies for buy-down products.

Fixed Installment loans never populate these tables.


Loan Summary – aggregate balances

This table mirrors the derived totals in m_loan, but it keeps historical aggregates even when some loan fields are migrated. Use it when you need a single-row summary without recalculating through every schedule row.

ColumnDescriptionNotes
total_principal_derivedTotal contractual principal.
principal_disbursed_derived, principal_repaid_derived, principal_outstanding_derivedPrincipal movement snapshots.
interest_charged_derived, interest_repaid_derived, interest_outstanding_derivedInterest aggregates. Dynamic schedule loans with interest capitalization move deferred interest into capitalized_income_derived until recognition.
fee_charges_*_derived, penalty_charges_*_derivedFee/penalty aggregates (charged, repaid, waived, written off, outstanding).
total_expected_repayment_derived, total_repayment_derivedExpected vs collected cash to date.
total_expected_costofloan_derived, total_costofloan_derivedInterest + fees + penalties expected/collected.
total_waived_derived, total_writtenoff_derived, total_outstanding_derivedOverall loan state used for dashboards and reporting.

No behavioural differences between schedule types appear in this table; it’s purely aggregated data.


Loan Disbursement Detail – tranche tracking

ColumnDescriptionNotes
loan_idParent loan.
expected_disburse_datePlanned tranche disbursement.Approval populates this from the application or overrides.
disbursedon_dateActual disbursement date (null until executed).
principalAmount assigned to this tranche.
net_disbursal_amountAmount after tranche-specific disbursement charges.
is_reversedFlag indicating the tranche was reversed (e.g., undo disbursement).

Dynamic schedule loans use the same structure. If down payment is enabled, the down-payment amount shows up as the first repayment schedule period rather than a tranche.


Loan Repayment Schedule – instalment plan

Each row represents a single repayment period (including down-payment or additional adjustment periods).

ColumnDescriptionDynamic Schedule notes
installmentInstalment sequence number (starts at 1).Down-payment periods are flagged with is_down_payment = true and typically use instalment 0 or 1 depending on configuration.
fromdate / duedatePeriod boundaries.Dynamic Schedule daily interest recalculation may insert additional rows flagged with recalculated_interest_component = true.
principal_amountContracted principal due in the period.Down payment shows the upfront contribution here.
principal_completed_derived, principal_writtenoff_derivedAmounts already satisfied or written off.Partial prepayments reduce principal_completed_derived, even if the due date is in the future.
interest_amount, interest_completed_derived, interest_waived_derived, interest_writtenoff_derived, accrual_interest_derivedInterest movements.When Dynamic Schedule interest recalculation runs, recalculated_interest_component rows capture the incremental interest until the next scheduled period.
fee_charges_amount, penalty_charges_amount and their _completed/_waived/_writtenoff counterpartsInstalment-level fees/penalties.Dynamic Schedule loans often keep instalment fees here to align with merchant agreements.
total_paid_in_advance_derived / total_paid_late_derivedCredits paid before/after due date.Important when interpreting delinquent.nextPaymentAmount: the delinquency API subtracts advance payments to surface the remaining balance.
obligations_met_on_dateWhen populated, the instalment is considered fully satisfied.If null, the instalment remains open even if the due date is in the future.
recalculated_interest_componentMarks rows created by interest recalculation.Common for Dynamic Schedule loans with daily interest; Fixed Schedule loans may also set this when interest recalculation is enabled, but fewer rows are generated.
is_additionalFlags adjustment rows (e.g., post-approval corrections).
is_down_paymentTrue when the row represents a down-payment period.Always false for Fixed Schedule loans.
is_re_agedTrue when the instalment was shifted by a re-age command.

Loan Transaction – cash movements and adjustments

ColumnDescriptionSchedule details
idPrimary key.
loan_idParent loan.
transaction_type_enumEnumerated type: repayment, disbursement, interest waiver, charge-off, down payment, buy-down fee, capitalized income, etc.Dynamic Schedule loans introduce additional transaction types (downPayment, buyDownFee, capitalizedIncome*, interestPaymentWaiver).
transaction_dateEffective date of the transaction.
submitted_on_dateWhen the command was submitted.
amountGross amount processed.
principal_portion_derived, interest_portion_derived, fee_charges_portion_derived, penalty_charges_portion_derived, overpayment_portion_derivedHow the amount was allocated.For Dynamic Schedule buy-down/capitalisation transactions the principal/interest portions may be zero while deferred income fields move in the balance tables.
unrecognized_income_portionAmount held as deferred income (used for capitalised interest/buy-downs).Mostly non-zero on Dynamic Schedule transactions.
is_reversedIndicates the transaction has a matching reversal entry.
external_id / reversal_external_idOptional references for reconciliation.
outstanding_loan_balance_derivedLoan balance immediately after the transaction (principal only).
manually_adjusted_or_reversedFlag when back-office manually adjusted the transaction.
charge_refund_charge_typeCharge type associated with charge refunds.

Mapping table m_loan_transaction_repayment_schedule_mapping

Links transactions to specific schedule rows and records allocation amounts (principal_portion_derived, interest_portion_derived, fee_charges_portion_derived, penalty_charges_portion_derived, amount). Useful when you need to reconcile which transactions cleared which installments.


Loan Charge and related tables

ColumnDescriptionNotes
charge_time_enumWhen the charge is assessed (disbursement, installment-specific, overdue, specified-date).Dynamic schedule loans often attach installment-level fees to mirror merchant agreements.
due_for_collection_as_of_dateCharge due date.
charge_calculation_enumAmount type (flat, percentage of principal, etc.).
amountOriginal charge amount.
amount_paid_derived, amount_waived_derived, amount_writtenoff_derived, amount_outstanding_derivedLifecycle of the charge.Delinquency amounts exclude charges unless amount_outstanding_derived is still positive.
is_penalty, is_paid_derived, waived, is_activeStatus flags.
external_idExternal reference for reconciliation.

Supporting tables:

  • m_loan_charge_paid_by – how a repayment settled specific charges (loan_transaction_id, loan_charge_id, allocation amounts).
  • m_loan_installment_charge – splits instalment-based charges per schedule row for Dynamic Schedule products.
  • m_loan_overdue_installment_charge – generated by the overdue-charge job for instalment-level penalties.

Payments, payment instruments, and autopay

em_payment_instrument

ColumnDescriptionNotes
idPrimary key.Parent row for every stored instrument.
customer_idBorrower (m_client.id).Enforces same-owner rule for loans, autopay, and payments.
payment_instrument_typeEnum (BANK_ACCOUNT, future types such as DEBIT_CARD).Determines which child table stores instrument details.
nick_nameFriendly label shown in UI/history.Unique per customer is recommended.
statusEnum (ACTIVE, INACTIVE).Only active instruments appear in payment/autopay pickers.
is_deletedSoft-delete flag.TRUE hides the instrument but keeps audit trail.
versionOptimistic locking counter.Incremented on each update.
created_at, updated_atTimestamps (UTC).
created_by, updated_bym_appuser references.Captures who created/last modified.

em_bank_payment_instrument

Child table with bank-specific fields (1:1 via payment_instrument_id).

ColumnDescriptionNotes
account_holder_name / account_holder_typeLegal owner of the account (INDIVIDUAL, BUSINESS).
account_typeEnum (CHECKING, SAVINGS).
account_number, routing_numberStored encrypted/masked.Mask before exposing downstream.
bank_nameFree-form issuer label.
verification_stateEnum (PENDING, VERIFIED, REJECTED, REVOKED).Autopay requires VERIFIED.
external_idOptional reference to external processors/KYC providers.
created_at, updated_at, version, created_by, updated_byStandard auditing columns.

em_autopay

ColumnDescriptionNotes
idPrimary key.
loan_idLoan enrolled in autopay (m_loan.id).
customer_idBorrower (m_client.id).Must equal the instrument’s owner.
payment_instrument_idFK to em_payment_instrument.Instrument must be active & verified.
statusEnum (ACTIVE, PAUSED, CANCELLED).Scheduler only pulls ACTIVE rows.
cancelled_reasonEnum reason when status = CANCELLED.E.g., CUSTOMER_REQUEST, LOAN_CLOSED, PAYMENT_FAILURES_EXCEEDED.
enrollment_dateTimestamp of initial enrollment.
cancelled_at, cancelled_byWhen/who cancelled (if applicable).
created_at, updated_at, created_by, updated_byAudit trail.
versionOptimistic locking counter.

em_payment

ColumnDescriptionNotes
idPrimary key.
loan_idLoan the payment belongs to.Required for all rows.
external_idUnique idempotency/payload reference.Enforced by uq_em_payment_external_id.
payment_instrument_idOptional FK to em_payment_instrument.Populated for initiated payments and autopay executions.
autopay_idOptional FK to em_autopay.Links settled autopay runs back to the enrollment.
amountGross payment amount (loan currency).
effective_dateBusiness date applied to the loan.
statusEnum (PENDING, PROCESSING, SETTLED, RETURNED, FAILED, CANCELED, CHARGEBACK).Drives which timeline columns below are populated.
type, sourceFree-form descriptors (e.g., REPAYMENT, REFUND; PORTAL, CSR).Useful for reporting.
is_external_paymentTRUE when payment was logged after the fact.
payment_methodEnum (ACH, RTP, WIRE, CARD, CHECK, CASH, MONEY_ORDER, OTHER).
trace_number, check_number, account_number, routing_number, bank_name, payor_name, payee_nameProcessor metadata.Mask values before exposing externally.
metadataJSONB payload for processor responses or custom fields.
noteFree-form comment.
created_at, updated_at, created_by, updated_byAudit trail.
processed_at, settled_at, expected_settlement_at, returned_at, failed_at, canceled_at, chargeback_at, effective_atTimestamps that track the payment lifecycle.Use to build settlement dashboards and SLAs.
failure_reason, failure_details, failure_log, return_reason, return_details, cancel_reason, cancel_details, return_amount, chargeback_amount, chargeback_atCaptures why a payment reversed and any partial refund amounts.
loan_transaction_idFK to the posting entry in m_loan_transaction.Links processor record to ledger impact.
return_loan_transaction_id, chargeback_loan_transaction_idFKs to reversal transactions created for returns/chargebacks.
processor_transaction_id, processor_return_id, processor_chargeback_idExternal processor identifiers.
versionOptimistic locking counter.

Payments are the system-of-record for processor state. Pair them with m_loan_transaction data when reconciling the general ledger.


Additional tables frequently used in reporting

TablePurposeNotes
m_loan_arrears_agingSnapshot of arrears ageing (principal, interest, fee, penalty past due buckets).Populated by COB/delinquency jobs.
m_loan_installment_delinquency_tagWhen instalment-level delinquency is enabled, this table records the current tag (range_id) per instalment.Dynamic Schedule BNPL implementations set this flag to surface which instalments are past due.
m_loan_interest_recalculation_additional_detailsStores recalculation metadata for Fixed Schedule loans (e.g., compounding strategy).Dynamic Schedule loans rely more on the progressive model tables instead.

Interpreting data by schedule type

ConsiderationFixed Schedule loansDynamic Schedule loans
Installment outstanding (principal_amount - principal_completed)Represents the true remaining balance and is what the delinquency API surfaces. Partial prepayments reduce it immediately.The same calculation applies, but if daily interest recalculation is enabled additional rows (recalculated_interest_component = true) hold interim interest until the next scheduled due date.
Down paymentNot applicable; first installment behaves like any other repayment.Represented as a schedule row with is_down_payment = true and accompanied by a downPayment loan transaction.
Buy-down / capitalised incomeNot tracked in schedule totals.Additional balance tables (m_loan_buy_down_fee_balance, m_loan_capitalized_income_balance) store deferred revenue; related transactions use the custom types in m_loan_transaction.
Delinquency next paymentStraightforward outstanding amount from the next unpaid schedule row.Amount is predicted via the dynamic interest model; ensure next-payment-due-date config is set appropriately to avoid pointing to the last repayment date.

Usage tips

  • Always filter by is_reversed = false when aggregating loan transactions; reversal entries remain in the table for audit.
  • Schedule rows are immutable—the platform creates adjustment rows (is_additional = true) instead of editing past records. When reconciling, include these rows in your calculations.
  • Charges vs installment totals – Statement designs often need both schedule data and outstanding charges (amount_outstanding_derived). Partial installment payments may leave charges unpaid even though the schedule row shows zero outstanding.
  • Dynamic Schedule analytics – To mirror how Embarc predicts the next payment for dynamic (precomputed) plans, read the stored progressive loan model (m_progressive_loan_model) and run it through the same interest-forecast logic used for Pay-in-N/BNPL schedules. This applies the advanced payment allocation rules, daily interest accrual, and down-payment adjustments exactly as Embarc does. For Fixed Schedule loans you simply sum the remaining amounts on the standard repayment schedule.