front-1, signed.
At a glance
- Get it:
GET /v1/agents/{agent_id}/operations/{correlation_id}/proof, orapi.getOperationProof()in the SDK, for anyop_…execution. - Check it: fetch a fresh head from the witness with the pinned witness key, request the proof from that head’s size, and pass the head to
verifyOperationProof(proof, origin, trusted). The check itself runs offline. - Then, yourself: look up the settlement transactions on-chain, and verify the notary’s TDX quote as on TEE & Attestation.
front-1, a separate host outside the VM, which keeps the log’s newest head and accepts only consistent extensions of it. The proof endpoint returns the retained events for one execution, with proofs anyone can check.
Pin the witness key
The witness signs the head it serves with an Ed25519 key. Pin this key in your own code or configuration. Never read it from an API response, because the API only relays the witness’s answer.
The same key is
WITNESS_PUBLIC_KEY in the compose that the attestation covers, so you can confirm it against app_compose from /tee/info.
Get and verify a proof
The call needs your partner API key.correlation_id is the op_… id of an execution of that agent. Owner intents (intent_…) have no operation proof.
Verification needs a trusted checkpoint that does not come from the proof. The flow is:
- Fetch the witness head.
fetchWitnessCheckpointsends a fresh nonce to/tee/witnessand checksfront-1’s signature with the key you pinned. - Request the proof with
from_sizeset to that head’s size, so the response carries a consistency proof from your head. - Pass the head to
verifyOperationProof.
verifyOperationProof needs no network. It throws NoteError or ProofError when the proof is for another log, a signature is wrong, the checkpoint does not extend your trusted one, an event isn’t this execution’s, or a recorded result was changed after it was committed. Without a trusted checkpoint it refuses to verify at all. If the server’s log is behind the size you sent, the endpoint answers 409 transparency_checkpoint_behind. Fetch the head again and retry. The verify-operations example is a complete script.
Response
Each event has an
action, a created_at time, a status, a proof and its evidence:
evidence is the result the event recorded, as canonical JSON, or null when it recorded none. For an execution, it includes the settlement transaction hashes.
notary holds log_key and notary_key (the verifier keys), signing_address, and birth: the TDX attestation quote, its report_data, and previous, the checkpoint the notary continued from after a restart, or null on its first boot.
The log’s public tiles and latest checkpoint are served at https://log.agentsonintents.com/.
What a proof lets you check
APROVEN event’s proof carries the event’s opening (the committed content, in the extra line), its leaf index, the inclusion path and the signed checkpoint. verifyOperationProof checks that:
- The notary keys belong to the origin you pinned and match the birth attestation’s
report_data. - The checkpoint is signed by the log key and cosigned by the notary key.
- The checkpoint extends the trusted checkpoint you passed in. A smaller tree, a fork of the same size or a missing consistency path is refused.
- The opening hashes to a leaf the checkpoint includes, and names this execution, its action and its time.
- The
evidencehashes to the opening’sevidenceHash, so a result changed after it was committed is refused.
- Check the settlement on-chain. Look up each NEAR transaction the evidence names:
tx_hash,transaction_hashandsettlement_tx_hash, anddestination_tx_hashonly when the withdrawal’schainisnear. Each should be final and successful. Confidential routes other than withdrawals, and same-chain withdrawals that settle by intent hash alone, name no public transaction, so there is nothing to look up for them. - Check the attestation. Verify the TDX quote in
notary.birthwith a quote verifier, such as dstack-verifier, run by you or by a service you trust. TEE & Attestation shows how. Itsreport_datamust equalverified.birthReportData. That ties the keys to the attested code.
Receipts
A completed transfer, withdrawal, swap, limit order or deposit also has a receipt: a separate log leaf that commits only to the settled terms. It names no agent or account, so you can hand it to a payee, who verifies it against the same witnessed log without an API key.Retention and errors
The API keeps audit events for 90 days. Their commitments stay in the log, so the tree stays valid, but an expired event no longer appears in proofs.
See Status & Errors for every code.