Developers · MCP

One API.
One MCP.

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.

api.hashdt.io v1 stable OpenAPI 3.1 99.99% target SLA
Quickstart

From zero
to first call
in 60 seconds.

Sign in, generate sandbox keys, hit the API. Real flows, fake money. Flip one flag when you're ready for production.

1
Get keys

Sandbox keys are issued instantly on signup.

2
Install SDK

npm i hashdt · pip install hashdt · go get …

3
Make a call

Issue a card, send a payout, swap FX.

4
Go live

One environment flag to switch to production.

Issue a card
Send a payout
Quote FX
Webhook
// 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();
});
API reference

Surface area, in full.

Every resource is REST-shaped, idempotent, paginated by cursor, and returns typed errors with a stable code. Webhooks mirror every state transition.

Cards

POST /v1/cards · GET /v1/cards · PATCH /v1/cards/:id · POST /v1/cards/:id/freeze

Accounts

POST /v1/accounts · GET /v1/accounts/:id/balances · POST /v1/accounts/:id/sub-accounts

FX

POST /v1/fx/quotes · POST /v1/fx/executions · GET /v1/fx/pairs

Payouts

POST /v1/payouts · GET /v1/payouts/:id · POST /v1/payouts/bulk

Customers

POST /v1/customers · POST /v1/customers/:id/kyc · GET /v1/customers/:id

Webhooks

POST /v1/webhooks · 47 event types · HMAC-signed · 7-day replay window

SDKs

Typed. Idempotent. Friendly.

Same surface across every language. Idempotency keys, retry with backoff, and request signing are baked in — not optional.

JS

hashdt · TypeScript / Node

v2.4.1

ESM + CJS. Zod-validated types. npm i hashdt

PY

hashdt · Python 3.10+

v2.4.0

Pydantic models. Async + sync. pip install hashdt

GO

hashdt-go · Go 1.21+

v1.8.3

Context-aware. Zero deps beyond stdlib. go get github.com/hashdt/hashdt-go

RB

hashdt · Ruby 3.2+

v1.4.0

Sorbet types optional. Rails-friendly. gem install hashdt

MCP server

Every endpoint, agent-callable.

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.

Scoped tokens

Granular read / write / simulate scopes per agent.

Audit log

Every action recorded with the calling agent's identity.

HITL hooks

Require human approval above configurable thresholds.

Streaming

Long-running ops (bulk payouts, KYB) stream progress.

Config
Tool call
Scopes
// 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
Status

All systems operational.

API · v1● operational
Card issuing● operational
Payouts · global● operational
FX engine● operational
MCP server● operational
Changelog

Recent shipped.

2026-05-20 · v2.4.1
MCP: streaming bulk payouts
Long-running tools now stream incremental progress.
2026-05-12 · v2.4.0
FX: lock-in quotes (60s window)
POST /v1/fx/quotes returns a quote_id with TTL.
2026-04-30 · v2.3.4
Payouts: GCash and DANA rails
Philippines and Indonesia local instant payouts.
2026-04-14 · v2.3.0
Cards: programmable MCC blocking
Allow/deny lists per category, configurable at issuance.
Build with us

Sandbox keys.
60 seconds.

Real flows, fake money. Flip a flag when you're ready for production.