Skip to main content
[AVAILABLE], every example below is real output from this session, commit 651497a. No authentication middleware exists on any route.

System

GET /

packages/api/src/app.ts, defined inline, not in a separate routes/ file, unlike every other route on this page. Easy to miss when enumerating routes by scanning routes/.
{"name":"Parmana","status":"UP"}

GET /health

packages/api/src/routes/health.ts
{"status":"UP"}

GET /version

packages/api/src/routes/version.ts
{"name":"Parmana","version":"0.4.0","api":"v1"}

Execution

POST /execute

packages/api/src/routes/execute.ts. Validates businessTransactionId is a UUID, maps the body via BusinessTransactionMapper.fromRequest (forces status: RECEIVED, createdAt: now, regardless of what the client sends), then executes through The gateway. Returns the full Execution trust record. Request: a BusinessTransaction (see Execution trust records for the shape). Response (200): the resulting ExecutionTrustRecord.
StatusConditionReal example, this session
400businessTransactionId is missing or not a UUID{"error":"businessTransactionId must be a valid UUID."}
409A record with this businessTransactionId already exists (DuplicateBusinessTransactionError){"error":"Business Transaction 'a1a1a1a1-1111-4111-8111-111111111111' already exists."}
500Policy evaluated to REJECTED (a RuntimeError, not a distinct status){"error":"Execution rejected: Vendor payment rejected because the vendor has not been verified.","code":"RUNTIME_ERROR"}
500No connector registered for the request’s action{"error":"No connector registered for action: <action>.","code":"RUNTIME_ERROR"} (see The gateway)
Verified, not inferred: a structurally incomplete body (a valid UUID but missing required nested objects like metadata) does not produce the 400 BusinessTransactionValidationError the error-handler is written to catch. It crashes with an unstructured 500:
{"error":"Internal Server Error"}
The real cause, from the server’s own log: BusinessTransactionValidator.validate throws a raw TypeError: Cannot read properties of undefined (reading 'businessTransactionId') (packages/runtime/src/validators/BusinessTransactionValidator.ts:14), which is not an instance of BusinessTransactionValidationError, so error-handler.ts’s instanceof check never matches and it falls through to the generic 500. This is a real gap between the error-handler’s apparent design and what a caller actually sees for this specific input shape, reported here, not fixed, see the phase report accompanying this page’s introduction for tracking.

GET/POST /transactions

packages/api/src/routes/transactions.ts.
  • GET /transactions?page=1&pageSize=25: list. Response (200): BusinessTransaction[].
  • GET /transactions/:id: one Business Transaction. Response (200): BusinessTransaction. 404 if not found: {"error":"Business Transaction not found."}.
  • POST /transactions: also executes, duplicating POST /execute, but with weaker validation, no UUID-format distinction beyond the same regex check, and the body is spread directly rather than passed through the same mapper path (transactions.ts:91-101). Response (201): ExecutionTrustRecord. 400 on invalid UUID, verified identical message to /execute’s 400: {"error":"businessTransactionId must be a valid UUID."}. This duplication is flagged as a core-API finding, not fixed here, see Roadmap.

Verification

POST /verify

packages/api/src/routes/verify.ts. Fresh verification, appends a new Verification to the record’s history, see Verify a trust record independently. Request: {"businessTransactionId": "<uuid>"}. Response (200), real example:
{
  "verificationId": "dcf429c9-91c5-4ef1-9b8d-5259ff10aad1",
  "businessTransactionId": "a1a1a1a1-1111-4111-8111-111111111111",
  "status": "VERIFIED",
  "message": "Execution Trust Record verified successfully.",
  "verifiedAt": "2026-07-12T08:38:34.934Z",
  "trustRecordHash": "52da1a19a3cdb868f6ff0eb1ee8a1e7877301a767b65926b165afb88bff1601e"
}
StatusConditionReal example
400businessTransactionId missing{"error":"businessTransactionId is required."}
400businessTransactionId not a UUID{"error":"businessTransactionId must be a valid UUID."}
404Valid UUID, no matching record{"error":"Execution Trust Record not found.","code":"VERIFICATION_FAILED"}

GET /verification/:id

