API documentation

Build on the GoBTC Pay protocol

One open protocol, two ways to integrate: connect your wallet or platform to let your users pay any GoBTC Pay merchant, or accept Bitcoin payments on your own website. Instant confirmation, on-chain settlement, and a built-in 50/50 revenue share for integrating partners.

This is the initial published reference for the June 19 release. Endpoints, key formats and the OpenAPI file are being finalized — confirm exact values with your integration manager before going to production.

Overview

GoBTC Pay is a Bitcoin payment protocol with instant confirmation and on-chain settlement, built on the Bitcoin Instant Protocol. There are two integration surfaces:

  • Wallet / Institution API — a server-to-server REST API for wallets and platforms that want to let their users pay GoBTC Pay merchants. Payments are attributed to your institution and accrue a revenue share.
  • Web SDK — a client + server toolkit for merchants accepting BTC payments on their own website via a button/widget and signed webhooks.
Productionhttps://api.gobtcpay.com/v1
Sandboxhttps://sandbox.api.gobtcpay.com/v1

Authentication & environments

Every request is authenticated with API keys. You get two types of key per environment:

  • Publishable key (pk_…) — safe to expose in the browser; used by the Web SDK to start a payment.
  • Secret key (sk_…) — server-side only; sent as a Bearer token. Never expose it client-side.

Sandbox keys are available immediately and require no approval — build and test the full flow against test data. Production keys are issued after KYB approval (merchant) or institution review (wallet partner).

http
Authorization: Bearer sk_live_...

Wallet / Institution API

For wallets and platforms connecting their users to the protocol. Onboarding is reviewed by our BD team; once approved you receive an institution ID, sandbox + production keys, and a webhook signing secret. Every payment you create carries an attribution_id so the revenue share is credited to you.

POST/payments

Create a payment. Returns a QR string and a mobile deep link to render in your own UX.

FieldTypeDescription
amountnumberAmount in the fiat currency below.
currencystringISO 4217 code, e.g. USD.
merchant_idstringThe merchant receiving the payment.
attribution_idstringYour institution ID — drives the 50/50 revenue share.
referencestringYour own order/reference identifier. Optional.
metadataobjectArbitrary key/value pairs echoed back on events. Optional.

Performance target: ≤ 500 ms (P95). Send an Idempotency-Key header for safe retries.

bash
curl https://api.gobtcpay.com/v1/payments \
  -H "Authorization: Bearer sk_live_..." \
  -H "Idempotency-Key: 5f3c1b2a-7d9e-4a10-9c2f-..." \
  -H "Content-Type: application/json" \
  -d '{
    "amount": 49.99,
    "currency": "USD",
    "merchant_id": "mrc_8Kd2...",
    "attribution_id": "inst_3Ad9...",
    "reference": "order-1024",
    "metadata": { "cart_id": "c_88f" }
  }'
json
{
  "id": "pay_1Hk9x...",
  "status": "pending",
  "amount": 49.99,
  "currency": "USD",
  "amount_btc": "0.00052431",
  "merchant_id": "mrc_8Kd2...",
  "attribution_id": "inst_3Ad9...",
  "reference": "order-1024",
  "qr": "bitcoin:bc1q...?amount=0.00052431",
  "deep_link": "gobtcpay://pay/pay_1Hk9x...",
  "expires_at": "2026-06-19T03:15:00Z",
  "created_at": "2026-06-19T03:00:00Z"
}
GET/payments/{id}

Retrieve a payment's status. Statuses: pending, confirmed, failed, expired.

Performance target: ≤ 200 ms (P95).

json
{
  "id": "pay_1Hk9x...",
  "status": "confirmed",
  "amount": 49.99,
  "currency": "USD",
  "amount_btc": "0.00052431",
  "txid": "9b1c...e4",
  "confirmed_at": "2026-06-19T03:01:12Z"
}
GET/institutions/{id}/revenue-share

Accrued revenue share in BTC and the payout schedule. The merchant fee is split 50% to GoMining network miners and 50% to the partner whose client made the transaction. Accrued balance above the minimum threshold settles on a weekly payout.

