Plans
Sign a plan's risk assessment
POST /api/commit-plan returns the risk assessment Vera signs for a plan, for on-chain recording.
POST /api/commit-plan builds the RiskInference for a draft plan and returns it signed by Vera’s agent key. This signature is the accountability record: Vera signs the risk assessment, and the client records it on-chain in the same transaction that buys the assets. The user separately signs the spend.
POST /api/commit-plan· requires a Privy bearer token. Base URL, rate limits, and error shapes: conventions.
This route signs and returns — it does not broadcast and does not return a transaction hash. The client calls VeraRecord.record(planId, recHash, assessedRisk, maxRisk, expiry, signature, user, agentId, usdSpent, legCount) and batches that with the venue settlement calls into one gas-sponsored ERC-4337 userOp, relayed via POST /api/pimlico. Because the record and the buys share one atomic transaction, the assessment cannot be edited after the fact.
Parameters
Section titled “Parameters”JSON body.
| Name | Type | Required | Description |
|---|---|---|---|
address |
string (address) | yes | The smart account that will own the holdings and submit the invest transaction. |
allocation |
object | yes | The draft plan to sign, in the exact shape returned by POST /api/allocate: { summary, rationale, riskScore, allocations[] }. |
amountUsd |
number, >0 and ≤1000000 | yes | The dollar amount being invested. |
Returns
Section titled “Returns”| Field | Type | Description |
|---|---|---|
planId |
string (bytes32) | keccak256 of the allocation plus the request timestamp. Single-use — the on-chain record rejects a replayed planId. |
recHash |
string (bytes32) | keccak256 of the canonical allocation JSON, the recommendation commitment recorded on-chain. |
assessedRisk |
integer, 0–10000 | Vera’s assessed portfolio risk in basis points, clamped from allocation.riskScore. |
maxRisk |
integer, 0–10000 | The risk ceiling, assessedRisk + 1500, capped at 10000. On-chain verify reverts if assessedRisk exceeds it. |
expiry |
string (uint256 seconds) | Unix expiry, 15 minutes from signing. On-chain verify reverts past it. |
signature |
string (65-byte hex) | Vera’s EIP-712 signature over the RiskInference, recoverable to agentSigner(). |
agentId |
string | Vera’s agent id in Monvera’s IdentityRegistry, "1". |
The signed type is RiskInference(bytes32 planId, uint16 assessedRisk, uint16 maxRisk, uint256 expiry) over the EIP-712 domain { name: "VeraRecord", version: "1", chainId: 4663, verifyingContract: 0x7ff1a5ee19330c165146488a7ad8af6cb41da1df }. Verify any signature yourself: verify Vera.
Request
Section titled “Request”curl -X POST https://monvera.best/api/commit-plan \ -H "Authorization: Bearer $MONVERA_TOKEN" \ -H "Content-Type: application/json" \ -d '{ "address": "0x4D2b1c3A5e6F7089aB0cD1e2F3a4B5c6D7e8F901", "amountUsd": 100, "allocation": { "summary": "Steady Growth", "rationale": "A balanced five-year mix of broad market exposure, short Treasuries, and two large tech names.", "riskScore": 4200, "allocations": [ { "symbol": "SPY", "weightPct": 40, "reason": "Broad US market in one holding." }, { "symbol": "SGOV", "weightPct": 30, "reason": "Short US Treasuries, the low-volatility anchor." }, { "symbol": "AAPL", "weightPct": 15, "reason": "Profitable, cash-rich, steady demand." }, { "symbol": "NVDA", "weightPct": 15, "reason": "Strong trend, sized small because it swings hard." } ] } }'Example response
Section titled “Example response”{ "planId": "0x8f2a1c9b7d3e4f5a6b8c0d1e2f3a4b5c6d7e8f90a1b2c3d4e5f60718293a4b5c6", "recHash": "0x3c4d5e6f708192a3b4c5d6e7f8091a2b3c4d5e6f708192a3b4c5d6e7f8091a2b", "assessedRisk": 4200, "maxRisk": 5700, "expiry": "1751991300", "signature": "0x2b3c4d5e6f708192a3b4c5d6e7f8091a2b3c4d5e6f708192a3b4c5d6e7f8091a2b3c4d5e6f708192a3b4c5d6e7f8091a2b3c4d5e6f708192a3b4c5d6e7f8091a2b1b", "agentId": "1"}Errors
Section titled “Errors”| Status | Body | When |
|---|---|---|
400 |
{"error":"Invalid request body."} |
Schema validation failed: bad address, malformed allocation, non-positive amount or amount above 1000000. |
The signature is time-boxed
Section titled “The signature is time-boxed”Sign here but fail to submit the invest within the 15-minute expiry and the on-chain verify reverts with InferenceExpired() — no assets are bought. Fetch a fresh signature and settle promptly. The other on-chain reverts are RiskCeilingBreached(assessed, maxRisk), BadSigner(recovered), and PlanAlreadyRecorded(planId), documented on verify Vera.
© 2026 Aibora · Documentation interface. Original Monvera materials retain their upstream attribution andMIT license.