ISETAPI Documentation
ISET Registry API · v1

One integration. The whole registry.

Issue, hold, transfer, and verify eInstruments over plain HTTPS + JSON. Every response is post-quantum signed (NIST FIPS 204 · ML-DSA-65) and anchored in a hash-chained audit ledger — evidence-grade by design, independently re-verifiable by anyone.

Base URL: https://iset.finance/api

Sandbox by default. Records issued without a production issuer agreement are flagged sandbox — fully signed, fully verifiable, no legal effect. Production issuance follows issuer qualification (KYI).

Authentication

Two levels, by design:

Public — no credentials

Verification is public. Anyone holding a record's reference may confirm it — that is the point of a registry.

Session — passkey sign-in

Issuing, listing, and transferring act on your records, so they require your account session. Sign in at /console/ with a passkey, then send the session token:

# the dashboard does this automatically; direct callers send:
Authorization: Bearer <session_token>
No API key ever ships to a browser. Server-side keys are provisioned only under an issuer agreement, with their own scope.

The lifecycle

A record moves through controlled states. Every transition is a signed, audit-anchored event; invalid transitions are refused by the registry.

registered pledged released transferred discharged

pledge grants a lender control during a credit term · release returns it · transfer passes control to a new holder (MLETR-aligned §10 for transferable records) · discharge ends the instrument — terminal, irreversible.

Compose a request

Configure a record on the left — the exact API request builds itself on the right. Copy it, or sign in to issue it for real.

Instrument
Face amount2,500,000
Currency
First holder
Your request

          
Returns 200 · signed record (ML-DSA-65) · status registered · public verify path included
Issue for real

Verify a record

GET/api/etr/verify/{reference}Public

Confirms a record by its reference: what it is, its current status and holder, and the signature that proves it. This is what a bank officer reaches when scanning a record's QR.

Request
curl https://iset.finance/api/etr/verify/fvt_9f40e226_87a14068
Response · 200
{
  "ok": true, "verified": true,
  "record": {
    "etr_id": "fvt_9f40e226_87a14068",
    "instrument": "ePN", "instrument_name": "Electronic Promissory Note",
    "amount": "2500000", "currency": "PHP",
    "status": "registered", "holder_ref": "phase2-test",
    "history": [], "sandbox": true,
    "signature": "ML-DSA-65:…", "record_hash": "sha-256:…"
  },
  "brand": null
}

Issue an eInstrument

POST/api/etr/issueSession

Issues a record under your account: signed at the root, entered in the registry, owned by you, verifiable by anyone holding its reference.

FieldTypeDescription
type requiredstringOne of ePN · eBE · eBL · eLC · eWR · eCI
amountstringFace amount
currencystringDefault PHP
holder_refstringThe first holder — person or institution
memostringTerms or note, ≤ 500 chars
fieldsobjectPer-instrument particulars — parties, voyage, cargo, terms. Schema: /assets/etr-schemas.js. Stored and rendered on the certificate.
Request
curl -X POST https://iset.finance/api/etr/issue \
  -H "Authorization: Bearer <session_token>" \
  -H "Content-Type: application/json" \
  -d '{"type":"ePN","amount":"2500000","currency":"PHP","holder_ref":"Juan Dela Cruz"}'
Response · 200 — signed record + verify_path
{ "etr_id": "fvt_…", "status": "registered", "signature": "ML-DSA-65:…",
  "court_admissible": true, "verify_path": "/v1/etr/verify/fvt_…" }

List records

GET/api/etr/listSession

Your records, newest first — references, statuses, holders, and signatures. Listing is private: there is no public index of the registry.

Response · 200
{ "ok": true, "count": 2, "records": [ … ] }

Transfer control

POST/api/etr/transferSession

Acts on a record you own. Each action is a signed event; the registry enforces valid transitions and refuses anyone but the owner.

FieldTypeDescription
etr_id requiredstringThe record's reference
actionstringtransfer (default) · pledge · release · discharge
to_refstringWho receives control — required for transfer and pledge
notestringOptional, ≤ 300 chars — entered in the audit event
Request — pledge to a lender
curl -X POST https://iset.finance/api/etr/transfer \
  -H "Authorization: Bearer <session_token>" \
  -H "Content-Type: application/json" \
  -d '{"etr_id":"fvt_…","action":"pledge","to_ref":"Partner Bank A"}'
