Get an API keyAPI plans

API documentation

Create payment links from your server, then send customers to the hosted checkout. Payments are detected on-chain automatically and confirmed once they reach the required depth.

Authentication

Send your secret key as a bearer token. Keys start with sk_live_. Keep them on your server.

Authorization: Bearer sk_live_...

Create a payment link

POST https://monifyd.com/api/v1/payment-links. Send an Idempotency-Key header so retries never create duplicates. API request limits use a separate API subscription from Dashboard plans. Customers currently pay the requested amount with no added transaction fee.

{
  "amount": 500,
  "currency": "USD",
  "description": "Website development",
  "accepted_payments": [
    { "asset": "USDC", "networks": ["base", "solana"] },
    { "asset": "BTC", "networks": ["bitcoin"] }
  ],
  "metadata": { "order_id": "ORDER-123" },
  "success_url": "https://example.com/success"
}

201 { "id": "plink_...", "status": "ACTIVE", "checkout_url": "https://monifyd.com/pay/plink_..." }

Invoices

Create an invoice in draft state, then send it to the customer. Invoice amounts are in major currency units; checkout currently charges the requested amount without an added transaction fee.

POST https://monifyd.com/api/v1/invoices
Idempotency-Key: invoice-order-123

{
  "amount": 125,
  "currency": "USD",
  "customer_email": "customer@example.com",
  "title": "Design work",
  "due_date": "2026-10-20",
  "accepted_payments": [{ "asset": "USDC", "networks": ["base"] }]
}

POST https://monifyd.com/api/v1/invoices/:id/send
POST https://monifyd.com/api/v1/invoices/:id/cancel
GET  https://monifyd.com/api/v1/invoices
GET  https://monifyd.com/api/v1/invoices/:id

GET  https://monifyd.com/api/v1/payment-links        List your payment links
GET  https://monifyd.com/api/v1/payments             List payments
GET  https://monifyd.com/api/v1/payments/:id         Get one payment

Invoices with due dates are emailed a reminder three days before the due date and on the due date. Configure Resend to send invoice emails; the regular cron job also processes reminders.

Errors

Errors share one shape.

{ "error": { "code": "UNSUPPORTED_ASSET_NETWORK", "message": "USDT is not supported on base." } }

Webhooks

Add an endpoint in Dashboard, Webhooks. Monifyd sends a POST with a JSON body. Reply with any 2xx status within 8 seconds. Anything else is retried after 1 minute, 5 minutes, 30 minutes, 2 hours, 6 hours and 24 hours, then marked failed. You can replay any event from the dashboard.

Events: payment.created, payment.detected, payment.confirming, payment.paid,
        payment.partial, payment.underpaid, payment.overpaid, payment.expired, payment.failed,
        invoice.created, invoice.sent, invoice.paid, invoice.underpaid, invoice.overpaid, invoice.cancelled

Headers:
  X-Monifyd-Event-Id     evt_...   (use it to ignore duplicates)
  X-Monifyd-Timestamp    unix seconds
  X-Monifyd-Signature    hex HMAC-SHA256 of "<timestamp>.<raw body>" with your signing secret

Body:
{ "id": "evt_...", "type": "payment.paid", "created": 1760000000,
  "data": { "id": "pay_...", "status": "PAID", "amount_cents": 50000, "reference": "ORDER-123", ... } }

Verify the signature against the raw request body before you trust an event. Mark an order as paid only on payment.paid or invoice.paid.

import crypto from "node:crypto";

export function verify(rawBody, headers, secret) {
  const ts = headers["x-monifyd-timestamp"];
  const sig = headers["x-monifyd-signature"] ?? "";
  if (Math.abs(Date.now() / 1000 - Number(ts)) > 300) return false; // too old
  const expected = crypto.createHmac("sha256", secret).update(ts + "." + rawBody).digest("hex");
  return sig.length === expected.length &&
    crypto.timingSafeEqual(Buffer.from(sig), Buffer.from(expected));
}

Wrong-amount payments

If a customer sends the wrong amount, the payment ends as UNDERPAID or OVERPAID once the transfer is confirmed. The payload carries received_amount, shortfall and excess. Do not fulfil an payment.underpaid order. Treat payment.overpaid as paid in full, and refund the extra yourself if you choose. The merchant can accept an underpayment or close it from the dashboard, and an accepted underpayment then sends payment.paid.

Node.js integration

You can call the REST API directly from your server with Node.js. Save your API key and Monifyd URL as server-side environment variables; never expose the key in browser code. Get a key from Settings, Developer settings.

// .env.local (keep this file out of source control)
MONIFYD_API_KEY=sk_live_...
MONIFYD_BASE_URL=https://monifyd.com

// Server-side Node.js code
const response = await fetch(`${process.env.MONIFYD_BASE_URL}/api/v1/payment-links`, {
  method: "POST",
  headers: {
    Authorization: `Bearer ${process.env.MONIFYD_API_KEY}`,
    "Content-Type": "application/json",
    "Idempotency-Key": "order-123"
  },
  body: JSON.stringify({
    amount: 500,
    currency: "USD",
    accepted_payments: [{ asset: "USDC", networks: ["base"] }]
  })
});

const paymentLink = await response.json();
if (!response.ok) throw new Error(paymentLink.error?.message ?? "Request failed");
console.log(paymentLink.checkout_url);

The JavaScript SDK source is included in the Monifyd project repository, but the example above works without installing a separate package.