json
{
  "institution_id": "inst_3Ad9...",
  "currency": "BTC",
  "accrued": "0.01837402",
  "paid_to_date": "0.42910778",
  "split": { "miners": 0.5, "partner": 0.5 },
  "next_payout_at": "2026-06-23T00:00:00Z",
  "minimum_payout": "0.00100000"
}

Web SDK

Accept BTC payments on a merchant website. Install via npm or a script tag:

bash
npm install @gobtcpay/sdk
html
<script src="https://js.gobtcpay.com/v1/gobtc.js"></script>

Initialize

Create a client with your publishable key:

javascript
import { GoBTCPay } from "@gobtcpay/sdk";

const gobtc = GoBTCPay({
  publishableKey: "pk_live_...",
  environment: "production", // or "sandbox"
});

Create a payment

Call createPayment with the amount and your reference. The SDK opens a modal (or redirect) showing a QR on desktop and a deep link on mobile, then emits success, failure or expiry events.

javascript
const payment = await gobtc.createPayment({
  amount: 49.99,
  currency: "USD",
  reference: "order-1024",
  metadata: { cart_id: "c_88f" },
});

payment.on("success", (p) => console.log("Paid:", p.id));
payment.on("failure", (err) => console.error(err));
payment.on("expiry", () => console.warn("Payment expired"));

The publishable key starts the payment client-side; always confirm the final state server-side via webhooks before fulfilling an order.

Webhooks

We deliver events to your endpoint for every payment (Web SDK) or every attributed payment (institution-level). Events are signed with HMAC SHA-256, de-duplicated by event ID, and delivered within 5 s (P95).

http
POST https://your-server.com/webhooks/gobtc
X-GoBTC-Signature: t=1718766000,v1=4f2c8e...
Content-Type: application/json

{
  "id": "evt_9aZ...",
  "type": "payment.confirmed",
  "created_at": "2026-06-19T03:01:12Z",
  "data": {
    "id": "pay_1Hk9x...",
    "status": "confirmed",
    "attribution_id": "inst_3Ad9...",
    "amount_btc": "0.00052431"
  }
}

Verify the signature

Always verify the X-GoBTC-Signature header against the raw request body:

javascript
import crypto from "node:crypto";

// Verify the X-GoBTC-Signature header against the raw request body.
export function verifySignature(rawBody, header, secret) {
  const parts = Object.fromEntries(
    header.split(",").map((p) => p.split("=")),
  );
  const expected = crypto
    .createHmac("sha256", secret)
    .update(`${parts.t}.${rawBody}`)
    .digest("hex");
  return crypto.timingSafeEqual(
    Buffer.from(parts.v1),
    Buffer.from(expected),
  );
}

Rate limits & idempotency

  • Idempotency — pass an Idempotency-Key header on POST requests; retries with the same key return the original result instead of creating a duplicate payment.
  • Rate limits — requests are rate-limited per key; a 429 response includes a Retry-After header. Back off and retry.
  • Errors — standard HTTP status codes; the body carries a machine-readable code and a human-readable message.
  • Webhook idempotency — events may be re-delivered; key your handler on the event id.

Guides

Integrate as a wallet

  1. Apply via the form on this site → BD review → institution-level KYB + agreement.
  2. Receive credentials: institution ID, sandbox + production API keys, webhook signing secret.
  3. Integrate: call POST /payments with the merchant_id and your attribution_id; render the returned QR / deep link in your own UX.
  4. Track: poll GET /payments/{id} for status and subscribe to institution-level webhooks for every attributed payment.
  5. Earn: each attributed transaction accrues a 50/50 revenue share in BTC; a weekly payout settles the balance above the minimum threshold.

Accept payments on your website

  1. Sign up as a merchant and complete KYB to unlock production keys (sandbox works immediately).
  2. Install the Web SDK (npm or script tag) and initialize it with your publishable key.
  3. Call createPayment at checkout and handle the success / failure / expiry events in the UI.
  4. Add a webhook endpoint, verify the signature, and fulfill the order on payment.confirmed.