The default Dino pattern for AI-driven spend is:
agent runtime -> customer-owned constrained tool/server -> Dino POST /v1/spend (+ read APIs)
This is not just a demo trick. It is the recommended product architecture.
#Core rule
The model is the planner / requester. Dino is the execution, policy, and audit system of record.
That means:
- The model proposes a spend.
- A narrow tool forwards the request with Dino credentials injected server-side.
- Dino evaluates policy, approvals, budgets, and ledger effects.
- Operators retain pause, revoke, and approval control in Dino.
#Why this is the default
Dino is designed around governed agent spend, not around pasting payment credentials into a chat window.
This architecture gives you:
- policy enforcement at the Dino account level
- a complete ledger-backed audit trail
- approval routing for higher-risk requests
- revocation and pause controls that still work under automation
- a stable secret boundary outside model context
#What not to do
Do not use these as the happy path:
- pasting card details into ChatGPT, Claude, or any general-purpose LLM
- pasting a raw Dino spend key into prompts, custom instructions, or shared transcripts
- relying on "skills" or prompt text alone to protect secrets
- treating the model as an unconstrained payment actor
#Recommended tool shape
Start with a minimal surface:
create_spend(amount_cents, currency, merchant_name, reason, idempotency_key?)get_balance()get_spend(id)
The tool runner or wrapper should inject:
Authorization: Bearer din_...
and a stable:
Idempotency-Key: ...
#Retries and idempotency
Generate the idempotency key once per logical spend intent and reuse it for retries of that same request.
Do not create a fresh random key for each retry attempt. If the first request succeeded and only the response was lost, a brand-new key can create a duplicate spend.
#Ownership split
#Dino owns
REST /v1spend and read APIs- policy evaluation
- budgets and thresholds
- approvals
- ledger and audit trail
- key revocation
#Your integration owns
- the hosted tool boundary the model calls
- secret storage for Dino keys
- correlation IDs and request logging
- retry behavior and idempotency reuse
- optional extra guardrails for your workflow
#Client choice is secondary
OpenClaw, ChatGPT, Claude, Cursor, and MCP clients are all valid conversation shells. The trust boundary should remain the same:
assistant shell -> constrained tool -> Dino API
If you later add browser automation or merchant-specific checkout helpers, keep them behind the same governed execution layer rather than letting the model operate on raw credentials.
#Handling needs_approval
When a spend request returns needs_approval, the agent must wait for a human decision before proceeding.
Preferred path — webhooks: register an endpoint in the Dino dashboard under Developer → Webhooks. Dino pushes a spend_request.approved or spend_request.declined event signed with your endpoint's secret. The reference wrapper includes a minimal verified receiver in src/receiver-example.ts. See Agent Spend Webhooks for setup and signature verification.
Fallback path — polling: call GET /v1/spend/:id (or the wrapper's GET /tools/get_spend/:id) every 30–60 seconds until the status is terminal. Polling is the right choice before you have a webhook endpoint configured or when recovering from a missed delivery.
#Build order
- Thin wrapper or route that calls Dino
- OpenAPI description for Actions-style clients
- Register a webhook endpoint so approvals push rather than poll
- MCP adapter if you want broader agent distribution
For a concrete starting point, see the reference wrapper in packages/agent-spend-wrapper-example. It implements the narrow create_spend, get_balance, and get_spend tool surface, an Actions-compatible OpenAPI file, and a webhook receiver example.
#Demo versus production
Use the same architecture for both.
- Production uses the real wrapper and operator controls.
- Demo uses sandbox or seeded balance and tighter caps.
/playgroundis a storytelling UI, not proof of integration.