Response · 200 — signed control event
{ "isp_name": "ETR_CONTROL_PLEDGE", "status": "pledged",
  "holder_ref": "Partner Bank A", "signature": "ML-DSA-65:…" }
Refusals you can rely on: a non-owner gets 403; an invalid transition (for example pledging a pledged record) gets 409; a discharged record refuses everything.

Subscriber profile

GET/api/subscriberSession

Your account profile — name, account type, branding (colour · logo · verify destination), tier, packs. The same profile drives the white-label certificate at /record/<reference>.

POST/api/subscriberSession

Updates the profile. Send only the fields you change; logos are data-URLs ≤ 200 KB.

Audit retrieval

GET/api/audit/{audit_id}Public

Retrieves a signed event from the hash-chained ledger and re-verifies its signature against the published key on read. The public key lives at /.well-known/ml-dsa65-public.json — you can check the mathematics yourself.

Model Context Protocol

An AI client can verify records and read the instrument schemas without an integration. Point any MCP client at the endpoint below — no SDK, no account, no key.

GET / POST https://iset.finance/mcp

JSON-RPC 2.0. A GET returns the discovery document to a client and a readable page to a browser, so the same URL serves both.

Tools

ToolReturns
verify_recordWhether a record is real, who holds it, its status and audit anchor
list_instrumentsThe twelve instrument types, their legal basis, negotiability class, and which are transferable under MLETR
get_instrument_schemaParties, particulars and lifecycle for one instrument
get_instrument_lifecycle_stateThe status of one record — raw state, its band, and what it means commercially
verify_cif_setInvoice + bill + insurance checked as one set — cross-references and the UCP 600 art. 28 arithmetic
check_counterparty_limitsWhether a counterparty profile exists and what limits it records — never a fabricated pass
describe_registryWhat the registry is and is not — use before asserting anything about ISET

Connect a client

{
  "mcpServers": {
    "iset-etr": { "url": "https://iset.finance/mcp" }
  }
}

Try it by asking your client to verify EPN-2026-SAMPLE-0001 — or run every call yourself in the sandbox, no signup, with the well-known sandbox key iset_sandbox_demo_v1.

Read-only, deliberately. Issuance, endorsement and settlement are not exposed over MCP. An API key proves possession, not authority to bind an institution, and the audit chain has to record the actor rather than the key — so those operations require an authorised human signer.

On-chain settlement

The control layer is chain-portable by design — the registry record is chain-agnostic, and each network gets its own anchoring contract. Stellar is the first supported network.

The registry above is the system of record for terms and identity. A separate, public control layer runs on Stellar (Soroban): the epn_escrow contract governs who holds a note — exclusively, one holder at a time — and its full lifecycle through endorsement, settlement, or default. The contract never custodies or moves funds; it enforces control. The two layers are deliberately decoupled — the registry operates standalone without it (see deployment spectrum).

The reference application is live at stellar.iset.finance — issue, endorse, accept, settle, and verify against real wallets, no account needed.

POST/api/etr/stellar-issuePublic

Issues and post-quantum signs a record for the Stellar app: validates the instrument code against the six-type allow-list and the stellar_pubkey format, then registers the record and returns its signature and audit anchor. CORS-enabled for stellar.iset.finance.

Response · 200
{ "etr_id": "fvt_…", "record_hash": "sha-256:…",
  "signature": "ML-DSA-65:…", "audit_id": "aud_…", "sandbox": true }

The epn_escrow contract

Rust / Soroban. Every state transition requires the acting party's on-chain authorization and emits an event. Endorsement is a two-signature handshake — offer by the current holder, acceptance by the named endorsee — so transfer of control is bilateral, exclusive, and provable.

