{
  "openapi": "3.0.3",
  "info": {
    "title": "InstantPay API",
    "version": "1.0.0",
    "description": "Accept crypto on your website. Create an invoice in EUR or USD, send the customer to the checkout page, receive a signed webhook when it is paid. Authenticate with `X-API-Key: sk_live_...` or `Authorization: Bearer sk_live_...` (your secret key; keys from before the pairs, `ik_xxx.secret`, keep working). A test key creates test invoices you can pay with `POST /v1/invoices/{id}/simulate`. The public key (`pk_live_...`) is only accepted on `/v1/public/*`.",
    "contact": {
      "name": "InstantNode support",
      "url": "https://instantnode.eu/contact"
    }
  },
  "servers": [
    {
      "url": "https://pay.instantnode.eu/v1",
      "description": "Production"
    }
  ],
  "security": [
    {
      "apiKey": []
    },
    {
      "bearer": []
    }
  ],
  "tags": [
    {
      "name": "Invoices",
      "description": "A payment request with a price in EUR or USD. The customer pays it in any accepted coin."
    },
    {
      "name": "Currencies",
      "description": "What the checkout accepts right now."
    },
    {
      "name": "Account",
      "description": "Your merchant record, balance and ledger."
    },
    {
      "name": "Payouts",
      "description": "Money leaving your InstantPay balance to your own wallet, in the coin you picked in the dashboard (SOL by default). Requested in the dashboard or with POST /payouts."
    },
    {
      "name": "Refunds",
      "description": "Money sent back to a customer from a paid invoice. Requested in the dashboard, read here; `refund.paid` and `refund.failed` arrive as webhooks."
    },
    {
      "name": "Customers",
      "description": "Static deposit addresses per customer. Needs the customers feature on your account."
    },
    {
      "name": "Events",
      "description": "Everything that happened to your objects, newest first. The same bodies your webhook endpoints receive; read them to reconcile."
    },
    {
      "name": "Public",
      "description": "The routes a browser may call with your public key (pk_live_ / pk_test_): checkout configuration and opening the checkout for an invoice your server created."
    }
  ],
  "paths": {
    "/invoices": {
      "post": {
        "tags": [
          "Invoices"
        ],
        "summary": "Create an invoice",
        "description": "Returns the invoice with a `checkoutUrl`. Send an `Idempotency-Key` header to make retries safe; the same key with a different body answers `409`. Passing `asset` preselects the coin and skips the picker; when that fails the invoice is still created and a `warnings` array explains why.",
        "parameters": [
          {
            "name": "Idempotency-Key",
            "in": "header",
            "required": false,
            "schema": {
              "type": "string",
              "maxLength": 200
            }
          }
        ],
        "requestBody": {
          "required": true,
          "content": {
            "application/json": {
              "schema": {
                "type": "object",
                "required": [
                  "amount",
                  "currency"
                ],
                "properties": {
                  "amount": {
                    "oneOf": [
                      {
                        "type": "string"
                      },
                      {
                        "type": "number"
                      }
                    ],
                    "example": "19.99"
                  },
                  "currency": {
                    "type": "string",
                    "example": "EUR",
                    "description": "EUR or USD"
                  },
                  "orderId": {
                    "type": "string",
                    "maxLength": 200,
                    "example": "order-1042"
                  },
                  "description": {
                    "type": "string",
                    "maxLength": 500,
                    "example": "Game Server Pro, 1 month"
                  },
                  "asset": {
                    "type": "string",
                    "maxLength": 40,
                    "example": "SOL",
                    "description": "Preselect a coin (asset id from /currencies)"
                  },
                  "redirectUrl": {
                    "type": "string",
                    "format": "uri",
                    "description": "Where the customer goes after paying. Default: the success URL of your Checkout settings."
                  },
                  "cancelUrl": {
                    "type": "string",
                    "format": "uri",
                    "description": "Default: the cancel URL of your Checkout settings."
                  },
                  "webhookUrl": {
                    "type": "string",
                    "format": "uri",
                    "description": "An extra URL that receives the events of this invoice, signed with the legacy account secret, next to your endpoints. https only."
                  },
                  "metadata": {
                    "type": "object",
                    "additionalProperties": true,
                    "description": "Anything you want back in the webhook"
                  },
                  "ttlSeconds": {
                    "type": "integer",
                    "minimum": 60,
                    "maximum": 86400,
                    "description": "How long the customer has to pay. Default: the time to pay of your Checkout settings (20 minutes unless changed)."
                  },
                  "customerEmail": {
                    "type": "string",
                    "format": "email",
                    "maxLength": 200
                  }
                }
              },
              "example": {
                "amount": "19.99",
                "currency": "EUR",
                "orderId": "order-1042",
                "description": "Game Server Pro, 1 month",
                "redirectUrl": "https://shop.example/thanks",
                "webhookUrl": "https://shop.example/instantpay/webhook",
                "metadata": {
                  "userId": "u_8812"
                }
              }
            }
          }
        },
        "responses": {
          "201": {
            "description": "Created",
            "content": {
              "application/json": {
                "schema": {
                  "allOf": [
                    {
                      "$ref": "#/components/schemas/Invoice"
                    },
                    {
                      "type": "object",
                      "properties": {
                        "warnings": {
                          "type": "array",
                          "items": {
                            "type": "string"
                          }
                        }
                      }
                    }
                  ]
                }
              }
            }
          },
          "400": {
            "description": "Validation failed, or `amount_too_large` when above the maximum invoice amount set for your account",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "403": {
            "description": "Your account is not approved yet, or suspended",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "409": {
            "description": "Idempotency-Key reused with a different body",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "429": {
            "description": "Rate limit hit",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "503": {
            "description": "`maintenance`: live invoices are paused for a moment, retry after Retry-After",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          }
        }
      },
      "get": {
        "tags": [
          "Invoices"
        ],
        "summary": "List invoices",
        "parameters": [
          {
            "name": "limit",
            "in": "query",
            "schema": {
              "type": "integer",
              "minimum": 1,
              "maximum": 100,
              "default": 25
            }
          },
          {
            "name": "status",
            "in": "query",
            "schema": {
              "type": "string",
              "enum": [
                "created",
                "awaiting_payment",
                "detected",
                "confirmed",
                "overpaid",
                "underpaid",
                "expired",
                "paid_late",
                "cancelled",
                "failed"
              ]
            }
          },
          {
            "name": "orderId",
            "in": "query",
            "schema": {
              "type": "string"
            },
            "description": "Find the invoice behind one of your order ids"
          }
        ],
        "responses": {
          "200": {
            "description": "Newest first",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "data": {
                      "type": "array",
                      "items": {
                        "$ref": "#/components/schemas/Invoice"
                      }
                    }
                  }
                }
              }
            }
          }
        }
      }
    },
    "/invoices/{id}": {
      "get": {
        "tags": [
          "Invoices"
        ],
        "summary": "Get an invoice",
        "description": "Poll this if you cannot receive webhooks. `paid` is the field to act on.",
        "parameters": [
          {
            "name": "id",
            "in": "path",
            "required": true,
            "schema": {
              "type": "string",
              "format": "uuid"
            }
          }
        ],
        "responses": {
          "200": {
            "description": "OK",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Invoice"
                }
              }
            }
          },
          "404": {
            "description": "Not yours or unknown",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          }
        }
      }
    },
    "/invoices/{id}/select": {
      "post": {
        "tags": [
          "Invoices"
        ],
        "summary": "Pick the coin server-side",
        "description": "For a payment page you build yourself: locks the rate, claims a deposit address and returns `depositAddress` and `amountExpected`. The hosted checkout does this for you.",
        "parameters": [
          {
            "name": "id",
            "in": "path",
            "required": true,
            "schema": {
              "type": "string",
              "format": "uuid"
            }
          }
        ],
        "requestBody": {
          "required": true,
          "content": {
            "application/json": {
              "schema": {
                "type": "object",
                "required": [
                  "asset"
                ],
                "properties": {
                  "asset": {
                    "type": "string",
                    "example": "USDC_SOL"
                  }
                }
              }
            }
          }
        },
        "responses": {
          "200": {
            "description": "OK",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Invoice"
                }
              }
            }
          },
          "400": {
            "description": "Coin not available for this amount, or a payment is already in flight",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "404": {
            "description": "Not yours or unknown",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          }
        }
      }
    },
    "/invoices/{id}/simulate": {
      "post": {
        "tags": [
          "Invoices"
        ],
        "summary": "Pay a test invoice",
        "description": "Only for invoices created with a test key. Runs the whole pipeline without a chain: status changes, ledger, webhook.",
        "parameters": [
          {
            "name": "id",
            "in": "path",
            "required": true,
            "schema": {
              "type": "string",
              "format": "uuid"
            }
          }
        ],
        "requestBody": {
          "required": false,
          "content": {
            "application/json": {
              "schema": {
                "type": "object",
                "properties": {
                  "case": {
                    "type": "string",
                    "enum": [
                      "exact",
                      "under",
                      "over"
                    ],
                    "default": "exact"
                  },
                  "asset": {
                    "type": "string",
                    "description": "Coin to simulate with when none is picked yet"
                  }
                }
              }
            }
          }
        },
        "responses": {
          "200": {
            "description": "The invoice after the simulated payment",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Invoice"
                }
              }
            }
          },
          "403": {
            "description": "Not a test invoice",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "404": {
            "description": "Not yours or unknown",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          }
        }
      }
    },
    "/currencies": {
      "get": {
        "tags": [
          "Currencies"
        ],
        "summary": "Accepted coins",
        "responses": {
          "200": {
            "description": "Every enabled coin with its minimum",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "data": {
                      "type": "array",
                      "items": {
                        "type": "object",
                        "properties": {
                          "id": {
                            "type": "string",
                            "example": "USDC_SOL"
                          },
                          "symbol": {
                            "type": "string",
                            "example": "USDC"
                          },
                          "name": {
                            "type": "string",
                            "example": "USD Coin (Solana)"
                          },
                          "chain": {
                            "type": "string",
                            "example": "solana"
                          },
                          "kind": {
                            "type": "string",
                            "enum": [
                              "native",
                              "spl",
                              "erc20",
                              "trc20"
                            ]
                          },
                          "decimals": {
                            "type": "integer"
                          },
                          "minAmount": {
                            "type": "string",
                            "example": "0.01"
                          }
                        }
                      }
                    }
                  }
                }
              }
            }
          }
        }
      }
    },
    "/merchant": {
      "get": {
        "tags": [
          "Account"
        ],
        "summary": "Your merchant account",
        "responses": {
          "200": {
            "description": "OK",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "id": {
                      "type": "string"
                    },
                    "name": {
                      "type": "string"
                    },
                    "status": {
                      "type": "string",
                      "enum": [
                        "pending",
                        "active",
                        "suspended",
                        "rejected"
                      ]
                    },
                    "feeBps": {
                      "type": "integer",
                      "example": 166
                    },
                    "feePercent": {
                      "type": "string",
                      "example": "1.66"
                    },
                    "settlementEnabled": {
                      "type": "boolean"
                    },
                    "customersEnabled": {
                      "type": "boolean"
                    },
                    "webhookUrl": {
                      "type": "string",
                      "nullable": true
                    },
                    "payoutAsset": {
                      "type": "string",
                      "example": "SOL",
                      "description": "The coin payouts are sent in, chosen in the dashboard (asset id from /currencies, e.g. SOL, USDC_SOL, USDT_TRC20)"
                    },
                    "livemode": {
                      "type": "boolean",
                      "description": "Whether the key used is a live key"
                    },
                    "balances": {
                      "type": "array",
                      "items": {
                        "$ref": "#/components/schemas/Balance"
                      }
                    },
                    "createdAt": {
                      "type": "string",
                      "format": "date-time"
                    }
                  }
                }
              }
            }
          }
        }
      }
    },
    "/balances": {
      "get": {
        "tags": [
          "Account"
        ],
        "summary": "Your balance",
        "description": "What InstantPay owes you, per currency, after fees and open payouts. A test key answers with the test balance.",
        "responses": {
          "200": {
            "description": "OK",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "data": {
                      "type": "array",
                      "items": {
                        "$ref": "#/components/schemas/Balance"
                      }
                    }
                  }
                }
              }
            }
          }
        }
      }
    },
    "/ledger": {
      "get": {
        "tags": [
          "Account"
        ],
        "summary": "Ledger entries",
        "description": "Every sale, fee, payout, refund and adjustment on your balance, in the mode of the key. Paginate with `before` = the `nextBefore` of the previous page.",
        "parameters": [
          {
            "name": "limit",
            "in": "query",
            "schema": {
              "type": "integer",
              "minimum": 1,
              "maximum": 200,
              "default": 50
            }
          },
          {
            "name": "before",
            "in": "query",
            "schema": {
              "type": "string"
            }
          },
          {
            "name": "currency",
            "in": "query",
            "schema": {
              "type": "string",
              "enum": [
                "EUR",
                "USD"
              ]
            }
          }
        ],
        "responses": {
          "200": {
            "description": "OK",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "data": {
                      "type": "array",
                      "items": {
                        "type": "object",
                        "properties": {
                          "id": {
                            "type": "string"
                          },
                          "currency": {
                            "type": "string"
                          },
                          "amount": {
                            "type": "string",
                            "description": "Signed; fees and payouts are negative"
                          },
                          "kind": {
                            "type": "string",
                            "enum": [
                              "sale",
                              "fee",
                              "payout",
                              "payout_reversal",
                              "refund",
                              "refund_reversal",
                              "adjustment"
                            ]
                          },
                          "refType": {
                            "type": "string",
                            "enum": [
                              "invoice",
                              "deposit",
                              "payout",
                              "refund",
                              "admin"
                            ]
                          },
                          "refId": {
                            "type": "string",
                            "nullable": true
                          },
                          "feeBps": {
                            "type": "integer",
                            "nullable": true
                          },
                          "memo": {
                            "type": "string",
                            "nullable": true
                          },
                          "livemode": {
                            "type": "boolean"
                          },
                          "createdAt": {
                            "type": "string",
                            "format": "date-time"
                          }
                        }
                      }
                    },
                    "hasMore": {
                      "type": "boolean"
                    },
                    "nextBefore": {
                      "type": "string",
                      "nullable": true
                    }
                  }
                }
              }
            }
          }
        }
      }
    },
    "/payouts": {
      "post": {
        "tags": [
          "Payouts"
        ],
        "summary": "Request a payout",
        "description": "What the dashboard form does, with the same checks: minimum, daily limit, one open payout at a time, a payout address past its 24 h cooling. The amount leaves the balance at once; the coin amount and the network fee (taken out of the payout) are fixed at approval. Live keys only.",
        "requestBody": {
          "required": true,
          "content": {
            "application/json": {
              "schema": {
                "type": "object",
                "required": [
                  "amount"
                ],
                "properties": {
                  "currency": {
                    "type": "string",
                    "example": "EUR",
                    "description": "EUR or USD, default EUR"
                  },
                  "amount": {
                    "type": "string",
                    "example": "250.00",
                    "description": "Fiat amount with at most two decimals, or \"all\" for the whole available balance"
                  }
                }
              }
            }
          }
        },
        "responses": {
          "201": {
            "description": "Requested",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Payout"
                }
              }
            }
          },
          "400": {
            "description": "`invalid_amount`, `below_minimum`, `insufficient_balance`, `daily_limit`, `no_address`, or `test_mode` for a test key",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "403": {
            "description": "Account not active",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "409": {
            "description": "`payout_open`: a payout is already open",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "503": {
            "description": "`maintenance`: payouts are paused for a moment",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          }
        }
      },
      "get": {
        "tags": [
          "Payouts"
        ],
        "summary": "List payouts",
        "parameters": [
          {
            "name": "limit",
            "in": "query",
            "schema": {
              "type": "integer",
              "minimum": 1,
              "maximum": 100,
              "default": 25
            }
          }
        ],
        "responses": {
          "200": {
            "description": "Newest first",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "data": {
                      "type": "array",
                      "items": {
                        "$ref": "#/components/schemas/Payout"
                      }
                    }
                  }
                }
              }
            }
          }
        }
      }
    },
    "/payouts/{id}": {
      "get": {
        "tags": [
          "Payouts"
        ],
        "summary": "Get a payout",
        "parameters": [
          {
            "name": "id",
            "in": "path",
            "required": true,
            "schema": {
              "type": "string",
              "format": "uuid"
            }
          }
        ],
        "responses": {
          "200": {
            "description": "OK",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Payout"
                }
              }
            }
          },
          "404": {
            "description": "Not yours or unknown",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          }
        }
      }
    },
    "/refunds": {
      "get": {
        "tags": [
          "Refunds"
        ],
        "summary": "List refunds",
        "parameters": [
          {
            "name": "limit",
            "in": "query",
            "schema": {
              "type": "integer",
              "minimum": 1,
              "maximum": 100,
              "default": 25
            }
          },
          {
            "name": "invoiceId",
            "in": "query",
            "schema": {
              "type": "string",
              "format": "uuid"
            },
            "description": "Only refunds of this invoice"
          }
        ],
        "responses": {
          "200": {
            "description": "Newest first, in the mode of the key",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "data": {
                      "type": "array",
                      "items": {
                        "$ref": "#/components/schemas/Refund"
                      }
                    }
                  }
                }
              }
            }
          }
        }
      }
    },
    "/refunds/{id}": {
      "get": {
        "tags": [
          "Refunds"
        ],
        "summary": "Get a refund",
        "parameters": [
          {
            "name": "id",
            "in": "path",
            "required": true,
            "schema": {
              "type": "string",
              "format": "uuid"
            }
          }
        ],
        "responses": {
          "200": {
            "description": "OK",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Refund"
                }
              }
            }
          },
          "404": {
            "description": "Not yours or unknown",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          }
        }
      }
    },
    "/customers/{ref}/addresses": {
      "post": {
        "tags": [
          "Customers"
        ],
        "summary": "Create or fetch a customer's static addresses",
        "description": "One address per chain family that stays with the customer for good. Every confirmed deposit on it is reported with a `deposit.confirmed` webhook carrying the net EUR value. Idempotent.",
        "parameters": [
          {
            "name": "ref",
            "in": "path",
            "required": true,
            "schema": {
              "type": "string",
              "pattern": "^[A-Za-z0-9._:-]{1,120}$"
            },
            "description": "Your customer id"
          }
        ],
        "responses": {
          "201": {
            "description": "OK",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/CustomerAddresses"
                }
              }
            }
          },
          "403": {
            "description": "Customers feature not enabled for your account",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "503": {
            "description": "Address pool is refilling, retry in a few seconds",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          }
        }
      },
      "get": {
        "tags": [
          "Customers"
        ],
        "summary": "Fetch a customer's addresses",
        "parameters": [
          {
            "name": "ref",
            "in": "path",
            "required": true,
            "schema": {
              "type": "string"
            }
          }
        ],
        "responses": {
          "200": {
            "description": "OK",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/CustomerAddresses"
                }
              }
            }
          },
          "404": {
            "description": "Unknown customer",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          }
        }
      }
    },
    "/events": {
      "get": {
        "tags": [
          "Events"
        ],
        "summary": "List events",
        "description": "Every event of your account in the mode of the key, newest first. Paginate with `before` = the `nextBefore` of the previous page.",
        "parameters": [
          {
            "name": "limit",
            "in": "query",
            "schema": {
              "type": "integer",
              "minimum": 1,
              "maximum": 200,
              "default": 50
            }
          },
          {
            "name": "before",
            "in": "query",
            "schema": {
              "type": "string",
              "example": "evt_01K5N3Y7Z2Q8XW6M3R9V4T1B5C"
            }
          },
          {
            "name": "type",
            "in": "query",
            "schema": {
              "type": "string",
              "enum": [
                "invoice.created",
                "invoice.detected",
                "invoice.confirmed",
                "invoice.overpaid",
                "invoice.underpaid",
                "invoice.expired",
                "invoice.paid_late",
                "invoice.cancelled",
                "invoice.failed",
                "deposit.confirmed",
                "payout.paid",
                "payout.failed",
                "refund.paid",
                "refund.failed",
                "account.approved",
                "account.suspended"
              ]
            }
          },
          {
            "name": "object",
            "in": "query",
            "description": "Only events of one object (an invoice or payout id)",
            "schema": {
              "type": "string"
            }
          }
        ],
        "responses": {
          "200": {
            "description": "OK",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "data": {
                      "type": "array",
                      "items": {
                        "$ref": "#/components/schemas/Event"
                      }
                    },
                    "hasMore": {
                      "type": "boolean"
                    },
                    "nextBefore": {
                      "type": "string",
                      "nullable": true
                    }
                  }
                }
              }
            }
          }
        }
      }
    },
    "/events/{id}": {
      "get": {
        "tags": [
          "Events"
        ],
        "summary": "One event",
        "parameters": [
          {
            "name": "id",
            "in": "path",
            "required": true,
            "schema": {
              "type": "string"
            }
          }
        ],
        "responses": {
          "200": {
            "description": "OK",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Event"
                }
              }
            }
          },
          "404": {
            "description": "Not yours, unknown, or from the other mode",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          }
        }
      }
    },
    "/public/config": {
      "get": {
        "tags": [
          "Public"
        ],
        "summary": "Checkout configuration (public key)",
        "description": "Branding, accepted coins and currencies of your account, for a page that builds its own coin picker. Answers with `Access-Control-Allow-Origin: *`.",
        "security": [
          {
            "publicKey": []
          }
        ],
        "responses": {
          "200": {
            "description": "OK",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "merchant": {
                      "type": "string"
                    },
                    "livemode": {
                      "type": "boolean"
                    },
                    "branding": {
                      "type": "object",
                      "properties": {
                        "color": {
                          "type": "string",
                          "nullable": true
                        },
                        "logoUrl": {
                          "type": "string",
                          "nullable": true
                        }
                      }
                    },
                    "currencies": {
                      "type": "array",
                      "items": {
                        "type": "string"
                      }
                    },
                    "checkoutLang": {
                      "type": "string"
                    },
                    "coins": {
                      "type": "array",
                      "items": {
                        "type": "object",
                        "properties": {
                          "id": {
                            "type": "string"
                          },
                          "symbol": {
                            "type": "string"
                          },
                          "name": {
                            "type": "string"
                          },
                          "chain": {
                            "type": "string"
                          }
                        }
                      }
                    },
                    "widgetUrl": {
                      "type": "string"
                    }
                  }
                }
              }
            }
          },
          "403": {
            "description": "A secret key was used here, or a public key elsewhere",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          }
        }
      }
    },
    "/public/checkout-sessions": {
      "post": {
        "tags": [
          "Public"
        ],
        "summary": "Open the checkout for an invoice (public key)",
        "description": "The browser hands over the id of an invoice your server created with the secret key and gets the checkout token and URL back, so the secret key never reaches the page.",
        "security": [
          {
            "publicKey": []
          }
        ],
        "requestBody": {
          "required": true,
          "content": {
            "application/json": {
              "schema": {
                "type": "object",
                "required": [
                  "invoiceId"
                ],
                "properties": {
                  "invoiceId": {
                    "type": "string",
                    "format": "uuid"
                  }
                }
              }
            }
          }
        },
        "responses": {
          "200": {
            "description": "OK",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "invoiceId": {
                      "type": "string"
                    },
                    "token": {
                      "type": "string"
                    },
                    "checkoutUrl": {
                      "type": "string",
                      "format": "uri"
                    },
                    "status": {
                      "type": "string",
                      "enum": [
                        "created",
                        "awaiting_payment",
                        "detected",
                        "confirmed",
                        "overpaid",
                        "underpaid",
                        "expired",
                        "paid_late",
                        "cancelled",
                        "failed"
                      ]
                    },
                    "expiresAt": {
                      "type": "string",
                      "format": "date-time"
                    }
                  }
                }
              }
            }
          },
          "404": {
            "description": "Not an invoice of this account in this mode",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          }
        }
      }
    }
  },
  "components": {
    "securitySchemes": {
      "apiKey": {
        "type": "apiKey",
        "in": "header",
        "name": "X-API-Key",
        "description": "Your secret key: `sk_live_...` / `sk_test_...` (or a legacy `ik_xxx.secret`)"
      },
      "publicKey": {
        "type": "apiKey",
        "in": "header",
        "name": "X-API-Key",
        "description": "Your public key: `pk_live_...` / `pk_test_...`; only on /v1/public/*"
      },
      "bearer": {
        "type": "http",
        "scheme": "bearer",
        "description": "Same key as a Bearer token"
      }
    },
    "schemas": {
      "Invoice": {
        "type": "object",
        "properties": {
          "id": {
            "type": "string",
            "format": "uuid"
          },
          "orderId": {
            "type": "string",
            "nullable": true,
            "description": "Your own reference. Unique per merchant; creating again with the same orderId returns the existing invoice."
          },
          "status": {
            "type": "string",
            "enum": [
              "created",
              "awaiting_payment",
              "detected",
              "confirmed",
              "overpaid",
              "underpaid",
              "expired",
              "paid_late",
              "cancelled",
              "failed"
            ]
          },
          "object": {
            "type": "string",
            "example": "invoice"
          },
          "paid": {
            "type": "boolean",
            "description": "true for confirmed and overpaid"
          },
          "livemode": {
            "type": "boolean",
            "description": "false when created with a test key"
          },
          "amount": {
            "type": "string",
            "example": "19.99",
            "description": "The price you asked for"
          },
          "currency": {
            "type": "string",
            "example": "EUR",
            "description": "EUR or USD"
          },
          "description": {
            "type": "string",
            "nullable": true
          },
          "asset": {
            "type": "string",
            "nullable": true,
            "example": "USDC_SOL",
            "description": "The coin the customer picked, null until they pick"
          },
          "assetSymbol": {
            "type": "string",
            "nullable": true,
            "example": "USDC"
          },
          "amountExpected": {
            "type": "string",
            "nullable": true,
            "example": "21.687",
            "description": "In the picked coin"
          },
          "amountReceived": {
            "type": "string",
            "nullable": true
          },
          "rate": {
            "type": "string",
            "nullable": true,
            "description": "Fiat per whole coin, frozen when the customer picked"
          },
          "depositAddress": {
            "type": "string",
            "nullable": true
          },
          "checkoutUrl": {
            "type": "string",
            "format": "uri",
            "description": "Send the customer here"
          },
          "customerEmail": {
            "type": "string",
            "nullable": true
          },
          "metadata": {
            "type": "object",
            "additionalProperties": true
          },
          "paymentLinkId": {
            "type": "string",
            "nullable": true,
            "description": "Set when the invoice came from a payment link"
          },
          "refundedAmount": {
            "type": "string",
            "nullable": true,
            "example": "0.00"
          },
          "createdAt": {
            "type": "string",
            "format": "date-time"
          },
          "expiresAt": {
            "type": "string",
            "format": "date-time"
          },
          "confirmedAt": {
            "type": "string",
            "format": "date-time",
            "nullable": true
          }
        }
      },
      "Error": {
        "type": "object",
        "required": [
          "error",
          "message"
        ],
        "properties": {
          "error": {
            "type": "string",
            "example": "invalid_request"
          },
          "message": {
            "type": "string"
          }
        }
      },
      "Balance": {
        "type": "object",
        "description": "One currency of your balance in the mode of the key (a test key sees the test balance). `available` is what may be paid out right now, `pending` what is detected on chain but not confirmed, `reserved` the open payouts and refunds already deducted; the other fields are lifetime sums.",
        "properties": {
          "currency": {
            "type": "string",
            "example": "EUR"
          },
          "available": {
            "type": "string",
            "example": "98.34"
          },
          "pending": {
            "type": "string",
            "example": "0.00",
            "description": "Expected net of invoices in status detected; shown, not spendable"
          },
          "reserved": {
            "type": "string",
            "example": "0.00",
            "description": "Open payouts and refunds; already subtracted from available"
          },
          "sales": {
            "type": "string",
            "example": "100.00"
          },
          "fees": {
            "type": "string",
            "example": "-1.66",
            "description": "Negative"
          },
          "payouts": {
            "type": "string",
            "example": "0.00",
            "description": "Negative; reversals of failed payouts are added back"
          },
          "refunds": {
            "type": "string",
            "example": "0.00",
            "description": "Negative; reversals of failed refunds are added back"
          }
        }
      },
      "Payout": {
        "type": "object",
        "properties": {
          "id": {
            "type": "string",
            "format": "uuid"
          },
          "status": {
            "type": "string",
            "enum": [
              "requested",
              "approved",
              "processing",
              "paid",
              "failed",
              "rejected",
              "cancelled"
            ]
          },
          "currency": {
            "type": "string",
            "example": "EUR"
          },
          "amount": {
            "type": "string",
            "example": "250.00"
          },
          "asset": {
            "type": "string",
            "example": "USDT_TRC20",
            "description": "The coin the payout is sent in: the payout coin chosen in the dashboard when it was requested (asset id from /currencies)"
          },
          "assetSymbol": {
            "type": "string",
            "example": "USDT"
          },
          "chain": {
            "type": "string",
            "example": "tron"
          },
          "toAddress": {
            "type": "string"
          },
          "amountCrypto": {
            "type": "string",
            "nullable": true,
            "description": "What is sent, network fee already taken out; filled once approved and quoted"
          },
          "networkFeeCrypto": {
            "type": "string",
            "nullable": true,
            "description": "The network fee taken out of the payout, in the coin"
          },
          "rate": {
            "type": "string",
            "nullable": true,
            "description": "Fiat per coin, fixed at approval"
          },
          "txid": {
            "type": "string",
            "nullable": true
          },
          "failureReason": {
            "type": "string",
            "nullable": true
          },
          "requestedAt": {
            "type": "string",
            "format": "date-time"
          },
          "approvedAt": {
            "type": "string",
            "format": "date-time",
            "nullable": true
          },
          "finalizedAt": {
            "type": "string",
            "format": "date-time",
            "nullable": true
          }
        }
      },
      "Refund": {
        "type": "object",
        "description": "Part of a paid invoice sent back to the customer. The fiat amount left the balance when it was requested; a failed refund is reversed on the ledger.",
        "properties": {
          "object": {
            "type": "string",
            "example": "refund"
          },
          "id": {
            "type": "string",
            "format": "uuid"
          },
          "invoiceId": {
            "type": "string",
            "format": "uuid"
          },
          "status": {
            "type": "string",
            "enum": [
              "requested",
              "approved",
              "processing",
              "paid",
              "failed",
              "rejected",
              "cancelled"
            ]
          },
          "livemode": {
            "type": "boolean"
          },
          "currency": {
            "type": "string",
            "example": "EUR"
          },
          "amount": {
            "type": "string",
            "example": "10.00",
            "description": "Fiat amount deducted from the balance"
          },
          "asset": {
            "type": "string",
            "example": "USDT_TRC20",
            "description": "The coin the refund is sent in"
          },
          "assetSymbol": {
            "type": "string",
            "example": "USDT"
          },
          "chain": {
            "type": "string",
            "example": "tron"
          },
          "toAddress": {
            "type": "string"
          },
          "amountCrypto": {
            "type": "string",
            "nullable": true,
            "description": "What the customer receives, network fee already taken out"
          },
          "networkFeeCrypto": {
            "type": "string",
            "nullable": true
          },
          "rate": {
            "type": "string",
            "nullable": true,
            "description": "Fiat per coin at the time of the quote"
          },
          "txid": {
            "type": "string",
            "nullable": true
          },
          "reason": {
            "type": "string",
            "nullable": true
          },
          "failureReason": {
            "type": "string",
            "nullable": true
          },
          "requestedAt": {
            "type": "string",
            "format": "date-time"
          },
          "approvedAt": {
            "type": "string",
            "format": "date-time",
            "nullable": true
          },
          "finalizedAt": {
            "type": "string",
            "format": "date-time",
            "nullable": true
          }
        }
      },
      "CustomerAddresses": {
        "type": "object",
        "properties": {
          "customer": {
            "type": "string"
          },
          "conversion": {
            "type": "object",
            "properties": {
              "provider": {
                "type": "string",
                "example": "FixedFloat"
              },
              "target": {
                "type": "string",
                "example": "SOL"
              },
              "feesPaidBy": {
                "type": "string",
                "example": "payer"
              }
            }
          },
          "addresses": {
            "type": "array",
            "items": {
              "type": "object",
              "properties": {
                "family": {
                  "type": "string",
                  "enum": [
                    "solana",
                    "evm",
                    "tron",
                    "utxo"
                  ]
                },
                "chainIds": {
                  "type": "array",
                  "items": {
                    "type": "string"
                  }
                },
                "address": {
                  "type": "string"
                },
                "assets": {
                  "type": "array",
                  "items": {
                    "type": "object",
                    "properties": {
                      "id": {
                        "type": "string"
                      },
                      "symbol": {
                        "type": "string"
                      },
                      "chainId": {
                        "type": "string"
                      },
                      "kind": {
                        "type": "string"
                      }
                    }
                  }
                }
              }
            }
          }
        }
      },
      "Event": {
        "type": "object",
        "description": "What an endpoint receives and what GET /v1/events returns: `data.object` is the object exactly as its GET answers it. `id` is the idempotency key.",
        "properties": {
          "id": {
            "type": "string",
            "example": "evt_01K5N3Y7Z2Q8XW6M3R9V4T1B5C"
          },
          "object": {
            "type": "string",
            "example": "event"
          },
          "type": {
            "type": "string",
            "enum": [
              "invoice.created",
              "invoice.detected",
              "invoice.confirmed",
              "invoice.overpaid",
              "invoice.underpaid",
              "invoice.expired",
              "invoice.paid_late",
              "invoice.cancelled",
              "invoice.failed",
              "deposit.confirmed",
              "payout.paid",
              "payout.failed",
              "refund.paid",
              "refund.failed",
              "account.approved",
              "account.suspended"
            ]
          },
          "livemode": {
            "type": "boolean"
          },
          "created": {
            "type": "string",
            "format": "date-time"
          },
          "data": {
            "type": "object",
            "properties": {
              "object": {
                "oneOf": [
                  {
                    "$ref": "#/components/schemas/Invoice"
                  },
                  {
                    "$ref": "#/components/schemas/Payout"
                  },
                  {
                    "$ref": "#/components/schemas/Refund"
                  }
                ],
                "description": "The invoice, payout, refund, deposit or account the event is about"
              }
            }
          }
        }
      },
      "WebhookEvent": {
        "type": "object",
        "description": "Delivered as `POST` with `Content-Type: application/json`. Header `X-InstantPay-Signature: t=<unix>,v1=<hex>` where `v1 = HMAC-SHA256(endpoint secret, \"<t>.<raw body>\")`. Reject when `|now - t| > 300s`. Answer 2xx; anything else is retried up to 10 times over a day. The default body is the Event schema; an endpoint set to the legacy body receives this shape instead.",
        "properties": {
          "id": {
            "type": "string",
            "example": "evt_01K5N3Y7Z2Q8XW6M3R9V4T1B5C"
          },
          "event": {
            "type": "string",
            "enum": [
              "invoice.created",
              "invoice.detected",
              "invoice.confirmed",
              "invoice.underpaid",
              "invoice.expired",
              "invoice.paid_late",
              "invoice.cancelled",
              "invoice.failed",
              "deposit.confirmed",
              "payout.paid",
              "payout.failed",
              "refund.paid",
              "refund.failed"
            ]
          },
          "livemode": {
            "type": "boolean"
          },
          "createdAt": {
            "type": "string",
            "format": "date-time"
          },
          "invoice": {
            "type": "object",
            "description": "Legacy invoice shape: priceAmount, priceCurrency, overpaid, underpaid next to the usual fields"
          }
        }
      }
    }
  }
}