Lu71

API Reference

MCP tools, TypeScript SDK, and REST endpoints for Lu71.

MCP Setup

Fastest path. One command gives any MCP-compatible agent dispute tools.

shellnpx lu71-install --key=lu71_live_YOUR_KEY

Your agent gets these tools:

lu71_capture_intent

Call BEFORE every purchase. Returns a signed receipt (intentId + signature) required for disputes.

lu71_file_dispute

File a chargeback. Requires intentId + signature from capture_intent, plus the transaction ID from Stripe, Lithic, Visa, or Mastercard.

lu71_check_dispute

Get dispute status: submitted, under_review, won (money back), or lost (no charge).

lu71_list_disputes

List all disputes with status, amount, reason, platform, and dates.

lu71_connect_status

Check which card platforms are connected and their connection method.

lu71_account_status

Diagnose setup issues: 2FA status, active API keys, connected platforms.

lu71_verify_payment

Check a crypto address for scams, sanctions, and fraud before sending. Supports Ethereum, Solana, Bitcoin, XRP, and 6 more chains. Returns risk score + recommendation.

lu71_update_dispute

Add evidence, notes, or communication records to an existing dispute.

Manual config (Claude Desktop):

json{
  "mcpServers": {
    "lu71": {
      "command": "npx",
      "args": ["-y", "@lu71/mcp", "--key=lu71_live_YOUR_KEY"]
    }
  }
}

Remote HTTP (no local install needed):

json{
  "mcpServers": {
    "lu71": {
      "url": "https://api.getlu71.com/mcp",
      "headers": { "x-api-key": "lu71_live_YOUR_KEY" }
    }
  }
}

TypeScript SDK

Any package manager:

shellnpm install @lu71/sdk
# or
pnpm add @lu71/sdk
# or
bun add @lu71/sdk

Quick start:

typescriptimport { Lu71 } from "@lu71/sdk"

const lu71 = new Lu71({ apiKey: "lu71_live_..." })

// 1. Capture intent before purchase
const { intentId, signature } = await lu71.captureIntent({
  description: "Buy 100 blue widgets",
  merchant: "WidgetCo",
  maxAmount: 5000,
})

// 2. Agent makes purchase with its card...

// 3. File dispute when something goes wrong
const dispute = await lu71.fileDispute({
  intentId,
  intentSignature: signature,
  transactionId: "ipi_xxx",
  reason: "not_as_described",
  description: "Received red widgets instead of blue",
})

REST Endpoints

All requests require an x-api-key header except signup. Click to expand.

Creates a customer account. Returns an API key for authentication. After signup, enable 2FA and add a payment method to generate production keys.

Request

json{
  "name": "Acme Corp",
  "email": "[email protected]",
  "password": "min6chars"
}

Response

json{
  "message": "Account created.",
  "customerId": "cus_abc123",
  "apiKey": "lu71_live_..."
}

Call this BEFORE every purchase your agent makes. It creates a cryptographically signed record of what the agent plans to buy. The returned intentId and signature are required when filing a dispute later. Without them, disputes will be rejected.

Request

json{
  "description": "Buy 100 blue widgets from WidgetCo",
  "merchant": "WidgetCo",
  "maxAmount": 5000,
  "currency": "gbp",
  "constraints": { "color": "blue", "quantity": "100" }
}

Response

json{
  "message": "Purchase intent captured.",
  "intentId": "int_abc123",
  "signature": "hmac_sha256_...",
  "createdAt": "2026-06-05T10:00:00Z"
}

File a chargeback when a purchase goes wrong. You must provide the intentId and signature from a previous capture_intent call, plus the transaction ID from your card platform (Stripe, Lithic, Visa, or Mastercard). The description becomes part of the evidence submitted to the card network, so be factual and specific.

Request

json{
  "intentId": "int_abc123",
  "intentSignature": "hmac_sha256_...",
  "transactionId": "ipi_xxx",
  "reason": "not_as_described",
  "description": "Received red widgets instead of blue",
  "evidence": {
    "whatWasReceived": "100 red widgets",
    "productType": "merchandise",
    "receivedAt": "2026-06-06T14:00:00Z",
    "returnStatus": "merchant_rejected"
  }
}

Response

json{
  "message": "Dispute filed.",
  "disputeId": "dsp_abc123",
  "status": "submitted",
  "platformDisputeId": "idp_xxx"
}

Returns the full details of a single dispute including status, evidence, platform info, and resolution dates.

Response

