Skip to content

Review payments

Release the clearly safe payments and send the rest to a person.

Most payments are routine: the same rent, to the same landlord, from the same phone. A few are not, such as a large transfer to a new payee minutes after a password reset. This guide asks Sage2 one strict question about each payment and releases only the ones it is confident about.

Everything else goes to a person, before the money moves.

  • Yes/No
Try
  1. Check the payment is clearly the owner's ownYes/No

    Answer: no

    Chance of yes 0.01%

    3 ms
  2. Your codeSent to a person

    Sage2 does not find it clearly the owner's own: the chance of yes is 0.01%. A person checks the payment before the money moves.

One request: 3 ms. Your code releases a payment only at 98% or more.

Get the code

Set SAGE_API_KEY (get a free key), then run it. Python: pip install requests. TypeScript: Node 22+. Save as recipe.mts and run npx tsx recipe.mts.

A null answer is not an error. Sage2 isn't sure, and each step below says what to do with it. Limits, errors and retries: Limits and errors.

import os
import requests

def sage(path, body):
    r = requests.post(
        "https://sage.levanto.ai" + path,
        headers={"Authorization": f"Bearer {os.environ['SAGE_API_KEY']}"},
        json=body,
        timeout=30,
    )
    r.raise_for_status()
    return r.json()

payment = """Customer since 2022. Average payment 80 EUR.
Password reset 12 minutes ago. New device in another country.
Payment: 9,400 EUR to a payee added 4 minutes ago."""

result = sage("/decide", {
    "content": payment,
    "question": {
        "id": "safe_to_release",
        "kind": "yesno",
        "instructions": "Is this payment clearly the account owner's own, and safe to release without a person checking it?",
    },
})["result"]

BAR = 0.98  # release only when Sage is at least this sure

if result["answer"] == "yes" and result["probability"] >= BAR:
    print("Release")
else:
    # "no", null (not sure), or a "yes" below the bar: a person checks it
    print("Review queue:", result)

How it works

  1. Yes/No

    Ask if it's safe to release

    Yes/No docs

    Send what a reviewer would look at as content: the account's history, the device and location, recent account changes, and the payment itself.

    The question is phrased so that only a clear case is a yes: "clearly the account owner's own, and safe to release without a person checking it". An unusual payment gets a no.

    The result has answer (yes, no or null) and probability, the chance the answer is yes.

    Runs with the helper from Get the code.

    payment = """Customer since 2022. Average payment 80 EUR.
    Password reset 12 minutes ago. New device in another country.
    Payment: 9,400 EUR to a payee added 4 minutes ago."""
    
    result = sage("/decide", {
        "content": payment,
        "question": {
            "id": "safe_to_release",
            "kind": "yesno",
            "instructions": "Is this payment clearly the account owner's own, and safe to release without a person checking it?",
        },
    })["result"]
    Example Sage2 output
    {
      "id": "safe_to_release",
      "kind": "yesno",
      "result": {
        "answer": "no",
        "probability": 0.0001
      },
      "meta": {
        "model": "levanto-sage-2",
        "latency_ms": 3.2,
        "question_count": 1,
        "usage": {
          "billed_input_tokens": 108,
          "image_count": 0,
          "image_tokens": 0,
          "input_tokens": 108,
          "output_tokens": 0
        }
      }
    }
  2. Your code

    Release only above your bar

    Release a payment only when the answer is yes and probability is at or above a bar you choose. Everything else goes to the review queue:

    • a no,
    • a null, when Sage2 isn't sure,
    • a yes below your bar.

    The payment in this recipe, from a new device to a new payee, goes to the queue. The monthly rent sample comes back yes at about 99%, so it is released.

    A higher bar sends more payments to a person.

    Runs with the helper from Get the code.

    BAR = 0.98  # release only when Sage is at least this sure
    
    if result["answer"] == "yes" and result["probability"] >= BAR:
        print("Release")
    else:
        # "no", null (not sure), or a "yes" below the bar: a person checks it
        print("Review queue:", result)

Before you ship

  1. Start strict. Begin with a high bar. Lower it only after you check what the review queue catches.
  2. Send the context. Sage2 only knows what is in content. Include account age, usual amounts, device and recent changes.
  3. Fail closed. If the Sage2 call errors or times out, hold the payment for review.
  4. Keep fixed rules in code. Hard limits and blocklists stay deterministic. Sage2 handles the cases between them.
  5. Fast and small. One check reads about 110 tokens and answers in about 130 ms.

Sage / Levanto

Start free.

Sign in or create an account.

Continue with Google
or with email

We’ll email you a 6-digit code.