Skip to main content

Internal Endpoints

These endpoints are called by the CRE workflows and are authenticated via the x-api-key header. They are not intended for direct user access.

All internal endpoints are mounted under /api/v1/internal/.

GET /internal/pending-intents​

Fetch all active lend intents and pending borrow intents for the current matching epoch.

Response​

{
"lendIntents": [
{
"intentId": "intent_001",
"userId": "0xAlice...",
"token": "0xgUSD...",
"amount": "10000000000",
"encryptedRate": "04a1b2c3...",
"epochId": "epoch_42"
}
],
"borrowIntents": [
{
"intentId": "borrow_001",
"borrower": "0xBob...",
"token": "0xgUSD...",
"amount": "8000000000",
"encryptedMaxRate": "04d5e6f7...",
"collateralToken": "0xgETH...",
"collateralAmount": "5000000000",
"status": "pending"
}
]
}

Behavior​

Returns lend intents that are not currently locked in pending proposals. This prevents double matching of the same liquidity across epochs.

POST /internal/record-match-proposals​

Submit match proposals generated by the CRE matching engine.

Request Body​

{
"proposals": [
{
"borrowIntentId": "borrow_001",
"borrower": "0xBob...",
"token": "0xgUSD...",
"principal": "8000000000",
"matchedTicks": [
{ "lender": "0xAlice...", "lendIntentId": "intent_001", "amount": "5000000000", "rate": 0.035 },
{ "lender": "0xCarol...", "lendIntentId": "intent_002", "amount": "3000000000", "rate": 0.04 }
],
"effectiveBorrowerRate": 0.0369,
"collateralToken": "0xgETH...",
"collateralAmount": "5000000000"
}
]
}

Behavior​

  1. Creates MatchProposal records with status pending
  2. Sets expiration time (5 seconds in current implementation)
  3. Updates associated borrow intents to status proposed
  4. Locks the lend intents referenced in matched ticks

POST /internal/expire-proposals​

Auto accept proposals that have passed their expiration window.

Behavior​

  1. Finds all proposals where expiresAt < now and status === "pending"
  2. For each expired proposal, performs the same logic as acceptProposal: a. Creates an active loan b. Consumes matched lend ticks c. Queues principal disbursement transfer
  3. Marks the proposal as accepted

This ensures proposals are never left in limbo. The CRE calls this endpoint at the beginning of each matching epoch before fetching new intents.

GET /internal/check-loans​

Return all active loans for the CRE to perform health checks.

Response​

{
"loans": [
{
"loanId": "loan_001",
"borrower": "0xBob...",
"token": "0xgUSD...",
"principal": "8000000000",
"collateralToken": "0xgETH...",
"collateralAmount": "5000000000",
"requiredCollateral": "4500000000",
"maturity": "2026-04-09T00:00:00Z",
"matchedTicks": [...]
}
]
}

GET /internal/pending-transfers​

Fetch transfers queued by the server that need to be executed via the vault.

Response​

{
"transfers": [
{
"id": "tx_001",
"recipient": "0xAlice...",
"token": "0xgUSD...",
"amount": "5000000000",
"reason": "disburse",
"createdAt": "2026-03-09T12:00:00Z",
"status": "pending"
}
]
}

POST /internal/confirm-transfers​

Mark transfers as completed after the CRE has executed them through the vault.

Request Body​

{
"transferIds": ["tx_001", "tx_002"]
}

Behavior​

Updates the status of each transfer from pending to completed. This prevents the CRE from re executing the same transfer on subsequent polling cycles.

POST /internal/liquidate-loans​

Trigger liquidation for undercollateralized or expired loans.

Request Body​

{
"loanIds": ["loan_001", "loan_003"]
}

Behavior​

For each loan ID:

  1. Marks the loan as defaulted
  2. Downgrades the borrower's credit tier by one level
  3. Calculates the 5% protocol fee from collateral
  4. Distributes 95% of collateral pro rata to lenders based on tick amounts
  5. Queues transfer of protocol fee (reason: liquidate)
  6. Queues individual transfers to each lender (reason: liquidate)

Response​

{
"liquidated": 2,
"transfersQueued": 5
}

Authentication​

All internal endpoints require the x-api-key header:

x-api-key: <value of INTERNAL_API_KEY env var>

Requests without a valid key receive a 401 Unauthorized response.