json{
  "id": "dsp_abc123",
  "status": "won",
  "amount": 5000,
  "currency": "gbp",
  "reason": "not_as_described",
  "platform": "stripe",
  "transactionId": "ipi_xxx",
  "description": "Received red widgets instead of blue",
  "filedAt": "2026-06-05T10:30:00Z",
  "resolvedAt": "2026-06-20T09:00:00Z"
}

Returns all disputes for the authenticated account, ordered by most recent. Each dispute includes full details.

Response

json[
  { "id": "dsp_abc123", "status": "won", "amount": 5000, ... },
  { "id": "dsp_def456", "status": "submitted", "amount": 2000, ... }
]

Returns a URL to redirect your user to Stripe's OAuth consent screen. After authorization, Stripe redirects back and we store the connected account ID. We never store your Stripe API key.

Response

json{
  "url": "https://connect.stripe.com/oauth/authorize?...",
  "message": "Redirect customer to this URL"
}

Connect a Lithic account using a restricted API key. The key should have disputes:write scope. We validate it against Lithic's API before storing.

Request

json{ "apiKey": "li_restricted_..." }

Response

json{ "message": "Lithic connected. Using restricted API key." }

Connect Visa Intelligent Commerce using your API key and shared secret from developer.visa.com.

Request

json{ "apiKey": "visa_...", "sharedSecret": "..." }

Response

json{ "message": "Visa connected. Using API key and shared secret." }

Connect Mastercard Agent Pay using your consumer key and signing key (PEM) from developer.mastercard.com.

Request

json{ "consumerKey": "mc_...", "signingKey": "-----BEGIN PRIVATE KEY-----..." }

Response

json{ "message": "Mastercard connected. Using consumer key and signing key." }

Register a URL where we will POST dispute status updates. Returns a signing secret you can use to verify that incoming webhooks are genuinely from Lu71.

Request

json{ "url": "https://your-app.com/webhooks/lu71" }

Response

json{
  "message": "Webhook configured.",
  "webhookUrl": "https://your-app.com/webhooks/lu71",
  "webhookSecret": "whsec_...",
  "events": ["dispute.submitted", "dispute.under_review", "dispute.won", "dispute.lost"]
}

Check a blockchain address for scams, sanctions, and fraud risk before sending payment. Supports 10 chains. Returns a risk score (0-100), risk level, flags, and a recommendation (SAFE / CAUTION / DO NOT PAY). Crypto payments are irreversible — always verify first.

Request

json{ "recipient": "0x098B716B8Aaf21512996dC57EB0615e2383E2f96", "chain": "ethereum" }

Response

json{
  "riskScore": 100,
  "riskLevel": "critical",
  "flags": ["blacklisted", "stealing_attack", "sanctioned"],
  "recommendation": "DO NOT PAY",
  "sources": ["goplus"],
  "chain": "ethereum",
  "address": "0x098B716B..."
}

Dispute Reasons

Use one of these reason codes when filing:

not_receivedItem was paid for but never arrived
not_as_describedItem received does not match what was ordered
duplicateCharged more than once for the same purchase
unauthorizedCharge was not authorized by the cardholder
cancelledOrder was cancelled but payment was still taken
service_not_renderedService was paid for but never provided
otherDoes not fit the above categories

Webhook Events

Register a URL via POST /v1/connect/webhooks. We POST on every status change. Each payload is HMAC-signed.

json{
  "id": "evt_1717578600000",
  "type": "dispute.won",
  "created": "2026-07-02T09:30:00Z",
  "data": {
    "disputeId": "dsp_abc123",
    "status": "won",
    "amount": 5000,
    "currency": "gbp",
    "reason": "not_as_described",
    "resolvedAt": "2026-07-02T09:30:00Z"
  }
}

Available events:

dispute.submitted

Dispute has been filed with the card network. Evidence submitted.

dispute.under_review

Card network is actively reviewing the evidence. Typically takes 1 to 4 weeks.

dispute.won

Dispute resolved in your favour. Funds returned to cardholder. Success fee charged.

dispute.lost

Dispute resolved in the merchant's favour. No fee charged.

Verify webhook signatures:

typescriptimport crypto from "crypto"

function verifyWebhook(body: string, signature: string, secret: string): boolean {
  const expected = crypto.createHmac("sha256", secret).update(body).digest("hex")
  return signature === expected
}

// In your webhook handler:
const sig = req.headers["x-lu71-signature"]
const valid = verifyWebhook(req.body, sig, "whsec_your_secret")
if (!valid) return res.status(401).send("Invalid signature")