Browse the extensions reference

Preview Schedule

post/extensions/roboledger/{graph_id}/operations/preview-schedule

Part of RoboLedger: Fiscal Close.

Generate a schedule from a definition without keeping it: the same generator and guards as creating one (block_type='schedule' on create-information-block), run and rolled back. Returns the envelope create would leave (its ids provisional) and the period-by-period roll-forward: the balance the schedule carries on the account it credits (a loan's: the note), opening, the period's amount, closing, and for a loan the interest, payment, principal and current portion. Show it to the person before asking to create. A definition create would refuse (a roll-forward that climbs where it should fall, legs that do not balance) is refused here with the period that breaks. warnings names any active schedule already posting the same accounts in the same months. With replaces_structure_id, replaces says what the schedule being edited or recreated has posted, by month, and the path the change takes: rebuild (rebuild-schedule with the new definition) while nothing has posted, terminate_and_succeed after.

Idempotency: supply an Idempotency-Key header to make safe retries; replays within 24 hours return the same envelope. Reusing the key with a different body returns HTTP 409 Conflict.

Authentication

Authenticate in any one of these ways — not all of them:

  • API key in the X-API-Key header.
  • Bearer token in the Authorization header.

Path parameters

NameTypeDescription
graph_idrequiredstringGraph Id

Constraints: matches ^(kg[a-f0-9]{16,}(?:_[a-zA-Z0-9]{1,20})?|sec(?:_[a-zA-Z0-9]{1,20})?|library)$

Header parameters

NameTypeDescription
Idempotency-KeyoptionalstringIdempotency-Key

Request body

Required, application/json.

FieldTypeDescription
namerequiredstring

Schedule name

entity_idoptionalstring

The entity whose books the schedule belongs to, by id. Omit for the group parent. Its facts, obligations and closing entries land in that entity's books, against that entity's own accounts.

taxonomy_idoptionalstring

Taxonomy ID (auto-creates if omitted)

element_idsrequiredstring[]

CoA element ids the schedule touches (the id from get-unmapped-elements, not taxonomy qnames) — typically the same debit + credit ids used in entry_template.

period_startrequiredstring (date)

First period start

period_endrequiredstring (date)

Last period end

monthly_amountoptionalinteger

Monthly amount in cents. Required for a straight-line schedule; a custom or loan schedule takes its amounts from its curve.

Default: 0

entry_templaterequiredEntryTemplateRequest
EntryTemplateRequest fields
FieldTypeDescription
debit_element_idrequiredstring

CoA element id to debit (e.g. Depreciation Expense). This is a chart-of-accounts element id — the id returned by get-unmapped-elements / get-graph-schema — NOT a taxonomy qname.

credit_element_idrequiredstring

CoA element id to credit (e.g. Accumulated Depreciation). A chart-of-accounts element id (see get-unmapped-elements), not a taxonomy qname. A straight-line or custom schedule posts this one debit/credit pair; a loan schedule posts its legs.

entry_typeoptionalstring

Entry type for generated entries

One of: standard, adjusting, closing, reversing

Default: closing

memo_templateoptionalstring

Memo template ({structure_name} is replaced)

Default:

auto_reverseoptionalboolean

Auto-generate a reversing entry on the first day of the next period

Default: false

dimension_idsoptionalstring[]

The management dimension members (department, class, location, project) every entry the schedule drafts carries on both lines, one per axis: a department's depreciation lands in that department.

legsoptionalScheduleLegRequest[]

The lines of a loan schedule's entry (method='effective_interest' only), each taking one column of the amortization table; each period's lines must balance. Accrue interest and pay through the bank: debit Interest Expense and credit Accrued Interest, both interest. The schedule settles the payment itself: debit the note principal, debit Interest Expense interest, credit cash or a due-to payment. debit_element_id names the interest debit leg and credit_element_id one credit leg. Empty for every other method, which posts the debit/credit pair.

ScheduleLegRequest fields
FieldTypeDescription
element_idrequiredstring

CoA element id the line posts to.

siderequiredstring

The line's side.

One of: debit, credit

amount_sourcerequiredstring

The amortization-table column the line takes each period: interest (accrued in the period), interest_paid (accrued interest settled by the period's payment), principal (principal repaid), payment (interest_paid + principal).

One of: interest, interest_paid, principal, payment

schedule_metadataoptionalScheduleMetadataRequest
ScheduleMetadataRequest fields
FieldTypeDescription
methodoptionalstring

Calculation method. 'straight_line' (default) distributes monthly_amount evenly across periods with the final period absorbing rounding. 'custom' requires periodic_amounts — the generator uses those values verbatim instead of computing. 'effective_interest' requires loan_terms and the template's legs: the generator computes the amortization table (opening balance, interest, payment, principal, closing balance) and drafts the legs from it. Other strings are labels only; fact values still come from monthly_amount or periodic_amounts.

Default: straight_line

loan_termsoptionalLoanTermsRequest

The loan's terms, for method='effective_interest'.

LoanTermsRequest fields
FieldTypeDescription
principalrequiredinteger

Principal drawn, in cents.

Constraints: greater than 0

annual_raterequirednumber

Annual interest rate as a fraction: 0.099 for 9.9%.

Constraints: at least 0; less than 1

start_daterequiredstring (date)

The day the principal was drawn; interest accrues from it. Falls in the schedule's first month.

day_countoptionalstring

How a period's interest counts days: 30/360 (every whole month is 30 days), actual/365 or actual/360 (the days elapsed, over a 365- or 360-day year; actual/360 is the usual bank line of credit).

One of: 30/360, actual/365, actual/360

Default: 30/360

payment_frequencyoptionalstring

How often a payment falls due. A payment is applied at the end of the month it falls in.

One of: monthly, quarterly, annual, at_maturity

Default: monthly

first_payment_dateoptionalstring (date)

The first payment's date. Omit for one frequency after the schedule's first month.

payment_amountoptionalinteger

Each scheduled payment in cents, interest included. Omit for the level payment that retires the principal by maturity_date, or for the accrued interest when interest_only.

Constraints: greater than 0

interest_onlyoptionalboolean

Payments settle interest only; the principal is due at maturity.

Default: false

maturity_dateoptionalstring (date)

When the remaining principal is due: it is repaid in that month, which is the schedule's last. Omit for a line of credit with no maturity, whose balance carries past the schedule.

capitalize_interestoptionalboolean

Interest is added to the note rather than accrued apart (a PIK note): the balance grows by each period's interest, and payments reduce it whole.

Default: false

note_element_idrequiredstring

The liability account the principal is carried in. The schedule states its balance each period, which the schedule reconciliation compares with the ledger.

current_portion_element_idoptionalstring

A current-liability account for the principal due within twelve months. When set, each period's entry also reclasses between it and note_element_id so it holds the next twelve months' principal.

original_amountoptionalinteger

Cost basis in cents

Default: 0

residual_valueoptionalinteger

Salvage value in cents. The schedule expenses original_amount less this; net book value ends at it.

Default: 0

useful_life_monthsoptionalinteger

Useful life in months

Default: 0

asset_element_idoptionalstring

BS asset element for net book value

booked_onoptionalstring (date)

The date the cost went on the books, when that is before the schedule's first period: a policy paid in December that starts amortizing in January, or an asset bought the month before it is placed in service. From this date until the first period the schedule carries its full cost, so the schedule reconciliation does not report that balance as unscheduled. Leave it out when the cost is booked in the first period.

periodic_amountsoptionalinteger[]

Explicit per-period amounts in cents. When set, the generator uses these values instead of monthly_amount — enabling non-straight-line schedules (effective-interest bond discount amortization, day-count interest accrual, variable lease payments, pre-computed effective-yield curves, etc.). Length must match the number of monthly periods between period_start and period_end; sum must equal original_amount less residual_value exactly. The auto-generated SumEquals rule proves that total regardless of the curve shape.

closed_throughoptionalstring (date)

Watermark for onboarding. Facts with period_end ≤ this date are flagged 'historical' and their schedule_entry_due obligations are emitted 'voided', so the close workflow starts drafting at the first open period. Defaults to the calendar's history end: the last day of its closed_through month (calendar '2026-05' → '2026-05-31'), or the day before its first month when nothing has closed yet. An earlier date is raised to it, since an obligation there could never post; set a later one only to treat more months as already booked.

source_transaction_idoptionalstring

Free-form reference to the originating GL transaction (e.g. an import ID, ledger entry ID, or external system key). Stored in artifact_mechanics for audit; no FK constraint.

replaces_structure_idoptionalstring

The schedule this definition would replace, when editing or recreating one: the preview then says what its posted entries mean for the change.

Example request

curl
curl -X POST "https://api.robosystems.ai/extensions/roboledger/{graph_id}/operations/preview-schedule" \
  -H "X-API-Key: $ROBOSYSTEMS_API_KEY" \
  -H "Idempotency-Key: <Idempotency-Key>" \
  -H "Content-Type: application/json" \
  -d '{
  "name": "string",
  "element_ids": [
    "string"
  ],
  "period_start": "2026-01-31",
  "period_end": "2026-01-31",
  "entry_template": {
    "debit_element_id": "string",
    "credit_element_id": "string"
  }
}'

Responses

200 Successful Response

FieldTypeDescription
operationrequiredstring

Kebab-case operation name

operationIdrequiredstring

op_-prefixed ULID for audit and SSE correlation

statusrequiredstring

Operation lifecycle state

One of: completed, pending, failed

resultoptionalPreviewScheduleResponse

Command-specific result payload

PreviewScheduleResponse fields
FieldTypeDescription
enveloperequiredInformationBlockEnvelope

The schedule's Information Block envelope as create would leave it. Its ids are provisional: nothing was written.

InformationBlockEnvelope fields
FieldTypeDescription
idrequiredstring
block_typerequiredstring

Discriminator — 'schedule', …

namerequiredstring
display_namerequiredstring

Registry-sourced display label (e.g., 'Schedule').

categoryrequiredstring

Registry-sourced sidebar grouping ('Close', 'Reporting', …).

taxonomy_idoptionalstring

Source taxonomy the Structure was seeded from. Always present for currently-registered block types (the Structure → Taxonomy FK is non-null); declared optional to keep the shape forward-compatible with future synthetic blocks that don't originate from a taxonomy.

taxonomy_nameoptionalstring

Display name of the source taxonomy.

disclosure_idoptionalstring

Qname of the named Disclosure this block corresponds to (e.g., 'disclosures:BalanceSheet'), when an inbound reportedDisclosure-requiresDisclosure arc identifies one. Null for tenant-authored blocks without a Disclosure mapping.

entity_idoptionalstring

The entity whose books the envelope reads. A schedule, reconciliation or forecast is one entity's own and always reads its owner's; a block shared by the group (statements, metrics) reads the entity asked for, else the group parent. Null on the library and on a graph with no entity yet.

information_modelrequiredInformationModelResponse

The block's intrinsic shape — concept + member arrangement patterns.

artifactrequiredArtifactResponse

The block's producible-artifact envelope — topic, template, mechanics.

elementsoptionalElementLite[]

Element projection for bundling inside an Information Block envelope. Narrower than :class:LibraryElementResponse — excludes the heavy fields (labels, references, classifications) that library browsing needs but block consumers don't. Agents + frontends ask for those on demand via the full library GraphQL fields when they need them.

connectionsoptionalConnectionLite[]

Connection (= Association) projection. "Connection" is the ontology term used on the wire; the storage table is associations (models/extensions/association.py).

factsoptionalFactLite[]

Fact projection — just the values the envelope caller cares about.

rulesoptionalRuleLite[]

Rule projection for the Information Block envelope. One row per public.rules entry scoped to this block. The rule engine consumes rule_expression + rule_variables to evaluate against the in-scope fact set; the envelope surfaces the rules so the UI can render them as a checklist alongside any persisted verification results.

dimensionsoptionalobject[]
fact_setoptionalFactSetLite

The period-specific FactSet this envelope instantiates. Null when the underlying block has no FactSet row yet — typically library-seeded statement Structures with no tenant-generated facts, or Schedule rows written before the create-side FactSet stamping was added.

verification_resultsoptionalVerificationResultLite[]

Persisted outcome of one Rule evaluation. One row per public.verification_results entry the rule engine writes. The envelope surfaces them so the block viewer's "Verification Results" tab and MCP list-verification-failures tool can render + aggregate without a second round-trip.

verification_summaryoptionalVerificationSummary

Server-computed aggregate over verification_results — overall pass/fail/error/skip counts plus a per-rule_category breakdown for the grouped Verification Results panel. Null when the block has no verification results.

viewoptionalViewProjections

Server-computed view projections (the six type-of View projections). view.rendering carries pre-computed rows + periods + validation for blocks where rendering is deterministic (the statement family today). Projections without backend support yet are empty — see :class:ViewProjections.

roll_forwardoptionalScheduleRollForwardRow[]

One period of a previewed schedule: the balance it carries, and what moves it.

ScheduleRollForwardRow fields
FieldTypeDescription
period_startrequiredstring (date)
period_endrequiredstring (date)
openingrequirednumber

The carried balance at the period's start.

amountrequirednumber

What the period recognizes: the entry's debit amount.

closingrequirednumber

The carried balance at the period's end.

scoperequiredstring

historical for a month already in the books' history, which the schedule records but never drafts; in_scope for one a close drafts.

One of: historical, in_scope

interestoptionalnumber

Loan schedules: interest accrued.

paymentoptionalnumber

Loan schedules: the payment.

principaloptionalnumber

Loan schedules: principal repaid.

current_portionoptionalnumber

Loan schedules with a current-portion account: the principal due in the next twelve months.

warningsoptionalstring[]

Things create would go ahead with that deserve a look: an active schedule already posting to the same accounts over the same months.

replacesoptionalScheduleReplacementSummary

With replaces_structure_id: the schedule being replaced.

ScheduleReplacementSummary fields
FieldTypeDescription
structure_idrequiredstring
namerequiredstring
posted_entry_countrequiredinteger

Its posted or shadowed closing entries.

posted_periodsoptionalstring[]

The months those entries are in (YYYY-MM).

draft_entry_countoptionalinteger

Default: 0

pathrequiredstring

rebuild when nothing has posted: rebuild-schedule with the new definition replaces it in place. terminate_and_succeed once an entry has: terminate it after its last posted month and create the successor from the month after.

One of: rebuild, terminate_and_succeed

atrequiredstring

ISO-8601 UTC timestamp

createdByoptionalstring

User ID that initiated the operation

idempotentReplayoptionalboolean

True when this envelope came from the idempotency cache — the underlying command did not execute again. False on fresh executions.

Default: false

StatusMeaning
400Invalid request
401Authentication required
403Access denied
404Resource not found
409Idempotency-Key conflict — key reused with different body
422Validation error
429Rate limit exceeded
500Internal server error