Skip to main content

API reference

Base URL: https://tranching-production.up.railway.app

No authentication on read endpoints. All amounts are strings of base units, and every response carries the assetDecimals you need to convert them. Errors are { "error": "..." } with the matching HTTP status.

This API indexes the chain. It never decides anything: if it disagrees with a contract, the contract is right and the index has a bug.

Registry

GET /api/deals

Every deal with its classes. phase is read live from the contract on each call.

curl -s $BASE/api/deals
FieldTypeMeaning
idnumberRegistry id, used in other paths
namestringDeal name
dealContractIdstringThe abs-deal contract
payingAgentContractIdstringThe paying-agent contract
periodDaysnumberLength of a period
phasestringFUNDING, AMORTIZING, ENFORCED, MATURED
tranches[]arrayThe classes, senior first

GET /api/tranches

Every class across every deal, each with a stats block (see below).

GET /api/tranches/:id

One class. 404 if the id is unknown.

The stats block:

FieldMeaning
phaseLifecycle phase of the deal
originalFaceFace value at issuance, base units
outstandingFace value still outstanding, base units
noteFactorPctoutstanding / originalFace as a percentage
coupon.allInPctCurrent all-in rate, percent
coupon.pricingHow that rate is built, in words
accrued.daysDays accrued in the current period
accrued.interestInterest accrued so far this period, base units
cumulative.interestPaidInterest paid since closing, base units
cumulative.principalPaidPrincipal repaid since closing, base units
lastDistribution{ ts, period } of the last waterfall run
nextPayment{ dueAt, estimatedInterest }

stats is null during FUNDING: nothing is outstanding before closing.

POST /api/deals

Register a deal. Body:

{
"name": "CARA7 Demo Series 3",
"description": "optional",
"dealContractId": "C...",
"payingAgentContractId": "C...",
"periodDays": 3
}

201 with the created deal, 409 if the name exists, 400 on a bad contract id (must match ^C[A-Z2-7]{55}$).

POST /api/deals/:id/tranches

Register a class under a deal. Body:

{
"name": "Class A Notes",
"seniority": "SENIOR",
"contractId": "C...",
"originalFace": "1000000000000",
"couponBps": 281
}

seniority is SENIOR, MEZZANINE or JUNIOR. originalFace is a string of base units. 409 if that contract is already registered.

Notes

Paths take the note token contract id, not the registry id.

GET /notes/:contractId/stats

The same stats block as above, at the top level.

GET /notes/:contractId/history

Time series for the charts: outstanding and note factor per snapshot.

GET /notes/:contractId/holders

Every holder of the class, with what they have been paid.

FieldMeaning
addressStellar account
unitsNotes held, whole numbers
sharePctShare of the class
interestReceivedInterest received to date, base units
principalReceivedPrincipal received to date, base units

GET /notes/:contractId/events

Decoded contract events, newest first: issues, transfers, interest and principal payments.

Positions

GET /users/:address/positions

Every position of one Stellar account across all classes: units held, outstanding claim, cost basis if they subscribed at issuance, and cash received split between interest and principal.

GET /users/:address/notes/:contractId/history

Time series of one account's position in one class: remaining claim and cumulative cash received.

Distributions

GET /api/deals/:id/distributions

Every waterfall run, newest first, one object per period.

{
"period": 3,
"ts": "2026-08-03T19:15:33.000Z",
"ledger": 3952923,
"collections": "99000000000",
"reserveReleased": "50000000000",
"carryIn": "1800",
"ada": "149000001800",
"fees": "500000000",
"reserveRefunded": "50000000000",
"carryOut": "1700",
"residual": "0",
"perClass": [
{ "class": 0, "tranche": "C...", "interest": "188126000", "principal": "98197291000", "shortfall": "0" }
],
"payments": { "C...": "98385417000" }
}

ada is the available distribution amount: collections plus the whole reserve released plus the carry. perClass is in seniority order, class 0 being senior. payments maps each note token to the total handed to the paying agent for it.

Other

GET /health

{ "ok": true }.

GET /api/stats

Totals across the registry: deals, classes, holders, cumulative amounts paid.

GET /prices/:symbol

Latest recorded price for an asset symbol, used for display only. It plays no part in the waterfall.