GuidesEvaluate a transfer

Evaluate a transfer

Check a transfer with POST /evaluate before creating an operation: get allow/queue/block, the reason, and the matched policies without changing anything.

Before creating a transfer, you can ask the Policy Engine "will this go through?" without creating anything or reserving funds. evaluate returns the same allow / queue / block verdict, along with the reason and the list of matched policies. It's useful for preflight checks in UIs and automation. For the engine itself, see Policy Engine.

How evaluate reaches a verdict (the same calculation as when creating a transfer, but with no side effects):

Prerequisites

  • A Vault (vaultId) and the user (userId) on whose behalf the action is checked.
  • An access token (see Authentication).
  • The parameters of the intended action: asset, amount, toAddress.

Step 1. Send an evaluation request

POST /api/v1/evaluate is a top-level endpoint (not under /vaults/{code}). It doesn't create anything; it only calculates the verdict.

curl -X POST "[BASE_URL]/api/v1/evaluate" \
  -H "Authorization: Bearer $V3_TOKEN" \
  -H "Content-Type: application/json" \
  -d '{
    "action": "transfer",
    "vaultId": "VAULT_ID",
    "userId": "USER_ID",
    "asset": "usdt",
    "amount": "1350.00",
    "toAddress": "TQ2m...p4rX"
  }'

asset is required; tokenCode is optional. The other body fields are for illustration only. Check the exact schema on the evaluate page in the API Reference. vaultId is the Vault's id, not its code.

Step 2. Read the decision

The response contains the verdict and an explanation:

{
  "decision": "block",
  "reason": "AMOUNT_EXCEEDED",
  "policyId": "...",
  "policyCode": "otc-daily-limit",
  "trace": [
    { "policyCode": "otc-daily-limit", "policyName": "OTC daily limit", "effect": "block" }
  ]
}
FieldMeaning
decisionthe outcome: allow, queue, or block
reasona machine-readable reason (for example, AMOUNT_EXCEEDED)
policyCodethe code of the policy that determined the outcome
tracethe list of matched policies with their effect

How to use the verdict:

VerdictWhat to do in the UI or automation
allowyou can create the transfer right away
queueyou can create it, but it will go to awaiting_approval; warn the user upfront
blockshow the reason and don't allow sending

Step 3. How the engine makes a decision

evaluate follows the deny-overrides principle:

  1. All of the user's policies in the Vault are collected (through group memberships).
  2. Only enabled policies whose action type matches the requested one are kept.
  3. Applicability is checked (a condition tree; an empty tree means "always applies").
  4. If at least one policy blocks, the outcome is block.

The same calculation runs when a transfer is created, but there it comes with side effects (a reserve, an approval request). evaluate, on the other hand, is safe to call repeatedly. For details, see Policy Engine.

Common mistakes

SymptomCause
always allow when you expected a blockthe context (amount / asset) wasn't passed, so the policy didn't apply
asset not recognizedtokenCode was passed instead of the required asset
verdict differs from the actual transfer creationthe request parameters differ; compare the body with the actual transfer call
401 / 403 on the endpoint itselfa token or access problem, not a policy one; see Authentication
vaultId not foundthe Vault's code was passed instead of its id

You're done when

  • POST /api/v1/evaluate returns a decision without creating anything;
  • when a limit is expected, you get block with a clear reason;
  • trace contains the matched policies;
  • a repeated call with the same parameters returns the same verdict (no side effects).

Next steps