FunctionWho may callEffect
initmakerRegisters terms (maker, holder, amount, maturity) · status Active
endorsecurrent holderOffers control to a named endorsee — revocable until accepted
acceptnamed endorseeTakes exclusive control; previous holder loses all authority
release_fundscurrent holderSettles the note · terminal Released
claim_defaultmaker, after maturityReclaims a matured, unsettled note · terminal Defaulted
terms · status · pendinganyoneRead views — no wallet, no credentials, via transaction simulation
Structural guarantees, not policy: a second endorsement of the same note by a former holder is refused on-chain (Unauthorized); a settled or defaulted note refuses every further action (NotActive); default before maturity is refused (NotMatured). These refusals hold regardless of who operates the registry.

Deployments

NetworkContractState
TestnetCDZMFQBSZO44IX5TMHY55PYG6I3JOUEZFWSRMFJCUAF2AKWOOWX2H3ITFull lifecycle incl. two-party endorsement — the live demo network
MainnetCBDFHJ2V7YBQGF4PNDPTKAALHIE6PYRBL6PVAGMJA5OFFEUMHJYQLL7OIssue + settle live; the endorsement upgrade is staged and pending deployment

For institutions — legal posture & integration

Legal posture, stated precisely

Records issued here have legal standing as electronic documents and signatures under the Electronic Commerce Act (RA 8792) — an electronic record is not denied validity for being electronic. What RA 8792 does not settle is full negotiable-instrument status: the electronic equivalent of indorsement and delivery. That is precisely what the UNCITRAL MLETR codifies — and the Philippines has not yet enacted it.

Our position is therefore deliberate: we built the control architecture MLETR's test requires — a single authoritative record of control, exclusive control enforced by contract, integrity by hash-chain and signature, and an identifiable current holder — so records are MLETR-ready ahead of recognition, not claimed compliant before it. For secured lenders, the Personal Property Security Act (RA 11057) is the operative hook today: §19 ranks possession/control of an instrument above registration when perfecting a security interest — and on-chain exclusive control is the electronic analogue of possession.

Sandbox scope, plainly: records today are signed and independently verifiable with no asserted legal effect. Production legal recognition follows issuer qualification and our regulatory engagement path — SEC, BSP, and NPC.

Deployment spectrum — fiat-first, chain-optional

Records are fiat-denominated (PHP by default), and because the settlement contract never custodies funds, actual payment has always run on a separate rail — which can be InstaPay, PESONet, a bank transfer, or a wallet, with the payment reference entered into the signed audit event. That makes two deployment modes real today, not roadmap:

ModeWhat runsEnforcementTrust model
Registry standaloneThis API only — issue, transfer, verify; fiat settlement on your existing rails; no crypto exposure, no wallet UX for your usersLifecycle refusals enforced as policy by the registryTamper-evident: signatures + hash-chain make alteration detectable; you trust ISET as operator
+ Chain anchoringThe same records, control additionally enforced by the Soroban contractRefusals enforced as structure — they hold even against the registry operatorTamper-proof exclusivity: no one, including ISET, can double-pledge a note

An institution can start registry-only — zero blockchain touch — and enable anchoring later without re-architecture, because the layers were never coupled. One honest caveat: in registry-only mode, the RA 11057 §19 control-as-possession argument is softer — control enforced by an operator's server is a weaker form of "possession" than contract-enforced control. We state that before counsel asks.

Integration paths

PathWhat it isStarts with
PilotOne corridor, one instrument, measured against agreed success criteria — free at design-partner stageA scoping conversation
APIServer-side keys under an issuer agreement — issue, transfer, and verify from your own systemsIssuer qualification (KYI)
White-labelYour brand on the records and certificates your customers see — branding is already live in the subscriber profileAn issuer agreement

Download the institutional brief → — a one-page summary built for internal circulation: what this is, proof of deployment, legal posture, pilot shape, and known limits.

Contact: trust@iset.finance

Errors

StatusBodyMeaning
401auth_requiredNo valid session — sign in at /console/
403Only the record owner…The session's account does not own this record
404No record for that reference.Reference not in the registry
409Cannot <action> a record in status…Invalid lifecycle transition
413payload_too_largeBody exceeds the limit
502upstream_unreachableThe engine could not be reached — retry