Read a live deal in five minutes
No key, no account, no signup. Everything on this page is a real request against the running test network deal, and the responses below are what it returned.
1. List the deals
curl -s https://tranching-production.up.railway.app/api/deals
{
"deals": [
{
"id": 1,
"name": "Bavarian Sky French Auto Leases 5",
"dealContractId": "CB3S3NWG7IUKUBAWAAJPFKVMCIMTRJ73GHZX6YZASRMZPVUGYFLCATJ4",
"payingAgentContractId": "CAXBYHZVHXOP3HQCMXPPVZMDUYEO27CTQQQDMWVNMMGSRCBSJHGIARZW",
"periodDays": 3,
"phase": "AMORTIZING",
"tranches": [ "..." ]
},
{ "id": 2, "name": "CARA7 Demo Series 2", "phase": "FUNDING", "...": "..." }
]
}
phase is read live from the contract, not from the database: FUNDING,
AMORTIZING, ENFORCED or MATURED.
2. Get a class and its current state
curl -s https://tranching-production.up.railway.app/api/tranches/1
{
"tranche": {
"id": 1,
"name": "Class A Notes",
"seniority": "SENIOR",
"contractId": "CBHFKNK7UK6YBVXZUWPOMY6LK44FZJSKWHPF4HJBUBV64KC455IJDROK",
"originalFace": "1000000000000",
"assetSymbol": "EURC",
"assetDecimals": 7,
"stats": {
"phase": "AMORTIZING",
"outstanding": "705477067000",
"noteFactorPct": 70.5477,
"coupon": { "allInPct": 2.809, "pricing": "EURIBOR 1M + 0.60% (floor 0%)" },
"cumulative": {
"interestPaid": "633316000",
"principalPaid": "294522933000"
},
"nextPayment": { "dueAt": "2026-08-06T19:15:33.000Z", "estimatedInterest": "165140423" }
}
}
}
Every amount is a string of base units. EURC has 7 decimals, so
705477067000 is 70,547.7067 EURC. Amounts are strings because they do not fit
in a JavaScript number without losing the last digits, and the last digits are
the ones that make a waterfall balance.
const toDecimal = (baseUnits: string, decimals: number): number =>
Number(BigInt(baseUnits)) / 10 ** decimals;
toDecimal('705477067000', 7); // 70547.7067
3. See who holds the notes and what they were paid
curl -s https://tranching-production.up.railway.app/notes/CBHFKNK7UK6YBVXZUWPOMY6LK44FZJSKWHPF4HJBUBV64KC455IJDROK/holders
[
{
"address": "GCV6OX6GKQOJJGD3DTF5AIENK3EKR64OPHCNCX5MGZUT2KTDD5QGFFRI",
"units": "800",
"sharePct": 80,
"interestReceived": "632916751",
"principalReceived": "274883474800"
},
{
"address": "GBXMM4TTZO3T7Y7VAZLXHZDTUEXODNU7NHA744FWFP5VBFGGCV22PGKB",
"units": "200",
"sharePct": 20,
"interestReceived": "399248",
"principalReceived": "19639458200"
}
]
The second holder bought 200 notes in the middle of a period. Look at the two numbers: they received 20% of the principal, because principal follows the holder at the end of the period, but only 0.0399 EURC of interest, because the coupon is split by the days each side actually held the notes. That is the whole day weighting rule, visible in one response.
4. Read the contract directly, without our API
Our API is a cache. The contract is the source. Anyone can query it:
stellar contract invoke \
--id CB3S3NWG7IUKUBAWAAJPFKVMCIMTRJ73GHZX6YZASRMZPVUGYFLCATJ4 \
--source-account <any-account> --network testnet --send=no \
-- get_note_factors
["705477067","10000000","10000000"]
Three classes, in seniority order. Factors are in units where 10000000 is
100%, so Class A stands at 70.5477067% and B and C are untouched.
From TypeScript, without a key:
import { rpc, TransactionBuilder, Contract, BASE_FEE, Account, Keypair, scValToNative } from '@stellar/stellar-sdk';
const server = new rpc.Server('https://soroban-testnet.stellar.org');
const tx = new TransactionBuilder(new Account(Keypair.random().publicKey(), '0'), {
fee: BASE_FEE,
networkPassphrase: 'Test SDF Network ; September 2015',
})
.addOperation(new Contract(DEAL_ID).call('get_note_factors'))
.setTimeout(30)
.build();
const simulation = await server.simulateTransaction(tx);
const factors = scValToNative(simulation.result!.retval) as bigint[];
Simulation costs nothing and needs no signature. Every get_* function on every
contract can be read this way.
Next
- Every endpoint: API reference
- The contracts, their functions and their invariants: contracts
- Try the subscription flow with a wallet: see it live