Typed REST, idempotent by default. Signed and replayable webhooks. SDKs for the languages you actually ship in. And every endpoint exposed through a first-class Model Context Protocol server.
Sign in, generate sandbox keys, hit the API. Real flows, fake money. Flip one flag when you're ready for production.
Sandbox keys are issued instantly on signup.
npm i hashdt · pip install hashdt · go get …
Issue a card, send a payout, swap FX.
One environment flag to switch to production.
// node — issue a USDC-backed virtual card import { HashDT } from "hashdt"; const client = new HashDT({ apiKey: process.env.HASHDT_KEY }); const card = await client.cards.create({ customer_id: "cus_8X4Tq", type: "virtual", currency: "USDC", controls: { max_amount_per_day: 2500 } }); console.log(card.id, card.last4); // crd_4Hf2 9134
# python — USDC → NGN via M-PESA import hashdt, os client = hashdt.Client(api_key=os.environ["HASHDT_KEY"]) payout = client.payouts.create( source_currency="USDC", destination_currency="NGN", rail="mpesa", amount=2_400_000, beneficiary={ "name": "Adunni Co.", "phone": "+234801234567", }, idempotency_key="po_2026_q1_0048", ) print(payout.status) # "settled" in ~6s
// go — lock a quote, settle async package main import ( "context" "github.com/hashdt/hashdt-go" ) func main() { c := hashdt.New("sk_live_...") q, _ := c.FX.Quote(ctx(), &hashdt.QuoteReq{ From: "USDC", To: "EUR", Amount: 100_000, }) c.FX.Execute(ctx(), q.ID) }
// node — verify and handle a signed webhook app.post("/webhooks/hashdt", (req, res) => { const ok = client.webhooks.verify({ payload: req.rawBody, signature: req.headers["x-hashdt-signature"], secret: process.env.WH_SECRET, }); if (!ok) return res.status(400).end(); const evt = JSON.parse(req.rawBody); if (evt.type === "payout.settled") { // fulfill } res.status(200).end(); });
Every resource is REST-shaped, idempotent, paginated by cursor, and returns typed errors with a stable code. Webhooks mirror every state transition.
POST /v1/cards · GET /v1/cards · PATCH /v1/cards/:id · POST /v1/cards/:id/freeze
POST /v1/accounts · GET /v1/accounts/:id/balances · POST /v1/accounts/:id/sub-accounts
POST /v1/fx/quotes · POST /v1/fx/executions · GET /v1/fx/pairs
POST /v1/payouts · GET /v1/payouts/:id · POST /v1/payouts/bulk
POST /v1/customers · POST /v1/customers/:id/kyc · GET /v1/customers/:id
POST /v1/webhooks · 47 event types · HMAC-signed · 7-day replay window
Same surface across every language. Idempotency keys, retry with backoff, and request signing are baked in — not optional.
v2.4.1
ESM + CJS. Zod-validated types. npm i hashdt
v2.4.0
Pydantic models. Async + sync. pip install hashdt
v1.8.3
Context-aware. Zero deps beyond stdlib. go get github.com/hashdt/hashdt-go
v1.4.0
Sorbet types optional. Rails-friendly. gem install hashdt
A first-class Model Context Protocol server, npx-installable, with scoped tokens, per-action audit, and optional human-in-the-loop hooks for sensitive operations.
Granular read / write / simulate scopes per agent.
Every action recorded with the calling agent's identity.
Require human approval above configurable thresholds.
Long-running ops (bulk payouts, KYB) stream progress.
// Drop HashDT into any MCP-aware client { "mcpServers": { "hashdt": { "command": "npx", "args": ["-y", "@hashdt/mcp"], "env": { "HASHDT_KEY": "sk_live_...", "HASHDT_SCOPES": "cards.read,payouts.create", "HASHDT_HITL": "payouts > 10000" } } } }
// agent invocation — looks like a tool call { "tool": "hashdt.payouts.create", "args": { "source_currency": "USDC", "destination_currency": "BRL", "rail": "pix", "amount": 8500, "beneficiary_id": "ben_92Lp" } } // → returns // { "payout_id": "po_xH4q", "status": "queued", // "estimated_settlement": "2026-05-23T14:21Z" }
# scopes are granular, additive, and audited cards.read # list / get cards.create # issue new cards cards.freeze # freeze / unfreeze only payouts.simulate # quote / preview only — no money moves payouts.create # execute payouts fx.quote # pull rates fx.execute # execute conversions # pair with HASHDT_HITL="payouts > 10000" for human approval
Real flows, fake money. Flip a flag when you're ready for production.