DEVELOPER PREVIEWSANDBOX / TESTNO PRODUCTION MONEY MOVEMENT

For developers

One authorization layer for every consequential agent action.

Your agent decides what it wants to do - spend, subscribe, disclose, delegate, hire. Quattrino decides whether it is authorized, on which authority, and up to what limit. Any provider executes. Quattrino records why it was allowed and what happened - even when Quattrino never moves the money. Why not build this yourself? Because narrowing algebra, commitment classes, conserved delegation, single-use binding and evidence are the hard part - and they must never be wrong.

AUTHORIZEDAPPROVAL_REQUIREDDENIEDNEEDS_INFORMATION

Quickstart · under 15 minutes · TEST/SANDBOX

Credential to first meaningful authorization.

Single-file SDKs with no dependencies (not yet on PyPI/npm), an MCP server, or plain REST. Nothing here moves real money.

  1. 1 · Sandbox account

    Create a sandbox account (open signup, no invite, no card). MFA optional.

    /signup

  2. 2 · Standing authority

    Give an agent a standing policy (e.g. $50 per action), sandbox funds and a scoped key - in the app or with bootstrap_sandbox.py.

    bootstrap_sandbox.py

  3. 3 · Authorize

    authorize(amount 19.99, task under $20) -> AUTHORIZED; 20.01 -> DENIED. Handle the four answers the same way, always.

    quickstart.py

  4. 4 · Act · prove

    Binding authorization -> you execute anywhere -> record the outcome -> explain in plain language.

    quickstart.ts

The first workflow

Six steps. One question: is this authorized?

You never need to understand payment rails to ask. Execution is optional and pluggable.

  1. 1

    Connect agent

    Pair an agent and issue it a scoped credential. It never sees a card, a login or a secret.

  2. 2

    Call authorize()

    State the action, the amount, the counterparty, the purpose and any structured task constraints.

  3. 3

    Receive a decision

    AUTHORIZED, APPROVAL_REQUIRED, DENIED or NEEDS_INFORMATION - with the effective maximum and why.

  4. 4

    Execute (optional)

    Use a Quattrino execution adapter when one exists, or execute with your own provider.

  5. 5

    Record outcome

    Tell Quattrino what actually happened. Deviations from the authorized terms are flagged.

  6. 6

    Explain

    Every authorization answers who, on whose behalf, why, what narrowed it and what happened.

Quattrino may infer meaning. It must never infer consequential permission.

Vague instruction in. Safe progress out. One precise question, only when it matters.

compile_intent turns what the human said into an amendable AuthorityEnvelope. Research proceeds immediately; hiring, paying, subscribing and sharing data wait for authority that exists - or for the latest safe question.

# Phase 30: vague human intent -> safe partial progress, no invented authority
c = q.compile_intent("Find someone who can fix the embossing machine.")
c["authorized_now"]        # ["research_and_compare", "contact_counterparties"]
c["not_yet_authorized"]    # ["hire_supplier_or_agent", "start_subscription_or_account", ...]
env = c["envelope"]["envelope_id"]

# research is always allowed - no question asked yet
q.authorize(envelope_id=env, action_class="NON_CONSEQUENTIAL_RESEARCH", purpose="find suppliers").decision  # AUTHORIZED

# the consequence point: a quote arrives. Quattrino asks ONE precise question, now.
r = q.authorize(envelope_id=env, action_type="hire_agent", merchant="Repair Co", amount_minor=32700,
                purpose="repair", commitment="CONTRACT")
r.decision              # NEEDS_INFORMATION (hiring authority + ceiling missing)
r.question["question"]  # "May the agent hire supplier or agent (with Repair Co for $327.00) for this task?"
r.missing_authority     # [{dimension: "purpose.allowed_action_classes", ...}, {dimension: "money...", ...}]

# a $9.99/month offer can never pass as a $20 one-time purchase
q.authorize(envelope_id=env_one_time, merchant="SaaSCo", amount_minor=999, purpose="software",
            commitment="SUBSCRIPTION").decision   # DENIED (commitment_prohibited)
Purpose
objective, category, allowed action classes
Money
per-action + aggregate ceilings, conditional ceilings ("$1,200 only if RAM >= 32 GB")
Commitment
ONE_TIME vs SUBSCRIPTION vs CONTRACT ... never assumed
Data
per-field posture: RELEASE_ONCE / REDACTED / ASK_OWNER / DENY, purpose-bound
Delegation
allowed, budget, depth - conserved: children never add up to more than the parent
Counterparty & time
merchants, categories, attribute rules, deadlines, expiry

Every envelope version is immutable with provenance. Agents may only narrow; owners widen - bounded by the standing policy. Outcomes are checked for amount, counterparty, commitment class, data disclosed, delegation and time.

result = quattrino.authorize({...})

Standing $50. Task says under $20. Effective: $20.

A task instruction may narrow standing authority but can never expand it. Ambiguity returns NEEDS_INFORMATION, never more authority.

from quattrino import Quattrino

q = Quattrino(api_key="qtrn_sk_...")           # the agent's scoped credential

result = q.authorize(
    amount_minor=1899, merchant="Amazon", purpose="USB-C cable for the office",
    task={"max_amount_minor": 2000, "categories": ["electronics"],
          "prohibited_side_effects": ["subscription"]},
)
result.decision                 # AUTHORIZED
result.effective_maximum_minor  # 2000  <- standing $50 narrowed to $20 by the task

auth = q.authorize_binding(amount_minor=1899, merchant="Amazon", purpose="USB-C cable")
if auth.decision == "AUTHORIZED":
    if auth.execution_package["execution_mode"] == "quattrino":
        q.execute(auth)                                   # certified adapter
    else:
        # you execute with your own provider, then attest
        q.record_outcome(auth.authorization_id, success=True,
                         provider="amazon", provider_reference="114-2233",
                         actual_amount_minor=1899)
print(q.explain(auth.authorization_id)["plain_language"])

SDKs are thin wrappers over the REST contract and embed no policy logic. Source: /sdk/python, /sdk/typescript (not yet published).

Decisions

Four answers. Always deterministic. Always explainable.

AUTHORIZED

Within the effective authority. In binding mode a portable EconomicAuthorization is issued: it expires, can be revoked and is consumed exactly once.

APPROVAL_REQUIRED

A human must approve: above the autonomous maximum, a policy rule, a delegated requirement or an owner-gated disclosure. The owner decides in Approvals.

DENIED

Outside the effective authority, blocked by policy, or the task constraints are violated. Nothing is issued.

NEEDS_INFORMATION

Ambiguous or missing terms (amount, merchant, purpose, unknown constraint). Ambiguity never expands authority.

One canonical pipeline

INTENTNORMALIZEIDENTITYDELEGATIONAUTHORITY INTERSECTIONPOLICYRISKDISCLOSUREAPPROVALAUTHORIZATIONEXECUTION PLANEXECUTE OR ATTESTOUTCOMEEVIDENCE

Advanced

Execution adapters (optional)

Capabilities underneath the control plane. You only meet them if you ask Quattrino to execute.

Developer preview · sandbox only. Live payments, mainnet and MPP production are OFF platform-wide. Authorization usage is metered in neutral Authorization Units; authorization pricing is not activated.