packages/api/src/routes/verify-get.ts, mounted at /verification. Reads the latest verification without re-running one, distinct route from POST /verify above. Response (200): the same Verification shape as POST /verify.
StatusConditionReal example
404Record not found{"error":"Execution Trust Record not found."}
404Record found, but verifications is empty{"error":"Verification not found."}

Receipts

POST /receipt

packages/api/src/routes/receipt.ts. Same request pattern as /verify. Request: {"businessTransactionId": "<uuid>"}. Response (200), real example:
{
  "receiptId": "218ec153-5bc4-4b13-aa51-58fea5829acd",
  "businessTransactionId": "a1a1a1a1-1111-4111-8111-111111111111",
  "trustRecordHash": "52da1a19a3cdb868f6ff0eb1ee8a1e7877301a767b65926b165afb88bff1601e",
  "receiptHash": "38c75aec10023d012f9c435acc2e5b0e89009da90da1ff484fcb327e15ed51f8",
  "issuedAt": "2026-07-12T08:38:43.623Z",
  "algorithm": "ed25519",
  "signature": "6Jo++W3JpFpcbG3lKKHRLraVRVQenftCTusJxB+x2LYP8zW3P5Evbw+kFXeSmyREUxfxbxEN5PsNpq3sF+a6Bg=="
}
StatusCondition
400businessTransactionId missing or not a UUID, same messages as /verify

GET /receipt/latest/:id

packages/api/src/routes/receipt-get.ts, mounted at /receipt/latest. Reads the latest receipt without generating a new one. Response (200): the same Receipt shape as POST /receipt.
StatusConditionReal example
404Record not found{"error":"Execution Trust Record not found."}
404Record found, receipts empty{"error":"Receipt not found."}

Replay

POST /replay

packages/api/src/routes/replay.ts. Re-verifies the trust record’s signature, it does not reconstruct or re-execute anything. See Replay for why this name is narrower than it sounds. Request: {"businessTransactionId": "<uuid>"}. Response (200), real example:
{
  "businessTransactionId": "a1a1a1a1-1111-4111-8111-111111111111",
  "trustRecordHash": "52da1a19a3cdb868f6ff0eb1ee8a1e7877301a767b65926b165afb88bff1601e",
  "verified": true
}
StatusConditionReal example
400businessTransactionId missing{"error":"businessTransactionId is required."}
404Valid UUID, no matching record{"error":"Execution Trust Record not found.","code":"VERIFICATION_FAILED"}
Note this route does not validate UUID format the way /verify does, only presence, an invalid non-UUID string reaches the same “not found” path as a well-formed but unknown UUID.

Trust Records

GET /trust-records/:id

packages/api/src/routes/trust-records.ts. Returns the full Execution trust record.
StatusConditionReal example
404Not found{"error":"Execution Trust Record not found."}

Policies

POST /policies/validate

packages/api/src/routes/policies.ts. Does not validate a policy document. It checks only that a policy with the given policyId + policyVersion is loadable from disk, policyRepository.load(policyId, policyVersion). This naming/semantics gap is flagged in Roadmap, not fixed at the route level. Request: {"policyId": "...", "policyVersion": "..."}.
StatusConditionReal example
200Policy loadable{"valid":true,"errors":[]}
400policyId missing/empty{"valid":false,"errors":["policyId is required."]}
400policyVersion missing/empty{"valid":false,"errors":["policyVersion is required."]}
404Policy/version not found on disk{"valid":false,"errors":["Policy 'nonexistent-policy' version '9.9.9' was not found."]}

Full route list

MethodPathSource
GET/app.ts (inline)
GET/healthroutes/health.ts
GET/versionroutes/version.ts
POST/executeroutes/execute.ts
POST/verifyroutes/verify.ts
GET/verification/:idroutes/verify-get.ts
POST/receiptroutes/receipt.ts
GET/receipt/latest/:idroutes/receipt-get.ts
GET/transactionsroutes/transactions.ts
GET/transactions/:idroutes/transactions.ts
POST/transactionsroutes/transactions.ts
POST/policies/validateroutes/policies.ts
GET/trust-records/:idroutes/trust-records.ts
POST/replayroutes/replay.ts
No other routes exist in packages/api/src/app.ts.