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.